⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thttpd_patch

📁 php-4.4.7学习linux时下载的源代码
💻
📖 第 1 页 / 共 5 页
字号:
 /* Done with an mmap()ed area that was returned by mmc_map(). ** If you have a stat buffer on the file, pass it in, otherwise pass 0.diff -ur thttpd-2.21b/thttpd.c thttpd-2.21b-cool/thttpd.c--- thttpd-2.21b/thttpd.c	Tue Apr 24 00:41:57 2001+++ thttpd-2.21b-cool/thttpd.c	Sat Sep 20 14:43:20 2003@@ -53,6 +53,10 @@ #endif #include <unistd.h> +#include <sys/mman.h>++#include <limits.h>+ #include "fdwatch.h" #include "libhttpd.h" #include "mmc.h"@@ -66,6 +70,8 @@ static char* dir; static int do_chroot, no_log, no_symlink, do_vhost, do_global_passwd; static char* cgi_pattern;+static char* php_pattern;+static char* phps_pattern; static char* url_pattern; static int no_empty_referers; static char* local_pattern;@@ -95,10 +101,10 @@     httpd_conn* hc;     int tnums[MAXTHROTTLENUMS];         /* throttle indexes */     int numtnums;+    int keep_alive;     long limit;     time_t started_at;-    Timer* idle_read_timer;-    Timer* idle_send_timer;+    time_t last_io;     Timer* wakeup_timer;     Timer* linger_timer;     long wouldblock_delay;@@ -106,17 +112,22 @@     off_t bytes_sent;     off_t bytes_to_send;     } connecttab;-static connecttab* connects;+static connecttab* connects, **free_connects;+static int next_free_connect; static int numconnects, maxconnects; static int httpd_conn_count;  /* The connection states. */-#define CNST_FREE 0-#define CNST_READING 1-#define CNST_SENDING 2-#define CNST_PAUSING 3-#define CNST_LINGERING 4-+enum {+	CNST_FREE = 0,+	CNST_READING,+	CNST_SENDING,+	CNST_PAUSING,+	CNST_LINGERING,+	CNST_SENDING_RESP,+	CNST_READING_BODY,+	CNST_TOTAL_NR+};  static httpd_server* hs = (httpd_server*) 0; int terminate = 0;@@ -140,23 +151,32 @@ static int handle_newconnect( struct timeval* tvP, int listen_fd ); static void handle_read( connecttab* c, struct timeval* tvP ); static void handle_send( connecttab* c, struct timeval* tvP );+static void handle_send_resp( connecttab* c, struct timeval* tvP );+static void handle_read_body( connecttab* c, struct timeval* tvP ); static void handle_linger( connecttab* c, struct timeval* tvP ); static int check_throttles( connecttab* c );+static void timeout_conns( ClientData client_data, struct timeval* nowP ); static void clear_throttles( connecttab* c, struct timeval* tvP ); static void update_throttles( ClientData client_data, struct timeval* nowP );-static void clear_connection( connecttab* c, struct timeval* tvP );+static void clear_connection( connecttab* c, struct timeval* tvP, int ); static void really_clear_connection( connecttab* c, struct timeval* tvP );-static void idle_read_connection( ClientData client_data, struct timeval* nowP );-static void idle_send_connection( ClientData client_data, struct timeval* nowP ); static void wakeup_connection( ClientData client_data, struct timeval* nowP ); static void linger_clear_connection( ClientData client_data, struct timeval* nowP ); static void occasional( ClientData client_data, struct timeval* nowP );+static void periodic_jobs( ClientData client_data, struct timeval* nowP ); #ifdef STATS_TIME static void show_stats( ClientData client_data, struct timeval* nowP ); #endif /* STATS_TIME */ static void logstats( struct timeval* nowP ); static void thttpd_logstats( long secs );+static void boot_request(connecttab *c, struct timeval *tvP);++typedef void (*handler_func)(connecttab*, struct timeval *);++handler_func handler_array[CNST_TOTAL_NR] =+{NULL, handle_read, handle_send, NULL, handle_linger, handle_send_resp, handle_read_body}; +#define RUN_HANDLER(type, c) if (handler_array[type]) handler_array[type](c, &tv)  static void handle_term( int sig )@@ -177,7 +197,7 @@ 	return;      /* Re-open the log file. */-    if ( logfile != (char*) 0 )+    if ( logfile != (char*) 0 && strcmp(logfile, "-") != 0) 	{ 	logfp = fopen( logfile, "a" ); 	if ( logfp == (FILE*) 0 )@@ -198,6 +218,8 @@     }  +time_t httpd_time_now;+ static void handle_usr2( int sig )     {@@ -217,7 +239,6 @@     int num_ready;     int cnum, ridx;     connecttab* c;-    httpd_conn* hc;     httpd_sockaddr sa4;     httpd_sockaddr sa6;     int gotv4, gotv6;@@ -270,7 +291,9 @@ 	    no_log = 1; 	    logfp = (FILE*) 0; 	    }-	else+	else if (strcmp(logfile, "-") == 0) {+		logfp = stdout;+	} else 	    { 	    logfp = fopen( logfile, "a" ); 	    if ( logfp == (FILE*) 0 )@@ -420,7 +443,8 @@ 	hostname, 	gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0, 	port, cgi_pattern, charset, cwd, no_log, logfp, no_symlink, do_vhost,-	do_global_passwd, url_pattern, local_pattern, no_empty_referers );+	do_global_passwd, url_pattern, local_pattern, no_empty_referers,+	php_pattern, phps_pattern);     if ( hs == (httpd_server*) 0 ) 	exit( 1 ); @@ -430,6 +454,12 @@ 	syslog( LOG_CRIT, "tmr_create(occasional) failed" ); 	exit( 1 ); 	}++	if (tmr_create(0, timeout_conns, JunkClientData, 30 * 1000, 1) == 0) {+		syslog(LOG_CRIT, "tmr_create(timeout_conns) failed");+		exit(1);+	}+     if ( numthrottles > 0 ) 	{ 	/* Set up the throttles timer. */@@ -439,6 +469,12 @@ 	    exit( 1 ); 	    } 	}++	if (tmr_create(0, periodic_jobs, JunkClientData, 2000, 1) == 0) {+		syslog(LOG_CRIT, "tmr_create failed");+		exit(1);+	}+	 #ifdef STATS_TIME     /* Set up the stats timer. */     if ( tmr_create( (struct timeval*) 0, show_stats, JunkClientData, STATS_TIME * 1000L, 1 ) == (Timer*) 0 )@@ -454,12 +490,14 @@     /* If we're root, try to become someone else. */     if ( getuid() == 0 ) 	{+#ifndef __CYGWIN__ 	/* Set aux groups to null. */ 	if ( setgroups( 0, (const gid_t*) 0 ) < 0 ) 	    { 	    syslog( LOG_CRIT, "setgroups - %m" ); 	    exit( 1 ); 	    }+#endif 	/* Set primary group. */ 	if ( setgid( gid ) < 0 ) 	    {@@ -495,13 +533,17 @@ 	}     maxconnects -= SPARE_FDS;     connects = NEW( connecttab, maxconnects );+    free_connects = malloc(sizeof(connecttab *) * maxconnects);+    next_free_connect = maxconnects;     if ( connects == (connecttab*) 0 ) 	{ 	syslog( LOG_CRIT, "out of memory allocating a connecttab" ); 	exit( 1 ); 	}+	     for ( cnum = 0; cnum < maxconnects; ++cnum ) 	{+	free_connects[cnum] = &connects[maxconnects - cnum - 1]; 	connects[cnum].conn_state = CNST_FREE; 	connects[cnum].hc = (httpd_conn*) 0; 	}@@ -518,6 +560,9 @@      /* Main loop. */     (void) gettimeofday( &tv, (struct timezone*) 0 );+    httpd_time_now = tv.tv_sec;+	periodic_jobs(JunkClientData, &tv);+     while ( ( ! terminate ) || numconnects > 0 ) 	{ 	/* Do the fd watch. */@@ -530,6 +575,7 @@ 	    exit( 1 ); 	    } 	(void) gettimeofday( &tv, (struct timezone*) 0 );+    httpd_time_now = tv.tv_sec; 	if ( num_ready == 0 ) 	    { 	    /* No fd's are ready - run the timers. */@@ -565,16 +611,10 @@ 	    c = (connecttab*) fdwatch_get_client_data( ridx ); 	    if ( c == (connecttab*) 0 ) 		continue;-	    hc = c->hc;-	    if ( c->conn_state == CNST_READING &&-		 fdwatch_check_fd( hc->conn_fd ) )-		handle_read( c, &tv );-	    else if ( c->conn_state == CNST_SENDING &&-		 fdwatch_check_fd( hc->conn_fd ) )-		handle_send( c, &tv );-	    else if ( c->conn_state == CNST_LINGERING &&-		 fdwatch_check_fd( hc->conn_fd ) )-		handle_linger( c, &tv );+#if DO_UNNECESSARY_CHECK_FD+	    fdwatch_check_fd(c->hc->conn_fd);+#endif+	    RUN_HANDLER(c->conn_state, c); 	    } 	tmr_run( &tv ); @@ -627,6 +667,8 @@ #else /* CGI_PATTERN */     cgi_pattern = (char*) 0; #endif /* CGI_PATTERN */+    php_pattern = "**.php";+    phps_pattern = "**.phps";     url_pattern = (char*) 0;     no_empty_referers = 0;     local_pattern = (char*) 0;@@ -833,6 +875,16 @@ 		value_required( name, value ); 		cgi_pattern = e_strdup( value ); 		}+	    else if ( strcasecmp( name, "phppat" ) == 0 )+		{+		value_required( name, value );+		php_pattern = e_strdup( value );+		}+	    else if ( strcasecmp( name, "phpspat" ) == 0 )+		{+		value_required( name, value );+		phps_pattern = e_strdup( value );+		} 	    else if ( strcasecmp( name, "urlpat" ) == 0 ) 		{ 		value_required( name, value );@@ -1196,8 +1248,10 @@     logstats( &tv );     for ( cnum = 0; cnum < maxconnects; ++cnum ) 	{-	if ( connects[cnum].conn_state != CNST_FREE )+	if ( connects[cnum].conn_state != CNST_FREE ) {+	    httpd_complete_request( connects[cnum].hc, &tv ); 	    httpd_close_conn( connects[cnum].hc, &tv );+	} 	if ( connects[cnum].hc != (httpd_conn*) 0 ) 	    { 	    httpd_destroy_conn( connects[cnum].hc );@@ -1214,6 +1268,7 @@ 	}     mmc_destroy();     tmr_destroy();+    free( (void*) free_connects );     free( (void*) connects );     if ( throttles != (throttletab*) 0 ) 	free( (void*) throttles );@@ -1234,7 +1289,7 @@     for (;;) 	{ 	/* Is there room in the connection table? */-	if ( numconnects >= maxconnects )+	if ( numconnects >= maxconnects || next_free_connect == 0 ) 	    { 	    /* Out of connection slots.  Run the timers, then the 	    ** existing connections, and maybe we'll free up a slot@@ -1245,10 +1300,10 @@ 	    return 0; 	    } 	/* Find a free connection entry. */-	for ( cnum = 0; cnum < maxconnects; ++cnum )-	    if ( connects[cnum].conn_state == CNST_FREE )-		break;-	c = &connects[cnum];++	c = free_connects[--next_free_connect];+	free_connects[next_free_connect] = NULL;+ 	/* Make the httpd_conn if necessary. */ 	if ( c->hc == (httpd_conn*) 0 ) 	    {@@ -1267,24 +1322,18 @@ 	    { 	    case GC_FAIL: 	    case GC_NO_MORE:+		free_connects[next_free_connect++] = c; 	    return 1; 	    } 	c->conn_state = CNST_READING; 	++numconnects; 	client_data.p = c;-	c->idle_read_timer = tmr_create(-	    tvP, idle_read_connection, client_data, IDLE_READ_TIMELIMIT * 1000L,-	    0 );-	if ( c->idle_read_timer == (Timer*) 0 )-	    {-	    syslog( LOG_CRIT, "tmr_create(idle_read_connection) failed" );-	    exit( 1 );-	    }-	c->idle_send_timer = (Timer*) 0; 	c->wakeup_timer = (Timer*) 0; 	c->linger_timer = (Timer*) 0; 	c->bytes_sent = 0; 	c->numtnums = 0;+	c->keep_alive = 0;+	c->last_io = httpd_time_now;  	/* Set the connection file descriptor to no-delay mode. */ 	httpd_set_ndelay( c->hc->conn_fd );@@ -1298,11 +1347,100 @@     }  +#define FIXUP(x) if (hc->x >= oldptr && hc->x < pe) hc->x += d++static void+realign_hc(httpd_conn *hc, char *oldptr)+{+	int d = hc->read_buf - oldptr;+	char *pe = oldptr + hc->checked_idx;++	FIXUP(encodedurl);+	FIXUP(protocol);+	FIXUP(referer);+	FIXUP(useragent);+	FIXUP(acceptl);+	FIXUP(cookie);+	FIXUP(contenttype);+	FIXUP(hdrhost);+	FIXUP(authorization);+}++#undef FIXUP++static void+setup_read_body(connecttab *c, struct timeval *tvP) +{+	httpd_conn *hc = c->hc;+	int already, missing;+	char *oldptr = hc->read_buf;+	+	c->conn_state = CNST_READING_BODY;++	hc->read_body_into_mem = 0;+	+	already = hc->read_idx - hc->checked_idx;+	missing = hc->contentlength - already;++	if (missing > 16384) {+		char filename[] = "/tmp/thttpd.upload.XXXXXX";+		int tmp = mkstemp(filename);+		+		if (tmp >= 0) {+			void *p;+			size_t sz = hc->contentlength + hc->checked_idx + 10;++			unlink(filename);++			ftruncate(tmp, sz);+			p = mmap(NULL, sz,+					PROT_READ|PROT_WRITE, MAP_PRIVATE, tmp, 0);++			if (p != MAP_FAILED) {+				memcpy(p, hc->read_buf, hc->read_idx);+				free(hc->read_buf);+				hc->read_size = sz;+				hc->read_buf = p;+				hc->read_buf_is_mmap = 1;+			}+			close(tmp);+		}+	+		if (!hc->read_buf_is_mmap) {+			clear_connection( c, tvP, 0 );+			return;+		}+	} else if (missing > 0) {+		httpd_realloc_str(&hc->read_buf, &hc->read_size, hc->checked_idx + hc->contentlength + 10);+	}+	if (oldptr != hc->read_buf) realign_hc(hc, oldptr);++    fdwatch_del_fd( hc->conn_fd );+    fdwatch_add_fd( hc->conn_fd, c, FDW_READ );+}++static void+setup_sending(connecttab *c, int state, struct timeval *tvP)+{+    httpd_conn *hc = c->hc;+    ClientData client_data;++    c->conn_state = state;+    c->started_at = tvP->tv_sec;+    c->wouldblock_delay = 0;+    client_data.p = c;++    fdwatch_del_fd( hc->conn_fd );+    fdwatch_add_fd( hc->conn_fd, c, FDW_WRITE );+}++static void handle_request( connecttab *c, struct timeval *tvP);++ static void handle_read( connecttab* c, struct timeval* tvP )     {     int sz;-    ClientData client_data;     httpd_conn* hc = c->hc;      /* Is there room in our buffer to read more bytes? */@@ -1311,7 +1449,7 @@ 	if ( hc->read_size > 5000 ) 	    { 	    httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );-	    clear_connection( c, tvP );+	    clear_connection( c, tvP, 0 ); 	    return; 	    } 	httpd_realloc_str(@@ -1327,14 +1465,53 @@     ** EWOULDBLOCK; however, this apparently can happen if a packet gets     ** garbled.     */-    if ( sz == 0 || ( sz < 0 && ( errno != EWOULDBLOCK ) ) )-	{-	httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );-	clear_connection( c, tvP );+    if ( sz == 0 ) {+    	if (! c->keep_alive) {+		httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );+	}+	clear_connection( c, tvP, 0 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -