X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=apps%2Flib%2Fhttp_server.c;h=36ea7a3bdc677170dd14a955ee153bfcedc31786;hb=fba140c73541c03e22b4fdb219a05d129bf0406d;hp=1858d04ccb56dda2c01a007008126dc2737acfb3;hpb=db70dc2cdac6dec2366138fe1f46bf433ee1c2c8;p=thirdparty%2Fopenssl.git diff --git a/apps/lib/http_server.c b/apps/lib/http_server.c index 1858d04ccb..36ea7a3bdc 100644 --- a/apps/lib/http_server.c +++ b/apps/lib/http_server.c @@ -17,7 +17,6 @@ # define _POSIX_C_SOURCE 2 #endif -#include #include #include "http_server.h" #include "internal/sockets.h" @@ -37,6 +36,7 @@ static int verbosity = LOG_INFO; #define HTTP_VERSION_PATT "1." /* allow 1.x */ #define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT #define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */ +#define HTTP_VERSION_STR " "HTTP_PREFIX_VERSION #ifdef HTTP_DAEMON @@ -216,18 +216,27 @@ void spawn_loop(const char *prog) #endif #ifndef OPENSSL_NO_SOCK -BIO *http_server_init_bio(const char *prog, const char *port) +BIO *http_server_init(const char *prog, const char *port, int verb) { BIO *acbio = NULL, *bufbio; int asock; + int port_num; + if (verb >= 0) { + if (verb > LOG_TRACE) { + log_message(prog, LOG_ERR, + "Logging verbosity level %d too high", verb); + return NULL; + } + verbosity = verb; + } bufbio = BIO_new(BIO_f_buffer()); if (bufbio == NULL) goto err; acbio = BIO_new(BIO_s_accept()); if (acbio == NULL || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0 - || BIO_set_accept_port(acbio, port) < 0) { + || BIO_set_accept_port(acbio, port /* may be "0" */) < 0) { log_message(prog, LOG_ERR, "Error setting up accept BIO"); goto err; } @@ -241,7 +250,8 @@ BIO *http_server_init_bio(const char *prog, const char *port) /* Report back what address and port are used */ BIO_get_fd(acbio, &asock); - if (!report_server_accept(bio_out, asock, 1)) { + port_num = report_server_accept(bio_out, asock, 1, 1); + if (port_num == 0) { log_message(prog, LOG_ERR, "Error printing ACCEPT string"); goto err; } @@ -283,8 +293,7 @@ static int urldecode(char *p) int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, char **ppath, BIO **pcbio, BIO *acbio, int *found_keep_alive, - const char *prog, const char *port, - int accept_get, int timeout) + const char *prog, int accept_get, int timeout) { BIO *cbio = *pcbio, *getbio = NULL, *b64 = NULL; int len; @@ -298,15 +307,24 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, *ppath = NULL; if (cbio == NULL) { + char *port; + + get_sock_info_address(BIO_get_fd(acbio, NULL), NULL, &port); + if (port == NULL) { + log_message(prog, LOG_ERR, "Cannot get port listening on"); + goto fatal; + } log_message(prog, LOG_DEBUG, - "Awaiting new connection on port %s...", port); + "Awaiting new connection on port %s ...", port); + OPENSSL_free(port); + if (BIO_do_accept(acbio) <= 0) /* Connection loss before accept() is routine, ignore silently */ return ret; *pcbio = cbio = BIO_pop(acbio); } else { - log_message(prog, LOG_DEBUG, "Awaiting next request..."); + log_message(prog, LOG_DEBUG, "Awaiting next request ..."); } if (cbio == NULL) { /* Cannot call http_server_send_status(cbio, ...) */ @@ -336,15 +354,12 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, *end = '\0'; log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf); - meth = reqbuf; - url = meth + 3; - if ((accept_get && strncmp(meth, "GET ", 4) == 0) - || (url++, strncmp(meth, "POST ", 5) == 0)) { - static const char http_version_str[] = " "HTTP_PREFIX_VERSION; - static const size_t http_version_str_len = sizeof(http_version_str) - 1; + url = meth = reqbuf; + if ((accept_get && CHECK_AND_SKIP_PREFIX(url, "GET ")) + || CHECK_AND_SKIP_PREFIX(url, "POST ")) { /* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */ - *(url++) = '\0'; + url[-1] = '\0'; while (*url == ' ') url++; if (*url != '/') { @@ -360,7 +375,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, for (end = url; *end != '\0'; end++) if (*end == ' ') break; - if (strncmp(end, http_version_str, http_version_str_len) != 0) { + if (!HAS_PREFIX(end, HTTP_VERSION_STR)) { log_message(prog, LOG_WARNING, "Invalid %s -- bad HTTP/version string: %s", meth, end + 1); @@ -370,7 +385,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, *end = '\0'; /* above HTTP 1.0, connection persistence is the default */ if (found_keep_alive != NULL) - *found_keep_alive = end[http_version_str_len] > '0'; + *found_keep_alive = end[sizeof(HTTP_VERSION_STR) - 1] > '0'; /*- * Skip "GET / HTTP..." requests often used by load-balancers. @@ -453,10 +468,11 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, } *line_end = '\0'; /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */ - if (found_keep_alive != NULL && strcasecmp(key, "Connection") == 0) { - if (strcasecmp(value, "keep-alive") == 0) + if (found_keep_alive != NULL + && OPENSSL_strcasecmp(key, "Connection") == 0) { + if (OPENSSL_strcasecmp(value, "keep-alive") == 0) *found_keep_alive = 1; - else if (strcasecmp(value, "close") == 0) + else if (OPENSSL_strcasecmp(value, "close") == 0) *found_keep_alive = 0; } }