diff --git a/INSTALL b/INSTALL index 7b15219..a9c9e9b 100644 --- a/INSTALL +++ b/INSTALL @@ -20,9 +20,9 @@ Red Hat: On Red Hat Linux systems you can use RPM to install thttpd, like so: cd /usr/src/redhat/SOURCES - wget http://www.acme.com/software/thttpd/thttpd-2.28.tar.gz - rpm -ta thttpd-2.28.tar.gz - rpm -i /usr/src/redhat/RPMS/i386/thttpd-2.28-1.i386.rpm + wget http://www.acme.com/software/thttpd/thttpd-2.29.tar.gz + rpm -ta thttpd-2.29.tar.gz + rpm -i /usr/src/redhat/RPMS/i386/thttpd-2.29-1.i386.rpm Solaris: diff --git a/README b/README new file mode 100644 index 0000000..a63f49e --- /dev/null +++ b/README @@ -0,0 +1,31 @@ + thttpd - tiny/turbo/throttling HTTP server + version 2.29 of 23May2018 + +thttpd is a simple, small, portable, fast, and secure HTTP server. + +Simple: It handles only the minimum necessary to implement HTTP/1.1. + +Small: See the size comparison chart at +http://www.acme.com/software/thttpd/notes.html#sizes. It also has a +very small run-time size, since it does not fork and is very careful about +memory allocation. + +Portable: It compiles cleanly on FreeBSD 2.x/3.x, SunOS 4.1.x, Solaris 2.x, +BSD/OS 2.x, Linux 1.2.x, OSF/1 (on a 64-bit Alpha), and no doubt many others. + +Fast: In typical use it's about as fast as the best full-featured servers +(Apache, NCSA, Netscape). Under extreme load it's much faster. + +Secure: It goes to great lengths to protect the web server machine +against attacks and breakins from other sites. + +It also has one extremely useful feature (URL-traffic-based throttling) that +no other server currently has. + +See the manual entry for more details. See the INSTALL file for +configuration and installation instructions. Check the web page +(http://www.acme.com/software/thttpd/) for updates, or add yourself to +the mailing list by sending a "subscribe" to thttpd-announce-request@mail.acme.com. + +Comments to: + Jef Poskanzer jef@mail.acme.com http://www.acme.com/jef/ diff --git a/contrib/redhat-rpm/thttpd.spec b/contrib/redhat-rpm/thttpd.spec index 4b5b3d8..6ee0fee 100644 --- a/contrib/redhat-rpm/thttpd.spec +++ b/contrib/redhat-rpm/thttpd.spec @@ -1,6 +1,6 @@ Summary: Throttleable lightweight httpd server Name: thttpd -Version: 2.28 +Version: 2.29 Release: 1 Group: Networking URL: http://www.acme.com/software/thttpd diff --git a/libhttpd.c b/libhttpd.c index 3814e6a..c6b1622 100644 --- a/libhttpd.c +++ b/libhttpd.c @@ -1210,6 +1210,9 @@ httpd_method_str( int method ) case METHOD_GET: return "GET"; case METHOD_HEAD: return "HEAD"; case METHOD_POST: return "POST"; + case METHOD_PUT: return "PUT"; + case METHOD_DELETE: return "DELETE"; + case METHOD_TRACE: return "TRACE"; default: return "UNKNOWN"; } } @@ -2028,6 +2031,12 @@ httpd_parse_request( httpd_conn* hc ) hc->method = METHOD_HEAD; else if ( strcasecmp( method_str, httpd_method_str( METHOD_POST ) ) == 0 ) hc->method = METHOD_POST; + else if ( strcasecmp( method_str, httpd_method_str( METHOD_PUT ) ) == 0 ) + hc->method = METHOD_PUT; + else if ( strcasecmp( method_str, httpd_method_str( METHOD_DELETE ) ) == 0 ) + hc->method = METHOD_DELETE; + else if ( strcasecmp( method_str, httpd_method_str( METHOD_TRACE ) ) == 0 ) + hc->method = METHOD_TRACE; else { httpd_send_err( hc, 501, err501title, "", err501form, method_str ); @@ -3567,54 +3576,45 @@ cgi( httpd_conn* hc ) int r; ClientData client_data; - if ( hc->method == METHOD_GET || hc->method == METHOD_POST ) + if ( hc->hs->cgi_limit != 0 && hc->hs->cgi_count >= hc->hs->cgi_limit ) { - if ( hc->hs->cgi_limit != 0 && hc->hs->cgi_count >= hc->hs->cgi_limit ) - { - httpd_send_err( - hc, 503, httpd_err503title, "", httpd_err503form, - hc->encodedurl ); - return -1; - } - ++hc->hs->cgi_count; - httpd_clear_ndelay( hc->conn_fd ); - r = fork( ); - if ( r < 0 ) - { - syslog( LOG_ERR, "fork - %m" ); - httpd_send_err( - hc, 500, err500title, "", err500form, hc->encodedurl ); - return -1; - } - if ( r == 0 ) - { - /* Child process. */ - sub_process = 1; - httpd_unlisten( hc->hs ); - cgi_child( hc ); - } - - /* Parent process. */ - syslog( LOG_DEBUG, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename ); -#ifdef CGI_TIMELIMIT - /* Schedule a kill for the child process, in case it runs too long */ - client_data.i = r; - if ( tmr_create( (struct timeval*) 0, cgi_kill, client_data, CGI_TIMELIMIT * 1000L, 0 ) == (Timer*) 0 ) - { - syslog( LOG_CRIT, "tmr_create(cgi_kill child) failed" ); - exit( 1 ); - } -#endif /* CGI_TIMELIMIT */ - hc->status = 200; - hc->bytes_sent = CGI_BYTECOUNT; - hc->should_linger = 0; + httpd_send_err( + hc, 503, httpd_err503title, "", httpd_err503form, + hc->encodedurl ); + return -1; } - else + ++hc->hs->cgi_count; + httpd_clear_ndelay( hc->conn_fd ); + r = fork( ); + if ( r < 0 ) { + syslog( LOG_ERR, "fork - %m" ); httpd_send_err( - hc, 501, err501title, "", err501form, httpd_method_str( hc->method ) ); + hc, 500, err500title, "", err500form, hc->encodedurl ); return -1; } + if ( r == 0 ) + { + /* Child process. */ + sub_process = 1; + httpd_unlisten( hc->hs ); + cgi_child( hc ); + } + + /* Parent process. */ + syslog( LOG_DEBUG, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename ); +#ifdef CGI_TIMELIMIT + /* Schedule a kill for the child process, in case it runs too long */ + client_data.i = r; + if ( tmr_create( (struct timeval*) 0, cgi_kill, client_data, CGI_TIMELIMIT * 1000L, 0 ) == (Timer*) 0 ) + { + syslog( LOG_CRIT, "tmr_create(cgi_kill child) failed" ); + exit( 1 ); + } +#endif /* CGI_TIMELIMIT */ + hc->status = 200; + hc->bytes_sent = CGI_BYTECOUNT; + hc->should_linger = 0; return 0; } @@ -3637,14 +3637,6 @@ really_start_request( httpd_conn* hc, struct timeval* nowP ) expnlen = strlen( hc->expnfilename ); - if ( hc->method != METHOD_GET && hc->method != METHOD_HEAD && - hc->method != METHOD_POST ) - { - httpd_send_err( - hc, 501, err501title, "", err501form, httpd_method_str( hc->method ) ); - return -1; - } - /* Stat the file. */ if ( stat( hc->expnfilename, &hc->sb ) < 0 ) { @@ -3855,6 +3847,13 @@ really_start_request( httpd_conn* hc, struct timeval* nowP ) return -1; } + if ( hc->method != METHOD_GET && hc->method != METHOD_HEAD ) + { + httpd_send_err( + hc, 501, err501title, "", err501form, httpd_method_str( hc->method ) ); + return -1; + } + /* Fill in last_byte_index, if necessary. */ if ( hc->got_range && ( hc->last_byte_index == -1 || hc->last_byte_index >= hc->sb.st_size ) ) diff --git a/libhttpd.h b/libhttpd.h index 7805546..e707bc7 100644 --- a/libhttpd.h +++ b/libhttpd.h @@ -152,6 +152,9 @@ typedef struct { #define METHOD_GET 1 #define METHOD_HEAD 2 #define METHOD_POST 3 +#define METHOD_PUT 4 +#define METHOD_DELETE 5 +#define METHOD_TRACE 6 /* States for checked_state. */ #define CHST_FIRSTWORD 0 diff --git a/version.h b/version.h index d0ea258..8d841b9 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,7 @@ #ifndef _VERSION_H_ #define _VERSION_H_ -#define SERVER_SOFTWARE "thttpd/2.28 04Feb2018" +#define SERVER_SOFTWARE "thttpd/2.29 23May2018" #define SERVER_ADDRESS "http://www.acme.com/software/thttpd/" #endif /* _VERSION_H_ */