thttpd_patch 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377
  1. diff -ur thttpd-2.21b/Makefile.in thttpd-2.21b-cool/Makefile.in
  2. --- thttpd-2.21b/Makefile.in Thu Mar 29 20:36:21 2001
  3. +++ thttpd-2.21b-cool/Makefile.in Sat Sep 20 14:43:20 2003
  4. @@ -46,13 +46,15 @@
  5. # You shouldn't need to edit anything below here.
  6. +include php_makefile
  7. +
  8. CC = @CC@
  9. CCOPT = @V_CCOPT@
  10. DEFS = @DEFS@
  11. -INCLS = -I.
  12. +INCLS = -I. $(PHP_CFLAGS)
  13. CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
  14. -LDFLAGS = @LDFLAGS@
  15. -LIBS = @LIBS@
  16. +LDFLAGS = @LDFLAGS@ $(PHP_LDFLAGS)
  17. +LIBS = @LIBS@ $(PHP_LIBS)
  18. NETLIBS = @V_NETLIBS@
  19. INSTALL = @INSTALL@
  20. @@ -62,7 +64,7 @@
  21. @rm -f $@
  22. $(CC) $(CFLAGS) -c $*.c
  23. -SRC = thttpd.c libhttpd.c fdwatch.c mmc.c timers.c match.c tdate_parse.c syslog.c
  24. +SRC = thttpd.c libhttpd.c fdwatch.c mmc.c timers.c match.c tdate_parse.c syslog.c php_thttpd.c
  25. OBJ = $(SRC:.c=.o) @LIBOBJS@
  26. @@ -77,7 +79,7 @@
  27. all: this subdirs
  28. this: $(ALL)
  29. -thttpd: $(OBJ)
  30. +thttpd: $(OBJ) libphp5.a
  31. @rm -f $@
  32. $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(NETLIBS)
  33. diff -ur thttpd-2.21b/config.h thttpd-2.21b-cool/config.h
  34. --- thttpd-2.21b/config.h Mon Apr 9 23:57:36 2001
  35. +++ thttpd-2.21b-cool/config.h Sat Sep 20 14:43:20 2003
  36. @@ -82,6 +82,11 @@
  37. */
  38. #define IDLE_READ_TIMELIMIT 60
  39. +/* CONFIGURE: How many seconds to allow for reading the subsequent requests
  40. +** on a keep-alive connection. Should be simiar to LINGER_TIME
  41. +*/
  42. +#define IDLE_KEEPALIVE_TIMELIMIT 2
  43. +
  44. /* CONFIGURE: How many seconds before an idle connection gets closed.
  45. */
  46. #define IDLE_SEND_TIMELIMIT 300
  47. @@ -316,7 +321,7 @@
  48. /* CONFIGURE: A list of index filenames to check. The files are searched
  49. ** for in this order.
  50. */
  51. -#define INDEX_NAMES "index.html", "index.htm", "Default.htm", "index.cgi"
  52. +#define INDEX_NAMES "index.php", "index.html", "index.htm", "Default.htm", "index.cgi"
  53. /* CONFIGURE: If this is defined then thttpd will automatically generate
  54. ** index pages for directories that don't have an explicit index file.
  55. diff -ur thttpd-2.21b/configure thttpd-2.21b-cool/configure
  56. --- thttpd-2.21b/configure Sat Apr 21 02:07:14 2001
  57. +++ thttpd-2.21b-cool/configure Sat Sep 20 14:43:20 2003
  58. @@ -1021,7 +1021,7 @@
  59. fi
  60. echo "$ac_t""$CPP" 1>&6
  61. -for ac_hdr in fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h
  62. +for ac_hdr in fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h netinet/tcp.h
  63. do
  64. ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
  65. echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
  66. diff -ur thttpd-2.21b/configure.in thttpd-2.21b-cool/configure.in
  67. --- thttpd-2.21b/configure.in Sat Apr 21 02:06:23 2001
  68. +++ thttpd-2.21b-cool/configure.in Sat Sep 20 14:43:20 2003
  69. @@ -64,7 +64,7 @@
  70. AC_MSG_RESULT(no)
  71. fi
  72. -AC_CHECK_HEADERS(fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h)
  73. +AC_CHECK_HEADERS(fcntl.h grp.h memory.h paths.h poll.h sys/poll.h sys/event.h osreldate.h netinet/tcp.h)
  74. AC_HEADER_TIME
  75. AC_HEADER_DIRENT
  76. diff -ur thttpd-2.21b/fdwatch.c thttpd-2.21b-cool/fdwatch.c
  77. --- thttpd-2.21b/fdwatch.c Fri Apr 13 07:36:08 2001
  78. +++ thttpd-2.21b-cool/fdwatch.c Sat Sep 20 14:43:20 2003
  79. @@ -419,6 +419,7 @@
  80. if ( pollfds == (struct pollfd*) 0 || poll_fdidx == (int*) 0 ||
  81. poll_rfdidx == (int*) 0 )
  82. return -1;
  83. + memset(pollfds, 0, sizeof(struct pollfd) * nfiles);
  84. return 0;
  85. }
  86. @@ -460,7 +461,7 @@
  87. ridx = 0;
  88. for ( i = 0; i < npollfds; ++i )
  89. - if ( pollfds[i].revents & ( POLLIN | POLLOUT ) )
  90. + if ( pollfds[i].revents & ( POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL ) )
  91. poll_rfdidx[ridx++] = pollfds[i].fd;
  92. return r;
  93. @@ -472,8 +473,8 @@
  94. {
  95. switch ( fd_rw[fd] )
  96. {
  97. - case FDW_READ: return pollfds[poll_fdidx[fd]].revents & POLLIN;
  98. - case FDW_WRITE: return pollfds[poll_fdidx[fd]].revents & POLLOUT;
  99. + case FDW_READ: return pollfds[poll_fdidx[fd]].revents & ( POLLIN | POLLERR | POLLHUP | POLLNVAL );
  100. + case FDW_WRITE: return pollfds[poll_fdidx[fd]].revents & ( POLLOUT | POLLERR | POLLHUP | POLLNVAL );
  101. default: return 0;
  102. }
  103. }
  104. diff -ur thttpd-2.21b/libhttpd.c thttpd-2.21b-cool/libhttpd.c
  105. --- thttpd-2.21b/libhttpd.c Tue Apr 24 00:42:40 2001
  106. +++ thttpd-2.21b-cool/libhttpd.c Sat Sep 20 14:43:29 2003
  107. @@ -56,6 +56,10 @@
  108. #include <unistd.h>
  109. #include <stdarg.h>
  110. +#ifdef HAVE_NETINET_TCP_H
  111. +#include <netinet/tcp.h>
  112. +#endif
  113. +
  114. #ifdef HAVE_OSRELDATE_H
  115. #include <osreldate.h>
  116. #endif /* HAVE_OSRELDATE_H */
  117. @@ -85,6 +89,12 @@
  118. #include "match.h"
  119. #include "tdate_parse.h"
  120. +#include "php_thttpd.h"
  121. +
  122. +#ifdef __CYGWIN__
  123. +# define timezone _timezone
  124. +#endif
  125. +
  126. #ifndef STDIN_FILENO
  127. #define STDIN_FILENO 0
  128. #endif
  129. @@ -111,7 +121,7 @@
  130. static int initialize_listen_socket( httpd_sockaddr* saP );
  131. static void unlisten( httpd_server* hs );
  132. static void add_response( httpd_conn* hc, char* str );
  133. -static void send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod );
  134. +static void send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod, const char *, size_t );
  135. static void send_response( httpd_conn* hc, int status, char* title, char* extraheads, char* form, char* arg );
  136. static void send_response_tail( httpd_conn* hc );
  137. static void defang( char* str, char* dfstr, int dfsize );
  138. @@ -242,6 +252,10 @@
  139. free( (void*) hs->cwd );
  140. if ( hs->cgi_pattern != (char*) 0 )
  141. free( (void*) hs->cgi_pattern );
  142. + if ( hs->php_pattern != (char*) 0 )
  143. + free( (void*) hs->php_pattern );
  144. + if ( hs->phps_pattern != (char*) 0 )
  145. + free( (void*) hs->phps_pattern );
  146. if ( hs->charset != (char*) 0 )
  147. free( (void*) hs->charset );
  148. if ( hs->url_pattern != (char*) 0 )
  149. @@ -249,6 +263,7 @@
  150. if ( hs->local_pattern != (char*) 0 )
  151. free( (void*) hs->local_pattern );
  152. free( (void*) hs );
  153. + thttpd_php_shutdown();
  154. }
  155. @@ -257,7 +272,8 @@
  156. char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port,
  157. char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp,
  158. int no_symlink, int vhost, int global_passwd, char* url_pattern,
  159. - char* local_pattern, int no_empty_referers )
  160. + char* local_pattern, int no_empty_referers, char* php_pattern,
  161. + char* phps_pattern )
  162. {
  163. httpd_server* hs;
  164. static char ghnbuf[256];
  165. @@ -312,6 +328,8 @@
  166. }
  167. hs->port = port;
  168. + hs->php_pattern = strdup(php_pattern);
  169. + hs->phps_pattern = strdup(phps_pattern);
  170. if ( cgi_pattern == (char*) 0 )
  171. hs->cgi_pattern = (char*) 0;
  172. else
  173. @@ -329,7 +347,7 @@
  174. while ( ( cp = strstr( hs->cgi_pattern, "|/" ) ) != (char*) 0 )
  175. (void) strcpy( cp + 1, cp + 2 );
  176. }
  177. - hs->charset = strdup( charset );
  178. + hs->charset = strdup( charset );
  179. hs->cwd = strdup( cwd );
  180. if ( hs->cwd == (char*) 0 )
  181. {
  182. @@ -385,6 +403,8 @@
  183. return (httpd_server*) 0;
  184. }
  185. + thttpd_php_init();
  186. +
  187. /* Done initializing. */
  188. if ( hs->binding_hostname == (char*) 0 )
  189. syslog( LOG_INFO, "%.80s starting on port %d", SERVER_SOFTWARE, hs->port );
  190. @@ -418,6 +438,11 @@
  191. }
  192. (void) fcntl( listen_fd, F_SETFD, 1 );
  193. +#if defined(TCP_DEFER_ACCEPT) && defined(SOL_TCP)
  194. + on = 30; /* give clients 30s to send first data packet */
  195. + setsockopt(listen_fd, SOL_TCP, TCP_DEFER_ACCEPT, &on, sizeof(on));
  196. +#endif
  197. +
  198. /* Allow reuse of local addresses. */
  199. on = 1;
  200. if ( setsockopt(
  201. @@ -582,6 +607,9 @@
  202. /* And send it, if necessary. */
  203. if ( hc->responselen > 0 )
  204. {
  205. +/*
  206. +printf("**RESPONSE [%d]** len = %d\n%*.*s\n", hc->conn_fd, hc->responselen, hc->responselen, hc->responselen, hc->response);
  207. +*/
  208. (void) write( hc->conn_fd, hc->response, hc->responselen );
  209. hc->responselen = 0;
  210. }
  211. @@ -619,18 +647,22 @@
  212. }
  213. }
  214. +extern time_t httpd_time_now;
  215. +extern char httpd_now_buf[];
  216. +
  217. +#define SMART_STR_USE_REALLOC
  218. +
  219. +#include "ext/standard/php_smart_str.h"
  220. static void
  221. -send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod )
  222. +send_mime( httpd_conn* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod, const char *last_modified, size_t last_modified_len)
  223. {
  224. - time_t now;
  225. const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
  226. - char nowbuf[100];
  227. char modbuf[100];
  228. - char fixed_type[500];
  229. - char buf[1000];
  230. int partial_content;
  231. -
  232. + smart_str s = {0};
  233. + int type_len;
  234. +
  235. hc->status = status;
  236. hc->bytes_to_send = length;
  237. if ( hc->mime_flag )
  238. @@ -649,41 +681,89 @@
  239. else
  240. partial_content = 0;
  241. - now = time( (time_t*) 0 );
  242. if ( mod == (time_t) 0 )
  243. - mod = now;
  244. - (void) strftime( nowbuf, sizeof(nowbuf), rfc1123fmt, gmtime( &now ) );
  245. - (void) strftime( modbuf, sizeof(modbuf), rfc1123fmt, gmtime( &mod ) );
  246. - (void) my_snprintf(
  247. - fixed_type, sizeof(fixed_type), type, hc->hs->charset );
  248. - (void) my_snprintf( buf, sizeof(buf),
  249. - "%.20s %d %s\r\nServer: %s\r\nContent-Type: %s\r\nDate: %s\r\nLast-Modified: %s\r\nAccept-Ranges: bytes\r\nConnection: close\r\n",
  250. - hc->protocol, status, title, EXPOSED_SERVER_SOFTWARE, fixed_type,
  251. - nowbuf, modbuf );
  252. - add_response( hc, buf );
  253. + mod = httpd_time_now;
  254. +
  255. + if (last_modified == 0) {
  256. + (void) strftime( modbuf, sizeof(modbuf), rfc1123fmt, gmtime( &mod ) );
  257. + last_modified = modbuf;
  258. + last_modified_len = strlen(modbuf);
  259. + }
  260. +
  261. + type_len = strlen(type);
  262. +
  263. + if (hc->response) {
  264. + s.c = hc->response;
  265. + s.len = 0;
  266. + s.a = hc->maxresponse;
  267. + hc->response = 0;
  268. + hc->maxresponse = 0;
  269. + }
  270. +
  271. + smart_str_appends(&s, "HTTP/1.1 ");
  272. + smart_str_append_long(&s, status);
  273. + smart_str_appends(&s, " HTTP\r\nServer: " EXPOSED_SERVER_SOFTWARE "\r\n"
  274. + "Content-Type: ");
  275. +
  276. + if (type[type_len-2] == '%' && type[type_len-1] == 's') {
  277. + smart_str_appendl(&s, type, type_len - 2);
  278. + smart_str_appends(&s, hc->hs->charset);
  279. + } else {
  280. + smart_str_appendl(&s, type, type_len);
  281. + }
  282. +
  283. +
  284. + smart_str_appends(&s, "\r\nDate: ");
  285. + smart_str_appends(&s, httpd_now_buf);
  286. + smart_str_appends(&s, "\r\nLast-Modified: ");
  287. + smart_str_appendl(&s, last_modified, last_modified_len);
  288. + smart_str_appends(&s, "\r\nAccept-Ranges: bytes\r\n");
  289. +
  290. if ( encodings[0] != '\0' )
  291. {
  292. - (void) my_snprintf( buf, sizeof(buf),
  293. - "Content-Encoding: %s\r\n", encodings );
  294. - add_response( hc, buf );
  295. + smart_str_appends(&s, "Content-Encoding: ");
  296. + smart_str_appends(&s, encodings);
  297. + smart_str_appends(&s, "\r\n");
  298. }
  299. if ( partial_content )
  300. {
  301. - (void) my_snprintf( buf, sizeof(buf),
  302. - "Content-Range: bytes %ld-%ld/%d\r\nContent-Length: %ld\r\n",
  303. - (long) hc->init_byte_loc, (long) hc->end_byte_loc, length,
  304. - (long) ( hc->end_byte_loc - hc->init_byte_loc + 1 ) );
  305. - add_response( hc, buf );
  306. +
  307. + smart_str_appends(&s, "Content-Range: bytes ");
  308. + smart_str_append_long(&s, hc->init_byte_loc);
  309. + smart_str_appendc(&s, '-');
  310. + smart_str_append_long(&s, hc->end_byte_loc);
  311. + smart_str_appendc(&s, '/');
  312. + smart_str_append_long(&s, length);
  313. + smart_str_appends(&s, "\r\nContent-Length: ");
  314. + smart_str_append_long(&s, hc->end_byte_loc - hc->init_byte_loc + 1);
  315. + smart_str_appends(&s, "\r\n");
  316. +
  317. }
  318. else if ( length >= 0 )
  319. {
  320. - (void) my_snprintf( buf, sizeof(buf),
  321. - "Content-Length: %d\r\n", length );
  322. - add_response( hc, buf );
  323. + smart_str_appends(&s, "Content-Length: ");
  324. + smart_str_append_long(&s, length);
  325. + smart_str_appends(&s, "\r\n");
  326. }
  327. + else {
  328. + hc->do_keep_alive = 0;
  329. + }
  330. if ( extraheads[0] != '\0' )
  331. - add_response( hc, extraheads );
  332. - add_response( hc, "\r\n" );
  333. + smart_str_appends(&s, extraheads);
  334. + if (hc->do_keep_alive) {
  335. + smart_str_appends(&s, "Connection: keep-alive\r\n\r\n" );
  336. + } else {
  337. + smart_str_appends(&s, "Connection: close\r\n\r\n" );
  338. + }
  339. + smart_str_0(&s);
  340. +
  341. + if (hc->response) {
  342. + free(hc->response);
  343. + }
  344. + hc->response = s.c;
  345. + hc->maxresponse = s.a;
  346. + hc->responselen = s.len;
  347. +
  348. }
  349. }
  350. @@ -725,7 +805,7 @@
  351. {
  352. char defanged_arg[1000], buf[2000];
  353. - send_mime( hc, status, title, "", extraheads, "text/html", -1, 0 );
  354. + send_mime( hc, status, title, "", extraheads, "text/html", -1, 0, 0, 0 );
  355. (void) my_snprintf( buf, sizeof(buf),
  356. "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n<BODY BGCOLOR=\"#cc9999\"><H2>%d %s</H2>\n",
  357. status, title, status, title );
  358. @@ -764,7 +844,7 @@
  359. char* cp2;
  360. for ( cp1 = str, cp2 = dfstr;
  361. - *cp1 != '\0' && cp2 - dfstr < dfsize - 1;
  362. + *cp1 != '\0' && cp2 - dfstr < dfsize - 5;
  363. ++cp1, ++cp2 )
  364. {
  365. switch ( *cp1 )
  366. @@ -834,7 +914,7 @@
  367. fp = fopen( filename, "r" );
  368. if ( fp == (FILE*) 0 )
  369. return 0;
  370. - send_mime( hc, status, title, "", extraheads, "text/html", -1, 0 );
  371. + send_mime( hc, status, title, "", extraheads, "text/html", -1, 0, 0, 0 );
  372. for (;;)
  373. {
  374. r = fread( buf, 1, sizeof(buf) - 1, fp );
  375. @@ -1336,6 +1416,9 @@
  376. if ( hc->tildemapped )
  377. return 1;
  378. + if ( hc->hostname[0] == '.' || strchr( hc->hostname, '/' ) != (char*) 0 )
  379. + return 0;
  380. +
  381. /* Figure out the host directory. */
  382. #ifdef VHOST_DIRLEVELS
  383. httpd_realloc_str(
  384. @@ -1436,7 +1519,7 @@
  385. restlen = strlen( path );
  386. httpd_realloc_str( &rest, &maxrest, restlen );
  387. (void) strcpy( rest, path );
  388. - if ( rest[restlen - 1] == '/' )
  389. + if ( restlen > 0 && rest[restlen - 1] == '/' )
  390. rest[--restlen] = '\0'; /* trim trailing slash */
  391. if ( ! tildemapped )
  392. /* Remove any leading slashes. */
  393. @@ -1603,6 +1686,70 @@
  394. int
  395. +httpd_request_reset(httpd_conn* hc, int preserve_read_buf )
  396. +{
  397. + if (!preserve_read_buf) {
  398. + hc->read_idx = 0;
  399. + hc->checked_idx = 0;
  400. + }
  401. +
  402. + if (hc->read_buf_is_mmap) {
  403. + hc->read_buf_is_mmap = 0;
  404. + munmap(hc->read_buf, hc->read_size);
  405. + hc->read_buf = NULL;
  406. + hc->read_size = 0;
  407. + httpd_realloc_str( &hc->read_buf, &hc->read_size, 500 );
  408. + }
  409. + hc->checked_state = CHST_FIRSTWORD;
  410. + hc->method = METHOD_UNKNOWN;
  411. + hc->status = 0;
  412. + hc->bytes_to_send = 0;
  413. + hc->bytes_sent = 0;
  414. + hc->encodedurl = "";
  415. + hc->decodedurl[0] = '\0';
  416. + hc->protocol = "UNKNOWN";
  417. + hc->origfilename[0] = '\0';
  418. + hc->expnfilename[0] = '\0';
  419. + hc->encodings[0] = '\0';
  420. + hc->pathinfo[0] = '\0';
  421. + hc->query[0] = '\0';
  422. + hc->referer = "";
  423. + hc->useragent = "";
  424. + hc->accept[0] = '\0';
  425. + hc->accepte[0] = '\0';
  426. + hc->acceptl = "";
  427. + hc->cookie = "";
  428. + hc->contenttype = "";
  429. + hc->reqhost[0] = '\0';
  430. + hc->hdrhost = "";
  431. + hc->hostdir[0] = '\0';
  432. + hc->authorization = "";
  433. + hc->remoteuser[0] = '\0';
  434. + hc->response[0] = '\0';
  435. +#ifdef TILDE_MAP_2
  436. + hc->altdir[0] = '\0';
  437. +#endif /* TILDE_MAP_2 */
  438. + hc->responselen = 0;
  439. + hc->if_modified_since = (time_t) -1;
  440. + hc->range_if = (time_t) -1;
  441. + hc->contentlength = -1;
  442. + hc->type = "";
  443. + hc->hostname = (char*) 0;
  444. + hc->mime_flag = 1;
  445. + hc->one_one = 0;
  446. + hc->got_range = 0;
  447. + hc->tildemapped = 0;
  448. + hc->init_byte_loc = 0;
  449. + hc->end_byte_loc = -1;
  450. + hc->keep_alive = 0;
  451. + hc->do_keep_alive = 0;
  452. + hc->should_linger = 0;
  453. + hc->file_address = (char*) 0;
  454. + hc->read_body_into_mem = 0;
  455. + return GC_OK;
  456. +}
  457. +
  458. +int
  459. httpd_get_conn( httpd_server* hs, int listen_fd, httpd_conn* hc )
  460. {
  461. httpd_sockaddr sa;
  462. @@ -1612,6 +1759,7 @@
  463. {
  464. hc->read_size = 0;
  465. httpd_realloc_str( &hc->read_buf, &hc->read_size, 500 );
  466. + hc->read_buf_is_mmap = 0;
  467. hc->maxdecodedurl =
  468. hc->maxorigfilename = hc->maxexpnfilename = hc->maxencodings =
  469. hc->maxpathinfo = hc->maxquery = hc->maxaccept =
  470. @@ -1631,12 +1779,19 @@
  471. httpd_realloc_str( &hc->reqhost, &hc->maxreqhost, 0 );
  472. httpd_realloc_str( &hc->hostdir, &hc->maxhostdir, 0 );
  473. httpd_realloc_str( &hc->remoteuser, &hc->maxremoteuser, 0 );
  474. - httpd_realloc_str( &hc->response, &hc->maxresponse, 0 );
  475. + httpd_realloc_str( &hc->response, &hc->maxresponse, 350 );
  476. #ifdef TILDE_MAP_2
  477. httpd_realloc_str( &hc->altdir, &hc->maxaltdir, 0 );
  478. #endif /* TILDE_MAP_2 */
  479. hc->initialized = 1;
  480. }
  481. + if (hc->read_buf_is_mmap) {
  482. + hc->read_buf_is_mmap = 0;
  483. + munmap(hc->read_buf, hc->read_size);
  484. + hc->read_buf = NULL;
  485. + hc->read_size = 0;
  486. + httpd_realloc_str( &hc->read_buf, &hc->read_size, 500 );
  487. + }
  488. /* Accept the new connection. */
  489. sz = sizeof(sa);
  490. @@ -1657,53 +1812,12 @@
  491. hc->hs = hs;
  492. memset( &hc->client_addr, 0, sizeof(hc->client_addr) );
  493. memcpy( &hc->client_addr, &sa, sockaddr_len( &sa ) );
  494. - hc->read_idx = 0;
  495. - hc->checked_idx = 0;
  496. - hc->checked_state = CHST_FIRSTWORD;
  497. - hc->method = METHOD_UNKNOWN;
  498. - hc->status = 0;
  499. - hc->bytes_to_send = 0;
  500. - hc->bytes_sent = 0;
  501. - hc->encodedurl = "";
  502. - hc->decodedurl[0] = '\0';
  503. - hc->protocol = "UNKNOWN";
  504. - hc->origfilename[0] = '\0';
  505. - hc->expnfilename[0] = '\0';
  506. - hc->encodings[0] = '\0';
  507. - hc->pathinfo[0] = '\0';
  508. - hc->query[0] = '\0';
  509. - hc->referer = "";
  510. - hc->useragent = "";
  511. - hc->accept[0] = '\0';
  512. - hc->accepte[0] = '\0';
  513. - hc->acceptl = "";
  514. - hc->cookie = "";
  515. - hc->contenttype = "";
  516. - hc->reqhost[0] = '\0';
  517. - hc->hdrhost = "";
  518. - hc->hostdir[0] = '\0';
  519. - hc->authorization = "";
  520. - hc->remoteuser[0] = '\0';
  521. - hc->response[0] = '\0';
  522. -#ifdef TILDE_MAP_2
  523. - hc->altdir[0] = '\0';
  524. -#endif /* TILDE_MAP_2 */
  525. - hc->responselen = 0;
  526. - hc->if_modified_since = (time_t) -1;
  527. - hc->range_if = (time_t) -1;
  528. - hc->contentlength = -1;
  529. - hc->type = "";
  530. - hc->hostname = (char*) 0;
  531. - hc->mime_flag = 1;
  532. - hc->one_one = 0;
  533. - hc->got_range = 0;
  534. - hc->tildemapped = 0;
  535. - hc->init_byte_loc = 0;
  536. - hc->end_byte_loc = -1;
  537. - hc->keep_alive = 0;
  538. - hc->should_linger = 0;
  539. - hc->file_address = (char*) 0;
  540. - return GC_OK;
  541. +
  542. +/*
  543. +printf("doing httpd_get_con(%d)\n", hc->conn_fd);
  544. +*/
  545. +
  546. + return httpd_request_reset(hc, 0);
  547. }
  548. @@ -1720,6 +1834,9 @@
  549. {
  550. char c;
  551. +/*
  552. +printf("**REQUEST [%d]**\n%*.*s\n", hc->conn_fd, hc->read_idx, hc->read_idx, hc->read_buf);
  553. +*/
  554. for ( ; hc->checked_idx < hc->read_idx; ++hc->checked_idx )
  555. {
  556. c = hc->read_buf[hc->checked_idx];
  557. @@ -1912,8 +2029,11 @@
  558. eol = strpbrk( protocol, " \t\n\r" );
  559. if ( eol != (char*) 0 )
  560. *eol = '\0';
  561. - if ( strcasecmp( protocol, "HTTP/1.0" ) != 0 )
  562. + if ( strcasecmp( protocol, "HTTP/1.0" ) != 0 ) {
  563. hc->one_one = 1;
  564. + hc->keep_alive = 1;
  565. + hc->do_keep_alive = 1;
  566. + }
  567. }
  568. }
  569. /* Check for HTTP/1.1 absolute URL. */
  570. @@ -2129,6 +2249,7 @@
  571. cp = &buf[11];
  572. cp += strspn( cp, " \t" );
  573. if ( strcasecmp( cp, "keep-alive" ) == 0 )
  574. + hc->do_keep_alive = 1;
  575. hc->keep_alive = 1;
  576. }
  577. #ifdef LOG_UNKNOWN_HEADERS
  578. @@ -2168,6 +2289,9 @@
  579. }
  580. }
  581. +/*
  582. +printf("one_one = %d keep_alive = %d\n", hc->one_one, hc->keep_alive);
  583. +*/
  584. if ( hc->one_one )
  585. {
  586. /* Check that HTTP/1.1 requests specify a host, as required. */
  587. @@ -2177,14 +2301,14 @@
  588. return -1;
  589. }
  590. - /* If the client wants to do keep-alives, it might also be doing
  591. - ** pipelining. There's no way for us to tell. Since we don't
  592. - ** implement keep-alives yet, if we close such a connection there
  593. - ** might be unread pipelined requests waiting. So, we have to
  594. - ** do a lingering close.
  595. + /*
  596. + ** Disable keep alive support for bad browsers,
  597. + ** list taken from Apache 1.3.19
  598. */
  599. - if ( hc->keep_alive )
  600. - hc->should_linger = 1;
  601. + if ( hc->do_keep_alive &&
  602. + ( strstr(hc->useragent, "Mozilla/2") != NULL ||
  603. + strstr(hc->useragent, "MSIE 4.0b2;") != NULL))
  604. + hc->do_keep_alive = 0;
  605. }
  606. /* Ok, the request has been parsed. Now we resolve stuff that
  607. @@ -2349,15 +2473,24 @@
  608. void
  609. -httpd_close_conn( httpd_conn* hc, struct timeval* nowP )
  610. - {
  611. - make_log_entry( hc, nowP );
  612. +httpd_complete_request( httpd_conn* hc, struct timeval* nowP)
  613. +{
  614. + if (hc->method != METHOD_UNKNOWN)
  615. + make_log_entry( hc, nowP );
  616. - if ( hc->file_address != (char*) 0 )
  617. + if ( hc->file_address == (char*) 1 )
  618. + {
  619. + thttpd_closed_conn(hc->conn_fd);
  620. + } else if ( hc->file_address != (char*) 0 )
  621. {
  622. mmc_unmap( hc->file_address, &(hc->sb), nowP );
  623. hc->file_address = (char*) 0;
  624. }
  625. + }
  626. +
  627. +void
  628. +httpd_close_conn( httpd_conn* hc, struct timeval* nowP )
  629. +{
  630. if ( hc->conn_fd >= 0 )
  631. {
  632. (void) close( hc->conn_fd );
  633. @@ -2370,7 +2503,12 @@
  634. {
  635. if ( hc->initialized )
  636. {
  637. - free( (void*) hc->read_buf );
  638. +
  639. + if ( hc->read_buf_is_mmap ) {
  640. + munmap( hc->read_buf, hc->read_size );
  641. + } else {
  642. + free( (void*) hc->read_buf );
  643. + }
  644. free( (void*) hc->decodedurl );
  645. free( (void*) hc->origfilename );
  646. free( (void*) hc->expnfilename );
  647. @@ -2556,7 +2694,7 @@
  648. return -1;
  649. }
  650. - send_mime( hc, 200, ok200title, "", "", "text/html", -1, hc->sb.st_mtime );
  651. + send_mime( hc, 200, ok200title, "", "", "text/html", -1, hc->sb.st_mtime, 0, 0 );
  652. if ( hc->method == METHOD_HEAD )
  653. closedir( dirp );
  654. else if ( hc->method == METHOD_GET )
  655. @@ -3026,11 +3164,9 @@
  656. post_post_garbage_hack( httpd_conn* hc )
  657. {
  658. char buf[2];
  659. - int r;
  660. - r = recv( hc->conn_fd, buf, sizeof(buf), MSG_PEEK );
  661. - if ( r > 0 )
  662. - (void) read( hc->conn_fd, buf, r );
  663. + fcntl(hc->conn_fd, F_SETFL, O_NONBLOCK);
  664. + (void) read( hc->conn_fd, buf, 2 );
  665. }
  666. @@ -3313,6 +3449,11 @@
  667. int r;
  668. ClientData client_data;
  669. + /*
  670. + ** We are not going to leave the socket open after a CGI... too hard
  671. + */
  672. + hc->do_keep_alive = 0;
  673. +
  674. if ( hc->method == METHOD_GET || hc->method == METHOD_POST )
  675. {
  676. httpd_clear_ndelay( hc->conn_fd );
  677. @@ -3369,6 +3510,7 @@
  678. int expnlen, indxlen;
  679. char* cp;
  680. char* pi;
  681. + int nocache = 0;
  682. expnlen = strlen( hc->expnfilename );
  683. @@ -3561,6 +3703,16 @@
  684. match( hc->hs->cgi_pattern, hc->expnfilename ) )
  685. return cgi( hc );
  686. + if ( hc->hs->php_pattern != (char*) 0 &&
  687. + match( hc->hs->php_pattern, hc->expnfilename)) {
  688. + return thttpd_php_request( hc, 0 );
  689. + }
  690. +
  691. + if ( hc->hs->phps_pattern != (char*) 0 &&
  692. + match( hc->hs->phps_pattern, hc->expnfilename)) {
  693. + return thttpd_php_request( hc, 1 );
  694. + }
  695. +
  696. /* It's not CGI. If it's executable or there's pathinfo, someone's
  697. ** trying to either serve or run a non-CGI file as CGI. Either case
  698. ** is prohibited.
  699. @@ -3594,32 +3746,46 @@
  700. hc->end_byte_loc = hc->sb.st_size - 1;
  701. figure_mime( hc );
  702. + if ( strncmp(hc->decodedurl, "/nocache/", sizeof("/nocache/") - 1 ) == 0 )
  703. + nocache = 1;
  704. if ( hc->method == METHOD_HEAD )
  705. {
  706. send_mime(
  707. hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size,
  708. - hc->sb.st_mtime );
  709. + hc->sb.st_mtime, 0, 0 );
  710. }
  711. - else if ( hc->if_modified_since != (time_t) -1 &&
  712. + else if ( !nocache && hc->if_modified_since != (time_t) -1 &&
  713. hc->if_modified_since >= hc->sb.st_mtime )
  714. {
  715. - hc->method = METHOD_HEAD;
  716. send_mime(
  717. - hc, 304, err304title, hc->encodings, "", hc->type, hc->sb.st_size,
  718. - hc->sb.st_mtime );
  719. + hc, 304, err304title, hc->encodings, "", hc->type, -1,
  720. + hc->sb.st_mtime, 0, 0 );
  721. }
  722. else
  723. {
  724. - hc->file_address = mmc_map( hc->expnfilename, &(hc->sb), nowP );
  725. + char *extraheads = "";
  726. + char *lm;
  727. + size_t lml;
  728. +
  729. + if ( nocache )
  730. + {
  731. + extraheads = "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n"
  732. + "Cache-Control: no-store, no-cache, must-revalidate, "
  733. + "post-check=0, pre-check=0\r\n"
  734. + "Pragma: no-cache\r\n";
  735. + }
  736. +
  737. + hc->file_address = mmc_map( hc->expnfilename, &(hc->sb), nowP, nocache, &lm, &lml );
  738. if ( hc->file_address == (char*) 0 )
  739. {
  740. httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl );
  741. return -1;
  742. }
  743. +
  744. send_mime(
  745. - hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size,
  746. - hc->sb.st_mtime );
  747. + hc, 200, ok200title, hc->encodings, extraheads, hc->type, hc->sb.st_size,
  748. + hc->sb.st_mtime, lm, lml );
  749. }
  750. return 0;
  751. @@ -3638,6 +3804,9 @@
  752. return r;
  753. }
  754. +#define smart_str_append_const(a,b) smart_str_appendl(a,b,sizeof(b)-1)
  755. +
  756. +static smart_str bentries;
  757. static void
  758. make_log_entry( httpd_conn* hc, struct timeval* nowP )
  759. @@ -3648,88 +3817,62 @@
  760. if ( hc->hs->no_log )
  761. return;
  762. -
  763. - /* This is straight CERN Combined Log Format - the only tweak
  764. - ** being that if we're using syslog() we leave out the date, because
  765. - ** syslogd puts it in. The included syslogtocern script turns the
  766. - ** results into true CERN format.
  767. - */
  768. -
  769. /* Format remote user. */
  770. if ( hc->remoteuser[0] != '\0' )
  771. - ru = hc->remoteuser;
  772. + ru = hc->remoteuser;
  773. else
  774. - ru = "-";
  775. + ru = "-";
  776. /* If we're vhosting, prepend the hostname to the url. This is
  777. ** a little weird, perhaps writing separate log files for
  778. ** each vhost would make more sense.
  779. */
  780. - if ( hc->hs->vhost && ! hc->tildemapped )
  781. - (void) my_snprintf( url, sizeof(url),
  782. - "/%.100s%.200s",
  783. - hc->hostname == (char*) 0 ? hc->hs->server_hostname : hc->hostname,
  784. - hc->encodedurl );
  785. - else
  786. - (void) my_snprintf( url, sizeof(url),
  787. - "%.200s", hc->encodedurl );
  788. - /* Format the bytes. */
  789. - if ( (long) hc->bytes_sent >= 0 )
  790. - (void) my_snprintf( bytes, sizeof(bytes),
  791. - "%ld", (long) hc->bytes_sent );
  792. - else
  793. - (void) strcpy( bytes, "-" );
  794. /* Logfile or syslog? */
  795. if ( hc->hs->logfp != (FILE*) 0 )
  796. - {
  797. - time_t now;
  798. - struct tm* t;
  799. - const char* cernfmt_nozone = "%d/%b/%Y:%H:%M:%S";
  800. - char date_nozone[100];
  801. - int zone;
  802. - char sign;
  803. - char date[100];
  804. -
  805. - /* Get the current time, if necessary. */
  806. - if ( nowP != (struct timeval*) 0 )
  807. - now = nowP->tv_sec;
  808. - else
  809. - now = time( (time_t*) 0 );
  810. - /* Format the time, forcing a numeric timezone (some log analyzers
  811. - ** are stoooopid about this).
  812. - */
  813. - t = localtime( &now );
  814. - (void) strftime( date_nozone, sizeof(date_nozone), cernfmt_nozone, t );
  815. -#ifdef HAVE_TM_GMTOFF
  816. - zone = t->tm_gmtoff / 60L;
  817. -#else
  818. - zone = -timezone / 60L;
  819. - /* Probably have to add something about daylight time here. */
  820. -#endif
  821. - if ( zone >= 0 )
  822. - sign = '+';
  823. - else
  824. - {
  825. - sign = '-';
  826. - zone = -zone;
  827. - }
  828. - zone = ( zone / 60 ) * 100 + zone % 60;
  829. - (void) my_snprintf( date, sizeof(date),
  830. - "%s %c%04d", date_nozone, sign, zone );
  831. - /* And write the log entry. */
  832. - (void) fprintf( hc->hs->logfp,
  833. - "%.80s - %.80s [%s] \"%.80s %.300s %.80s\" %d %s \"%.200s\" \"%.80s\"\n",
  834. - httpd_ntoa( &hc->client_addr ), ru, date,
  835. - httpd_method_str( hc->method ), url, hc->protocol,
  836. - hc->status, bytes, hc->referer, hc->useragent );
  837. - (void) fflush( hc->hs->logfp ); /* don't need to flush every time */
  838. - }
  839. - else
  840. - syslog( LOG_INFO,
  841. - "%.80s - %.80s \"%.80s %.200s %.80s\" %d %s \"%.200s\" \"%.80s\"",
  842. - httpd_ntoa( &hc->client_addr ), ru,
  843. - httpd_method_str( hc->method ), url, hc->protocol,
  844. - hc->status, bytes, hc->referer, hc->useragent );
  845. + {
  846. + /* XXXXXXX */
  847. +
  848. + smart_str_appends(&bentries, httpd_ntoa(&hc->client_addr));
  849. + smart_str_append_const(&bentries, " - ");
  850. + smart_str_appends(&bentries, ru);
  851. + smart_str_append_const(&bentries, " [");
  852. + smart_str_appendl(&bentries, hc->hs->log_date, hc->hs->log_date_len);
  853. + smart_str_append_const(&bentries, "] \"");
  854. + smart_str_appends(&bentries, httpd_method_str(hc->method));
  855. + smart_str_appendc(&bentries, ' ');
  856. +
  857. + if (hc->hs->vhost && ! hc->tildemapped) {
  858. + smart_str_appendc(&bentries, '/');
  859. + if (hc->hostname)
  860. + smart_str_appends(&bentries, hc->hostname);
  861. + else
  862. + smart_str_appends(&bentries, hc->hs->server_hostname);
  863. + }
  864. + smart_str_appends(&bentries, hc->encodedurl);
  865. +
  866. + smart_str_appendc(&bentries, ' ');
  867. + smart_str_appends(&bentries, hc->protocol);
  868. + smart_str_append_const(&bentries, "\" ");
  869. + smart_str_append_long(&bentries, hc->status);
  870. + if (hc->bytes_sent >= 0) {
  871. + smart_str_appendc(&bentries, ' ');
  872. + smart_str_append_long(&bentries, hc->bytes_sent);
  873. + smart_str_append_const(&bentries, " \"");
  874. + } else {
  875. + smart_str_append_const(&bentries, " - \"");
  876. + }
  877. + smart_str_appends(&bentries, hc->referer);
  878. + smart_str_append_const(&bentries, "\" \"");
  879. + smart_str_appends(&bentries, hc->useragent);
  880. + smart_str_append_const(&bentries, "\"\n");
  881. +
  882. + if (bentries.len > 16384) {
  883. + int fd = fileno(hc->hs->logfp);
  884. + write(fd, bentries.c, bentries.len);
  885. + bentries.len = 0;
  886. + }
  887. + }
  888. +
  889. }
  890. @@ -3840,7 +3983,24 @@
  891. {
  892. #ifdef HAVE_GETNAMEINFO
  893. static char str[200];
  894. + static smart_str httpd_ntoa_buf;
  895. +
  896. + if (saP->sa_in.sin_family == AF_INET) {
  897. + unsigned long n = ntohl(saP->sa_in.sin_addr.s_addr);
  898. + httpd_ntoa_buf.len = 0;
  899. + smart_str_append_long(&httpd_ntoa_buf, (n >> 24));
  900. + smart_str_appendc(&httpd_ntoa_buf, '.');
  901. + smart_str_append_long(&httpd_ntoa_buf, (n >> 16) & 255);
  902. + smart_str_appendc(&httpd_ntoa_buf, '.');
  903. + smart_str_append_long(&httpd_ntoa_buf, (n >> 8) & 255);
  904. + smart_str_appendc(&httpd_ntoa_buf, '.');
  905. + smart_str_append_long(&httpd_ntoa_buf, (n >> 0) & 255);
  906. + smart_str_0(&httpd_ntoa_buf);
  907. +
  908. + return httpd_ntoa_buf.c;
  909. + }
  910. +
  911. if ( getnameinfo( &saP->sa, sockaddr_len( saP ), str, sizeof(str), 0, 0, NI_NUMERICHOST ) != 0 )
  912. {
  913. str[0] = '?';
  914. diff -ur thttpd-2.21b/libhttpd.h thttpd-2.21b-cool/libhttpd.h
  915. --- thttpd-2.21b/libhttpd.h Tue Apr 24 00:36:50 2001
  916. +++ thttpd-2.21b-cool/libhttpd.h Sat Sep 20 14:43:20 2003
  917. @@ -69,6 +69,8 @@
  918. char* server_hostname;
  919. int port;
  920. char* cgi_pattern;
  921. + char* php_pattern;
  922. + char* phps_pattern;
  923. char* charset;
  924. char* cwd;
  925. int listen4_fd, listen6_fd;
  926. @@ -80,6 +82,8 @@
  927. char* url_pattern;
  928. char* local_pattern;
  929. int no_empty_referers;
  930. + size_t log_date_len;
  931. + char log_date[100];
  932. } httpd_server;
  933. /* A connection. */
  934. @@ -88,6 +92,7 @@
  935. httpd_server* hs;
  936. httpd_sockaddr client_addr;
  937. char* read_buf;
  938. + char read_buf_is_mmap;
  939. int read_size, read_idx, checked_idx;
  940. int checked_state;
  941. int method;
  942. @@ -132,11 +137,12 @@
  943. int got_range;
  944. int tildemapped; /* this connection got tilde-mapped */
  945. off_t init_byte_loc, end_byte_loc;
  946. - int keep_alive;
  947. + int keep_alive, do_keep_alive;
  948. int should_linger;
  949. struct stat sb;
  950. int conn_fd;
  951. char* file_address;
  952. + char read_body_into_mem;
  953. } httpd_conn;
  954. /* Methods. */
  955. @@ -168,7 +174,8 @@
  956. char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port,
  957. char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp,
  958. int no_symlink, int vhost, int global_passwd, char* url_pattern,
  959. - char* local_pattern, int no_empty_referers );
  960. + char* local_pattern, int no_empty_referers, char* php_pattern,
  961. + char* phps_pattern );
  962. /* Change the log file. */
  963. extern void httpd_set_logfp( httpd_server* hs, FILE* logfp );
  964. @@ -229,6 +236,8 @@
  965. ** If you don't have a current timeval handy just pass in 0.
  966. */
  967. extern void httpd_close_conn( httpd_conn* hc, struct timeval* nowP );
  968. +void httpd_complete_request( httpd_conn* hc, struct timeval* nowP);
  969. +int httpd_request_reset(httpd_conn* hc,int );
  970. /* Call this to de-initialize a connection struct and *really* free the
  971. ** mallocced strings.
  972. diff -ur thttpd-2.21b/mime_encodings.txt thttpd-2.21b-cool/mime_encodings.txt
  973. --- thttpd-2.21b/mime_encodings.txt Wed May 10 03:22:28 2000
  974. +++ thttpd-2.21b-cool/mime_encodings.txt Sat Sep 20 14:43:20 2003
  975. @@ -3,6 +3,6 @@
  976. # A list of file extensions followed by the corresponding MIME encoding.
  977. # Extensions not found in the table proceed to the mime_types table.
  978. -Z x-compress
  979. -gz x-gzip
  980. +Z compress
  981. +gz gzip
  982. uu x-uuencode
  983. diff -ur thttpd-2.21b/mime_types.txt thttpd-2.21b-cool/mime_types.txt
  984. --- thttpd-2.21b/mime_types.txt Sat Apr 14 04:53:30 2001
  985. +++ thttpd-2.21b-cool/mime_types.txt Sat Sep 20 14:43:20 2003
  986. @@ -1,135 +1,138 @@
  987. -# mime_types.txt
  988. -#
  989. -# A list of file extensions followed by the corresponding MIME type.
  990. -# Extensions not found in the table are returned as text/plain.
  991. -
  992. -html text/html; charset=%s
  993. -htm text/html; charset=%s
  994. -txt text/plain; charset=%s
  995. -rtx text/richtext
  996. -etx text/x-setext
  997. -tsv text/tab-separated-values
  998. -css text/css
  999. -xml text/xml
  1000. -dtd text/xml
  1001. -
  1002. -gif image/gif
  1003. -jpg image/jpeg
  1004. -jpeg image/jpeg
  1005. -jpe image/jpeg
  1006. -jfif image/jpeg
  1007. -tif image/tiff
  1008. -tiff image/tiff
  1009. -pbm image/x-portable-bitmap
  1010. -pgm image/x-portable-graymap
  1011. -ppm image/x-portable-pixmap
  1012. -pnm image/x-portable-anymap
  1013. -xbm image/x-xbitmap
  1014. -xpm image/x-xpixmap
  1015. -xwd image/x-xwindowdump
  1016. -ief image/ief
  1017. -png image/png
  1018. -
  1019. -au audio/basic
  1020. -snd audio/basic
  1021. -aif audio/x-aiff
  1022. -aiff audio/x-aiff
  1023. -aifc audio/x-aiff
  1024. -ra audio/x-pn-realaudio
  1025. -ram audio/x-pn-realaudio
  1026. -rm audio/x-pn-realaudio
  1027. -rpm audio/x-pn-realaudio-plugin
  1028. -wav audio/wav
  1029. -mid audio/midi
  1030. -midi audio/midi
  1031. -kar audio/midi
  1032. -mpga audio/mpeg
  1033. -mp2 audio/mpeg
  1034. -mp3 audio/mpeg
  1035. -
  1036. -mpeg video/mpeg
  1037. -mpg video/mpeg
  1038. -mpe video/mpeg
  1039. -qt video/quicktime
  1040. -mov video/quicktime
  1041. -avi video/x-msvideo
  1042. -movie video/x-sgi-movie
  1043. -mv video/x-sgi-movie
  1044. -vx video/x-rad-screenplay
  1045. -
  1046. -a application/octet-stream
  1047. +ez application/andrew-inset
  1048. +hqx application/mac-binhex40
  1049. +cpt application/mac-compactpro
  1050. +doc application/msword
  1051. bin application/octet-stream
  1052. +dms application/octet-stream
  1053. +lha application/octet-stream
  1054. +lzh application/octet-stream
  1055. exe application/octet-stream
  1056. -dump application/octet-stream
  1057. -o application/octet-stream
  1058. -class application/java
  1059. -js application/x-javascript
  1060. +class application/octet-stream
  1061. +so application/octet-stream
  1062. +dll application/octet-stream
  1063. +oda application/oda
  1064. +pdf application/pdf
  1065. ai application/postscript
  1066. eps application/postscript
  1067. ps application/postscript
  1068. -dir application/x-director
  1069. +smi application/smil
  1070. +smil application/smil
  1071. +mif application/vnd.mif
  1072. +xls application/vnd.ms-excel
  1073. +ppt application/vnd.ms-powerpoint
  1074. +wbxml application/vnd.wap.wbxml
  1075. +wmlc application/vnd.wap.wmlc
  1076. +wmlsc application/vnd.wap.wmlscriptc
  1077. +bcpio application/x-bcpio
  1078. +vcd application/x-cdlink
  1079. +pgn application/x-chess-pgn
  1080. +cpio application/x-cpio
  1081. +csh application/x-csh
  1082. dcr application/x-director
  1083. +dir application/x-director
  1084. dxr application/x-director
  1085. -fgd application/x-director
  1086. -aam application/x-authorware-map
  1087. -aas application/x-authorware-seg
  1088. -aab application/x-authorware-bin
  1089. -fh4 image/x-freehand
  1090. -fh7 image/x-freehand
  1091. -fh5 image/x-freehand
  1092. -fhc image/x-freehand
  1093. -fh image/x-freehand
  1094. -spl application/futuresplash
  1095. -swf application/x-shockwave-flash
  1096. dvi application/x-dvi
  1097. +spl application/x-futuresplash
  1098. gtar application/x-gtar
  1099. hdf application/x-hdf
  1100. -hqx application/mac-binhex40
  1101. -iv application/x-inventor
  1102. +js application/x-javascript
  1103. +skp application/x-koan
  1104. +skd application/x-koan
  1105. +skt application/x-koan
  1106. +skm application/x-koan
  1107. latex application/x-latex
  1108. -man application/x-troff-man
  1109. -me application/x-troff-me
  1110. -mif application/x-mif
  1111. -ms application/x-troff-ms
  1112. -oda application/oda
  1113. -pdf application/pdf
  1114. -rtf application/rtf
  1115. -bcpio application/x-bcpio
  1116. -cpio application/x-cpio
  1117. -sv4cpio application/x-sv4cpio
  1118. -sv4crc application/x-sv4crc
  1119. -sh application/x-shar
  1120. +nc application/x-netcdf
  1121. +cdf application/x-netcdf
  1122. +sh application/x-sh
  1123. shar application/x-shar
  1124. +swf application/x-shockwave-flash
  1125. sit application/x-stuffit
  1126. +sv4cpio application/x-sv4cpio
  1127. +sv4crc application/x-sv4crc
  1128. tar application/x-tar
  1129. +tcl application/x-tcl
  1130. tex application/x-tex
  1131. -texi application/x-texinfo
  1132. texinfo application/x-texinfo
  1133. +texi application/x-texinfo
  1134. +t application/x-troff
  1135. tr application/x-troff
  1136. roff application/x-troff
  1137. man application/x-troff-man
  1138. me application/x-troff-me
  1139. ms application/x-troff-ms
  1140. -zip application/x-zip-compressed
  1141. -tsp application/dsptype
  1142. -wsrc application/x-wais-source
  1143. ustar application/x-ustar
  1144. -cdf application/x-netcdf
  1145. -nc application/x-netcdf
  1146. -doc application/msword
  1147. -ppt application/powerpoint
  1148. -
  1149. -crt application/x-x509-ca-cert
  1150. -crl application/x-pkcs7-crl
  1151. -
  1152. +src application/x-wais-source
  1153. +xhtml application/xhtml+xml
  1154. +xht application/xhtml+xml
  1155. +zip application/zip
  1156. +au audio/basic
  1157. +snd audio/basic
  1158. +mid audio/midi
  1159. +midi audio/midi
  1160. +kar audio/midi
  1161. +mpga audio/mpeg
  1162. +mp2 audio/mpeg
  1163. +mp3 audio/mpeg
  1164. +aif audio/x-aiff
  1165. +aiff audio/x-aiff
  1166. +aifc audio/x-aiff
  1167. +m3u audio/x-mpegurl
  1168. +ram audio/x-pn-realaudio
  1169. +rm audio/x-pn-realaudio
  1170. +rpm audio/x-pn-realaudio-plugin
  1171. +ra audio/x-realaudio
  1172. +wav audio/x-wav
  1173. +pdb chemical/x-pdb
  1174. +xyz chemical/x-xyz
  1175. +bmp image/bmp
  1176. +gif image/gif
  1177. +ief image/ief
  1178. +jpeg image/jpeg
  1179. +jpg image/jpeg
  1180. +jpe image/jpeg
  1181. +png image/png
  1182. +tiff image/tiff
  1183. +tif image/tiff
  1184. +djvu image/vnd.djvu
  1185. +djv image/vnd.djvu
  1186. +wbmp image/vnd.wap.wbmp
  1187. +ras image/x-cmu-raster
  1188. +pnm image/x-portable-anymap
  1189. +pbm image/x-portable-bitmap
  1190. +pgm image/x-portable-graymap
  1191. +ppm image/x-portable-pixmap
  1192. +rgb image/x-rgb
  1193. +xbm image/x-xbitmap
  1194. +xpm image/x-xpixmap
  1195. +xwd image/x-xwindowdump
  1196. +igs model/iges
  1197. +iges model/iges
  1198. +msh model/mesh
  1199. +mesh model/mesh
  1200. +silo model/mesh
  1201. wrl model/vrml
  1202. vrml model/vrml
  1203. -mime message/rfc822
  1204. -
  1205. -pac application/x-ns-proxy-autoconfig
  1206. -
  1207. +css text/css
  1208. +html text/html; charset=%s
  1209. +htm text/html; charset=%s
  1210. +asc text/plain; charset=%s
  1211. +txt text/plain; charset=%s
  1212. +rtx text/richtext
  1213. +rtf text/rtf
  1214. +sgml text/sgml
  1215. +sgm text/sgml
  1216. +tsv text/tab-separated-values
  1217. wml text/vnd.wap.wml
  1218. -wmlc application/vnd.wap.wmlc
  1219. wmls text/vnd.wap.wmlscript
  1220. -wmlsc application/vnd.wap.wmlscriptc
  1221. -wbmp image/vnd.wap.wbmp
  1222. +etx text/x-setext
  1223. +xml text/xml
  1224. +xsl text/xml
  1225. +mpeg video/mpeg
  1226. +mpg video/mpeg
  1227. +mpe video/mpeg
  1228. +qt video/quicktime
  1229. +mov video/quicktime
  1230. +mxu video/vnd.mpegurl
  1231. +avi video/x-msvideo
  1232. +movie video/x-sgi-movie
  1233. +ice x-conference/x-cooltalk
  1234. diff -ur thttpd-2.21b/mmc.c thttpd-2.21b-cool/mmc.c
  1235. --- thttpd-2.21b/mmc.c Fri Apr 13 23:02:15 2001
  1236. +++ thttpd-2.21b-cool/mmc.c Sat Sep 20 14:43:20 2003
  1237. @@ -70,6 +70,9 @@
  1238. unsigned int hash;
  1239. int hash_idx;
  1240. struct MapStruct* next;
  1241. + char nocache;
  1242. + size_t last_modified_len;
  1243. + char last_modified[100];
  1244. } Map;
  1245. @@ -93,12 +96,13 @@
  1246. void*
  1247. -mmc_map( char* filename, struct stat* sbP, struct timeval* nowP )
  1248. +mmc_map( char* filename, struct stat* sbP, struct timeval* nowP, int nocache, char **last_modified, size_t *last_modified_len )
  1249. {
  1250. time_t now;
  1251. struct stat sb;
  1252. Map* m;
  1253. int fd;
  1254. + const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
  1255. /* Stat the file, if necessary. */
  1256. if ( sbP != (struct stat*) 0 )
  1257. @@ -130,7 +134,7 @@
  1258. /* Yep. Just return the existing map */
  1259. ++m->refcount;
  1260. m->reftime = now;
  1261. - return m->addr;
  1262. + goto done;
  1263. }
  1264. /* Open the file. */
  1265. @@ -167,12 +171,13 @@
  1266. m->ctime = sb.st_ctime;
  1267. m->refcount = 1;
  1268. m->reftime = now;
  1269. + m->nocache = (char) nocache;
  1270. /* Avoid doing anything for zero-length files; some systems don't like
  1271. ** to mmap them, other systems dislike mallocing zero bytes.
  1272. */
  1273. if ( m->size == 0 )
  1274. - m->addr = (void*) 1; /* arbitrary non-NULL address */
  1275. + m->addr = (void*) 5; /* arbitrary non-NULL address */
  1276. else
  1277. {
  1278. #ifdef HAVE_MMAP
  1279. @@ -223,6 +228,13 @@
  1280. maps = m;
  1281. ++map_count;
  1282. + strftime( m->last_modified, sizeof(m->last_modified), rfc1123fmt, gmtime( &sb.st_mtime ) );
  1283. + m->last_modified_len = strlen(m->last_modified);
  1284. +
  1285. +done:
  1286. + *last_modified = m->last_modified;
  1287. + *last_modified_len = m->last_modified_len;
  1288. +
  1289. /* And return the address. */
  1290. return m->addr;
  1291. }
  1292. @@ -231,27 +243,32 @@
  1293. void
  1294. mmc_unmap( void* addr, struct stat* sbP, struct timeval* nowP )
  1295. {
  1296. - Map* m = (Map*) 0;
  1297. + Map* m = (Map*) 0, **mm = &maps;
  1298. /* Find the Map entry for this address. First try a hash. */
  1299. if ( sbP != (struct stat*) 0 )
  1300. {
  1301. m = find_hash( sbP->st_ino, sbP->st_dev, sbP->st_size, sbP->st_ctime );
  1302. - if ( m != (Map*) 0 && m->addr != addr )
  1303. + if ( m != (Map*) 0 && ( m->addr != addr || m->nocache == 1 ) )
  1304. m = (Map*) 0;
  1305. }
  1306. /* If that didn't work, try a full search. */
  1307. if ( m == (Map*) 0 )
  1308. - for ( m = maps; m != (Map*) 0; m = m->next )
  1309. + for ( m = maps; m != (Map*) 0; m = m->next ) {
  1310. if ( m->addr == addr )
  1311. break;
  1312. + mm = &m->next;
  1313. + }
  1314. if ( m == (Map*) 0 )
  1315. syslog( LOG_ERR, "mmc_unmap failed to find entry!" );
  1316. else if ( m->refcount <= 0 )
  1317. syslog( LOG_ERR, "mmc_unmap found zero or negative refcount!" );
  1318. else
  1319. {
  1320. - --m->refcount;
  1321. + if ( --m->refcount == 0 && m->nocache == 1 ) {
  1322. + really_unmap( mm );
  1323. + return;
  1324. + }
  1325. if ( nowP != (struct timeval*) 0 )
  1326. m->reftime = nowP->tv_sec;
  1327. else
  1328. diff -ur thttpd-2.21b/mmc.h thttpd-2.21b-cool/mmc.h
  1329. --- thttpd-2.21b/mmc.h Fri Apr 13 07:36:54 2001
  1330. +++ thttpd-2.21b-cool/mmc.h Sat Sep 20 14:43:20 2003
  1331. @@ -31,8 +31,9 @@
  1332. /* Returns an mmap()ed area for the given file, or (void*) 0 on errors.
  1333. ** If you have a stat buffer on the file, pass it in, otherwise pass 0.
  1334. ** Same for the current time.
  1335. +** Set nocache to 1, if this entry is supposed to be removed quickly.
  1336. */
  1337. -extern void* mmc_map( char* filename, struct stat* sbP, struct timeval* nowP );
  1338. +extern void* mmc_map( char* filename, struct stat* sbP, struct timeval* nowP, int nocache, char **last_modified, size_t *last_modified_len );
  1339. /* Done with an mmap()ed area that was returned by mmc_map().
  1340. ** If you have a stat buffer on the file, pass it in, otherwise pass 0.
  1341. diff -ur thttpd-2.21b/thttpd.c thttpd-2.21b-cool/thttpd.c
  1342. --- thttpd-2.21b/thttpd.c Tue Apr 24 00:41:57 2001
  1343. +++ thttpd-2.21b-cool/thttpd.c Sat Sep 20 14:43:20 2003
  1344. @@ -53,6 +53,10 @@
  1345. #endif
  1346. #include <unistd.h>
  1347. +#include <sys/mman.h>
  1348. +
  1349. +#include <limits.h>
  1350. +
  1351. #include "fdwatch.h"
  1352. #include "libhttpd.h"
  1353. #include "mmc.h"
  1354. @@ -66,6 +70,8 @@
  1355. static char* dir;
  1356. static int do_chroot, no_log, no_symlink, do_vhost, do_global_passwd;
  1357. static char* cgi_pattern;
  1358. +static char* php_pattern;
  1359. +static char* phps_pattern;
  1360. static char* url_pattern;
  1361. static int no_empty_referers;
  1362. static char* local_pattern;
  1363. @@ -95,10 +101,10 @@
  1364. httpd_conn* hc;
  1365. int tnums[MAXTHROTTLENUMS]; /* throttle indexes */
  1366. int numtnums;
  1367. + int keep_alive;
  1368. long limit;
  1369. time_t started_at;
  1370. - Timer* idle_read_timer;
  1371. - Timer* idle_send_timer;
  1372. + time_t last_io;
  1373. Timer* wakeup_timer;
  1374. Timer* linger_timer;
  1375. long wouldblock_delay;
  1376. @@ -106,17 +112,22 @@
  1377. off_t bytes_sent;
  1378. off_t bytes_to_send;
  1379. } connecttab;
  1380. -static connecttab* connects;
  1381. +static connecttab* connects, **free_connects;
  1382. +static int next_free_connect;
  1383. static int numconnects, maxconnects;
  1384. static int httpd_conn_count;
  1385. /* The connection states. */
  1386. -#define CNST_FREE 0
  1387. -#define CNST_READING 1
  1388. -#define CNST_SENDING 2
  1389. -#define CNST_PAUSING 3
  1390. -#define CNST_LINGERING 4
  1391. -
  1392. +enum {
  1393. + CNST_FREE = 0,
  1394. + CNST_READING,
  1395. + CNST_SENDING,
  1396. + CNST_PAUSING,
  1397. + CNST_LINGERING,
  1398. + CNST_SENDING_RESP,
  1399. + CNST_READING_BODY,
  1400. + CNST_TOTAL_NR
  1401. +};
  1402. static httpd_server* hs = (httpd_server*) 0;
  1403. int terminate = 0;
  1404. @@ -140,23 +151,32 @@
  1405. static int handle_newconnect( struct timeval* tvP, int listen_fd );
  1406. static void handle_read( connecttab* c, struct timeval* tvP );
  1407. static void handle_send( connecttab* c, struct timeval* tvP );
  1408. +static void handle_send_resp( connecttab* c, struct timeval* tvP );
  1409. +static void handle_read_body( connecttab* c, struct timeval* tvP );
  1410. static void handle_linger( connecttab* c, struct timeval* tvP );
  1411. static int check_throttles( connecttab* c );
  1412. +static void timeout_conns( ClientData client_data, struct timeval* nowP );
  1413. static void clear_throttles( connecttab* c, struct timeval* tvP );
  1414. static void update_throttles( ClientData client_data, struct timeval* nowP );
  1415. -static void clear_connection( connecttab* c, struct timeval* tvP );
  1416. +static void clear_connection( connecttab* c, struct timeval* tvP, int );
  1417. static void really_clear_connection( connecttab* c, struct timeval* tvP );
  1418. -static void idle_read_connection( ClientData client_data, struct timeval* nowP );
  1419. -static void idle_send_connection( ClientData client_data, struct timeval* nowP );
  1420. static void wakeup_connection( ClientData client_data, struct timeval* nowP );
  1421. static void linger_clear_connection( ClientData client_data, struct timeval* nowP );
  1422. static void occasional( ClientData client_data, struct timeval* nowP );
  1423. +static void periodic_jobs( ClientData client_data, struct timeval* nowP );
  1424. #ifdef STATS_TIME
  1425. static void show_stats( ClientData client_data, struct timeval* nowP );
  1426. #endif /* STATS_TIME */
  1427. static void logstats( struct timeval* nowP );
  1428. static void thttpd_logstats( long secs );
  1429. +static void boot_request(connecttab *c, struct timeval *tvP);
  1430. +
  1431. +typedef void (*handler_func)(connecttab*, struct timeval *);
  1432. +
  1433. +handler_func handler_array[CNST_TOTAL_NR] =
  1434. +{NULL, handle_read, handle_send, NULL, handle_linger, handle_send_resp, handle_read_body};
  1435. +#define RUN_HANDLER(type, c) if (handler_array[type]) handler_array[type](c, &tv)
  1436. static void
  1437. handle_term( int sig )
  1438. @@ -177,7 +197,7 @@
  1439. return;
  1440. /* Re-open the log file. */
  1441. - if ( logfile != (char*) 0 )
  1442. + if ( logfile != (char*) 0 && strcmp(logfile, "-") != 0)
  1443. {
  1444. logfp = fopen( logfile, "a" );
  1445. if ( logfp == (FILE*) 0 )
  1446. @@ -198,6 +218,8 @@
  1447. }
  1448. +time_t httpd_time_now;
  1449. +
  1450. static void
  1451. handle_usr2( int sig )
  1452. {
  1453. @@ -217,7 +239,6 @@
  1454. int num_ready;
  1455. int cnum, ridx;
  1456. connecttab* c;
  1457. - httpd_conn* hc;
  1458. httpd_sockaddr sa4;
  1459. httpd_sockaddr sa6;
  1460. int gotv4, gotv6;
  1461. @@ -270,7 +291,9 @@
  1462. no_log = 1;
  1463. logfp = (FILE*) 0;
  1464. }
  1465. - else
  1466. + else if (strcmp(logfile, "-") == 0) {
  1467. + logfp = stdout;
  1468. + } else
  1469. {
  1470. logfp = fopen( logfile, "a" );
  1471. if ( logfp == (FILE*) 0 )
  1472. @@ -420,7 +443,8 @@
  1473. hostname,
  1474. gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0,
  1475. port, cgi_pattern, charset, cwd, no_log, logfp, no_symlink, do_vhost,
  1476. - do_global_passwd, url_pattern, local_pattern, no_empty_referers );
  1477. + do_global_passwd, url_pattern, local_pattern, no_empty_referers,
  1478. + php_pattern, phps_pattern);
  1479. if ( hs == (httpd_server*) 0 )
  1480. exit( 1 );
  1481. @@ -430,6 +454,12 @@
  1482. syslog( LOG_CRIT, "tmr_create(occasional) failed" );
  1483. exit( 1 );
  1484. }
  1485. +
  1486. + if (tmr_create(0, timeout_conns, JunkClientData, 30 * 1000, 1) == 0) {
  1487. + syslog(LOG_CRIT, "tmr_create(timeout_conns) failed");
  1488. + exit(1);
  1489. + }
  1490. +
  1491. if ( numthrottles > 0 )
  1492. {
  1493. /* Set up the throttles timer. */
  1494. @@ -439,6 +469,12 @@
  1495. exit( 1 );
  1496. }
  1497. }
  1498. +
  1499. + if (tmr_create(0, periodic_jobs, JunkClientData, 2000, 1) == 0) {
  1500. + syslog(LOG_CRIT, "tmr_create failed");
  1501. + exit(1);
  1502. + }
  1503. +
  1504. #ifdef STATS_TIME
  1505. /* Set up the stats timer. */
  1506. if ( tmr_create( (struct timeval*) 0, show_stats, JunkClientData, STATS_TIME * 1000L, 1 ) == (Timer*) 0 )
  1507. @@ -454,12 +490,14 @@
  1508. /* If we're root, try to become someone else. */
  1509. if ( getuid() == 0 )
  1510. {
  1511. +#ifndef __CYGWIN__
  1512. /* Set aux groups to null. */
  1513. if ( setgroups( 0, (const gid_t*) 0 ) < 0 )
  1514. {
  1515. syslog( LOG_CRIT, "setgroups - %m" );
  1516. exit( 1 );
  1517. }
  1518. +#endif
  1519. /* Set primary group. */
  1520. if ( setgid( gid ) < 0 )
  1521. {
  1522. @@ -495,13 +533,17 @@
  1523. }
  1524. maxconnects -= SPARE_FDS;
  1525. connects = NEW( connecttab, maxconnects );
  1526. + free_connects = malloc(sizeof(connecttab *) * maxconnects);
  1527. + next_free_connect = maxconnects;
  1528. if ( connects == (connecttab*) 0 )
  1529. {
  1530. syslog( LOG_CRIT, "out of memory allocating a connecttab" );
  1531. exit( 1 );
  1532. }
  1533. +
  1534. for ( cnum = 0; cnum < maxconnects; ++cnum )
  1535. {
  1536. + free_connects[cnum] = &connects[maxconnects - cnum - 1];
  1537. connects[cnum].conn_state = CNST_FREE;
  1538. connects[cnum].hc = (httpd_conn*) 0;
  1539. }
  1540. @@ -518,6 +560,9 @@
  1541. /* Main loop. */
  1542. (void) gettimeofday( &tv, (struct timezone*) 0 );
  1543. + httpd_time_now = tv.tv_sec;
  1544. + periodic_jobs(JunkClientData, &tv);
  1545. +
  1546. while ( ( ! terminate ) || numconnects > 0 )
  1547. {
  1548. /* Do the fd watch. */
  1549. @@ -530,6 +575,7 @@
  1550. exit( 1 );
  1551. }
  1552. (void) gettimeofday( &tv, (struct timezone*) 0 );
  1553. + httpd_time_now = tv.tv_sec;
  1554. if ( num_ready == 0 )
  1555. {
  1556. /* No fd's are ready - run the timers. */
  1557. @@ -565,16 +611,10 @@
  1558. c = (connecttab*) fdwatch_get_client_data( ridx );
  1559. if ( c == (connecttab*) 0 )
  1560. continue;
  1561. - hc = c->hc;
  1562. - if ( c->conn_state == CNST_READING &&
  1563. - fdwatch_check_fd( hc->conn_fd ) )
  1564. - handle_read( c, &tv );
  1565. - else if ( c->conn_state == CNST_SENDING &&
  1566. - fdwatch_check_fd( hc->conn_fd ) )
  1567. - handle_send( c, &tv );
  1568. - else if ( c->conn_state == CNST_LINGERING &&
  1569. - fdwatch_check_fd( hc->conn_fd ) )
  1570. - handle_linger( c, &tv );
  1571. +#if DO_UNNECESSARY_CHECK_FD
  1572. + fdwatch_check_fd(c->hc->conn_fd);
  1573. +#endif
  1574. + RUN_HANDLER(c->conn_state, c);
  1575. }
  1576. tmr_run( &tv );
  1577. @@ -627,6 +667,8 @@
  1578. #else /* CGI_PATTERN */
  1579. cgi_pattern = (char*) 0;
  1580. #endif /* CGI_PATTERN */
  1581. + php_pattern = "**.php";
  1582. + phps_pattern = "**.phps";
  1583. url_pattern = (char*) 0;
  1584. no_empty_referers = 0;
  1585. local_pattern = (char*) 0;
  1586. @@ -833,6 +875,16 @@
  1587. value_required( name, value );
  1588. cgi_pattern = e_strdup( value );
  1589. }
  1590. + else if ( strcasecmp( name, "phppat" ) == 0 )
  1591. + {
  1592. + value_required( name, value );
  1593. + php_pattern = e_strdup( value );
  1594. + }
  1595. + else if ( strcasecmp( name, "phpspat" ) == 0 )
  1596. + {
  1597. + value_required( name, value );
  1598. + phps_pattern = e_strdup( value );
  1599. + }
  1600. else if ( strcasecmp( name, "urlpat" ) == 0 )
  1601. {
  1602. value_required( name, value );
  1603. @@ -1196,8 +1248,10 @@
  1604. logstats( &tv );
  1605. for ( cnum = 0; cnum < maxconnects; ++cnum )
  1606. {
  1607. - if ( connects[cnum].conn_state != CNST_FREE )
  1608. + if ( connects[cnum].conn_state != CNST_FREE ) {
  1609. + httpd_complete_request( connects[cnum].hc, &tv );
  1610. httpd_close_conn( connects[cnum].hc, &tv );
  1611. + }
  1612. if ( connects[cnum].hc != (httpd_conn*) 0 )
  1613. {
  1614. httpd_destroy_conn( connects[cnum].hc );
  1615. @@ -1214,6 +1268,7 @@
  1616. }
  1617. mmc_destroy();
  1618. tmr_destroy();
  1619. + free( (void*) free_connects );
  1620. free( (void*) connects );
  1621. if ( throttles != (throttletab*) 0 )
  1622. free( (void*) throttles );
  1623. @@ -1234,7 +1289,7 @@
  1624. for (;;)
  1625. {
  1626. /* Is there room in the connection table? */
  1627. - if ( numconnects >= maxconnects )
  1628. + if ( numconnects >= maxconnects || next_free_connect == 0 )
  1629. {
  1630. /* Out of connection slots. Run the timers, then the
  1631. ** existing connections, and maybe we'll free up a slot
  1632. @@ -1245,10 +1300,10 @@
  1633. return 0;
  1634. }
  1635. /* Find a free connection entry. */
  1636. - for ( cnum = 0; cnum < maxconnects; ++cnum )
  1637. - if ( connects[cnum].conn_state == CNST_FREE )
  1638. - break;
  1639. - c = &connects[cnum];
  1640. +
  1641. + c = free_connects[--next_free_connect];
  1642. + free_connects[next_free_connect] = NULL;
  1643. +
  1644. /* Make the httpd_conn if necessary. */
  1645. if ( c->hc == (httpd_conn*) 0 )
  1646. {
  1647. @@ -1267,24 +1322,18 @@
  1648. {
  1649. case GC_FAIL:
  1650. case GC_NO_MORE:
  1651. + free_connects[next_free_connect++] = c;
  1652. return 1;
  1653. }
  1654. c->conn_state = CNST_READING;
  1655. ++numconnects;
  1656. client_data.p = c;
  1657. - c->idle_read_timer = tmr_create(
  1658. - tvP, idle_read_connection, client_data, IDLE_READ_TIMELIMIT * 1000L,
  1659. - 0 );
  1660. - if ( c->idle_read_timer == (Timer*) 0 )
  1661. - {
  1662. - syslog( LOG_CRIT, "tmr_create(idle_read_connection) failed" );
  1663. - exit( 1 );
  1664. - }
  1665. - c->idle_send_timer = (Timer*) 0;
  1666. c->wakeup_timer = (Timer*) 0;
  1667. c->linger_timer = (Timer*) 0;
  1668. c->bytes_sent = 0;
  1669. c->numtnums = 0;
  1670. + c->keep_alive = 0;
  1671. + c->last_io = httpd_time_now;
  1672. /* Set the connection file descriptor to no-delay mode. */
  1673. httpd_set_ndelay( c->hc->conn_fd );
  1674. @@ -1298,11 +1347,100 @@
  1675. }
  1676. +#define FIXUP(x) if (hc->x >= oldptr && hc->x < pe) hc->x += d
  1677. +
  1678. +static void
  1679. +realign_hc(httpd_conn *hc, char *oldptr)
  1680. +{
  1681. + int d = hc->read_buf - oldptr;
  1682. + char *pe = oldptr + hc->checked_idx;
  1683. +
  1684. + FIXUP(encodedurl);
  1685. + FIXUP(protocol);
  1686. + FIXUP(referer);
  1687. + FIXUP(useragent);
  1688. + FIXUP(acceptl);
  1689. + FIXUP(cookie);
  1690. + FIXUP(contenttype);
  1691. + FIXUP(hdrhost);
  1692. + FIXUP(authorization);
  1693. +}
  1694. +
  1695. +#undef FIXUP
  1696. +
  1697. +static void
  1698. +setup_read_body(connecttab *c, struct timeval *tvP)
  1699. +{
  1700. + httpd_conn *hc = c->hc;
  1701. + int already, missing;
  1702. + char *oldptr = hc->read_buf;
  1703. +
  1704. + c->conn_state = CNST_READING_BODY;
  1705. +
  1706. + hc->read_body_into_mem = 0;
  1707. +
  1708. + already = hc->read_idx - hc->checked_idx;
  1709. + missing = hc->contentlength - already;
  1710. +
  1711. + if (missing > 16384) {
  1712. + char filename[] = "/tmp/thttpd.upload.XXXXXX";
  1713. + int tmp = mkstemp(filename);
  1714. +
  1715. + if (tmp >= 0) {
  1716. + void *p;
  1717. + size_t sz = hc->contentlength + hc->checked_idx + 10;
  1718. +
  1719. + unlink(filename);
  1720. +
  1721. + ftruncate(tmp, sz);
  1722. + p = mmap(NULL, sz,
  1723. + PROT_READ|PROT_WRITE, MAP_PRIVATE, tmp, 0);
  1724. +
  1725. + if (p != MAP_FAILED) {
  1726. + memcpy(p, hc->read_buf, hc->read_idx);
  1727. + free(hc->read_buf);
  1728. + hc->read_size = sz;
  1729. + hc->read_buf = p;
  1730. + hc->read_buf_is_mmap = 1;
  1731. + }
  1732. + close(tmp);
  1733. + }
  1734. +
  1735. + if (!hc->read_buf_is_mmap) {
  1736. + clear_connection( c, tvP, 0 );
  1737. + return;
  1738. + }
  1739. + } else if (missing > 0) {
  1740. + httpd_realloc_str(&hc->read_buf, &hc->read_size, hc->checked_idx + hc->contentlength + 10);
  1741. + }
  1742. + if (oldptr != hc->read_buf) realign_hc(hc, oldptr);
  1743. +
  1744. + fdwatch_del_fd( hc->conn_fd );
  1745. + fdwatch_add_fd( hc->conn_fd, c, FDW_READ );
  1746. +}
  1747. +
  1748. +static void
  1749. +setup_sending(connecttab *c, int state, struct timeval *tvP)
  1750. +{
  1751. + httpd_conn *hc = c->hc;
  1752. + ClientData client_data;
  1753. +
  1754. + c->conn_state = state;
  1755. + c->started_at = tvP->tv_sec;
  1756. + c->wouldblock_delay = 0;
  1757. + client_data.p = c;
  1758. +
  1759. + fdwatch_del_fd( hc->conn_fd );
  1760. + fdwatch_add_fd( hc->conn_fd, c, FDW_WRITE );
  1761. +}
  1762. +
  1763. +static void handle_request( connecttab *c, struct timeval *tvP);
  1764. +
  1765. +
  1766. static void
  1767. handle_read( connecttab* c, struct timeval* tvP )
  1768. {
  1769. int sz;
  1770. - ClientData client_data;
  1771. httpd_conn* hc = c->hc;
  1772. /* Is there room in our buffer to read more bytes? */
  1773. @@ -1311,7 +1449,7 @@
  1774. if ( hc->read_size > 5000 )
  1775. {
  1776. httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
  1777. - clear_connection( c, tvP );
  1778. + clear_connection( c, tvP, 0 );
  1779. return;
  1780. }
  1781. httpd_realloc_str(
  1782. @@ -1327,14 +1465,53 @@
  1783. ** EWOULDBLOCK; however, this apparently can happen if a packet gets
  1784. ** garbled.
  1785. */
  1786. - if ( sz == 0 || ( sz < 0 && ( errno != EWOULDBLOCK ) ) )
  1787. - {
  1788. - httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
  1789. - clear_connection( c, tvP );
  1790. + if ( sz == 0 ) {
  1791. + if (! c->keep_alive) {
  1792. + httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
  1793. + }
  1794. + clear_connection( c, tvP, 0 );
  1795. + return;
  1796. + } else if ( sz < 0 ) {
  1797. + if (errno != EWOULDBLOCK) {
  1798. + clear_connection( c, tvP, 0 );
  1799. + }
  1800. return;
  1801. + }
  1802. +
  1803. + /* If this is a persistent PHP connection, we must not receive
  1804. + ** any further requests on this connection. Some broken HTTP/1.1
  1805. + ** implementations (e.g. Mozilla 1.0.1) are known to do
  1806. + ** pipelining on a connection, although a prior response included
  1807. + ** Connection: close
  1808. + */
  1809. + if (c->hc->file_address == (char *) 1) {
  1810. + return;
  1811. + }
  1812. +
  1813. + c->last_io = httpd_time_now;
  1814. + if (sz > 0) hc->read_idx += sz;
  1815. +
  1816. + /*
  1817. + ** if we start getting new data on this socket, "promote" it
  1818. + ** to read timeout
  1819. + */
  1820. + if ( hc->keep_alive ) {
  1821. + ClientData client_data;
  1822. +
  1823. +
  1824. + client_data.p = c;
  1825. +
  1826. + hc->keep_alive = 0;
  1827. + }
  1828. + handle_request(c, tvP);
  1829. }
  1830. - hc->read_idx += sz;
  1831. +
  1832. +static void
  1833. +handle_request( connecttab *c, struct timeval *tvP)
  1834. +{
  1835. + httpd_conn* hc = c->hc;
  1836. +
  1837. /* Do we have a complete request yet? */
  1838. switch ( httpd_got_request( hc ) )
  1839. {
  1840. @@ -1342,14 +1519,14 @@
  1841. return;
  1842. case GR_BAD_REQUEST:
  1843. httpd_send_err( hc, 400, httpd_err400title, "", httpd_err400form, "" );
  1844. - clear_connection( c, tvP );
  1845. + clear_connection( c, tvP, 0 );
  1846. return;
  1847. }
  1848. /* Yes. Try parsing and resolving it. */
  1849. if ( httpd_parse_request( hc ) < 0 )
  1850. {
  1851. - clear_connection( c, tvP );
  1852. + clear_connection( c, tvP, 0 );
  1853. return;
  1854. }
  1855. @@ -1358,18 +1535,28 @@
  1856. {
  1857. httpd_send_err(
  1858. hc, 503, httpd_err503title, "", httpd_err503form, hc->encodedurl );
  1859. - clear_connection( c, tvP );
  1860. + clear_connection( c, tvP, 0 );
  1861. return;
  1862. }
  1863. + boot_request(c, tvP);
  1864. +}
  1865. +static void boot_request(connecttab *c, struct timeval *tvP)
  1866. +{
  1867. + httpd_conn *hc = c->hc;
  1868. /* Start the connection going. */
  1869. if ( httpd_start_request( hc, tvP ) < 0 )
  1870. {
  1871. /* Something went wrong. Close down the connection. */
  1872. - clear_connection( c, tvP );
  1873. + clear_connection( c, tvP, 0 );
  1874. return;
  1875. }
  1876. + if ( hc->read_body_into_mem ) {
  1877. + setup_read_body( c, tvP );
  1878. + return;
  1879. + }
  1880. +
  1881. /* Fill in bytes_to_send. */
  1882. if ( hc->got_range )
  1883. {
  1884. @@ -1384,37 +1571,25 @@
  1885. {
  1886. /* No file address means someone else is handling it. */
  1887. c->bytes_sent = hc->bytes_sent;
  1888. - clear_connection( c, tvP );
  1889. + clear_connection( c, tvP, 1 );
  1890. return;
  1891. }
  1892. + if (hc->file_address == (char *) 1) {
  1893. + c->last_io = (time_t) LONG_MAX;
  1894. + c->wouldblock_delay = 0;
  1895. + return;
  1896. + }
  1897. if ( c->bytes_sent >= c->bytes_to_send )
  1898. {
  1899. /* There's nothing to send. */
  1900. - clear_connection( c, tvP );
  1901. + clear_connection( c, tvP, 1 );
  1902. return;
  1903. }
  1904. /* Cool, we have a valid connection and a file to send to it. */
  1905. - c->conn_state = CNST_SENDING;
  1906. - c->started_at = tvP->tv_sec;
  1907. - c->wouldblock_delay = 0;
  1908. - client_data.p = c;
  1909. - tmr_cancel( c->idle_read_timer );
  1910. - c->idle_read_timer = (Timer*) 0;
  1911. - c->idle_send_timer = tmr_create(
  1912. - tvP, idle_send_connection, client_data, IDLE_SEND_TIMELIMIT * 1000L,
  1913. - 0 );
  1914. - if ( c->idle_send_timer == (Timer*) 0 )
  1915. - {
  1916. - syslog( LOG_CRIT, "tmr_create(idle_send_connection) failed" );
  1917. - exit( 1 );
  1918. - }
  1919. -
  1920. - fdwatch_del_fd( hc->conn_fd );
  1921. - fdwatch_add_fd( hc->conn_fd, c, FDW_WRITE );
  1922. + setup_sending(c, CNST_SENDING, tvP);
  1923. }
  1924. -
  1925. static void
  1926. handle_send( connecttab* c, struct timeval* tvP )
  1927. {
  1928. @@ -1443,6 +1618,9 @@
  1929. iv[1].iov_base = &(hc->file_address[c->bytes_sent]);
  1930. iv[1].iov_len = MIN( c->bytes_to_send - c->bytes_sent, c->limit );
  1931. sz = writev( hc->conn_fd, iv, 2 );
  1932. +/*
  1933. +printf("**RESPONSE2 [%d]** len = %d\n%*.*s\n", hc->conn_fd, hc->responselen, hc->responselen, hc->responselen, hc->response);
  1934. +*/
  1935. }
  1936. if ( sz == 0 ||
  1937. @@ -1486,12 +1664,12 @@
  1938. */
  1939. if ( errno != EPIPE && errno != EINVAL && errno != ECONNRESET )
  1940. syslog( LOG_ERR, "write - %m sending %.80s", hc->encodedurl );
  1941. - clear_connection( c, tvP );
  1942. + clear_connection( c, tvP, 0 );
  1943. return;
  1944. }
  1945. /* Ok, we wrote something. */
  1946. - tmr_reset( tvP, c->idle_send_timer );
  1947. + c->last_io = httpd_time_now;
  1948. /* Was this a headers + file writev()? */
  1949. if ( hc->responselen > 0 )
  1950. {
  1951. @@ -1500,7 +1678,7 @@
  1952. {
  1953. /* Yes; move the unwritten part to the front of the buffer. */
  1954. int newlen = hc->responselen - sz;
  1955. - (void) memcpy( hc->response, &(hc->response[sz]), newlen );
  1956. + (void) memmove( hc->response, &(hc->response[sz]), newlen );
  1957. hc->responselen = newlen;
  1958. sz = 0;
  1959. }
  1960. @@ -1519,7 +1697,7 @@
  1961. if ( c->bytes_sent >= c->bytes_to_send )
  1962. {
  1963. /* This connection is finished! */
  1964. - clear_connection( c, tvP );
  1965. + clear_connection( c, tvP, 1 );
  1966. return;
  1967. }
  1968. @@ -1560,6 +1738,9 @@
  1969. char buf[1024];
  1970. int r;
  1971. +/*
  1972. +printf("*LINGER read\n");
  1973. +*/
  1974. /* In lingering-close mode we just read and ignore bytes. An error
  1975. ** or EOF ends things, otherwise we go until a timeout.
  1976. */
  1977. @@ -1569,6 +1750,63 @@
  1978. }
  1979. +static void
  1980. +handle_read_body(connecttab *c, struct timeval *tvP)
  1981. +{
  1982. + httpd_conn *hc = c->hc;
  1983. + int n;
  1984. +
  1985. + n = read(hc->conn_fd, hc->read_buf + hc->read_idx,
  1986. + hc->contentlength - (hc->read_idx - hc->checked_idx));
  1987. +
  1988. + if (n <= 0) {
  1989. + if (errno == EAGAIN)
  1990. + return;
  1991. + clear_connection(c, tvP, 0);
  1992. + return;
  1993. + }
  1994. +
  1995. + c->last_io = httpd_time_now;
  1996. +
  1997. + hc->read_idx += n;
  1998. +
  1999. + if (hc->contentlength == hc->read_idx - hc->checked_idx) {
  2000. + boot_request(c, tvP);
  2001. + return;
  2002. + }
  2003. +}
  2004. +
  2005. +static void
  2006. +handle_send_resp(connecttab *c, struct timeval *tvP)
  2007. +{
  2008. + httpd_conn* hc = c->hc;
  2009. + int n = send(hc->conn_fd, hc->response, hc->responselen, 0);
  2010. + int dokeep = 1;
  2011. +
  2012. + if (n < 0) {
  2013. + if (errno == EAGAIN)
  2014. + return;
  2015. +
  2016. + dokeep = 0;
  2017. + goto clear;
  2018. + }
  2019. +
  2020. + c->last_io = httpd_time_now;
  2021. +
  2022. + if (n == hc->responselen) {
  2023. +clear:
  2024. + hc->response = realloc(hc->response, hc->maxresponse + 1);
  2025. + hc->responselen = 0;
  2026. +
  2027. + clear_connection(c, tvP, dokeep);
  2028. + return;
  2029. + }
  2030. +
  2031. + hc->responselen -= n;
  2032. +
  2033. + memmove(hc->response, hc->response + n, hc->responselen);
  2034. +}
  2035. +
  2036. static int
  2037. check_throttles( connecttab* c )
  2038. {
  2039. @@ -1635,23 +1873,18 @@
  2040. static void
  2041. -clear_connection( connecttab* c, struct timeval* tvP )
  2042. +clear_connection( connecttab* c, struct timeval* tvP, int doKeep )
  2043. {
  2044. ClientData client_data;
  2045. + int linger;
  2046. /* If we haven't actually sent the buffered response yet, do so now. */
  2047. - httpd_write_response( c->hc );
  2048. + if (c->hc->responselen && c->conn_state != CNST_SENDING_RESP) {
  2049. + setup_sending(c, CNST_SENDING_RESP, tvP);
  2050. - if ( c->idle_read_timer != (Timer*) 0 )
  2051. - {
  2052. - tmr_cancel( c->idle_read_timer );
  2053. - c->idle_read_timer = 0;
  2054. - }
  2055. - if ( c->idle_send_timer != (Timer*) 0 )
  2056. - {
  2057. - tmr_cancel( c->idle_send_timer );
  2058. - c->idle_send_timer = 0;
  2059. + return;
  2060. }
  2061. +
  2062. if ( c->wakeup_timer != (Timer*) 0 )
  2063. {
  2064. tmr_cancel( c->wakeup_timer );
  2065. @@ -1669,13 +1902,36 @@
  2066. ** circumstances that make a lingering close necessary. If the flag
  2067. ** isn't set we do the real close now.
  2068. */
  2069. - if ( c->hc->should_linger )
  2070. +
  2071. + if ( c->hc->do_keep_alive && doKeep)
  2072. {
  2073. - c->conn_state = CNST_LINGERING;
  2074. + httpd_conn *hc = c->hc;
  2075. + c->conn_state = CNST_READING;
  2076. +
  2077. + client_data.p = c;
  2078. + c->bytes_sent = 0;
  2079. + c->numtnums = 0;
  2080. + c->keep_alive = 1;
  2081. +
  2082. + httpd_complete_request( c->hc, tvP );
  2083. +
  2084. fdwatch_del_fd( c->hc->conn_fd );
  2085. fdwatch_add_fd( c->hc->conn_fd, c, FDW_READ );
  2086. +
  2087. + httpd_request_reset( c->hc, 1 );
  2088. +
  2089. + hc->read_idx -= hc->checked_idx;
  2090. + memmove(hc->read_buf, hc->read_buf + hc->checked_idx, hc->read_idx);
  2091. + hc->checked_idx = 0;
  2092. +
  2093. /* Make sure we are still in no-delay mode. */
  2094. httpd_set_ndelay( c->hc->conn_fd );
  2095. + handle_request(c, tvP);
  2096. + }
  2097. + else if ( c->hc->should_linger )
  2098. + {
  2099. + c->conn_state = CNST_LINGERING;
  2100. +
  2101. client_data.p = c;
  2102. c->linger_timer = tmr_create(
  2103. tvP, linger_clear_connection, client_data, LINGER_TIME * 1000L, 0 );
  2104. @@ -1684,9 +1940,19 @@
  2105. syslog( LOG_CRIT, "tmr_create(linger_clear_connection) failed" );
  2106. exit( 1 );
  2107. }
  2108. +
  2109. + httpd_complete_request( c->hc, tvP );
  2110. +
  2111. + fdwatch_del_fd( c->hc->conn_fd );
  2112. + fdwatch_add_fd( c->hc->conn_fd, c, FDW_READ );
  2113. + /* Make sure we are still in no-delay mode. */
  2114. + httpd_set_ndelay( c->hc->conn_fd );
  2115. }
  2116. - else
  2117. + else
  2118. + {
  2119. + httpd_complete_request( c->hc, tvP );
  2120. really_clear_connection( c, tvP );
  2121. + }
  2122. }
  2123. @@ -1702,45 +1968,12 @@
  2124. tmr_cancel( c->linger_timer );
  2125. c->linger_timer = 0;
  2126. }
  2127. + free_connects[next_free_connect++] = c;
  2128. c->conn_state = CNST_FREE;
  2129. --numconnects;
  2130. }
  2131. -static void
  2132. -idle_read_connection( ClientData client_data, struct timeval* nowP )
  2133. - {
  2134. - connecttab* c;
  2135. -
  2136. - c = (connecttab*) client_data.p;
  2137. - c->idle_read_timer = (Timer*) 0;
  2138. - if ( c->conn_state != CNST_FREE )
  2139. - {
  2140. - syslog( LOG_INFO,
  2141. - "%.80s connection timed out reading",
  2142. - httpd_ntoa( &c->hc->client_addr ) );
  2143. - httpd_send_err( c->hc, 408, httpd_err408title, "", httpd_err408form, "" );
  2144. - clear_connection( c, nowP );
  2145. - }
  2146. - }
  2147. -
  2148. -
  2149. -static void
  2150. -idle_send_connection( ClientData client_data, struct timeval* nowP )
  2151. - {
  2152. - connecttab* c;
  2153. -
  2154. - c = (connecttab*) client_data.p;
  2155. - c->idle_send_timer = (Timer*) 0;
  2156. - if ( c->conn_state != CNST_FREE )
  2157. - {
  2158. - syslog( LOG_INFO,
  2159. - "%.80s connection timed out sending",
  2160. - httpd_ntoa( &c->hc->client_addr ) );
  2161. - clear_connection( c, nowP );
  2162. - }
  2163. - }
  2164. -
  2165. static void
  2166. wakeup_connection( ClientData client_data, struct timeval* nowP )
  2167. @@ -1783,6 +2016,43 @@
  2168. }
  2169. #endif /* STATS_TIME */
  2170. +char httpd_now_buf[100];
  2171. +
  2172. +
  2173. +
  2174. +static void
  2175. +periodic_jobs( ClientData client_data, struct timeval* nowP )
  2176. +{
  2177. + const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
  2178. + struct tm *t;
  2179. + char date_nozone[100];
  2180. + const char* cernfmt_nozone = "%d/%b/%Y:%H:%M:%S";
  2181. + char data[100];
  2182. + int zone;
  2183. + char sign;
  2184. +
  2185. + strftime( httpd_now_buf, sizeof(httpd_now_buf), rfc1123fmt, gmtime( &nowP->tv_sec ) );
  2186. +
  2187. + t = localtime(&nowP->tv_sec);
  2188. + strftime( date_nozone, sizeof(date_nozone), cernfmt_nozone, t );
  2189. +#ifdef HAVE_TM_GMTOFF
  2190. + zone = t->tm_gmtoff / 60L;
  2191. +#else
  2192. + zone = -timezone / 60L;
  2193. + /* Probably have to add something about daylight time here. */
  2194. +#endif
  2195. + if ( zone >= 0 )
  2196. + sign = '+';
  2197. + else
  2198. + {
  2199. + sign = '-';
  2200. + zone = -zone;
  2201. + }
  2202. + zone = ( zone / 60 ) * 100 + zone % 60;
  2203. + hs->log_date_len = sprintf( hs->log_date, "%s %c%04d", date_nozone, sign,
  2204. + zone );
  2205. +}
  2206. +
  2207. /* Generate debugging statistics syslog messages for all packages. */
  2208. static void
  2209. @@ -1826,3 +2096,42 @@
  2210. stats_connections = stats_bytes = 0L;
  2211. stats_simultaneous = 0;
  2212. }
  2213. +
  2214. +static void
  2215. +timeout_conns(ClientData client_data, struct timeval *nowP)
  2216. +{
  2217. + connecttab *c = connects, *ce = c + maxconnects;
  2218. + time_t now = nowP->tv_sec;
  2219. + int r = 0, w = 0;
  2220. + int checked = 0;
  2221. +
  2222. + while (c < ce) {
  2223. + switch (c->conn_state) {
  2224. + case CNST_SENDING:
  2225. + case CNST_SENDING_RESP:
  2226. + checked++;
  2227. + if ((now - c->last_io) > IDLE_SEND_TIMELIMIT) {
  2228. + clear_connection( c, nowP, 0 );
  2229. + w++;
  2230. + }
  2231. + break;
  2232. + case CNST_READING:
  2233. + case CNST_READING_BODY:
  2234. + checked++;
  2235. + if ((now - c->last_io) > IDLE_READ_TIMELIMIT) {
  2236. + clear_connection( c, nowP, 0 );
  2237. + r++;
  2238. + }
  2239. + break;
  2240. + case CNST_FREE: break;
  2241. + default: checked++; break;
  2242. + }
  2243. + c++;
  2244. + if (checked >= numconnects) break;
  2245. + }
  2246. +
  2247. + if (r > 0 || w > 0) {
  2248. + syslog(LOG_INFO, "Expired %d/%d connections in read/write state", r, w);
  2249. + }
  2250. +}
  2251. +
  2252. diff -ur thttpd-2.21b/version.h thttpd-2.21b-cool/version.h
  2253. --- thttpd-2.21b/version.h Tue Apr 24 04:05:23 2001
  2254. +++ thttpd-2.21b-cool/version.h Sat Sep 20 14:43:20 2003
  2255. @@ -3,7 +3,7 @@
  2256. #ifndef _VERSION_H_
  2257. #define _VERSION_H_
  2258. -#define SERVER_SOFTWARE "thttpd/2.21b 23apr2001"
  2259. +#define SERVER_SOFTWARE "thttpd/2.21b PHP/20030920"
  2260. #define SERVER_ADDRESS "http://www.acme.com/software/thttpd/"
  2261. #endif /* _VERSION_H_ */