Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <limits.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <openssl/ssl.h>
- #include <openssl/err.h>
- void usage()
- {
- fprintf(stderr, "usage: httpsclient [-h] [-q] [-t] <uri>\n");
- fprintf(stderr, "\t-h : send HEAD instead of GET request\n");
- fprintf(stderr, "\t-q : don't print output\n");
- fprintf(stderr, "\t-t : print milliseconds to complete request in MRTG format\n");
- fprintf(stderr, "\t-d : print debugging information\n");
- exit(EXIT_FAILURE);
- }
- int main(int argc, char **argv)
- {
- char *uri = 0;
- char *host;
- char *request;
- char *port = 0;
- const char *proto = "tcp";
- char *service;
- char *randfile;
- struct protoent *pe;
- struct hostent *he;
- struct sockaddr_in addr;
- struct timeval t1, t2, t3;
- unsigned long td1, td2;
- int s, n;
- char *buffer;
- const int bufsize = 4096;
- int opt_q = 0;
- int opt_t = 0;
- int opt_h = 0;
- int opt_d = 0;
- SSL_CTX *ctx;
- SSL *ssl = 0;
- int https = 0;
- /* skip argv[0] */
- argv++;
- argc--;
- while (*argv && **argv == '-') {
- char *opt = *argv + 1;
- switch (*opt) {
- case 'h':
- opt_h = 1; break;
- case 'q':
- opt_q = 1; break;
- case 't':
- opt_t = 1; break;
- case 'd':
- opt_d = 1; break;
- default:
- usage();
- }
- argv++;
- argc--;
- }
- if (argc == 1) {
- uri = *argv++; argc--;
- } else {
- usage();
- }
- /* parse the URI */
- {
- if (strncmp(uri, "http://", 7) == 0) {
- host = uri + 7;
- uri[4] = '\0';
- } else if (strncmp(uri, "https://", 8) == 0) {
- host = uri + 8;
- uri[5] = '\0';
- https = 1;
- } else {
- fprintf(stderr, "error: invalid uri\n");
- return EXIT_FAILURE;
- }
- service = uri;
- request = strchr(host, '/');
- if (request) {
- *request++ = '\0';
- } else {
- request = "";
- }
- /* look for a port number */
- port = strrchr(host, ':');
- if (port) {
- *port++ = '\0';
- /* catch empty port specifiers */
- if (*port == '\0') {
- port = 0;
- }
- }
- }
- if ((buffer = malloc(bufsize)) == 0) {
- perror("malloc");
- return EXIT_FAILURE;
- }
- if ((he = gethostbyname(host)) == 0) {
- if (h_errno == HOST_NOT_FOUND) {
- fprintf(stderr, "gethostbyname: host not found\n");
- } else if (h_errno == NO_DATA) {
- fprintf(stderr, "gethostbyname: no data for host\n");
- } else if (h_errno == TRY_AGAIN) {
- fprintf(stderr, "gethostbyname: host not found\n");
- } else {
- fprintf(stderr, "gethostbyname: error %d\n", h_errno);
- }
- return EXIT_FAILURE;
- }
- if ((pe = getprotobyname(proto)) == 0) {
- perror("getprotobyname");
- return EXIT_FAILURE;
- }
- memset(&addr, 0, sizeof(addr));
- memcpy(&addr.sin_addr, he->h_addr, sizeof(addr.sin_addr));
- addr.sin_family = AF_INET;
- if (port) {
- addr.sin_port = htons(atoi(port));
- } else {
- struct servent *se;
- if ((se = getservbyname(service, proto)) == 0) {
- perror("getservbyname");
- return EXIT_FAILURE;
- }
- addr.sin_port = se->s_port;
- }
- /* create the socket */
- if ((s = socket(PF_INET, SOCK_STREAM, pe->p_proto)) < 0) {
- perror("socket");
- return EXIT_FAILURE;
- }
- /* first timing point here */
- if (gettimeofday(&t1, NULL) < 0) {
- perror("gettimeofday(t1)");
- return EXIT_FAILURE;
- }
- if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- perror("connect");
- return EXIT_FAILURE;
- }
- /* create SSL connection if necessary */
- if (https) {
- SSL_load_error_strings();
- randfile = (char *)malloc(_POSIX_PATH_MAX);
- RAND_file_name(randfile, _POSIX_PATH_MAX);
- RAND_load_file(randfile, -1);
- SSL_library_init();
- ctx = SSL_CTX_new(SSLv23_client_method());
- ssl = SSL_new(ctx);
- SSL_set_fd(ssl, s);
- SSL_connect(ssl);
- if (opt_d) {
- char buffer[128];
- SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
- SSL_CIPHER_description(cipher, buffer, sizeof(buffer));
- fputs(buffer, stderr);
- }
- }
- /* second timing point here */
- if (gettimeofday(&t2, NULL) < 0) {
- perror("gettimeofday(t2)");
- return EXIT_FAILURE;
- }
- n = sprintf(buffer, "%s /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
- (opt_h ? "HEAD" : "GET"), request, host);
- if (n > bufsize) {
- fprintf(stderr, "buffer overflow");
- return EXIT_FAILURE;
- }
- if (https) {
- if (SSL_write(ssl, buffer, n) <= 0) {
- fprintf(stderr, "SSL error 1\n");
- ERR_print_errors_fp(stderr);
- return EXIT_FAILURE;
- }
- ERR_clear_error();
- while ((n = SSL_read(ssl, buffer, bufsize)) > 0) {
- if (opt_q) continue;
- fwrite(buffer, 1, n, stdout);
- }
- if (n <= 0) {
- int error = SSL_get_error(ssl, n);
- if (error == SSL_ERROR_SYSCALL) {
- if (errno != 0) {
- perror("SSL_read");
- ERR_print_errors_fp(stderr);
- }
- } else if (error != SSL_ERROR_ZERO_RETURN &&
- error != SSL_ERROR_NONE)
- {
- ERR_print_errors_fp(stderr);
- return EXIT_FAILURE;
- }
- }
- } else {
- if (write(s, buffer, n) != n) {
- perror("write");
- return EXIT_FAILURE;
- }
- while ((n = read(s, buffer, bufsize)) > 0) {
- if (opt_q) continue;
- fwrite(buffer, 1, n, stdout);
- }
- }
- /* third timing point here */
- if (gettimeofday(&t3, NULL) < 0) {
- perror("gettimeofday(t3)");
- return EXIT_FAILURE;
- }
- /* calculate elapsed times */
- td1 = (t3.tv_sec - t2.tv_sec) * 1000;
- td1 += (t3.tv_usec - t2.tv_usec) / 1000;
- td2 = (t3.tv_sec - t1.tv_sec) * 1000;
- td2 += (t3.tv_usec - t1.tv_usec) / 1000;
- if (opt_t) {
- fprintf(stdout, "%ld\n%ld\n", td1, td2);
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement