From: Urban Wallasch Date: Sat, 26 Oct 2019 18:44:13 +0000 (+0200) Subject: * Inspect the "Connection:" request header field and act accordingly. X-Git-Tag: v0.1.0~4 X-Git-Url: https://git.packet-gain.de/?a=commitdiff_plain;h=933821e218f899271d969afda5b7d16e9d677792;p=ets2_tele.git * Inspect the "Connection:" request header field and act accordingly. * Improved request handling and header parsing. --- diff --git a/telehttpd.c b/telehttpd.c index a219c84..ec0cacd 100644 --- a/telehttpd.c +++ b/telehttpd.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -98,11 +99,19 @@ static int check_shm( bool retry ) { return 0; } +static char *strcasestr( const char *haystack, const char *needle ) { + size_t l = strlen( needle ); + for ( char *p = (char *)haystack; *p; ++p ) + if ( strncasecmp( p, needle, l ) == 0 ) + return p; + return NULL; +} + static size_t copy_field_val( char *buf, size_t bufsz, const char *needle, const char *haystack, const char *def ) { const char *s; size_t l; - if ( NULL != ( s = strstr( haystack, needle ) ) ) { + if ( NULL != ( s = strcasestr( haystack, needle ) ) ) { const char *e; s += strlen( needle ); if ( NULL != ( e = strstr( s, "\r\n" ) ) ) @@ -138,6 +147,7 @@ static int respond( int sock, const char *req ) { char hdr[512]; char origin[256]; char host[256]; + char conn[32]; enum respond_code { r_index, r_json, @@ -152,6 +162,7 @@ static int respond( int sock, const char *req ) { code = r_none; copy_field_val( host, sizeof host, "Host: ", req, cfg.host ); + copy_field_val( conn, sizeof conn, "Connection: ", req, "keep-alive" ); switch (code) { case r_json: { @@ -170,11 +181,12 @@ static int respond( int sock, const char *req ) { "Host: %s\r\n" "Access-Control-Allow-Origin: %s\r\n" "Content-type: text/json\r\n" - "Connection: keep-alive\r\n" + "Connection: %s\r\n" "Content-Length: %zu\r\n" "\r\n", host, origin, + conn, jsz ); if ( 0 < n && (size_t)n < sizeof hdr && n == sockwrite( sock, hdr, n ) ) @@ -189,16 +201,17 @@ static int respond( int sock, const char *req ) { goto SEND_404; if ( 0 > fstat(fi, &st) ) { close( fi ); - goto SEND_404; + goto SEND_500; } n = snprintf( hdr, sizeof hdr, "HTTP/1.1 200 OK\r\n" "Host: %s\r\n" "Content-type: text/html\r\n" - "Connection: keep-alive\r\n" + "Connection: %s\r\n" "Content-Length: %jd\r\n" "\r\n", host, + conn, (intmax_t)st.st_size ); if ( 0 < n && (size_t)n < sizeof hdr && n == sockwrite( sock, hdr, n ) ) { @@ -236,11 +249,14 @@ static int respond( int sock, const char *req ) { sockwrite( sock, hdr, n ); break; } + if ( 0 < ret && 0 != strcasecmp( conn, "keep-alive" ) ) + ret = 0; return ret; } static int rcv_request(int sock, char *buf, size_t size, int timeout) { int res = -1; + char junk, *eohdr; size_t total = 0; ssize_t bread = 0; --size; @@ -259,11 +275,16 @@ static int rcv_request(int sock, char *buf, size_t size, int timeout) { break; } total += bread; - timeout = 5; + timeout = 1; } + while ( 1 == read_tm( sock, &junk, 1, 0 ) ) + ; buf[total] = 0; - if ( strstr( buf, "\r\n\r\n" ) ) + eohdr = strstr( buf, "\r\n\r\n" ); + if ( NULL != eohdr ) { + eohdr[4] = '\0'; res = 0; + } return res; } @@ -275,7 +296,7 @@ static void *handle_conn( void *p ) { DPRINT( "sock: %d\n", td->sock ); while ( 0 == rcv_request(td->sock, req, sizeof req, 5000) ) { DPRINT( "request:\n%s", req); - if ( 0 > respond( td->sock, req ) ) + if ( 0 >= respond( td->sock, req ) ) break; } net_close( td->sock );