From 6f72420e2c253b1e51a9cac02d0b25860352d754 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Thu, 15 Nov 2018 15:59:23 +0000 Subject: Import Upstream version 1.23 --- README | 2 +- contrib/redhat-rpm/mini_httpd.spec | 2 +- mini_httpd.c | 186 ++++++++++++++++++++----------------- port.h | 6 +- version.h | 2 +- 5 files changed, 109 insertions(+), 89 deletions(-) diff --git a/README b/README index 14c1cc5..3f152b4 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ mini_httpd - small HTTP server - version 1.21 of 18oct2004 + version 1.23 of 28Dec2015 mini_httpd is a small HTTP server. Its performance is not great, but for low or medium traffic sites it's quite adequate. It implements all the diff --git a/contrib/redhat-rpm/mini_httpd.spec b/contrib/redhat-rpm/mini_httpd.spec index 3f52202..2cab698 100644 --- a/contrib/redhat-rpm/mini_httpd.spec +++ b/contrib/redhat-rpm/mini_httpd.spec @@ -1,6 +1,6 @@ Summary: small, simple http daemon, supports SSL Name: mini_httpd -Version: 1.21 +Version: 1.23 Release: 1 Copyright: Freely Redistributable Packager: Bennett Todd diff --git a/mini_httpd.c b/mini_httpd.c index 881843f..4051625 100644 --- a/mini_httpd.c +++ b/mini_httpd.c @@ -113,6 +113,8 @@ typedef long long int64_t; #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif +/* Do overlapping strcpy safely, by using memmove. */ +#define ol_strcpy(dst,src) memmove(dst,src,strlen(src)+1) #ifndef ERR_DIR #define ERR_DIR "errors" @@ -195,8 +197,8 @@ static char* p3p; static int max_age; static FILE* logfp; static int listen4_fd, listen6_fd; -#ifdef USE_SSL static int do_ssl; +#ifdef USE_SSL static char* certfile; static char* cipher; static SSL_CTX* ssl_ctx; @@ -267,10 +269,10 @@ static int send_error_file( char* filename ); static void send_error_tail( void ); static void add_headers( int s, char* title, char* extra_header, char* me, char* mt, off_t b, time_t mod ); static void start_request( void ); -static void add_to_request( char* str, size_t len ); +static void add_to_request( char* str ); static char* get_request_line( void ); static void start_response( void ); -static void add_to_response( char* str, size_t len ); +static void add_to_response( char* str ); static void send_response( void ); static void send_via_write( int fd, off_t size ); static void send_via_sendfile( int fd, int s, off_t size ); @@ -279,7 +281,7 @@ static ssize_t my_write( void* buf, size_t size ); #ifdef HAVE_SENDFILE static int my_sendfile( int fd, int s, off_t offset, size_t nbytes ); #endif /* HAVE_SENDFILE */ -static void add_to_buf( char** bufP, size_t* bufsizeP, size_t* buflenP, char* str, size_t len ); +static void add_str( char** bufP, size_t* bufsizeP, size_t* buflenP, char* str ); static void make_log_entry( void ); static void check_referrer( void ); static int really_check_referrer( void ); @@ -346,8 +348,8 @@ main( int argc, char** argv ) logfile = (char*) 0; pidfile = (char*) 0; logfp = (FILE*) 0; -#ifdef USE_SSL do_ssl = 0; +#ifdef USE_SSL certfile = DEFAULT_CERTFILE; cipher = (char*) 0; #endif /* USE_SSL */ @@ -688,7 +690,7 @@ main( int argc, char** argv ) { if ( strncmp( logfile, cwd, strlen( cwd ) ) == 0 ) { - (void) strcpy( logfile, &logfile[strlen( cwd ) - 1] ); + (void) ol_strcpy( logfile, &logfile[strlen( cwd ) - 1] ); /* (We already guaranteed that cwd ends with a slash, so leaving ** that slash in logfile makes it an absolute pathname within ** the chroot tree.) @@ -1173,14 +1175,17 @@ handle_request( void ) useragent = ""; #ifdef TCP_NOPUSH - /* Set the TCP_NOPUSH socket option, to try and avoid the 0.2 second - ** delay between sending the headers and sending the data. A better - ** solution is writev() (as used in thttpd), or send the headers with - ** send(MSG_MORE) (only available in Linux so far). - */ - r = 1; - (void) setsockopt( - conn_fd, IPPROTO_TCP, TCP_NOPUSH, (void*) &r, sizeof(r) ); + if ( ! do_ssl ) + { + /* Set the TCP_NOPUSH socket option, to try and avoid the 0.2 second + ** delay between sending the headers and sending the data. A better + ** solution is writev() (as used in thttpd), or send the headers with + ** send(MSG_MORE) (only available in Linux so far). + */ + r = 1; + (void) setsockopt( + conn_fd, IPPROTO_TCP, TCP_NOPUSH, (void*) &r, sizeof(r) ); + } #endif /* TCP_NOPUSH */ #ifdef USE_SSL @@ -1201,13 +1206,14 @@ handle_request( void ) for (;;) { char buf[10000]; - int rr = my_read( buf, sizeof(buf) ); + int rr = my_read( buf, sizeof(buf) - 1 ); if ( rr < 0 && ( errno == EINTR || errno == EAGAIN ) ) continue; if ( rr <= 0 ) break; (void) alarm( READ_TIMEOUT ); - add_to_request( buf, rr ); + buf[rr] = '\0'; + add_to_request( buf ); if ( strstr( request, "\015\012\015\012" ) != (char*) 0 || strstr( request, "\012\012" ) != (char*) 0 ) break; @@ -1397,26 +1403,26 @@ de_dotdot( char* f ) { for ( cp2 = cp + 2; *cp2 == '/'; ++cp2 ) continue; - (void) strcpy( cp + 1, cp2 ); + (void) ol_strcpy( cp + 1, cp2 ); } /* Remove leading ./ and any /./ sequences. */ while ( strncmp( f, "./", 2 ) == 0 ) - (void) strcpy( f, f + 2 ); + (void) ol_strcpy( f, f + 2 ); while ( ( cp = strstr( f, "/./") ) != (char*) 0 ) - (void) strcpy( cp, cp + 2 ); + (void) ol_strcpy( cp, cp + 2 ); /* Alternate between removing leading ../ and removing xxx/../ */ for (;;) { while ( strncmp( f, "../", 3 ) == 0 ) - (void) strcpy( f, f + 3 ); + (void) ol_strcpy( f, f + 3 ); cp = strstr( f, "/../" ); if ( cp == (char*) 0 ) break; for ( cp2 = cp - 1; cp2 >= f && *cp2 != '/'; --cp2 ) continue; - (void) strcpy( cp2 + 1, cp + 4 ); + (void) ol_strcpy( cp2 + 1, cp + 4 ); } /* Also elide any xxx/.. at the end. */ @@ -1560,7 +1566,6 @@ static void do_dir( void ) { char buf[10000]; - size_t buflen; char* contents; size_t contents_size, contents_len; #ifdef HAVE_SCANDIR @@ -1593,7 +1598,7 @@ do_dir( void ) #endif /* HAVE_SCANDIR */ contents_size = 0; - buflen = snprintf( buf, sizeof(buf), "\ + (void) snprintf( buf, sizeof(buf), "\ \n\ \n\ \n\ @@ -1607,16 +1612,14 @@ do_dir( void )

