X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit-ng%2Fhttp.c;h=0dd7623650aaa0844cb51a8912f022056d6045cf;hb=fd396aeb6d3e10be928dd899ae228147b1728fb3;hp=0749a21a1380f50b8fc0b5fc8e1e3159238567c0;hpb=7f7214d4e20d34e813eef0794e55d1a1fe835f93;p=citadel.git diff --git a/webcit-ng/http.c b/webcit-ng/http.c index 0749a21a1..0dd762365 100644 --- a/webcit-ng/http.c +++ b/webcit-ng/http.c @@ -1,24 +1,24 @@ -/* - * This module handles HTTP transactions. - * - * Copyright (c) 1996-2016 by the citadel.org team - * - * This program is open source software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// +// This module handles HTTP transactions. +// +// Copyright (c) 1996-2018 by the citadel.org team +// +// This program is open source software. It runs great on the +// Linux operating system (and probably elsewhere). You can use, +// copy, and run it under the terms of the GNU General Public +// License version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. #include "webcit.h" /* * Write data to the HTTP client. Encrypt if necessary. */ -int client_write(struct client_handle *ch, char *buf, int nbytes) -{ +int client_write(struct client_handle *ch, char *buf, int nbytes) { if (is_https) { return client_write_ssl(ch, buf, nbytes); } @@ -32,8 +32,7 @@ int client_write(struct client_handle *ch, char *buf, int nbytes) * Read data from the HTTP client. Decrypt if necessary. * Returns number of bytes read, or -1 to indicate an error. */ -int client_read(struct client_handle *ch, char *buf, int nbytes) -{ +int client_read(struct client_handle *ch, char *buf, int nbytes) { if (is_https) { return client_read_ssl(ch, buf, nbytes); } @@ -41,13 +40,13 @@ int client_read(struct client_handle *ch, char *buf, int nbytes) int bytes_received = 0; int bytes_this_block = 0; while (bytes_received < nbytes) { - bytes_this_block = read(ch->sock, &buf[bytes_received], nbytes-bytes_received); + bytes_this_block = read(ch->sock, &buf[bytes_received], nbytes - bytes_received); if (bytes_this_block < 1) { - return(-1); + return (-1); } bytes_received += bytes_this_block; } - return(nbytes); + return (nbytes); } } @@ -57,37 +56,37 @@ int client_read(struct client_handle *ch, char *buf, int nbytes) * Implemented in terms of client_read() and is therefore transparent... * Returns the string length or -1 for error. */ -int client_readline(struct client_handle *ch, char *buf, int maxbytes) -{ +int client_readline(struct client_handle *ch, char *buf, int maxbytes) { int len = 0; int c = 0; - if (buf == NULL) return(-1); + if (buf == NULL) { + return (-1); + } while (len < maxbytes) { c = client_read(ch, &buf[len], 1); if (c <= 0) { syslog(LOG_DEBUG, "Socket error or zero-length read"); - return(-1); + return (-1); } if (buf[len] == '\n') { - if ( (len >0) && (buf[len-1] == '\r') ) { + if ((len > 0) && (buf[len - 1] == '\r')) { --len; } buf[len] = 0; - return(len); + return (len); } ++len; } - return(len); + return (len); } /* * printf() type function to send data to the web client. */ -void client_printf(struct client_handle *ch, const char *format,...) -{ +void client_printf(struct client_handle *ch, const char *format, ...) { va_list arg_ptr; StrBuf *Buf = NewStrBuf(); @@ -95,7 +94,7 @@ void client_printf(struct client_handle *ch, const char *format,...) StrBufVAppendPrintf(Buf, format, arg_ptr); va_end(arg_ptr); - client_write(ch, (char *)ChrPtr(Buf), StrLength(Buf)); + client_write(ch, (char *) ChrPtr(Buf), StrLength(Buf)); FreeStrBuf(&Buf); } @@ -104,8 +103,7 @@ void client_printf(struct client_handle *ch, const char *format,...) * Push one new header into the response of an HTTP request. * When completed, the HTTP transaction now owns the memory allocated for key and val. */ -void add_response_header(struct http_transaction *h, char *key, char *val) -{ +void add_response_header(struct http_transaction *h, char *key, char *val) { struct http_header *new_response_header = malloc(sizeof(struct http_header)); new_response_header->key = key; new_response_header->val = val; @@ -118,23 +116,22 @@ void add_response_header(struct http_transaction *h, char *key, char *val) * Entry point for this layer. Socket is connected. If running as an HTTPS * server, SSL has already been negotiated. Now perform one transaction. */ -void perform_one_http_transaction(struct client_handle *ch) -{ +void perform_one_http_transaction(struct client_handle *ch) { char buf[1024]; int len; int lines_read = 0; struct http_transaction h; char *c, *d; struct sockaddr_in sin; - struct http_header *clh; // general purpose iterator variable + struct http_header *clh; // general purpose iterator variable memset(&h, 0, sizeof h); - while (len = client_readline(ch, buf, sizeof buf), (len > 0) ) { + while (len = client_readline(ch, buf, sizeof buf), (len > 0)) { ++lines_read; - if (lines_read == 1) { // First line is method and URI. - c = strchr(buf, ' '); // IGnore the HTTP-version. + if (lines_read == 1) { // First line is method and URI. + c = strchr(buf, ' '); // IGnore the HTTP-version. if (c == NULL) { h.method = strdup("NULL"); h.uri = strdup("/"); @@ -152,8 +149,8 @@ void perform_one_http_transaction(struct client_handle *ch) h.uri = strdup(d); } } - else { // Subsequent lines are headers. - c = strchr(buf, ':'); // Header line folding is obsolete so we don't support it. + else { // Subsequent lines are headers. + c = strchr(buf, ':'); // Header line folding is obsolete so we don't support it. if (c != NULL) { struct http_header *new_request_header = malloc(sizeof(struct http_header)); *c = 0; @@ -173,7 +170,6 @@ void perform_one_http_transaction(struct client_handle *ch) } // build up the site prefix, such as https://foo.bar.com:4343 - h.site_prefix = malloc(256); strcpy(h.site_prefix, (is_https ? "https://" : "http://")); char *hostheader = header_val(&h, "Host"); @@ -184,12 +180,11 @@ void perform_one_http_transaction(struct client_handle *ch) strcat(h.site_prefix, "127.0.0.1"); } socklen_t llen = sizeof(sin); - if (getsockname(ch->sock, (struct sockaddr *)&sin, &llen) >= 0) { + if (getsockname(ch->sock, (struct sockaddr *) &sin, &llen) >= 0) { sprintf(&h.site_prefix[strlen(h.site_prefix)], ":%d", ntohs(sin.sin_port)); } // Now try to read in the request body (if one is present) - if (len < 0) { syslog(LOG_DEBUG, "Client disconnected"); } @@ -211,7 +206,6 @@ void perform_one_http_transaction(struct client_handle *ch) //write(2, HKEY("\033[0m\n")); } - // Now pass control up to the next layer to perform the request. perform_request(&h); @@ -230,7 +224,7 @@ void perform_one_http_transaction(struct client_handle *ch) free(datestring); } - client_printf(ch, "Content-encoding: identity\r\n"); // change if we gzip/deflate + client_printf(ch, "Content-encoding: identity\r\n"); // change if we gzip/deflate for (clh = h.response_headers; clh != NULL; clh = clh->next) { #ifdef DEBUG_HTTP syslog(LOG_DEBUG, "} %s: %s", clh->key, clh->val); @@ -245,24 +239,33 @@ void perform_one_http_transaction(struct client_handle *ch) // free the transaction memory while (h.request_headers) { - if (h.request_headers->key) free(h.request_headers->key); - if (h.request_headers->val) free(h.request_headers->val); + if (h.request_headers->key) + free(h.request_headers->key); + if (h.request_headers->val) + free(h.request_headers->val); clh = h.request_headers->next; free(h.request_headers); h.request_headers = clh; } while (h.response_headers) { - if (h.response_headers->key) free(h.response_headers->key); - if (h.response_headers->val) free(h.response_headers->val); + if (h.response_headers->key) + free(h.response_headers->key); + if (h.response_headers->val) + free(h.response_headers->val); clh = h.response_headers->next; free(h.response_headers); h.response_headers = clh; } - if (h.method) free(h.method); - if (h.uri) free(h.uri); - if (h.request_body) free(h.request_body); - if (h.response_string) free(h.response_string); - if (h.site_prefix) free(h.site_prefix); + if (h.method) + free(h.method); + if (h.uri) + free(h.uri); + if (h.request_body) + free(h.request_body); + if (h.response_string) + free(h.response_string); + if (h.site_prefix) + free(h.site_prefix); } @@ -272,13 +275,12 @@ void perform_one_http_transaction(struct client_handle *ch) * The caller does NOT own the memory of the returned pointer, but can count on the pointer * to still be valid through the end of the transaction. */ -char *header_val(struct http_transaction *h, char *requested_header) -{ - struct http_header *clh; // general purpose iterator variable +char *header_val(struct http_transaction *h, char *requested_header) { + struct http_header *clh; // general purpose iterator variable for (clh = h->request_headers; clh != NULL; clh = clh->next) { if (!strcasecmp(clh->key, requested_header)) { - return(clh->val); + return (clh->val); } } - return(NULL); + return (NULL); }