From: Simon Ruderich Date: Sun, 27 Feb 2011 01:22:05 +0000 (+0100) Subject: tlsproxy.c: Add read_http_request(). X-Git-Tag: 0.1~45 X-Git-Url: https://ruderich.org/simon/gitweb/?a=commitdiff_plain;h=ee6d97ea88ddc5f387db3f77d5f04cd8d6217ace;p=tlsproxy%2Ftlsproxy.git tlsproxy.c: Add read_http_request(). --- diff --git a/tlsproxy.c b/tlsproxy.c index b417a98..a7b4157 100644 --- a/tlsproxy.c +++ b/tlsproxy.c @@ -34,7 +34,14 @@ #include +/* Maximum line of the request line. Longer request lines are aborted with an + * error. The standard doesn't specify a maximum line length but this should + * be a good limit to make processing simpler. */ +#define MAX_REQUEST_LINE 4096 + + static void handle_connection(int socket); +static int read_http_request(FILE *client_fd, char *request, size_t length); static void send_close_bad_request(FILE *client_fd); static void send_close_forwarding_failure(FILE *client_fd); @@ -114,11 +121,12 @@ static void handle_connection(int client_socket) { int server_socket; FILE *client_fd, *server_fd; - char buffer[4096]; - char host[4096]; + char buffer[MAX_REQUEST_LINE]; + char host[MAX_REQUEST_LINE]; char port[5 + 1]; int version_minor; + int result; client_fd = fdopen(client_socket, "a+"); if (NULL == client_fd) { @@ -131,13 +139,13 @@ static void handle_connection(int client_socket) { printf("New connection:\n"); #endif - if (NULL == fgets(buffer, sizeof(buffer), client_fd)) { - if (ferror(client_fd)) { - perror("fgets(), request"); - fclose(client_fd); - return; - } - + /* Read request line (CONNECT ..) and headers (they are discarded). */ + result = read_http_request(client_fd, buffer, sizeof(buffer)); + if (result == -1) { + /* Read error. */ + return; + } else if (result == -2) { + /* EOF */ send_close_bad_request(client_fd); return; } @@ -154,18 +162,6 @@ static void handle_connection(int client_socket) { return; } - while (NULL != fgets(buffer, sizeof(buffer), client_fd)) { - /* End of header. */ - if (0 == strcmp(buffer, "\n") || 0 == strcmp(buffer, "\r\n")) { - break; - } - } - if (ferror(client_fd)) { - perror("fgets(), header"); - fclose(client_fd); - return; - } - #ifdef DEBUG printf(" %s:%s (HTTP 1.%d)\n", host, port, version_minor); #endif @@ -193,6 +189,39 @@ static void handle_connection(int client_socket) { fclose(server_fd); } +/* Read HTTP request line and headers (ignored). + * + * On success 0 is returned, -1 on client error (we close client descriptor in + * this case), -2 on unexpected EOF. + */ +static int read_http_request(FILE *client_fd, char *request, size_t length) { + char buffer[MAX_REQUEST_LINE]; + + if (NULL == fgets(request, (int)length, client_fd)) { + if (ferror(client_fd)) { + perror("fgets(), request"); + fclose(client_fd); + return -1; + } + + return -2; + } + + while (NULL != fgets(buffer, MAX_REQUEST_LINE, client_fd)) { + /* End of header. */ + if (0 == strcmp(buffer, "\n") || 0 == strcmp(buffer, "\r\n")) { + break; + } + } + if (ferror(client_fd)) { + perror("fgets(), header"); + fclose(client_fd); + return -1; + } + + return 0; +} + static void send_close_bad_request(FILE *client_fd) { fprintf(client_fd, "HTTP/1.0 400 Bad Request\r\n"); fprintf(client_fd, "\r\n");