Index of %s

\n\
\n",
 	file, file );
-    add_to_buf( &contents, &contents_size, &contents_len, buf, buflen );
+    add_str( &contents, &contents_size, &contents_len, buf );
 
 #ifdef HAVE_SCANDIR
 
     for ( i = 0; i < n; ++i )
 	{
 	name_info = file_details( file, dl[i]->d_name );
-	add_to_buf(
-	    &contents, &contents_size, &contents_len, name_info,
-	    strlen( name_info ) );
+	add_str( &contents, &contents_size, &contents_len, name_info );
 	}
 
 #else /* HAVE_SCANDIR */
@@ -1631,16 +1634,17 @@ do_dir( void )
 	for (;;)
 	    {
 	    size_t r;
-	    r = fread( buf, 1, sizeof(buf), fp );
+	    r = fread( buf, 1, sizeof(buf) - 1, fp );
 	    if ( r == 0 )
 		break;
-	    add_to_buf( &contents, &contents_size, &contents_len, buf, r );
+	    buf[r] = '\0';
+	    add_str( &contents, &contents_size, &contents_len, buf );
 	    }
 	(void) pclose( fp );
 	}
 #endif /* HAVE_SCANDIR */
 
-    buflen = snprintf( buf, sizeof(buf), "\
+    (void) snprintf( buf, sizeof(buf), "\
     
\n\ \n\
\n\ @@ -1651,11 +1655,14 @@ do_dir( void ) \n\ \n", SERVER_URL, SERVER_SOFTWARE ); - add_to_buf( &contents, &contents_size, &contents_len, buf, buflen ); + add_str( &contents, &contents_size, &contents_len, buf ); add_headers( 200, "Ok", "", "", "text/html; charset=%s", contents_len, sb.st_mtime ); if ( method != METHOD_HEAD ) - add_to_response( contents, contents_len ); + { + contents[contents_len] = '\0'; + add_to_response( contents ); + } send_response(); } @@ -1987,10 +1994,10 @@ cgi_interpose_output( int rfd, int parse_headers ) /* Slurp in all headers. */ headers_size = 0; - add_to_buf( &headers, &headers_size, &headers_len, (char*) 0, 0 ); + add_str( &headers, &headers_size, &headers_len, (char*) 0 ); for (;;) { - r = read( rfd, buf, sizeof(buf) ); + r = read( rfd, buf, sizeof(buf) - 1 ); if ( r < 0 && ( errno == EINTR || errno == EAGAIN ) ) { sleep( 1 ); @@ -2001,7 +2008,8 @@ cgi_interpose_output( int rfd, int parse_headers ) br = &(headers[headers_len]); break; } - add_to_buf( &headers, &headers_size, &headers_len, buf, r ); + buf[r] = '\0'; + add_str( &headers, &headers_size, &headers_len, buf ); if ( ( br = strstr( headers, "\015\012\015\012" ) ) != (char*) 0 || ( br = strstr( headers, "\012\012" ) ) != (char*) 0 ) break; @@ -2392,7 +2400,6 @@ send_error_body( int s, char* title, char* text ) { char filename[1000]; char buf[10000]; - int buflen; if ( vhost && req_hostname != (char*) 0 ) { @@ -2411,7 +2418,7 @@ send_error_body( int s, char* title, char* text ) return; /* Send built-in error page. */ - buflen = snprintf( + (void) snprintf( buf, sizeof(buf), "\ \n\ \n\ @@ -2426,9 +2433,9 @@ send_error_body( int s, char* title, char* text ) \n\

%d %s

\n", s, title, s, title ); - add_to_response( buf, buflen ); - buflen = snprintf( buf, sizeof(buf), "%s\n", text ); - add_to_response( buf, buflen ); + add_to_response( buf ); + (void) snprintf( buf, sizeof(buf), "%s\n", text ); + add_to_response( buf ); } @@ -2444,10 +2451,11 @@ send_error_file( char* filename ) return 0; for (;;) { - r = fread( buf, 1, sizeof(buf), fp ); + r = fread( buf, 1, sizeof(buf) - 1, fp ); if ( r == 0 ) break; - add_to_response( buf, r ); + buf[r] = '\0'; + add_to_response( buf ); } (void) fclose( fp ); return 1; @@ -2458,23 +2466,22 @@ static void send_error_tail( void ) { char buf[500]; - int buflen; if ( match( "**MSIE**", useragent ) ) { int n; - buflen = snprintf( buf, sizeof(buf), "\n" ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "-->\n" ); + add_to_response( buf ); } - buflen = snprintf( buf, sizeof(buf), "\ + (void) snprintf( buf, sizeof(buf), "\
\n\ \n\
%s
\n\ @@ -2483,7 +2490,7 @@ send_error_tail( void ) \n\ \n", SERVER_URL, SERVER_SOFTWARE ); - add_to_response( buf, buflen ); + add_to_response( buf ); } @@ -2493,7 +2500,6 @@ add_headers( int s, char* title, char* extra_header, char* me, char* mt, off_t b time_t now, expires; char timebuf[100]; char buf[10000]; - int buflen; int s100; const char* rfc1123_fmt = "%a, %d %b %Y %H:%M:%S GMT"; @@ -2501,64 +2507,64 @@ add_headers( int s, char* title, char* extra_header, char* me, char* mt, off_t b bytes = b; make_log_entry(); start_response(); - buflen = snprintf( buf, sizeof(buf), "%s %d %s\015\012", protocol, status, title ); - add_to_response( buf, buflen ); - buflen = snprintf( buf, sizeof(buf), "Server: %s\015\012", SERVER_SOFTWARE ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "%s %d %s\015\012", protocol, status, title ); + add_to_response( buf ); + (void) snprintf( buf, sizeof(buf), "Server: %s\015\012", SERVER_SOFTWARE ); + add_to_response( buf ); now = time( (time_t*) 0 ); (void) strftime( timebuf, sizeof(timebuf), rfc1123_fmt, gmtime( &now ) ); - buflen = snprintf( buf, sizeof(buf), "Date: %s\015\012", timebuf ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "Date: %s\015\012", timebuf ); + add_to_response( buf ); s100 = status / 100; if ( s100 != 2 && s100 != 3 ) { - buflen = snprintf( buf, sizeof(buf), "Cache-Control: no-cache,no-store\015\012" ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "Cache-Control: no-cache,no-store\015\012" ); + add_to_response( buf ); } if ( extra_header != (char*) 0 && extra_header[0] != '\0' ) { - buflen = snprintf( buf, sizeof(buf), "%s\015\012", extra_header ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "%s\015\012", extra_header ); + add_to_response( buf ); } if ( me != (char*) 0 && me[0] != '\0' ) { - buflen = snprintf( buf, sizeof(buf), "Content-Encoding: %s\015\012", me ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "Content-Encoding: %s\015\012", me ); + add_to_response( buf ); } if ( mt != (char*) 0 && mt[0] != '\0' ) { - buflen = snprintf( buf, sizeof(buf), "Content-Type: %s\015\012", mt ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "Content-Type: %s\015\012", mt ); + add_to_response( buf ); } if ( bytes >= 0 ) { - buflen = snprintf( + (void) snprintf( buf, sizeof(buf), "Content-Length: %lld\015\012", (long long) bytes ); - add_to_response( buf, buflen ); + add_to_response( buf ); } if ( p3p != (char*) 0 && p3p[0] != '\0' ) { - buflen = snprintf( buf, sizeof(buf), "P3P: %s\015\012", p3p ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "P3P: %s\015\012", p3p ); + add_to_response( buf ); } if ( max_age >= 0 ) { expires = now + max_age; (void) strftime( timebuf, sizeof(timebuf), rfc1123_fmt, gmtime( &expires ) ); - buflen = snprintf( buf, sizeof(buf), + (void) snprintf( buf, sizeof(buf), "Cache-Control: max-age=%d\015\012Expires: %s\015\012", max_age, timebuf ); - add_to_response( buf, buflen ); + add_to_response( buf ); } if ( mod != (time_t) -1 ) { (void) strftime( timebuf, sizeof(timebuf), rfc1123_fmt, gmtime( &mod ) ); - buflen = snprintf( buf, sizeof(buf), "Last-Modified: %s\015\012", timebuf ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "Last-Modified: %s\015\012", timebuf ); + add_to_response( buf ); } - buflen = snprintf( buf, sizeof(buf), "Connection: close\015\012\015\012" ); - add_to_response( buf, buflen ); + (void) snprintf( buf, sizeof(buf), "Connection: close\015\012\015\012" ); + add_to_response( buf ); } @@ -2570,9 +2576,9 @@ start_request( void ) } static void -add_to_request( char* str, size_t len ) +add_to_request( char* str ) { - add_to_buf( &request, &request_size, &request_len, str, len ); + add_str( &request, &request_size, &request_len, str ); } static char* @@ -2611,9 +2617,9 @@ start_response( void ) } static void -add_to_response( char* str, size_t len ) +add_to_response( char* str ) { - add_to_buf( &response, &response_size, &response_len, str, len ); + add_str( &response, &response_size, &response_len, str ); } static void @@ -2777,8 +2783,15 @@ my_sendfile( int fd, int s, off_t offset, size_t nbytes ) static void -add_to_buf( char** bufP, size_t* bufsizeP, size_t* buflenP, char* str, size_t len ) +add_str( char** bufP, size_t* bufsizeP, size_t* buflenP, char* str ) { + size_t len; + + if ( str == (char*) 0 ) + len = 0; + else + len = strlen( str ); + if ( *bufsizeP == 0 ) { *bufsizeP = len + 500; @@ -2790,8 +2803,13 @@ add_to_buf( char** bufP, size_t* bufsizeP, size_t* buflenP, char* str, size_t le *bufsizeP = *buflenP + len + 500; *bufP = (char*) e_realloc( (void*) *bufP, *bufsizeP ); } - (void) memmove( &((*bufP)[*buflenP]), str, len ); - *buflenP += len; + + if ( len > 0 ) + { + (void) memmove( &((*bufP)[*buflenP]), str, len ); + *buflenP += len; + } + (*bufP)[*buflenP] = '\0'; } @@ -3405,7 +3423,7 @@ ntoa( usockaddr* usaP ) } else if ( IN6_IS_ADDR_V4MAPPED( &usaP->sa_in6.sin6_addr ) && strncmp( str, "::ffff:", 7 ) == 0 ) /* Elide IPv6ish prefix for IPv4 addresses. */ - (void) strcpy( str, &str[7] ); + (void) ol_strcpy( str, &str[7] ); return str; diff --git a/port.h b/port.h index 7d451a9..f11aaef 100644 --- a/port.h +++ b/port.h @@ -12,7 +12,7 @@ #elif defined(linux) # define OS_Linux # define ARCH "Linux" -#elif defined(sun) +#elif defined(sun) || defined(SunOS) || defined(Solaris) || defined(__sun__) # define OS_Solaris # define ARCH "Solaris" #elif defined(__osf__) @@ -88,6 +88,8 @@ # define HAVE_SIGSET # define HAVE_INT64T # define HAVE_RAND +# define HAVE_SENDFILE +# define HAVE_LINUX_SENDFILE #endif /* OS_Solaris */ #ifdef OS_DigitalUnix @@ -106,7 +108,7 @@ # define HAVE_MEMORY_H # define HAVE_SIGSET # define HAVE_RAND -#endif /* OS_Solaris */ +#endif /* OS_SysV */ #ifdef HAVE_RAND # define srandom srand diff --git a/version.h b/version.h index b94e6a9..22b8730 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,7 @@ #ifndef _VERSION_H_ #define _VERSION_H_ -#define SERVER_SOFTWARE "mini_httpd/1.21 18oct2014" +#define SERVER_SOFTWARE "mini_httpd/1.23 28Dec2015" #define SERVER_URL "http://www.acme.com/software/mini_httpd/" #endif /* _VERSION_H_ */ -- cgit v1.2.3