Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
31 changes: 31 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -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/
2 changes: 1 addition & 1 deletion contrib/redhat-rpm/thttpd.spec
Original file line number Diff line number Diff line change
@@ -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
Expand Down
99 changes: 49 additions & 50 deletions libhttpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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;
}
Expand All @@ -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 )
{
Expand Down Expand Up @@ -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 ) )
Expand Down
3 changes: 3 additions & 0 deletions libhttpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */