]>
Commit | Line | Data |
---|---|---|
1175ccec | 1 | --- ../lighttpd-1.4.11/NEWS 2006-03-09 19:34:33.000000000 +0200 |
36e2a29e | 2 | +++ lighttpd-1.4.12/NEWS 2006-07-11 22:07:54.000000000 +0300 |
f26f9fd5 ER |
3 | @@ -3,6 +3,23 @@ |
4 | NEWS | |
5 | ==== | |
6 | ||
7 | +- 1.4.12 - 2006-..-.. | |
8 | + | |
9 | + * added handling of Content-Range to PUT requests in mod_webdav | |
10 | + * added handling of ETag and If-Modified-Since to mod_compress if | |
11 | + cache-dir is not set | |
12 | + * added experimental LOCK support for mod_webdav | |
13 | + * added support for X-Sendfile as addition to X-LIGHTTPD-send-file. | |
14 | + This allows compatibility with mod_xsendfile for apache | |
15 | + (http://celebnamer.celebworld.ws/stuff/mod_xsendfile/) | |
16 | + * fixed handling of If-Modified-Since if Etag is not set | |
17 | + * fixed hanging fastcgi connections | |
18 | + * fixed stalling SSL POST requests | |
19 | + * fixed round-robin load-balancing in mod_proxy | |
20 | + * TODO: add fail-over to mod-proxy | |
21 | + * TODO: fix CACHE_HIT/MISS in mod_cml | |
22 | + * TODO: finish LOCK/UNLOCK in mod_webdav | |
23 | + | |
24 | - 1.4.11 - 2006-03-09 | |
25 | ||
26 | * added ability to specify which ip address spawn-fci listens on | |
1175ccec ER |
27 | --- ../lighttpd-1.4.11/configure.in 2006-03-04 16:32:38.000000000 +0200 |
28 | +++ lighttpd-1.4.12/configure.in 2006-07-15 22:43:22.000000000 +0300 | |
f673a614 ER |
29 | @@ -1,7 +1,7 @@ |
30 | # -*- Autoconf -*- | |
31 | # Process this file with autoconf to produce a configure script. | |
32 | AC_PREREQ(2.57) | |
33 | -AC_INIT(lighttpd, 1.4.11, jan@kneschke.de) | |
34 | +AC_INIT(lighttpd, 1.4.12, jan@kneschke.de) | |
35 | AC_CONFIG_SRCDIR([src/server.c]) | |
36 | ||
37 | AC_CANONICAL_TARGET | |
38 | @@ -66,7 +66,7 @@ | |
39 | AC_TYPE_PID_T | |
40 | AC_TYPE_SIZE_T | |
41 | ||
42 | -AC_CHECK_MEMBER(struct tm.tm_gmtoff,AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm]),,[#include <time.h>]) | |
43 | +AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include <time.h>]) | |
44 | AC_CHECK_TYPES(struct sockaddr_storage,,,[#include <sys/socket.h>]) | |
45 | AC_CHECK_TYPES(socklen_t,,,[#include <sys/types.h> | |
46 | #include <sys/socket.h>]) | |
47 | @@ -339,6 +339,22 @@ | |
48 | AC_DEFINE([HAVE_SQLITE3], [1], [libsqlite3]) | |
49 | AC_DEFINE([HAVE_SQLITE3_H], [1], [sqlite3.h]) | |
50 | ]) | |
51 | + | |
52 | + AC_MSG_CHECKING(for locks in mod_webdav) | |
53 | + AC_ARG_WITH(webdav-locks, AC_HELP_STRING([--with-webdav-locks],[locks in mod_webdav]), | |
54 | + [WITH_WEBDAV_LOCKS=$withval],[WITH_WEBDAV_LOCKS=no]) | |
55 | + AC_MSG_RESULT([$WITH_WEBDAV_LOCKS]) | |
56 | + | |
57 | + if test "$WITH_WEBDAV_LOCKS" != "no"; then | |
58 | + AC_CHECK_LIB(uuid, uuid_unparse, [ | |
59 | + AC_CHECK_HEADERS([uuid/uuid.h],[ | |
60 | + UUID_LIB=-luuid | |
61 | + AC_DEFINE([HAVE_UUID], [1], [libuuid]) | |
62 | + AC_DEFINE([HAVE_UUID_H], [1], [uuid/uuid.h is available]) | |
63 | + ]) | |
64 | + ]) | |
65 | + | |
66 | + fi | |
67 | fi | |
68 | ||
69 | dnl Check for gdbm | |
1175ccec ER |
70 | @@ -381,30 +397,11 @@ |
71 | ||
72 | AC_MSG_RESULT($WITH_LUA) | |
73 | if test "$WITH_LUA" != "no"; then | |
74 | - AC_PATH_PROG(LUACONFIG, lua-config) | |
75 | - | |
76 | - if test x"$LUACONFIG" != x; then | |
77 | - LUA_CFLAGS=`$LUACONFIG --include` | |
78 | - LUA_LIBS=`$LUACONFIG --libs --extralibs` | |
79 | + # try pkgconfig | |
80 | + PKG_CHECK_MODULES(LUA, lua >= 5.1, [ | |
81 | AC_DEFINE([HAVE_LUA], [1], [liblua]) | |
82 | AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) | |
83 | - else | |
84 | - AC_CHECK_LIB(lua, lua_open, [ | |
85 | - AC_CHECK_HEADERS([lua.h],[ | |
86 | - LUA_LIBS="-llua -llualib" | |
87 | - AC_DEFINE([HAVE_LUA], [1], [liblua]) | |
88 | - AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) | |
89 | - ]) | |
90 | - ]) | |
91 | - fi | |
92 | - | |
93 | - if test x"$LUA_LIBS" = x; then | |
94 | - # try pkgconfig | |
95 | - PKG_CHECK_MODULES(LUA, lua, [ | |
96 | - AC_DEFINE([HAVE_LUA], [1], [liblua]) | |
97 | - AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) | |
98 | - ]) | |
99 | - fi | |
100 | + ]) | |
101 | ||
102 | AC_SUBST(LUA_CFLAGS) | |
103 | AC_SUBST(LUA_LIBS) | |
104 | @@ -440,7 +437,7 @@ | |
f673a614 ER |
105 | esac |
106 | ||
107 | AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \ | |
108 | - strdup strerror strstr strtol sendfile getopt socket \ | |
109 | + strdup strerror strstr strtol sendfile getopt socket lstat \ | |
110 | gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \ | |
111 | getuid select signal pathconf madvise posix_fadvise posix_madvise \ | |
112 | writev sigaction sendfile64 send_file kqueue port_create localtime_r]) | |
1175ccec | 113 | @@ -538,7 +535,7 @@ |
f673a614 ER |
114 | AC_OUTPUT |
115 | ||
116 | ||
117 | -do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi" | |
118 | +do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming" | |
119 | ||
120 | plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl" | |
121 | features="regex-conditionals" | |
1175ccec | 122 | @@ -642,6 +639,14 @@ |
f673a614 ER |
123 | disable_feature="$disable_feature $features" |
124 | fi | |
125 | ||
126 | +features="webdav-locks" | |
127 | +if test "x$UUID_LIB" \!= x; then | |
128 | + enable_feature="$enable_feature $features" | |
129 | +else | |
130 | + disable_feature="$disable_feature $features" | |
131 | +fi | |
132 | + | |
133 | + | |
134 | ## output | |
135 | ||
136 | $ECHO | |
1175ccec | 137 | --- ../lighttpd-1.4.11/cygwin/lighttpd.README 2006-03-07 14:22:19.000000000 +0200 |
36e2a29e | 138 | +++ lighttpd-1.4.12/cygwin/lighttpd.README 2006-07-11 22:08:04.000000000 +0300 |
2519e6e5 ER |
139 | @@ -1,114 +1,114 @@ |
140 | -lighttpd\r | |
141 | -------------------------------------------\r | |
142 | -A fast, secure and flexible webserver\r | |
143 | -\r | |
144 | -Runtime requirements:\r | |
145 | - cygwin-1.5.10 or newer\r | |
146 | - crypt-1.1 or newer\r | |
147 | - libbz2_1-1.0.2 or newer\r | |
148 | - libpcre0-4.5 or newer\r | |
149 | - openssl-0.9.7d or newer\r | |
150 | - zlib-1.2.1 or newer\r | |
151 | -\r | |
152 | -Build requirements:\r | |
153 | - cygwin-1.5.10 or newer\r | |
154 | - gcc-3.3.1-3 or newer\r | |
155 | - binutils-20030901-1 or newer\r | |
156 | - crypt\r | |
157 | - openssl-devel\r | |
158 | - openssl\r | |
159 | - openldap\r | |
160 | - openldap-devel\r | |
161 | - zlib\r | |
162 | - bzip2\r | |
163 | -\r | |
164 | -Canonical homepage:\r | |
165 | - http://jan.kneschke.de/projects/lighttpd/\r | |
166 | -\r | |
167 | -Canonical download:\r | |
168 | - http://jan.kneschke.de/projects/lighttpd/download\r | |
169 | -\r | |
170 | -------------------------------------\r | |
171 | -\r | |
172 | -Build instructions:\r | |
173 | - unpack lighttpd-1.4.11-<REL>-src.tar.bz2\r | |
174 | - if you use setup to install this src package, it will be\r | |
175 | - unpacked under /usr/src automatically\r | |
176 | - cd /usr/src\r | |
177 | - ./lighttpd-1.4.11-<REL>.sh all\r | |
178 | -\r | |
179 | -This will create:\r | |
180 | - /usr/src/lighttpd-1.4.11-<REL>.tar.bz2\r | |
181 | - /usr/src/lighttpd-1.4.11-<REL>-src.tar.bz2\r | |
182 | -\r | |
183 | -Or use './lighttpd-1.4.11-<REL>.sh prep' to get a patched source directory\r | |
184 | -\r | |
185 | --------------------------------------------\r | |
186 | -\r | |
187 | -Files included in the binary distribution:\r | |
188 | -\r | |
189 | - /etc/lighttpd/lighttpd.conf.default\r | |
190 | - /usr/lib/cyglightcomp.dll\r | |
191 | - /usr/lib/lighttpd/mod_access.dll\r | |
192 | - /usr/lib/lighttpd/mod_accesslog.dll\r | |
193 | - /usr/lib/lighttpd/mod_auth.dll\r | |
194 | - /usr/lib/lighttpd/mod_cgi.dll\r | |
195 | - /usr/lib/lighttpd/mod_compress.dll\r | |
196 | - /usr/lib/lighttpd/mod_evhost.dll\r | |
197 | - /usr/lib/lighttpd/mod_expire.dll\r | |
198 | - /usr/lib/lighttpd/mod_fastcgi.dll\r | |
199 | - /usr/lib/lighttpd/mod_httptls.dll\r | |
200 | - /usr/lib/lighttpd/mod_maps.dll\r | |
201 | - /usr/lib/lighttpd/mod_proxy.dll\r | |
202 | - /usr/lib/lighttpd/mod_redirect.dll\r | |
203 | - /usr/lib/lighttpd/mod_rewrite.dll\r | |
204 | - /usr/lib/lighttpd/mod_rrdtool.dll\r | |
205 | - /usr/lib/lighttpd/mod_secdownload.dll\r | |
206 | - /usr/lib/lighttpd/mod_simple_vhost.dll\r | |
207 | - /usr/lib/lighttpd/mod_ssi.dll\r | |
208 | - /usr/lib/lighttpd/mod_status.dll\r | |
209 | - /usr/lib/lighttpd/mod_usertrack.dll\r | |
210 | - /usr/sbin/lighttpd.exe\r | |
211 | - /usr/share/doc/Cygwin/lighttpd-1.3.0.README\r | |
212 | - /usr/share/doc/lighttpd-1.3.0/accesslog.txt\r | |
213 | - /usr/share/doc/lighttpd-1.3.0/authentification.txt\r | |
214 | - /usr/share/doc/lighttpd-1.3.0/AUTHORS\r | |
215 | - /usr/share/doc/lighttpd-1.3.0/cgi.txt\r | |
216 | - /usr/share/doc/lighttpd-1.3.0/ChangeLog\r | |
217 | - /usr/share/doc/lighttpd-1.3.0/compress.txt\r | |
218 | - /usr/share/doc/lighttpd-1.3.0/configuration.txt\r | |
219 | - /usr/share/doc/lighttpd-1.3.0/COPYING\r | |
220 | - /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt\r | |
221 | - /usr/share/doc/lighttpd-1.3.0/fastcgi.txt\r | |
222 | - /usr/share/doc/lighttpd-1.3.0/features.txt\r | |
223 | - /usr/share/doc/lighttpd-1.3.0/INSTALL\r | |
224 | - /usr/share/doc/lighttpd-1.3.0/NEWS\r | |
225 | - /usr/share/doc/lighttpd-1.3.0/performance.txt\r | |
226 | - /usr/share/doc/lighttpd-1.3.0/plugins.txt\r | |
227 | - /usr/share/doc/lighttpd-1.3.0/proxy.txt\r | |
228 | - /usr/share/doc/lighttpd-1.3.0/README\r | |
229 | - /usr/share/doc/lighttpd-1.3.0/redirect.txt\r | |
230 | - /usr/share/doc/lighttpd-1.3.0/rewrite.txt\r | |
231 | - /usr/share/doc/lighttpd-1.3.0/rrdtool.txt\r | |
232 | - /usr/share/doc/lighttpd-1.3.0/secdownload.txt\r | |
233 | - /usr/share/doc/lighttpd-1.3.0/security.txt\r | |
234 | - /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt\r | |
235 | - /usr/share/doc/lighttpd-1.3.0/skeleton.txt\r | |
236 | - /usr/share/doc/lighttpd-1.3.0/ssi.txt\r | |
237 | - /usr/share/doc/lighttpd-1.3.0/state.txt\r | |
238 | - /usr/share/man/man1/lighttpd.1.gz\r | |
239 | -\r | |
240 | -------------------\r | |
241 | -\r | |
242 | -Port Notes:\r | |
243 | -\r | |
244 | ----------- lighttpd-1.3.1-1 -----------\r | |
245 | -\r | |
246 | -Updated to 1.3.1\r | |
247 | -\r | |
248 | ----------- lighttpd-1.3.0-1 -----------\r | |
249 | -Initial release\r | |
250 | -\r | |
251 | -Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>\r | |
252 | -Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>\r | |
253 | -\r | |
254 | +lighttpd | |
255 | +------------------------------------------ | |
256 | +A fast, secure and flexible webserver | |
257 | + | |
258 | +Runtime requirements: | |
259 | + cygwin-1.5.10 or newer | |
260 | + crypt-1.1 or newer | |
261 | + libbz2_1-1.0.2 or newer | |
262 | + libpcre0-4.5 or newer | |
263 | + openssl-0.9.7d or newer | |
264 | + zlib-1.2.1 or newer | |
265 | + | |
266 | +Build requirements: | |
267 | + cygwin-1.5.10 or newer | |
268 | + gcc-3.3.1-3 or newer | |
269 | + binutils-20030901-1 or newer | |
270 | + crypt | |
271 | + openssl-devel | |
272 | + openssl | |
273 | + openldap | |
274 | + openldap-devel | |
275 | + zlib | |
276 | + bzip2 | |
277 | + | |
278 | +Canonical homepage: | |
279 | + http://jan.kneschke.de/projects/lighttpd/ | |
280 | + | |
281 | +Canonical download: | |
282 | + http://jan.kneschke.de/projects/lighttpd/download | |
283 | + | |
284 | +------------------------------------ | |
285 | + | |
286 | +Build instructions: | |
287 | + unpack lighttpd-1.4.12-<REL>-src.tar.bz2 | |
288 | + if you use setup to install this src package, it will be | |
289 | + unpacked under /usr/src automatically | |
290 | + cd /usr/src | |
291 | + ./lighttpd-1.4.12-<REL>.sh all | |
292 | + | |
293 | +This will create: | |
294 | + /usr/src/lighttpd-1.4.12-<REL>.tar.bz2 | |
295 | + /usr/src/lighttpd-1.4.12-<REL>-src.tar.bz2 | |
296 | + | |
297 | +Or use './lighttpd-1.4.12-<REL>.sh prep' to get a patched source directory | |
298 | + | |
299 | +------------------------------------------- | |
300 | + | |
301 | +Files included in the binary distribution: | |
302 | + | |
303 | + /etc/lighttpd/lighttpd.conf.default | |
304 | + /usr/lib/cyglightcomp.dll | |
305 | + /usr/lib/lighttpd/mod_access.dll | |
306 | + /usr/lib/lighttpd/mod_accesslog.dll | |
307 | + /usr/lib/lighttpd/mod_auth.dll | |
308 | + /usr/lib/lighttpd/mod_cgi.dll | |
309 | + /usr/lib/lighttpd/mod_compress.dll | |
310 | + /usr/lib/lighttpd/mod_evhost.dll | |
311 | + /usr/lib/lighttpd/mod_expire.dll | |
312 | + /usr/lib/lighttpd/mod_fastcgi.dll | |
313 | + /usr/lib/lighttpd/mod_httptls.dll | |
314 | + /usr/lib/lighttpd/mod_maps.dll | |
315 | + /usr/lib/lighttpd/mod_proxy.dll | |
316 | + /usr/lib/lighttpd/mod_redirect.dll | |
317 | + /usr/lib/lighttpd/mod_rewrite.dll | |
318 | + /usr/lib/lighttpd/mod_rrdtool.dll | |
319 | + /usr/lib/lighttpd/mod_secdownload.dll | |
320 | + /usr/lib/lighttpd/mod_simple_vhost.dll | |
321 | + /usr/lib/lighttpd/mod_ssi.dll | |
322 | + /usr/lib/lighttpd/mod_status.dll | |
323 | + /usr/lib/lighttpd/mod_usertrack.dll | |
324 | + /usr/sbin/lighttpd.exe | |
325 | + /usr/share/doc/Cygwin/lighttpd-1.3.0.README | |
326 | + /usr/share/doc/lighttpd-1.3.0/accesslog.txt | |
327 | + /usr/share/doc/lighttpd-1.3.0/authentification.txt | |
328 | + /usr/share/doc/lighttpd-1.3.0/AUTHORS | |
329 | + /usr/share/doc/lighttpd-1.3.0/cgi.txt | |
330 | + /usr/share/doc/lighttpd-1.3.0/ChangeLog | |
331 | + /usr/share/doc/lighttpd-1.3.0/compress.txt | |
332 | + /usr/share/doc/lighttpd-1.3.0/configuration.txt | |
333 | + /usr/share/doc/lighttpd-1.3.0/COPYING | |
334 | + /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt | |
335 | + /usr/share/doc/lighttpd-1.3.0/fastcgi.txt | |
336 | + /usr/share/doc/lighttpd-1.3.0/features.txt | |
337 | + /usr/share/doc/lighttpd-1.3.0/INSTALL | |
338 | + /usr/share/doc/lighttpd-1.3.0/NEWS | |
339 | + /usr/share/doc/lighttpd-1.3.0/performance.txt | |
340 | + /usr/share/doc/lighttpd-1.3.0/plugins.txt | |
341 | + /usr/share/doc/lighttpd-1.3.0/proxy.txt | |
342 | + /usr/share/doc/lighttpd-1.3.0/README | |
343 | + /usr/share/doc/lighttpd-1.3.0/redirect.txt | |
344 | + /usr/share/doc/lighttpd-1.3.0/rewrite.txt | |
345 | + /usr/share/doc/lighttpd-1.3.0/rrdtool.txt | |
346 | + /usr/share/doc/lighttpd-1.3.0/secdownload.txt | |
347 | + /usr/share/doc/lighttpd-1.3.0/security.txt | |
348 | + /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt | |
349 | + /usr/share/doc/lighttpd-1.3.0/skeleton.txt | |
350 | + /usr/share/doc/lighttpd-1.3.0/ssi.txt | |
351 | + /usr/share/doc/lighttpd-1.3.0/state.txt | |
352 | + /usr/share/man/man1/lighttpd.1.gz | |
353 | + | |
354 | +------------------ | |
355 | + | |
356 | +Port Notes: | |
357 | + | |
358 | +---------- lighttpd-1.3.1-1 ----------- | |
359 | + | |
360 | +Updated to 1.3.1 | |
361 | + | |
362 | +---------- lighttpd-1.3.0-1 ----------- | |
363 | +Initial release | |
364 | + | |
365 | +Cygwin port maintained by: Jan Kneschke <jan@kneschke.de> | |
366 | +Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com> | |
367 | + | |
1175ccec | 368 | --- ../lighttpd-1.4.11/cygwin/lighttpd.README.in 2005-08-11 01:26:59.000000000 +0300 |
36e2a29e | 369 | +++ lighttpd-1.4.12/cygwin/lighttpd.README.in 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
370 | @@ -1,114 +1,114 @@ |
371 | -lighttpd\r | |
372 | -------------------------------------------\r | |
373 | -A fast, secure and flexible webserver\r | |
374 | -\r | |
375 | -Runtime requirements:\r | |
376 | - cygwin-1.5.10 or newer\r | |
377 | - crypt-1.1 or newer\r | |
378 | - libbz2_1-1.0.2 or newer\r | |
379 | - libpcre0-4.5 or newer\r | |
380 | - openssl-0.9.7d or newer\r | |
381 | - zlib-1.2.1 or newer\r | |
382 | -\r | |
383 | -Build requirements:\r | |
384 | - cygwin-1.5.10 or newer\r | |
385 | - gcc-3.3.1-3 or newer\r | |
386 | - binutils-20030901-1 or newer\r | |
387 | - crypt\r | |
388 | - openssl-devel\r | |
389 | - openssl\r | |
390 | - openldap\r | |
391 | - openldap-devel\r | |
392 | - zlib\r | |
393 | - bzip2\r | |
394 | -\r | |
395 | -Canonical homepage:\r | |
396 | - http://jan.kneschke.de/projects/lighttpd/\r | |
397 | -\r | |
398 | -Canonical download:\r | |
399 | - http://jan.kneschke.de/projects/lighttpd/download\r | |
400 | -\r | |
401 | -------------------------------------\r | |
402 | -\r | |
403 | -Build instructions:\r | |
404 | - unpack lighttpd-@VERSION@-<REL>-src.tar.bz2\r | |
405 | - if you use setup to install this src package, it will be\r | |
406 | - unpacked under /usr/src automatically\r | |
407 | - cd /usr/src\r | |
408 | - ./lighttpd-@VERSION@-<REL>.sh all\r | |
409 | -\r | |
410 | -This will create:\r | |
411 | - /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2\r | |
412 | - /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2\r | |
413 | -\r | |
414 | -Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory\r | |
415 | -\r | |
416 | --------------------------------------------\r | |
417 | -\r | |
418 | -Files included in the binary distribution:\r | |
419 | -\r | |
420 | - /etc/lighttpd/lighttpd.conf.default\r | |
421 | - /usr/lib/cyglightcomp.dll\r | |
422 | - /usr/lib/lighttpd/mod_access.dll\r | |
423 | - /usr/lib/lighttpd/mod_accesslog.dll\r | |
424 | - /usr/lib/lighttpd/mod_auth.dll\r | |
425 | - /usr/lib/lighttpd/mod_cgi.dll\r | |
426 | - /usr/lib/lighttpd/mod_compress.dll\r | |
427 | - /usr/lib/lighttpd/mod_evhost.dll\r | |
428 | - /usr/lib/lighttpd/mod_expire.dll\r | |
429 | - /usr/lib/lighttpd/mod_fastcgi.dll\r | |
430 | - /usr/lib/lighttpd/mod_httptls.dll\r | |
431 | - /usr/lib/lighttpd/mod_maps.dll\r | |
432 | - /usr/lib/lighttpd/mod_proxy.dll\r | |
433 | - /usr/lib/lighttpd/mod_redirect.dll\r | |
434 | - /usr/lib/lighttpd/mod_rewrite.dll\r | |
435 | - /usr/lib/lighttpd/mod_rrdtool.dll\r | |
436 | - /usr/lib/lighttpd/mod_secdownload.dll\r | |
437 | - /usr/lib/lighttpd/mod_simple_vhost.dll\r | |
438 | - /usr/lib/lighttpd/mod_ssi.dll\r | |
439 | - /usr/lib/lighttpd/mod_status.dll\r | |
440 | - /usr/lib/lighttpd/mod_usertrack.dll\r | |
441 | - /usr/sbin/lighttpd.exe\r | |
442 | - /usr/share/doc/Cygwin/lighttpd-1.3.0.README\r | |
443 | - /usr/share/doc/lighttpd-1.3.0/accesslog.txt\r | |
444 | - /usr/share/doc/lighttpd-1.3.0/authentification.txt\r | |
445 | - /usr/share/doc/lighttpd-1.3.0/AUTHORS\r | |
446 | - /usr/share/doc/lighttpd-1.3.0/cgi.txt\r | |
447 | - /usr/share/doc/lighttpd-1.3.0/ChangeLog\r | |
448 | - /usr/share/doc/lighttpd-1.3.0/compress.txt\r | |
449 | - /usr/share/doc/lighttpd-1.3.0/configuration.txt\r | |
450 | - /usr/share/doc/lighttpd-1.3.0/COPYING\r | |
451 | - /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt\r | |
452 | - /usr/share/doc/lighttpd-1.3.0/fastcgi.txt\r | |
453 | - /usr/share/doc/lighttpd-1.3.0/features.txt\r | |
454 | - /usr/share/doc/lighttpd-1.3.0/INSTALL\r | |
455 | - /usr/share/doc/lighttpd-1.3.0/NEWS\r | |
456 | - /usr/share/doc/lighttpd-1.3.0/performance.txt\r | |
457 | - /usr/share/doc/lighttpd-1.3.0/plugins.txt\r | |
458 | - /usr/share/doc/lighttpd-1.3.0/proxy.txt\r | |
459 | - /usr/share/doc/lighttpd-1.3.0/README\r | |
460 | - /usr/share/doc/lighttpd-1.3.0/redirect.txt\r | |
461 | - /usr/share/doc/lighttpd-1.3.0/rewrite.txt\r | |
462 | - /usr/share/doc/lighttpd-1.3.0/rrdtool.txt\r | |
463 | - /usr/share/doc/lighttpd-1.3.0/secdownload.txt\r | |
464 | - /usr/share/doc/lighttpd-1.3.0/security.txt\r | |
465 | - /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt\r | |
466 | - /usr/share/doc/lighttpd-1.3.0/skeleton.txt\r | |
467 | - /usr/share/doc/lighttpd-1.3.0/ssi.txt\r | |
468 | - /usr/share/doc/lighttpd-1.3.0/state.txt\r | |
469 | - /usr/share/man/man1/lighttpd.1.gz\r | |
470 | -\r | |
471 | -------------------\r | |
472 | -\r | |
473 | -Port Notes:\r | |
474 | -\r | |
475 | ----------- lighttpd-1.3.1-1 -----------\r | |
476 | -\r | |
477 | -Updated to 1.3.1\r | |
478 | -\r | |
479 | ----------- lighttpd-1.3.0-1 -----------\r | |
480 | -Initial release\r | |
481 | -\r | |
482 | -Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>\r | |
483 | -Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>\r | |
484 | -\r | |
485 | +lighttpd | |
486 | +------------------------------------------ | |
487 | +A fast, secure and flexible webserver | |
488 | + | |
489 | +Runtime requirements: | |
490 | + cygwin-1.5.10 or newer | |
491 | + crypt-1.1 or newer | |
492 | + libbz2_1-1.0.2 or newer | |
493 | + libpcre0-4.5 or newer | |
494 | + openssl-0.9.7d or newer | |
495 | + zlib-1.2.1 or newer | |
496 | + | |
497 | +Build requirements: | |
498 | + cygwin-1.5.10 or newer | |
499 | + gcc-3.3.1-3 or newer | |
500 | + binutils-20030901-1 or newer | |
501 | + crypt | |
502 | + openssl-devel | |
503 | + openssl | |
504 | + openldap | |
505 | + openldap-devel | |
506 | + zlib | |
507 | + bzip2 | |
508 | + | |
509 | +Canonical homepage: | |
510 | + http://jan.kneschke.de/projects/lighttpd/ | |
511 | + | |
512 | +Canonical download: | |
513 | + http://jan.kneschke.de/projects/lighttpd/download | |
514 | + | |
515 | +------------------------------------ | |
516 | + | |
517 | +Build instructions: | |
518 | + unpack lighttpd-@VERSION@-<REL>-src.tar.bz2 | |
519 | + if you use setup to install this src package, it will be | |
520 | + unpacked under /usr/src automatically | |
521 | + cd /usr/src | |
522 | + ./lighttpd-@VERSION@-<REL>.sh all | |
523 | + | |
524 | +This will create: | |
525 | + /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2 | |
526 | + /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2 | |
527 | + | |
528 | +Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory | |
529 | + | |
530 | +------------------------------------------- | |
531 | + | |
532 | +Files included in the binary distribution: | |
533 | + | |
534 | + /etc/lighttpd/lighttpd.conf.default | |
535 | + /usr/lib/cyglightcomp.dll | |
536 | + /usr/lib/lighttpd/mod_access.dll | |
537 | + /usr/lib/lighttpd/mod_accesslog.dll | |
538 | + /usr/lib/lighttpd/mod_auth.dll | |
539 | + /usr/lib/lighttpd/mod_cgi.dll | |
540 | + /usr/lib/lighttpd/mod_compress.dll | |
541 | + /usr/lib/lighttpd/mod_evhost.dll | |
542 | + /usr/lib/lighttpd/mod_expire.dll | |
543 | + /usr/lib/lighttpd/mod_fastcgi.dll | |
544 | + /usr/lib/lighttpd/mod_httptls.dll | |
545 | + /usr/lib/lighttpd/mod_maps.dll | |
546 | + /usr/lib/lighttpd/mod_proxy.dll | |
547 | + /usr/lib/lighttpd/mod_redirect.dll | |
548 | + /usr/lib/lighttpd/mod_rewrite.dll | |
549 | + /usr/lib/lighttpd/mod_rrdtool.dll | |
550 | + /usr/lib/lighttpd/mod_secdownload.dll | |
551 | + /usr/lib/lighttpd/mod_simple_vhost.dll | |
552 | + /usr/lib/lighttpd/mod_ssi.dll | |
553 | + /usr/lib/lighttpd/mod_status.dll | |
554 | + /usr/lib/lighttpd/mod_usertrack.dll | |
555 | + /usr/sbin/lighttpd.exe | |
556 | + /usr/share/doc/Cygwin/lighttpd-1.3.0.README | |
557 | + /usr/share/doc/lighttpd-1.3.0/accesslog.txt | |
558 | + /usr/share/doc/lighttpd-1.3.0/authentification.txt | |
559 | + /usr/share/doc/lighttpd-1.3.0/AUTHORS | |
560 | + /usr/share/doc/lighttpd-1.3.0/cgi.txt | |
561 | + /usr/share/doc/lighttpd-1.3.0/ChangeLog | |
562 | + /usr/share/doc/lighttpd-1.3.0/compress.txt | |
563 | + /usr/share/doc/lighttpd-1.3.0/configuration.txt | |
564 | + /usr/share/doc/lighttpd-1.3.0/COPYING | |
565 | + /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt | |
566 | + /usr/share/doc/lighttpd-1.3.0/fastcgi.txt | |
567 | + /usr/share/doc/lighttpd-1.3.0/features.txt | |
568 | + /usr/share/doc/lighttpd-1.3.0/INSTALL | |
569 | + /usr/share/doc/lighttpd-1.3.0/NEWS | |
570 | + /usr/share/doc/lighttpd-1.3.0/performance.txt | |
571 | + /usr/share/doc/lighttpd-1.3.0/plugins.txt | |
572 | + /usr/share/doc/lighttpd-1.3.0/proxy.txt | |
573 | + /usr/share/doc/lighttpd-1.3.0/README | |
574 | + /usr/share/doc/lighttpd-1.3.0/redirect.txt | |
575 | + /usr/share/doc/lighttpd-1.3.0/rewrite.txt | |
576 | + /usr/share/doc/lighttpd-1.3.0/rrdtool.txt | |
577 | + /usr/share/doc/lighttpd-1.3.0/secdownload.txt | |
578 | + /usr/share/doc/lighttpd-1.3.0/security.txt | |
579 | + /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt | |
580 | + /usr/share/doc/lighttpd-1.3.0/skeleton.txt | |
581 | + /usr/share/doc/lighttpd-1.3.0/ssi.txt | |
582 | + /usr/share/doc/lighttpd-1.3.0/state.txt | |
583 | + /usr/share/man/man1/lighttpd.1.gz | |
584 | + | |
585 | +------------------ | |
586 | + | |
587 | +Port Notes: | |
588 | + | |
589 | +---------- lighttpd-1.3.1-1 ----------- | |
590 | + | |
591 | +Updated to 1.3.1 | |
592 | + | |
593 | +---------- lighttpd-1.3.0-1 ----------- | |
594 | +Initial release | |
595 | + | |
596 | +Cygwin port maintained by: Jan Kneschke <jan@kneschke.de> | |
597 | +Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com> | |
598 | + | |
1175ccec | 599 | --- ../lighttpd-1.4.11/doc/authentication.txt 2006-01-12 20:34:26.000000000 +0200 |
36e2a29e | 600 | +++ lighttpd-1.4.12/doc/authentication.txt 2006-07-11 22:07:54.000000000 +0300 |
f26f9fd5 ER |
601 | @@ -7,8 +7,8 @@ |
602 | ---------------- | |
603 | ||
604 | :Author: Jan Kneschke | |
605 | -:Date: $Date$ | |
606 | -:Revision: $Revision$ | |
607 | +:Date: $Date$ | |
608 | +:Revision: $Revision$ | |
f673a614 | 609 | |
f26f9fd5 ER |
610 | :abstract: |
611 | The auth module provides ... | |
1175ccec | 612 | --- ../lighttpd-1.4.11/doc/compress.txt 2005-08-11 01:26:16.000000000 +0300 |
36e2a29e | 613 | +++ lighttpd-1.4.12/doc/compress.txt 2006-07-11 22:07:54.000000000 +0300 |
f26f9fd5 ER |
614 | @@ -22,12 +22,38 @@ |
615 | =========== | |
f673a614 | 616 | |
f26f9fd5 ER |
617 | Output compression reduces the network load and can improve the overall |
618 | -throughput of the webserver. | |
619 | +throughput of the webserver. All major http-clients support compression by | |
620 | +announcing it in the Accept-Encoding header. This is used to negotiate the | |
621 | +most suitable compression method. We support deflate, gzip and bzip2. | |
622 | ||
623 | -Only static content is supported up to now. | |
624 | +deflate (RFC1950, RFC1951) and gzip (RFC1952) depend on zlib while bzip2 | |
625 | +depends on libbzip2. bzip2 is only supported by lynx and some other console | |
626 | +text-browsers. | |
627 | ||
628 | -The server negotiates automaticly which compression method is used. | |
629 | -Supported are gzip, deflate, bzip. | |
630 | +Currently we limit to compression support to static files. | |
f673a614 | 631 | + |
f26f9fd5 ER |
632 | +Caching |
633 | +------- | |
f673a614 | 634 | + |
f26f9fd5 ER |
635 | +mod_compress can stored compressed files on disk to optimized the compression |
636 | +on a second request away. As soon as compress.cache-dir is set the files are | |
637 | +compressed. | |
f673a614 | 638 | + |
f26f9fd5 ER |
639 | +The names of the cache files are made of the filename, the compression method |
640 | +and the etag associated to the file. | |
f673a614 | 641 | + |
f26f9fd5 ER |
642 | +Cleaning the cache is left to the user. A cron job deleting files older than |
643 | +10 days should do fine. | |
f673a614 | 644 | + |
f26f9fd5 ER |
645 | +Limitations |
646 | +----------- | |
f673a614 | 647 | + |
f26f9fd5 ER |
648 | +The module limits the compression of files to files larger than 128 Byte and |
649 | +smaller than 128 MByte. | |
f673a614 | 650 | + |
f26f9fd5 ER |
651 | +The lower limit is set as small files tend to become larger by compressing due |
652 | +to the compression headers, the upper limit is set to work sensable with | |
653 | +memory and cpu-time. | |
f673a614 | 654 | |
f26f9fd5 ER |
655 | Options |
656 | ======= | |
2519e6e5 | 657 | @@ -47,15 +73,28 @@ |
f26f9fd5 | 658 | Default: not set, compress the file for every request |
f673a614 | 659 | |
f26f9fd5 ER |
660 | compress.filetype |
661 | - mimetypes where might get compressed | |
662 | + mimetypes which might get compressed | |
663 | ||
664 | e.g.: :: | |
665 | ||
666 | compress.filetype = ("text/plain", "text/html") | |
f673a614 | 667 | |
f26f9fd5 ER |
668 | + Keep in mind that compressed JavaScript and CSS files are broken in some |
669 | + browsers. | |
f673a614 | 670 | + |
f26f9fd5 ER |
671 | Default: not set |
672 | ||
673 | +compress.max-file-size | |
674 | + maximum size of the original file to be compressed kBytes. | |
f673a614 | 675 | + |
f26f9fd5 ER |
676 | + This is meant to protect the server against DoSing as compressing large |
677 | + (let's say 1Gbyte) takes a lot of time and would delay the whole operation | |
678 | + of the server. | |
2519e6e5 | 679 | |
f26f9fd5 | 680 | + There is a hard upper limit of 128Mbyte. |
f673a614 | 681 | + |
f26f9fd5 | 682 | + Default: unlimited (== hard-limit of 128MByte) |
2519e6e5 | 683 | + |
f26f9fd5 ER |
684 | Compressing Dynamic Content |
685 | =========================== | |
2519e6e5 | 686 | |
1175ccec | 687 | --- ../lighttpd-1.4.11/doc/configuration.txt 2006-03-09 02:10:40.000000000 +0200 |
36e2a29e | 688 | +++ lighttpd-1.4.12/doc/configuration.txt 2006-07-11 22:07:54.000000000 +0300 |
f26f9fd5 ER |
689 | @@ -7,8 +7,8 @@ |
690 | ------------ | |
691 | ||
692 | :Author: Jan Kneschke | |
693 | -:Date: $Date$ | |
694 | -:Revision: $Revision$ | |
695 | +:Date: $Date$ | |
696 | +:Revision: $Revision$ | |
f673a614 | 697 | |
f26f9fd5 ER |
698 | :abstract: |
699 | the layout of the configuration file | |
700 | @@ -511,3 +511,10 @@ | |
701 | ||
702 | debug.log-request-handling | |
703 | default: disabled | |
f673a614 | 704 | + |
f26f9fd5 ER |
705 | +debug.log-condition-handling |
706 | + default: disabled | |
f673a614 | 707 | + |
f26f9fd5 ER |
708 | +debug.log-condition-cache-handling |
709 | + for developers only | |
710 | + default: disabled | |
1175ccec | 711 | --- ../lighttpd-1.4.11/doc/fastcgi.txt 2006-02-16 17:03:52.000000000 +0200 |
36e2a29e | 712 | +++ lighttpd-1.4.12/doc/fastcgi.txt 2006-07-11 22:07:54.000000000 +0300 |
f26f9fd5 ER |
713 | @@ -144,8 +144,8 @@ |
714 | PHP can extract PATH_INFO from it (default: disabled) | |
715 | :"disable-time": time to wait before a disabled backend is checked | |
716 | again | |
717 | - :"allow-x-send-file": controls if X-LIGHTTPD-send-file headers | |
718 | - are allowed | |
719 | + :"allow-x-send-file": controls if X-LIGHTTPD-send-file and X-Sendfile | |
720 | + headers are allowed | |
f673a614 | 721 | |
f26f9fd5 | 722 | If bin-path is set: |
f673a614 | 723 | |
1175ccec | 724 | --- ../lighttpd-1.4.11/doc/lighttpd.conf 2006-03-04 14:41:12.000000000 +0200 |
36e2a29e | 725 | +++ lighttpd-1.4.12/doc/lighttpd.conf 2006-07-11 22:07:54.000000000 +0300 |
2519e6e5 ER |
726 | @@ -172,10 +172,11 @@ |
727 | #dir-listing.activate = "enable" | |
728 | ||
729 | ## enable debugging | |
730 | -#debug.log-request-header = "enable" | |
731 | -#debug.log-response-header = "enable" | |
732 | -#debug.log-request-handling = "enable" | |
733 | -#debug.log-file-not-found = "enable" | |
734 | +#debug.log-request-header = "enable" | |
735 | +#debug.log-response-header = "enable" | |
736 | +#debug.log-request-handling = "enable" | |
737 | +#debug.log-file-not-found = "enable" | |
f26f9fd5 ER |
738 | +#debug.log-condition-handling = "enable" |
739 | ||
740 | ### only root can use these options | |
741 | # | |
1175ccec | 742 | --- ../lighttpd-1.4.11/doc/performance.txt 2006-02-02 13:01:08.000000000 +0200 |
36e2a29e | 743 | +++ lighttpd-1.4.12/doc/performance.txt 2006-07-11 22:07:54.000000000 +0300 |
f26f9fd5 ER |
744 | @@ -183,6 +183,8 @@ |
745 | ||
746 | server.stat-cache-engine = "fam" # either fam, simple or disabled | |
747 | ||
748 | +See http://oss.sgi.com/projects/fam/faq.html for information about FAM. | |
749 | +See http://www.gnome.org/~veillard/gamin/overview.html for information about gamin. | |
750 | ||
751 | Platform-Specific Notes | |
752 | ======================= | |
1175ccec | 753 | --- ../lighttpd-1.4.11/doc/secdownload.txt 2005-12-20 15:58:58.000000000 +0200 |
36e2a29e | 754 | +++ lighttpd-1.4.12/doc/secdownload.txt 2006-07-11 22:07:54.000000000 +0300 |
f26f9fd5 ER |
755 | @@ -118,7 +118,7 @@ |
756 | $secret = "verysecret"; | |
757 | $uri_prefix = "/dl/"; | |
758 | ||
759 | - # filename | |
760 | + # filename, make sure it's started with a "/" or you'll get 404 in the browser | |
761 | $f = "/secret-file.txt"; | |
762 | ||
763 | # current timestamp | |
1175ccec | 764 | --- ../lighttpd-1.4.11/lighttpd.spec 2006-03-07 14:22:18.000000000 +0200 |
36e2a29e | 765 | +++ lighttpd-1.4.12/lighttpd.spec 2006-07-11 22:07:58.000000000 +0300 |
2519e6e5 ER |
766 | @@ -1,6 +1,6 @@ |
767 | Summary: A fast webserver with minimal memory-footprint (lighttpd) | |
768 | Name: lighttpd | |
769 | -Version: 1.4.11 | |
770 | +Version: 1.4.12 | |
771 | Release: 1 | |
772 | Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz | |
773 | Packager: Jan Kneschke <jan@kneschke.de> | |
1175ccec | 774 | --- ../lighttpd-1.4.11/openwrt/control 2006-03-07 14:22:19.000000000 +0200 |
36e2a29e | 775 | +++ lighttpd-1.4.12/openwrt/control 2006-07-11 22:08:05.000000000 +0300 |
2519e6e5 ER |
776 | @@ -1,8 +1,8 @@ |
777 | Package: lighttpd | |
778 | -Version: 1.4.11 | |
779 | +Version: 1.4.12 | |
780 | Architecture: mipsel | |
781 | Maintainer: Jan Kneschke <jan@kneschke.de> | |
782 | -Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.11.tar.gz | |
783 | +Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.12.tar.gz | |
784 | Section: net | |
785 | Priority: optional | |
786 | Depends: | |
1175ccec | 787 | --- ../lighttpd-1.4.11/openwrt/lighttpd.mk 2006-03-07 14:22:19.000000000 +0200 |
36e2a29e | 788 | +++ lighttpd-1.4.12/openwrt/lighttpd.mk 2006-07-11 22:08:05.000000000 +0300 |
2519e6e5 ER |
789 | @@ -10,7 +10,7 @@ |
790 | ||
791 | # For this example we'll use a fairly simple package that compiles easily | |
792 | # and has sources available for download at sourceforge | |
793 | -LIGHTTPD=lighttpd-1.4.11 | |
794 | +LIGHTTPD=lighttpd-1.4.12 | |
795 | LIGHTTPD_TARGET=.built | |
796 | LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD) | |
797 | LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk | |
1175ccec ER |
798 | --- ../lighttpd-1.4.11/src/Makefile.am 2006-03-07 14:20:20.000000000 +0200 |
799 | +++ lighttpd-1.4.12/src/Makefile.am 2006-07-15 22:43:21.000000000 +0300 | |
800 | @@ -16,18 +16,24 @@ | |
801 | else | |
802 | configparser.y: lemon | |
803 | mod_ssi_exprparser.y: lemon | |
804 | +http_resp_parser.y: lemon | |
805 | ||
806 | configparser.c configparser.h: configparser.y | |
807 | rm -f configparser.h | |
808 | - $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c | |
809 | + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c | |
810 | + | |
811 | +http_resp_parser.c http_resp_parser.h: http_resp_parser.y | |
812 | + rm -f http_resp_parser.h | |
813 | + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c | |
814 | ||
815 | mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y | |
816 | rm -f mod_ssi_exprparser.h | |
817 | - $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c | |
818 | + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c | |
819 | endif | |
2519e6e5 | 820 | |
1175ccec ER |
821 | configfile.c: configparser.h |
822 | mod_ssi_expr.c: mod_ssi_exprparser.h | |
823 | +http_resp.c: http_resp_parser.h | |
2519e6e5 | 824 | |
1175ccec ER |
825 | common_src=buffer.c log.c \ |
826 | keyvalue.c chunk.c \ | |
827 | @@ -46,7 +52,7 @@ | |
2519e6e5 ER |
828 | network_write.c network_linux_sendfile.c \ |
829 | network_freebsd_sendfile.c network_writev.c \ | |
830 | network_solaris_sendfilev.c network_openssl.c \ | |
831 | - splaytree.c | |
832 | + splaytree.c http_resp.c http_resp_parser.c | |
1175ccec ER |
833 | |
834 | src = server.c response.c connections.c network.c \ | |
835 | configfile.c configparser.c request.c proc_open.c | |
836 | @@ -82,9 +88,9 @@ | |
2519e6e5 | 837 | |
1175ccec | 838 | lib_LTLIBRARIES += mod_webdav.la |
2519e6e5 ER |
839 | mod_webdav_la_SOURCES = mod_webdav.c |
840 | -mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS) | |
841 | +mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS) | |
842 | mod_webdav_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined | |
843 | -mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) | |
844 | +mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) $(UUID_LIB) | |
1175ccec ER |
845 | |
846 | lib_LTLIBRARIES += mod_cml.la | |
2519e6e5 | 847 | mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c |
1175ccec | 848 | @@ -103,6 +109,11 @@ |
2519e6e5 ER |
849 | mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd) |
850 | mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE) | |
1175ccec ER |
851 | |
852 | +lib_LTLIBRARIES += mod_sql_vhost_core.la | |
2519e6e5 ER |
853 | +mod_sql_vhost_core_la_SOURCES = mod_sql_vhost_core.c |
854 | +mod_sql_vhost_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined | |
855 | +mod_sql_vhost_core_la_LIBADD = $(common_libadd) | |
1175ccec ER |
856 | + |
857 | lib_LTLIBRARIES += mod_cgi.la | |
2519e6e5 ER |
858 | mod_cgi_la_SOURCES = mod_cgi.c |
859 | mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined | |
1175ccec | 860 | @@ -240,7 +251,8 @@ |
2519e6e5 ER |
861 | mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \ |
862 | configparser.h mod_ssi_exprparser.h \ | |
863 | sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \ | |
864 | - splaytree.h proc_open.h | |
36e2a29e | 865 | + splaytree.h proc_open.h http_resp.h mod_sql_vhost_core.h \ |
1175ccec | 866 | + sys-files.h sys-process.h sys-strings.h http_resp_parser.h |
2519e6e5 | 867 | |
1175ccec ER |
868 | DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" |
869 | ||
870 | @@ -267,4 +279,4 @@ | |
871 | #ajp_SOURCES = ajp.c | |
872 | ||
873 | noinst_HEADERS = $(hdr) | |
874 | -EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c | |
875 | +EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c http_resp_parser.y | |
876 | --- ../lighttpd-1.4.11/src/array.c 2005-11-18 13:58:32.000000000 +0200 | |
36e2a29e | 877 | +++ lighttpd-1.4.12/src/array.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
878 | @@ -11,12 +11,12 @@ |
879 | ||
880 | array *array_init(void) { | |
881 | array *a; | |
882 | - | |
883 | + | |
884 | a = calloc(1, sizeof(*a)); | |
885 | assert(a); | |
886 | - | |
887 | + | |
888 | a->next_power_of_2 = 1; | |
889 | - | |
890 | + | |
891 | return a; | |
892 | } | |
893 | ||
894 | @@ -43,29 +43,29 @@ | |
895 | void array_free(array *a) { | |
896 | size_t i; | |
897 | if (!a) return; | |
898 | - | |
899 | + | |
900 | if (!a->is_weakref) { | |
901 | for (i = 0; i < a->size; i++) { | |
902 | if (a->data[i]) a->data[i]->free(a->data[i]); | |
903 | } | |
904 | } | |
905 | - | |
906 | + | |
907 | if (a->data) free(a->data); | |
908 | if (a->sorted) free(a->sorted); | |
909 | - | |
910 | + | |
911 | free(a); | |
912 | } | |
913 | ||
914 | void array_reset(array *a) { | |
915 | size_t i; | |
916 | if (!a) return; | |
917 | - | |
918 | + | |
919 | if (!a->is_weakref) { | |
920 | for (i = 0; i < a->used; i++) { | |
921 | a->data[i]->reset(a->data[i]); | |
922 | } | |
923 | } | |
924 | - | |
925 | + | |
926 | a->used = 0; | |
927 | } | |
928 | ||
929 | @@ -84,20 +84,20 @@ | |
930 | static int array_get_index(array *a, const char *key, size_t keylen, int *rndx) { | |
931 | int ndx = -1; | |
932 | int i, pos = 0; | |
933 | - | |
934 | + | |
935 | if (key == NULL) return -1; | |
936 | - | |
937 | + | |
938 | /* try to find the string */ | |
939 | for (i = pos = a->next_power_of_2 / 2; ; i >>= 1) { | |
940 | int cmp; | |
941 | - | |
942 | + | |
943 | if (pos < 0) { | |
944 | pos += i; | |
945 | } else if (pos >= (int)a->used) { | |
946 | pos -= i; | |
947 | } else { | |
948 | cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used); | |
949 | - | |
950 | + | |
951 | if (cmp == 0) { | |
952 | /* found */ | |
953 | ndx = a->sorted[pos]; | |
954 | @@ -110,46 +110,46 @@ | |
955 | } | |
956 | if (i == 0) break; | |
957 | } | |
958 | - | |
959 | + | |
960 | if (rndx) *rndx = pos; | |
961 | - | |
962 | + | |
963 | return ndx; | |
964 | } | |
965 | ||
966 | data_unset *array_get_element(array *a, const char *key) { | |
967 | int ndx; | |
968 | - | |
969 | + | |
970 | if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) { | |
971 | /* found, leave here */ | |
972 | - | |
973 | + | |
974 | return a->data[ndx]; | |
975 | - } | |
976 | - | |
977 | + } | |
978 | + | |
979 | return NULL; | |
980 | } | |
981 | ||
982 | data_unset *array_get_unused_element(array *a, data_type_t t) { | |
983 | data_unset *ds = NULL; | |
984 | - | |
985 | + | |
986 | UNUSED(t); | |
987 | ||
988 | if (a->size == 0) return NULL; | |
989 | - | |
990 | + | |
991 | if (a->used == a->size) return NULL; | |
992 | ||
993 | if (a->data[a->used]) { | |
994 | ds = a->data[a->used]; | |
995 | - | |
996 | + | |
997 | a->data[a->used] = NULL; | |
998 | } | |
999 | - | |
1000 | + | |
1001 | return ds; | |
1002 | } | |
1003 | ||
1004 | /* replace or insert data, return the old one with the same key */ | |
1005 | data_unset *array_replace(array *a, data_unset *du) { | |
1006 | int ndx; | |
1007 | - | |
1008 | + | |
1009 | if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) { | |
1010 | array_insert_unique(a, du); | |
1011 | return NULL; | |
1012 | @@ -164,13 +164,13 @@ | |
1013 | int ndx = -1; | |
f26f9fd5 ER |
1014 | int pos = 0; |
1015 | size_t j; | |
2519e6e5 | 1016 | - |
f26f9fd5 | 1017 | - /* generate unique index if neccesary */ |
2519e6e5 | 1018 | + |
f26f9fd5 ER |
1019 | + /* generate unique index if necessary */ |
1020 | if (str->key->used == 0 || str->is_index_key) { | |
1021 | buffer_copy_long(str->key, a->unique_ndx++); | |
1022 | str->is_index_key = 1; | |
2519e6e5 ER |
1023 | } |
1024 | - | |
1025 | + | |
1026 | /* try to find the string */ | |
1027 | if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) { | |
1028 | /* found, leave here */ | |
1029 | @@ -181,14 +181,14 @@ | |
1030 | } | |
1031 | return 0; | |
1032 | } | |
1033 | - | |
1034 | + | |
1035 | /* insert */ | |
1036 | - | |
1037 | + | |
1038 | if (a->used+1 > INT_MAX) { | |
1039 | /* we can't handle more then INT_MAX entries: see array_get_index() */ | |
1040 | return -1; | |
1041 | } | |
1042 | - | |
1043 | + | |
1044 | if (a->size == 0) { | |
1045 | a->size = 16; | |
1046 | a->data = malloc(sizeof(*a->data) * a->size); | |
1047 | @@ -204,27 +204,27 @@ | |
1048 | assert(a->sorted); | |
1049 | for (j = a->used; j < a->size; j++) a->data[j] = NULL; | |
1050 | } | |
1051 | - | |
1052 | + | |
1053 | ndx = (int) a->used; | |
1054 | - | |
1055 | + | |
1056 | a->data[a->used++] = str; | |
1057 | - | |
1058 | + | |
1059 | if (pos != ndx && | |
1060 | - ((pos < 0) || | |
1061 | + ((pos < 0) || | |
1062 | buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) { | |
f26f9fd5 | 1063 | pos++; |
2519e6e5 ER |
1064 | - } |
1065 | - | |
f26f9fd5 | 1066 | - /* move everything on step to the right */ |
2519e6e5 ER |
1067 | + } |
1068 | + | |
f26f9fd5 ER |
1069 | + /* move everything one step to the right */ |
1070 | if (pos != ndx) { | |
1071 | memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted)); | |
f673a614 | 1072 | } |
2519e6e5 ER |
1073 | - |
1074 | + | |
1075 | /* insert */ | |
1076 | a->sorted[pos] = ndx; | |
1077 | - | |
1078 | + | |
1079 | if (a->next_power_of_2 == (size_t)ndx) a->next_power_of_2 <<= 1; | |
1080 | - | |
1081 | + | |
1082 | return 0; | |
1083 | } | |
1084 | ||
1085 | @@ -254,7 +254,7 @@ | |
1086 | size_t i; | |
1087 | size_t maxlen; | |
1088 | int oneline = 1; | |
1089 | - | |
1090 | + | |
1091 | if (a->used > 5) { | |
1092 | oneline = 0; | |
1093 | } | |
1094 | @@ -314,7 +314,7 @@ | |
1095 | } | |
1096 | array_print_indent(depth); | |
1097 | fprintf(stderr, ")"); | |
1098 | - | |
1099 | + | |
1100 | return 0; | |
1101 | } | |
1102 | ||
1103 | @@ -323,47 +323,47 @@ | |
1104 | array *a; | |
1105 | data_string *ds; | |
1106 | data_count *dc; | |
1107 | - | |
1108 | + | |
1109 | UNUSED(argc); | |
1110 | UNUSED(argv); | |
1111 | ||
1112 | a = array_init(); | |
1113 | - | |
1114 | + | |
1115 | ds = data_string_init(); | |
1116 | buffer_copy_string(ds->key, "abc"); | |
1117 | buffer_copy_string(ds->value, "alfrag"); | |
1118 | - | |
1119 | + | |
1120 | array_insert_unique(a, (data_unset *)ds); | |
1121 | - | |
1122 | + | |
1123 | ds = data_string_init(); | |
1124 | buffer_copy_string(ds->key, "abc"); | |
1125 | buffer_copy_string(ds->value, "hameplman"); | |
1126 | - | |
1127 | + | |
1128 | array_insert_unique(a, (data_unset *)ds); | |
1129 | - | |
1130 | + | |
1131 | ds = data_string_init(); | |
1132 | buffer_copy_string(ds->key, "123"); | |
1133 | buffer_copy_string(ds->value, "alfrag"); | |
1134 | - | |
1135 | + | |
1136 | array_insert_unique(a, (data_unset *)ds); | |
1137 | - | |
1138 | + | |
1139 | dc = data_count_init(); | |
1140 | buffer_copy_string(dc->key, "def"); | |
1141 | - | |
1142 | + | |
1143 | array_insert_unique(a, (data_unset *)dc); | |
1144 | - | |
1145 | + | |
1146 | dc = data_count_init(); | |
1147 | buffer_copy_string(dc->key, "def"); | |
1148 | - | |
1149 | + | |
1150 | array_insert_unique(a, (data_unset *)dc); | |
1151 | - | |
1152 | + | |
1153 | array_print(a, 0); | |
1154 | - | |
1155 | + | |
1156 | array_free(a); | |
1157 | - | |
1158 | + | |
1159 | fprintf(stderr, "%d\n", | |
1160 | buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type"))); | |
1161 | - | |
1162 | + | |
1163 | return 0; | |
1164 | } | |
1165 | #endif | |
1175ccec | 1166 | --- ../lighttpd-1.4.11/src/array.h 2005-09-23 21:24:18.000000000 +0300 |
36e2a29e | 1167 | +++ lighttpd-1.4.12/src/array.h 2006-07-11 22:07:51.000000000 +0300 |
f26f9fd5 ER |
1168 | @@ -16,7 +16,7 @@ |
1169 | #define DATA_UNSET \ | |
1170 | data_type_t type; \ | |
1171 | buffer *key; \ | |
1172 | - int is_index_key; /* 1 if key is a array index (autogenerated keys) */ \ | |
1173 | + int is_index_key; /* 1 if key is an array index (auto-generated keys) */ \ | |
1174 | struct data_unset *(*copy)(const struct data_unset *src); \ | |
1175 | void (* free)(struct data_unset *p); \ | |
1176 | void (* reset)(struct data_unset *p); \ | |
2519e6e5 ER |
1177 | @@ -29,21 +29,21 @@ |
1178 | ||
1179 | typedef struct { | |
1180 | data_unset **data; | |
1181 | - | |
1182 | + | |
1183 | size_t *sorted; | |
1184 | - | |
1185 | + | |
1186 | size_t used; | |
1187 | size_t size; | |
1188 | - | |
1189 | + | |
1190 | size_t unique_ndx; | |
1191 | - | |
1192 | + | |
1193 | size_t next_power_of_2; | |
1194 | int is_weakref; /* data is weakref, don't bother the data */ | |
1195 | } array; | |
1196 | ||
1197 | typedef struct { | |
1198 | DATA_UNSET; | |
1199 | - | |
1200 | + | |
1201 | int count; | |
1202 | } data_count; | |
1203 | ||
1204 | @@ -51,7 +51,7 @@ | |
1205 | ||
1206 | typedef struct { | |
1207 | DATA_UNSET; | |
1208 | - | |
1209 | + | |
1210 | buffer *value; | |
1211 | } data_string; | |
1212 | ||
1213 | @@ -60,7 +60,7 @@ | |
1214 | ||
1215 | typedef struct { | |
1216 | DATA_UNSET; | |
1217 | - | |
1218 | + | |
1219 | array *value; | |
1220 | } data_array; | |
1221 | ||
1222 | @@ -74,7 +74,7 @@ | |
1223 | COMP_SERVER_SOCKET, COMP_HTTP_URL, COMP_HTTP_HOST, COMP_HTTP_REFERER, COMP_HTTP_USERAGENT, COMP_HTTP_COOKIE, COMP_HTTP_REMOTEIP | |
1224 | } comp_key_t; | |
1225 | ||
1226 | -/* $HTTP["host"] == "incremental.home.kneschke.de" { ... } | |
1227 | +/* $HTTP["host"] == "incremental.home.kneschke.de" { ... } | |
1228 | * for print: comp_key op string | |
1229 | * for compare: comp cond string/regex | |
1230 | */ | |
1231 | @@ -82,15 +82,15 @@ | |
1232 | typedef struct _data_config data_config; | |
1233 | struct _data_config { | |
1234 | DATA_UNSET; | |
1235 | - | |
1236 | + | |
1237 | array *value; | |
1238 | - | |
1239 | + | |
1240 | buffer *comp_key; | |
1241 | comp_key_t comp; | |
1242 | - | |
1243 | + | |
1244 | config_cond_t cond; | |
1245 | buffer *op; | |
1246 | - | |
1247 | + | |
1248 | int context_ndx; /* more or less like an id */ | |
1249 | array *childs; | |
1250 | /* nested */ | |
1251 | @@ -98,7 +98,7 @@ | |
1252 | /* for chaining only */ | |
1253 | data_config *prev; | |
1254 | data_config *next; | |
1255 | - | |
1256 | + | |
1257 | buffer *string; | |
1258 | #ifdef HAVE_PCRE_H | |
1259 | pcre *regex; | |
1260 | @@ -110,7 +110,7 @@ | |
1261 | ||
1262 | typedef struct { | |
1263 | DATA_UNSET; | |
1264 | - | |
1265 | + | |
1266 | int value; | |
1267 | } data_integer; | |
1268 | ||
1269 | @@ -120,13 +120,13 @@ | |
1270 | DATA_UNSET; | |
1271 | ||
1272 | buffer *host; | |
1273 | - | |
1274 | + | |
1275 | unsigned short port; | |
1276 | ||
1277 | time_t disable_ts; | |
1278 | int is_disabled; | |
1279 | size_t balance; | |
1280 | - | |
1281 | + | |
1282 | int usage; /* fair-balancing needs the no. of connections active on this host */ | |
1283 | int last_used_ndx; /* round robin */ | |
1284 | } data_fastcgi; | |
1175ccec ER |
1285 | --- ../lighttpd-1.4.11/src/base.h 2006-01-11 16:51:04.000000000 +0200 |
1286 | +++ lighttpd-1.4.12/src/base.h 2006-07-15 22:43:21.000000000 +0300 | |
f26f9fd5 ER |
1287 | @@ -2,7 +2,6 @@ |
1288 | #define _BASE_H_ | |
1289 | ||
1290 | #include <sys/types.h> | |
1291 | -#include <sys/time.h> | |
1292 | #include <sys/stat.h> | |
1293 | ||
1294 | #ifdef HAVE_CONFIG_H | |
2519e6e5 | 1295 | @@ -26,10 +25,9 @@ |
f26f9fd5 ER |
1296 | #include "sys-socket.h" |
1297 | #include "splaytree.h" | |
1298 | ||
1299 | - | |
1300 | #if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H | |
1301 | # define USE_OPENSSL | |
2519e6e5 ER |
1302 | -# include <openssl/ssl.h> |
1303 | +# include <openssl/ssl.h> | |
1304 | #endif | |
1305 | ||
1306 | #ifdef HAVE_FAM_H | |
f26f9fd5 ER |
1307 | @@ -40,10 +38,6 @@ |
1308 | # define O_BINARY 0 | |
f673a614 | 1309 | #endif |
f673a614 | 1310 | |
f26f9fd5 ER |
1311 | -#ifndef O_LARGEFILE |
1312 | -# define O_LARGEFILE 0 | |
1313 | -#endif | |
1314 | - | |
1315 | #ifndef SIZE_MAX | |
1316 | # ifdef SIZE_T_MAX | |
1317 | # define SIZE_MAX SIZE_T_MAX | |
1318 | @@ -70,7 +64,8 @@ | |
f673a614 | 1319 | |
f26f9fd5 ER |
1320 | /* solaris and NetBSD 1.3.x again */ |
1321 | #if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t)) | |
1322 | -# define uint32_t u_int32_t | |
1175ccec | 1323 | +/* # define uint32_t u_int32_t */ |
f26f9fd5 ER |
1324 | +typedef unsigned __int32 uint32_t; |
1325 | #endif | |
f673a614 | 1326 | |
f673a614 | 1327 | |
2519e6e5 ER |
1328 | @@ -80,24 +75,24 @@ |
1329 | ||
1330 | #include "settings.h" | |
1331 | ||
1332 | -typedef enum { T_CONFIG_UNSET, | |
1333 | - T_CONFIG_STRING, | |
1334 | - T_CONFIG_SHORT, | |
1335 | - T_CONFIG_BOOLEAN, | |
1336 | - T_CONFIG_ARRAY, | |
1337 | - T_CONFIG_LOCAL, | |
1338 | +typedef enum { T_CONFIG_UNSET, | |
1339 | + T_CONFIG_STRING, | |
1340 | + T_CONFIG_SHORT, | |
1341 | + T_CONFIG_BOOLEAN, | |
1342 | + T_CONFIG_ARRAY, | |
1343 | + T_CONFIG_LOCAL, | |
1344 | T_CONFIG_DEPRECATED | |
1345 | } config_values_type_t; | |
1346 | ||
1347 | -typedef enum { T_CONFIG_SCOPE_UNSET, | |
1348 | - T_CONFIG_SCOPE_SERVER, | |
1349 | +typedef enum { T_CONFIG_SCOPE_UNSET, | |
1350 | + T_CONFIG_SCOPE_SERVER, | |
1351 | T_CONFIG_SCOPE_CONNECTION | |
1352 | } config_scope_type_t; | |
f673a614 | 1353 | |
f26f9fd5 | 1354 | typedef struct { |
2519e6e5 ER |
1355 | const char *key; |
1356 | void *destination; | |
1357 | - | |
1358 | + | |
1359 | config_values_type_t type; | |
1360 | config_scope_type_t scope; | |
1361 | } config_values_t; | |
1175ccec ER |
1362 | @@ -118,18 +113,6 @@ |
1363 | short factor; | |
1364 | } fcgi_connections; | |
1365 | ||
1366 | - | |
1367 | -typedef union { | |
1368 | -#ifdef HAVE_IPV6 | |
1369 | - struct sockaddr_in6 ipv6; | |
1370 | -#endif | |
1371 | - struct sockaddr_in ipv4; | |
1372 | -#ifdef HAVE_SYS_UN_H | |
1373 | - struct sockaddr_un un; | |
1374 | -#endif | |
1375 | - struct sockaddr plain; | |
1376 | -} sock_addr; | |
1377 | - | |
1378 | /* fcgi_response_header contains ... */ | |
1379 | #define HTTP_STATUS BV(0) | |
1380 | #define HTTP_CONNECTION BV(1) | |
1381 | @@ -142,40 +125,40 @@ | |
2519e6e5 ER |
1382 | /* the request-line */ |
1383 | buffer *request; | |
1384 | buffer *uri; | |
1385 | - | |
1386 | + | |
1387 | buffer *orig_uri; | |
1388 | - | |
1389 | + | |
1390 | http_method_t http_method; | |
1391 | http_version_t http_version; | |
1392 | - | |
1393 | + | |
1394 | buffer *request_line; | |
1395 | - | |
1396 | + | |
1397 | /* strings to the header */ | |
1398 | buffer *http_host; /* not alloced */ | |
1399 | const char *http_range; | |
1400 | const char *http_content_type; | |
1401 | const char *http_if_modified_since; | |
1402 | const char *http_if_none_match; | |
1403 | - | |
1404 | + | |
f26f9fd5 | 1405 | array *headers; |
2519e6e5 ER |
1406 | - |
1407 | + | |
1408 | /* CONTENT */ | |
1409 | size_t content_length; /* returned by strtoul() */ | |
1410 | - | |
1411 | + | |
1412 | /* internal representation */ | |
1413 | int accept_encoding; | |
1414 | - | |
1415 | + | |
1416 | /* internal */ | |
1417 | buffer *pathinfo; | |
1418 | } request; | |
1419 | ||
1420 | typedef struct { | |
1421 | off_t content_length; | |
1422 | - int keep_alive; /* used by the subrequests in proxy, cgi and fcgi to say the subrequest was keep-alive or not */ | |
1423 | - | |
1424 | + int keep_alive; /* used by the subrequests in proxy, cgi and fcgi to say whether the subrequest was keep-alive or not */ | |
1425 | + | |
1426 | array *headers; | |
1427 | - | |
1428 | - enum { | |
1429 | + | |
1430 | + enum { | |
1431 | HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED | |
1432 | } transfer_encoding; | |
1433 | } response; | |
1175ccec | 1434 | @@ -191,21 +174,21 @@ |
2519e6e5 ER |
1435 | typedef struct { |
1436 | buffer *path; | |
1437 | buffer *basedir; /* path = "(basedir)(.*)" */ | |
1438 | - | |
1439 | + | |
1440 | buffer *doc_root; /* path = doc_root + rel_path */ | |
1441 | buffer *rel_path; | |
1442 | - | |
1443 | + | |
1444 | buffer *etag; | |
1445 | } physical; | |
1446 | ||
1447 | typedef struct { | |
1448 | buffer *name; | |
1449 | buffer *etag; | |
1450 | - | |
1451 | + | |
1452 | struct stat st; | |
1453 | - | |
1454 | + | |
1455 | time_t stat_ts; | |
1456 | - | |
1457 | + | |
1458 | #ifdef HAVE_FAM_H | |
1459 | int dir_version; | |
1460 | int dir_ndx; | |
1175ccec | 1461 | @@ -215,8 +198,8 @@ |
f26f9fd5 ER |
1462 | } stat_cache_entry; |
1463 | ||
1464 | typedef struct { | |
1465 | - splay_tree *files; /* the nodes of the tree are stat_cache_entry's */ | |
2519e6e5 | 1466 | - |
f26f9fd5 | 1467 | + splay_tree *files; /* the nodes of the tree are stat_cache_entries */ |
2519e6e5 | 1468 | + |
f26f9fd5 ER |
1469 | buffer *dir_name; /* for building the dirname from the filename */ |
1470 | #ifdef HAVE_FAM_H | |
2519e6e5 | 1471 | splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */ |
1175ccec | 1472 | @@ -228,7 +211,7 @@ |
2519e6e5 ER |
1473 | |
1474 | typedef struct { | |
1475 | array *mimetypes; | |
1476 | - | |
1477 | + | |
1478 | /* virtual-servers */ | |
1479 | buffer *document_root; | |
1480 | buffer *server_name; | |
1175ccec | 1481 | @@ -236,7 +219,7 @@ |
2519e6e5 ER |
1482 | buffer *server_tag; |
1483 | buffer *dirlist_encoding; | |
1484 | buffer *errorfile_prefix; | |
1485 | - | |
1486 | + | |
1487 | unsigned short max_keep_alive_requests; | |
1488 | unsigned short max_keep_alive_idle; | |
1489 | unsigned short max_read_idle; | |
1175ccec | 1490 | @@ -244,16 +227,17 @@ |
2519e6e5 ER |
1491 | unsigned short use_xattr; |
1492 | unsigned short follow_symlink; | |
1493 | unsigned short range_requests; | |
1494 | - | |
1495 | + | |
1496 | /* debug */ | |
1497 | - | |
1498 | + | |
1499 | unsigned short log_file_not_found; | |
1500 | unsigned short log_request_header; | |
f26f9fd5 ER |
1501 | unsigned short log_request_handling; |
1502 | unsigned short log_response_header; | |
1503 | unsigned short log_condition_handling; | |
2519e6e5 ER |
1504 | - |
1505 | - | |
f26f9fd5 | 1506 | + unsigned short log_condition_cache_handling; |
2519e6e5 ER |
1507 | + |
1508 | + | |
f26f9fd5 | 1509 | /* server wide */ |
2519e6e5 ER |
1510 | buffer *ssl_pemfile; |
1511 | buffer *ssl_ca_file; | |
1175ccec | 1512 | @@ -268,22 +252,22 @@ |
2519e6e5 ER |
1513 | /* configside */ |
1514 | unsigned short global_kbytes_per_second; /* */ | |
1515 | ||
1516 | - off_t global_bytes_per_second_cnt; | |
1517 | + off_t global_bytes_per_second_cnt; | |
f26f9fd5 | 1518 | /* server-wide traffic-shaper |
2519e6e5 ER |
1519 | - * |
1520 | + * | |
f26f9fd5 ER |
1521 | * each context has the counter which is inited once |
1522 | - * a second by the global_kbytes_per_second config-var | |
1523 | + * per second by the global_kbytes_per_second config-var | |
1524 | * | |
1525 | * as soon as global_kbytes_per_second gets below 0 | |
1526 | * the connected conns are "offline" a little bit | |
1527 | * | |
1528 | * the problem: | |
1529 | - * we somehow have to loose our "we are writable" signal | |
1530 | + * we somehow have to lose our "we are writable" signal | |
1531 | * on the way. | |
2519e6e5 ER |
1532 | - * |
1533 | + * | |
f26f9fd5 | 1534 | */ |
2519e6e5 ER |
1535 | off_t *global_bytes_per_second_cnt_ptr; /* */ |
1536 | - | |
1537 | + | |
1538 | #ifdef USE_OPENSSL | |
1539 | SSL_CTX *ssl_ctx; | |
1540 | #endif | |
1175ccec | 1541 | @@ -291,18 +275,18 @@ |
2519e6e5 ER |
1542 | |
1543 | /* the order of the items should be the same as they are processed | |
1544 | * read before write as we use this later */ | |
1545 | -typedef enum { | |
1546 | - CON_STATE_CONNECT, | |
1547 | - CON_STATE_REQUEST_START, | |
1548 | - CON_STATE_READ, | |
1549 | - CON_STATE_REQUEST_END, | |
1550 | - CON_STATE_READ_POST, | |
1551 | - CON_STATE_HANDLE_REQUEST, | |
1552 | - CON_STATE_RESPONSE_START, | |
1553 | - CON_STATE_WRITE, | |
1554 | - CON_STATE_RESPONSE_END, | |
1555 | - CON_STATE_ERROR, | |
1556 | - CON_STATE_CLOSE | |
1557 | +typedef enum { | |
1558 | + CON_STATE_CONNECT, | |
1559 | + CON_STATE_REQUEST_START, | |
1560 | + CON_STATE_READ, | |
1561 | + CON_STATE_REQUEST_END, | |
1562 | + CON_STATE_READ_POST, | |
1563 | + CON_STATE_HANDLE_REQUEST, | |
1564 | + CON_STATE_RESPONSE_START, | |
1565 | + CON_STATE_WRITE, | |
1566 | + CON_STATE_RESPONSE_END, | |
1567 | + CON_STATE_ERROR, | |
1568 | + CON_STATE_CLOSE | |
1569 | } connection_state_t; | |
1570 | ||
1571 | typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t; | |
1175ccec | 1572 | @@ -315,88 +299,88 @@ |
2519e6e5 ER |
1573 | |
1574 | typedef struct { | |
1575 | connection_state_t state; | |
1576 | - | |
1577 | + | |
1578 | /* timestamps */ | |
1579 | time_t read_idle_ts; | |
1580 | time_t close_timeout_ts; | |
1581 | time_t write_request_ts; | |
1582 | - | |
1583 | + | |
1584 | time_t connection_start; | |
1585 | time_t request_start; | |
1586 | - | |
1587 | + | |
1588 | struct timeval start_tv; | |
1589 | - | |
1590 | + | |
1591 | size_t request_count; /* number of requests handled in this connection */ | |
1592 | size_t loops_per_request; /* to catch endless loops in a single request | |
1593 | - * | |
1594 | + * | |
1595 | * used by mod_rewrite, mod_fastcgi, ... and others | |
1596 | * this is self-protection | |
1597 | */ | |
1598 | - | |
1599 | + | |
1600 | int fd; /* the FD for this connection */ | |
1601 | int fde_ndx; /* index for the fdevent-handler */ | |
1602 | int ndx; /* reverse mapping to server->connection[ndx] */ | |
1603 | - | |
1604 | + | |
1605 | /* fd states */ | |
f26f9fd5 ER |
1606 | int is_readable; |
1607 | int is_writable; | |
2519e6e5 | 1608 | - |
f26f9fd5 | 1609 | - int keep_alive; /* only request.c can enable it, all other just disable */ |
2519e6e5 ER |
1610 | - |
1611 | + | |
f26f9fd5 | 1612 | + int keep_alive; /* only request.c can enable it, all others just disable */ |
2519e6e5 | 1613 | + |
f26f9fd5 ER |
1614 | int file_started; |
1615 | int file_finished; | |
2519e6e5 ER |
1616 | - |
1617 | + | |
1618 | chunkqueue *write_queue; /* a large queue for low-level write ( HTTP response ) [ file, mem ] */ | |
1619 | chunkqueue *read_queue; /* a small queue for low-level read ( HTTP request ) [ mem ] */ | |
1620 | chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/ | |
1621 | - | |
1622 | + | |
1623 | int traffic_limit_reached; | |
1624 | - | |
1625 | + | |
1626 | off_t bytes_written; /* used by mod_accesslog, mod_rrd */ | |
1627 | off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */ | |
1628 | off_t bytes_read; /* used by mod_accesslog, mod_rrd */ | |
1629 | off_t bytes_header; | |
1630 | - | |
1631 | + | |
1632 | int http_status; | |
1633 | - | |
1634 | + | |
1635 | sock_addr dst_addr; | |
1636 | buffer *dst_addr_buf; | |
1637 | ||
1638 | /* request */ | |
1639 | buffer *parse_request; | |
1640 | unsigned int parsed_response; /* bitfield which contains the important header-fields of the parsed response header */ | |
1641 | - | |
1642 | + | |
1643 | request request; | |
1644 | request_uri uri; | |
1645 | - physical physical; | |
1646 | + physical physical; | |
1647 | response response; | |
1648 | - | |
1649 | + | |
1650 | size_t header_len; | |
1651 | - | |
1652 | + | |
1653 | buffer *authed_user; | |
1654 | array *environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */ | |
1655 | - | |
1656 | + | |
1657 | /* response */ | |
1658 | int got_response; | |
1659 | - | |
1660 | + | |
1661 | int in_joblist; | |
1662 | - | |
1663 | + | |
1664 | connection_type mode; | |
1665 | - | |
1666 | + | |
1667 | void **plugin_ctx; /* plugin connection specific config */ | |
1668 | - | |
1669 | + | |
1670 | specific_config conf; /* global connection specific config */ | |
1671 | cond_cache_t *cond_cache; | |
1672 | - | |
1673 | + | |
1674 | buffer *server_name; | |
1675 | - | |
1676 | + | |
1677 | /* error-handler */ | |
1678 | buffer *error_handler; | |
1679 | int error_handler_saved_status; | |
1680 | int in_error_handler; | |
1681 | - | |
1682 | + | |
1683 | void *srv_socket; /* reference to the server-socket (typecast to server_socket) */ | |
1684 | - | |
1685 | + | |
1686 | #ifdef USE_OPENSSL | |
1687 | SSL *ssl; | |
1688 | #endif | |
1175ccec | 1689 | @@ -439,39 +423,48 @@ |
f26f9fd5 ER |
1690 | size_t size; |
1691 | } buffer_plugin; | |
1692 | ||
1693 | +typedef enum { | |
1694 | + NETWORK_STATUS_UNSET, | |
1695 | + NETWORK_STATUS_SUCCESS, | |
1696 | + NETWORK_STATUS_FATAL_ERROR, | |
1697 | + NETWORK_STATUS_CONNECTION_CLOSE, | |
1698 | + NETWORK_STATUS_WAIT_FOR_EVENT, | |
1699 | + NETWORK_STATUS_INTERRUPTED | |
1700 | +} network_status_t; | |
f673a614 | 1701 | + |
f26f9fd5 ER |
1702 | typedef struct { |
1703 | unsigned short port; | |
1704 | buffer *bindhost; | |
2519e6e5 ER |
1705 | - |
1706 | + | |
1707 | buffer *errorlog_file; | |
1708 | unsigned short errorlog_use_syslog; | |
1709 | - | |
1710 | + | |
1711 | unsigned short dont_daemonize; | |
1712 | buffer *changeroot; | |
1713 | buffer *username; | |
1714 | buffer *groupname; | |
1715 | - | |
1716 | + | |
1717 | buffer *pid_file; | |
1718 | - | |
1719 | + | |
1720 | buffer *event_handler; | |
1721 | - | |
1722 | + | |
1723 | buffer *modules_dir; | |
1724 | buffer *network_backend; | |
1725 | array *modules; | |
1726 | array *upload_tempdirs; | |
1727 | - | |
1728 | + | |
1729 | unsigned short max_worker; | |
1730 | unsigned short max_fds; | |
1731 | unsigned short max_conns; | |
1732 | unsigned short max_request_size; | |
1733 | - | |
1734 | + | |
1735 | unsigned short log_request_header_on_error; | |
1736 | unsigned short log_state_handling; | |
1737 | - | |
1738 | - enum { STAT_CACHE_ENGINE_UNSET, | |
1739 | - STAT_CACHE_ENGINE_NONE, | |
1740 | - STAT_CACHE_ENGINE_SIMPLE, | |
1741 | - STAT_CACHE_ENGINE_FAM | |
1742 | + | |
1743 | + enum { STAT_CACHE_ENGINE_UNSET, | |
1744 | + STAT_CACHE_ENGINE_NONE, | |
1745 | + STAT_CACHE_ENGINE_SIMPLE, | |
1746 | + STAT_CACHE_ENGINE_FAM | |
1747 | } stat_cache_engine; | |
1748 | unsigned short enable_cores; | |
1749 | } server_config; | |
1175ccec | 1750 | @@ -480,14 +473,14 @@ |
2519e6e5 ER |
1751 | sock_addr addr; |
1752 | int fd; | |
1753 | int fde_ndx; | |
1754 | - | |
1755 | + | |
1756 | buffer *ssl_pemfile; | |
1757 | buffer *ssl_ca_file; | |
1758 | unsigned short use_ipv6; | |
1759 | unsigned short is_ssl; | |
1760 | - | |
1761 | + | |
1762 | buffer *srv_token; | |
1763 | - | |
1764 | + | |
1765 | #ifdef USE_OPENSSL | |
1766 | SSL_CTX *ssl_ctx; | |
1767 | #endif | |
1175ccec | 1768 | @@ -495,37 +488,37 @@ |
2519e6e5 ER |
1769 | |
1770 | typedef struct { | |
1771 | server_socket **ptr; | |
1772 | - | |
1773 | + | |
1774 | size_t size; | |
1775 | size_t used; | |
1776 | } server_socket_array; | |
1777 | ||
1778 | typedef struct server { | |
1779 | server_socket_array srv_sockets; | |
1780 | - | |
1781 | + | |
1782 | /* the errorlog */ | |
1783 | int errorlog_fd; | |
1784 | enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode; | |
1785 | buffer *errorlog_buf; | |
1786 | - | |
1787 | + | |
1788 | fdevents *ev, *ev_ins; | |
1789 | - | |
1790 | + | |
1791 | buffer_plugin plugins; | |
1792 | void *plugin_slots; | |
1793 | - | |
1794 | + | |
1795 | /* counters */ | |
1796 | int con_opened; | |
1797 | int con_read; | |
1798 | int con_written; | |
1799 | int con_closed; | |
1800 | - | |
1801 | + | |
1802 | int ssl_is_init; | |
1803 | - | |
1804 | + | |
1805 | int max_fds; /* max possible fds */ | |
1806 | int cur_fds; /* currently used fds */ | |
1807 | int want_fds; /* waiting fds */ | |
1808 | int sockets_disabled; | |
1809 | - | |
1810 | + | |
1811 | size_t max_conns; | |
1812 | ||
1813 | /* buffers */ | |
1175ccec | 1814 | @@ -533,13 +526,13 @@ |
2519e6e5 ER |
1815 | buffer *response_header; |
1816 | buffer *response_range; | |
1817 | buffer *tmp_buf; | |
1818 | - | |
1819 | + | |
1820 | buffer *tmp_chunk_len; | |
1821 | - | |
1822 | + | |
1823 | buffer *empty_string; /* is necessary for cond_match */ | |
1824 | ||
1825 | buffer *cond_check_buf; | |
1826 | - | |
1827 | + | |
1828 | /* caches */ | |
1829 | #ifdef HAVE_IPV6 | |
1830 | inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX]; | |
1175ccec | 1831 | @@ -547,31 +540,31 @@ |
2519e6e5 ER |
1832 | mtime_cache_type mtime_cache[FILE_CACHE_MAX]; |
1833 | ||
1834 | array *split_vals; | |
1835 | - | |
1836 | + | |
1837 | /* Timestamps */ | |
1838 | time_t cur_ts; | |
1839 | time_t last_generated_date_ts; | |
1840 | time_t last_generated_debug_ts; | |
1841 | time_t startup_ts; | |
1842 | - | |
1843 | + | |
1844 | buffer *ts_debug_str; | |
1845 | buffer *ts_date_str; | |
1846 | - | |
1847 | + | |
1848 | /* config-file */ | |
1849 | array *config; | |
1850 | array *config_touched; | |
1851 | - | |
1852 | + | |
1853 | array *config_context; | |
1854 | specific_config **config_storage; | |
1855 | - | |
1856 | + | |
1857 | server_config srvconf; | |
1858 | - | |
1859 | + | |
1860 | int config_deprecated; | |
1861 | - | |
1862 | + | |
1863 | connections *conns; | |
1864 | connections *joblist; | |
1865 | connections *fdwaitqueue; | |
1866 | - | |
1867 | + | |
1868 | stat_cache *stat_cache; | |
1869 | ||
1870 | /** | |
1175ccec | 1871 | @@ -588,18 +581,20 @@ |
2519e6e5 ER |
1872 | * fastcgi.backend.<key>.disconnects = ... |
1873 | */ | |
1874 | array *status; | |
1875 | - | |
1876 | + | |
f26f9fd5 | 1877 | fdevent_handler_t event_handler; |
f673a614 | 1878 | |
f26f9fd5 ER |
1879 | - int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq); |
1880 | - int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq); | |
1881 | + network_status_t (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq); | |
1882 | + network_status_t (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq); | |
1883 | #ifdef USE_OPENSSL | |
1884 | - int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); | |
1885 | - int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); | |
1886 | + network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); | |
1887 | + network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); | |
f673a614 | 1888 | #endif |
f26f9fd5 ER |
1889 | |
1890 | +#ifdef HAVE_PWD_H | |
1891 | uid_t uid; | |
1892 | gid_t gid; | |
f673a614 | 1893 | +#endif |
f26f9fd5 | 1894 | } server; |
f673a614 | 1895 | |
f673a614 | 1896 | |
1175ccec | 1897 | --- ../lighttpd-1.4.11/src/buffer.c 2006-01-13 00:00:45.000000000 +0200 |
36e2a29e | 1898 | +++ lighttpd-1.4.12/src/buffer.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
1899 | @@ -12,20 +12,20 @@ |
1900 | ||
1901 | ||
1902 | /** | |
1903 | - * init the buffer | |
1904 | - * | |
1905 | + * init the buffer | |
1906 | + * | |
1907 | */ | |
1908 | ||
1909 | buffer* buffer_init(void) { | |
1910 | buffer *b; | |
1911 | - | |
1912 | + | |
1913 | b = malloc(sizeof(*b)); | |
1914 | assert(b); | |
1915 | - | |
1916 | + | |
1917 | b->ptr = NULL; | |
1918 | b->size = 0; | |
1919 | b->used = 0; | |
1920 | - | |
1921 | + | |
1922 | return b; | |
1923 | } | |
1924 | ||
1925 | @@ -36,8 +36,8 @@ | |
1926 | } | |
1927 | ||
1928 | /** | |
1929 | - * free the buffer | |
1930 | - * | |
1931 | + * free the buffer | |
1932 | + * | |
1933 | */ | |
1934 | ||
1935 | void buffer_free(buffer *b) { | |
1936 | @@ -49,39 +49,39 @@ | |
1937 | ||
1938 | void buffer_reset(buffer *b) { | |
1939 | if (!b) return; | |
1940 | - | |
1941 | + | |
1942 | /* limit don't reuse buffer larger than ... bytes */ | |
1943 | if (b->size > BUFFER_MAX_REUSE_SIZE) { | |
1944 | free(b->ptr); | |
1945 | b->ptr = NULL; | |
1946 | b->size = 0; | |
1947 | } | |
1948 | - | |
1949 | + | |
1950 | b->used = 0; | |
1951 | } | |
1952 | ||
f673a614 ER |
1953 | |
1954 | /** | |
2519e6e5 | 1955 | - * |
f26f9fd5 | 1956 | - * allocate (if neccessary) enough space for 'size' bytes and |
2519e6e5 | 1957 | + * |
f26f9fd5 ER |
1958 | + * allocate (if necessary) enough space for 'size' bytes and |
1959 | * set the 'used' counter to 0 | |
2519e6e5 ER |
1960 | - * |
1961 | + * | |
f673a614 | 1962 | */ |
2519e6e5 ER |
1963 | |
1964 | #define BUFFER_PIECE_SIZE 64 | |
1965 | ||
1966 | int buffer_prepare_copy(buffer *b, size_t size) { | |
1967 | if (!b) return -1; | |
1968 | - | |
1969 | - if ((0 == b->size) || | |
1970 | + | |
1971 | + if ((0 == b->size) || | |
1972 | (size > b->size)) { | |
1973 | if (b->size) free(b->ptr); | |
1974 | - | |
1975 | + | |
f26f9fd5 | 1976 | b->size = size; |
2519e6e5 | 1977 | - |
f26f9fd5 | 1978 | - /* always allocate a multiply of BUFFER_PIECE_SIZE */ |
2519e6e5 | 1979 | + |
f26f9fd5 ER |
1980 | + /* always allocate a multiple of BUFFER_PIECE_SIZE */ |
1981 | b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE); | |
2519e6e5 ER |
1982 | - |
1983 | + | |
f26f9fd5 | 1984 | b->ptr = malloc(b->size); |
2519e6e5 ER |
1985 | assert(b->ptr); |
1986 | } | |
1987 | @@ -90,30 +90,30 @@ | |
1988 | } | |
f673a614 | 1989 | |
f26f9fd5 | 1990 | /** |
2519e6e5 | 1991 | - * |
f26f9fd5 | 1992 | - * increase the internal buffer (if neccessary) to append another 'size' byte |
2519e6e5 | 1993 | + * |
f26f9fd5 ER |
1994 | + * increase the internal buffer (if necessary) to append another 'size' byte |
1995 | * ->used isn't changed | |
2519e6e5 ER |
1996 | - * |
1997 | + * | |
f26f9fd5 | 1998 | */ |
2519e6e5 ER |
1999 | |
2000 | int buffer_prepare_append(buffer *b, size_t size) { | |
2001 | if (!b) return -1; | |
2002 | - | |
2003 | + | |
f26f9fd5 ER |
2004 | if (0 == b->size) { |
2005 | b->size = size; | |
2519e6e5 | 2006 | - |
f26f9fd5 | 2007 | - /* always allocate a multiply of BUFFER_PIECE_SIZE */ |
2519e6e5 | 2008 | + |
f26f9fd5 ER |
2009 | + /* always allocate a multiple of BUFFER_PIECE_SIZE */ |
2010 | b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE); | |
2519e6e5 ER |
2011 | - |
2012 | + | |
f26f9fd5 | 2013 | b->ptr = malloc(b->size); |
2519e6e5 ER |
2014 | b->used = 0; |
2015 | assert(b->ptr); | |
f26f9fd5 ER |
2016 | } else if (b->used + size > b->size) { |
2017 | b->size += size; | |
2519e6e5 | 2018 | - |
f26f9fd5 | 2019 | - /* always allocate a multiply of BUFFER_PIECE_SIZE */ |
2519e6e5 | 2020 | + |
f26f9fd5 ER |
2021 | + /* always allocate a multiple of BUFFER_PIECE_SIZE */ |
2022 | b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE); | |
2519e6e5 ER |
2023 | - |
2024 | + | |
f26f9fd5 | 2025 | b->ptr = realloc(b->ptr, b->size); |
2519e6e5 ER |
2026 | assert(b->ptr); |
2027 | } | |
2028 | @@ -122,7 +122,7 @@ | |
2029 | ||
2030 | int buffer_copy_string(buffer *b, const char *s) { | |
2031 | size_t s_len; | |
2032 | - | |
2033 | + | |
2034 | if (!s || !b) return -1; | |
2035 | ||
2036 | s_len = strlen(s) + 1; | |
2037 | @@ -136,26 +136,26 @@ | |
2038 | ||
2039 | int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) { | |
2040 | if (!s || !b) return -1; | |
2041 | -#if 0 | |
2042 | - /* removed optimization as we have to keep the empty string | |
2043 | +#if 0 | |
2044 | + /* removed optimization as we have to keep the empty string | |
2045 | * in some cases for the config handling | |
2046 | - * | |
2047 | + * | |
2048 | * url.access-deny = ( "" ) | |
2049 | */ | |
2050 | if (s_len == 0) return 0; | |
2051 | -#endif | |
2052 | +#endif | |
2053 | buffer_prepare_copy(b, s_len + 1); | |
2054 | - | |
2055 | + | |
2056 | memcpy(b->ptr, s, s_len); | |
2057 | b->ptr[s_len] = '\0'; | |
2058 | b->used = s_len + 1; | |
2059 | - | |
2060 | + | |
2061 | return 0; | |
2062 | } | |
2063 | ||
2064 | int buffer_copy_string_buffer(buffer *b, const buffer *src) { | |
2065 | if (!src) return -1; | |
2066 | - | |
2067 | + | |
2068 | if (src->used == 0) { | |
2069 | b->used = 0; | |
2070 | return 0; | |
2071 | @@ -201,10 +201,10 @@ | |
2072 | ||
2073 | /** | |
f26f9fd5 | 2074 | * append a string to the end of the buffer |
2519e6e5 ER |
2075 | - * |
2076 | - * the resulting buffer is terminated with a '\0' | |
f26f9fd5 | 2077 | - * s is treated as a un-terminated string (a \0 is handled a normal character) |
2519e6e5 ER |
2078 | - * |
2079 | + * | |
2080 | + * the resulting buffer is terminated with a '\0' | |
f26f9fd5 | 2081 | + * s is treated as an un-terminated string (a \0 is handled as a normal character) |
2519e6e5 | 2082 | + * |
f26f9fd5 ER |
2083 | * @param b a buffer |
2084 | * @param s the string | |
2519e6e5 ER |
2085 | * @param s_len size of the string (without the terminating \0) |
2086 | @@ -228,7 +228,7 @@ | |
2087 | int buffer_append_string_buffer(buffer *b, const buffer *src) { | |
2088 | if (!src) return -1; | |
2089 | if (src->used == 0) return 0; | |
2090 | - | |
2091 | + | |
2092 | return buffer_append_string_len(b, src->ptr, src->used - 1); | |
2093 | } | |
2094 | ||
2095 | @@ -245,9 +245,9 @@ | |
2096 | ||
2097 | int buffer_copy_memory(buffer *b, const char *s, size_t s_len) { | |
2098 | if (!s || !b) return -1; | |
2099 | - | |
2100 | + | |
2101 | b->used = 0; | |
2102 | - | |
2103 | + | |
2104 | return buffer_append_memory(b, s, s_len); | |
2105 | } | |
2106 | ||
2107 | @@ -402,46 +402,115 @@ | |
f673a614 | 2108 | |
f673a614 ER |
2109 | |
2110 | /** | |
2519e6e5 ER |
2111 | - * init the buffer |
2112 | - * | |
f26f9fd5 | 2113 | + * init the ptr buffer |
f673a614 | 2114 | + * |
f26f9fd5 ER |
2115 | + */ |
2116 | +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer) | |
2117 | +{ | |
2118 | + buffer_ptr *l = calloc(1, sizeof(buffer_ptr)); | |
2119 | + l->free = freer; | |
f673a614 | 2120 | + |
f26f9fd5 ER |
2121 | + return l; |
2122 | +} | |
f673a614 | 2123 | + |
f26f9fd5 ER |
2124 | +/** |
2125 | + * free the buffer_array | |
2126 | + * | |
2127 | + */ | |
2128 | +void buffer_ptr_free(buffer_ptr *l) | |
2129 | +{ | |
2130 | + if (NULL != l) { | |
2131 | + buffer_ptr_clear(l); | |
2132 | + free(l); | |
2133 | + } | |
2134 | +} | |
f673a614 | 2135 | + |
f26f9fd5 ER |
2136 | +void buffer_ptr_clear(buffer_ptr *l) |
2137 | +{ | |
2138 | + assert(NULL != l); | |
f673a614 | 2139 | + |
f26f9fd5 ER |
2140 | + if (l->free && l->used) { |
2141 | + size_t i; | |
2142 | + for (i = 0; i < l->used; i ++) { | |
2143 | + l->free(l->ptr[i]); | |
2144 | + } | |
2145 | + } | |
f673a614 | 2146 | + |
f26f9fd5 ER |
2147 | + if (l->ptr) { |
2148 | + free(l->ptr); | |
2149 | + l->ptr = NULL; | |
2150 | + } | |
2151 | + l->used = 0; | |
2152 | + l->size = 0; | |
2153 | +} | |
f673a614 | 2154 | + |
f26f9fd5 ER |
2155 | +void buffer_ptr_append(buffer_ptr* l, void *item) |
2156 | +{ | |
2157 | + assert(NULL != l); | |
2158 | + if (l->ptr == NULL) { | |
2159 | + l->size = 16; | |
2160 | + l->ptr = (void **)malloc(sizeof(void *) * l->size); | |
2161 | + } | |
2162 | + else if (l->used == l->size) { | |
2163 | + l->size += 16; | |
2164 | + l->ptr = realloc(l->ptr, sizeof(void *) * l->size); | |
2165 | + } | |
2166 | + l->ptr[l->used++] = item; | |
2167 | +} | |
f673a614 | 2168 | + |
f26f9fd5 ER |
2169 | +void *buffer_ptr_pop(buffer_ptr* l) |
2170 | +{ | |
2171 | + assert(NULL != l && l->used > 0); | |
2172 | + return l->ptr[--l->used]; | |
2173 | +} | |
f673a614 | 2174 | + |
f26f9fd5 ER |
2175 | +void *buffer_ptr_top(buffer_ptr* l) |
2176 | +{ | |
2177 | + assert(NULL != l && l->used > 0); | |
2178 | + return l->ptr[l->used-1]; | |
2179 | +} | |
f673a614 | 2180 | + |
f26f9fd5 | 2181 | +/** |
2519e6e5 ER |
2182 | + * init the buffer |
2183 | + * | |
2184 | */ | |
2185 | ||
2186 | buffer_array* buffer_array_init(void) { | |
2187 | buffer_array *b; | |
2188 | - | |
2189 | + | |
2190 | b = malloc(sizeof(*b)); | |
2191 | - | |
2192 | + | |
2193 | assert(b); | |
2194 | b->ptr = NULL; | |
2195 | b->size = 0; | |
2196 | b->used = 0; | |
2197 | - | |
2198 | + | |
2199 | return b; | |
2200 | } | |
2201 | ||
2202 | void buffer_array_reset(buffer_array *b) { | |
2203 | size_t i; | |
2204 | - | |
2205 | + | |
2206 | if (!b) return; | |
2207 | - | |
2208 | + | |
2209 | /* if they are too large, reduce them */ | |
2210 | for (i = 0; i < b->used; i++) { | |
2211 | buffer_reset(b->ptr[i]); | |
2212 | } | |
2213 | - | |
2214 | + | |
2215 | b->used = 0; | |
2216 | } | |
2217 | ||
2218 | ||
2219 | /** | |
2220 | - * free the buffer_array | |
2221 | - * | |
2222 | + * free the buffer_array | |
2223 | + * | |
f26f9fd5 | 2224 | */ |
2519e6e5 ER |
2225 | |
2226 | void buffer_array_free(buffer_array *b) { | |
2227 | size_t i; | |
2228 | if (!b) return; | |
2229 | - | |
2230 | + | |
2231 | for (i = 0; i < b->size; i++) { | |
2232 | if (b->ptr[i]) buffer_free(b->ptr[i]); | |
2233 | } | |
2234 | @@ -451,7 +520,7 @@ | |
2235 | ||
2236 | buffer *buffer_array_append_get_buffer(buffer_array *b) { | |
2237 | size_t i; | |
2238 | - | |
2239 | + | |
2240 | if (b->size == 0) { | |
2241 | b->size = 16; | |
2242 | b->ptr = malloc(sizeof(*b->ptr) * b->size); | |
2243 | @@ -467,13 +536,13 @@ | |
2244 | b->ptr[i] = NULL; | |
2245 | } | |
2246 | } | |
2247 | - | |
2248 | + | |
2249 | if (b->ptr[b->used] == NULL) { | |
2250 | b->ptr[b->used] = buffer_init(); | |
2251 | } | |
2252 | - | |
2253 | + | |
2254 | b->ptr[b->used]->used = 0; | |
2255 | - | |
2256 | + | |
2257 | return b->ptr[b->used++]; | |
2258 | } | |
2259 | ||
2260 | @@ -482,23 +551,23 @@ | |
2261 | size_t i; | |
2262 | if (len == 0) return NULL; | |
2263 | if (needle == NULL) return NULL; | |
2264 | - | |
2265 | + | |
2266 | if (b->used < len) return NULL; | |
2267 | - | |
2268 | + | |
2269 | for(i = 0; i < b->used - len; i++) { | |
2270 | if (0 == memcmp(b->ptr + i, needle, len)) { | |
2271 | return b->ptr + i; | |
2272 | } | |
2273 | } | |
2274 | - | |
2275 | + | |
2276 | return NULL; | |
2277 | } | |
2278 | ||
2279 | buffer *buffer_init_string(const char *str) { | |
2280 | buffer *b = buffer_init(); | |
2281 | - | |
2282 | + | |
2283 | buffer_copy_string(b, str); | |
2284 | - | |
2285 | + | |
2286 | return b; | |
2287 | } | |
2288 | ||
2289 | @@ -507,8 +576,8 @@ | |
f26f9fd5 | 2290 | } |
f673a614 | 2291 | |
f26f9fd5 ER |
2292 | /** |
2293 | - * check if two buffer contain the same data | |
2519e6e5 | 2294 | - * |
f26f9fd5 | 2295 | + * check if two buffers contain the same data |
2519e6e5 | 2296 | + * |
f26f9fd5 ER |
2297 | * HISTORY: this function was pretty much optimized, but didn't handled |
2298 | * alignment properly. | |
2519e6e5 ER |
2299 | */ |
2300 | @@ -522,100 +591,100 @@ | |
2301 | ||
2302 | int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) { | |
2303 | buffer b; | |
2304 | - | |
2305 | + | |
2306 | b.ptr = (char *)s; | |
2307 | b.used = b_len + 1; | |
2308 | - | |
2309 | + | |
2310 | return buffer_is_equal(a, &b); | |
2311 | } | |
f673a614 | 2312 | |
f26f9fd5 | 2313 | /* simple-assumption: |
2519e6e5 | 2314 | - * |
f26f9fd5 | 2315 | - * most parts are equal and doing a case conversion needs time |
2519e6e5 ER |
2316 | - * |
2317 | + * | |
f26f9fd5 | 2318 | + * most parts are equal and doing a case conversion takes time |
2519e6e5 | 2319 | + * |
f26f9fd5 ER |
2320 | */ |
2321 | int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) { | |
2519e6e5 ER |
2322 | size_t ndx = 0, max_ndx; |
2323 | size_t *al, *bl; | |
2324 | size_t mask = sizeof(*al) - 1; | |
2325 | - | |
2326 | + | |
2327 | al = (size_t *)a; | |
2328 | bl = (size_t *)b; | |
2329 | - | |
2330 | - /* is the alignment correct ? */ | |
2331 | + | |
2332 | + /* is the alignment correct? */ | |
2333 | if ( ((size_t)al & mask) == 0 && | |
2334 | ((size_t)bl & mask) == 0 ) { | |
2335 | - | |
2336 | + | |
2337 | max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask; | |
2338 | - | |
2339 | + | |
2340 | for (; ndx < max_ndx; ndx += sizeof(*al)) { | |
2341 | if (*al != *bl) break; | |
2342 | al++; bl++; | |
2343 | - | |
2344 | + | |
2345 | } | |
2346 | - | |
2347 | + | |
2348 | } | |
2349 | - | |
2350 | + | |
2351 | a = (char *)al; | |
2352 | b = (char *)bl; | |
2353 | - | |
2354 | + | |
2355 | max_ndx = ((a_len < b_len) ? a_len : b_len); | |
2356 | - | |
2357 | + | |
2358 | for (; ndx < max_ndx; ndx++) { | |
2359 | char a1 = *a++, b1 = *b++; | |
2360 | - | |
2361 | + | |
2362 | if (a1 != b1) { | |
2363 | if ((a1 >= 'A' && a1 <= 'Z') && (b1 >= 'a' && b1 <= 'z')) | |
2364 | a1 |= 32; | |
2365 | else if ((a1 >= 'a' && a1 <= 'z') && (b1 >= 'A' && b1 <= 'Z')) | |
2366 | b1 |= 32; | |
2367 | if ((a1 - b1) != 0) return (a1 - b1); | |
2368 | - | |
2369 | + | |
2370 | } | |
2371 | } | |
2372 | - | |
2373 | + | |
2374 | return 0; | |
2375 | } | |
2376 | ||
2377 | ||
2378 | /** | |
2379 | * check if the rightmost bytes of the string are equal. | |
2380 | - * | |
2381 | - * | |
2382 | + * | |
2383 | + * | |
2384 | */ | |
2385 | ||
2386 | int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) { | |
2387 | /* no, len -> equal */ | |
2388 | if (len == 0) return 1; | |
2389 | - | |
2390 | + | |
2391 | /* len > 0, but empty buffers -> not equal */ | |
f26f9fd5 | 2392 | if (b1->used == 0 || b2->used == 0) return 0; |
2519e6e5 ER |
2393 | - |
2394 | + | |
f26f9fd5 ER |
2395 | /* buffers too small -> not equal */ |
2396 | - if (b1->used - 1 < len || b1->used - 1 < len) return 0; | |
2519e6e5 ER |
2397 | - |
2398 | - if (0 == strncmp(b1->ptr + b1->used - 1 - len, | |
f26f9fd5 | 2399 | + if (b1->used - 1 < len || b2->used - 1 < len) return 0; |
2519e6e5 ER |
2400 | + |
2401 | + if (0 == strncmp(b1->ptr + b1->used - 1 - len, | |
f26f9fd5 | 2402 | b2->ptr + b2->used - 1 - len, len)) { |
2519e6e5 ER |
2403 | return 1; |
2404 | } | |
2405 | - | |
2406 | + | |
2407 | return 0; | |
2408 | } | |
2409 | ||
2410 | int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) { | |
2411 | size_t i; | |
2412 | - | |
2413 | + | |
2414 | /* BO protection */ | |
2415 | if (in_len * 2 < in_len) return -1; | |
2416 | - | |
2417 | + | |
2418 | buffer_prepare_copy(b, in_len * 2 + 1); | |
2419 | - | |
2420 | + | |
2421 | for (i = 0; i < in_len; i++) { | |
2422 | b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F]; | |
2423 | b->ptr[b->used++] = hex_chars[in[i] & 0x0F]; | |
2424 | } | |
2425 | b->ptr[b->used++] = '\0'; | |
2426 | - | |
2427 | + | |
2428 | return 0; | |
2429 | } | |
2430 | ||
2431 | @@ -624,7 +693,7 @@ | |
2432 | 0 1 2 3 4 5 6 7 8 9 A B C D E F | |
2433 | */ | |
2434 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ | |
2435 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2436 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2437 | 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, /* 20 - 2F space " # $ % & ' + , / */ | |
2438 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */ | |
2439 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ | |
2440 | @@ -646,7 +715,7 @@ | |
2441 | 0 1 2 3 4 5 6 7 8 9 A B C D E F | |
2442 | */ | |
2443 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ | |
2444 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2445 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2446 | 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, /* 20 - 2F space " # $ % & ' + , / */ | |
2447 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */ | |
2448 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ | |
2449 | @@ -668,7 +737,7 @@ | |
2450 | 0 1 2 3 4 5 6 7 8 9 A B C D E F | |
2451 | */ | |
2452 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ | |
2453 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2454 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2455 | 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */ | |
2456 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */ | |
2457 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ | |
2458 | @@ -690,7 +759,7 @@ | |
2459 | 0 1 2 3 4 5 6 7 8 9 A B C D E F | |
2460 | */ | |
2461 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ | |
2462 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2463 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2464 | 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */ | |
2465 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */ | |
2466 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ | |
2467 | @@ -712,12 +781,12 @@ | |
2468 | 0 1 2 3 4 5 6 7 8 9 A B C D E F | |
2469 | */ | |
2470 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ | |
2471 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2472 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ | |
2473 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ | |
2474 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ | |
2475 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ | |
2476 | - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ | |
2477 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ | |
2478 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ | |
2479 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ | |
2480 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ | |
2481 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ | |
2482 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ | |
2483 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 - 7F */ | |
2484 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */ | |
2485 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */ | |
2486 | @@ -734,13 +803,13 @@ | |
2487 | unsigned char *ds, *d; | |
2488 | size_t d_len, ndx; | |
2489 | const char *map = NULL; | |
2490 | - | |
2491 | + | |
2492 | if (!s || !b) return -1; | |
2493 | - | |
2494 | + | |
2495 | if (b->ptr[b->used - 1] != '\0') { | |
2496 | SEGFAULT(); | |
2497 | } | |
2498 | - | |
2499 | + | |
2500 | if (s_len == 0) return 0; | |
2501 | ||
2502 | switch(encoding) { | |
f26f9fd5 ER |
2503 | @@ -760,12 +829,12 @@ |
2504 | map = encoded_chars_hex; | |
2505 | break; | |
2506 | case ENCODING_UNSET: | |
2507 | - break; | |
2508 | + return buffer_append_string_len(b, s, s_len); | |
2509 | } | |
f673a614 | 2510 | |
f26f9fd5 | 2511 | assert(map != NULL); |
2519e6e5 | 2512 | - |
f26f9fd5 | 2513 | - /* count to-be-encoded-characters */ |
2519e6e5 | 2514 | + |
f26f9fd5 ER |
2515 | + /* count to-be-encoded characters */ |
2516 | for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) { | |
2517 | if (map[*ds]) { | |
2518 | switch(encoding) { | |
2519e6e5 ER |
2519 | @@ -787,9 +856,9 @@ |
2520 | d_len ++; | |
2521 | } | |
2522 | } | |
2523 | - | |
2524 | + | |
2525 | buffer_prepare_append(b, d_len); | |
2526 | - | |
2527 | + | |
2528 | for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) { | |
2529 | if (map[*ds]) { | |
2530 | switch(encoding) { | |
2531 | @@ -820,16 +889,16 @@ | |
2532 | } | |
2533 | } | |
2534 | ||
2535 | - /* terminate buffer and calculate new length */ | |
2536 | + /* terminate buffer and calculate new length */ | |
2537 | b->ptr[b->used + d_len - 1] = '\0'; | |
2538 | - | |
2539 | + | |
2540 | b->used += d_len; | |
2541 | ||
2542 | return 0; | |
f673a614 ER |
2543 | } |
2544 | ||
f673a614 | 2545 | |
f26f9fd5 ER |
2546 | -/* decodes url-special-chars inplace. |
2547 | +/* decodes url-special chars in-place. | |
2548 | * replaces non-printable characters with '_' | |
2549 | */ | |
f673a614 | 2550 | |
2519e6e5 ER |
2551 | @@ -854,10 +923,10 @@ |
2552 | low = hex2int(*(src + 2)); | |
f26f9fd5 ER |
2553 | if (low != 0xFF) { |
2554 | high = (high << 4) | low; | |
2519e6e5 | 2555 | - |
f26f9fd5 | 2556 | - /* map control-characters out */ |
2519e6e5 | 2557 | + |
f26f9fd5 ER |
2558 | + /* map out control characters */ |
2559 | if (high < 32 || high == 127) high = '_'; | |
2519e6e5 ER |
2560 | - |
2561 | + | |
f26f9fd5 | 2562 | *dst = high; |
2519e6e5 ER |
2563 | src += 2; |
2564 | } | |
f26f9fd5 ER |
2565 | @@ -891,7 +960,7 @@ |
2566 | * /abc/./xyz gets /abc/xyz | |
2567 | * /abc//xyz gets /abc/xyz | |
2568 | * | |
2569 | - * NOTE: src and dest can point to the same buffer, in which case, | |
2570 | + * NOTE: src and dest can point to the same buffer, in which case | |
2571 | * the operation is performed in-place. | |
2572 | */ | |
f673a614 | 2573 | |
2519e6e5 ER |
2574 | @@ -979,7 +1048,7 @@ |
2575 | ||
2576 | int light_isxdigit(int c) { | |
2577 | if (light_isdigit(c)) return 1; | |
2578 | - | |
2579 | + | |
2580 | c |= 32; | |
2581 | return (c >= 'a' && c <= 'f'); | |
2582 | } | |
2583 | @@ -993,31 +1062,56 @@ | |
f26f9fd5 | 2584 | return light_isdigit(c) || light_isalpha(c); |
f673a614 ER |
2585 | } |
2586 | ||
f26f9fd5 ER |
2587 | +#undef BUFFER_CTYPE_FUNC |
2588 | +#define BUFFER_CTYPE_FUNC(type) \ | |
2589 | + int buffer_is##type(buffer *b) { \ | |
2590 | + size_t i, len; \ | |
2591 | + if (b->used < 2) return 0; \ | |
2592 | + /* strlen */ \ | |
2593 | + len = b->used - 1; \ | |
2594 | + /* c-string only */ \ | |
2595 | + if (b->ptr[len] != '\0') { \ | |
2596 | + return 0; \ | |
2597 | + } \ | |
2598 | + /* check on the whole string */ \ | |
2599 | + for (i = 0; i < len; i ++) { \ | |
2600 | + if (!light_is##type(b->ptr[i])) { \ | |
2601 | + return 0; \ | |
2602 | + } \ | |
2603 | + } \ | |
2604 | + return 1; \ | |
2605 | + } | |
f673a614 | 2606 | + |
f26f9fd5 ER |
2607 | +BUFFER_CTYPE_FUNC(digit) |
2608 | +BUFFER_CTYPE_FUNC(xdigit) | |
2609 | +BUFFER_CTYPE_FUNC(alpha) | |
2610 | +BUFFER_CTYPE_FUNC(alnum) | |
f673a614 | 2611 | + |
f26f9fd5 ER |
2612 | int buffer_to_lower(buffer *b) { |
2613 | char *c; | |
2519e6e5 ER |
2614 | - |
2615 | + | |
2616 | if (b->used == 0) return 0; | |
2617 | - | |
2618 | + | |
2619 | for (c = b->ptr; *c; c++) { | |
2620 | if (*c >= 'A' && *c <= 'Z') { | |
2621 | *c |= 32; | |
2622 | } | |
2623 | } | |
2624 | - | |
2625 | + | |
2626 | return 0; | |
2627 | } | |
2628 | ||
2629 | ||
2630 | int buffer_to_upper(buffer *b) { | |
2631 | char *c; | |
2632 | - | |
2633 | + | |
2634 | if (b->used == 0) return 0; | |
2635 | - | |
2636 | + | |
2637 | for (c = b->ptr; *c; c++) { | |
2638 | if (*c >= 'a' && *c <= 'z') { | |
2639 | *c &= ~32; | |
2640 | } | |
2641 | } | |
2642 | - | |
2643 | + | |
2644 | return 0; | |
2645 | } | |
1175ccec | 2646 | --- ../lighttpd-1.4.11/src/buffer.h 2006-01-13 00:00:45.000000000 +0200 |
36e2a29e | 2647 | +++ lighttpd-1.4.12/src/buffer.h 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
2648 | @@ -12,27 +12,44 @@ |
2649 | ||
2650 | typedef struct { | |
2651 | char *ptr; | |
2652 | - | |
2653 | + | |
2654 | size_t used; | |
f26f9fd5 ER |
2655 | size_t size; |
2656 | } buffer; | |
f673a614 ER |
2657 | |
2658 | + | |
f26f9fd5 | 2659 | +typedef void (*buffer_ptr_free_t)(void *p); |
f673a614 | 2660 | + |
f26f9fd5 ER |
2661 | +typedef struct { |
2662 | + void **ptr; | |
2663 | + size_t size; | |
2664 | + size_t used; | |
2665 | + buffer_ptr_free_t free; | |
2666 | +} buffer_ptr; | |
f673a614 | 2667 | + |
f26f9fd5 ER |
2668 | typedef struct { |
2669 | buffer **ptr; | |
2519e6e5 ER |
2670 | - |
2671 | + | |
2672 | size_t used; | |
2673 | size_t size; | |
2674 | } buffer_array; | |
2675 | ||
2676 | typedef struct { | |
2677 | char *ptr; | |
2678 | - | |
f26f9fd5 | 2679 | - size_t offset; /* input-pointer */ |
2519e6e5 | 2680 | - |
f26f9fd5 | 2681 | - size_t used; /* output-pointer */ |
2519e6e5 ER |
2682 | + |
2683 | + size_t offset; /* input pointer */ | |
2684 | + | |
f26f9fd5 ER |
2685 | + size_t used; /* output pointer */ |
2686 | size_t size; | |
2687 | } read_buffer; | |
f673a614 | 2688 | |
f26f9fd5 ER |
2689 | +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer); |
2690 | +void buffer_ptr_free(buffer_ptr *b); | |
2691 | +void buffer_ptr_clear(buffer_ptr *b); | |
2692 | +void buffer_ptr_append(buffer_ptr *b, void *item); | |
2693 | +void *buffer_ptr_pop(buffer_ptr *b); | |
2694 | +void *buffer_ptr_top(buffer_ptr *b); | |
f673a614 | 2695 | + |
f26f9fd5 ER |
2696 | buffer_array* buffer_array_init(void); |
2697 | void buffer_array_free(buffer_array *b); | |
2698 | void buffer_array_reset(buffer_array *b); | |
2519e6e5 ER |
2699 | @@ -43,7 +60,7 @@ |
2700 | buffer* buffer_init_string(const char *str); | |
2701 | void buffer_free(buffer *b); | |
2702 | void buffer_reset(buffer *b); | |
2703 | - | |
2704 | + | |
2705 | int buffer_prepare_copy(buffer *b, size_t size); | |
2706 | int buffer_prepare_append(buffer *b, size_t size); | |
2707 | ||
f26f9fd5 | 2708 | @@ -85,9 +102,9 @@ |
f673a614 | 2709 | |
f26f9fd5 ER |
2710 | typedef enum { |
2711 | ENCODING_UNSET, | |
2712 | - ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */ | |
2713 | - ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */ | |
2714 | - ENCODING_HTML, /* & becomes & and so on */ | |
2715 | + ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of an href */ | |
2716 | + ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus encoding "/" as "%2F" */ | |
2717 | + ENCODING_HTML, /* "&" becomes "&" and so on */ | |
2718 | ENCODING_MINIMAL_XML, /* minimal encoding for xml */ | |
2719 | ENCODING_HEX /* encode string as hex */ | |
2720 | } buffer_encoding_t; | |
2721 | @@ -111,19 +128,21 @@ | |
2722 | int light_isalpha(int c); | |
2723 | int light_isalnum(int c); | |
2724 | ||
2725 | +#define BUFFER_CTYPE_FUNC(type) int buffer_is##type(buffer *b); | |
2726 | +BUFFER_CTYPE_FUNC(digit) | |
2727 | +BUFFER_CTYPE_FUNC(xdigit) | |
2728 | +BUFFER_CTYPE_FUNC(alpha) | |
2729 | +BUFFER_CTYPE_FUNC(alnum) | |
f673a614 | 2730 | + |
f26f9fd5 ER |
2731 | #define BUFFER_APPEND_STRING_CONST(x, y) \ |
2732 | buffer_append_string_len(x, y, sizeof(y) - 1) | |
2733 | ||
2734 | #define BUFFER_COPY_STRING_CONST(x, y) \ | |
2735 | buffer_copy_string_len(x, y, sizeof(y) - 1) | |
2736 | ||
2737 | -#define BUFFER_APPEND_SLASH(x) \ | |
2738 | - if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); } | |
2739 | - | |
2740 | #define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0 | |
2741 | #define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0 | |
2742 | ||
2743 | - | |
2744 | #define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0) | |
2745 | #define UNUSED(x) ( (void)(x) ) | |
2746 | ||
1175ccec | 2747 | --- ../lighttpd-1.4.11/src/chunk.c 2005-11-18 15:18:19.000000000 +0200 |
36e2a29e | 2748 | +++ lighttpd-1.4.12/src/chunk.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
2749 | @@ -1,16 +1,14 @@ |
2750 | /** | |
2751 | * the network chunk-API | |
2752 | - * | |
2753 | - * | |
2754 | + * | |
2755 | + * | |
2756 | */ | |
f26f9fd5 ER |
2757 | |
2758 | #include <sys/types.h> | |
2759 | #include <sys/stat.h> | |
2760 | -#include <sys/mman.h> | |
2761 | ||
2762 | #include <stdlib.h> | |
2763 | #include <fcntl.h> | |
2764 | -#include <unistd.h> | |
2765 | ||
2766 | #include <stdio.h> | |
2767 | #include <errno.h> | |
2519e6e5 | 2768 | @@ -18,36 +16,39 @@ |
f26f9fd5 ER |
2769 | |
2770 | #include "chunk.h" | |
2771 | ||
2772 | +#include "sys-mmap.h" | |
2773 | +#include "sys-files.h" | |
f673a614 | 2774 | + |
f26f9fd5 ER |
2775 | chunkqueue *chunkqueue_init(void) { |
2776 | chunkqueue *cq; | |
2519e6e5 ER |
2777 | - |
2778 | + | |
2779 | cq = calloc(1, sizeof(*cq)); | |
2780 | - | |
2781 | + | |
2782 | cq->first = NULL; | |
2783 | cq->last = NULL; | |
2784 | - | |
2785 | + | |
2786 | cq->unused = NULL; | |
2787 | - | |
2788 | + | |
2789 | return cq; | |
2790 | } | |
2791 | ||
2792 | static chunk *chunk_init(void) { | |
2793 | chunk *c; | |
2794 | - | |
2795 | + | |
2796 | c = calloc(1, sizeof(*c)); | |
2797 | - | |
2798 | + | |
2799 | c->mem = buffer_init(); | |
2800 | c->file.name = buffer_init(); | |
2801 | c->file.fd = -1; | |
2802 | c->file.mmap.start = MAP_FAILED; | |
2803 | c->next = NULL; | |
2804 | - | |
2805 | + | |
2806 | return c; | |
2807 | } | |
2808 | ||
2809 | static void chunk_free(chunk *c) { | |
2810 | if (!c) return; | |
2811 | - | |
2812 | + | |
2813 | buffer_free(c->mem); | |
2814 | buffer_free(c->file.name); | |
2815 | ||
2816 | @@ -56,13 +57,13 @@ | |
2817 | ||
2818 | static void chunk_reset(chunk *c) { | |
2819 | if (!c) return; | |
2820 | - | |
2821 | + | |
2822 | buffer_reset(c->mem); | |
2823 | ||
2824 | if (c->file.is_temp && !buffer_is_empty(c->file.name)) { | |
2825 | unlink(c->file.name->ptr); | |
2826 | } | |
2827 | - | |
2828 | + | |
2829 | buffer_reset(c->file.name); | |
2830 | ||
2831 | if (c->file.fd != -1) { | |
2832 | @@ -78,28 +79,28 @@ | |
2833 | ||
2834 | void chunkqueue_free(chunkqueue *cq) { | |
2835 | chunk *c, *pc; | |
2836 | - | |
2837 | + | |
2838 | if (!cq) return; | |
2839 | - | |
2840 | + | |
2841 | for (c = cq->first; c; ) { | |
2842 | pc = c; | |
2843 | c = c->next; | |
2844 | chunk_free(pc); | |
2845 | } | |
2846 | - | |
2847 | + | |
2848 | for (c = cq->unused; c; ) { | |
2849 | pc = c; | |
2850 | c = c->next; | |
2851 | chunk_free(pc); | |
2852 | } | |
2853 | - | |
2854 | + | |
2855 | free(cq); | |
2856 | } | |
2857 | ||
f26f9fd5 ER |
2858 | static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) { |
2859 | chunk *c; | |
2519e6e5 | 2860 | - |
f26f9fd5 | 2861 | - /* check if we have a unused chunk */ |
2519e6e5 | 2862 | + |
f26f9fd5 ER |
2863 | + /* check if we have an unused chunk */ |
2864 | if (!cq->unused) { | |
2865 | c = chunk_init(); | |
2866 | } else { | |
2519e6e5 ER |
2867 | @@ -109,18 +110,18 @@ |
2868 | c->next = NULL; | |
2869 | cq->unused_chunks--; | |
2870 | } | |
2871 | - | |
2872 | + | |
2873 | return c; | |
2874 | } | |
2875 | ||
2876 | static int chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) { | |
2877 | c->next = cq->first; | |
2878 | cq->first = c; | |
2879 | - | |
2880 | + | |
2881 | if (cq->last == NULL) { | |
2882 | cq->last = c; | |
2883 | } | |
2884 | - | |
2885 | + | |
2886 | return 0; | |
2887 | } | |
2888 | ||
2889 | @@ -129,19 +130,19 @@ | |
2890 | cq->last->next = c; | |
2891 | } | |
2892 | cq->last = c; | |
2893 | - | |
2894 | + | |
2895 | if (cq->first == NULL) { | |
2896 | cq->first = c; | |
2897 | } | |
2898 | - | |
2899 | + | |
2900 | return 0; | |
2901 | } | |
2902 | ||
2903 | void chunkqueue_reset(chunkqueue *cq) { | |
2904 | chunk *c; | |
2905 | /* move everything to the unused queue */ | |
2906 | - | |
2907 | - /* mark all read written */ | |
2908 | + | |
2909 | + /* mark all read written */ | |
2910 | for (c = cq->first; c; c = c->next) { | |
2911 | switch(c->type) { | |
2912 | case MEM_CHUNK: | |
2913 | @@ -150,7 +151,7 @@ | |
2914 | case FILE_CHUNK: | |
2915 | c->offset = c->file.length; | |
2916 | break; | |
2917 | - default: | |
2918 | + default: | |
2919 | break; | |
2920 | } | |
2921 | } | |
2922 | @@ -162,93 +163,93 @@ | |
2923 | ||
2924 | int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) { | |
2925 | chunk *c; | |
2926 | - | |
2927 | + | |
2928 | if (len == 0) return 0; | |
2929 | - | |
2930 | + | |
2931 | c = chunkqueue_get_unused_chunk(cq); | |
2932 | - | |
2933 | + | |
2934 | c->type = FILE_CHUNK; | |
2935 | - | |
2936 | + | |
2937 | buffer_copy_string_buffer(c->file.name, fn); | |
2938 | c->file.start = offset; | |
2939 | c->file.length = len; | |
2940 | c->offset = 0; | |
2941 | - | |
2942 | + | |
2943 | chunkqueue_append_chunk(cq, c); | |
2944 | - | |
2945 | + | |
2946 | return 0; | |
2947 | } | |
2948 | ||
2949 | int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) { | |
2950 | chunk *c; | |
2951 | - | |
2952 | + | |
2953 | if (mem->used == 0) return 0; | |
2954 | - | |
2955 | + | |
2956 | c = chunkqueue_get_unused_chunk(cq); | |
2957 | c->type = MEM_CHUNK; | |
2958 | c->offset = 0; | |
2959 | buffer_copy_string_buffer(c->mem, mem); | |
2960 | - | |
2961 | + | |
2962 | chunkqueue_append_chunk(cq, c); | |
2963 | - | |
2964 | + | |
2965 | return 0; | |
2966 | } | |
2967 | ||
2968 | int chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) { | |
2969 | chunk *c; | |
2970 | - | |
2971 | + | |
2972 | if (mem->used == 0) return 0; | |
2973 | - | |
2974 | + | |
2975 | c = chunkqueue_get_unused_chunk(cq); | |
2976 | c->type = MEM_CHUNK; | |
2977 | c->offset = 0; | |
2978 | buffer_copy_string_buffer(c->mem, mem); | |
2979 | - | |
2980 | + | |
2981 | chunkqueue_prepend_chunk(cq, c); | |
2982 | - | |
2983 | + | |
2984 | return 0; | |
2985 | } | |
2986 | ||
2987 | int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) { | |
2988 | chunk *c; | |
2989 | - | |
2990 | + | |
2991 | if (len == 0) return 0; | |
2992 | - | |
2993 | + | |
2994 | c = chunkqueue_get_unused_chunk(cq); | |
2995 | c->type = MEM_CHUNK; | |
2996 | c->offset = 0; | |
2997 | buffer_copy_string_len(c->mem, mem, len - 1); | |
2998 | - | |
2999 | + | |
3000 | chunkqueue_append_chunk(cq, c); | |
3001 | - | |
3002 | + | |
3003 | return 0; | |
3004 | } | |
3005 | ||
3006 | buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) { | |
3007 | chunk *c; | |
3008 | - | |
3009 | + | |
3010 | c = chunkqueue_get_unused_chunk(cq); | |
3011 | - | |
3012 | + | |
3013 | c->type = MEM_CHUNK; | |
3014 | c->offset = 0; | |
3015 | buffer_reset(c->mem); | |
3016 | - | |
3017 | + | |
3018 | chunkqueue_prepend_chunk(cq, c); | |
3019 | - | |
3020 | + | |
3021 | return c->mem; | |
3022 | } | |
3023 | ||
3024 | buffer *chunkqueue_get_append_buffer(chunkqueue *cq) { | |
3025 | chunk *c; | |
3026 | - | |
3027 | + | |
3028 | c = chunkqueue_get_unused_chunk(cq); | |
3029 | - | |
3030 | + | |
3031 | c->type = MEM_CHUNK; | |
3032 | c->offset = 0; | |
3033 | buffer_reset(c->mem); | |
3034 | - | |
3035 | + | |
3036 | chunkqueue_append_chunk(cq, c); | |
3037 | - | |
3038 | + | |
3039 | return c->mem; | |
3040 | } | |
3041 | ||
3042 | @@ -263,7 +264,7 @@ | |
3043 | chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) { | |
3044 | chunk *c; | |
3045 | buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX"); | |
3046 | - | |
3047 | + | |
3048 | c = chunkqueue_get_unused_chunk(cq); | |
3049 | ||
3050 | c->type = FILE_CHUNK; | |
3051 | @@ -273,12 +274,12 @@ | |
3052 | size_t i; | |
3053 | ||
3054 | /* we have several tempdirs, only if all of them fail we jump out */ | |
3055 | - | |
3056 | + | |
3057 | for (i = 0; i < cq->tempdirs->used; i++) { | |
f26f9fd5 ER |
3058 | data_string *ds = (data_string *)cq->tempdirs->data[i]; |
3059 | ||
3060 | buffer_copy_string_buffer(template, ds->value); | |
3061 | - BUFFER_APPEND_SLASH(template); | |
3062 | + PATHNAME_APPEND_SLASH(template); | |
3063 | BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX"); | |
3064 | ||
3065 | if (-1 != (c->file.fd = mkstemp(template->ptr))) { | |
2519e6e5 ER |
3066 | @@ -300,7 +301,7 @@ |
3067 | chunkqueue_append_chunk(cq, c); | |
3068 | ||
3069 | buffer_free(template); | |
3070 | - | |
3071 | + | |
3072 | return c; | |
3073 | } | |
3074 | ||
3075 | @@ -308,7 +309,7 @@ | |
3076 | off_t chunkqueue_length(chunkqueue *cq) { | |
3077 | off_t len = 0; | |
3078 | chunk *c; | |
3079 | - | |
3080 | + | |
3081 | for (c = cq->first; c; c = c->next) { | |
3082 | switch (c->type) { | |
3083 | case MEM_CHUNK: | |
3084 | @@ -321,14 +322,14 @@ | |
3085 | break; | |
3086 | } | |
3087 | } | |
3088 | - | |
3089 | + | |
3090 | return len; | |
3091 | } | |
3092 | ||
3093 | off_t chunkqueue_written(chunkqueue *cq) { | |
3094 | off_t len = 0; | |
3095 | chunk *c; | |
3096 | - | |
3097 | + | |
3098 | for (c = cq->first; c; c = c->next) { | |
3099 | switch (c->type) { | |
3100 | case MEM_CHUNK: | |
3101 | @@ -339,7 +340,7 @@ | |
3102 | break; | |
3103 | } | |
3104 | } | |
3105 | - | |
3106 | + | |
3107 | return len; | |
3108 | } | |
3109 | ||
3110 | @@ -358,9 +359,9 @@ | |
3111 | if (c->offset == (off_t)c->mem->used - 1) is_finished = 1; | |
3112 | break; | |
3113 | case FILE_CHUNK: | |
3114 | - if (c->offset == c->file.length) is_finished = 1; | |
3115 | + if (c->offset == c->file.length) is_finished = 1; | |
3116 | break; | |
3117 | - default: | |
3118 | + default: | |
3119 | break; | |
3120 | } | |
3121 | ||
1175ccec | 3122 | --- ../lighttpd-1.4.11/src/chunk.h 2005-11-01 09:32:21.000000000 +0200 |
36e2a29e | 3123 | +++ lighttpd-1.4.12/src/chunk.h 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
3124 | @@ -6,7 +6,7 @@ |
3125 | ||
3126 | typedef struct chunk { | |
3127 | enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type; | |
3128 | - | |
3129 | + | |
3130 | buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */ | |
3131 | ||
3132 | struct { | |
3133 | @@ -16,28 +16,28 @@ | |
3134 | off_t length; /* octets to send from the starting offset */ | |
3135 | ||
3136 | int fd; | |
3137 | - struct { | |
3138 | + struct { | |
f26f9fd5 ER |
3139 | char *start; /* the start pointer of the mmap'ed area */ |
3140 | size_t length; /* size of the mmap'ed area */ | |
3141 | - off_t offset; /* start is <n> octet away from the start of the file */ | |
3142 | + off_t offset; /* start is <n> octets away from the start of the file */ | |
3143 | } mmap; | |
3144 | ||
3145 | - int is_temp; /* file is temporary and will be deleted if on cleanup */ | |
3146 | + int is_temp; /* file is temporary and will be deleted on cleanup */ | |
3147 | } file; | |
2519e6e5 ER |
3148 | - |
3149 | - off_t offset; /* octets sent from this chunk | |
3150 | - the size of the chunk is either | |
3151 | + | |
3152 | + off_t offset; /* octets sent from this chunk | |
3153 | + the size of the chunk is either | |
3154 | - mem-chunk: mem->used - 1 | |
3155 | - file-chunk: file.length | |
3156 | */ | |
3157 | - | |
3158 | + | |
3159 | struct chunk *next; | |
3160 | } chunk; | |
3161 | ||
3162 | typedef struct { | |
3163 | chunk *first; | |
3164 | chunk *last; | |
3165 | - | |
3166 | + | |
3167 | chunk *unused; | |
3168 | size_t unused_chunks; | |
3169 | ||
1175ccec | 3170 | --- ../lighttpd-1.4.11/src/configfile-glue.c 2006-03-03 20:14:56.000000000 +0200 |
36e2a29e | 3171 | +++ lighttpd-1.4.12/src/configfile-glue.c 2006-07-11 22:07:51.000000000 +0300 |
f26f9fd5 ER |
3172 | @@ -1,4 +1,5 @@ |
3173 | #include <string.h> | |
3174 | +#include <ctype.h> | |
3175 | ||
3176 | #include "base.h" | |
3177 | #include "buffer.h" | |
2519e6e5 ER |
3178 | @@ -11,10 +12,10 @@ |
3179 | * are the external interface of lighttpd. The functions | |
3180 | * are used by the server itself and the plugins. | |
3181 | * | |
3182 | - * The main-goal is to have a small library in the end | |
3183 | - * which is linked against both and which will define | |
3184 | + * The main-goal is to have a small library in the end | |
3185 | + * which is linked against both and which will define | |
3186 | * the interface itself in the end. | |
3187 | - * | |
3188 | + * | |
3189 | */ | |
3190 | ||
3191 | ||
3192 | @@ -24,56 +25,60 @@ | |
3193 | int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) { | |
3194 | size_t i; | |
3195 | data_unset *du; | |
3196 | - | |
f673a614 | 3197 | + |
2519e6e5 ER |
3198 | for (i = 0; cv[i].key; i++) { |
3199 | - | |
f673a614 | 3200 | + |
2519e6e5 ER |
3201 | if (NULL == (du = array_get_element(ca, cv[i].key))) { |
3202 | /* no found */ | |
3203 | - | |
3204 | + | |
3205 | continue; | |
3206 | } | |
3207 | - | |
3208 | + | |
3209 | switch (cv[i].type) { | |
3210 | case T_CONFIG_ARRAY: | |
3211 | if (du->type == TYPE_ARRAY) { | |
3212 | size_t j; | |
3213 | data_array *da = (data_array *)du; | |
3214 | - | |
3215 | + | |
3216 | for (j = 0; j < da->value->used; j++) { | |
3217 | if (da->value->data[j]->type == TYPE_STRING) { | |
3218 | data_string *ds = data_string_init(); | |
3219 | - | |
3220 | + | |
3221 | buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value); | |
3222 | if (!da->is_index_key) { | |
3223 | /* the id's were generated automaticly, as we copy now we might have to renumber them | |
3224 | - * this is used to prepend server.modules by mod_indexfiles as it has to be loaded | |
3225 | + * this is used to prepend server.modules by mod_indexfiles as it has to be loaded | |
3226 | * before mod_fastcgi and friends */ | |
3227 | buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key); | |
3228 | } | |
3229 | - | |
3230 | + | |
3231 | array_insert_unique(cv[i].destination, (data_unset *)ds); | |
3232 | } else { | |
3233 | - log_error_write(srv, __FILE__, __LINE__, "sssd", | |
3234 | - "the key of and array can only be a string or a integer, variable:", | |
3235 | - cv[i].key, "type:", da->value->data[j]->type); | |
3236 | - | |
3237 | + log_error_write(srv, __FILE__, __LINE__, "sssd", | |
3238 | + "the key of and array can only be a string or a integer, variable:", | |
3239 | + cv[i].key, "type:", da->value->data[j]->type); | |
3240 | + | |
3241 | return -1; | |
3242 | } | |
3243 | } | |
3244 | } else { | |
3245 | log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", cv[i].key, "array of strings"); | |
3246 | - | |
3247 | + | |
3248 | return -1; | |
3249 | } | |
3250 | break; | |
3251 | case T_CONFIG_STRING: | |
3252 | if (du->type == TYPE_STRING) { | |
3253 | data_string *ds = (data_string *)du; | |
3254 | - | |
3255 | + | |
3256 | buffer_copy_string_buffer(cv[i].destination, ds->value); | |
3257 | + } else if (du->type == TYPE_INTEGER) { | |
3258 | + data_integer *di = (data_integer *)du; | |
3259 | + | |
3260 | + buffer_copy_long(cv[i].destination, di->value); | |
3261 | } else { | |
3262 | log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\""); | |
3263 | - | |
3264 | + | |
3265 | return -1; | |
3266 | } | |
3267 | break; | |
3268 | @@ -81,15 +86,20 @@ | |
3269 | switch(du->type) { | |
3270 | case TYPE_INTEGER: { | |
3271 | data_integer *di = (data_integer *)du; | |
3272 | - | |
3273 | + | |
3274 | *((unsigned short *)(cv[i].destination)) = di->value; | |
3275 | break; | |
3276 | } | |
3277 | case TYPE_STRING: { | |
3278 | data_string *ds = (data_string *)du; | |
3279 | - | |
3280 | + | |
3281 | + if (buffer_isdigit(ds->value)) { | |
3282 | + *((unsigned short *)(cv[i].destination)) = strtol(ds->value->ptr, NULL, 10); | |
3283 | + break; | |
3284 | + } | |
3285 | + | |
3286 | log_error_write(srv, __FILE__, __LINE__, "ssb", "get a string but expected a short:", cv[i].key, ds->value); | |
3287 | - | |
3288 | + | |
3289 | return -1; | |
3290 | } | |
3291 | default: | |
3292 | @@ -100,19 +110,19 @@ | |
3293 | case T_CONFIG_BOOLEAN: | |
3294 | if (du->type == TYPE_STRING) { | |
3295 | data_string *ds = (data_string *)du; | |
3296 | - | |
3297 | + | |
3298 | if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable"))) { | |
3299 | *((unsigned short *)(cv[i].destination)) = 1; | |
3300 | } else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable"))) { | |
3301 | *((unsigned short *)(cv[i].destination)) = 0; | |
3302 | } else { | |
3303 | log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)"); | |
3304 | - | |
3305 | + | |
3306 | return -1; | |
3307 | } | |
3308 | } else { | |
3309 | log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\""); | |
3310 | - | |
3311 | + | |
3312 | return -1; | |
3313 | } | |
3314 | break; | |
3315 | @@ -121,9 +131,9 @@ | |
3316 | break; | |
3317 | case T_CONFIG_DEPRECATED: | |
3318 | log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination)); | |
3319 | - | |
3320 | + | |
3321 | srv->config_deprecated = 1; | |
3322 | - | |
3323 | + | |
3324 | break; | |
3325 | } | |
3326 | } | |
3327 | @@ -133,25 +143,25 @@ | |
3328 | int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) { | |
3329 | size_t i; | |
3330 | data_unset *du; | |
3331 | - | |
3332 | + | |
3333 | for (i = 0; cv[i].key; i++) { | |
3334 | data_string *touched; | |
3335 | - | |
3336 | + | |
3337 | if (NULL == (du = array_get_element(ca, cv[i].key))) { | |
3338 | /* no found */ | |
3339 | - | |
3340 | + | |
3341 | continue; | |
3342 | } | |
3343 | - | |
3344 | + | |
3345 | /* touched */ | |
3346 | touched = data_string_init(); | |
3347 | - | |
3348 | + | |
3349 | buffer_copy_string(touched->value, ""); | |
3350 | buffer_copy_string_buffer(touched->key, du->key); | |
3351 | - | |
3352 | + | |
3353 | array_insert_unique(srv->config_touched, (data_unset *)touched); | |
3354 | } | |
3355 | - | |
3356 | + | |
3357 | return config_insert_values_internal(srv, ca, cv); | |
3358 | } | |
3359 | ||
3360 | @@ -191,25 +201,25 @@ | |
3361 | } | |
3362 | ||
3363 | /* pass the rules */ | |
3364 | - | |
3365 | + | |
3366 | switch (dc->comp) { | |
3367 | case COMP_HTTP_HOST: { | |
3368 | char *ck_colon = NULL, *val_colon = NULL; | |
3369 | - | |
3370 | + | |
3371 | if (!buffer_is_empty(con->uri.authority)) { | |
3372 | - | |
3373 | - /* | |
3374 | + | |
3375 | + /* | |
3376 | * append server-port to the HTTP_POST if necessary | |
3377 | */ | |
3378 | - | |
3379 | + | |
3380 | l = con->uri.authority; | |
3381 | - | |
3382 | + | |
3383 | switch(dc->cond) { | |
3384 | case CONFIG_COND_NE: | |
3385 | case CONFIG_COND_EQ: | |
3386 | ck_colon = strchr(dc->string->ptr, ':'); | |
3387 | val_colon = strchr(l->ptr, ':'); | |
3388 | - | |
3389 | + | |
3390 | if (ck_colon == val_colon) { | |
3391 | /* nothing to do with it */ | |
3392 | break; | |
3393 | @@ -230,21 +240,21 @@ | |
3394 | break; | |
3395 | } | |
3396 | } else { | |
3397 | - l = NULL; | |
f26f9fd5 | 3398 | + l = srv->empty_string; |
f673a614 | 3399 | } |
f26f9fd5 | 3400 | break; |
f673a614 | 3401 | } |
2519e6e5 ER |
3402 | case COMP_HTTP_REMOTEIP: { |
3403 | char *nm_slash; | |
3404 | - /* handle remoteip limitations | |
3405 | - * | |
3406 | + /* handle remoteip limitations | |
3407 | + * | |
3408 | * "10.0.0.1" is provided for all comparisions | |
3409 | - * | |
3410 | + * | |
3411 | * only for == and != we support | |
3412 | - * | |
3413 | + * | |
3414 | * "10.0.0.1/24" | |
3415 | */ | |
3416 | - | |
3417 | + | |
3418 | if ((dc->cond == CONFIG_COND_EQ || | |
3419 | dc->cond == CONFIG_COND_NE) && | |
3420 | (con->dst_addr.plain.sa_family == AF_INET) && | |
3421 | @@ -253,41 +263,48 @@ | |
3422 | long nm; | |
f26f9fd5 ER |
3423 | char *err; |
3424 | struct in_addr val_inp; | |
2519e6e5 ER |
3425 | - |
3426 | + | |
f26f9fd5 ER |
3427 | + if (con->conf.log_condition_handling) { |
3428 | + l = srv->empty_string; | |
f673a614 | 3429 | + |
f26f9fd5 ER |
3430 | + log_error_write(srv, __FILE__, __LINE__, "bsbsb", dc->comp_key, |
3431 | + "(", l, ") compare to", dc->string); | |
3432 | + } | |
f673a614 | 3433 | + |
f26f9fd5 ER |
3434 | if (*(nm_slash+1) == '\0') { |
3435 | log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string); | |
2519e6e5 ER |
3436 | - |
3437 | + | |
3438 | return COND_RESULT_FALSE; | |
3439 | } | |
3440 | - | |
3441 | + | |
3442 | nm_bits = strtol(nm_slash + 1, &err, 10); | |
3443 | - | |
3444 | + | |
3445 | if (*err) { | |
3446 | log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, *err); | |
3447 | - | |
3448 | + | |
3449 | return COND_RESULT_FALSE; | |
3450 | } | |
3451 | - | |
3452 | + | |
f26f9fd5 ER |
3453 | /* take IP convert to the native */ |
3454 | buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr); | |
3455 | -#ifdef __WIN32 | |
3456 | +#ifdef _WIN32 | |
3457 | if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) { | |
3458 | log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); | |
2519e6e5 ER |
3459 | - |
3460 | + | |
3461 | return COND_RESULT_FALSE; | |
3462 | } | |
3463 | ||
3464 | #else | |
3465 | if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) { | |
3466 | log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); | |
3467 | - | |
3468 | + | |
3469 | return COND_RESULT_FALSE; | |
3470 | } | |
3471 | #endif | |
3472 | - | |
3473 | + | |
3474 | /* build netmask */ | |
3475 | nm = htonl(~((1 << (32 - nm_bits)) - 1)); | |
3476 | - | |
3477 | + | |
3478 | if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) { | |
3479 | return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE; | |
3480 | } else { | |
3481 | @@ -308,7 +325,7 @@ | |
3482 | ||
3483 | case COMP_HTTP_REFERER: { | |
3484 | data_string *ds; | |
3485 | - | |
3486 | + | |
3487 | if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) { | |
3488 | l = ds->value; | |
3489 | } else { | |
3490 | @@ -338,7 +355,7 @@ | |
3491 | default: | |
3492 | return COND_RESULT_FALSE; | |
3493 | } | |
3494 | - | |
3495 | + | |
3496 | if (NULL == l) { | |
3497 | if (con->conf.log_condition_handling) { | |
3498 | log_error_write(srv, __FILE__, __LINE__, "bsbs", dc->comp_key, | |
3499 | @@ -346,10 +363,10 @@ | |
3500 | } | |
3501 | return COND_RESULT_FALSE; | |
3502 | } | |
3503 | - | |
3504 | + | |
3505 | if (con->conf.log_condition_handling) { | |
3506 | log_error_write(srv, __FILE__, __LINE__, "bsbsb", dc->comp_key, | |
3507 | - "(", l, ") compare to ", dc->string); | |
3508 | + "(", l, ") compare to", dc->string); | |
3509 | } | |
3510 | switch(dc->cond) { | |
3511 | case CONFIG_COND_NE: | |
3512 | @@ -365,13 +382,13 @@ | |
3513 | case CONFIG_COND_MATCH: { | |
3514 | cond_cache_t *cache = &con->cond_cache[dc->context_ndx]; | |
3515 | int n; | |
3516 | - | |
3517 | + | |
3518 | #ifndef elementsof | |
3519 | #define elementsof(x) (sizeof(x) / sizeof(x[0])) | |
3520 | #endif | |
3521 | n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0, | |
3522 | cache->matches, elementsof(cache->matches)); | |
3523 | - | |
3524 | + | |
3525 | cache->patterncount = n; | |
3526 | if (n > 0) { | |
3527 | cache->comp_value = l; | |
3528 | @@ -387,7 +404,7 @@ | |
3529 | /* no way */ | |
3530 | break; | |
3531 | } | |
3532 | - | |
3533 | + | |
3534 | return COND_RESULT_FALSE; | |
3535 | } | |
3536 | ||
f26f9fd5 ER |
3537 | @@ -395,6 +412,9 @@ |
3538 | cond_cache_t *caches = con->cond_cache; | |
f673a614 | 3539 | |
f26f9fd5 ER |
3540 | if (COND_RESULT_UNSET == caches[dc->context_ndx].result) { |
3541 | + if (con->conf.log_condition_handling) { | |
3542 | + log_error_write(srv, __FILE__, __LINE__, "sds", "=== start of", dc->context_ndx, "condition block ==="); | |
3543 | + } | |
3544 | if (COND_RESULT_TRUE == (caches[dc->context_ndx].result = config_check_cond_nocache(srv, con, dc))) { | |
3545 | if (dc->next) { | |
3546 | data_config *c; | |
3547 | @@ -409,11 +429,11 @@ | |
3548 | } | |
3549 | if (con->conf.log_condition_handling) { | |
3550 | log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx, | |
3551 | - "(uncached) result:", | |
3552 | + "result:", | |
3553 | caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false"); | |
3554 | } | |
3555 | } else { | |
3556 | - if (con->conf.log_condition_handling) { | |
3557 | + if (con->conf.log_condition_cache_handling) { | |
3558 | log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx, | |
3559 | "(cached) result:", | |
3560 | caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false"); | |
3561 | @@ -423,9 +443,6 @@ | |
f673a614 ER |
3562 | } |
3563 | ||
f26f9fd5 ER |
3564 | int config_check_cond(server *srv, connection *con, data_config *dc) { |
3565 | - if (con->conf.log_condition_handling) { | |
3566 | - log_error_write(srv, __FILE__, __LINE__, "s", "=== start of condition block ==="); | |
3567 | - } | |
3568 | return (config_check_cond_cached(srv, con, dc) == COND_RESULT_TRUE); | |
3569 | } | |
f673a614 | 3570 | |
f26f9fd5 ER |
3571 | @@ -443,3 +460,85 @@ |
3572 | return 1; | |
f673a614 ER |
3573 | } |
3574 | ||
f26f9fd5 ER |
3575 | +/* return <0 on error |
3576 | + * return 0-x if matched (and replaced) | |
3577 | + */ | |
3578 | +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result) | |
3579 | +{ | |
3580 | +#ifdef HAVE_PCRE_H | |
3581 | + pcre *match; | |
3582 | + pcre_extra *extra; | |
3583 | + const char *pattern; | |
3584 | + size_t pattern_len; | |
3585 | + int n; | |
3586 | + size_t i; | |
3587 | + pcre_keyvalue *kv; | |
3588 | +# define N 10 | |
3589 | + int ovec[N * 3]; | |
f673a614 | 3590 | + |
f26f9fd5 ER |
3591 | + for (i = 0; i < kvb->used; i++) { |
3592 | + kv = kvb->kv[i]; | |
f673a614 | 3593 | + |
f26f9fd5 ER |
3594 | + match = kv->key; |
3595 | + extra = kv->key_extra; | |
3596 | + pattern = kv->value->ptr; | |
3597 | + pattern_len = kv->value->used - 1; | |
f673a614 | 3598 | + |
f26f9fd5 ER |
3599 | + if ((n = pcre_exec(match, extra, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) { |
3600 | + if (n != PCRE_ERROR_NOMATCH) { | |
3601 | + return n; | |
3602 | + } | |
3603 | + } else { | |
3604 | + const char **list; | |
3605 | + size_t start, end; | |
3606 | + size_t k; | |
f673a614 | 3607 | + |
f26f9fd5 ER |
3608 | + /* it matched */ |
3609 | + pcre_get_substring_list(match_buf->ptr, ovec, n, &list); | |
f673a614 | 3610 | + |
f26f9fd5 | 3611 | + /* search for $[0-9] */ |
f673a614 | 3612 | + |
f26f9fd5 | 3613 | + buffer_reset(result); |
f673a614 | 3614 | + |
f26f9fd5 ER |
3615 | + start = 0; end = pattern_len; |
3616 | + for (k = 0; k < pattern_len; k++) { | |
3617 | + if ((pattern[k] == '$' || pattern[k] == '%') && | |
3618 | + isdigit((unsigned char)pattern[k + 1])) { | |
3619 | + /* got one */ | |
f673a614 | 3620 | + |
f26f9fd5 | 3621 | + size_t num = pattern[k + 1] - '0'; |
f673a614 | 3622 | + |
f26f9fd5 | 3623 | + end = k; |
f673a614 | 3624 | + |
f26f9fd5 | 3625 | + buffer_append_string_len(result, pattern + start, end - start); |
f673a614 | 3626 | + |
f26f9fd5 ER |
3627 | + if (pattern[k] == '$') { |
3628 | + /* n is always > 0 */ | |
3629 | + if (num < (size_t)n) { | |
3630 | + buffer_append_string(result, list[num]); | |
3631 | + } | |
3632 | + } else { | |
3633 | + config_append_cond_match_buffer(con, context, result, num); | |
3634 | + } | |
f673a614 | 3635 | + |
f26f9fd5 ER |
3636 | + k++; |
3637 | + start = k + 1; | |
3638 | + } | |
3639 | + } | |
f673a614 | 3640 | + |
f26f9fd5 | 3641 | + buffer_append_string_len(result, pattern + start, pattern_len - start); |
f673a614 | 3642 | + |
f26f9fd5 | 3643 | + pcre_free(list); |
f673a614 | 3644 | + |
f26f9fd5 ER |
3645 | + return i; |
3646 | + } | |
3647 | + } | |
f673a614 | 3648 | + |
f26f9fd5 ER |
3649 | + return PCRE_ERROR_NOMATCH; |
3650 | +#undef N | |
3651 | +#else | |
3652 | + UNUSED(kvb); | |
3653 | + return -2; | |
3654 | +#endif | |
3655 | +} | |
f673a614 | 3656 | + |
1175ccec ER |
3657 | --- ../lighttpd-1.4.11/src/configfile.c 2006-02-15 14:26:42.000000000 +0200 |
3658 | +++ lighttpd-1.4.12/src/configfile.c 2006-07-15 22:43:21.000000000 +0300 | |
f26f9fd5 ER |
3659 | @@ -2,7 +2,6 @@ |
3660 | ||
3661 | #include <stdlib.h> | |
3662 | #include <fcntl.h> | |
3663 | -#include <unistd.h> | |
3664 | #include <errno.h> | |
3665 | #include <string.h> | |
3666 | #include <stdio.h> | |
1175ccec | 3667 | @@ -13,21 +12,24 @@ |
f26f9fd5 ER |
3668 | #include "log.h" |
3669 | #include "stream.h" | |
3670 | #include "plugin.h" | |
3671 | -#ifdef USE_LICENSE | |
3672 | -#include "license.h" | |
3673 | -#endif | |
3674 | - | |
3675 | #include "configparser.h" | |
3676 | #include "configfile.h" | |
3677 | #include "proc_open.h" | |
3678 | ||
3679 | +#include "sys-files.h" | |
1175ccec | 3680 | +#include "sys-process.h" |
f673a614 | 3681 | + |
f26f9fd5 ER |
3682 | +#ifndef PATH_MAX |
3683 | +/* win32 */ | |
3684 | +#define PATH_MAX 64 | |
3685 | +#endif | |
3686 | ||
3687 | static int config_insert(server *srv) { | |
3688 | size_t i; | |
2519e6e5 ER |
3689 | int ret = 0; |
3690 | buffer *stat_cache_string; | |
3691 | - | |
3692 | - config_values_t cv[] = { | |
3693 | + | |
3694 | + config_values_t cv[] = { | |
3695 | { "server.bind", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 */ | |
3696 | { "server.errorlog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 1 */ | |
3697 | { "server.errorfile-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 2 */ | |
1175ccec | 3698 | @@ -38,7 +40,7 @@ |
2519e6e5 ER |
3699 | { "server.tag", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */ |
3700 | { "server.use-ipv6", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */ | |
3701 | { "server.modules", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 9 */ | |
3702 | - | |
3703 | + | |
3704 | { "server.event-handler", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 */ | |
3705 | { "server.pid-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 */ | |
3706 | { "server.max-request-size", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ | |
1175ccec | 3707 | @@ -49,7 +51,7 @@ |
2519e6e5 ER |
3708 | { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */ |
3709 | { "server.name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 18 */ | |
3710 | { "server.max-keep-alive-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 19 */ | |
3711 | - | |
3712 | + | |
3713 | { "server.max-read-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 20 */ | |
3714 | { "server.max-write-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 21 */ | |
3715 | { "server.error-handler-404", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 22 */ | |
1175ccec | 3716 | @@ -60,19 +62,19 @@ |
2519e6e5 ER |
3717 | { "mimetype.use-xattr", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */ |
3718 | { "mimetype.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 28 */ | |
3719 | { "ssl.pemfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 29 */ | |
3720 | - | |
3721 | + | |
3722 | { "ssl.engine", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 30 */ | |
3723 | - | |
3724 | + | |
3725 | { "debug.log-file-not-found", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 31 */ | |
3726 | { "debug.log-request-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 32 */ | |
3727 | { "debug.log-response-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 33 */ | |
3728 | { "debug.log-request-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 34 */ | |
3729 | - | |
3730 | + | |
3731 | { "server.protocol-http11", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 35 */ | |
3732 | { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */ | |
3733 | { "debug.log-state-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */ | |
3734 | { "ssl.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 38 */ | |
3735 | - | |
3736 | + | |
3737 | { "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 39 */ | |
3738 | { "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */ | |
3739 | { "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 41 */ | |
1175ccec | 3740 | @@ -80,7 +82,8 @@ |
f26f9fd5 ER |
3741 | { "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 43 */ |
3742 | { "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 44 */ | |
3743 | { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */ | |
2519e6e5 | 3744 | - |
f26f9fd5 | 3745 | + { "debug.log-condition-cache-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 46 */ |
2519e6e5 | 3746 | + |
f26f9fd5 ER |
3747 | { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, |
3748 | { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, | |
2519e6e5 | 3749 | { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, |
1175ccec | 3750 | @@ -90,11 +93,11 @@ |
2519e6e5 ER |
3751 | { "server.groupid", "use server.groupname instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, |
3752 | { "server.use-keep-alive", "use server.max-keep-alive-requests = 0 instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, | |
3753 | { "server.force-lower-case-files", "use server.force-lowercase-filenames instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, | |
3754 | - | |
3755 | + | |
3756 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
3757 | }; | |
3758 | ||
3759 | - | |
3760 | + | |
3761 | /* 0 */ | |
3762 | cv[0].destination = srv->srvconf.bindhost; | |
3763 | cv[1].destination = srv->srvconf.errorlog_file; | |
1175ccec | 3764 | @@ -102,33 +105,33 @@ |
2519e6e5 ER |
3765 | cv[4].destination = srv->srvconf.username; |
3766 | cv[5].destination = srv->srvconf.groupname; | |
3767 | cv[6].destination = &(srv->srvconf.port); | |
3768 | - | |
3769 | + | |
3770 | cv[9].destination = srv->srvconf.modules; | |
3771 | cv[10].destination = srv->srvconf.event_handler; | |
3772 | cv[11].destination = srv->srvconf.pid_file; | |
3773 | - | |
3774 | + | |
3775 | cv[13].destination = &(srv->srvconf.max_worker); | |
3776 | cv[23].destination = &(srv->srvconf.max_fds); | |
3777 | cv[36].destination = &(srv->srvconf.log_request_header_on_error); | |
3778 | cv[37].destination = &(srv->srvconf.log_state_handling); | |
3779 | - | |
3780 | + | |
3781 | cv[39].destination = &(srv->srvconf.errorlog_use_syslog); | |
3782 | - | |
3783 | + | |
3784 | stat_cache_string = buffer_init(); | |
3785 | cv[41].destination = stat_cache_string; | |
3786 | cv[43].destination = srv->srvconf.network_backend; | |
3787 | cv[44].destination = srv->srvconf.upload_tempdirs; | |
3788 | cv[45].destination = &(srv->srvconf.enable_cores); | |
3789 | - | |
3790 | + | |
3791 | cv[42].destination = &(srv->srvconf.max_conns); | |
3792 | cv[12].destination = &(srv->srvconf.max_request_size); | |
3793 | srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
3794 | ||
3795 | assert(srv->config_storage); | |
3796 | - | |
3797 | + | |
3798 | for (i = 0; i < srv->config_context->used; i++) { | |
3799 | specific_config *s; | |
3800 | - | |
3801 | + | |
3802 | s = calloc(1, sizeof(specific_config)); | |
3803 | assert(s); | |
3804 | s->document_root = buffer_init(); | |
1175ccec | 3805 | @@ -154,17 +157,18 @@ |
2519e6e5 ER |
3806 | s->global_kbytes_per_second = 0; |
3807 | s->global_bytes_per_second_cnt = 0; | |
3808 | s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt; | |
3809 | - | |
3810 | + | |
3811 | cv[2].destination = s->errorfile_prefix; | |
3812 | - | |
3813 | + | |
3814 | cv[7].destination = s->server_tag; | |
3815 | cv[8].destination = &(s->use_ipv6); | |
3816 | - | |
3817 | - | |
3818 | + | |
3819 | + | |
3820 | /* 13 max-worker */ | |
f26f9fd5 ER |
3821 | cv[14].destination = s->document_root; |
3822 | cv[15].destination = &(s->force_lowercase_filenames); | |
3823 | cv[16].destination = &(s->log_condition_handling); | |
3824 | + cv[46].destination = &(s->log_condition_cache_handling); | |
3825 | cv[17].destination = &(s->max_keep_alive_requests); | |
3826 | cv[18].destination = s->server_name; | |
3827 | cv[19].destination = &(s->max_keep_alive_idle); | |
1175ccec | 3828 | @@ -179,23 +183,23 @@ |
2519e6e5 ER |
3829 | cv[28].destination = s->mimetypes; |
3830 | cv[29].destination = s->ssl_pemfile; | |
3831 | cv[30].destination = &(s->is_ssl); | |
3832 | - | |
3833 | + | |
3834 | cv[31].destination = &(s->log_file_not_found); | |
3835 | cv[32].destination = &(s->log_request_handling); | |
3836 | cv[33].destination = &(s->log_response_header); | |
3837 | cv[34].destination = &(s->log_request_header); | |
3838 | - | |
3839 | + | |
3840 | cv[35].destination = &(s->allow_http11); | |
3841 | cv[38].destination = s->ssl_ca_file; | |
3842 | cv[40].destination = &(s->range_requests); | |
3843 | - | |
3844 | + | |
3845 | srv->config_storage[i] = s; | |
3846 | - | |
3847 | + | |
3848 | if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) { | |
3849 | break; | |
3850 | } | |
3851 | } | |
3852 | - | |
3853 | + | |
3854 | if (buffer_is_empty(stat_cache_string)) { | |
3855 | srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE; | |
3856 | } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) { | |
1175ccec | 3857 | @@ -205,22 +209,22 @@ |
2519e6e5 ER |
3858 | } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) { |
3859 | srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE; | |
3860 | } else { | |
3861 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
3862 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
3863 | "server.stat-cache-engine can be one of \"disable\", \"simple\", \"fam\", but not:", stat_cache_string); | |
3864 | ret = HANDLER_ERROR; | |
3865 | } | |
3866 | - | |
3867 | + | |
3868 | buffer_free(stat_cache_string); | |
3869 | - | |
3870 | + | |
3871 | return ret; | |
3872 | - | |
3873 | -} | |
3874 | ||
3875 | +} | |
f26f9fd5 | 3876 | |
f26f9fd5 ER |
3877 | -#define PATCH(x) con->conf.x = s->x |
3878 | +#define PATCH(x) \ | |
3879 | + con->conf.x = s->x | |
3880 | int config_setup_connection(server *srv, connection *con) { | |
3881 | specific_config *s = srv->config_storage[0]; | |
2519e6e5 ER |
3882 | - |
3883 | + | |
3884 | PATCH(allow_http11); | |
3885 | PATCH(mimetypes); | |
3886 | PATCH(document_root); | |
1175ccec | 3887 | @@ -236,20 +240,21 @@ |
2519e6e5 ER |
3888 | PATCH(kbytes_per_second); |
3889 | PATCH(global_kbytes_per_second); | |
3890 | PATCH(global_bytes_per_second_cnt); | |
3891 | - | |
3892 | + | |
3893 | con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt; | |
3894 | buffer_copy_string_buffer(con->server_name, s->server_name); | |
3895 | - | |
3896 | + | |
3897 | PATCH(log_request_header); | |
3898 | PATCH(log_response_header); | |
3899 | PATCH(log_request_handling); | |
3900 | PATCH(log_condition_handling); | |
3901 | + PATCH(log_condition_cache_handling); | |
f26f9fd5 | 3902 | PATCH(log_file_not_found); |
2519e6e5 ER |
3903 | - |
3904 | + | |
f26f9fd5 | 3905 | PATCH(range_requests); |
2519e6e5 ER |
3906 | PATCH(force_lowercase_filenames); |
3907 | PATCH(is_ssl); | |
3908 | - | |
3909 | + | |
3910 | PATCH(ssl_pemfile); | |
3911 | PATCH(ssl_ca_file); | |
3912 | return 0; | |
1175ccec | 3913 | @@ -257,22 +262,22 @@ |
2519e6e5 ER |
3914 | |
3915 | int config_patch_connection(server *srv, connection *con, comp_key_t comp) { | |
3916 | size_t i, j; | |
3917 | - | |
3918 | + | |
3919 | /* skip the first, the global context */ | |
3920 | for (i = 1; i < srv->config_context->used; i++) { | |
3921 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
3922 | specific_config *s = srv->config_storage[i]; | |
3923 | - | |
3924 | + | |
3925 | /* not our stage */ | |
3926 | if (comp != dc->comp) continue; | |
3927 | - | |
3928 | + | |
3929 | /* condition didn't match */ | |
3930 | if (!config_check_cond(srv, con, dc)) continue; | |
3931 | - | |
3932 | + | |
3933 | /* merge config */ | |
3934 | for (j = 0; j < dc->value->used; j++) { | |
3935 | data_unset *du = dc->value->data[j]; | |
3936 | - | |
3937 | + | |
3938 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.document-root"))) { | |
3939 | PATCH(document_root); | |
3940 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.range-requests"))) { | |
1175ccec | 3941 | @@ -315,11 +320,13 @@ |
f26f9fd5 ER |
3942 | PATCH(log_response_header); |
3943 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-handling"))) { | |
3944 | PATCH(log_condition_handling); | |
3945 | + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-cache-handling"))) { | |
3946 | + PATCH(log_condition_cache_handling); | |
3947 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-file-not-found"))) { | |
3948 | PATCH(log_file_not_found); | |
3949 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) { | |
2519e6e5 ER |
3950 | PATCH(allow_http11); |
3951 | - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) { | |
3952 | + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) { | |
3953 | PATCH(force_lowercase_filenames); | |
3954 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.kbytes-per-second"))) { | |
3955 | PATCH(global_kbytes_per_second); | |
1175ccec | 3956 | @@ -328,7 +335,7 @@ |
2519e6e5 ER |
3957 | } |
3958 | } | |
3959 | } | |
3960 | - | |
3961 | + | |
3962 | return 0; | |
3963 | } | |
3964 | #undef PATCH | |
1175ccec | 3965 | @@ -336,15 +343,15 @@ |
2519e6e5 ER |
3966 | typedef struct { |
3967 | int foo; | |
3968 | int bar; | |
3969 | - | |
3970 | + | |
3971 | const buffer *source; | |
3972 | const char *input; | |
3973 | size_t offset; | |
3974 | size_t size; | |
3975 | - | |
3976 | + | |
3977 | int line_pos; | |
3978 | int line; | |
3979 | - | |
3980 | + | |
3981 | int in_key; | |
3982 | int in_brace; | |
3983 | int in_cond; | |
1175ccec | 3984 | @@ -362,7 +369,7 @@ |
2519e6e5 ER |
3985 | } |
3986 | ||
3987 | if (0 != stream_open(&(t->s), t->file)) { | |
3988 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
3989 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
3990 | "opening configfile ", t->file, "failed:", strerror(errno)); | |
3991 | buffer_free(t->file); | |
3992 | return -1; | |
1175ccec | 3993 | @@ -373,7 +380,7 @@ |
2519e6e5 ER |
3994 | t->size = t->s.size; |
3995 | t->line = 1; | |
3996 | t->line_pos = 1; | |
3997 | - | |
3998 | + | |
3999 | t->in_key = 1; | |
4000 | t->in_brace = 0; | |
4001 | t->in_cond = 0; | |
1175ccec | 4002 | @@ -401,7 +408,7 @@ |
2519e6e5 ER |
4003 | static int config_skip_comment(tokenizer_t *t) { |
4004 | int i; | |
4005 | assert(t->input[t->offset] == '#'); | |
4006 | - for (i = 1; t->input[t->offset + i] && | |
4007 | + for (i = 1; t->input[t->offset + i] && | |
4008 | (t->input[t->offset + i] != '\n' && t->input[t->offset + i] != '\r'); | |
4009 | i++); | |
4010 | t->offset += i; | |
1175ccec | 4011 | @@ -411,44 +418,44 @@ |
2519e6e5 ER |
4012 | static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer *token) { |
4013 | int tid = 0; | |
4014 | size_t i; | |
4015 | - | |
4016 | + | |
4017 | for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) { | |
4018 | char c = t->input[t->offset]; | |
4019 | const char *start = NULL; | |
4020 | - | |
4021 | + | |
4022 | switch (c) { | |
4023 | - case '=': | |
4024 | + case '=': | |
4025 | if (t->in_brace) { | |
4026 | if (t->input[t->offset + 1] == '>') { | |
4027 | t->offset += 2; | |
4028 | - | |
4029 | + | |
4030 | buffer_copy_string(token, "=>"); | |
4031 | - | |
4032 | + | |
4033 | tid = TK_ARRAY_ASSIGN; | |
4034 | } else { | |
4035 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4036 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4037 | "source:", t->source, | |
4038 | - "line:", t->line, "pos:", t->line_pos, | |
4039 | + "line:", t->line, "pos:", t->line_pos, | |
4040 | "use => for assignments in arrays"); | |
4041 | return -1; | |
4042 | } | |
4043 | } else if (t->in_cond) { | |
4044 | if (t->input[t->offset + 1] == '=') { | |
4045 | t->offset += 2; | |
4046 | - | |
4047 | + | |
4048 | buffer_copy_string(token, "=="); | |
4049 | - | |
4050 | + | |
4051 | tid = TK_EQ; | |
4052 | } else if (t->input[t->offset + 1] == '~') { | |
4053 | t->offset += 2; | |
4054 | - | |
4055 | + | |
4056 | buffer_copy_string(token, "=~"); | |
4057 | - | |
4058 | + | |
4059 | tid = TK_MATCH; | |
4060 | } else { | |
4061 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4062 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4063 | "source:", t->source, | |
4064 | - "line:", t->line, "pos:", t->line_pos, | |
4065 | + "line:", t->line, "pos:", t->line_pos, | |
4066 | "only =~ and == are allowed in the condition"); | |
4067 | return -1; | |
4068 | } | |
1175ccec | 4069 | @@ -456,51 +463,51 @@ |
2519e6e5 ER |
4070 | t->in_cond = 0; |
4071 | } else if (t->in_key) { | |
4072 | tid = TK_ASSIGN; | |
4073 | - | |
4074 | + | |
4075 | buffer_copy_string_len(token, t->input + t->offset, 1); | |
4076 | - | |
4077 | + | |
4078 | t->offset++; | |
4079 | t->line_pos++; | |
4080 | } else { | |
4081 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4082 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4083 | "source:", t->source, | |
4084 | - "line:", t->line, "pos:", t->line_pos, | |
4085 | + "line:", t->line, "pos:", t->line_pos, | |
4086 | "unexpected equal-sign: ="); | |
4087 | return -1; | |
4088 | } | |
4089 | - | |
4090 | + | |
4091 | break; | |
4092 | - case '!': | |
4093 | + case '!': | |
4094 | if (t->in_cond) { | |
4095 | if (t->input[t->offset + 1] == '=') { | |
4096 | t->offset += 2; | |
4097 | - | |
4098 | + | |
4099 | buffer_copy_string(token, "!="); | |
4100 | - | |
4101 | + | |
4102 | tid = TK_NE; | |
4103 | } else if (t->input[t->offset + 1] == '~') { | |
4104 | t->offset += 2; | |
4105 | - | |
4106 | + | |
4107 | buffer_copy_string(token, "!~"); | |
4108 | - | |
4109 | + | |
4110 | tid = TK_NOMATCH; | |
4111 | } else { | |
4112 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4113 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4114 | "source:", t->source, | |
4115 | - "line:", t->line, "pos:", t->line_pos, | |
4116 | + "line:", t->line, "pos:", t->line_pos, | |
4117 | "only !~ and != are allowed in the condition"); | |
4118 | return -1; | |
4119 | } | |
4120 | t->in_key = 1; | |
4121 | t->in_cond = 0; | |
4122 | } else { | |
4123 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4124 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4125 | "source:", t->source, | |
4126 | - "line:", t->line, "pos:", t->line_pos, | |
4127 | + "line:", t->line, "pos:", t->line_pos, | |
4128 | "unexpected exclamation-marks: !"); | |
4129 | return -1; | |
4130 | } | |
4131 | - | |
4132 | + | |
4133 | break; | |
4134 | case '\t': | |
4135 | case ' ': | |
1175ccec | 4136 | @@ -546,10 +553,10 @@ |
2519e6e5 ER |
4137 | case ',': |
4138 | if (t->in_brace > 0) { | |
4139 | tid = TK_COMMA; | |
4140 | - | |
4141 | + | |
4142 | buffer_copy_string(token, "(COMMA)"); | |
4143 | } | |
4144 | - | |
4145 | + | |
4146 | t->offset++; | |
4147 | t->line_pos++; | |
4148 | break; | |
1175ccec | 4149 | @@ -557,70 +564,70 @@ |
2519e6e5 ER |
4150 | /* search for the terminating " */ |
4151 | start = t->input + t->offset + 1; | |
4152 | buffer_copy_string(token, ""); | |
4153 | - | |
4154 | + | |
4155 | for (i = 1; t->input[t->offset + i]; i++) { | |
4156 | if (t->input[t->offset + i] == '\\' && | |
4157 | t->input[t->offset + i + 1] == '"') { | |
4158 | - | |
4159 | + | |
4160 | buffer_append_string_len(token, start, t->input + t->offset + i - start); | |
4161 | - | |
4162 | + | |
4163 | start = t->input + t->offset + i + 1; | |
4164 | - | |
4165 | + | |
4166 | /* skip the " */ | |
4167 | i++; | |
4168 | continue; | |
4169 | } | |
4170 | - | |
4171 | - | |
4172 | + | |
4173 | + | |
4174 | if (t->input[t->offset + i] == '"') { | |
4175 | tid = TK_STRING; | |
4176 | - | |
4177 | + | |
4178 | buffer_append_string_len(token, start, t->input + t->offset + i - start); | |
4179 | - | |
4180 | + | |
4181 | break; | |
4182 | } | |
4183 | } | |
4184 | ||
4185 | if (t->input[t->offset + i] == '\0') { | |
4186 | /* ERROR */ | |
4187 | - | |
4188 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4189 | + | |
4190 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4191 | "source:", t->source, | |
4192 | - "line:", t->line, "pos:", t->line_pos, | |
4193 | + "line:", t->line, "pos:", t->line_pos, | |
4194 | "missing closing quote"); | |
4195 | - | |
4196 | + | |
4197 | return -1; | |
4198 | } | |
4199 | - | |
4200 | + | |
4201 | t->offset += i + 1; | |
4202 | t->line_pos += i + 1; | |
4203 | - | |
4204 | + | |
4205 | break; | |
4206 | case '(': | |
4207 | t->offset++; | |
4208 | t->in_brace++; | |
4209 | - | |
4210 | + | |
4211 | tid = TK_LPARAN; | |
4212 | - | |
4213 | + | |
4214 | buffer_copy_string(token, "("); | |
4215 | break; | |
4216 | case ')': | |
4217 | t->offset++; | |
4218 | t->in_brace--; | |
4219 | - | |
4220 | + | |
4221 | tid = TK_RPARAN; | |
4222 | - | |
4223 | + | |
4224 | buffer_copy_string(token, ")"); | |
4225 | break; | |
4226 | case '$': | |
4227 | t->offset++; | |
4228 | - | |
4229 | + | |
4230 | tid = TK_DOLLAR; | |
4231 | t->in_cond = 1; | |
4232 | t->in_key = 0; | |
4233 | - | |
4234 | + | |
4235 | buffer_copy_string(token, "$"); | |
4236 | - | |
4237 | + | |
4238 | break; | |
4239 | ||
4240 | case '+': | |
1175ccec | 4241 | @@ -637,96 +644,88 @@ |
2519e6e5 ER |
4242 | |
4243 | case '{': | |
4244 | t->offset++; | |
4245 | - | |
4246 | + | |
4247 | tid = TK_LCURLY; | |
4248 | - | |
4249 | + | |
4250 | buffer_copy_string(token, "{"); | |
4251 | - | |
4252 | + | |
4253 | break; | |
4254 | - | |
4255 | + | |
4256 | case '}': | |
4257 | t->offset++; | |
4258 | - | |
4259 | + | |
4260 | tid = TK_RCURLY; | |
4261 | - | |
4262 | + | |
4263 | buffer_copy_string(token, "}"); | |
4264 | - | |
4265 | + | |
4266 | break; | |
4267 | ||
4268 | case '[': | |
4269 | t->offset++; | |
4270 | - | |
4271 | + | |
4272 | tid = TK_LBRACKET; | |
4273 | - | |
4274 | + | |
4275 | buffer_copy_string(token, "["); | |
4276 | - | |
4277 | + | |
4278 | break; | |
4279 | - | |
4280 | + | |
4281 | case ']': | |
4282 | t->offset++; | |
4283 | - | |
4284 | + | |
4285 | tid = TK_RBRACKET; | |
4286 | - | |
4287 | + | |
4288 | buffer_copy_string(token, "]"); | |
4289 | - | |
4290 | + | |
4291 | break; | |
4292 | case '#': | |
4293 | t->line_pos += config_skip_comment(t); | |
4294 | - | |
4295 | + | |
4296 | break; | |
4297 | default: | |
4298 | if (t->in_cond) { | |
4299 | - for (i = 0; t->input[t->offset + i] && | |
4300 | + for (i = 0; t->input[t->offset + i] && | |
4301 | (isalpha((unsigned char)t->input[t->offset + i]) | |
4302 | ); i++); | |
4303 | - | |
4304 | + | |
4305 | if (i && t->input[t->offset + i]) { | |
4306 | tid = TK_SRVVARNAME; | |
4307 | buffer_copy_string_len(token, t->input + t->offset, i); | |
4308 | - | |
4309 | + | |
4310 | t->offset += i; | |
4311 | t->line_pos += i; | |
4312 | } else { | |
4313 | /* ERROR */ | |
4314 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4315 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4316 | "source:", t->source, | |
4317 | - "line:", t->line, "pos:", t->line_pos, | |
4318 | + "line:", t->line, "pos:", t->line_pos, | |
4319 | "invalid character in condition"); | |
4320 | return -1; | |
4321 | } | |
4322 | } else if (isdigit((unsigned char)c)) { | |
4323 | /* take all digits */ | |
f26f9fd5 | 4324 | for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]); i++); |
2519e6e5 ER |
4325 | - |
4326 | + | |
f26f9fd5 ER |
4327 | /* was there it least a digit ? */ |
4328 | - if (i && t->input[t->offset + i]) { | |
4329 | + if (i) { | |
4330 | tid = TK_INTEGER; | |
2519e6e5 ER |
4331 | - |
4332 | + | |
f26f9fd5 | 4333 | buffer_copy_string_len(token, t->input + t->offset, i); |
2519e6e5 ER |
4334 | - |
4335 | + | |
f26f9fd5 ER |
4336 | t->offset += i; |
4337 | t->line_pos += i; | |
4338 | - } else { | |
4339 | - /* ERROR */ | |
4340 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4341 | - "source:", t->source, | |
4342 | - "line:", t->line, "pos:", t->line_pos, | |
4343 | - "unexpected EOF"); | |
f673a614 | 4344 | - |
f26f9fd5 | 4345 | - return -1; |
f673a614 | 4346 | } |
f26f9fd5 ER |
4347 | } else { |
4348 | /* the key might consist of [-.0-9a-z] */ | |
2519e6e5 ER |
4349 | - for (i = 0; t->input[t->offset + i] && |
4350 | - (isalnum((unsigned char)t->input[t->offset + i]) || | |
4351 | + for (i = 0; t->input[t->offset + i] && | |
4352 | + (isalnum((unsigned char)t->input[t->offset + i]) || | |
4353 | t->input[t->offset + i] == '.' || | |
4354 | t->input[t->offset + i] == '_' || /* for env.* */ | |
4355 | t->input[t->offset + i] == '-' | |
4356 | ); i++); | |
4357 | - | |
4358 | + | |
4359 | if (i && t->input[t->offset + i]) { | |
4360 | buffer_copy_string_len(token, t->input + t->offset, i); | |
4361 | - | |
4362 | + | |
4363 | if (strcmp(token->ptr, "include") == 0) { | |
4364 | tid = TK_INCLUDE; | |
4365 | } else if (strcmp(token->ptr, "include_shell") == 0) { | |
1175ccec | 4366 | @@ -738,14 +737,14 @@ |
2519e6e5 ER |
4367 | } else { |
4368 | tid = TK_LKEY; | |
4369 | } | |
4370 | - | |
4371 | + | |
4372 | t->offset += i; | |
4373 | t->line_pos += i; | |
4374 | } else { | |
4375 | /* ERROR */ | |
4376 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4377 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", | |
4378 | "source:", t->source, | |
4379 | - "line:", t->line, "pos:", t->line_pos, | |
4380 | + "line:", t->line, "pos:", t->line_pos, | |
4381 | "invalid character in variable name"); | |
4382 | return -1; | |
4383 | } | |
1175ccec | 4384 | @@ -753,16 +752,16 @@ |
2519e6e5 ER |
4385 | break; |
4386 | } | |
4387 | } | |
4388 | - | |
4389 | + | |
4390 | if (tid) { | |
4391 | *token_id = tid; | |
4392 | #if 0 | |
4393 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", | |
4394 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", | |
4395 | "source:", t->source, | |
4396 | "line:", t->line, "pos:", t->line_pos, | |
4397 | token, token->used - 1, tid); | |
4398 | #endif | |
4399 | - | |
4400 | + | |
4401 | return 1; | |
4402 | } else if (t->offset < t->size) { | |
4403 | fprintf(stderr, "%s.%d: %d, %s\n", | |
1175ccec | 4404 | @@ -781,10 +780,11 @@ |
f26f9fd5 ER |
4405 | pParser = configparserAlloc( malloc ); |
4406 | lasttoken = buffer_init(); | |
4407 | token = buffer_init(); | |
f673a614 | 4408 | + |
f26f9fd5 ER |
4409 | while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) { |
4410 | buffer_copy_string_buffer(lasttoken, token); | |
4411 | configparser(pParser, token_id, token, context); | |
2519e6e5 ER |
4412 | - |
4413 | + | |
4414 | token = buffer_init(); | |
4415 | } | |
4416 | buffer_free(token); | |
1175ccec | 4417 | @@ -797,14 +797,14 @@ |
2519e6e5 ER |
4418 | } |
4419 | } | |
4420 | configparserFree(pParser, free); | |
4421 | - | |
4422 | + | |
4423 | if (ret == -1) { | |
4424 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
4425 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
4426 | "configfile parser failed:", lasttoken); | |
4427 | } else if (context->ok == 0) { | |
4428 | - log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", | |
4429 | + log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", | |
4430 | "source:", t->source, | |
4431 | - "line:", t->line, "pos:", t->line_pos, | |
4432 | + "line:", t->line, "pos:", t->line_pos, | |
4433 | "parser failed somehow near here:", lasttoken); | |
4434 | ret = -1; | |
4435 | } | |
1175ccec | 4436 | @@ -821,7 +821,7 @@ |
2519e6e5 ER |
4437 | t->offset = 0; |
4438 | t->line = 1; | |
4439 | t->line_pos = 1; | |
4440 | - | |
4441 | + | |
4442 | t->in_key = 1; | |
4443 | t->in_brace = 0; | |
4444 | t->in_cond = 0; | |
1175ccec | 4445 | @@ -844,7 +844,7 @@ |
2519e6e5 ER |
4446 | } |
4447 | ||
4448 | if (0 != stream_open(&s, filename)) { | |
4449 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
4450 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
4451 | "opening configfile ", filename, "failed:", strerror(errno)); | |
4452 | ret = -1; | |
4453 | } else { | |
1175ccec | 4454 | @@ -866,7 +866,7 @@ |
2519e6e5 ER |
4455 | char oldpwd[PATH_MAX]; |
4456 | ||
4457 | if (NULL == getcwd(oldpwd, sizeof(oldpwd))) { | |
4458 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
4459 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
4460 | "cannot get cwd", strerror(errno)); | |
4461 | return -1; | |
4462 | } | |
1175ccec | 4463 | @@ -879,7 +879,7 @@ |
2519e6e5 ER |
4464 | } |
4465 | ||
4466 | if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) { | |
4467 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
4468 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
4469 | "opening", source, "failed:", strerror(errno)); | |
4470 | ret = -1; | |
4471 | } else { | |
1175ccec | 4472 | @@ -896,13 +896,12 @@ |
2519e6e5 ER |
4473 | static void context_init(server *srv, config_t *context) { |
4474 | context->srv = srv; | |
4475 | context->ok = 1; | |
4476 | - context->configs_stack = array_init(); | |
4477 | - context->configs_stack->is_weakref = 1; | |
4478 | + context->configs_stack = buffer_ptr_init(NULL); | |
4479 | context->basedir = buffer_init(); | |
4480 | } | |
4481 | ||
4482 | static void context_free(config_t *context) { | |
4483 | - array_free(context->configs_stack); | |
4484 | + buffer_ptr_free(context->configs_stack); | |
4485 | buffer_free(context->basedir); | |
f26f9fd5 | 4486 | } |
f673a614 | 4487 | |
1175ccec | 4488 | @@ -918,18 +917,15 @@ |
f26f9fd5 ER |
4489 | context_init(srv, &context); |
4490 | context.all_configs = srv->config_context; | |
f673a614 | 4491 | |
f26f9fd5 ER |
4492 | - pos = strrchr(fn, |
4493 | -#ifdef __WIN32 | |
4494 | - '\\' | |
4495 | -#else | |
4496 | - '/' | |
4497 | -#endif | |
4498 | - ); | |
4499 | + /* use the current dir as basedir for all other includes | |
4500 | + */ | |
4501 | + pos = strrchr(fn, DIR_SEPERATOR); | |
f673a614 | 4502 | + |
f26f9fd5 ER |
4503 | if (pos) { |
4504 | buffer_copy_string_len(context.basedir, fn, pos - fn + 1); | |
4505 | fn = pos + 1; | |
2519e6e5 ER |
4506 | } |
4507 | - | |
4508 | + | |
4509 | dc = data_config_init(); | |
4510 | buffer_copy_string(dc->key, "global"); | |
4511 | ||
1175ccec ER |
4512 | @@ -944,7 +940,7 @@ |
4513 | dpid->value = getpid(); | |
2519e6e5 ER |
4514 | buffer_copy_string(dpid->key, "var.PID"); |
4515 | array_insert_unique(srv->config, (data_unset *)dpid); | |
4516 | - | |
4517 | + | |
4518 | dcwd = data_string_init(); | |
4519 | buffer_prepare_copy(dcwd->value, 1024); | |
4520 | if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) { | |
1175ccec | 4521 | @@ -968,7 +964,7 @@ |
2519e6e5 ER |
4522 | } else { |
4523 | return -1; | |
4524 | } | |
4525 | - | |
4526 | + | |
4527 | if (NULL != (modules = (data_array *)array_get_element(srv->config, "server.modules"))) { | |
4528 | data_string *ds; | |
4529 | data_array *prepends; | |
1175ccec | 4530 | @@ -1026,22 +1022,23 @@ |
2519e6e5 ER |
4531 | buffer_copy_string(modules->key, "server.modules"); |
4532 | array_insert_unique(srv->config, (data_unset *)modules); | |
4533 | } | |
4534 | - | |
4535 | + | |
4536 | ||
4537 | if (0 != config_insert(srv)) { | |
4538 | return -1; | |
4539 | } | |
4540 | - | |
4541 | + | |
f26f9fd5 | 4542 | return 0; |
f673a614 ER |
4543 | } |
4544 | ||
f673a614 | 4545 | + |
f26f9fd5 ER |
4546 | int config_set_defaults(server *srv) { |
4547 | size_t i; | |
4548 | specific_config *s = srv->config_storage[0]; | |
2519e6e5 ER |
4549 | struct stat st1, st2; |
4550 | - | |
4551 | - struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = | |
4552 | - { | |
4553 | + | |
4554 | + struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = | |
4555 | + { | |
4556 | /* - poll is most reliable | |
4557 | * - select works everywhere | |
4558 | * - linux-* are experimental | |
1175ccec | 4559 | @@ -1067,20 +1064,21 @@ |
2519e6e5 ER |
4560 | #endif |
4561 | { FDEVENT_HANDLER_UNSET, NULL } | |
4562 | }; | |
4563 | - | |
4564 | ||
4565 | - if (buffer_is_empty(s->document_root)) { | |
4566 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
4567 | - "a default document-root has to be set"); | |
4568 | - | |
4569 | - return -1; | |
4570 | - } | |
4571 | - | |
4572 | + | |
4573 | + if (buffer_is_empty(s->document_root)) { | |
4574 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
4575 | + "a default document-root has to be set"); | |
4576 | + | |
4577 | + return -1; | |
4578 | + } | |
4579 | + | |
f26f9fd5 | 4580 | if (buffer_is_empty(srv->srvconf.changeroot)) { |
2519e6e5 | 4581 | - if (-1 == stat(s->document_root->ptr, &st1)) { |
f26f9fd5 | 4582 | - log_error_write(srv, __FILE__, __LINE__, "sb", |
2519e6e5 ER |
4583 | + pathname_unix2local(s->document_root); |
4584 | + if (-1 == stat(s->document_root->ptr, &st1)) { | |
f26f9fd5 ER |
4585 | + log_error_write(srv, __FILE__, __LINE__, "sbs", |
4586 | "base-docroot doesn't exist:", | |
4587 | - s->document_root); | |
4588 | + s->document_root, strerror(errno)); | |
4589 | return -1; | |
f673a614 | 4590 | } |
f673a614 | 4591 | |
1175ccec | 4592 | @@ -1088,18 +1086,18 @@ |
2519e6e5 ER |
4593 | buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.changeroot); |
4594 | buffer_append_string_buffer(srv->tmp_buf, s->document_root); | |
4595 | ||
4596 | - if (-1 == stat(srv->tmp_buf->ptr, &st1)) { | |
4597 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
4598 | + if (-1 == stat(srv->tmp_buf->ptr, &st1)) { | |
4599 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
4600 | "base-docroot doesn't exist:", | |
4601 | - srv->tmp_buf); | |
4602 | + srv->tmp_buf); | |
4603 | return -1; | |
4604 | } | |
4605 | - | |
4606 | + | |
4607 | } | |
4608 | - | |
4609 | - buffer_copy_string_buffer(srv->tmp_buf, s->document_root); | |
4610 | ||
4611 | - buffer_to_lower(srv->tmp_buf); | |
4612 | + buffer_copy_string_buffer(srv->tmp_buf, s->document_root); | |
4613 | + | |
4614 | + buffer_to_lower(srv->tmp_buf); | |
4615 | ||
4616 | if (0 == stat(srv->tmp_buf->ptr, &st1)) { | |
4617 | int is_lower = 0; | |
1175ccec | 4618 | @@ -1107,68 +1105,68 @@ |
2519e6e5 ER |
4619 | is_lower = buffer_is_equal(srv->tmp_buf, s->document_root); |
4620 | ||
4621 | /* lower-case existed, check upper-case */ | |
4622 | - buffer_copy_string_buffer(srv->tmp_buf, s->document_root); | |
4623 | + buffer_copy_string_buffer(srv->tmp_buf, s->document_root); | |
4624 | ||
4625 | - buffer_to_upper(srv->tmp_buf); | |
4626 | + buffer_to_upper(srv->tmp_buf); | |
4627 | ||
4628 | /* we have to handle the special case that upper and lower-casing results in the same filename | |
4629 | * as in server.document-root = "/" or "/12345/" */ | |
4630 | ||
4631 | if (is_lower && buffer_is_equal(srv->tmp_buf, s->document_root)) { | |
4632 | - /* lower-casing and upper-casing didn't result in | |
4633 | - * an other filename, no need to stat(), | |
4634 | + /* lower-casing and upper-casing didn't result in | |
4635 | + * an other filename, no need to stat(), | |
4636 | * just assume it is case-sensitive. */ | |
4637 | ||
4638 | s->force_lowercase_filenames = 0; | |
4639 | - } else if (0 == stat(srv->tmp_buf->ptr, &st2)) { | |
4640 | + } else if (0 == stat(srv->tmp_buf->ptr, &st2)) { | |
4641 | + | |
4642 | + /* upper case exists too, doesn't the FS handle this ? */ | |
4643 | + | |
4644 | + /* upper and lower have the same inode -> case-insensitve FS */ | |
4645 | + | |
4646 | + if (st1.st_ino == st2.st_ino) { | |
4647 | + /* upper and lower have the same inode -> case-insensitve FS */ | |
4648 | + | |
4649 | + s->force_lowercase_filenames = 1; | |
4650 | + } | |
4651 | + } | |
4652 | + } | |
4653 | ||
4654 | - /* upper case exists too, doesn't the FS handle this ? */ | |
4655 | - | |
4656 | - /* upper and lower have the same inode -> case-insensitve FS */ | |
4657 | - | |
4658 | - if (st1.st_ino == st2.st_ino) { | |
4659 | - /* upper and lower have the same inode -> case-insensitve FS */ | |
4660 | - | |
4661 | - s->force_lowercase_filenames = 1; | |
4662 | - } | |
4663 | - } | |
4664 | - } | |
4665 | - | |
4666 | if (srv->srvconf.port == 0) { | |
4667 | srv->srvconf.port = s->is_ssl ? 443 : 80; | |
4668 | } | |
4669 | - | |
4670 | + | |
4671 | if (srv->srvconf.event_handler->used == 0) { | |
4672 | /* choose a good default | |
4673 | - * | |
4674 | - * the event_handler list is sorted by 'goodness' | |
4675 | + * | |
4676 | + * the event_handler list is sorted by 'goodness' | |
4677 | * taking the first available should be the best solution | |
4678 | */ | |
4679 | srv->event_handler = event_handlers[0].et; | |
4680 | - | |
4681 | + | |
4682 | if (FDEVENT_HANDLER_UNSET == srv->event_handler) { | |
4683 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
4684 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
4685 | "sorry, there is no event handler for this system"); | |
4686 | - | |
4687 | + | |
4688 | return -1; | |
4689 | } | |
4690 | } else { | |
4691 | /* | |
4692 | * User override | |
4693 | */ | |
4694 | - | |
4695 | + | |
4696 | for (i = 0; event_handlers[i].name; i++) { | |
4697 | if (0 == strcmp(event_handlers[i].name, srv->srvconf.event_handler->ptr)) { | |
4698 | srv->event_handler = event_handlers[i].et; | |
4699 | break; | |
4700 | } | |
4701 | } | |
4702 | - | |
4703 | + | |
4704 | if (FDEVENT_HANDLER_UNSET == srv->event_handler) { | |
4705 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
4706 | - "the selected event-handler in unknown or not supported:", | |
4707 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
4708 | + "the selected event-handler in unknown or not supported:", | |
4709 | srv->srvconf.event_handler ); | |
4710 | - | |
4711 | + | |
4712 | return -1; | |
4713 | } | |
4714 | } | |
1175ccec | 4715 | @@ -1176,19 +1174,19 @@ |
2519e6e5 ER |
4716 | if (s->is_ssl) { |
4717 | if (buffer_is_empty(s->ssl_pemfile)) { | |
4718 | /* PEM file is require */ | |
4719 | - | |
4720 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
4721 | + | |
4722 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
4723 | "ssl.pemfile has to be set"); | |
4724 | return -1; | |
4725 | } | |
4726 | - | |
4727 | + | |
4728 | #ifndef USE_OPENSSL | |
4729 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
4730 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
4731 | "ssl support is missing, recompile with --with-openssl"); | |
4732 | - | |
4733 | + | |
4734 | return -1; | |
4735 | #endif | |
4736 | } | |
4737 | - | |
4738 | + | |
4739 | return 0; | |
4740 | } | |
1175ccec | 4741 | --- ../lighttpd-1.4.11/src/configfile.h 2005-08-23 17:36:12.000000000 +0300 |
36e2a29e | 4742 | +++ lighttpd-1.4.12/src/configfile.h 2006-07-11 22:07:51.000000000 +0300 |
f26f9fd5 ER |
4743 | @@ -9,7 +9,7 @@ |
4744 | server *srv; | |
4745 | int ok; | |
4746 | array *all_configs; | |
4747 | - array *configs_stack; /* to parse nested block */ | |
4748 | + buffer_ptr *configs_stack; /* to parse nested block */ | |
4749 | data_config *current; /* current started with { */ | |
4750 | buffer *basedir; | |
4751 | } config_t; | |
1175ccec | 4752 | --- ../lighttpd-1.4.11/src/configparser.c 2006-02-01 19:51:15.000000000 +0200 |
36e2a29e | 4753 | +++ lighttpd-1.4.12/src/configparser.c 2006-07-11 22:08:02.000000000 +0300 |
2519e6e5 | 4754 | @@ -24,52 +24,34 @@ |
f26f9fd5 ER |
4755 | dc->parent = ctx->current; |
4756 | array_insert_unique(dc->parent->childs, (data_unset *)dc); | |
4757 | } | |
4758 | - array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current); | |
4759 | + buffer_ptr_append(ctx->configs_stack, (void *)ctx->current); | |
4760 | ctx->current = dc; | |
4761 | } | |
f673a614 | 4762 | |
f26f9fd5 ER |
4763 | static data_config *configparser_pop(config_t *ctx) { |
4764 | data_config *old = ctx->current; | |
4765 | - ctx->current = (data_config *) array_pop(ctx->configs_stack); | |
4766 | + ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack); | |
4767 | return old; | |
f673a614 ER |
4768 | } |
4769 | ||
f26f9fd5 ER |
4770 | /* return a copied variable */ |
4771 | static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) { | |
4772 | - if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) { | |
4773 | - char *env; | |
4774 | - | |
4775 | - if (NULL != (env = getenv(key->ptr + 4))) { | |
4776 | - data_string *ds; | |
4777 | - ds = data_string_init(); | |
4778 | - buffer_append_string(ds->value, env); | |
4779 | - return (data_unset *)ds; | |
4780 | - } | |
4781 | - | |
4782 | - fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4); | |
4783 | - ctx->ok = 0; | |
4784 | - | |
4785 | - return NULL; | |
4786 | - } else { | |
2519e6e5 ER |
4787 | - data_unset *du; |
4788 | - data_config *dc; | |
4789 | + data_unset *du; | |
4790 | + data_config *dc; | |
f673a614 | 4791 | |
2519e6e5 ER |
4792 | #if 0 |
4793 | - fprintf(stderr, "get var %s\n", key->ptr); | |
4794 | + fprintf(stderr, "get var %s\n", key->ptr); | |
4795 | #endif | |
4796 | - for (dc = ctx->current; dc; dc = dc->parent) { | |
4797 | + for (dc = ctx->current; dc; dc = dc->parent) { | |
4798 | #if 0 | |
4799 | - fprintf(stderr, "get var on block: %s\n", dc->key->ptr); | |
4800 | - array_print(dc->value, 0); | |
4801 | + fprintf(stderr, "get var on block: %s\n", dc->key->ptr); | |
4802 | + array_print(dc->value, 0); | |
4803 | #endif | |
4804 | - if (NULL != (du = array_get_element(dc->value, key->ptr))) { | |
4805 | - return du->copy(du); | |
4806 | - } | |
4807 | + if (NULL != (du = array_get_element(dc->value, key->ptr))) { | |
4808 | + return du->copy(du); | |
f26f9fd5 ER |
4809 | } |
4810 | - fprintf(stderr, "Undefined config variable: %s\n", key->ptr); | |
4811 | - ctx->ok = 0; | |
2519e6e5 | 4812 | - return NULL; |
f26f9fd5 | 4813 | } |
2519e6e5 ER |
4814 | + return NULL; |
4815 | } | |
f673a614 | 4816 | |
f26f9fd5 | 4817 | /* op1 is to be eat/return by this function, op1->key is not cared |
2519e6e5 ER |
4818 | @@ -124,14 +106,14 @@ |
4819 | } | |
f673a614 | 4820 | |
2519e6e5 ER |
4821 | |
4822 | -#line 128 "configparser.c" | |
4823 | +#line 110 "configparser.c" | |
4824 | /* Next is all token values, in a form suitable for use by makeheaders. | |
4825 | ** This section will be null unless lemon is run with the -m switch. | |
4826 | */ | |
4827 | -/* | |
4828 | +/* | |
4829 | ** These constants (all generated automatically by the parser generator) | |
4830 | ** specify the various kinds of tokens (terminals) that the parser | |
4831 | -** understands. | |
4832 | +** understands. | |
4833 | ** | |
4834 | ** Each symbol here is a terminal symbol in the grammar. | |
4835 | */ | |
4836 | @@ -148,7 +130,7 @@ | |
4837 | ** and nonterminals. "int" is used otherwise. | |
4838 | ** YYNOCODE is a number of type YYCODETYPE which corresponds | |
4839 | ** to no legal terminal or nonterminal number. This | |
4840 | -** number is used to fill in empty slots of the hash | |
4841 | +** number is used to fill in empty slots of the hash | |
4842 | ** table. | |
4843 | ** YYFALLBACK If defined, this indicates that one or more tokens | |
4844 | ** have fall-back values which should be used if the | |
4845 | @@ -157,7 +139,7 @@ | |
4846 | ** and nonterminal numbers. "unsigned char" is | |
4847 | ** used if there are fewer than 250 rules and | |
4848 | ** states combined. "int" is used otherwise. | |
4849 | -** configparserTOKENTYPE is the data type used for minor tokens given | |
4850 | +** configparserTOKENTYPE is the data type used for minor tokens given | |
4851 | ** directly to the parser from the tokenizer. | |
4852 | ** YYMINORTYPE is the data type used for all minor tokens. | |
4853 | ** This is typically a union of many types, one of | |
4854 | @@ -192,8 +174,8 @@ | |
4855 | #define configparserARG_PDECL ,config_t *ctx | |
4856 | #define configparserARG_FETCH config_t *ctx = yypParser->ctx | |
4857 | #define configparserARG_STORE yypParser->ctx = ctx | |
4858 | -#define YYNSTATE 62 | |
4859 | -#define YYNRULE 39 | |
4860 | +#define YYNSTATE 63 | |
4861 | +#define YYNRULE 40 | |
4862 | #define YYERRORSYMBOL 26 | |
4863 | #define YYERRSYMDT yy95 | |
4864 | #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) | |
4865 | @@ -203,7 +185,7 @@ | |
4866 | /* Next are that tables used to determine what action to take based on the | |
4867 | ** current state and lookahead token. These tables are used to implement | |
4868 | ** functions that take a state number and lookahead value and return an | |
4869 | -** action integer. | |
4870 | +** action integer. | |
4871 | ** | |
4872 | ** Suppose the action integer is N. Then the action is determined as | |
4873 | ** follows | |
4874 | @@ -228,7 +210,7 @@ | |
4875 | ** If the index value yy_shift_ofst[S]+X is out of range or if the value | |
4876 | ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] | |
4877 | ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table | |
4878 | -** and that yy_default[S] should be used instead. | |
4879 | +** and that yy_default[S] should be used instead. | |
4880 | ** | |
4881 | ** The formula above is for computing the action when the lookahead is | |
4882 | ** a terminal symbol. If the lookahead is a non-terminal (as occurs after | |
4883 | @@ -248,67 +230,69 @@ | |
4884 | ** yy_default[] Default action for each state. | |
4885 | */ | |
4886 | static YYACTIONTYPE yy_action[] = { | |
4887 | - /* 0 */ 2, 3, 4, 5, 13, 14, 62, 15, 7, 44, | |
4888 | - /* 10 */ 20, 86, 16, 45, 28, 48, 40, 10, 39, 25, | |
4889 | - /* 20 */ 22, 49, 45, 8, 15, 102, 1, 20, 28, 18, | |
4890 | - /* 30 */ 57, 59, 19, 25, 22, 39, 19, 61, 98, 45, | |
4891 | - /* 40 */ 20, 6, 23, 24, 26, 28, 35, 57, 59, 12, | |
4892 | - /* 50 */ 25, 22, 28, 27, 36, 87, 29, 25, 22, 33, | |
4893 | - /* 60 */ 15, 30, 31, 20, 28, 38, 9, 17, 37, 25, | |
4894 | - /* 70 */ 22, 39, 42, 43, 10, 45, 11, 53, 54, 55, | |
4895 | - /* 80 */ 56, 28, 52, 57, 59, 34, 25, 22, 28, 27, | |
4896 | - /* 90 */ 32, 88, 41, 25, 22, 33, 28, 48, 46, 28, | |
4897 | - /* 100 */ 48, 25, 22, 58, 25, 22, 60, 21, 19, 47, | |
4898 | - /* 110 */ 51, 50, 25, 22, 88, 88, 93, | |
4899 | + /* 0 */ 2, 3, 4, 5, 13, 14, 63, 15, 7, 45, | |
4900 | + /* 10 */ 20, 88, 16, 46, 28, 49, 41, 10, 40, 25, | |
4901 | + /* 20 */ 22, 50, 46, 8, 15, 104, 1, 20, 28, 18, | |
4902 | + /* 30 */ 58, 60, 6, 25, 22, 40, 47, 62, 11, 46, | |
4903 | + /* 40 */ 20, 9, 23, 24, 26, 29, 89, 58, 60, 10, | |
4904 | + /* 50 */ 17, 38, 28, 27, 37, 19, 30, 25, 22, 34, | |
4905 | + /* 60 */ 15, 100, 20, 20, 23, 24, 26, 12, 19, 31, | |
4906 | + /* 70 */ 32, 40, 19, 44, 43, 46, 95, 35, 90, 89, | |
4907 | + /* 80 */ 28, 49, 42, 58, 60, 25, 22, 59, 28, 27, | |
4908 | + /* 90 */ 33, 48, 52, 25, 22, 34, 28, 49, 51, 28, | |
4909 | + /* 100 */ 36, 25, 22, 61, 25, 22, 89, 28, 39, 89, | |
4910 | + /* 110 */ 89, 89, 25, 22, 54, 55, 56, 57, 89, 28, | |
4911 | + /* 120 */ 53, 21, 89, 89, 25, 22, 25, 22, | |
4912 | }; | |
4913 | static YYCODETYPE yy_lookahead[] = { | |
4914 | /* 0 */ 29, 30, 31, 32, 33, 34, 0, 1, 44, 38, | |
4915 | /* 10 */ 4, 15, 41, 16, 35, 36, 45, 46, 12, 40, | |
4916 | /* 20 */ 41, 42, 16, 15, 1, 27, 28, 4, 35, 36, | |
4917 | - /* 30 */ 24, 25, 5, 40, 41, 12, 5, 14, 11, 16, | |
4918 | - /* 40 */ 4, 1, 6, 7, 8, 35, 36, 24, 25, 28, | |
4919 | - /* 50 */ 40, 41, 35, 36, 37, 15, 39, 40, 41, 42, | |
4920 | - /* 60 */ 1, 9, 10, 4, 35, 36, 38, 2, 3, 40, | |
4921 | - /* 70 */ 41, 12, 28, 14, 46, 16, 13, 20, 21, 22, | |
4922 | - /* 80 */ 23, 35, 36, 24, 25, 11, 40, 41, 35, 36, | |
4923 | - /* 90 */ 37, 13, 13, 40, 41, 42, 35, 36, 17, 35, | |
4924 | - /* 100 */ 36, 40, 41, 42, 40, 41, 42, 35, 5, 18, | |
4925 | - /* 110 */ 43, 19, 40, 41, 47, 47, 13, | |
4926 | + /* 30 */ 24, 25, 1, 40, 41, 12, 17, 14, 13, 16, | |
4927 | + /* 40 */ 4, 38, 6, 7, 8, 9, 15, 24, 25, 46, | |
4928 | + /* 50 */ 2, 3, 35, 36, 37, 5, 39, 40, 41, 42, | |
4929 | + /* 60 */ 1, 11, 4, 4, 6, 7, 8, 28, 5, 9, | |
4930 | + /* 70 */ 10, 12, 5, 14, 28, 16, 13, 11, 13, 47, | |
4931 | + /* 80 */ 35, 36, 13, 24, 25, 40, 41, 42, 35, 36, | |
4932 | + /* 90 */ 37, 18, 43, 40, 41, 42, 35, 36, 19, 35, | |
4933 | + /* 100 */ 36, 40, 41, 42, 40, 41, 47, 35, 36, 47, | |
4934 | + /* 110 */ 47, 47, 40, 41, 20, 21, 22, 23, 47, 35, | |
4935 | + /* 120 */ 36, 35, 47, 47, 40, 41, 40, 41, | |
4936 | }; | |
4937 | #define YY_SHIFT_USE_DFLT (-5) | |
4938 | static signed char yy_shift_ofst[] = { | |
4939 | - /* 0 */ -5, 6, -5, -5, -5, 40, -4, 8, -3, -5, | |
4940 | - /* 10 */ 63, -5, 23, -5, -5, -5, 65, 36, 31, 36, | |
4941 | - /* 20 */ -5, -5, -5, -5, -5, -5, 36, 27, -5, 52, | |
4942 | - /* 30 */ -5, 36, -5, 74, 36, 31, -5, 36, 31, 78, | |
4943 | - /* 40 */ 79, -5, 59, -5, -5, 81, 91, 36, 31, 92, | |
4944 | - /* 50 */ 57, 36, 103, -5, -5, -5, -5, 36, -5, 36, | |
4945 | - /* 60 */ -5, -5, | |
4946 | + /* 0 */ -5, 6, -5, -5, -5, 31, -4, 8, -3, -5, | |
4947 | + /* 10 */ 25, -5, 23, -5, -5, -5, 48, 58, 67, 58, | |
4948 | + /* 20 */ -5, -5, -5, -5, -5, -5, 36, 50, -5, -5, | |
4949 | + /* 30 */ 60, -5, 58, -5, 66, 58, 67, -5, 58, 67, | |
4950 | + /* 40 */ 65, 69, -5, 59, -5, -5, 19, 73, 58, 67, | |
4951 | + /* 50 */ 79, 94, 58, 63, -5, -5, -5, -5, 58, -5, | |
4952 | + /* 60 */ 58, -5, -5, | |
4953 | }; | |
4954 | #define YY_REDUCE_USE_DFLT (-37) | |
4955 | static signed char yy_reduce_ofst[] = { | |
4956 | - /* 0 */ -2, -29, -37, -37, -37, -36, -37, -37, 28, -37, | |
4957 | - /* 10 */ -37, 21, -29, -37, -37, -37, -37, -7, -37, 72, | |
4958 | + /* 0 */ -2, -29, -37, -37, -37, -36, -37, -37, 3, -37, | |
4959 | + /* 10 */ -37, 39, -29, -37, -37, -37, -37, -7, -37, 86, | |
4960 | /* 20 */ -37, -37, -37, -37, -37, -37, 17, -37, -37, -37, | |
4961 | - /* 30 */ -37, 53, -37, -37, 10, -37, -37, 29, -37, -37, | |
4962 | - /* 40 */ -37, 44, -29, -37, -37, -37, -37, -21, -37, -37, | |
4963 | - /* 50 */ 67, 46, -37, -37, -37, -37, -37, 61, -37, 64, | |
4964 | - /* 60 */ -37, -37, | |
4965 | + /* 30 */ -37, -37, 53, -37, -37, 64, -37, -37, 72, -37, | |
4966 | + /* 40 */ -37, -37, 46, -29, -37, -37, -37, -37, -21, -37, | |
4967 | + /* 50 */ -37, 49, 84, -37, -37, -37, -37, -37, 45, -37, | |
4968 | + /* 60 */ 61, -37, -37, | |
4969 | }; | |
4970 | static YYACTIONTYPE yy_default[] = { | |
4971 | - /* 0 */ 64, 101, 63, 65, 66, 101, 67, 101, 101, 90, | |
4972 | - /* 10 */ 101, 64, 101, 68, 69, 70, 101, 101, 71, 101, | |
4973 | - /* 20 */ 73, 74, 76, 77, 78, 79, 101, 84, 75, 101, | |
4974 | - /* 30 */ 80, 82, 81, 101, 101, 85, 83, 101, 72, 101, | |
4975 | - /* 40 */ 101, 64, 101, 89, 91, 101, 101, 101, 98, 101, | |
4976 | - /* 50 */ 101, 101, 101, 94, 95, 96, 97, 101, 99, 101, | |
4977 | - /* 60 */ 100, 92, | |
4978 | + /* 0 */ 65, 103, 64, 66, 67, 103, 68, 103, 103, 92, | |
4979 | + /* 10 */ 103, 65, 103, 69, 70, 71, 103, 103, 72, 103, | |
4980 | + /* 20 */ 74, 75, 77, 78, 79, 80, 103, 86, 76, 81, | |
4981 | + /* 30 */ 103, 82, 84, 83, 103, 103, 87, 85, 103, 73, | |
4982 | + /* 40 */ 103, 103, 65, 103, 91, 93, 103, 103, 103, 100, | |
4983 | + /* 50 */ 103, 103, 103, 103, 96, 97, 98, 99, 103, 101, | |
4984 | + /* 60 */ 103, 102, 94, | |
4985 | }; | |
4986 | #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) | |
4987 | ||
4988 | /* The next table maps tokens into fallback tokens. If a construct | |
4989 | ** like the following: | |
4990 | -** | |
4991 | +** | |
4992 | ** %fallback ID X Y Z. | |
4993 | ** | |
4994 | ** appears in the grammer, then ID becomes a fallback token for X, Y, | |
4995 | @@ -359,10 +343,10 @@ | |
4996 | #endif /* NDEBUG */ | |
4997 | ||
4998 | #ifndef NDEBUG | |
4999 | -/* | |
5000 | +/* | |
5001 | ** Turn parser tracing on by giving a stream to which to write the trace | |
5002 | ** and a prompt to preface each trace message. Tracing is turned off | |
5003 | -** by making either argument NULL | |
5004 | +** by making either argument NULL | |
5005 | ** | |
5006 | ** Inputs: | |
5007 | ** <ul> | |
5008 | @@ -387,7 +371,7 @@ | |
5009 | #ifndef NDEBUG | |
5010 | /* For tracing shifts, the names of all terminals and nonterminals | |
5011 | ** are required. The following table supplies these names */ | |
5012 | -static const char *yyTokenName[] = { | |
5013 | +static const char *yyTokenName[] = { | |
5014 | "$", "EOL", "ASSIGN", "APPEND", | |
5015 | "LKEY", "PLUS", "STRING", "INTEGER", | |
5016 | "LPARAN", "RPARAN", "COMMA", "ARRAY_ASSIGN", | |
5017 | @@ -425,27 +409,28 @@ | |
5018 | /* 15 */ "value ::= STRING", | |
5019 | /* 16 */ "value ::= INTEGER", | |
5020 | /* 17 */ "value ::= array", | |
5021 | - /* 18 */ "array ::= LPARAN aelements RPARAN", | |
5022 | - /* 19 */ "aelements ::= aelements COMMA aelement", | |
5023 | - /* 20 */ "aelements ::= aelements COMMA", | |
5024 | - /* 21 */ "aelements ::= aelement", | |
5025 | - /* 22 */ "aelement ::= expression", | |
5026 | - /* 23 */ "aelement ::= stringop ARRAY_ASSIGN expression", | |
5027 | - /* 24 */ "eols ::= EOL", | |
5028 | - /* 25 */ "eols ::=", | |
5029 | - /* 26 */ "globalstart ::= GLOBAL", | |
5030 | - /* 27 */ "global ::= globalstart LCURLY metalines RCURLY", | |
5031 | - /* 28 */ "condlines ::= condlines eols ELSE condline", | |
5032 | - /* 29 */ "condlines ::= condline", | |
5033 | - /* 30 */ "condline ::= context LCURLY metalines RCURLY", | |
5034 | - /* 31 */ "context ::= DOLLAR SRVVARNAME LBRACKET stringop RBRACKET cond expression", | |
5035 | - /* 32 */ "cond ::= EQ", | |
5036 | - /* 33 */ "cond ::= MATCH", | |
5037 | - /* 34 */ "cond ::= NE", | |
5038 | - /* 35 */ "cond ::= NOMATCH", | |
5039 | - /* 36 */ "stringop ::= expression", | |
5040 | - /* 37 */ "include ::= INCLUDE stringop", | |
5041 | - /* 38 */ "include_shell ::= INCLUDE_SHELL stringop", | |
5042 | + /* 18 */ "array ::= LPARAN RPARAN", | |
5043 | + /* 19 */ "array ::= LPARAN aelements RPARAN", | |
5044 | + /* 20 */ "aelements ::= aelements COMMA aelement", | |
5045 | + /* 21 */ "aelements ::= aelements COMMA", | |
5046 | + /* 22 */ "aelements ::= aelement", | |
5047 | + /* 23 */ "aelement ::= expression", | |
5048 | + /* 24 */ "aelement ::= stringop ARRAY_ASSIGN expression", | |
5049 | + /* 25 */ "eols ::= EOL", | |
5050 | + /* 26 */ "eols ::=", | |
5051 | + /* 27 */ "globalstart ::= GLOBAL", | |
5052 | + /* 28 */ "global ::= globalstart LCURLY metalines RCURLY", | |
5053 | + /* 29 */ "condlines ::= condlines eols ELSE condline", | |
5054 | + /* 30 */ "condlines ::= condline", | |
5055 | + /* 31 */ "condline ::= context LCURLY metalines RCURLY", | |
5056 | + /* 32 */ "context ::= DOLLAR SRVVARNAME LBRACKET stringop RBRACKET cond expression", | |
5057 | + /* 33 */ "cond ::= EQ", | |
5058 | + /* 34 */ "cond ::= MATCH", | |
5059 | + /* 35 */ "cond ::= NE", | |
5060 | + /* 36 */ "cond ::= NOMATCH", | |
5061 | + /* 37 */ "stringop ::= expression", | |
5062 | + /* 38 */ "include ::= INCLUDE stringop", | |
5063 | + /* 39 */ "include_shell ::= INCLUDE_SHELL stringop", | |
5064 | }; | |
5065 | #endif /* NDEBUG */ | |
5066 | ||
5067 | @@ -465,7 +450,7 @@ | |
5068 | #endif | |
5069 | } | |
5070 | ||
5071 | -/* | |
5072 | +/* | |
5073 | ** This function allocates a new parser. | |
5074 | ** The only argument is a pointer to a function which works like | |
5075 | ** malloc. | |
5076 | @@ -496,7 +481,7 @@ | |
5077 | /* Here is inserted the actions which take place when a | |
5078 | ** terminal or non-terminal is destroyed. This can happen | |
5079 | ** when the symbol is popped from the stack during a | |
5080 | - ** reduce or during error processing or when a parser is | |
5081 | + ** reduce or during error processing or when a parser is | |
5082 | ** being destroyed before it is finished parsing. | |
5083 | ** | |
5084 | ** Note: during a reduce, the only symbols destroyed are those | |
5085 | @@ -528,44 +513,44 @@ | |
5086 | case 23: | |
5087 | case 24: | |
5088 | case 25: | |
5089 | -#line 160 "./configparser.y" | |
5090 | +#line 143 "./configparser.y" | |
5091 | { buffer_free((yypminor->yy0)); } | |
5092 | -#line 533 "configparser.c" | |
5093 | +#line 518 "configparser.c" | |
5094 | break; | |
5095 | case 35: | |
5096 | -#line 151 "./configparser.y" | |
5097 | +#line 134 "./configparser.y" | |
5098 | { (yypminor->yy41)->free((yypminor->yy41)); } | |
5099 | -#line 538 "configparser.c" | |
5100 | +#line 523 "configparser.c" | |
5101 | break; | |
5102 | case 36: | |
5103 | -#line 152 "./configparser.y" | |
5104 | +#line 135 "./configparser.y" | |
5105 | { (yypminor->yy41)->free((yypminor->yy41)); } | |
5106 | -#line 543 "configparser.c" | |
5107 | +#line 528 "configparser.c" | |
5108 | break; | |
5109 | case 37: | |
5110 | -#line 153 "./configparser.y" | |
5111 | +#line 136 "./configparser.y" | |
5112 | { (yypminor->yy41)->free((yypminor->yy41)); } | |
5113 | -#line 548 "configparser.c" | |
5114 | +#line 533 "configparser.c" | |
5115 | break; | |
5116 | case 39: | |
5117 | -#line 154 "./configparser.y" | |
5118 | +#line 137 "./configparser.y" | |
5119 | { array_free((yypminor->yy40)); } | |
5120 | -#line 553 "configparser.c" | |
5121 | +#line 538 "configparser.c" | |
5122 | break; | |
5123 | case 40: | |
5124 | -#line 155 "./configparser.y" | |
5125 | +#line 138 "./configparser.y" | |
5126 | { array_free((yypminor->yy40)); } | |
5127 | -#line 558 "configparser.c" | |
5128 | +#line 543 "configparser.c" | |
5129 | break; | |
5130 | case 41: | |
5131 | -#line 156 "./configparser.y" | |
5132 | +#line 139 "./configparser.y" | |
5133 | { buffer_free((yypminor->yy43)); } | |
5134 | -#line 563 "configparser.c" | |
5135 | +#line 548 "configparser.c" | |
5136 | break; | |
5137 | case 42: | |
5138 | -#line 157 "./configparser.y" | |
5139 | +#line 140 "./configparser.y" | |
5140 | { buffer_free((yypminor->yy43)); } | |
5141 | -#line 568 "configparser.c" | |
5142 | +#line 553 "configparser.c" | |
5143 | break; | |
5144 | default: break; /* If no destructor action specified: do nothing */ | |
5145 | } | |
5146 | @@ -597,7 +582,7 @@ | |
5147 | return yymajor; | |
5148 | } | |
5149 | ||
5150 | -/* | |
5151 | +/* | |
5152 | ** Deallocate and destroy a parser. Destructors are all called for | |
5153 | ** all stack elements before shutting the parser down. | |
5154 | ** | |
5155 | @@ -633,7 +618,7 @@ | |
5156 | ){ | |
5157 | int i; | |
5158 | int stateno = pParser->yystack[pParser->yyidx].stateno; | |
5159 | - | |
5160 | + | |
5161 | /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */ | |
5162 | i = yy_shift_ofst[stateno]; | |
5163 | if( i==YY_SHIFT_USE_DFLT ){ | |
5164 | @@ -677,7 +662,7 @@ | |
5165 | ){ | |
5166 | int i; | |
5167 | int stateno = pParser->yystack[pParser->yyidx].stateno; | |
5168 | - | |
5169 | + | |
5170 | i = yy_reduce_ofst[stateno]; | |
5171 | if( i==YY_REDUCE_USE_DFLT ){ | |
5172 | return yy_default[stateno]; | |
5173 | @@ -759,6 +744,7 @@ | |
5174 | { 35, 1 }, | |
5175 | { 35, 1 }, | |
5176 | { 35, 1 }, | |
5177 | + { 40, 2 }, | |
5178 | { 40, 3 }, | |
5179 | { 39, 3 }, | |
5180 | { 39, 2 }, | |
5181 | @@ -800,7 +786,7 @@ | |
5182 | configparserARG_FETCH; | |
5183 | yymsp = &yypParser->yystack[yypParser->yyidx]; | |
5184 | #ifndef NDEBUG | |
5185 | - if( yyTraceFILE && yyruleno>=0 | |
5186 | + if( yyTraceFILE && yyruleno>=0 | |
5187 | && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){ | |
5188 | fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, | |
5189 | yyRuleName[yyruleno]); | |
5190 | @@ -832,9 +818,9 @@ | |
5191 | /* No destructor defined for global */ | |
5192 | break; | |
5193 | case 5: | |
5194 | -#line 134 "./configparser.y" | |
5195 | +#line 116 "./configparser.y" | |
5196 | { yymsp[-1].minor.yy78 = NULL; } | |
5197 | -#line 837 "configparser.c" | |
5198 | +#line 823 "configparser.c" | |
5199 | yy_destructor(1,&yymsp[0].minor); | |
5200 | break; | |
5201 | case 6: | |
5202 | @@ -847,10 +833,15 @@ | |
5203 | yy_destructor(1,&yymsp[0].minor); | |
5204 | break; | |
5205 | case 9: | |
5206 | -#line 162 "./configparser.y" | |
5207 | +#line 145 "./configparser.y" | |
5208 | { | |
5209 | buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43); | |
5210 | - if (NULL == array_get_element(ctx->current->value, yymsp[0].minor.yy41->key->ptr)) { | |
5211 | + if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) { | |
f26f9fd5 ER |
5212 | + fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n", |
5213 | + ctx->current->context_ndx, | |
2519e6e5 | 5214 | + ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr); |
f26f9fd5 | 5215 | + ctx->ok = 0; |
2519e6e5 ER |
5216 | + } else if (NULL == array_get_element(ctx->current->value, yymsp[0].minor.yy41->key->ptr)) { |
5217 | array_insert_unique(ctx->current->value, yymsp[0].minor.yy41); | |
5218 | yymsp[0].minor.yy41 = NULL; | |
f26f9fd5 | 5219 | } else { |
2519e6e5 ER |
5220 | @@ -864,16 +855,21 @@ |
5221 | buffer_free(yymsp[-2].minor.yy43); | |
5222 | yymsp[-2].minor.yy43 = NULL; | |
5223 | } | |
5224 | -#line 867 "configparser.c" | |
5225 | +#line 858 "configparser.c" | |
5226 | yy_destructor(2,&yymsp[-1].minor); | |
5227 | break; | |
5228 | case 10: | |
5229 | -#line 179 "./configparser.y" | |
5230 | +#line 167 "./configparser.y" | |
5231 | { | |
f26f9fd5 ER |
5232 | array *vars = ctx->current->value; |
5233 | data_unset *du; | |
f673a614 | 5234 | |
2519e6e5 ER |
5235 | - if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) { |
5236 | + if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) { | |
f26f9fd5 ER |
5237 | + fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n", |
5238 | + ctx->current->context_ndx, | |
2519e6e5 | 5239 | + ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr); |
f26f9fd5 | 5240 | + ctx->ok = 0; |
2519e6e5 | 5241 | + } else if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) { |
f26f9fd5 | 5242 | /* exists in current block */ |
2519e6e5 | 5243 | du = configparser_merge_data(du, yymsp[0].minor.yy41); |
f26f9fd5 | 5244 | if (NULL == du) { |
2519e6e5 ER |
5245 | @@ -883,6 +879,7 @@ |
5246 | buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43); | |
f26f9fd5 ER |
5247 | array_replace(vars, du); |
5248 | } | |
2519e6e5 ER |
5249 | + yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); |
5250 | } else if (NULL != (du = configparser_get_variable(ctx, yymsp[-2].minor.yy43))) { | |
5251 | du = configparser_merge_data(du, yymsp[0].minor.yy41); | |
f26f9fd5 | 5252 | if (NULL == du) { |
2519e6e5 ER |
5253 | @@ -892,22 +889,20 @@ |
5254 | buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43); | |
f26f9fd5 ER |
5255 | array_insert_unique(ctx->current->value, du); |
5256 | } | |
2519e6e5 | 5257 | + yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); |
f26f9fd5 ER |
5258 | } else { |
5259 | - fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", | |
5260 | - ctx->current->context_ndx, | |
2519e6e5 | 5261 | - ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr); |
f26f9fd5 | 5262 | - ctx->ok = 0; |
2519e6e5 ER |
5263 | + buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43); |
5264 | + array_insert_unique(ctx->current->value, yymsp[0].minor.yy41); | |
f26f9fd5 | 5265 | } |
2519e6e5 ER |
5266 | buffer_free(yymsp[-2].minor.yy43); |
5267 | yymsp[-2].minor.yy43 = NULL; | |
5268 | - yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); | |
5269 | yymsp[0].minor.yy41 = NULL; | |
f673a614 | 5270 | } |
2519e6e5 ER |
5271 | -#line 906 "configparser.c" |
5272 | +#line 901 "configparser.c" | |
5273 | yy_destructor(3,&yymsp[-1].minor); | |
5274 | break; | |
5275 | case 11: | |
5276 | -#line 214 "./configparser.y" | |
5277 | +#line 206 "./configparser.y" | |
5278 | { | |
5279 | if (strchr(yymsp[0].minor.yy0->ptr, '.') == NULL) { | |
5280 | yygotominor.yy43 = buffer_init_string("var."); | |
5281 | @@ -919,10 +914,10 @@ | |
5282 | yymsp[0].minor.yy0 = NULL; | |
5283 | } | |
f26f9fd5 | 5284 | } |
2519e6e5 ER |
5285 | -#line 922 "configparser.c" |
5286 | +#line 917 "configparser.c" | |
5287 | break; | |
5288 | case 12: | |
5289 | -#line 226 "./configparser.y" | |
5290 | +#line 218 "./configparser.y" | |
5291 | { | |
5292 | yygotominor.yy41 = configparser_merge_data(yymsp[-2].minor.yy41, yymsp[0].minor.yy41); | |
5293 | if (NULL == yygotominor.yy41) { | |
5294 | @@ -932,21 +927,38 @@ | |
5295 | yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); | |
5296 | yymsp[0].minor.yy41 = NULL; | |
5297 | } | |
5298 | -#line 935 "configparser.c" | |
5299 | +#line 930 "configparser.c" | |
5300 | yy_destructor(5,&yymsp[-1].minor); | |
5301 | break; | |
5302 | case 13: | |
5303 | -#line 236 "./configparser.y" | |
5304 | +#line 228 "./configparser.y" | |
5305 | { | |
5306 | yygotominor.yy41 = yymsp[0].minor.yy41; | |
5307 | yymsp[0].minor.yy41 = NULL; | |
5308 | } | |
5309 | -#line 944 "configparser.c" | |
5310 | +#line 939 "configparser.c" | |
5311 | break; | |
5312 | case 14: | |
5313 | -#line 241 "./configparser.y" | |
5314 | +#line 233 "./configparser.y" | |
5315 | { | |
5316 | - yygotominor.yy41 = configparser_get_variable(ctx, yymsp[0].minor.yy43); | |
5317 | + if (strncmp(yymsp[0].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) { | |
f26f9fd5 | 5318 | + char *env; |
f673a614 | 5319 | + |
2519e6e5 | 5320 | + if (NULL != (env = getenv(yymsp[0].minor.yy43->ptr + 4))) { |
f26f9fd5 ER |
5321 | + data_string *ds; |
5322 | + ds = data_string_init(); | |
5323 | + buffer_append_string(ds->value, env); | |
2519e6e5 | 5324 | + yygotominor.yy41 = (data_unset *)ds; |
f26f9fd5 ER |
5325 | + } |
5326 | + else { | |
2519e6e5 ER |
5327 | + yygotominor.yy41 = NULL; |
5328 | + fprintf(stderr, "Undefined env variable: %s\n", yymsp[0].minor.yy43->ptr + 4); | |
f26f9fd5 ER |
5329 | + ctx->ok = 0; |
5330 | + } | |
2519e6e5 ER |
5331 | + } else if (NULL == (yygotominor.yy41 = configparser_get_variable(ctx, yymsp[0].minor.yy43))) { |
5332 | + fprintf(stderr, "Undefined config variable: %s\n", yymsp[0].minor.yy43->ptr); | |
f26f9fd5 ER |
5333 | + ctx->ok = 0; |
5334 | + } | |
2519e6e5 | 5335 | if (!yygotominor.yy41) { |
f26f9fd5 | 5336 | /* make a dummy so it won't crash */ |
2519e6e5 ER |
5337 | yygotominor.yy41 = (data_unset *)data_string_init(); |
5338 | @@ -954,50 +966,59 @@ | |
5339 | buffer_free(yymsp[0].minor.yy43); | |
5340 | yymsp[0].minor.yy43 = NULL; | |
f26f9fd5 | 5341 | } |
2519e6e5 ER |
5342 | -#line 957 "configparser.c" |
5343 | +#line 969 "configparser.c" | |
5344 | break; | |
5345 | case 15: | |
5346 | -#line 251 "./configparser.y" | |
5347 | +#line 260 "./configparser.y" | |
5348 | { | |
5349 | yygotominor.yy41 = (data_unset *)data_string_init(); | |
5350 | buffer_copy_string_buffer(((data_string *)(yygotominor.yy41))->value, yymsp[0].minor.yy0); | |
5351 | buffer_free(yymsp[0].minor.yy0); | |
5352 | yymsp[0].minor.yy0 = NULL; | |
5353 | } | |
5354 | -#line 967 "configparser.c" | |
5355 | +#line 979 "configparser.c" | |
5356 | break; | |
5357 | case 16: | |
5358 | -#line 258 "./configparser.y" | |
5359 | +#line 267 "./configparser.y" | |
5360 | { | |
5361 | yygotominor.yy41 = (data_unset *)data_integer_init(); | |
5362 | ((data_integer *)(yygotominor.yy41))->value = strtol(yymsp[0].minor.yy0->ptr, NULL, 10); | |
5363 | buffer_free(yymsp[0].minor.yy0); | |
5364 | yymsp[0].minor.yy0 = NULL; | |
5365 | } | |
5366 | -#line 977 "configparser.c" | |
5367 | +#line 989 "configparser.c" | |
5368 | break; | |
5369 | case 17: | |
5370 | -#line 264 "./configparser.y" | |
5371 | +#line 273 "./configparser.y" | |
5372 | { | |
5373 | yygotominor.yy41 = (data_unset *)data_array_init(); | |
5374 | array_free(((data_array *)(yygotominor.yy41))->value); | |
5375 | ((data_array *)(yygotominor.yy41))->value = yymsp[0].minor.yy40; | |
5376 | yymsp[0].minor.yy40 = NULL; | |
5377 | } | |
5378 | -#line 987 "configparser.c" | |
5379 | +#line 999 "configparser.c" | |
5380 | break; | |
5381 | case 18: | |
5382 | -#line 270 "./configparser.y" | |
5383 | +#line 279 "./configparser.y" | |
5384 | +{ | |
5385 | + yygotominor.yy40 = array_init(); | |
f26f9fd5 | 5386 | +} |
2519e6e5 ER |
5387 | +#line 1006 "configparser.c" |
5388 | + yy_destructor(8,&yymsp[-1].minor); | |
5389 | + yy_destructor(9,&yymsp[0].minor); | |
5390 | + break; | |
5391 | + case 19: | |
5392 | +#line 282 "./configparser.y" | |
5393 | { | |
5394 | yygotominor.yy40 = yymsp[-1].minor.yy40; | |
5395 | yymsp[-1].minor.yy40 = NULL; | |
5396 | } | |
5397 | -#line 995 "configparser.c" | |
5398 | +#line 1016 "configparser.c" | |
5399 | yy_destructor(8,&yymsp[-2].minor); | |
5400 | yy_destructor(9,&yymsp[0].minor); | |
5401 | break; | |
5402 | - case 19: | |
5403 | -#line 275 "./configparser.y" | |
5404 | + case 20: | |
5405 | +#line 287 "./configparser.y" | |
5406 | { | |
5407 | if (buffer_is_empty(yymsp[0].minor.yy41->key) || | |
5408 | NULL == array_get_element(yymsp[-2].minor.yy40, yymsp[0].minor.yy41->key->ptr)) { | |
5409 | @@ -1014,37 +1035,37 @@ | |
5410 | yygotominor.yy40 = yymsp[-2].minor.yy40; | |
5411 | yymsp[-2].minor.yy40 = NULL; | |
5412 | } | |
5413 | -#line 1017 "configparser.c" | |
5414 | +#line 1038 "configparser.c" | |
5415 | yy_destructor(10,&yymsp[-1].minor); | |
5416 | break; | |
5417 | - case 20: | |
5418 | -#line 292 "./configparser.y" | |
5419 | + case 21: | |
5420 | +#line 304 "./configparser.y" | |
5421 | { | |
5422 | yygotominor.yy40 = yymsp[-1].minor.yy40; | |
5423 | yymsp[-1].minor.yy40 = NULL; | |
5424 | } | |
5425 | -#line 1026 "configparser.c" | |
5426 | +#line 1047 "configparser.c" | |
5427 | yy_destructor(10,&yymsp[0].minor); | |
5428 | break; | |
5429 | - case 21: | |
5430 | -#line 297 "./configparser.y" | |
5431 | + case 22: | |
5432 | +#line 309 "./configparser.y" | |
5433 | { | |
5434 | yygotominor.yy40 = array_init(); | |
5435 | array_insert_unique(yygotominor.yy40, yymsp[0].minor.yy41); | |
5436 | yymsp[0].minor.yy41 = NULL; | |
5437 | } | |
5438 | -#line 1036 "configparser.c" | |
5439 | +#line 1057 "configparser.c" | |
5440 | break; | |
5441 | - case 22: | |
5442 | -#line 303 "./configparser.y" | |
5443 | + case 23: | |
5444 | +#line 315 "./configparser.y" | |
5445 | { | |
5446 | yygotominor.yy41 = yymsp[0].minor.yy41; | |
5447 | yymsp[0].minor.yy41 = NULL; | |
5448 | } | |
5449 | -#line 1044 "configparser.c" | |
5450 | +#line 1065 "configparser.c" | |
5451 | break; | |
5452 | - case 23: | |
5453 | -#line 307 "./configparser.y" | |
5454 | + case 24: | |
5455 | +#line 319 "./configparser.y" | |
5456 | { | |
5457 | buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43); | |
5458 | buffer_free(yymsp[-2].minor.yy43); | |
5459 | @@ -1053,27 +1074,27 @@ | |
5460 | yygotominor.yy41 = yymsp[0].minor.yy41; | |
5461 | yymsp[0].minor.yy41 = NULL; | |
5462 | } | |
5463 | -#line 1056 "configparser.c" | |
5464 | +#line 1077 "configparser.c" | |
5465 | yy_destructor(11,&yymsp[-1].minor); | |
5466 | break; | |
5467 | - case 24: | |
5468 | - yy_destructor(1,&yymsp[0].minor); | |
5469 | - break; | |
5470 | case 25: | |
5471 | + yy_destructor(1,&yymsp[0].minor); | |
5472 | break; | |
5473 | case 26: | |
5474 | -#line 319 "./configparser.y" | |
5475 | + break; | |
5476 | + case 27: | |
5477 | +#line 331 "./configparser.y" | |
5478 | { | |
5479 | data_config *dc; | |
5480 | dc = (data_config *)array_get_element(ctx->srv->config_context, "global"); | |
5481 | assert(dc); | |
5482 | configparser_push(ctx, dc, 0); | |
5483 | } | |
5484 | -#line 1072 "configparser.c" | |
5485 | +#line 1093 "configparser.c" | |
5486 | yy_destructor(12,&yymsp[0].minor); | |
5487 | break; | |
5488 | - case 27: | |
5489 | -#line 326 "./configparser.y" | |
5490 | + case 28: | |
5491 | +#line 338 "./configparser.y" | |
5492 | { | |
5493 | data_config *cur; | |
5494 | ||
5495 | @@ -1082,16 +1103,16 @@ | |
5496 | ||
5497 | assert(cur && ctx->current); | |
5498 | ||
5499 | - yygotominor.yy0 = cur; | |
5500 | + yygotominor.yy78 = cur; | |
5501 | } | |
5502 | -#line 1087 "configparser.c" | |
5503 | +#line 1108 "configparser.c" | |
5504 | /* No destructor defined for globalstart */ | |
5505 | yy_destructor(13,&yymsp[-2].minor); | |
5506 | /* No destructor defined for metalines */ | |
5507 | yy_destructor(14,&yymsp[0].minor); | |
5508 | break; | |
5509 | - case 28: | |
5510 | -#line 337 "./configparser.y" | |
5511 | + case 29: | |
5512 | +#line 349 "./configparser.y" | |
5513 | { | |
5514 | assert(yymsp[-3].minor.yy78->context_ndx < yymsp[0].minor.yy78->context_ndx); | |
5515 | yymsp[0].minor.yy78->prev = yymsp[-3].minor.yy78; | |
5516 | @@ -1100,20 +1121,20 @@ | |
5517 | yymsp[-3].minor.yy78 = NULL; | |
5518 | yymsp[0].minor.yy78 = NULL; | |
5519 | } | |
5520 | -#line 1103 "configparser.c" | |
5521 | +#line 1124 "configparser.c" | |
5522 | /* No destructor defined for eols */ | |
5523 | yy_destructor(15,&yymsp[-1].minor); | |
5524 | break; | |
5525 | - case 29: | |
5526 | -#line 346 "./configparser.y" | |
5527 | + case 30: | |
5528 | +#line 358 "./configparser.y" | |
5529 | { | |
5530 | yygotominor.yy78 = yymsp[0].minor.yy78; | |
5531 | yymsp[0].minor.yy78 = NULL; | |
5532 | } | |
5533 | -#line 1113 "configparser.c" | |
5534 | +#line 1134 "configparser.c" | |
5535 | break; | |
5536 | - case 30: | |
5537 | -#line 351 "./configparser.y" | |
5538 | + case 31: | |
5539 | +#line 363 "./configparser.y" | |
5540 | { | |
5541 | data_config *cur; | |
5542 | ||
5543 | @@ -1124,14 +1145,14 @@ | |
5544 | ||
5545 | yygotominor.yy78 = cur; | |
5546 | } | |
5547 | -#line 1127 "configparser.c" | |
5548 | +#line 1148 "configparser.c" | |
5549 | /* No destructor defined for context */ | |
5550 | yy_destructor(13,&yymsp[-2].minor); | |
5551 | /* No destructor defined for metalines */ | |
5552 | yy_destructor(14,&yymsp[0].minor); | |
5553 | break; | |
5554 | - case 31: | |
5555 | -#line 362 "./configparser.y" | |
5556 | + case 32: | |
5557 | +#line 374 "./configparser.y" | |
5558 | { | |
5559 | data_config *dc; | |
5560 | buffer *b, *rvalue, *op; | |
5561 | @@ -1266,45 +1287,45 @@ | |
5562 | yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); | |
5563 | yymsp[0].minor.yy41 = NULL; | |
5564 | } | |
5565 | -#line 1269 "configparser.c" | |
5566 | +#line 1290 "configparser.c" | |
5567 | yy_destructor(16,&yymsp[-6].minor); | |
5568 | yy_destructor(18,&yymsp[-4].minor); | |
5569 | yy_destructor(19,&yymsp[-2].minor); | |
5570 | break; | |
5571 | - case 32: | |
5572 | -#line 496 "./configparser.y" | |
5573 | + case 33: | |
5574 | +#line 508 "./configparser.y" | |
5575 | { | |
5576 | yygotominor.yy27 = CONFIG_COND_EQ; | |
5577 | } | |
5578 | -#line 1279 "configparser.c" | |
5579 | +#line 1300 "configparser.c" | |
5580 | yy_destructor(20,&yymsp[0].minor); | |
5581 | break; | |
5582 | - case 33: | |
5583 | -#line 499 "./configparser.y" | |
5584 | + case 34: | |
5585 | +#line 511 "./configparser.y" | |
5586 | { | |
5587 | yygotominor.yy27 = CONFIG_COND_MATCH; | |
5588 | } | |
5589 | -#line 1287 "configparser.c" | |
5590 | +#line 1308 "configparser.c" | |
5591 | yy_destructor(21,&yymsp[0].minor); | |
5592 | break; | |
5593 | - case 34: | |
5594 | -#line 502 "./configparser.y" | |
5595 | + case 35: | |
5596 | +#line 514 "./configparser.y" | |
5597 | { | |
5598 | yygotominor.yy27 = CONFIG_COND_NE; | |
5599 | } | |
5600 | -#line 1295 "configparser.c" | |
5601 | +#line 1316 "configparser.c" | |
5602 | yy_destructor(22,&yymsp[0].minor); | |
5603 | break; | |
5604 | - case 35: | |
5605 | -#line 505 "./configparser.y" | |
5606 | + case 36: | |
5607 | +#line 517 "./configparser.y" | |
5608 | { | |
5609 | yygotominor.yy27 = CONFIG_COND_NOMATCH; | |
5610 | } | |
5611 | -#line 1303 "configparser.c" | |
5612 | +#line 1324 "configparser.c" | |
5613 | yy_destructor(23,&yymsp[0].minor); | |
5614 | break; | |
5615 | - case 36: | |
5616 | -#line 509 "./configparser.y" | |
5617 | + case 37: | |
5618 | +#line 521 "./configparser.y" | |
5619 | { | |
5620 | yygotominor.yy43 = NULL; | |
5621 | if (ctx->ok) { | |
5622 | @@ -1321,10 +1342,10 @@ | |
5623 | yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); | |
5624 | yymsp[0].minor.yy41 = NULL; | |
5625 | } | |
5626 | -#line 1324 "configparser.c" | |
5627 | +#line 1345 "configparser.c" | |
5628 | break; | |
5629 | - case 37: | |
5630 | -#line 526 "./configparser.y" | |
5631 | + case 38: | |
5632 | +#line 538 "./configparser.y" | |
5633 | { | |
5634 | if (ctx->ok) { | |
5635 | if (0 != config_parse_file(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) { | |
5636 | @@ -1334,11 +1355,11 @@ | |
5637 | yymsp[0].minor.yy43 = NULL; | |
5638 | } | |
5639 | } | |
5640 | -#line 1337 "configparser.c" | |
5641 | +#line 1358 "configparser.c" | |
5642 | yy_destructor(24,&yymsp[-1].minor); | |
5643 | break; | |
5644 | - case 38: | |
5645 | -#line 536 "./configparser.y" | |
5646 | + case 39: | |
5647 | +#line 548 "./configparser.y" | |
5648 | { | |
5649 | if (ctx->ok) { | |
5650 | if (0 != config_parse_cmd(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) { | |
5651 | @@ -1348,7 +1369,7 @@ | |
5652 | yymsp[0].minor.yy43 = NULL; | |
5653 | } | |
5654 | } | |
5655 | -#line 1351 "configparser.c" | |
5656 | +#line 1372 "configparser.c" | |
5657 | yy_destructor(25,&yymsp[-1].minor); | |
5658 | break; | |
5659 | }; | |
5660 | @@ -1378,11 +1399,11 @@ | |
5661 | while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); | |
5662 | /* Here code is inserted which will be executed whenever the | |
5663 | ** parser fails */ | |
5664 | -#line 125 "./configparser.y" | |
5665 | +#line 107 "./configparser.y" | |
5666 | ||
5667 | ctx->ok = 0; | |
5668 | ||
5669 | -#line 1385 "configparser.c" | |
5670 | +#line 1406 "configparser.c" | |
5671 | configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */ | |
5672 | } | |
5673 | ||
5674 | @@ -1489,7 +1510,7 @@ | |
5675 | #ifdef YYERRORSYMBOL | |
5676 | /* A syntax error has occurred. | |
5677 | ** The response to an error depends upon whether or not the | |
5678 | - ** grammar defines an error token "ERROR". | |
5679 | + ** grammar defines an error token "ERROR". | |
5680 | ** | |
5681 | ** This is what we do if the grammar does define ERROR: | |
5682 | ** | |
1175ccec | 5683 | --- ../lighttpd-1.4.11/src/configparser.y 2006-01-26 18:46:25.000000000 +0200 |
36e2a29e | 5684 | +++ lighttpd-1.4.12/src/configparser.y 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
5685 | @@ -21,52 +21,34 @@ |
5686 | dc->parent = ctx->current; | |
5687 | array_insert_unique(dc->parent->childs, (data_unset *)dc); | |
5688 | } | |
5689 | - array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current); | |
5690 | + buffer_ptr_append(ctx->configs_stack, (void *)ctx->current); | |
5691 | ctx->current = dc; | |
5692 | } | |
5693 | ||
5694 | static data_config *configparser_pop(config_t *ctx) { | |
5695 | data_config *old = ctx->current; | |
5696 | - ctx->current = (data_config *) array_pop(ctx->configs_stack); | |
5697 | + ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack); | |
5698 | return old; | |
5699 | } | |
5700 | ||
5701 | /* return a copied variable */ | |
5702 | static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) { | |
5703 | - if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) { | |
5704 | - char *env; | |
5705 | - | |
5706 | - if (NULL != (env = getenv(key->ptr + 4))) { | |
5707 | - data_string *ds; | |
5708 | - ds = data_string_init(); | |
5709 | - buffer_append_string(ds->value, env); | |
5710 | - return (data_unset *)ds; | |
5711 | - } | |
5712 | - | |
5713 | - fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4); | |
5714 | - ctx->ok = 0; | |
5715 | - | |
5716 | - return NULL; | |
5717 | - } else { | |
5718 | - data_unset *du; | |
5719 | - data_config *dc; | |
5720 | + data_unset *du; | |
5721 | + data_config *dc; | |
5722 | ||
5723 | #if 0 | |
5724 | - fprintf(stderr, "get var %s\n", key->ptr); | |
5725 | + fprintf(stderr, "get var %s\n", key->ptr); | |
5726 | #endif | |
5727 | - for (dc = ctx->current; dc; dc = dc->parent) { | |
5728 | + for (dc = ctx->current; dc; dc = dc->parent) { | |
5729 | #if 0 | |
5730 | - fprintf(stderr, "get var on block: %s\n", dc->key->ptr); | |
5731 | - array_print(dc->value, 0); | |
5732 | + fprintf(stderr, "get var on block: %s\n", dc->key->ptr); | |
5733 | + array_print(dc->value, 0); | |
5734 | #endif | |
5735 | - if (NULL != (du = array_get_element(dc->value, key->ptr))) { | |
5736 | - return du->copy(du); | |
5737 | - } | |
5738 | + if (NULL != (du = array_get_element(dc->value, key->ptr))) { | |
5739 | + return du->copy(du); | |
5740 | } | |
5741 | - fprintf(stderr, "Undefined config variable: %s\n", key->ptr); | |
5742 | - ctx->ok = 0; | |
5743 | - return NULL; | |
5744 | } | |
5745 | + return NULL; | |
5746 | } | |
5747 | ||
5748 | /* op1 is to be eat/return by this function, op1->key is not cared | |
5749 | @@ -141,6 +123,7 @@ | |
5750 | %type aelement {data_unset *} | |
5751 | %type condline {data_config *} | |
5752 | %type condlines {data_config *} | |
5753 | +%type global {data_config *} | |
5754 | %type aelements {array *} | |
5755 | %type array {array *} | |
5756 | %type key {buffer *} | |
5757 | @@ -161,7 +144,12 @@ | |
5758 | ||
5759 | varline ::= key(A) ASSIGN expression(B). { | |
5760 | buffer_copy_string_buffer(B->key, A); | |
5761 | - if (NULL == array_get_element(ctx->current->value, B->key->ptr)) { | |
5762 | + if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) { | |
5763 | + fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n", | |
5764 | + ctx->current->context_ndx, | |
5765 | + ctx->current->key->ptr, A->ptr); | |
5766 | + ctx->ok = 0; | |
5767 | + } else if (NULL == array_get_element(ctx->current->value, B->key->ptr)) { | |
5768 | array_insert_unique(ctx->current->value, B); | |
5769 | B = NULL; | |
5770 | } else { | |
5771 | @@ -180,7 +168,12 @@ | |
5772 | array *vars = ctx->current->value; | |
5773 | data_unset *du; | |
5774 | ||
5775 | - if (NULL != (du = array_get_element(vars, A->ptr))) { | |
5776 | + if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) { | |
5777 | + fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n", | |
5778 | + ctx->current->context_ndx, | |
5779 | + ctx->current->key->ptr, A->ptr); | |
5780 | + ctx->ok = 0; | |
5781 | + } else if (NULL != (du = array_get_element(vars, A->ptr))) { | |
5782 | /* exists in current block */ | |
5783 | du = configparser_merge_data(du, B); | |
5784 | if (NULL == du) { | |
5785 | @@ -190,6 +183,7 @@ | |
5786 | buffer_copy_string_buffer(du->key, A); | |
5787 | array_replace(vars, du); | |
5788 | } | |
5789 | + B->free(B); | |
5790 | } else if (NULL != (du = configparser_get_variable(ctx, A))) { | |
5791 | du = configparser_merge_data(du, B); | |
5792 | if (NULL == du) { | |
5793 | @@ -199,15 +193,13 @@ | |
5794 | buffer_copy_string_buffer(du->key, A); | |
5795 | array_insert_unique(ctx->current->value, du); | |
5796 | } | |
5797 | + B->free(B); | |
5798 | } else { | |
5799 | - fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", | |
5800 | - ctx->current->context_ndx, | |
5801 | - ctx->current->key->ptr, A->ptr); | |
5802 | - ctx->ok = 0; | |
5803 | + buffer_copy_string_buffer(B->key, A); | |
5804 | + array_insert_unique(ctx->current->value, B); | |
5805 | } | |
5806 | buffer_free(A); | |
5807 | A = NULL; | |
5808 | - B->free(B); | |
5809 | B = NULL; | |
5810 | } | |
5811 | ||
5812 | @@ -239,7 +231,24 @@ | |
5813 | } | |
5814 | ||
5815 | value(A) ::= key(B). { | |
5816 | - A = configparser_get_variable(ctx, B); | |
5817 | + if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) { | |
5818 | + char *env; | |
5819 | + | |
5820 | + if (NULL != (env = getenv(B->ptr + 4))) { | |
5821 | + data_string *ds; | |
5822 | + ds = data_string_init(); | |
5823 | + buffer_append_string(ds->value, env); | |
5824 | + A = (data_unset *)ds; | |
5825 | + } | |
5826 | + else { | |
5827 | + A = NULL; | |
5828 | + fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4); | |
5829 | + ctx->ok = 0; | |
5830 | + } | |
5831 | + } else if (NULL == (A = configparser_get_variable(ctx, B))) { | |
5832 | + fprintf(stderr, "Undefined config variable: %s\n", B->ptr); | |
5833 | + ctx->ok = 0; | |
5834 | + } | |
5835 | if (!A) { | |
5836 | /* make a dummy so it won't crash */ | |
5837 | A = (data_unset *)data_string_init(); | |
5838 | @@ -267,6 +276,9 @@ | |
5839 | ((data_array *)(A))->value = B; | |
5840 | B = NULL; | |
5841 | } | |
5842 | +array(A) ::= LPARAN RPARAN. { | |
5843 | + A = array_init(); | |
5844 | +} | |
5845 | array(A) ::= LPARAN aelements(B) RPARAN. { | |
5846 | A = B; | |
5847 | B = NULL; | |
1175ccec | 5848 | --- ../lighttpd-1.4.11/src/connections-glue.c 2005-09-12 10:04:23.000000000 +0300 |
36e2a29e | 5849 | +++ lighttpd-1.4.12/src/connections-glue.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
5850 | @@ -13,7 +13,7 @@ |
5851 | case CON_STATE_REQUEST_END: return "req-end"; | |
5852 | case CON_STATE_RESPONSE_START: return "resp-start"; | |
5853 | case CON_STATE_RESPONSE_END: return "resp-end"; | |
5854 | - default: return "(unknown)"; | |
5855 | + default: return "(unknown)"; | |
5856 | } | |
5857 | } | |
5858 | ||
5859 | @@ -30,15 +30,15 @@ | |
5860 | case CON_STATE_REQUEST_END: return "Q"; | |
5861 | case CON_STATE_RESPONSE_START: return "s"; | |
5862 | case CON_STATE_RESPONSE_END: return "S"; | |
5863 | - default: return "x"; | |
5864 | + default: return "x"; | |
5865 | } | |
5866 | } | |
5867 | ||
5868 | int connection_set_state(server *srv, connection *con, connection_state_t state) { | |
5869 | UNUSED(srv); | |
5870 | - | |
5871 | + | |
5872 | con->state = state; | |
5873 | - | |
5874 | + | |
5875 | return 0; | |
5876 | } | |
5877 | ||
1175ccec ER |
5878 | --- ../lighttpd-1.4.11/src/connections.c 2006-03-05 22:14:53.000000000 +0200 |
5879 | +++ lighttpd-1.4.12/src/connections.c 2006-07-15 22:43:21.000000000 +0300 | |
2519e6e5 ER |
5880 | @@ -2,7 +2,6 @@ |
5881 | ||
5882 | #include <stdlib.h> | |
5883 | #include <stdio.h> | |
5884 | -#include <unistd.h> | |
5885 | #include <errno.h> | |
5886 | #include <string.h> | |
5887 | #include <fcntl.h> | |
5888 | @@ -26,8 +25,8 @@ | |
5889 | #include "inet_ntop_cache.h" | |
5890 | ||
5891 | #ifdef USE_OPENSSL | |
5892 | -# include <openssl/ssl.h> | |
5893 | -# include <openssl/err.h> | |
5894 | +# include <openssl/ssl.h> | |
5895 | +# include <openssl/err.h> | |
5896 | #endif | |
5897 | ||
5898 | #ifdef HAVE_SYS_FILIO_H | |
1175ccec | 5899 | @@ -35,15 +34,16 @@ |
f26f9fd5 | 5900 | #endif |
f673a614 | 5901 | |
f26f9fd5 ER |
5902 | #include "sys-socket.h" |
5903 | +#include "sys-files.h" | |
f673a614 | 5904 | |
f26f9fd5 | 5905 | typedef struct { |
1175ccec ER |
5906 | - PLUGIN_DATA; |
5907 | + PLUGIN_DATA; | |
5908 | } plugin_data; | |
5909 | ||
2519e6e5 ER |
5910 | static connection *connections_get_new_connection(server *srv) { |
5911 | connections *conns = srv->conns; | |
5912 | size_t i; | |
5913 | - | |
5914 | + | |
5915 | if (conns->size == 0) { | |
5916 | conns->size = 128; | |
5917 | conns->ptr = NULL; | |
5918 | @@ -54,21 +54,21 @@ | |
5919 | } else if (conns->size == conns->used) { | |
5920 | conns->size += 128; | |
5921 | conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size); | |
5922 | - | |
5923 | + | |
5924 | for (i = conns->used; i < conns->size; i++) { | |
5925 | conns->ptr[i] = connection_init(srv); | |
5926 | } | |
5927 | } | |
f673a614 | 5928 | |
2519e6e5 ER |
5929 | connection_reset(srv, conns->ptr[conns->used]); |
5930 | -#if 0 | |
5931 | +#if 0 | |
5932 | fprintf(stderr, "%s.%d: add: ", __FILE__, __LINE__); | |
5933 | for (i = 0; i < conns->used + 1; i++) { | |
5934 | fprintf(stderr, "%d ", conns->ptr[i]->fd); | |
5935 | } | |
5936 | fprintf(stderr, "\n"); | |
5937 | -#endif | |
5938 | - | |
5939 | +#endif | |
5940 | + | |
5941 | conns->ptr[conns->used]->ndx = conns->used; | |
5942 | return conns->ptr[conns->used++]; | |
5943 | } | |
5944 | @@ -77,26 +77,26 @@ | |
5945 | size_t i; | |
5946 | connections *conns = srv->conns; | |
5947 | connection *temp; | |
5948 | - | |
5949 | + | |
5950 | if (con == NULL) return -1; | |
5951 | - | |
5952 | + | |
5953 | if (-1 == con->ndx) return -1; | |
5954 | - | |
5955 | + | |
5956 | i = con->ndx; | |
5957 | - | |
5958 | + | |
5959 | /* not last element */ | |
5960 | - | |
5961 | + | |
5962 | if (i != conns->used - 1) { | |
5963 | temp = conns->ptr[i]; | |
5964 | conns->ptr[i] = conns->ptr[conns->used - 1]; | |
5965 | conns->ptr[conns->used - 1] = temp; | |
5966 | - | |
5967 | + | |
5968 | conns->ptr[i]->ndx = i; | |
5969 | conns->ptr[conns->used - 1]->ndx = -1; | |
5970 | } | |
5971 | - | |
5972 | + | |
5973 | conns->used--; | |
5974 | - | |
5975 | + | |
5976 | con->ndx = -1; | |
5977 | #if 0 | |
5978 | fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used); | |
5979 | @@ -104,25 +104,23 @@ | |
5980 | fprintf(stderr, "%d ", conns->ptr[i]->fd); | |
5981 | } | |
5982 | fprintf(stderr, "\n"); | |
5983 | -#endif | |
5984 | +#endif | |
5985 | return 0; | |
5986 | } | |
5987 | ||
5988 | int connection_close(server *srv, connection *con) { | |
5989 | #ifdef USE_OPENSSL | |
5990 | server_socket *srv_sock = con->srv_socket; | |
5991 | -#endif | |
5992 | - | |
5993 | -#ifdef USE_OPENSSL | |
5994 | + | |
5995 | if (srv_sock->is_ssl) { | |
5996 | if (con->ssl) SSL_free(con->ssl); | |
5997 | con->ssl = NULL; | |
5998 | } | |
5999 | #endif | |
6000 | - | |
6001 | + | |
6002 | fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd); | |
6003 | fdevent_unregister(srv->ev, con->fd); | |
6004 | -#ifdef __WIN32 | |
6005 | +#ifdef _WIN32 | |
6006 | if (closesocket(con->fd)) { | |
6007 | log_error_write(srv, __FILE__, __LINE__, "sds", | |
6008 | "(warning) close:", con->fd, strerror(errno)); | |
6009 | @@ -133,207 +131,96 @@ | |
6010 | "(warning) close:", con->fd, strerror(errno)); | |
6011 | } | |
6012 | #endif | |
6013 | - | |
6014 | + | |
6015 | srv->cur_fds--; | |
6016 | #if 0 | |
6017 | log_error_write(srv, __FILE__, __LINE__, "sd", | |
6018 | "closed()", con->fd); | |
6019 | #endif | |
6020 | - | |
6021 | + | |
6022 | connection_del(srv, con); | |
6023 | connection_set_state(srv, con, CON_STATE_CONNECT); | |
6024 | - | |
6025 | + | |
6026 | return 0; | |
6027 | } | |
6028 | ||
6029 | #if 0 | |
6030 | static void dump_packet(const unsigned char *data, size_t len) { | |
6031 | size_t i, j; | |
6032 | - | |
6033 | + | |
6034 | if (len == 0) return; | |
6035 | - | |
6036 | + | |
6037 | for (i = 0; i < len; i++) { | |
6038 | if (i % 16 == 0) fprintf(stderr, " "); | |
6039 | - | |
6040 | + | |
6041 | fprintf(stderr, "%02x ", data[i]); | |
6042 | - | |
6043 | + | |
6044 | if ((i + 1) % 16 == 0) { | |
6045 | fprintf(stderr, " "); | |
6046 | for (j = 0; j <= i % 16; j++) { | |
6047 | unsigned char c; | |
6048 | - | |
6049 | + | |
6050 | if (i-15+j >= len) break; | |
6051 | - | |
6052 | + | |
6053 | c = data[i-15+j]; | |
6054 | - | |
6055 | + | |
6056 | fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.'); | |
6057 | } | |
6058 | - | |
6059 | + | |
6060 | fprintf(stderr, "\n"); | |
6061 | } | |
6062 | } | |
6063 | - | |
6064 | + | |
6065 | if (len % 16 != 0) { | |
6066 | for (j = i % 16; j < 16; j++) { | |
6067 | fprintf(stderr, " "); | |
6068 | } | |
6069 | - | |
6070 | + | |
6071 | fprintf(stderr, " "); | |
6072 | for (j = i & ~0xf; j < len; j++) { | |
6073 | unsigned char c; | |
6074 | - | |
6075 | + | |
6076 | c = data[j]; | |
6077 | fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.'); | |
6078 | } | |
6079 | fprintf(stderr, "\n"); | |
6080 | } | |
6081 | } | |
6082 | -#endif | |
f26f9fd5 | 6083 | - |
2519e6e5 ER |
6084 | -static int connection_handle_read(server *srv, connection *con) { |
6085 | - int len; | |
6086 | - buffer *b; | |
6087 | - int toread; | |
6088 | -#ifdef USE_OPENSSL | |
6089 | - server_socket *srv_sock = con->srv_socket; | |
6090 | #endif | |
6091 | ||
f26f9fd5 ER |
6092 | - b = chunkqueue_get_append_buffer(con->read_queue); |
6093 | - buffer_prepare_copy(b, 4096); | |
2519e6e5 ER |
6094 | +static network_status_t connection_handle_read(server *srv, connection *con) { |
6095 | + off_t oldlen, newlen; | |
6096 | ||
f26f9fd5 ER |
6097 | -#ifdef USE_OPENSSL |
6098 | - if (srv_sock->is_ssl) { | |
6099 | - len = SSL_read(con->ssl, b->ptr, b->size - 1); | |
6100 | - } else { | |
6101 | - if (ioctl(con->fd, FIONREAD, &toread)) { | |
6102 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
6103 | - "unexpected end-of-file:", | |
6104 | - con->fd); | |
6105 | - return -1; | |
6106 | - } | |
6107 | - buffer_prepare_copy(b, toread); | |
1175ccec | 6108 | + oldlen = chunkqueue_length(con->read_queue); |
2519e6e5 | 6109 | |
f26f9fd5 ER |
6110 | - len = read(con->fd, b->ptr, b->size - 1); |
6111 | - } | |
6112 | -#elif defined(__WIN32) | |
6113 | - len = recv(con->fd, b->ptr, b->size - 1, 0); | |
6114 | -#else | |
6115 | - if (ioctl(con->fd, FIONREAD, &toread)) { | |
6116 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
6117 | - "unexpected end-of-file:", | |
6118 | - con->fd); | |
6119 | - return -1; | |
6120 | - } | |
6121 | - buffer_prepare_copy(b, toread); | |
6122 | - | |
6123 | - len = read(con->fd, b->ptr, b->size - 1); | |
6124 | -#endif | |
6125 | - | |
6126 | - if (len < 0) { | |
1175ccec ER |
6127 | + switch(network_read_chunkqueue(srv, con, con->read_queue)) { |
6128 | + case NETWORK_STATUS_SUCCESS: | |
6129 | + break; | |
6130 | + case NETWORK_STATUS_WAIT_FOR_EVENT: | |
6131 | + con->is_readable = 0; | |
6132 | + return NETWORK_STATUS_WAIT_FOR_EVENT; | |
6133 | + case NETWORK_STATUS_INTERRUPTED: | |
6134 | + con->is_readable = 1; | |
6135 | + return NETWORK_STATUS_WAIT_FOR_EVENT; | |
6136 | + case NETWORK_STATUS_CONNECTION_CLOSE: | |
6137 | + /* pipelining */ | |
6138 | + con->is_readable = 0; | |
6139 | + return NETWORK_STATUS_CONNECTION_CLOSE; | |
6140 | + case NETWORK_STATUS_FATAL_ERROR: | |
6141 | con->is_readable = 0; | |
f673a614 | 6142 | - |
f26f9fd5 ER |
6143 | -#ifdef USE_OPENSSL |
6144 | - if (srv_sock->is_ssl) { | |
6145 | - int r, ssl_err; | |
6146 | - | |
6147 | - switch ((r = SSL_get_error(con->ssl, len))) { | |
6148 | - case SSL_ERROR_WANT_READ: | |
6149 | - return 0; | |
6150 | - case SSL_ERROR_SYSCALL: | |
6151 | - /** | |
6152 | - * man SSL_get_error() | |
6153 | - * | |
6154 | - * SSL_ERROR_SYSCALL | |
6155 | - * Some I/O error occurred. The OpenSSL error queue may contain more | |
6156 | - * information on the error. If the error queue is empty (i.e. | |
6157 | - * ERR_get_error() returns 0), ret can be used to find out more about | |
6158 | - * the error: If ret == 0, an EOF was observed that violates the | |
6159 | - * protocol. If ret == -1, the underlying BIO reported an I/O error | |
6160 | - * (for socket I/O on Unix systems, consult errno for details). | |
6161 | - * | |
6162 | - */ | |
6163 | - while((ssl_err = ERR_get_error())) { | |
6164 | - /* get all errors from the error-queue */ | |
6165 | - log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", | |
6166 | - r, ERR_error_string(ssl_err, NULL)); | |
6167 | - } | |
2519e6e5 | 6168 | |
f26f9fd5 ER |
6169 | - switch(errno) { |
6170 | - default: | |
6171 | - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", | |
6172 | - len, r, errno, | |
6173 | - strerror(errno)); | |
6174 | - break; | |
6175 | - } | |
6176 | - | |
6177 | - break; | |
6178 | - case SSL_ERROR_ZERO_RETURN: | |
6179 | - /* clean shutdown on the remote side */ | |
2519e6e5 | 6180 | - |
f26f9fd5 ER |
6181 | - if (r == 0) { |
6182 | - /* FIXME: later */ | |
6183 | - } | |
2519e6e5 | 6184 | - |
f26f9fd5 ER |
6185 | - /* fall thourgh */ |
6186 | - default: | |
6187 | - while((ssl_err = ERR_get_error())) { | |
6188 | - /* get all errors from the error-queue */ | |
6189 | - log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", | |
6190 | - r, ERR_error_string(ssl_err, NULL)); | |
6191 | - } | |
2519e6e5 | 6192 | - break; |
f26f9fd5 ER |
6193 | - } |
6194 | - } else { | |
6195 | - if (errno == EAGAIN) return 0; | |
6196 | - if (errno == EINTR) { | |
6197 | - /* we have been interrupted before we could read */ | |
6198 | - con->is_readable = 1; | |
6199 | - return 0; | |
6200 | - } | |
f673a614 | 6201 | - |
f26f9fd5 ER |
6202 | - if (errno != ECONNRESET) { |
6203 | - /* expected for keep-alive */ | |
6204 | - log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno); | |
6205 | - } | |
6206 | - } | |
6207 | -#else | |
6208 | - if (errno == EAGAIN) return 0; | |
6209 | - if (errno == EINTR) { | |
6210 | - /* we have been interrupted before we could read */ | |
6211 | - con->is_readable = 1; | |
6212 | - return 0; | |
6213 | - } | |
f673a614 | 6214 | - |
f26f9fd5 ER |
6215 | - if (errno != ECONNRESET) { |
6216 | - /* expected for keep-alive */ | |
6217 | - log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno); | |
6218 | - } | |
6219 | -#endif | |
1175ccec | 6220 | connection_set_state(srv, con, CON_STATE_ERROR); |
f673a614 | 6221 | - |
f26f9fd5 ER |
6222 | - return -1; |
6223 | - } else if (len == 0) { | |
2519e6e5 | 6224 | - con->is_readable = 0; |
f26f9fd5 | 6225 | - /* the other end close the connection -> KEEP-ALIVE */ |
1175ccec ER |
6226 | + return NETWORK_STATUS_FATAL_ERROR; |
6227 | + default: | |
6228 | + SEGFAULT(); | |
6229 | + break; | |
6230 | + } | |
6231 | ||
2519e6e5 | 6232 | - /* pipelining */ |
1175ccec ER |
6233 | + newlen = chunkqueue_length(con->read_queue); |
6234 | ||
f26f9fd5 ER |
6235 | - return -2; |
6236 | - } else if ((size_t)len < b->size - 1) { | |
6237 | - /* we got less then expected, wait for the next fd-event */ | |
f673a614 | 6238 | - |
2519e6e5 ER |
6239 | - con->is_readable = 0; |
6240 | - } | |
6241 | - | |
f26f9fd5 ER |
6242 | - b->used = len; |
6243 | - b->ptr[b->used++] = '\0'; | |
2519e6e5 | 6244 | - |
f26f9fd5 ER |
6245 | - con->bytes_read += len; |
6246 | -#if 0 | |
6247 | - dump_packet(b->ptr, len); | |
6248 | -#endif | |
2519e6e5 | 6249 | - |
f26f9fd5 | 6250 | - return 0; |
2519e6e5 ER |
6251 | + con->bytes_read += (newlen - oldlen); |
6252 | + | |
f26f9fd5 | 6253 | + return NETWORK_STATUS_SUCCESS; |
f673a614 ER |
6254 | } |
6255 | ||
f26f9fd5 ER |
6256 | static int connection_handle_write_prepare(server *srv, connection *con) { |
6257 | @@ -343,6 +230,7 @@ | |
6258 | case HTTP_METHOD_GET: | |
6259 | case HTTP_METHOD_POST: | |
6260 | case HTTP_METHOD_HEAD: | |
6261 | + /* webdav */ | |
6262 | case HTTP_METHOD_PUT: | |
6263 | case HTTP_METHOD_MKCOL: | |
6264 | case HTTP_METHOD_DELETE: | |
2519e6e5 | 6265 | @@ -350,12 +238,14 @@ |
f26f9fd5 ER |
6266 | case HTTP_METHOD_MOVE: |
6267 | case HTTP_METHOD_PROPFIND: | |
6268 | case HTTP_METHOD_PROPPATCH: | |
6269 | + case HTTP_METHOD_LOCK: | |
6270 | + case HTTP_METHOD_UNLOCK: | |
6271 | break; | |
6272 | case HTTP_METHOD_OPTIONS: | |
6273 | /* | |
2519e6e5 ER |
6274 | * 400 is coming from the request-parser BEFORE uri.path is set |
6275 | - * 403 is from the response handler when noone else catched it | |
6276 | - * | |
6277 | + * 403 is from the response handler when noone else catched it | |
6278 | + * | |
6279 | * */ | |
6280 | if (con->uri.path->used && | |
6281 | con->uri.path->ptr[0] != '*') { | |
6282 | @@ -381,55 +271,58 @@ | |
6283 | break; | |
6284 | } | |
6285 | } | |
6286 | - | |
6287 | + | |
6288 | if (con->http_status == 0) { | |
6289 | con->http_status = 403; | |
6290 | } | |
6291 | - | |
6292 | + | |
6293 | switch(con->http_status) { | |
6294 | case 400: /* class: header + custom body */ | |
6295 | case 401: | |
f26f9fd5 ER |
6296 | case 403: |
6297 | case 404: | |
6298 | case 408: | |
6299 | + case 409: | |
6300 | + case 410: | |
6301 | case 411: | |
6302 | case 416: | |
6303 | case 423: | |
2519e6e5 | 6304 | case 500: |
f26f9fd5 ER |
6305 | case 501: |
6306 | case 503: | |
2519e6e5 ER |
6307 | - case 505: |
6308 | + case 505: | |
f26f9fd5 ER |
6309 | + case 509: |
6310 | if (con->mode != DIRECT) break; | |
2519e6e5 ER |
6311 | - |
6312 | + | |
f26f9fd5 | 6313 | con->file_finished = 0; |
2519e6e5 ER |
6314 | - |
6315 | + | |
6316 | buffer_reset(con->physical.path); | |
6317 | - | |
6318 | + | |
6319 | /* try to send static errorfile */ | |
6320 | if (!buffer_is_empty(con->conf.errorfile_prefix)) { | |
6321 | stat_cache_entry *sce = NULL; | |
6322 | - | |
6323 | + | |
6324 | buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix); | |
6325 | buffer_append_string(con->physical.path, get_http_status_body_name(con->http_status)); | |
6326 | - | |
6327 | + | |
6328 | if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { | |
6329 | con->file_finished = 1; | |
6330 | - | |
6331 | + | |
6332 | http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size); | |
6333 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); | |
6334 | } | |
f26f9fd5 | 6335 | } |
2519e6e5 ER |
6336 | - |
6337 | - if (!con->file_finished) { | |
6338 | + | |
6339 | + if (!con->file_finished) { | |
6340 | buffer *b; | |
6341 | - | |
6342 | + | |
6343 | buffer_reset(con->physical.path); | |
6344 | - | |
6345 | + | |
6346 | con->file_finished = 1; | |
6347 | b = chunkqueue_get_append_buffer(con->write_queue); | |
6348 | - | |
6349 | + | |
6350 | /* build default error-page */ | |
6351 | - buffer_copy_string(b, | |
6352 | + buffer_copy_string(b, | |
6353 | "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" | |
6354 | "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" | |
6355 | " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" | |
6356 | @@ -439,7 +332,7 @@ | |
6357 | buffer_append_long(b, con->http_status); | |
6358 | buffer_append_string(b, " - "); | |
6359 | buffer_append_string(b, get_http_status_name(con->http_status)); | |
6360 | - | |
6361 | + | |
6362 | buffer_append_string(b, | |
6363 | "</title>\n" | |
6364 | " </head>\n" | |
6365 | @@ -448,12 +341,12 @@ | |
6366 | buffer_append_long(b, con->http_status); | |
6367 | buffer_append_string(b, " - "); | |
6368 | buffer_append_string(b, get_http_status_name(con->http_status)); | |
6369 | - | |
6370 | - buffer_append_string(b,"</h1>\n" | |
6371 | + | |
6372 | + buffer_append_string(b,"</h1>\n" | |
6373 | " </body>\n" | |
6374 | "</html>\n" | |
6375 | ); | |
6376 | - | |
6377 | + | |
6378 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); | |
6379 | } | |
6380 | /* fall through */ | |
6381 | @@ -463,10 +356,10 @@ | |
6382 | case 301: | |
6383 | case 302: | |
f26f9fd5 | 6384 | break; |
2519e6e5 ER |
6385 | - |
6386 | + | |
6387 | case 206: /* write_queue is already prepared */ | |
6388 | con->file_finished = 1; | |
6389 | - | |
6390 | + | |
f26f9fd5 | 6391 | break; |
2519e6e5 ER |
6392 | case 205: /* class: header only */ |
6393 | case 304: | |
6394 | @@ -474,19 +367,19 @@ | |
6395 | /* disable chunked encoding again as we have no body */ | |
6396 | con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; | |
6397 | chunkqueue_reset(con->write_queue); | |
6398 | - | |
6399 | + | |
6400 | con->file_finished = 1; | |
f26f9fd5 | 6401 | break; |
f26f9fd5 | 6402 | } |
2519e6e5 ER |
6403 | - |
6404 | + | |
f673a614 | 6405 | |
2519e6e5 ER |
6406 | if (con->file_finished) { |
6407 | - /* we have all the content and chunked encoding is not used, set a content-length */ | |
6408 | - | |
6409 | - if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) && | |
6410 | + /* we have all the content and chunked encoding is not used, set a content-length */ | |
6411 | + | |
6412 | + if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) && | |
6413 | (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) { | |
6414 | buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->write_queue)); | |
6415 | - | |
6416 | + | |
6417 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf)); | |
6418 | } | |
6419 | } else { | |
6420 | @@ -495,74 +388,77 @@ | |
6421 | ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0)) { | |
6422 | con->keep_alive = 0; | |
6423 | } | |
6424 | - | |
6425 | + | |
6426 | if (0 == (con->parsed_response & HTTP_CONNECTION)) { | |
6427 | /* (f)cgi did'nt send Connection: header | |
6428 | - * | |
6429 | + * | |
6430 | * shall we ? | |
6431 | */ | |
6432 | if (((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) && | |
6433 | (con->parsed_response & HTTP_CONTENT_LENGTH) == 0) { | |
6434 | /* without content_length, no keep-alive */ | |
6435 | - | |
6436 | + | |
6437 | con->keep_alive = 0; | |
6438 | } | |
6439 | } else { | |
6440 | /* a subrequest disable keep-alive although the client wanted it */ | |
6441 | if (con->keep_alive && !con->response.keep_alive) { | |
6442 | con->keep_alive = 0; | |
6443 | - | |
6444 | + | |
6445 | /* FIXME: we have to drop the Connection: Header from the subrequest */ | |
6446 | } | |
6447 | } | |
6448 | } | |
6449 | - | |
6450 | + | |
6451 | if (con->request.http_method == HTTP_METHOD_HEAD) { | |
6452 | chunkqueue_reset(con->write_queue); | |
6453 | } | |
6454 | ||
6455 | http_response_write_header(srv, con); | |
6456 | - | |
6457 | + | |
6458 | return 0; | |
6459 | } | |
6460 | ||
6461 | static int connection_handle_write(server *srv, connection *con) { | |
1175ccec | 6462 | switch(network_write_chunkqueue(srv, con, con->write_queue)) { |
2519e6e5 | 6463 | - case 0: |
2519e6e5 ER |
6464 | + case NETWORK_STATUS_SUCCESS: |
6465 | if (con->file_finished) { | |
6466 | connection_set_state(srv, con, CON_STATE_RESPONSE_END); | |
6467 | joblist_append(srv, con); | |
6468 | } | |
6469 | break; | |
6470 | - case -1: /* error on our side */ | |
6471 | + case NETWORK_STATUS_FATAL_ERROR: /* error on our side */ | |
6472 | log_error_write(srv, __FILE__, __LINE__, "sd", | |
6473 | "connection closed: write failed on fd", con->fd); | |
6474 | connection_set_state(srv, con, CON_STATE_ERROR); | |
6475 | joblist_append(srv, con); | |
6476 | break; | |
6477 | - case -2: /* remote close */ | |
6478 | + case NETWORK_STATUS_CONNECTION_CLOSE: /* remote close */ | |
6479 | connection_set_state(srv, con, CON_STATE_ERROR); | |
6480 | joblist_append(srv, con); | |
6481 | break; | |
6482 | - case 1: | |
6483 | + case NETWORK_STATUS_WAIT_FOR_EVENT: | |
6484 | con->is_writable = 0; | |
6485 | - | |
6486 | + | |
6487 | /* not finished yet -> WRITE */ | |
6488 | break; | |
6489 | + case NETWORK_STATUS_INTERRUPTED: | |
6490 | + con->is_writable = 1; | |
6491 | + break; | |
6492 | + case NETWORK_STATUS_UNSET: | |
6493 | + break; | |
6494 | } | |
6495 | - | |
6496 | + | |
6497 | return 0; | |
6498 | } | |
6499 | ||
6500 | - | |
f26f9fd5 ER |
6501 | - |
6502 | connection *connection_init(server *srv) { | |
6503 | connection *con; | |
2519e6e5 ER |
6504 | - |
6505 | + | |
6506 | UNUSED(srv); | |
6507 | ||
6508 | con = calloc(1, sizeof(*con)); | |
6509 | - | |
6510 | + | |
6511 | con->fd = 0; | |
6512 | con->ndx = -1; | |
6513 | con->fde_ndx = -1; | |
6514 | @@ -573,32 +469,32 @@ | |
6515 | ||
6516 | #define CLEAN(x) \ | |
6517 | con->x = buffer_init(); | |
6518 | - | |
6519 | + | |
6520 | CLEAN(request.uri); | |
6521 | CLEAN(request.request_line); | |
6522 | CLEAN(request.request); | |
6523 | CLEAN(request.pathinfo); | |
6524 | - | |
6525 | + | |
6526 | CLEAN(request.orig_uri); | |
6527 | - | |
6528 | + | |
6529 | CLEAN(uri.scheme); | |
6530 | CLEAN(uri.authority); | |
6531 | CLEAN(uri.path); | |
6532 | CLEAN(uri.path_raw); | |
6533 | CLEAN(uri.query); | |
6534 | - | |
6535 | + | |
6536 | CLEAN(physical.doc_root); | |
6537 | CLEAN(physical.path); | |
6538 | CLEAN(physical.basedir); | |
6539 | CLEAN(physical.rel_path); | |
6540 | CLEAN(physical.etag); | |
6541 | CLEAN(parse_request); | |
6542 | - | |
6543 | + | |
6544 | CLEAN(authed_user); | |
6545 | CLEAN(server_name); | |
6546 | CLEAN(error_handler); | |
6547 | CLEAN(dst_addr_buf); | |
6548 | - | |
6549 | + | |
6550 | #undef CLEAN | |
6551 | con->write_queue = chunkqueue_init(); | |
6552 | con->read_queue = chunkqueue_init(); | |
6553 | @@ -608,26 +504,26 @@ | |
6554 | con->request.headers = array_init(); | |
6555 | con->response.headers = array_init(); | |
6556 | con->environment = array_init(); | |
6557 | - | |
6558 | + | |
6559 | /* init plugin specific connection structures */ | |
6560 | - | |
6561 | + | |
6562 | con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *)); | |
6563 | - | |
6564 | + | |
6565 | con->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t)); | |
6566 | config_setup_connection(srv, con); | |
6567 | - | |
6568 | + | |
6569 | return con; | |
6570 | } | |
6571 | ||
6572 | void connections_free(server *srv) { | |
6573 | connections *conns = srv->conns; | |
6574 | - size_t i; | |
6575 | - | |
6576 | + size_t i; | |
6577 | + | |
6578 | for (i = 0; i < conns->size; i++) { | |
6579 | connection *con = conns->ptr[i]; | |
6580 | - | |
6581 | + | |
6582 | connection_reset(srv, con); | |
6583 | - | |
6584 | + | |
6585 | chunkqueue_free(con->write_queue); | |
6586 | chunkqueue_free(con->read_queue); | |
6587 | chunkqueue_free(con->request_content_queue); | |
6588 | @@ -637,27 +533,27 @@ | |
6589 | ||
6590 | #define CLEAN(x) \ | |
6591 | buffer_free(con->x); | |
6592 | - | |
6593 | + | |
6594 | CLEAN(request.uri); | |
6595 | CLEAN(request.request_line); | |
6596 | CLEAN(request.request); | |
6597 | CLEAN(request.pathinfo); | |
6598 | - | |
6599 | + | |
6600 | CLEAN(request.orig_uri); | |
6601 | - | |
6602 | + | |
6603 | CLEAN(uri.scheme); | |
6604 | CLEAN(uri.authority); | |
6605 | CLEAN(uri.path); | |
6606 | CLEAN(uri.path_raw); | |
6607 | CLEAN(uri.query); | |
6608 | - | |
6609 | + | |
6610 | CLEAN(physical.doc_root); | |
6611 | CLEAN(physical.path); | |
6612 | CLEAN(physical.basedir); | |
6613 | CLEAN(physical.etag); | |
6614 | CLEAN(physical.rel_path); | |
6615 | CLEAN(parse_request); | |
6616 | - | |
6617 | + | |
6618 | CLEAN(authed_user); | |
6619 | CLEAN(server_name); | |
6620 | CLEAN(error_handler); | |
6621 | @@ -665,97 +561,97 @@ | |
6622 | #undef CLEAN | |
6623 | free(con->plugin_ctx); | |
6624 | free(con->cond_cache); | |
6625 | - | |
6626 | + | |
6627 | free(con); | |
6628 | } | |
6629 | - | |
6630 | + | |
6631 | free(conns->ptr); | |
6632 | } | |
6633 | ||
6634 | ||
6635 | int connection_reset(server *srv, connection *con) { | |
6636 | size_t i; | |
6637 | - | |
6638 | + | |
6639 | plugins_call_connection_reset(srv, con); | |
6640 | - | |
6641 | + | |
6642 | con->is_readable = 1; | |
6643 | con->is_writable = 1; | |
6644 | con->http_status = 0; | |
6645 | con->file_finished = 0; | |
6646 | con->file_started = 0; | |
6647 | con->got_response = 0; | |
6648 | - | |
6649 | + | |
6650 | con->parsed_response = 0; | |
6651 | - | |
6652 | + | |
6653 | con->bytes_written = 0; | |
6654 | con->bytes_written_cur_second = 0; | |
6655 | con->bytes_read = 0; | |
6656 | con->bytes_header = 0; | |
6657 | con->loops_per_request = 0; | |
6658 | - | |
6659 | + | |
6660 | con->request.http_method = HTTP_METHOD_UNSET; | |
6661 | con->request.http_version = HTTP_VERSION_UNSET; | |
6662 | - | |
6663 | + | |
6664 | con->request.http_if_modified_since = NULL; | |
6665 | con->request.http_if_none_match = NULL; | |
6666 | - | |
6667 | + | |
6668 | con->response.keep_alive = 0; | |
6669 | con->response.content_length = -1; | |
6670 | con->response.transfer_encoding = 0; | |
6671 | - | |
6672 | + | |
6673 | con->mode = DIRECT; | |
6674 | - | |
6675 | + | |
6676 | #define CLEAN(x) \ | |
6677 | if (con->x) buffer_reset(con->x); | |
6678 | - | |
6679 | + | |
6680 | CLEAN(request.uri); | |
6681 | CLEAN(request.request_line); | |
6682 | CLEAN(request.pathinfo); | |
6683 | CLEAN(request.request); | |
6684 | - | |
6685 | + | |
6686 | CLEAN(request.orig_uri); | |
6687 | - | |
6688 | + | |
6689 | CLEAN(uri.scheme); | |
6690 | CLEAN(uri.authority); | |
6691 | CLEAN(uri.path); | |
6692 | CLEAN(uri.path_raw); | |
6693 | CLEAN(uri.query); | |
6694 | - | |
6695 | + | |
6696 | CLEAN(physical.doc_root); | |
6697 | CLEAN(physical.path); | |
6698 | CLEAN(physical.basedir); | |
6699 | CLEAN(physical.rel_path); | |
6700 | CLEAN(physical.etag); | |
6701 | - | |
6702 | + | |
6703 | CLEAN(parse_request); | |
6704 | - | |
6705 | + | |
6706 | CLEAN(authed_user); | |
6707 | CLEAN(server_name); | |
6708 | CLEAN(error_handler); | |
6709 | -#undef CLEAN | |
6710 | - | |
6711 | +#undef CLEAN | |
6712 | + | |
6713 | #define CLEAN(x) \ | |
6714 | - if (con->x) con->x->used = 0; | |
6715 | - | |
6716 | + if (con->x) con->x->used = 0; | |
6717 | + | |
6718 | #undef CLEAN | |
6719 | - | |
6720 | + | |
6721 | #define CLEAN(x) \ | |
6722 | con->request.x = NULL; | |
6723 | - | |
6724 | + | |
6725 | CLEAN(http_host); | |
6726 | CLEAN(http_range); | |
6727 | CLEAN(http_content_type); | |
6728 | #undef CLEAN | |
6729 | con->request.content_length = 0; | |
6730 | - | |
6731 | + | |
6732 | array_reset(con->request.headers); | |
6733 | array_reset(con->response.headers); | |
6734 | array_reset(con->environment); | |
6735 | - | |
6736 | + | |
6737 | chunkqueue_reset(con->write_queue); | |
6738 | chunkqueue_reset(con->request_content_queue); | |
6739 | ||
6740 | - /* the plugins should cleanup themself */ | |
6741 | + /* the plugins should cleanup themself */ | |
6742 | for (i = 0; i < srv->plugins.used; i++) { | |
6743 | plugin *p = ((plugin **)(srv->plugins.ptr))[i]; | |
6744 | plugin_data *pd = p->data; | |
6745 | @@ -768,7 +664,7 @@ | |
6746 | ||
6747 | con->plugin_ctx[pd->id] = NULL; | |
6748 | } | |
6749 | - | |
6750 | + | |
6751 | #if COND_RESULT_UNSET | |
6752 | for (i = srv->config_context->used - 1; i >= 0; i --) { | |
6753 | con->cond_cache[i].result = COND_RESULT_UNSET; | |
6754 | @@ -777,56 +673,56 @@ | |
6755 | #else | |
6756 | memset(con->cond_cache, 0, sizeof(cond_cache_t) * srv->config_context->used); | |
6757 | #endif | |
6758 | - | |
6759 | + | |
6760 | con->header_len = 0; | |
6761 | con->in_error_handler = 0; | |
6762 | - | |
6763 | + | |
6764 | config_setup_connection(srv, con); | |
6765 | - | |
6766 | + | |
6767 | return 0; | |
6768 | } | |
6769 | ||
6770 | /** | |
6771 | - * | |
6772 | - * search for \r\n\r\n | |
6773 | - * | |
6774 | + * | |
6775 | + * search for \r\n\r\n | |
6776 | + * | |
6777 | * this is a special 32bit version which is using a sliding window for | |
6778 | - * the comparisions | |
6779 | - * | |
6780 | + * the comparisions | |
6781 | + * | |
6782 | * how it works: | |
6783 | - * | |
6784 | + * | |
6785 | * b: 'abcdefg' | |
6786 | * rnrn: 'cdef' | |
6787 | - * | |
6788 | + * | |
6789 | * cmpbuf: abcd != cdef | |
6790 | * cmpbuf: bcde != cdef | |
6791 | * cmpbuf: cdef == cdef -> return &c | |
6792 | - * | |
6793 | - * cmpbuf and rnrn are treated as 32bit uint and bit-ops are used to | |
6794 | + * | |
6795 | + * cmpbuf and rnrn are treated as 32bit uint and bit-ops are used to | |
6796 | * maintain cmpbuf and rnrn | |
6797 | - * | |
6798 | + * | |
6799 | */ | |
6800 | ||
6801 | char *buffer_search_rnrn(buffer *b) { | |
6802 | uint32_t cmpbuf, rnrn; | |
6803 | char *cp; | |
6804 | size_t i; | |
6805 | - | |
6806 | + | |
6807 | if (b->used < 4) return NULL; | |
6808 | - | |
6809 | + | |
6810 | rnrn = ('\r' << 24) | ('\n' << 16) | | |
6811 | ('\r' << 8) | ('\n' << 0); | |
6812 | - | |
6813 | + | |
6814 | cmpbuf = (b->ptr[0] << 24) | (b->ptr[1] << 16) | | |
6815 | (b->ptr[2] << 8) | (b->ptr[3] << 0); | |
6816 | - | |
6817 | + | |
6818 | cp = b->ptr + 4; | |
6819 | for (i = 0; i < b->used - 4; i++) { | |
6820 | if (cmpbuf == rnrn) return cp - 4; | |
6821 | - | |
6822 | + | |
6823 | cmpbuf = (cmpbuf << 8 | *(cp++)) & 0xffffffff; | |
6824 | } | |
6825 | - | |
6826 | + | |
6827 | return NULL; | |
6828 | } | |
6829 | /** | |
6830 | @@ -840,22 +736,25 @@ | |
6831 | chunk *c; | |
6832 | chunkqueue *cq = con->read_queue; | |
6833 | chunkqueue *dst_cq = con->request_content_queue; | |
6834 | - | |
6835 | + | |
6836 | if (con->is_readable) { | |
f26f9fd5 | 6837 | con->read_idle_ts = srv->cur_ts; |
2519e6e5 ER |
6838 | - |
6839 | + | |
f26f9fd5 ER |
6840 | switch(connection_handle_read(srv, con)) { |
6841 | - case -1: | |
6842 | + case NETWORK_STATUS_FATAL_ERROR: | |
6843 | return -1; | |
6844 | - case -2: | |
6845 | + case NETWORK_STATUS_CONNECTION_CLOSE: | |
6846 | /* remote side closed the connection | |
6847 | * if we still have content, handle it, if not leave here */ | |
6848 | ||
6849 | if (cq->first == cq->last && | |
6850 | - cq->first->mem->used == 0) { | |
1175ccec | 6851 | + (NULL == cq->first || |
f26f9fd5 ER |
6852 | + cq->first->mem->used == 0)) { |
6853 | ||
6854 | /* conn-closed, leave here */ | |
6855 | connection_set_state(srv, con, CON_STATE_ERROR); | |
f673a614 | 6856 | + |
1175ccec | 6857 | + return 0; |
f26f9fd5 ER |
6858 | } |
6859 | default: | |
6860 | break; | |
2519e6e5 ER |
6861 | @@ -891,14 +790,14 @@ |
6862 | /* the last node was empty */ | |
6863 | if (c->next == NULL) { | |
6864 | cq->last = c; | |
6865 | - } | |
6866 | + } | |
6867 | ||
6868 | c = c->next; | |
6869 | } else { | |
6870 | c = c->next; | |
6871 | } | |
6872 | } | |
6873 | - | |
6874 | + | |
6875 | /* nothing to handle */ | |
6876 | if (cq->first == NULL) return 0; | |
6877 | ||
6878 | @@ -906,25 +805,26 @@ | |
6879 | case CON_STATE_READ: | |
6880 | /* prepare con->request.request */ | |
6881 | c = cq->first; | |
6882 | - | |
6883 | + | |
6884 | /* check if we need the full package */ | |
6885 | if (con->request.request->used == 0) { | |
6886 | buffer b; | |
6887 | - | |
6888 | + | |
6889 | b.ptr = c->mem->ptr + c->offset; | |
6890 | b.used = c->mem->used - c->offset; | |
6891 | - | |
6892 | + | |
6893 | if (NULL != (h_term = buffer_search_rnrn(&b))) { | |
6894 | /* \r\n\r\n found | |
6895 | * - copy everything incl. the terminator to request.request | |
6896 | */ | |
6897 | - | |
6898 | - buffer_copy_string_len(con->request.request, | |
6899 | - b.ptr, | |
6900 | + | |
6901 | + buffer_copy_string_len(con->request.request, | |
6902 | + b.ptr, | |
6903 | h_term - b.ptr + 4); | |
6904 | - | |
6905 | + | |
f26f9fd5 ER |
6906 | /* the buffer has been read up to the terminator */ |
6907 | c->offset += h_term - b.ptr + 4; | |
f673a614 | 6908 | + |
f26f9fd5 ER |
6909 | } else { |
6910 | /* not found, copy everything */ | |
6911 | buffer_copy_string_len(con->request.request, c->mem->ptr + c->offset, c->mem->used - c->offset - 1); | |
2519e6e5 ER |
6912 | @@ -932,14 +832,14 @@ |
6913 | } | |
6914 | } else { | |
6915 | /* have to take care of overlapping header terminators */ | |
6916 | - | |
6917 | + | |
6918 | size_t l = con->request.request->used - 2; | |
6919 | char *s = con->request.request->ptr; | |
6920 | buffer b; | |
6921 | - | |
6922 | + | |
6923 | b.ptr = c->mem->ptr + c->offset; | |
6924 | b.used = c->mem->used - c->offset; | |
6925 | - | |
6926 | + | |
6927 | if (con->request.request->used - 1 > 3 && | |
6928 | c->mem->used > 1 && | |
6929 | s[l-2] == '\r' && | |
6930 | @@ -948,7 +848,7 @@ | |
6931 | c->mem->ptr[0] == '\n') { | |
6932 | buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 1); | |
6933 | c->offset += 1; | |
6934 | - | |
6935 | + | |
6936 | h_term = con->request.request->ptr; | |
6937 | } else if (con->request.request->used - 1 > 2 && | |
6938 | c->mem->used > 2 && | |
6939 | @@ -958,7 +858,7 @@ | |
6940 | c->mem->ptr[1] == '\n') { | |
6941 | buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 2); | |
6942 | c->offset += 2; | |
6943 | - | |
6944 | + | |
6945 | h_term = con->request.request->ptr; | |
6946 | } else if (con->request.request->used - 1 > 1 && | |
6947 | c->mem->used > 3 && | |
6948 | @@ -968,17 +868,17 @@ | |
6949 | c->mem->ptr[2] == '\n') { | |
6950 | buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 3); | |
6951 | c->offset += 3; | |
6952 | - | |
6953 | + | |
6954 | h_term = con->request.request->ptr; | |
6955 | } else if (NULL != (h_term = buffer_search_string_len(&b, "\r\n\r\n", 4))) { | |
6956 | /* \r\n\r\n found | |
6957 | * - copy everything incl. the terminator to request.request | |
6958 | */ | |
6959 | - | |
6960 | - buffer_append_string_len(con->request.request, | |
6961 | - c->mem->ptr + c->offset, | |
6962 | + | |
6963 | + buffer_append_string_len(con->request.request, | |
6964 | + c->mem->ptr + c->offset, | |
6965 | c->offset + h_term - b.ptr + 4); | |
6966 | - | |
6967 | + | |
6968 | /* the buffer has been read up to the terminator */ | |
6969 | c->offset += h_term - b.ptr + 4; | |
6970 | } else { | |
6971 | @@ -999,16 +899,16 @@ | |
6972 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
6973 | } | |
6974 | break; | |
6975 | - case CON_STATE_READ_POST: | |
6976 | + case CON_STATE_READ_POST: | |
6977 | for (c = cq->first; c && (dst_cq->bytes_in != (off_t)con->request.content_length); c = c->next) { | |
6978 | off_t weWant, weHave, toRead; | |
6979 | - | |
6980 | + | |
6981 | weWant = con->request.content_length - dst_cq->bytes_in; | |
6982 | - | |
6983 | + | |
6984 | assert(c->mem->used); | |
6985 | - | |
6986 | + | |
6987 | weHave = c->mem->used - c->offset - 1; | |
6988 | - | |
6989 | + | |
6990 | toRead = weHave > weWant ? weWant : weHave; | |
6991 | ||
6992 | /* the new way, copy everything into a chunkqueue whcih might use tempfiles */ | |
6993 | @@ -1017,13 +917,13 @@ | |
6994 | /* copy everything to max 1Mb sized tempfiles */ | |
6995 | ||
6996 | /* | |
6997 | - * if the last chunk is | |
6998 | + * if the last chunk is | |
6999 | * - smaller than 1Mb (size < 1Mb) | |
7000 | * - not read yet (offset == 0) | |
7001 | * -> append to it | |
7002 | * otherwise | |
7003 | - * -> create a new chunk | |
7004 | - * | |
7005 | + * -> create a new chunk | |
7006 | + * | |
7007 | * */ | |
7008 | ||
7009 | if (dst_cq->last && | |
7010 | @@ -1056,14 +956,14 @@ | |
7011 | /* we have a chunk, let's write to it */ | |
7012 | ||
7013 | if (dst_c->file.fd == -1) { | |
7014 | - /* we don't have file to write to, | |
7015 | + /* we don't have file to write to, | |
7016 | * EACCES might be one reason. | |
7017 | * | |
7018 | * Instead of sending 500 we send 413 and say the request is too large | |
7019 | * */ | |
7020 | ||
7021 | log_error_write(srv, __FILE__, __LINE__, "sbs", | |
7022 | - "denying upload as opening to temp-file for upload failed:", | |
7023 | + "denying upload as opening to temp-file for upload failed:", | |
7024 | dst_c->file.name, strerror(errno)); | |
7025 | ||
7026 | con->http_status = 413; /* Request-Entity too large */ | |
7027 | @@ -1074,15 +974,15 @@ | |
7028 | } | |
7029 | ||
7030 | if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) { | |
7031 | - /* write failed for some reason ... disk full ? */ | |
7032 | + /* write failed for some reason ... disk full ? */ | |
7033 | log_error_write(srv, __FILE__, __LINE__, "sbs", | |
7034 | - "denying upload as writing to file failed:", | |
7035 | + "denying upload as writing to file failed:", | |
7036 | dst_c->file.name, strerror(errno)); | |
7037 | - | |
7038 | + | |
7039 | con->http_status = 413; /* Request-Entity too large */ | |
7040 | con->keep_alive = 0; | |
7041 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
7042 | - | |
7043 | + | |
7044 | close(dst_c->file.fd); | |
7045 | dst_c->file.fd = -1; | |
7046 | ||
7047 | @@ -1090,7 +990,7 @@ | |
7048 | } | |
7049 | ||
7050 | dst_c->file.length += toRead; | |
7051 | - | |
7052 | + | |
7053 | if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) { | |
7054 | /* we read everything, close the chunk */ | |
7055 | close(dst_c->file.fd); | |
7056 | @@ -1102,7 +1002,7 @@ | |
7057 | b = chunkqueue_get_append_buffer(dst_cq); | |
7058 | buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead); | |
7059 | } | |
7060 | - | |
7061 | + | |
7062 | c->offset += toRead; | |
7063 | dst_cq->bytes_in += toRead; | |
7064 | } | |
7065 | @@ -1111,7 +1011,7 @@ | |
7066 | if (dst_cq->bytes_in == (off_t)con->request.content_length) { | |
7067 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
7068 | } | |
7069 | - | |
7070 | + | |
7071 | break; | |
7072 | } | |
7073 | ||
7074 | @@ -1123,9 +1023,9 @@ | |
7075 | handler_t connection_handle_fdevent(void *s, void *context, int revents) { | |
7076 | server *srv = (server *)s; | |
7077 | connection *con = context; | |
7078 | - | |
7079 | + | |
7080 | joblist_append(srv, con); | |
7081 | - | |
7082 | + | |
7083 | if (revents & FDEVENT_IN) { | |
7084 | con->is_readable = 1; | |
7085 | #if 0 | |
7086 | @@ -1136,19 +1036,19 @@ | |
7087 | con->is_writable = 1; | |
7088 | /* we don't need the event twice */ | |
7089 | } | |
7090 | - | |
7091 | - | |
7092 | + | |
7093 | + | |
7094 | if (revents & ~(FDEVENT_IN | FDEVENT_OUT)) { | |
7095 | /* looks like an error */ | |
7096 | - | |
7097 | + | |
7098 | /* FIXME: revents = 0x19 still means that we should read from the queue */ | |
7099 | if (revents & FDEVENT_HUP) { | |
7100 | if (con->state == CON_STATE_CLOSE) { | |
7101 | con->close_timeout_ts = 0; | |
7102 | } else { | |
7103 | /* sigio reports the wrong event here | |
7104 | - * | |
7105 | - * there was no HUP at all | |
7106 | + * | |
7107 | + * there was no HUP at all | |
7108 | */ | |
7109 | #ifdef USE_LINUX_SIGIO | |
7110 | if (srv->ev->in_sigio == 1) { | |
7111 | @@ -1160,32 +1060,39 @@ | |
7112 | #else | |
7113 | connection_set_state(srv, con, CON_STATE_ERROR); | |
7114 | #endif | |
7115 | - | |
7116 | + | |
7117 | } | |
7118 | } else if (revents & FDEVENT_ERR) { | |
7119 | #ifndef USE_LINUX_SIGIO | |
7120 | log_error_write(srv, __FILE__, __LINE__, "sd", | |
7121 | "connection closed: poll() -> ERR", con->fd); | |
7122 | -#endif | |
7123 | +#endif | |
7124 | connection_set_state(srv, con, CON_STATE_ERROR); | |
7125 | } else { | |
7126 | log_error_write(srv, __FILE__, __LINE__, "sd", | |
7127 | "connection closed: poll() -> ???", revents); | |
7128 | - } | |
7129 | + } | |
7130 | } | |
7131 | - | |
7132 | + | |
7133 | if (con->state == CON_STATE_READ || | |
7134 | con->state == CON_STATE_READ_POST) { | |
7135 | connection_handle_read_state(srv, con); | |
7136 | + /** | |
7137 | + * if SSL_read() is not readin in the full packet we won't get | |
7138 | + * a fdevent as the low-level has already fetched everything. | |
7139 | + * | |
7140 | + * we have to call the state-engine to read the rest of the packet | |
7141 | + */ | |
7142 | + if (con->is_readable) joblist_append(srv, con); | |
7143 | } | |
7144 | - | |
7145 | + | |
7146 | if (con->state == CON_STATE_WRITE && | |
7147 | !chunkqueue_is_empty(con->write_queue) && | |
7148 | con->is_writable) { | |
7149 | - | |
7150 | + | |
7151 | if (-1 == connection_handle_write(srv, con)) { | |
7152 | connection_set_state(srv, con, CON_STATE_ERROR); | |
7153 | - | |
7154 | + | |
7155 | log_error_write(srv, __FILE__, __LINE__, "ds", | |
7156 | con->fd, | |
7157 | "handle write failed."); | |
7158 | @@ -1193,30 +1100,30 @@ | |
7159 | con->write_request_ts = srv->cur_ts; | |
7160 | } | |
7161 | } | |
7162 | - | |
7163 | + | |
7164 | if (con->state == CON_STATE_CLOSE) { | |
7165 | /* flush the read buffers */ | |
7166 | int b; | |
7167 | - | |
7168 | + | |
7169 | if (ioctl(con->fd, FIONREAD, &b)) { | |
7170 | log_error_write(srv, __FILE__, __LINE__, "ss", | |
7171 | "ioctl() failed", strerror(errno)); | |
7172 | } | |
7173 | - | |
7174 | + | |
7175 | if (b > 0) { | |
7176 | char buf[1024]; | |
7177 | log_error_write(srv, __FILE__, __LINE__, "sdd", | |
7178 | "CLOSE-read()", con->fd, b); | |
7179 | - | |
7180 | + | |
7181 | /* */ | |
7182 | read(con->fd, buf, sizeof(buf)); | |
7183 | } else { | |
7184 | /* nothing to read */ | |
7185 | - | |
7186 | + | |
7187 | con->close_timeout_ts = 0; | |
7188 | } | |
7189 | } | |
7190 | - | |
7191 | + | |
7192 | return HANDLER_FINISHED; | |
7193 | } | |
7194 | ||
7195 | @@ -1229,63 +1136,68 @@ | |
7196 | sock_addr cnt_addr; | |
7197 | socklen_t cnt_len; | |
7198 | /* accept it and register the fd */ | |
7199 | - | |
7200 | + | |
7201 | cnt_len = sizeof(cnt_addr); | |
7202 | ||
7203 | if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) { | |
7204 | +#ifdef _WIN32 | |
1175ccec | 7205 | + errno = WSAGetLastError(); |
f26f9fd5 ER |
7206 | +#endif |
7207 | if ((errno != EAGAIN) && | |
1175ccec | 7208 | + (errno != EWOULDBLOCK) && |
f26f9fd5 ER |
7209 | (errno != EINTR)) { |
7210 | - log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno); | |
7211 | + log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), srv_socket->fd); | |
7212 | } | |
7213 | return NULL; | |
7214 | } else { | |
2519e6e5 ER |
7215 | connection *con; |
7216 | - | |
7217 | + | |
7218 | srv->cur_fds++; | |
7219 | - | |
7220 | + | |
7221 | /* ok, we have the connection, register it */ | |
7222 | #if 0 | |
7223 | log_error_write(srv, __FILE__, __LINE__, "sd", | |
7224 | "appected()", cnt); | |
7225 | #endif | |
f26f9fd5 | 7226 | srv->con_opened++; |
2519e6e5 ER |
7227 | - |
7228 | + | |
f26f9fd5 ER |
7229 | con = connections_get_new_connection(srv); |
7230 | - | |
7231 | con->fd = cnt; | |
7232 | con->fde_ndx = -1; | |
2519e6e5 ER |
7233 | -#if 0 |
7234 | +#if 0 | |
7235 | gettimeofday(&(con->start_tv), NULL); | |
7236 | -#endif | |
7237 | +#endif | |
7238 | fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con); | |
7239 | - | |
7240 | + | |
7241 | connection_set_state(srv, con, CON_STATE_REQUEST_START); | |
7242 | - | |
7243 | + | |
7244 | con->connection_start = srv->cur_ts; | |
7245 | con->dst_addr = cnt_addr; | |
7246 | buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr))); | |
7247 | con->srv_socket = srv_socket; | |
7248 | - | |
7249 | + | |
f26f9fd5 ER |
7250 | if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) { |
7251 | log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno)); | |
7252 | + connection_close(srv, con); | |
7253 | return NULL; | |
7254 | } | |
7255 | #ifdef USE_OPENSSL | |
2519e6e5 ER |
7256 | /* connect FD to SSL */ |
7257 | if (srv_socket->is_ssl) { | |
f26f9fd5 | 7258 | if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) { |
2519e6e5 ER |
7259 | - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
7260 | + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
f26f9fd5 ER |
7261 | ERR_error_string(ERR_get_error(), NULL)); |
7262 | - | |
7263 | + connection_close(srv, con); | |
7264 | return NULL; | |
7265 | } | |
2519e6e5 ER |
7266 | - |
7267 | + | |
7268 | SSL_set_accept_state(con->ssl); | |
7269 | con->conf.is_ssl=1; | |
7270 | - | |
7271 | + | |
f26f9fd5 | 7272 | if (1 != (SSL_set_fd(con->ssl, cnt))) { |
2519e6e5 ER |
7273 | - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
7274 | + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
f26f9fd5 ER |
7275 | ERR_error_string(ERR_get_error(), NULL)); |
7276 | + connection_close(srv, con); | |
7277 | return NULL; | |
7278 | } | |
7279 | } | |
2519e6e5 ER |
7280 | @@ -1300,10 +1212,10 @@ |
7281 | #ifdef USE_OPENSSL | |
7282 | server_socket *srv_sock = con->srv_socket; | |
f26f9fd5 | 7283 | #endif |
2519e6e5 | 7284 | - |
f673a614 | 7285 | + |
2519e6e5 ER |
7286 | if (srv->srvconf.log_state_handling) { |
7287 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7288 | - "state at start", | |
7289 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7290 | + "state at start", | |
7291 | con->fd, | |
7292 | connection_get_state(con->state)); | |
7293 | } | |
7294 | @@ -1311,91 +1223,91 @@ | |
7295 | while (done == 0) { | |
7296 | size_t ostate = con->state; | |
7297 | int b; | |
7298 | - | |
f26f9fd5 | 7299 | + |
2519e6e5 ER |
7300 | switch (con->state) { |
7301 | case CON_STATE_REQUEST_START: /* transient */ | |
7302 | if (srv->srvconf.log_state_handling) { | |
7303 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7304 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7305 | "state for fd", con->fd, connection_get_state(con->state)); | |
7306 | } | |
7307 | - | |
7308 | + | |
7309 | con->request_start = srv->cur_ts; | |
7310 | con->read_idle_ts = srv->cur_ts; | |
7311 | - | |
7312 | + | |
7313 | con->request_count++; | |
7314 | con->loops_per_request = 0; | |
7315 | - | |
7316 | + | |
7317 | connection_set_state(srv, con, CON_STATE_READ); | |
7318 | - | |
7319 | + | |
7320 | break; | |
7321 | case CON_STATE_REQUEST_END: /* transient */ | |
7322 | if (srv->srvconf.log_state_handling) { | |
7323 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7324 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7325 | "state for fd", con->fd, connection_get_state(con->state)); | |
7326 | } | |
7327 | - | |
7328 | + | |
7329 | if (http_request_parse(srv, con)) { | |
7330 | /* we have to read some data from the POST request */ | |
7331 | - | |
7332 | + | |
7333 | connection_set_state(srv, con, CON_STATE_READ_POST); | |
f673a614 | 7334 | |
2519e6e5 ER |
7335 | break; |
7336 | } | |
7337 | - | |
f673a614 | 7338 | + |
2519e6e5 ER |
7339 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); |
7340 | - | |
f673a614 | 7341 | + |
2519e6e5 ER |
7342 | break; |
7343 | case CON_STATE_HANDLE_REQUEST: | |
7344 | - /* | |
7345 | + /* | |
7346 | * the request is parsed | |
7347 | - * | |
7348 | + * | |
7349 | * decided what to do with the request | |
7350 | - * - | |
7351 | - * | |
7352 | - * | |
7353 | + * - | |
7354 | + * | |
7355 | + * | |
7356 | */ | |
7357 | - | |
f26f9fd5 | 7358 | + |
2519e6e5 ER |
7359 | if (srv->srvconf.log_state_handling) { |
7360 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7361 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7362 | "state for fd", con->fd, connection_get_state(con->state)); | |
7363 | } | |
7364 | - | |
f26f9fd5 | 7365 | + |
2519e6e5 ER |
7366 | switch (r = http_response_prepare(srv, con)) { |
7367 | case HANDLER_FINISHED: | |
7368 | if (con->http_status == 404 || | |
7369 | con->http_status == 403) { | |
7370 | /* 404 error-handler */ | |
7371 | - | |
7372 | - if (con->in_error_handler == 0 && | |
f26f9fd5 | 7373 | + |
2519e6e5 ER |
7374 | + if (con->in_error_handler == 0 && |
7375 | (!buffer_is_empty(con->conf.error_handler) || | |
7376 | !buffer_is_empty(con->error_handler))) { | |
7377 | /* call error-handler */ | |
7378 | - | |
7379 | + | |
7380 | con->error_handler_saved_status = con->http_status; | |
7381 | con->http_status = 0; | |
7382 | - | |
7383 | + | |
7384 | if (buffer_is_empty(con->error_handler)) { | |
7385 | buffer_copy_string_buffer(con->request.uri, con->conf.error_handler); | |
7386 | } else { | |
7387 | buffer_copy_string_buffer(con->request.uri, con->error_handler); | |
7388 | } | |
7389 | buffer_reset(con->physical.path); | |
7390 | - | |
7391 | + | |
7392 | con->in_error_handler = 1; | |
7393 | - | |
7394 | + | |
7395 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
7396 | - | |
7397 | + | |
7398 | done = -1; | |
7399 | break; | |
7400 | } else if (con->in_error_handler) { | |
7401 | /* error-handler is a 404 */ | |
7402 | - | |
7403 | + | |
7404 | /* continue as normal, status is the same */ | |
7405 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
7406 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
7407 | "Warning: Either the error-handler returned status 404 or the error-handler itself was not found:", con->request.uri); | |
7408 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
7409 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
7410 | "returning the original status", con->error_handler_saved_status); | |
7411 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
7412 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
7413 | "If this is a rails app: check your production.log"); | |
7414 | con->http_status = con->error_handler_saved_status; | |
f26f9fd5 | 7415 | } |
2519e6e5 ER |
7416 | @@ -1403,26 +1315,26 @@ |
7417 | /* error-handler is back and has generated content */ | |
7418 | /* if Status: was set, take it otherwise use 200 */ | |
7419 | } | |
7420 | - | |
f673a614 | 7421 | + |
2519e6e5 ER |
7422 | if (con->http_status == 0) con->http_status = 200; |
7423 | - | |
f673a614 | 7424 | + |
2519e6e5 ER |
7425 | /* we have something to send, go on */ |
7426 | connection_set_state(srv, con, CON_STATE_RESPONSE_START); | |
7427 | break; | |
7428 | case HANDLER_WAIT_FOR_FD: | |
7429 | srv->want_fds++; | |
7430 | - | |
f673a614 | 7431 | + |
2519e6e5 ER |
7432 | fdwaitqueue_append(srv, con); |
7433 | - | |
f673a614 | 7434 | + |
2519e6e5 ER |
7435 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); |
7436 | - | |
f673a614 | 7437 | + |
2519e6e5 ER |
7438 | break; |
7439 | case HANDLER_COMEBACK: | |
7440 | done = -1; | |
7441 | case HANDLER_WAIT_FOR_EVENT: | |
7442 | /* come back here */ | |
7443 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
7444 | - | |
f673a614 | 7445 | + |
2519e6e5 ER |
7446 | break; |
7447 | case HANDLER_ERROR: | |
7448 | /* something went wrong */ | |
7449 | @@ -1432,44 +1344,44 @@ | |
7450 | log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r); | |
7451 | break; | |
7452 | } | |
7453 | - | |
7454 | + | |
7455 | break; | |
7456 | case CON_STATE_RESPONSE_START: | |
7457 | - /* | |
7458 | + /* | |
7459 | * the decision is done | |
7460 | * - create the HTTP-Response-Header | |
7461 | - * | |
7462 | + * | |
7463 | */ | |
7464 | - | |
7465 | + | |
7466 | if (srv->srvconf.log_state_handling) { | |
7467 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7468 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7469 | "state for fd", con->fd, connection_get_state(con->state)); | |
7470 | } | |
7471 | - | |
7472 | + | |
7473 | if (-1 == connection_handle_write_prepare(srv, con)) { | |
7474 | connection_set_state(srv, con, CON_STATE_ERROR); | |
7475 | - | |
7476 | + | |
7477 | break; | |
7478 | } | |
7479 | - | |
7480 | + | |
7481 | connection_set_state(srv, con, CON_STATE_WRITE); | |
7482 | break; | |
7483 | case CON_STATE_RESPONSE_END: /* transient */ | |
7484 | /* log the request */ | |
7485 | - | |
7486 | + | |
7487 | if (srv->srvconf.log_state_handling) { | |
7488 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7489 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7490 | "state for fd", con->fd, connection_get_state(con->state)); | |
7491 | } | |
7492 | - | |
7493 | + | |
7494 | plugins_call_handle_request_done(srv, con); | |
7495 | - | |
7496 | + | |
7497 | srv->con_written++; | |
7498 | - | |
7499 | + | |
7500 | if (con->keep_alive) { | |
7501 | connection_set_state(srv, con, CON_STATE_REQUEST_START); | |
7502 | - | |
7503 | -#if 0 | |
7504 | + | |
7505 | +#if 0 | |
7506 | con->request_start = srv->cur_ts; | |
7507 | con->read_idle_ts = srv->cur_ts; | |
7508 | #endif | |
7509 | @@ -1482,7 +1394,7 @@ | |
7510 | log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r); | |
7511 | break; | |
7512 | } | |
7513 | - | |
f673a614 | 7514 | + |
f26f9fd5 | 7515 | #ifdef USE_OPENSSL |
2519e6e5 ER |
7516 | if (srv_sock->is_ssl) { |
7517 | switch (SSL_shutdown(con->ssl)) { | |
7518 | @@ -1490,44 +1402,44 @@ | |
7519 | /* done */ | |
7520 | break; | |
7521 | case 0: | |
7522 | - /* wait for fd-event | |
7523 | - * | |
7524 | + /* wait for fd-event | |
7525 | + * | |
7526 | * FIXME: wait for fdevent and call SSL_shutdown again | |
7527 | - * | |
7528 | + * | |
7529 | */ | |
7530 | - | |
7531 | + | |
7532 | break; | |
7533 | default: | |
7534 | - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
7535 | + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
7536 | ERR_error_string(ERR_get_error(), NULL)); | |
7537 | } | |
7538 | } | |
f26f9fd5 | 7539 | #endif |
2519e6e5 ER |
7540 | connection_close(srv, con); |
7541 | - | |
7542 | + | |
7543 | srv->con_closed++; | |
7544 | } | |
7545 | - | |
7546 | + | |
7547 | connection_reset(srv, con); | |
7548 | - | |
7549 | + | |
7550 | break; | |
7551 | case CON_STATE_CONNECT: | |
7552 | if (srv->srvconf.log_state_handling) { | |
7553 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7554 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7555 | "state for fd", con->fd, connection_get_state(con->state)); | |
7556 | } | |
7557 | - | |
7558 | + | |
7559 | chunkqueue_reset(con->read_queue); | |
7560 | - | |
7561 | + | |
7562 | con->request_count = 0; | |
7563 | - | |
7564 | + | |
7565 | break; | |
7566 | case CON_STATE_CLOSE: | |
7567 | if (srv->srvconf.log_state_handling) { | |
7568 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7569 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7570 | "state for fd", con->fd, connection_get_state(con->state)); | |
7571 | } | |
7572 | - | |
7573 | + | |
7574 | if (con->keep_alive) { | |
7575 | if (ioctl(con->fd, FIONREAD, &b)) { | |
7576 | log_error_write(srv, __FILE__, __LINE__, "ss", | |
7577 | @@ -1537,43 +1449,43 @@ | |
7578 | char buf[1024]; | |
7579 | log_error_write(srv, __FILE__, __LINE__, "sdd", | |
7580 | "CLOSE-read()", con->fd, b); | |
7581 | - | |
7582 | + | |
7583 | /* */ | |
7584 | read(con->fd, buf, sizeof(buf)); | |
7585 | } else { | |
7586 | /* nothing to read */ | |
7587 | - | |
7588 | + | |
7589 | con->close_timeout_ts = 0; | |
7590 | } | |
7591 | } else { | |
7592 | con->close_timeout_ts = 0; | |
7593 | } | |
7594 | - | |
7595 | + | |
7596 | if (srv->cur_ts - con->close_timeout_ts > 1) { | |
7597 | connection_close(srv, con); | |
7598 | - | |
7599 | + | |
7600 | if (srv->srvconf.log_state_handling) { | |
7601 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
7602 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
7603 | "connection closed for fd", con->fd); | |
7604 | } | |
7605 | } | |
7606 | - | |
7607 | + | |
7608 | break; | |
7609 | case CON_STATE_READ_POST: | |
7610 | case CON_STATE_READ: | |
7611 | if (srv->srvconf.log_state_handling) { | |
7612 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7613 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7614 | "state for fd", con->fd, connection_get_state(con->state)); | |
7615 | } | |
7616 | - | |
7617 | + | |
7618 | connection_handle_read_state(srv, con); | |
7619 | break; | |
7620 | case CON_STATE_WRITE: | |
7621 | if (srv->srvconf.log_state_handling) { | |
7622 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7623 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7624 | "state for fd", con->fd, connection_get_state(con->state)); | |
7625 | } | |
7626 | - | |
7627 | + | |
7628 | /* only try to write if we have something in the queue */ | |
7629 | if (!chunkqueue_is_empty(con->write_queue)) { | |
7630 | #if 0 | |
7631 | @@ -1593,10 +1505,10 @@ | |
7632 | con->write_request_ts = srv->cur_ts; | |
7633 | } | |
7634 | } | |
7635 | - | |
7636 | + | |
7637 | break; | |
7638 | case CON_STATE_ERROR: /* transient */ | |
7639 | - | |
7640 | + | |
7641 | /* even if the connection was drop we still have to write it to the access log */ | |
7642 | if (con->http_status) { | |
7643 | plugins_call_handle_request_done(srv, con); | |
7644 | @@ -1612,19 +1524,19 @@ | |
7645 | SSL_shutdown(con->ssl); | |
7646 | break; | |
7647 | default: | |
7648 | - log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", | |
7649 | - SSL_get_error(con->ssl, ret), | |
7650 | + log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", | |
7651 | + SSL_get_error(con->ssl, ret), | |
7652 | ERR_error_string(ERR_get_error(), NULL)); | |
7653 | return -1; | |
7654 | } | |
7655 | } | |
f26f9fd5 | 7656 | #endif |
2519e6e5 ER |
7657 | - |
7658 | + | |
7659 | switch(con->mode) { | |
7660 | case DIRECT: | |
7661 | #if 0 | |
7662 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
7663 | - "emergency exit: direct", | |
7664 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
7665 | + "emergency exit: direct", | |
7666 | con->fd); | |
7667 | #endif | |
7668 | break; | |
7669 | @@ -1639,35 +1551,35 @@ | |
7670 | } | |
7671 | break; | |
7672 | } | |
7673 | - | |
7674 | + | |
7675 | connection_reset(srv, con); | |
7676 | - | |
7677 | + | |
7678 | /* close the connection */ | |
7679 | if ((con->keep_alive == 1) && | |
7680 | (0 == shutdown(con->fd, SHUT_WR))) { | |
7681 | con->close_timeout_ts = srv->cur_ts; | |
7682 | connection_set_state(srv, con, CON_STATE_CLOSE); | |
7683 | - | |
7684 | + | |
7685 | if (srv->srvconf.log_state_handling) { | |
7686 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
7687 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
7688 | "shutdown for fd", con->fd); | |
7689 | } | |
7690 | } else { | |
7691 | connection_close(srv, con); | |
7692 | } | |
7693 | - | |
7694 | + | |
7695 | con->keep_alive = 0; | |
7696 | - | |
7697 | + | |
7698 | srv->con_closed++; | |
7699 | - | |
7700 | + | |
7701 | break; | |
7702 | default: | |
7703 | - log_error_write(srv, __FILE__, __LINE__, "sdd", | |
7704 | + log_error_write(srv, __FILE__, __LINE__, "sdd", | |
7705 | "unknown state:", con->fd, con->state); | |
7706 | - | |
7707 | + | |
7708 | break; | |
7709 | } | |
7710 | - | |
7711 | + | |
7712 | if (done == -1) { | |
7713 | done = 0; | |
7714 | } else if (ostate == con->state) { | |
7715 | @@ -1676,12 +1588,12 @@ | |
7716 | } | |
f673a614 | 7717 | |
2519e6e5 ER |
7718 | if (srv->srvconf.log_state_handling) { |
7719 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
7720 | - "state at exit:", | |
7721 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
7722 | + "state at exit:", | |
7723 | con->fd, | |
7724 | connection_get_state(con->state)); | |
7725 | } | |
7726 | - | |
7727 | + | |
7728 | switch(con->state) { | |
7729 | case CON_STATE_READ_POST: | |
7730 | case CON_STATE_READ: | |
7731 | @@ -1689,11 +1601,11 @@ | |
7732 | fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN); | |
7733 | break; | |
7734 | case CON_STATE_WRITE: | |
7735 | - /* request write-fdevent only if we really need it | |
7736 | + /* request write-fdevent only if we really need it | |
7737 | * - if we have data to write | |
7738 | - * - if the socket is not writable yet | |
7739 | + * - if the socket is not writable yet | |
7740 | */ | |
7741 | - if (!chunkqueue_is_empty(con->write_queue) && | |
7742 | + if (!chunkqueue_is_empty(con->write_queue) && | |
7743 | (con->is_writable == 0) && | |
7744 | (con->traffic_limit_reached == 0)) { | |
7745 | fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT); | |
1175ccec | 7746 | --- ../lighttpd-1.4.11/src/crc32.h 2005-09-30 20:18:59.000000000 +0300 |
36e2a29e | 7747 | +++ lighttpd-1.4.12/src/crc32.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
7748 | @@ -6,6 +6,7 @@ |
7749 | #endif | |
f673a614 | 7750 | |
2519e6e5 ER |
7751 | #include <sys/types.h> |
7752 | +#include <stdlib.h> | |
f673a614 | 7753 | |
2519e6e5 ER |
7754 | #if defined HAVE_STDINT_H |
7755 | #include <stdint.h> | |
7756 | @@ -13,6 +14,10 @@ | |
7757 | #include <inttypes.h> | |
f26f9fd5 | 7758 | #endif |
f673a614 | 7759 | |
f26f9fd5 | 7760 | +#ifdef _WIN32 |
2519e6e5 | 7761 | +#define uint32_t unsigned __int32 |
f26f9fd5 ER |
7762 | +#endif |
7763 | + | |
2519e6e5 | 7764 | uint32_t generate_crc32c(char *string, size_t length); |
f673a614 | 7765 | |
f26f9fd5 | 7766 | #endif |
1175ccec | 7767 | --- ../lighttpd-1.4.11/src/data_array.c 2005-08-23 17:36:12.000000000 +0300 |
36e2a29e | 7768 | +++ lighttpd-1.4.12/src/data_array.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 | 7769 | @@ -17,16 +17,16 @@ |
f673a614 | 7770 | |
2519e6e5 ER |
7771 | static void data_array_free(data_unset *d) { |
7772 | data_array *ds = (data_array *)d; | |
7773 | - | |
7774 | + | |
7775 | buffer_free(ds->key); | |
7776 | array_free(ds->value); | |
7777 | - | |
7778 | + | |
7779 | free(d); | |
7780 | } | |
f673a614 | 7781 | |
2519e6e5 ER |
7782 | static void data_array_reset(data_unset *d) { |
7783 | data_array *ds = (data_array *)d; | |
7784 | - | |
7785 | + | |
7786 | /* reused array elements */ | |
7787 | buffer_reset(ds->key); | |
7788 | array_reset(ds->value); | |
7789 | @@ -36,7 +36,7 @@ | |
7790 | UNUSED(dst); | |
f673a614 | 7791 | |
2519e6e5 ER |
7792 | src->free(src); |
7793 | - | |
f26f9fd5 | 7794 | + |
2519e6e5 | 7795 | return 0; |
f673a614 ER |
7796 | } |
7797 | ||
2519e6e5 | 7798 | @@ -48,18 +48,18 @@ |
f673a614 | 7799 | |
2519e6e5 ER |
7800 | data_array *data_array_init(void) { |
7801 | data_array *ds; | |
7802 | - | |
7803 | + | |
7804 | ds = calloc(1, sizeof(*ds)); | |
7805 | - | |
7806 | + | |
7807 | ds->key = buffer_init(); | |
7808 | ds->value = array_init(); | |
7809 | - | |
7810 | + | |
7811 | ds->copy = data_array_copy; | |
7812 | ds->free = data_array_free; | |
7813 | ds->reset = data_array_reset; | |
7814 | ds->insert_dup = data_array_insert_dup; | |
7815 | ds->print = data_array_print; | |
7816 | ds->type = TYPE_ARRAY; | |
7817 | - | |
7818 | + | |
7819 | return ds; | |
f673a614 | 7820 | } |
1175ccec | 7821 | --- ../lighttpd-1.4.11/src/data_config.c 2005-08-17 12:53:19.000000000 +0300 |
36e2a29e | 7822 | +++ lighttpd-1.4.12/src/data_config.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 | 7823 | @@ -17,26 +17,26 @@ |
f673a614 | 7824 | |
2519e6e5 ER |
7825 | static void data_config_free(data_unset *d) { |
7826 | data_config *ds = (data_config *)d; | |
7827 | - | |
7828 | + | |
7829 | buffer_free(ds->key); | |
7830 | buffer_free(ds->op); | |
7831 | buffer_free(ds->comp_key); | |
7832 | - | |
7833 | + | |
7834 | array_free(ds->value); | |
7835 | array_free(ds->childs); | |
7836 | - | |
7837 | + | |
7838 | if (ds->string) buffer_free(ds->string); | |
7839 | #ifdef HAVE_PCRE_H | |
7840 | if (ds->regex) pcre_free(ds->regex); | |
7841 | if (ds->regex_study) pcre_free(ds->regex_study); | |
7842 | #endif | |
7843 | - | |
7844 | + | |
7845 | free(d); | |
7846 | } | |
f673a614 | 7847 | |
2519e6e5 ER |
7848 | static void data_config_reset(data_unset *d) { |
7849 | data_config *ds = (data_config *)d; | |
7850 | - | |
7851 | + | |
7852 | /* reused array elements */ | |
7853 | buffer_reset(ds->key); | |
7854 | buffer_reset(ds->comp_key); | |
7855 | @@ -45,9 +45,9 @@ | |
f673a614 | 7856 | |
2519e6e5 ER |
7857 | static int data_config_insert_dup(data_unset *dst, data_unset *src) { |
7858 | UNUSED(dst); | |
7859 | - | |
7860 | + | |
7861 | src->free(src); | |
7862 | - | |
7863 | + | |
7864 | return 0; | |
7865 | } | |
f673a614 | 7866 | |
2519e6e5 ER |
7867 | @@ -56,7 +56,7 @@ |
7868 | array *a = (array *)ds->value; | |
7869 | size_t i; | |
7870 | size_t maxlen; | |
f673a614 | 7871 | - |
2519e6e5 ER |
7872 | + |
7873 | if (0 == ds->context_ndx) { | |
7874 | fprintf(stderr, "config {\n"); | |
f26f9fd5 | 7875 | } |
2519e6e5 ER |
7876 | @@ -117,22 +117,22 @@ |
7877 | ||
7878 | data_config *data_config_init(void) { | |
7879 | data_config *ds; | |
7880 | - | |
7881 | + | |
7882 | ds = calloc(1, sizeof(*ds)); | |
7883 | - | |
7884 | + | |
7885 | ds->key = buffer_init(); | |
7886 | ds->op = buffer_init(); | |
7887 | ds->comp_key = buffer_init(); | |
7888 | ds->value = array_init(); | |
7889 | ds->childs = array_init(); | |
7890 | ds->childs->is_weakref = 1; | |
7891 | - | |
7892 | + | |
7893 | ds->copy = data_config_copy; | |
7894 | ds->free = data_config_free; | |
7895 | ds->reset = data_config_reset; | |
7896 | ds->insert_dup = data_config_insert_dup; | |
7897 | ds->print = data_config_print; | |
7898 | ds->type = TYPE_CONFIG; | |
7899 | - | |
7900 | + | |
7901 | return ds; | |
f673a614 | 7902 | } |
1175ccec | 7903 | --- ../lighttpd-1.4.11/src/data_count.c 2005-08-23 17:36:12.000000000 +0300 |
36e2a29e | 7904 | +++ lighttpd-1.4.12/src/data_count.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 | 7905 | @@ -16,53 +16,53 @@ |
f673a614 | 7906 | |
2519e6e5 ER |
7907 | static void data_count_free(data_unset *d) { |
7908 | data_count *ds = (data_count *)d; | |
7909 | - | |
7910 | + | |
7911 | buffer_free(ds->key); | |
7912 | - | |
7913 | + | |
7914 | free(d); | |
7915 | } | |
7916 | ||
7917 | static void data_count_reset(data_unset *d) { | |
7918 | data_count *ds = (data_count *)d; | |
7919 | - | |
7920 | + | |
7921 | buffer_reset(ds->key); | |
7922 | - | |
7923 | + | |
7924 | ds->count = 0; | |
7925 | } | |
7926 | ||
7927 | static int data_count_insert_dup(data_unset *dst, data_unset *src) { | |
7928 | data_count *ds_dst = (data_count *)dst; | |
7929 | data_count *ds_src = (data_count *)src; | |
7930 | - | |
7931 | + | |
7932 | ds_dst->count += ds_src->count; | |
7933 | - | |
7934 | + | |
7935 | src->free(src); | |
7936 | - | |
7937 | + | |
f26f9fd5 | 7938 | return 0; |
f673a614 ER |
7939 | } |
7940 | ||
2519e6e5 ER |
7941 | static void data_count_print(const data_unset *d, int depth) { |
7942 | data_count *ds = (data_count *)d; | |
7943 | UNUSED(depth); | |
7944 | - | |
7945 | + | |
7946 | fprintf(stderr, "count(%d)", ds->count); | |
7947 | } | |
f673a614 | 7948 | |
f673a614 | 7949 | |
2519e6e5 ER |
7950 | data_count *data_count_init(void) { |
7951 | data_count *ds; | |
7952 | - | |
7953 | + | |
7954 | ds = calloc(1, sizeof(*ds)); | |
7955 | - | |
7956 | + | |
7957 | ds->key = buffer_init(); | |
7958 | ds->count = 1; | |
7959 | - | |
7960 | + | |
7961 | ds->copy = data_count_copy; | |
7962 | ds->free = data_count_free; | |
7963 | ds->reset = data_count_reset; | |
7964 | ds->insert_dup = data_count_insert_dup; | |
7965 | ds->print = data_count_print; | |
7966 | ds->type = TYPE_COUNT; | |
7967 | - | |
7968 | + | |
7969 | return ds; | |
f673a614 | 7970 | } |
1175ccec | 7971 | --- ../lighttpd-1.4.11/src/data_fastcgi.c 2005-08-23 17:36:12.000000000 +0300 |
36e2a29e | 7972 | +++ lighttpd-1.4.12/src/data_fastcgi.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 | 7973 | @@ -17,53 +17,53 @@ |
f673a614 | 7974 | |
2519e6e5 ER |
7975 | static void data_fastcgi_free(data_unset *d) { |
7976 | data_fastcgi *ds = (data_fastcgi *)d; | |
7977 | - | |
7978 | + | |
7979 | buffer_free(ds->key); | |
7980 | buffer_free(ds->host); | |
7981 | - | |
7982 | + | |
7983 | free(d); | |
7984 | } | |
7985 | ||
7986 | static void data_fastcgi_reset(data_unset *d) { | |
7987 | data_fastcgi *ds = (data_fastcgi *)d; | |
7988 | - | |
7989 | + | |
7990 | buffer_reset(ds->key); | |
7991 | buffer_reset(ds->host); | |
7992 | - | |
7993 | + | |
7994 | } | |
7995 | ||
7996 | static int data_fastcgi_insert_dup(data_unset *dst, data_unset *src) { | |
7997 | UNUSED(dst); | |
7998 | ||
7999 | src->free(src); | |
8000 | - | |
8001 | + | |
f26f9fd5 | 8002 | return 0; |
f673a614 ER |
8003 | } |
8004 | ||
2519e6e5 ER |
8005 | static void data_fastcgi_print(const data_unset *d, int depth) { |
8006 | data_fastcgi *ds = (data_fastcgi *)d; | |
8007 | UNUSED(depth); | |
8008 | - | |
8009 | + | |
8010 | fprintf(stderr, "fastcgi(%s)", ds->host->ptr); | |
8011 | } | |
f673a614 | 8012 | |
f673a614 | 8013 | |
2519e6e5 ER |
8014 | data_fastcgi *data_fastcgi_init(void) { |
8015 | data_fastcgi *ds; | |
8016 | - | |
f673a614 | 8017 | + |
2519e6e5 ER |
8018 | ds = calloc(1, sizeof(*ds)); |
8019 | - | |
8020 | + | |
8021 | ds->key = buffer_init(); | |
8022 | ds->host = buffer_init(); | |
8023 | ds->port = 0; | |
8024 | ds->is_disabled = 0; | |
8025 | - | |
8026 | + | |
8027 | ds->copy = data_fastcgi_copy; | |
8028 | ds->free = data_fastcgi_free; | |
8029 | ds->reset = data_fastcgi_reset; | |
8030 | ds->insert_dup = data_fastcgi_insert_dup; | |
8031 | ds->print = data_fastcgi_print; | |
8032 | ds->type = TYPE_FASTCGI; | |
8033 | - | |
8034 | + | |
8035 | return ds; | |
8036 | } | |
1175ccec | 8037 | --- ../lighttpd-1.4.11/src/data_integer.c 2005-08-23 17:36:12.000000000 +0300 |
36e2a29e | 8038 | +++ lighttpd-1.4.12/src/data_integer.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
8039 | @@ -16,15 +16,15 @@ |
8040 | ||
8041 | static void data_integer_free(data_unset *d) { | |
8042 | data_integer *ds = (data_integer *)d; | |
8043 | - | |
8044 | + | |
8045 | buffer_free(ds->key); | |
8046 | - | |
8047 | + | |
8048 | free(d); | |
8049 | } | |
f26f9fd5 | 8050 | |
2519e6e5 ER |
8051 | static void data_integer_reset(data_unset *d) { |
8052 | data_integer *ds = (data_integer *)d; | |
8053 | - | |
8054 | + | |
8055 | /* reused integer elements */ | |
8056 | buffer_reset(ds->key); | |
8057 | ds->value = 0; | |
8058 | @@ -32,9 +32,9 @@ | |
f26f9fd5 | 8059 | |
2519e6e5 ER |
8060 | static int data_integer_insert_dup(data_unset *dst, data_unset *src) { |
8061 | UNUSED(dst); | |
8062 | - | |
8063 | + | |
8064 | src->free(src); | |
8065 | - | |
8066 | + | |
8067 | return 0; | |
f673a614 ER |
8068 | } |
8069 | ||
2519e6e5 | 8070 | @@ -48,18 +48,18 @@ |
f673a614 | 8071 | |
2519e6e5 ER |
8072 | data_integer *data_integer_init(void) { |
8073 | data_integer *ds; | |
8074 | - | |
8075 | + | |
8076 | ds = calloc(1, sizeof(*ds)); | |
8077 | - | |
8078 | + | |
8079 | ds->key = buffer_init(); | |
8080 | ds->value = 0; | |
8081 | - | |
8082 | + | |
8083 | ds->copy = data_integer_copy; | |
8084 | ds->free = data_integer_free; | |
8085 | ds->reset = data_integer_reset; | |
8086 | ds->insert_dup = data_integer_insert_dup; | |
8087 | ds->print = data_integer_print; | |
8088 | ds->type = TYPE_INTEGER; | |
8089 | - | |
8090 | + | |
8091 | return ds; | |
8092 | } | |
1175ccec | 8093 | --- ../lighttpd-1.4.11/src/data_string.c 2005-08-23 17:36:12.000000000 +0300 |
36e2a29e | 8094 | +++ lighttpd-1.4.12/src/data_string.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
8095 | @@ -17,16 +17,16 @@ |
8096 | ||
8097 | static void data_string_free(data_unset *d) { | |
8098 | data_string *ds = (data_string *)d; | |
8099 | - | |
8100 | + | |
8101 | buffer_free(ds->key); | |
8102 | buffer_free(ds->value); | |
8103 | - | |
8104 | + | |
8105 | free(d); | |
8106 | } | |
8107 | ||
8108 | static void data_string_reset(data_unset *d) { | |
8109 | data_string *ds = (data_string *)d; | |
8110 | - | |
8111 | + | |
8112 | /* reused array elements */ | |
8113 | buffer_reset(ds->key); | |
8114 | buffer_reset(ds->value); | |
8115 | @@ -35,23 +35,23 @@ | |
8116 | static int data_string_insert_dup(data_unset *dst, data_unset *src) { | |
8117 | data_string *ds_dst = (data_string *)dst; | |
8118 | data_string *ds_src = (data_string *)src; | |
8119 | - | |
8120 | + | |
8121 | if (ds_dst->value->used) { | |
8122 | buffer_append_string(ds_dst->value, ", "); | |
8123 | buffer_append_string_buffer(ds_dst->value, ds_src->value); | |
8124 | } else { | |
8125 | buffer_copy_string_buffer(ds_dst->value, ds_src->value); | |
f26f9fd5 | 8126 | } |
2519e6e5 ER |
8127 | - |
8128 | + | |
8129 | src->free(src); | |
8130 | - | |
8131 | + | |
f26f9fd5 | 8132 | return 0; |
f673a614 ER |
8133 | } |
8134 | ||
2519e6e5 ER |
8135 | static int data_response_insert_dup(data_unset *dst, data_unset *src) { |
8136 | data_string *ds_dst = (data_string *)dst; | |
8137 | data_string *ds_src = (data_string *)src; | |
8138 | - | |
8139 | + | |
8140 | if (ds_dst->value->used) { | |
8141 | buffer_append_string(ds_dst->value, "\r\n"); | |
8142 | buffer_append_string_buffer(ds_dst->value, ds_dst->key); | |
8143 | @@ -60,9 +60,9 @@ | |
8144 | } else { | |
8145 | buffer_copy_string_buffer(ds_dst->value, ds_src->value); | |
8146 | } | |
8147 | - | |
8148 | + | |
8149 | src->free(src); | |
8150 | - | |
8151 | + | |
8152 | return 0; | |
8153 | } | |
8154 | ||
8155 | @@ -77,28 +77,28 @@ | |
8156 | ||
8157 | data_string *data_string_init(void) { | |
8158 | data_string *ds; | |
8159 | - | |
8160 | + | |
8161 | ds = calloc(1, sizeof(*ds)); | |
8162 | assert(ds); | |
8163 | - | |
8164 | + | |
8165 | ds->key = buffer_init(); | |
8166 | ds->value = buffer_init(); | |
8167 | - | |
8168 | + | |
8169 | ds->copy = data_string_copy; | |
8170 | ds->free = data_string_free; | |
8171 | ds->reset = data_string_reset; | |
8172 | ds->insert_dup = data_string_insert_dup; | |
8173 | ds->print = data_string_print; | |
8174 | ds->type = TYPE_STRING; | |
8175 | - | |
8176 | + | |
8177 | return ds; | |
8178 | } | |
8179 | ||
8180 | data_string *data_response_init(void) { | |
8181 | data_string *ds; | |
8182 | - | |
8183 | + | |
8184 | ds = data_string_init(); | |
8185 | ds->insert_dup = data_response_insert_dup; | |
8186 | - | |
8187 | + | |
8188 | return ds; | |
8189 | } | |
1175ccec | 8190 | --- ../lighttpd-1.4.11/src/etag.c 2005-08-11 01:26:40.000000000 +0300 |
36e2a29e | 8191 | +++ lighttpd-1.4.12/src/etag.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
8192 | @@ -14,19 +14,19 @@ |
8193 | buffer_append_off_t(etag, st->st_size); | |
8194 | buffer_append_string_len(etag, CONST_STR_LEN("-")); | |
8195 | buffer_append_long(etag, st->st_mtime); | |
8196 | - | |
8197 | + | |
8198 | return 0; | |
8199 | } | |
8200 | ||
8201 | int etag_mutate(buffer *mut, buffer *etag) { | |
8202 | size_t h, i; | |
8203 | - | |
8204 | + | |
8205 | for (h=0, i=0; i < etag->used; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]); | |
8206 | - | |
8207 | + | |
8208 | buffer_reset(mut); | |
8209 | buffer_copy_string_len(mut, CONST_STR_LEN("\"")); | |
8210 | buffer_append_long(mut, h); | |
8211 | buffer_append_string_len(mut, CONST_STR_LEN("\"")); | |
8212 | - | |
8213 | + | |
8214 | return 0; | |
8215 | } | |
1175ccec | 8216 | --- ../lighttpd-1.4.11/src/etag.h 2005-08-11 01:26:40.000000000 +0300 |
36e2a29e | 8217 | +++ lighttpd-1.4.12/src/etag.h 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 | 8218 | @@ -3,13 +3,12 @@ |
f673a614 | 8219 | |
2519e6e5 ER |
8220 | #include <sys/types.h> |
8221 | #include <sys/stat.h> | |
f26f9fd5 | 8222 | -#include <unistd.h> |
f673a614 | 8223 | |
2519e6e5 | 8224 | #include "buffer.h" |
f26f9fd5 | 8225 | |
2519e6e5 ER |
8226 | int etag_is_equal(buffer *etag, const char *matches); |
8227 | int etag_create(buffer *etag, struct stat *st); | |
8228 | int etag_mutate(buffer *mut, buffer *etag); | |
8229 | - | |
f673a614 | 8230 | + |
2519e6e5 | 8231 | |
f26f9fd5 | 8232 | #endif |
1175ccec | 8233 | --- ../lighttpd-1.4.11/src/fastcgi.h 2005-08-11 01:26:40.000000000 +0300 |
36e2a29e | 8234 | +++ lighttpd-1.4.12/src/fastcgi.h 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
8235 | @@ -1,4 +1,4 @@ |
8236 | -/* | |
8237 | +/* | |
8238 | * fastcgi.h -- | |
8239 | * | |
8240 | * Defines for the FastCGI protocol. | |
8241 | @@ -123,7 +123,7 @@ | |
f26f9fd5 | 8242 | |
f26f9fd5 | 8243 | |
2519e6e5 ER |
8244 | typedef struct { |
8245 | - unsigned char type; | |
8246 | + unsigned char type; | |
8247 | unsigned char reserved[7]; | |
8248 | } FCGI_UnknownTypeBody; | |
f673a614 | 8249 | |
1175ccec | 8250 | --- ../lighttpd-1.4.11/src/fdevent.c 2005-11-15 10:51:05.000000000 +0200 |
36e2a29e | 8251 | +++ lighttpd-1.4.12/src/fdevent.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 | 8252 | @@ -2,7 +2,6 @@ |
f673a614 | 8253 | |
2519e6e5 | 8254 | #include "settings.h" |
f673a614 | 8255 | |
2519e6e5 | 8256 | -#include <unistd.h> |
f26f9fd5 ER |
8257 | #include <stdlib.h> |
8258 | #include <string.h> | |
8259 | #include <errno.h> | |
2519e6e5 ER |
8260 | @@ -12,59 +11,61 @@ |
8261 | #include "fdevent.h" | |
f26f9fd5 | 8262 | #include "buffer.h" |
f673a614 | 8263 | |
2519e6e5 ER |
8264 | +#include "sys-socket.h" |
8265 | + | |
8266 | fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type) { | |
8267 | fdevents *ev; | |
8268 | - | |
8269 | + | |
8270 | ev = calloc(1, sizeof(*ev)); | |
8271 | ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray)); | |
8272 | ev->maxfds = maxfds; | |
8273 | - | |
8274 | + | |
8275 | switch(type) { | |
8276 | case FDEVENT_HANDLER_POLL: | |
8277 | if (0 != fdevent_poll_init(ev)) { | |
8278 | - fprintf(stderr, "%s.%d: event-handler poll failed\n", | |
8279 | + fprintf(stderr, "%s.%d: event-handler poll failed\n", | |
8280 | __FILE__, __LINE__); | |
8281 | - | |
8282 | + | |
8283 | return NULL; | |
8284 | } | |
8285 | break; | |
8286 | case FDEVENT_HANDLER_SELECT: | |
8287 | if (0 != fdevent_select_init(ev)) { | |
8288 | - fprintf(stderr, "%s.%d: event-handler select failed\n", | |
8289 | + fprintf(stderr, "%s.%d: event-handler select failed\n", | |
8290 | __FILE__, __LINE__); | |
8291 | return NULL; | |
8292 | } | |
8293 | break; | |
8294 | case FDEVENT_HANDLER_LINUX_RTSIG: | |
8295 | if (0 != fdevent_linux_rtsig_init(ev)) { | |
8296 | - fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8297 | + fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8298 | __FILE__, __LINE__); | |
8299 | return NULL; | |
8300 | } | |
8301 | break; | |
8302 | case FDEVENT_HANDLER_LINUX_SYSEPOLL: | |
8303 | if (0 != fdevent_linux_sysepoll_init(ev)) { | |
8304 | - fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8305 | + fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8306 | __FILE__, __LINE__); | |
8307 | return NULL; | |
8308 | } | |
8309 | break; | |
8310 | case FDEVENT_HANDLER_SOLARIS_DEVPOLL: | |
8311 | if (0 != fdevent_solaris_devpoll_init(ev)) { | |
8312 | - fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8313 | + fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8314 | __FILE__, __LINE__); | |
8315 | return NULL; | |
8316 | } | |
8317 | break; | |
8318 | case FDEVENT_HANDLER_FREEBSD_KQUEUE: | |
8319 | if (0 != fdevent_freebsd_kqueue_init(ev)) { | |
8320 | - fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8321 | + fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8322 | __FILE__, __LINE__); | |
8323 | return NULL; | |
f673a614 | 8324 | } |
2519e6e5 ER |
8325 | break; |
8326 | default: | |
8327 | - fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8328 | + fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n", | |
8329 | __FILE__, __LINE__); | |
8330 | return NULL; | |
f673a614 | 8331 | } |
2519e6e5 ER |
8332 | @@ -75,26 +76,26 @@ |
8333 | void fdevent_free(fdevents *ev) { | |
8334 | size_t i; | |
8335 | if (!ev) return; | |
8336 | - | |
8337 | + | |
8338 | if (ev->free) ev->free(ev); | |
8339 | - | |
8340 | + | |
8341 | for (i = 0; i < ev->maxfds; i++) { | |
8342 | if (ev->fdarray[i]) free(ev->fdarray[i]); | |
8343 | } | |
8344 | - | |
8345 | + | |
8346 | free(ev->fdarray); | |
8347 | free(ev); | |
f26f9fd5 | 8348 | } |
f26f9fd5 | 8349 | |
2519e6e5 ER |
8350 | int fdevent_reset(fdevents *ev) { |
8351 | if (ev->reset) return ev->reset(ev); | |
8352 | - | |
f673a614 | 8353 | + |
2519e6e5 | 8354 | return 0; |
f26f9fd5 | 8355 | } |
f26f9fd5 | 8356 | |
2519e6e5 ER |
8357 | fdnode *fdnode_init() { |
8358 | fdnode *fdn; | |
f673a614 | 8359 | - |
2519e6e5 ER |
8360 | + |
8361 | fdn = calloc(1, sizeof(*fdn)); | |
8362 | fdn->fd = -1; | |
8363 | return fdn; | |
8364 | @@ -106,12 +107,12 @@ | |
f26f9fd5 | 8365 | |
2519e6e5 ER |
8366 | int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) { |
8367 | fdnode *fdn; | |
8368 | - | |
f673a614 | 8369 | + |
2519e6e5 ER |
8370 | fdn = fdnode_init(); |
8371 | fdn->handler = handler; | |
8372 | fdn->fd = fd; | |
8373 | fdn->ctx = ctx; | |
8374 | - | |
f673a614 | 8375 | + |
2519e6e5 ER |
8376 | ev->fdarray[fd] = fdn; |
8377 | ||
8378 | return 0; | |
8379 | @@ -121,31 +122,31 @@ | |
8380 | fdnode *fdn; | |
8381 | if (!ev) return 0; | |
8382 | fdn = ev->fdarray[fd]; | |
8383 | - | |
f673a614 | 8384 | + |
2519e6e5 ER |
8385 | fdnode_free(fdn); |
8386 | - | |
f673a614 | 8387 | + |
2519e6e5 ER |
8388 | ev->fdarray[fd] = NULL; |
8389 | - | |
f673a614 | 8390 | + |
2519e6e5 ER |
8391 | return 0; |
8392 | } | |
8393 | ||
8394 | int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) { | |
8395 | int fde = fde_ndx ? *fde_ndx : -1; | |
8396 | - | |
f673a614 | 8397 | + |
2519e6e5 ER |
8398 | if (ev->event_del) fde = ev->event_del(ev, fde, fd); |
8399 | - | |
f673a614 | 8400 | + |
2519e6e5 ER |
8401 | if (fde_ndx) *fde_ndx = fde; |
8402 | - | |
f673a614 | 8403 | + |
2519e6e5 ER |
8404 | return 0; |
8405 | } | |
8406 | ||
8407 | int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events) { | |
8408 | int fde = fde_ndx ? *fde_ndx : -1; | |
8409 | - | |
f673a614 | 8410 | + |
2519e6e5 ER |
8411 | if (ev->event_add) fde = ev->event_add(ev, fde, fd, events); |
8412 | - | |
f673a614 | 8413 | + |
2519e6e5 ER |
8414 | if (fde_ndx) *fde_ndx = fde; |
8415 | - | |
f673a614 | 8416 | + |
2519e6e5 ER |
8417 | return 0; |
8418 | } | |
8419 | ||
8420 | @@ -156,38 +157,43 @@ | |
8421 | ||
8422 | int fdevent_event_get_revent(fdevents *ev, size_t ndx) { | |
8423 | if (ev->event_get_revent == NULL) SEGFAULT(); | |
8424 | - | |
f673a614 | 8425 | + |
2519e6e5 ER |
8426 | return ev->event_get_revent(ev, ndx); |
8427 | } | |
8428 | ||
8429 | int fdevent_event_get_fd(fdevents *ev, size_t ndx) { | |
8430 | if (ev->event_get_fd == NULL) SEGFAULT(); | |
8431 | - | |
f673a614 | 8432 | + |
2519e6e5 ER |
8433 | return ev->event_get_fd(ev, ndx); |
8434 | } | |
8435 | ||
8436 | fdevent_handler fdevent_get_handler(fdevents *ev, int fd) { | |
8437 | if (ev->fdarray[fd] == NULL) SEGFAULT(); | |
8438 | if (ev->fdarray[fd]->fd != fd) SEGFAULT(); | |
8439 | - | |
f673a614 | 8440 | + |
2519e6e5 ER |
8441 | return ev->fdarray[fd]->handler; |
8442 | } | |
8443 | ||
8444 | void * fdevent_get_context(fdevents *ev, int fd) { | |
8445 | if (ev->fdarray[fd] == NULL) SEGFAULT(); | |
8446 | if (ev->fdarray[fd]->fd != fd) SEGFAULT(); | |
8447 | - | |
f673a614 | 8448 | + |
2519e6e5 ER |
8449 | return ev->fdarray[fd]->ctx; |
8450 | } | |
8451 | ||
8452 | int fdevent_fcntl_set(fdevents *ev, int fd) { | |
8453 | +#ifdef _WIN32 | |
8454 | + int i = 1; | |
8455 | +#endif | |
8456 | #ifdef FD_CLOEXEC | |
8457 | /* close fd on exec (cgi) */ | |
8458 | fcntl(fd, F_SETFD, FD_CLOEXEC); | |
8459 | #endif | |
8460 | if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd); | |
8461 | -#ifdef O_NONBLOCK | |
8462 | +#ifdef O_NONBLOCK | |
8463 | return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR); | |
8464 | +#elif defined _WIN32 | |
8465 | + return ioctlsocket(fd, FIONBIO, &i); | |
8466 | #else | |
8467 | return 0; | |
8468 | #endif | |
8469 | @@ -196,7 +202,7 @@ | |
8470 | ||
8471 | int fdevent_event_next_fdndx(fdevents *ev, int ndx) { | |
8472 | if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx); | |
8473 | - | |
f673a614 | 8474 | + |
2519e6e5 ER |
8475 | return -1; |
8476 | } | |
8477 | ||
1175ccec | 8478 | --- ../lighttpd-1.4.11/src/fdevent.h 2005-09-27 11:26:33.000000000 +0300 |
36e2a29e | 8479 | +++ lighttpd-1.4.12/src/fdevent.h 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
8480 | @@ -17,13 +17,13 @@ |
8481 | # include <sys/epoll.h> | |
8482 | #endif | |
8483 | ||
8484 | -/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes | |
8485 | +/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes | |
8486 | * under /usr/include/sys/ */ | |
8487 | #if defined HAVE_POLL && (defined(HAVE_SYS_POLL_H) || defined(HAVE_POLL_H)) | |
8488 | # define USE_POLL | |
8489 | # ifdef HAVE_POLL_H | |
8490 | # include <poll.h> | |
8491 | -# else | |
8492 | +# else | |
8493 | # include <sys/poll.h> | |
8494 | # endif | |
8495 | # if defined HAVE_SIGTIMEDWAIT && defined(__linux__) | |
8496 | @@ -31,9 +31,11 @@ | |
8497 | # include <signal.h> | |
8498 | # endif | |
8499 | #endif | |
8500 | - | |
8501 | +#ifdef _WIN32 | |
8502 | +# define HAVE_SELECT | |
8503 | +#endif | |
8504 | #if defined HAVE_SELECT | |
8505 | -# ifdef __WIN32 | |
8506 | +# ifdef _WIN32 | |
8507 | # include <winsock2.h> | |
8508 | # endif | |
8509 | # define USE_SELECT | |
8510 | @@ -67,14 +69,14 @@ | |
8511 | #define FDEVENT_HUP BV(4) | |
8512 | #define FDEVENT_NVAL BV(5) | |
8513 | ||
8514 | -typedef enum { FD_EVENT_TYPE_UNSET = -1, | |
8515 | - FD_EVENT_TYPE_CONNECTION, | |
8516 | - FD_EVENT_TYPE_FCGI_CONNECTION, | |
8517 | - FD_EVENT_TYPE_DIRWATCH, | |
8518 | - FD_EVENT_TYPE_CGI_CONNECTION | |
8519 | +typedef enum { FD_EVENT_TYPE_UNSET = -1, | |
8520 | + FD_EVENT_TYPE_CONNECTION, | |
8521 | + FD_EVENT_TYPE_FCGI_CONNECTION, | |
8522 | + FD_EVENT_TYPE_DIRWATCH, | |
8523 | + FD_EVENT_TYPE_CGI_CONNECTION | |
8524 | } fd_event_t; | |
8525 | ||
8526 | -typedef enum { FDEVENT_HANDLER_UNSET, | |
8527 | +typedef enum { FDEVENT_HANDLER_UNSET, | |
8528 | FDEVENT_HANDLER_SELECT, | |
8529 | FDEVENT_HANDLER_POLL, | |
8530 | FDEVENT_HANDLER_LINUX_RTSIG, | |
8531 | @@ -86,7 +88,7 @@ | |
8532 | ||
8533 | /** | |
8534 | * a mapping from fd to connection structure | |
8535 | - * | |
8536 | + * | |
8537 | */ | |
8538 | typedef struct { | |
8539 | int fd; /**< the fd */ | |
8540 | @@ -98,41 +100,41 @@ | |
8541 | ||
8542 | typedef struct { | |
8543 | fd_conn *ptr; | |
8544 | - | |
8545 | + | |
8546 | size_t size; | |
8547 | size_t used; | |
8548 | } fd_conn_buffer; | |
8549 | ||
8550 | /** | |
8551 | * array of unused fd's | |
8552 | - * | |
8553 | + * | |
8554 | */ | |
8555 | ||
8556 | typedef struct _fdnode { | |
8557 | fdevent_handler handler; | |
8558 | void *ctx; | |
8559 | int fd; | |
8560 | - | |
8561 | + | |
8562 | struct _fdnode *prev, *next; | |
8563 | } fdnode; | |
8564 | ||
8565 | typedef struct { | |
8566 | int *ptr; | |
8567 | - | |
8568 | + | |
8569 | size_t used; | |
8570 | size_t size; | |
8571 | } buffer_int; | |
8572 | ||
8573 | /** | |
8574 | * fd-event handler for select(), poll() and rt-signals on Linux 2.4 | |
8575 | - * | |
8576 | + * | |
8577 | */ | |
8578 | typedef struct fdevents { | |
8579 | fdevent_handler_t type; | |
8580 | - | |
8581 | + | |
8582 | fdnode **fdarray; | |
8583 | size_t maxfds; | |
8584 | - | |
8585 | + | |
8586 | #ifdef USE_LINUX_SIGIO | |
8587 | int in_sigio; | |
8588 | int signum; | |
8589 | @@ -146,21 +148,21 @@ | |
8590 | #endif | |
8591 | #ifdef USE_POLL | |
8592 | struct pollfd *pollfds; | |
8593 | - | |
8594 | + | |
8595 | size_t size; | |
8596 | size_t used; | |
8597 | - | |
8598 | + | |
8599 | buffer_int unused; | |
8600 | #endif | |
8601 | #ifdef USE_SELECT | |
8602 | fd_set select_read; | |
8603 | fd_set select_write; | |
8604 | fd_set select_error; | |
8605 | - | |
8606 | + | |
8607 | fd_set select_set_read; | |
8608 | fd_set select_set_write; | |
8609 | fd_set select_set_error; | |
8610 | - | |
8611 | + | |
8612 | int select_max_fd; | |
8613 | #endif | |
8614 | #ifdef USE_SOLARIS_DEVPOLL | |
8615 | @@ -177,16 +179,16 @@ | |
8616 | #endif | |
8617 | int (*reset)(struct fdevents *ev); | |
8618 | void (*free)(struct fdevents *ev); | |
8619 | - | |
8620 | + | |
8621 | int (*event_add)(struct fdevents *ev, int fde_ndx, int fd, int events); | |
8622 | int (*event_del)(struct fdevents *ev, int fde_ndx, int fd); | |
8623 | int (*event_get_revent)(struct fdevents *ev, size_t ndx); | |
8624 | int (*event_get_fd)(struct fdevents *ev, size_t ndx); | |
8625 | - | |
8626 | + | |
8627 | int (*event_next_fdndx)(struct fdevents *ev, int ndx); | |
8628 | - | |
8629 | + | |
8630 | int (*poll)(struct fdevents *ev, int timeout_ms); | |
8631 | - | |
8632 | + | |
8633 | int (*fcntl_set)(struct fdevents *ev, int fd); | |
8634 | } fdevents; | |
8635 | ||
1175ccec | 8636 | --- ../lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c 2005-09-01 10:46:24.000000000 +0300 |
36e2a29e | 8637 | +++ lighttpd-1.4.12/src/fdevent_freebsd_kqueue.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
8638 | @@ -1,6 +1,5 @@ |
8639 | #include <sys/types.h> | |
8640 | ||
8641 | -#include <unistd.h> | |
8642 | #include <stdlib.h> | |
8643 | #include <stdio.h> | |
8644 | #include <string.h> | |
8645 | @@ -48,7 +47,7 @@ | |
8646 | ||
f26f9fd5 ER |
8647 | return -1; |
8648 | } | |
2519e6e5 | 8649 | - |
f673a614 | 8650 | + |
2519e6e5 | 8651 | return -1; |
f26f9fd5 | 8652 | } |
2519e6e5 ER |
8653 | |
8654 | @@ -65,7 +64,7 @@ | |
8655 | ||
8656 | ts.tv_sec = 0; | |
8657 | ts.tv_nsec = 0; | |
f26f9fd5 | 8658 | - |
2519e6e5 ER |
8659 | + |
8660 | ret = kevent(ev->kq_fd, | |
8661 | &kev, 1, | |
8662 | NULL, 0, | |
8663 | @@ -77,7 +76,7 @@ | |
8664 | ||
f26f9fd5 ER |
8665 | return -1; |
8666 | } | |
2519e6e5 | 8667 | - |
f673a614 | 8668 | + |
2519e6e5 ER |
8669 | if (filter == EVFILT_READ) { |
8670 | bitset_set_bit(ev->kq_bevents, fd); | |
8671 | } else { | |
8672 | @@ -124,7 +123,7 @@ | |
8673 | } else if (e == EVFILT_WRITE) { | |
8674 | events |= FDEVENT_OUT; | |
f26f9fd5 | 8675 | } |
2519e6e5 ER |
8676 | - |
8677 | + | |
8678 | e = ev->kq_results[ndx].flags; | |
8679 | ||
8680 | if (e & EV_EOF) { | |
8681 | @@ -152,10 +151,10 @@ | |
8682 | if (-1 == (ev->kq_fd = kqueue())) { | |
8683 | fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n", | |
8684 | __FILE__, __LINE__, strerror(errno)); | |
8685 | - | |
8686 | + | |
8687 | return -1; | |
f26f9fd5 | 8688 | } |
2519e6e5 ER |
8689 | - |
8690 | + | |
f26f9fd5 ER |
8691 | return 0; |
8692 | } | |
f673a614 | 8693 | |
2519e6e5 ER |
8694 | @@ -186,7 +185,7 @@ |
8695 | if (-1 == (ev->kq_fd = kqueue())) { | |
8696 | fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n", | |
8697 | __FILE__, __LINE__, strerror(errno)); | |
8698 | - | |
8699 | + | |
8700 | return -1; | |
8701 | } | |
f673a614 | 8702 | |
1175ccec ER |
8703 | --- ../lighttpd-1.4.11/src/fdevent_linux_rtsig.c 2005-11-21 19:56:11.000000000 +0200 |
8704 | +++ lighttpd-1.4.12/src/fdevent_linux_rtsig.c 2006-07-15 22:43:21.000000000 +0300 | |
2519e6e5 ER |
8705 | @@ -1,6 +1,5 @@ |
8706 | #include <sys/types.h> | |
8707 | ||
8708 | -#include <unistd.h> | |
8709 | #include <stdlib.h> | |
8710 | #include <stdio.h> | |
8711 | #include <string.h> | |
1175ccec ER |
8712 | @@ -14,6 +13,7 @@ |
8713 | #include "fdevent.h" | |
8714 | #include "settings.h" | |
8715 | #include "buffer.h" | |
8716 | +#include "sys-process.h" | |
8717 | ||
8718 | #ifdef USE_LINUX_SIGIO | |
8719 | static void fdevent_linux_rtsig_free(fdevents *ev) { | |
8720 | @@ -26,19 +26,19 @@ | |
2519e6e5 ER |
8721 | |
8722 | static int fdevent_linux_rtsig_event_del(fdevents *ev, int fde_ndx, int fd) { | |
8723 | if (fde_ndx < 0) return -1; | |
8724 | - | |
8725 | + | |
8726 | if ((size_t)fde_ndx >= ev->used) { | |
8727 | fprintf(stderr, "%s.%d: del! out of range %d %zu\n", __FILE__, __LINE__, fde_ndx, ev->used); | |
8728 | SEGFAULT(); | |
f673a614 | 8729 | } |
2519e6e5 ER |
8730 | - |
8731 | + | |
8732 | if (ev->pollfds[fde_ndx].fd == fd) { | |
8733 | size_t k = fde_ndx; | |
8734 | - | |
8735 | + | |
8736 | ev->pollfds[k].fd = -1; | |
f673a614 | 8737 | |
2519e6e5 ER |
8738 | bitset_clear_bit(ev->sigbset, fd); |
8739 | - | |
f673a614 | 8740 | + |
2519e6e5 ER |
8741 | if (ev->unused.size == 0) { |
8742 | ev->unused.size = 16; | |
8743 | ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size); | |
1175ccec | 8744 | @@ -46,29 +46,29 @@ |
2519e6e5 ER |
8745 | ev->unused.size += 16; |
8746 | ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size); | |
8747 | } | |
8748 | - | |
f673a614 | 8749 | + |
2519e6e5 ER |
8750 | ev->unused.ptr[ev->unused.used++] = k; |
8751 | } else { | |
8752 | fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd); | |
8753 | - | |
f673a614 | 8754 | + |
2519e6e5 ER |
8755 | SEGFAULT(); |
8756 | } | |
8757 | - | |
f673a614 | 8758 | + |
2519e6e5 ER |
8759 | return -1; |
8760 | } | |
f26f9fd5 | 8761 | |
2519e6e5 ER |
8762 | #if 0 |
8763 | static int fdevent_linux_rtsig_event_compress(fdevents *ev) { | |
8764 | size_t j; | |
8765 | - | |
8766 | + | |
8767 | if (ev->used == 0) return 0; | |
8768 | if (ev->unused.used != 0) return 0; | |
8769 | - | |
8770 | + | |
8771 | for (j = ev->used - 1; j + 1 > 0; j--) { | |
8772 | if (ev->pollfds[j].fd == -1) ev->used--; | |
8773 | } | |
8774 | - | |
8775 | - | |
8776 | + | |
8777 | + | |
8778 | return 0; | |
8779 | } | |
f26f9fd5 | 8780 | #endif |
1175ccec | 8781 | @@ -78,21 +78,21 @@ |
2519e6e5 ER |
8782 | if (fde_ndx != -1) { |
8783 | if (ev->pollfds[fde_ndx].fd == fd) { | |
8784 | ev->pollfds[fde_ndx].events = events; | |
8785 | - | |
8786 | + | |
8787 | return fde_ndx; | |
8788 | } | |
8789 | fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd); | |
8790 | SEGFAULT(); | |
8791 | } | |
8792 | - | |
8793 | + | |
8794 | if (ev->unused.used > 0) { | |
8795 | int k = ev->unused.ptr[--ev->unused.used]; | |
8796 | - | |
8797 | + | |
8798 | ev->pollfds[k].fd = fd; | |
8799 | ev->pollfds[k].events = events; | |
f26f9fd5 | 8800 | |
2519e6e5 ER |
8801 | bitset_set_bit(ev->sigbset, fd); |
8802 | - | |
f673a614 | 8803 | + |
2519e6e5 ER |
8804 | return k; |
8805 | } else { | |
8806 | if (ev->size == 0) { | |
1175ccec | 8807 | @@ -102,12 +102,12 @@ |
2519e6e5 ER |
8808 | ev->size += 16; |
8809 | ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size); | |
8810 | } | |
8811 | - | |
8812 | + | |
8813 | ev->pollfds[ev->used].fd = fd; | |
8814 | ev->pollfds[ev->used].events = events; | |
f26f9fd5 | 8815 | |
2519e6e5 ER |
8816 | bitset_set_bit(ev->sigbset, fd); |
8817 | - | |
8818 | + | |
8819 | return ev->used++; | |
8820 | } | |
f26f9fd5 | 8821 | } |
1175ccec | 8822 | @@ -115,20 +115,20 @@ |
2519e6e5 ER |
8823 | static int fdevent_linux_rtsig_poll(fdevents *ev, int timeout_ms) { |
8824 | struct timespec ts; | |
8825 | int r; | |
8826 | - | |
8827 | + | |
8828 | #if 0 | |
8829 | fdevent_linux_rtsig_event_compress(ev); | |
8830 | #endif | |
8831 | - | |
8832 | + | |
8833 | ev->in_sigio = 1; | |
8834 | - | |
8835 | + | |
8836 | ts.tv_sec = timeout_ms / 1000; | |
8837 | ts.tv_nsec = (timeout_ms % 1000) * 1000000; | |
8838 | r = sigtimedwait(&(ev->sigset), &(ev->siginfo), &(ts)); | |
8839 | - | |
8840 | - if (r == -1) { | |
8841 | + | |
8842 | + if (r == -1) { | |
8843 | if (errno == EAGAIN) return 0; | |
8844 | - return r; | |
8845 | + return r; | |
8846 | } else if (r == SIGIO) { | |
8847 | struct sigaction act; | |
8848 | ||
1175ccec | 8849 | @@ -140,7 +140,7 @@ |
2519e6e5 ER |
8850 | /* re-enable the signal queue */ |
8851 | act.sa_handler = SIG_DFL; | |
8852 | sigaction(ev->signum, &act, NULL); | |
8853 | - | |
8854 | + | |
8855 | ev->in_sigio = 0; | |
8856 | r = poll(ev->pollfds, ev->used, timeout_ms); | |
f26f9fd5 | 8857 | |
1175ccec | 8858 | @@ -162,12 +162,12 @@ |
2519e6e5 ER |
8859 | if (ev->siginfo.si_band == POLLERR) { |
8860 | fprintf(stderr, "event: %d %02lx %02x %s\n", ev->siginfo.si_fd, ev->siginfo.si_band, errno, strerror(errno)); | |
8861 | } | |
8862 | -# endif | |
8863 | +# endif | |
8864 | if (ndx != 0) { | |
8865 | fprintf(stderr, "+\n"); | |
8866 | return 0; | |
8867 | } | |
8868 | - | |
8869 | + | |
8870 | return ev->siginfo.si_band & 0x3f; | |
8871 | } else { | |
8872 | if (ndx >= ev->used) { | |
1175ccec | 8873 | @@ -188,13 +188,13 @@ |
f26f9fd5 | 8874 | |
2519e6e5 ER |
8875 | static int fdevent_linux_rtsig_fcntl_set(fdevents *ev, int fd) { |
8876 | static pid_t pid = 0; | |
8877 | - | |
8878 | + | |
8879 | if (pid == 0) pid = getpid(); | |
8880 | - | |
8881 | + | |
8882 | if (-1 == fcntl(fd, F_SETSIG, ev->signum)) return -1; | |
8883 | - | |
8884 | + | |
8885 | if (-1 == fcntl(fd, F_SETOWN, (int) pid)) return -1; | |
8886 | - | |
8887 | + | |
8888 | return fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR); | |
8889 | } | |
8890 | ||
1175ccec | 8891 | @@ -205,12 +205,12 @@ |
2519e6e5 ER |
8892 | return -1; |
8893 | } else { | |
8894 | size_t i; | |
8895 | - | |
8896 | + | |
8897 | i = (ndx < 0) ? 0 : ndx + 1; | |
8898 | for (; i < ev->used; i++) { | |
8899 | if (ev->pollfds[i].revents) break; | |
f26f9fd5 | 8900 | } |
2519e6e5 ER |
8901 | - |
8902 | + | |
8903 | return i; | |
f26f9fd5 | 8904 | } |
f26f9fd5 | 8905 | } |
1175ccec | 8906 | @@ -219,34 +219,34 @@ |
2519e6e5 ER |
8907 | ev->type = FDEVENT_HANDLER_LINUX_RTSIG; |
8908 | #define SET(x) \ | |
8909 | ev->x = fdevent_linux_rtsig_##x; | |
8910 | - | |
8911 | + | |
8912 | SET(free); | |
8913 | SET(poll); | |
8914 | - | |
8915 | + | |
8916 | SET(event_del); | |
8917 | SET(event_add); | |
8918 | - | |
8919 | + | |
8920 | SET(event_next_fdndx); | |
8921 | SET(fcntl_set); | |
8922 | SET(event_get_fd); | |
8923 | SET(event_get_revent); | |
8924 | - | |
8925 | + | |
8926 | ev->signum = SIGRTMIN + 1; | |
8927 | - | |
8928 | + | |
8929 | sigemptyset(&(ev->sigset)); | |
8930 | sigaddset(&(ev->sigset), ev->signum); | |
8931 | sigaddset(&(ev->sigset), SIGIO); | |
8932 | if (-1 == sigprocmask(SIG_BLOCK, &(ev->sigset), NULL)) { | |
8933 | fprintf(stderr, "%s.%d: sigprocmask failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n", | |
8934 | __FILE__, __LINE__, strerror(errno)); | |
8935 | - | |
8936 | + | |
8937 | return -1; | |
f26f9fd5 | 8938 | } |
2519e6e5 ER |
8939 | - |
8940 | + | |
8941 | ev->in_sigio = 1; | |
8942 | ||
8943 | ev->sigbset = bitset_init(ev->maxfds); | |
8944 | - | |
8945 | + | |
8946 | return 0; | |
8947 | } | |
f26f9fd5 | 8948 | #else |
1175ccec | 8949 | --- ../lighttpd-1.4.11/src/fdevent_linux_sysepoll.c 2005-09-30 20:29:27.000000000 +0300 |
36e2a29e | 8950 | +++ lighttpd-1.4.12/src/fdevent_linux_sysepoll.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
8951 | @@ -1,6 +1,5 @@ |
8952 | #include <sys/types.h> | |
f673a614 | 8953 | |
2519e6e5 ER |
8954 | -#include <unistd.h> |
8955 | #include <stdlib.h> | |
8956 | #include <stdio.h> | |
8957 | #include <string.h> | |
8958 | @@ -12,6 +11,8 @@ | |
8959 | #include "settings.h" | |
8960 | #include "buffer.h" | |
f673a614 | 8961 | |
2519e6e5 ER |
8962 | +#include "sys-files.h" |
8963 | + | |
8964 | #ifdef USE_LINUX_EPOLL | |
8965 | static void fdevent_linux_sysepoll_free(fdevents *ev) { | |
8966 | close(ev->epoll_fd); | |
8967 | @@ -20,36 +21,36 @@ | |
8968 | ||
8969 | static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) { | |
8970 | struct epoll_event ep; | |
8971 | - | |
8972 | + | |
8973 | if (fde_ndx < 0) return -1; | |
8974 | - | |
8975 | + | |
8976 | memset(&ep, 0, sizeof(ep)); | |
8977 | - | |
8978 | + | |
8979 | ep.data.fd = fd; | |
8980 | ep.data.ptr = NULL; | |
8981 | - | |
8982 | + | |
8983 | if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) { | |
8984 | fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno)); | |
8985 | - | |
8986 | + | |
8987 | SEGFAULT(); | |
8988 | - | |
8989 | + | |
8990 | return 0; | |
8991 | } | |
8992 | - | |
8993 | - | |
8994 | + | |
8995 | + | |
8996 | return -1; | |
f26f9fd5 | 8997 | } |
f673a614 | 8998 | |
2519e6e5 ER |
8999 | static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) { |
9000 | struct epoll_event ep; | |
9001 | int add = 0; | |
9002 | - | |
9003 | + | |
9004 | if (fde_ndx == -1) add = 1; | |
9005 | - | |
9006 | + | |
9007 | memset(&ep, 0, sizeof(ep)); | |
9008 | - | |
9009 | + | |
9010 | ep.events = 0; | |
9011 | - | |
9012 | + | |
9013 | if (events & FDEVENT_IN) ep.events |= EPOLLIN; | |
9014 | if (events & FDEVENT_OUT) ep.events |= EPOLLOUT; | |
f673a614 | 9015 | |
2519e6e5 ER |
9016 | @@ -60,20 +61,20 @@ |
9017 | * sent. | |
9018 | * | |
9019 | */ | |
9020 | - | |
9021 | + | |
9022 | ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */; | |
9023 | - | |
9024 | + | |
9025 | ep.data.ptr = NULL; | |
9026 | ep.data.fd = fd; | |
9027 | - | |
9028 | + | |
9029 | if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) { | |
9030 | fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno)); | |
9031 | - | |
9032 | + | |
9033 | SEGFAULT(); | |
9034 | - | |
9035 | + | |
9036 | return 0; | |
f673a614 | 9037 | } |
2519e6e5 ER |
9038 | - |
9039 | + | |
9040 | return fd; | |
f673a614 ER |
9041 | } |
9042 | ||
2519e6e5 | 9043 | @@ -83,14 +84,14 @@ |
f673a614 | 9044 | |
2519e6e5 ER |
9045 | static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) { |
9046 | int events = 0, e; | |
9047 | - | |
f673a614 | 9048 | + |
2519e6e5 ER |
9049 | e = ev->epoll_events[ndx].events; |
9050 | if (e & EPOLLIN) events |= FDEVENT_IN; | |
9051 | if (e & EPOLLOUT) events |= FDEVENT_OUT; | |
9052 | if (e & EPOLLERR) events |= FDEVENT_ERR; | |
9053 | if (e & EPOLLHUP) events |= FDEVENT_HUP; | |
9054 | if (e & EPOLLPRI) events |= FDEVENT_PRI; | |
9055 | - | |
9056 | + | |
9057 | return e; | |
f673a614 ER |
9058 | } |
9059 | ||
2519e6e5 ER |
9060 | @@ -98,17 +99,17 @@ |
9061 | # if 0 | |
9062 | fprintf(stderr, "%s.%d: %d, %d\n", __FILE__, __LINE__, ndx, ev->epoll_events[ndx].data.fd); | |
9063 | # endif | |
9064 | - | |
9065 | + | |
9066 | return ev->epoll_events[ndx].data.fd; | |
f673a614 | 9067 | } |
f673a614 | 9068 | |
2519e6e5 ER |
9069 | static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) { |
9070 | size_t i; | |
9071 | - | |
9072 | + | |
9073 | UNUSED(ev); | |
f673a614 | 9074 | |
2519e6e5 ER |
9075 | i = (ndx < 0) ? 0 : ndx + 1; |
9076 | - | |
9077 | + | |
9078 | return i; | |
f673a614 | 9079 | } |
f26f9fd5 | 9080 | |
2519e6e5 ER |
9081 | @@ -116,17 +117,17 @@ |
9082 | ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL; | |
9083 | #define SET(x) \ | |
9084 | ev->x = fdevent_linux_sysepoll_##x; | |
9085 | - | |
9086 | + | |
9087 | SET(free); | |
9088 | SET(poll); | |
9089 | - | |
9090 | + | |
9091 | SET(event_del); | |
9092 | SET(event_add); | |
9093 | - | |
9094 | + | |
9095 | SET(event_next_fdndx); | |
9096 | SET(event_get_fd); | |
9097 | SET(event_get_revent); | |
9098 | - | |
9099 | + | |
9100 | if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) { | |
9101 | fprintf(stderr, "%s.%d: epoll_create failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n", | |
9102 | __FILE__, __LINE__, strerror(errno)); | |
9103 | @@ -154,7 +155,7 @@ | |
f26f9fd5 | 9104 | |
2519e6e5 ER |
9105 | fprintf(stderr, "%s.%d: linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n", |
9106 | __FILE__, __LINE__); | |
9107 | - | |
9108 | + | |
9109 | return -1; | |
9110 | } | |
f26f9fd5 | 9111 | #endif |
1175ccec | 9112 | --- ../lighttpd-1.4.11/src/fdevent_poll.c 2005-11-18 13:59:16.000000000 +0200 |
36e2a29e | 9113 | +++ lighttpd-1.4.12/src/fdevent_poll.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
9114 | @@ -1,6 +1,5 @@ |
9115 | #include <sys/types.h> | |
f26f9fd5 | 9116 | |
2519e6e5 ER |
9117 | -#include <unistd.h> |
9118 | #include <stdlib.h> | |
9119 | #include <stdio.h> | |
9120 | #include <string.h> | |
9121 | @@ -20,19 +19,19 @@ | |
f26f9fd5 | 9122 | |
2519e6e5 ER |
9123 | static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) { |
9124 | if (fde_ndx < 0) return -1; | |
9125 | - | |
9126 | + | |
9127 | if ((size_t)fde_ndx >= ev->used) { | |
9128 | fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, fde_ndx, ev->used); | |
9129 | SEGFAULT(); | |
9130 | } | |
9131 | - | |
9132 | + | |
9133 | if (ev->pollfds[fde_ndx].fd == fd) { | |
9134 | size_t k = fde_ndx; | |
9135 | - | |
9136 | + | |
9137 | ev->pollfds[k].fd = -1; | |
9138 | /* ev->pollfds[k].events = 0; */ | |
9139 | /* ev->pollfds[k].revents = 0; */ | |
9140 | - | |
9141 | + | |
9142 | if (ev->unused.size == 0) { | |
9143 | ev->unused.size = 16; | |
9144 | ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size); | |
9145 | @@ -40,47 +39,47 @@ | |
9146 | ev->unused.size += 16; | |
9147 | ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size); | |
9148 | } | |
9149 | - | |
9150 | + | |
9151 | ev->unused.ptr[ev->unused.used++] = k; | |
9152 | } else { | |
9153 | SEGFAULT(); | |
9154 | } | |
9155 | - | |
9156 | + | |
9157 | return -1; | |
9158 | } | |
f26f9fd5 | 9159 | |
2519e6e5 ER |
9160 | #if 0 |
9161 | static int fdevent_poll_event_compress(fdevents *ev) { | |
9162 | size_t j; | |
9163 | - | |
9164 | + | |
9165 | if (ev->used == 0) return 0; | |
9166 | if (ev->unused.used != 0) return 0; | |
9167 | - | |
9168 | + | |
9169 | for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--; | |
9170 | - | |
9171 | + | |
9172 | return 0; | |
9173 | } | |
f26f9fd5 ER |
9174 | #endif |
9175 | ||
2519e6e5 ER |
9176 | static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) { |
9177 | /* known index */ | |
9178 | - | |
f673a614 | 9179 | + |
2519e6e5 ER |
9180 | if (fde_ndx != -1) { |
9181 | if (ev->pollfds[fde_ndx].fd == fd) { | |
9182 | ev->pollfds[fde_ndx].events = events; | |
9183 | - | |
9184 | + | |
9185 | return fde_ndx; | |
9186 | } | |
9187 | fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd); | |
9188 | SEGFAULT(); | |
9189 | } | |
f673a614 | 9190 | - |
2519e6e5 ER |
9191 | + |
9192 | if (ev->unused.used > 0) { | |
9193 | int k = ev->unused.ptr[--ev->unused.used]; | |
9194 | - | |
9195 | + | |
9196 | ev->pollfds[k].fd = fd; | |
9197 | ev->pollfds[k].events = events; | |
9198 | - | |
9199 | + | |
9200 | return k; | |
9201 | } else { | |
9202 | if (ev->size == 0) { | |
9203 | @@ -90,10 +89,10 @@ | |
9204 | ev->size += 16; | |
9205 | ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size); | |
9206 | } | |
9207 | - | |
9208 | + | |
9209 | ev->pollfds[ev->used].fd = fd; | |
9210 | ev->pollfds[ev->used].events = events; | |
9211 | - | |
9212 | + | |
9213 | return ev->used++; | |
9214 | } | |
9215 | } | |
9216 | @@ -109,12 +108,12 @@ | |
9217 | int r, poll_r; | |
9218 | if (ndx >= ev->used) { | |
9219 | fprintf(stderr, "%s.%d: dying because: event: %zd >= %zd\n", __FILE__, __LINE__, ndx, ev->used); | |
9220 | - | |
9221 | + | |
9222 | SEGFAULT(); | |
9223 | - | |
9224 | + | |
9225 | return 0; | |
9226 | } | |
f673a614 | 9227 | - |
2519e6e5 ER |
9228 | + |
9229 | if (ev->pollfds[ndx].revents & POLLNVAL) { | |
9230 | /* should never happen */ | |
9231 | SEGFAULT(); | |
9232 | @@ -131,7 +130,7 @@ | |
9233 | if (poll_r & POLLHUP) r |= FDEVENT_HUP; | |
9234 | if (poll_r & POLLNVAL) r |= FDEVENT_NVAL; | |
9235 | if (poll_r & POLLPRI) r |= FDEVENT_PRI; | |
9236 | - | |
9237 | + | |
9238 | return ev->pollfds[ndx].revents; | |
9239 | } | |
f673a614 | 9240 | |
2519e6e5 | 9241 | @@ -141,12 +140,12 @@ |
f673a614 | 9242 | |
2519e6e5 ER |
9243 | static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) { |
9244 | size_t i; | |
9245 | - | |
f673a614 | 9246 | + |
2519e6e5 ER |
9247 | i = (ndx < 0) ? 0 : ndx + 1; |
9248 | for (; i < ev->used; i++) { | |
9249 | if (ev->pollfds[i].revents) break; | |
9250 | } | |
9251 | - | |
9252 | + | |
9253 | return i; | |
9254 | } | |
f673a614 | 9255 | |
2519e6e5 ER |
9256 | @@ -154,17 +153,17 @@ |
9257 | ev->type = FDEVENT_HANDLER_POLL; | |
9258 | #define SET(x) \ | |
9259 | ev->x = fdevent_poll_##x; | |
9260 | - | |
f673a614 | 9261 | + |
2519e6e5 ER |
9262 | SET(free); |
9263 | SET(poll); | |
9264 | - | |
f673a614 | 9265 | + |
2519e6e5 ER |
9266 | SET(event_del); |
9267 | SET(event_add); | |
9268 | - | |
9269 | + | |
9270 | SET(event_next_fdndx); | |
9271 | SET(event_get_fd); | |
9272 | SET(event_get_revent); | |
9273 | - | |
9274 | + | |
9275 | return 0; | |
9276 | } | |
f673a614 | 9277 | |
1175ccec | 9278 | --- ../lighttpd-1.4.11/src/fdevent_select.c 2005-08-31 11:12:46.000000000 +0300 |
36e2a29e | 9279 | +++ lighttpd-1.4.12/src/fdevent_select.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
9280 | @@ -1,18 +1,19 @@ |
9281 | -#include <sys/time.h> | |
9282 | #include <sys/types.h> | |
9283 | ||
9284 | -#include <unistd.h> | |
9285 | #include <stdlib.h> | |
9286 | #include <string.h> | |
9287 | #include <errno.h> | |
9288 | #include <signal.h> | |
9289 | #include <fcntl.h> | |
9290 | #include <assert.h> | |
9291 | +#include <stdio.h> | |
9292 | ||
9293 | #include "fdevent.h" | |
9294 | #include "settings.h" | |
9295 | #include "buffer.h" | |
9296 | ||
9297 | +#include "sys-socket.h" | |
9298 | + | |
9299 | #ifdef USE_SELECT | |
9300 | ||
9301 | static int fdevent_select_reset(fdevents *ev) { | |
9302 | @@ -38,7 +39,9 @@ | |
9303 | UNUSED(fde_ndx); | |
9304 | ||
9305 | /* we should be protected by max-fds, but you never know */ | |
f26f9fd5 | 9306 | +#ifndef _WIN32 |
2519e6e5 ER |
9307 | assert(fd < FD_SETSIZE); |
9308 | +#endif | |
9309 | ||
9310 | if (events & FDEVENT_IN) { | |
9311 | FD_SET(fd, &(ev->select_set_read)); | |
9312 | @@ -49,28 +52,28 @@ | |
9313 | FD_SET(fd, &(ev->select_set_write)); | |
9314 | } | |
9315 | FD_SET(fd, &(ev->select_set_error)); | |
9316 | - | |
f673a614 | 9317 | + |
2519e6e5 ER |
9318 | if (fd > ev->select_max_fd) ev->select_max_fd = fd; |
9319 | - | |
f673a614 | 9320 | + |
2519e6e5 ER |
9321 | return fd; |
9322 | } | |
9323 | ||
9324 | static int fdevent_select_poll(fdevents *ev, int timeout_ms) { | |
9325 | struct timeval tv; | |
9326 | - | |
f673a614 | 9327 | + |
2519e6e5 ER |
9328 | tv.tv_sec = timeout_ms / 1000; |
9329 | tv.tv_usec = (timeout_ms % 1000) * 1000; | |
9330 | - | |
f673a614 | 9331 | + |
2519e6e5 ER |
9332 | ev->select_read = ev->select_set_read; |
9333 | ev->select_write = ev->select_set_write; | |
9334 | ev->select_error = ev->select_set_error; | |
9335 | - | |
9336 | + | |
9337 | return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv); | |
f26f9fd5 | 9338 | } |
f673a614 | 9339 | |
2519e6e5 ER |
9340 | static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) { |
9341 | int revents = 0; | |
f673a614 | 9342 | - |
2519e6e5 ER |
9343 | + |
9344 | if (FD_ISSET(ndx, &(ev->select_read))) { | |
9345 | revents |= FDEVENT_IN; | |
9346 | } | |
9347 | @@ -80,7 +83,7 @@ | |
9348 | if (FD_ISSET(ndx, &(ev->select_error))) { | |
9349 | revents |= FDEVENT_ERR; | |
9350 | } | |
f26f9fd5 | 9351 | - |
2519e6e5 ER |
9352 | + |
9353 | return revents; | |
9354 | } | |
9355 | ||
9356 | @@ -92,15 +95,15 @@ | |
9357 | ||
9358 | static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) { | |
9359 | int i; | |
f26f9fd5 | 9360 | - |
2519e6e5 ER |
9361 | + |
9362 | i = (ndx < 0) ? 0 : ndx + 1; | |
9363 | - | |
9364 | + | |
9365 | for (; i < ev->select_max_fd + 1; i++) { | |
9366 | if (FD_ISSET(i, &(ev->select_read))) break; | |
9367 | if (FD_ISSET(i, &(ev->select_write))) break; | |
9368 | if (FD_ISSET(i, &(ev->select_error))) break; | |
9369 | } | |
9370 | - | |
9371 | + | |
9372 | return i; | |
9373 | } | |
9374 | ||
9375 | @@ -108,17 +111,17 @@ | |
9376 | ev->type = FDEVENT_HANDLER_SELECT; | |
9377 | #define SET(x) \ | |
9378 | ev->x = fdevent_select_##x; | |
9379 | - | |
9380 | + | |
9381 | SET(reset); | |
9382 | SET(poll); | |
9383 | - | |
9384 | + | |
9385 | SET(event_del); | |
9386 | SET(event_add); | |
9387 | - | |
9388 | + | |
9389 | SET(event_next_fdndx); | |
9390 | SET(event_get_fd); | |
9391 | SET(event_get_revent); | |
9392 | - | |
9393 | + | |
9394 | return 0; | |
9395 | } | |
9396 | ||
1175ccec | 9397 | --- ../lighttpd-1.4.11/src/fdevent_solaris_devpoll.c 2005-09-01 10:45:26.000000000 +0300 |
36e2a29e | 9398 | +++ lighttpd-1.4.12/src/fdevent_solaris_devpoll.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
9399 | @@ -1,6 +1,5 @@ |
9400 | #include <sys/types.h> | |
9401 | ||
9402 | -#include <unistd.h> | |
9403 | #include <stdlib.h> | |
9404 | #include <stdio.h> | |
9405 | #include <string.h> | |
9406 | @@ -23,55 +22,55 @@ | |
9407 | ||
9408 | static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) { | |
9409 | struct pollfd pfd; | |
f26f9fd5 | 9410 | - |
2519e6e5 ER |
9411 | + |
9412 | if (fde_ndx < 0) return -1; | |
9413 | - | |
9414 | + | |
9415 | pfd.fd = fd; | |
9416 | pfd.events = POLLREMOVE; | |
9417 | pfd.revents = 0; | |
9418 | - | |
9419 | + | |
9420 | if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) { | |
9421 | - fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", | |
9422 | - __FILE__, __LINE__, | |
9423 | + fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", | |
9424 | + __FILE__, __LINE__, | |
9425 | fd, strerror(errno)); | |
f26f9fd5 | 9426 | - |
2519e6e5 ER |
9427 | + |
9428 | return -1; | |
9429 | } | |
9430 | - | |
9431 | + | |
9432 | return -1; | |
9433 | } | |
9434 | ||
9435 | static int fdevent_solaris_devpoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) { | |
9436 | struct pollfd pfd; | |
9437 | int add = 0; | |
f26f9fd5 | 9438 | - |
2519e6e5 ER |
9439 | + |
9440 | if (fde_ndx == -1) add = 1; | |
9441 | - | |
9442 | + | |
9443 | pfd.fd = fd; | |
9444 | pfd.events = events; | |
9445 | pfd.revents = 0; | |
9446 | - | |
9447 | + | |
9448 | if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) { | |
9449 | - fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", | |
9450 | - __FILE__, __LINE__, | |
9451 | + fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", | |
9452 | + __FILE__, __LINE__, | |
9453 | fd, strerror(errno)); | |
f26f9fd5 | 9454 | - |
2519e6e5 ER |
9455 | + |
9456 | return -1; | |
9457 | } | |
f26f9fd5 | 9458 | - |
2519e6e5 ER |
9459 | + |
9460 | return fd; | |
9461 | } | |
f673a614 | 9462 | |
2519e6e5 ER |
9463 | static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) { |
9464 | struct dvpoll dopoll; | |
9465 | int ret; | |
f673a614 | 9466 | - |
2519e6e5 ER |
9467 | + |
9468 | dopoll.dp_timeout = timeout_ms; | |
9469 | dopoll.dp_nfds = ev->maxfds; | |
9470 | dopoll.dp_fds = ev->devpollfds; | |
f673a614 | 9471 | - |
2519e6e5 ER |
9472 | + |
9473 | ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll); | |
9474 | - | |
9475 | + | |
9476 | return ret; | |
9477 | } | |
f673a614 | 9478 | |
2519e6e5 | 9479 | @@ -85,11 +84,11 @@ |
f673a614 | 9480 | |
2519e6e5 ER |
9481 | static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) { |
9482 | size_t i; | |
9483 | - | |
9484 | + | |
9485 | UNUSED(ev); | |
f26f9fd5 | 9486 | |
2519e6e5 ER |
9487 | i = (last_ndx < 0) ? 0 : last_ndx + 1; |
9488 | - | |
f673a614 | 9489 | + |
2519e6e5 ER |
9490 | return i; |
9491 | } | |
9492 | ||
9493 | @@ -117,20 +116,20 @@ | |
9494 | ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL; | |
9495 | #define SET(x) \ | |
9496 | ev->x = fdevent_solaris_devpoll_##x; | |
9497 | - | |
f673a614 | 9498 | + |
2519e6e5 ER |
9499 | SET(free); |
9500 | SET(poll); | |
9501 | SET(reset); | |
9502 | - | |
f673a614 | 9503 | + |
2519e6e5 ER |
9504 | SET(event_del); |
9505 | SET(event_add); | |
9506 | - | |
9507 | + | |
9508 | SET(event_next_fdndx); | |
9509 | SET(event_get_fd); | |
9510 | SET(event_get_revent); | |
9511 | - | |
9512 | + | |
9513 | ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds); | |
9514 | - | |
9515 | + | |
9516 | if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) { | |
9517 | fprintf(stderr, "%s.%d: opening /dev/poll failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n", | |
9518 | __FILE__, __LINE__, strerror(errno)); | |
9519 | @@ -152,7 +151,7 @@ | |
f673a614 | 9520 | |
2519e6e5 ER |
9521 | fprintf(stderr, "%s.%d: solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n", |
9522 | __FILE__, __LINE__); | |
9523 | - | |
9524 | + | |
9525 | return -1; | |
9526 | } | |
9527 | #endif | |
1175ccec | 9528 | --- ../lighttpd-1.4.11/src/http-header-glue.c 2006-02-08 15:31:36.000000000 +0200 |
36e2a29e | 9529 | +++ lighttpd-1.4.12/src/http-header-glue.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
9530 | @@ -45,20 +45,20 @@ |
9531 | # ifdef HAVE_STRUCT_SOCKADDR_STORAGE | |
9532 | static size_t get_sa_len(const struct sockaddr *addr) { | |
9533 | switch (addr->sa_family) { | |
9534 | - | |
9535 | + | |
9536 | # ifdef AF_INET | |
9537 | case AF_INET: | |
9538 | return (sizeof (struct sockaddr_in)); | |
9539 | # endif | |
9540 | - | |
9541 | + | |
9542 | # ifdef AF_INET6 | |
9543 | case AF_INET6: | |
9544 | return (sizeof (struct sockaddr_in6)); | |
9545 | # endif | |
9546 | - | |
9547 | + | |
9548 | default: | |
9549 | return (sizeof (struct sockaddr)); | |
9550 | - | |
9551 | + | |
9552 | } | |
9553 | } | |
9554 | # define SA_LEN(addr) (get_sa_len(addr)) | |
9555 | @@ -74,7 +74,7 @@ | |
f673a614 | 9556 | |
2519e6e5 ER |
9557 | int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { |
9558 | data_string *ds; | |
9559 | - | |
9560 | + | |
9561 | UNUSED(srv); | |
f673a614 | 9562 | |
2519e6e5 ER |
9563 | if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { |
9564 | @@ -82,32 +82,32 @@ | |
9565 | } | |
9566 | buffer_copy_string_len(ds->key, key, keylen); | |
9567 | buffer_copy_string_len(ds->value, value, vallen); | |
9568 | - | |
f673a614 | 9569 | + |
2519e6e5 ER |
9570 | array_insert_unique(con->response.headers, (data_unset *)ds); |
9571 | - | |
f673a614 | 9572 | + |
2519e6e5 ER |
9573 | return 0; |
9574 | } | |
f673a614 | 9575 | |
2519e6e5 ER |
9576 | int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { |
9577 | data_string *ds; | |
9578 | - | |
9579 | + | |
9580 | UNUSED(srv); | |
f673a614 | 9581 | |
2519e6e5 ER |
9582 | /* if there already is a key by this name overwrite the value */ |
9583 | if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) { | |
9584 | buffer_copy_string(ds->value, value); | |
9585 | - | |
f673a614 | 9586 | + |
2519e6e5 ER |
9587 | return 0; |
9588 | } | |
9589 | - | |
f673a614 | 9590 | + |
2519e6e5 ER |
9591 | return response_header_insert(srv, con, key, keylen, value, vallen); |
9592 | } | |
9593 | ||
9594 | int http_response_redirect_to_directory(server *srv, connection *con) { | |
9595 | buffer *o; | |
9596 | - | |
f673a614 | 9597 | + |
2519e6e5 ER |
9598 | o = buffer_init(); |
9599 | - | |
f673a614 | 9600 | + |
2519e6e5 ER |
9601 | if (con->conf.is_ssl) { |
9602 | buffer_copy_string(o, "https://"); | |
9603 | } else { | |
9604 | @@ -123,36 +123,36 @@ | |
9605 | #endif | |
9606 | sock_addr our_addr; | |
9607 | socklen_t our_addr_len; | |
9608 | - | |
f673a614 | 9609 | + |
2519e6e5 ER |
9610 | our_addr_len = sizeof(our_addr); |
9611 | - | |
f673a614 | 9612 | + |
2519e6e5 ER |
9613 | if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) { |
9614 | con->http_status = 500; | |
9615 | - | |
f673a614 | 9616 | + |
2519e6e5 ER |
9617 | log_error_write(srv, __FILE__, __LINE__, "ss", |
9618 | "can't get sockname", strerror(errno)); | |
f26f9fd5 | 9619 | - |
2519e6e5 ER |
9620 | + |
9621 | buffer_free(o); | |
9622 | return 0; | |
9623 | } | |
9624 | - | |
9625 | - | |
9626 | + | |
9627 | + | |
9628 | /* Lookup name: secondly try to get hostname for bind address */ | |
9629 | switch(our_addr.plain.sa_family) { | |
9630 | #ifdef HAVE_IPV6 | |
9631 | case AF_INET6: | |
9632 | - if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6), | |
9633 | - SA_LEN((const struct sockaddr *)&our_addr.ipv6), | |
9634 | + if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6), | |
9635 | + SA_LEN((const struct sockaddr *)&our_addr.ipv6), | |
9636 | hbuf, sizeof(hbuf), NULL, 0, 0)) { | |
f26f9fd5 | 9637 | - |
f673a614 | 9638 | + |
2519e6e5 ER |
9639 | char dst[INET6_ADDRSTRLEN]; |
9640 | - | |
9641 | + | |
9642 | log_error_write(srv, __FILE__, __LINE__, | |
9643 | "SSSS", "NOTICE: getnameinfo failed: ", | |
9644 | strerror(errno), ", using ip-address instead"); | |
9645 | - | |
9646 | - buffer_append_string(o, | |
9647 | - inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr, | |
9648 | + | |
9649 | + buffer_append_string(o, | |
9650 | + inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr, | |
9651 | dst, sizeof(dst))); | |
9652 | } else { | |
9653 | buffer_append_string(o, hbuf); | |
9654 | @@ -164,7 +164,7 @@ | |
9655 | log_error_write(srv, __FILE__, __LINE__, | |
9656 | "SdSS", "NOTICE: gethostbyaddr failed: ", | |
9657 | h_errno, ", using ip-address instead"); | |
9658 | - | |
9659 | + | |
9660 | buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr)); | |
9661 | } else { | |
9662 | buffer_append_string(o, he->h_name); | |
9663 | @@ -173,12 +173,12 @@ | |
9664 | default: | |
9665 | log_error_write(srv, __FILE__, __LINE__, | |
9666 | "S", "ERROR: unsupported address-type"); | |
9667 | - | |
9668 | + | |
9669 | buffer_free(o); | |
9670 | return -1; | |
f673a614 | 9671 | } |
2519e6e5 ER |
9672 | - |
9673 | - if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) || | |
9674 | + | |
9675 | + if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) || | |
9676 | (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) { | |
9677 | buffer_append_string(o, ":"); | |
9678 | buffer_append_long(o, srv->srvconf.port); | |
9679 | @@ -190,41 +190,41 @@ | |
9680 | buffer_append_string(o, "?"); | |
9681 | buffer_append_string_buffer(o, con->uri.query); | |
f673a614 | 9682 | } |
2519e6e5 ER |
9683 | - |
9684 | + | |
9685 | response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(o)); | |
9686 | - | |
9687 | + | |
9688 | con->http_status = 301; | |
9689 | con->file_finished = 1; | |
9690 | - | |
9691 | + | |
9692 | buffer_free(o); | |
9693 | - | |
9694 | + | |
f673a614 ER |
9695 | return 0; |
9696 | } | |
9697 | ||
2519e6e5 ER |
9698 | buffer * strftime_cache_get(server *srv, time_t last_mod) { |
9699 | struct tm *tm; | |
9700 | size_t i; | |
9701 | - | |
9702 | + | |
9703 | for (i = 0; i < FILE_CACHE_MAX; i++) { | |
9704 | /* found cache-entry */ | |
9705 | if (srv->mtime_cache[i].mtime == last_mod) return srv->mtime_cache[i].str; | |
9706 | - | |
9707 | + | |
9708 | /* found empty slot */ | |
9709 | if (srv->mtime_cache[i].mtime == 0) break; | |
9710 | } | |
9711 | - | |
9712 | + | |
9713 | if (i == FILE_CACHE_MAX) { | |
9714 | i = 0; | |
9715 | } | |
9716 | - | |
9717 | + | |
9718 | srv->mtime_cache[i].mtime = last_mod; | |
9719 | buffer_prepare_copy(srv->mtime_cache[i].str, 1024); | |
9720 | tm = gmtime(&(srv->mtime_cache[i].mtime)); | |
9721 | - srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr, | |
9722 | + srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr, | |
9723 | srv->mtime_cache[i].str->size - 1, | |
9724 | "%a, %d %b %Y %H:%M:%S GMT", tm); | |
9725 | srv->mtime_cache[i].str->used++; | |
9726 | - | |
9727 | + | |
9728 | return srv->mtime_cache[i].str; | |
9729 | } | |
9730 | ||
9731 | @@ -239,56 +239,60 @@ | |
9732 | * request. That is, if no entity tags match, then the server MUST NOT | |
9733 | * return a 304 (Not Modified) response. | |
f26f9fd5 | 9734 | */ |
2519e6e5 ER |
9735 | - |
9736 | + | |
9737 | /* last-modified handling */ | |
9738 | if (con->request.http_if_none_match) { | |
9739 | if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) { | |
9740 | - if (con->request.http_method == HTTP_METHOD_GET || | |
9741 | + if (con->request.http_method == HTTP_METHOD_GET || | |
9742 | con->request.http_method == HTTP_METHOD_HEAD) { | |
9743 | - | |
9744 | + | |
9745 | /* check if etag + last-modified */ | |
9746 | if (con->request.http_if_modified_since) { | |
9747 | size_t used_len; | |
9748 | char *semicolon; | |
9749 | - | |
9750 | + | |
9751 | if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) { | |
9752 | used_len = strlen(con->request.http_if_modified_since); | |
9753 | } else { | |
9754 | used_len = semicolon - con->request.http_if_modified_since; | |
9755 | } | |
9756 | - | |
9757 | + | |
9758 | if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) { | |
9759 | con->http_status = 304; | |
9760 | return HANDLER_FINISHED; | |
9761 | } else { | |
9762 | +#ifdef HAVE_STRPTIME | |
9763 | char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")]; | |
9764 | + time_t t_header, t_file; | |
9765 | + struct tm tm; | |
f673a614 | 9766 | |
2519e6e5 ER |
9767 | - /* convert to timestamp */ |
9768 | - if (used_len < sizeof(buf)) { | |
9769 | - time_t t_header, t_file; | |
9770 | - struct tm tm; | |
9771 | - | |
9772 | - strncpy(buf, con->request.http_if_modified_since, used_len); | |
9773 | - buf[used_len] = '\0'; | |
9774 | - | |
9775 | - strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); | |
9776 | - t_header = mktime(&tm); | |
9777 | - | |
9778 | - strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm); | |
9779 | - t_file = mktime(&tm); | |
9780 | - | |
9781 | - if (t_file > t_header) { | |
9782 | - con->http_status = 304; | |
9783 | - return HANDLER_FINISHED; | |
9784 | - } | |
9785 | - } else { | |
9786 | - log_error_write(srv, __FILE__, __LINE__, "ssdd", | |
9787 | - "DEBUG: Last-Modified check failed as the received timestamp was too long:", | |
9788 | + /* check if we can safely copy the string */ | |
9789 | + if (used_len >= sizeof(buf)) { | |
9790 | + log_error_write(srv, __FILE__, __LINE__, "ssdd", | |
9791 | + "DEBUG: Last-Modified check failed as the received timestamp was too long:", | |
9792 | con->request.http_if_modified_since, used_len, sizeof(buf) - 1); | |
9793 | - | |
f673a614 | 9794 | + |
2519e6e5 ER |
9795 | con->http_status = 412; |
9796 | return HANDLER_FINISHED; | |
9797 | } | |
f26f9fd5 | 9798 | + |
f26f9fd5 | 9799 | + |
2519e6e5 ER |
9800 | + strncpy(buf, con->request.http_if_modified_since, used_len); |
9801 | + buf[used_len] = '\0'; | |
f26f9fd5 | 9802 | + |
2519e6e5 ER |
9803 | + strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); |
9804 | + t_header = mktime(&tm); | |
f26f9fd5 | 9805 | + |
2519e6e5 ER |
9806 | + strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm); |
9807 | + t_file = mktime(&tm); | |
f26f9fd5 | 9808 | + |
2519e6e5 | 9809 | + if (t_file > t_header) return HANDLER_GO_ON; |
f26f9fd5 | 9810 | + |
2519e6e5 ER |
9811 | + con->http_status = 304; |
9812 | + return HANDLER_FINISHED; | |
9813 | +#else | |
9814 | + return HANDLER_GO_ON; | |
9815 | +#endif | |
9816 | } | |
9817 | } else { | |
9818 | con->http_status = 304; | |
9819 | @@ -302,16 +306,41 @@ | |
9820 | } else if (con->request.http_if_modified_since) { | |
9821 | size_t used_len; | |
9822 | char *semicolon; | |
9823 | - | |
f673a614 | 9824 | + |
2519e6e5 ER |
9825 | if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) { |
9826 | used_len = strlen(con->request.http_if_modified_since); | |
9827 | } else { | |
9828 | used_len = semicolon - con->request.http_if_modified_since; | |
9829 | } | |
9830 | - | |
f26f9fd5 | 9831 | + |
2519e6e5 ER |
9832 | if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) { |
9833 | con->http_status = 304; | |
9834 | return HANDLER_FINISHED; | |
9835 | + } else { | |
9836 | +#ifdef HAVE_STRPTIME | |
9837 | + char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")]; | |
9838 | + time_t t_header, t_file; | |
9839 | + struct tm tm; | |
9840 | + | |
9841 | + /* convert to timestamp */ | |
9842 | + if (used_len >= sizeof(buf)) return HANDLER_GO_ON; | |
9843 | + | |
9844 | + strncpy(buf, con->request.http_if_modified_since, used_len); | |
9845 | + buf[used_len] = '\0'; | |
9846 | + | |
9847 | + strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); | |
9848 | + t_header = mktime(&tm); | |
9849 | + | |
9850 | + strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm); | |
9851 | + t_file = mktime(&tm); | |
9852 | + | |
9853 | + if (t_file > t_header) return HANDLER_GO_ON; | |
9854 | + | |
9855 | + con->http_status = 304; | |
9856 | + return HANDLER_FINISHED; | |
9857 | +#else | |
9858 | + return HANDLER_GO_ON; | |
f26f9fd5 | 9859 | +#endif |
f26f9fd5 ER |
9860 | } |
9861 | } | |
f673a614 | 9862 | |
1175ccec | 9863 | --- ../lighttpd-1.4.11/src/http_auth.c 2006-02-01 13:02:52.000000000 +0200 |
36e2a29e | 9864 | +++ lighttpd-1.4.12/src/http_auth.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
9865 | @@ -22,7 +22,6 @@ |
9866 | #include <string.h> | |
9867 | #include <time.h> | |
f26f9fd5 | 9868 | #include <errno.h> |
2519e6e5 ER |
9869 | -#include <unistd.h> |
9870 | #include <ctype.h> | |
f673a614 | 9871 | |
2519e6e5 ER |
9872 | #include "server.h" |
9873 | @@ -31,23 +30,14 @@ | |
9874 | #include "http_auth_digest.h" | |
9875 | #include "stream.h" | |
f26f9fd5 | 9876 | |
2519e6e5 | 9877 | +#include "sys-strings.h" |
f673a614 | 9878 | + |
2519e6e5 ER |
9879 | #ifdef USE_OPENSSL |
9880 | # include <openssl/md5.h> | |
9881 | #else | |
9882 | # include "md5.h" | |
f26f9fd5 | 9883 | #endif |
f26f9fd5 | 9884 | |
2519e6e5 ER |
9885 | - |
9886 | -#ifdef USE_PAM | |
9887 | -#include <security/pam_appl.h> | |
9888 | -#include <security/pam_misc.h> | |
9889 | - | |
9890 | -static struct pam_conv conv = { | |
9891 | - misc_conv, | |
9892 | - NULL | |
9893 | -}; | |
f26f9fd5 | 9894 | -#endif |
2519e6e5 ER |
9895 | - |
9896 | handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s); | |
f26f9fd5 | 9897 | |
2519e6e5 ER |
9898 | static const char base64_pad = '='; |
9899 | @@ -75,25 +65,25 @@ | |
9900 | unsigned char *result; | |
9901 | int ch, j = 0, k; | |
9902 | size_t i; | |
9903 | - | |
f673a614 | 9904 | + |
2519e6e5 ER |
9905 | size_t in_len = strlen(in); |
9906 | - | |
9907 | + | |
9908 | buffer_prepare_copy(out, in_len); | |
9909 | - | |
9910 | + | |
9911 | result = (unsigned char *)out->ptr; | |
9912 | - | |
9913 | + | |
9914 | ch = in[0]; | |
9915 | /* run through the whole string, converting as we go */ | |
9916 | for (i = 0; i < in_len; i++) { | |
9917 | ch = in[i]; | |
9918 | - | |
9919 | + | |
9920 | if (ch == '\0') break; | |
9921 | - | |
9922 | + | |
9923 | if (ch == base64_pad) break; | |
9924 | - | |
9925 | + | |
9926 | ch = base64_reverse_table[ch]; | |
9927 | if (ch < 0) continue; | |
9928 | - | |
9929 | + | |
9930 | switch(i % 4) { | |
9931 | case 0: | |
9932 | result[j] = ch << 2; | |
9933 | @@ -125,168 +115,168 @@ | |
9934 | } | |
9935 | } | |
9936 | result[k] = '\0'; | |
9937 | - | |
9938 | + | |
9939 | out->used = k; | |
9940 | - | |
9941 | + | |
9942 | return result; | |
f26f9fd5 | 9943 | } |
f673a614 | 9944 | |
2519e6e5 ER |
9945 | static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) { |
9946 | int ret = -1; | |
f26f9fd5 | 9947 | - |
2519e6e5 ER |
9948 | + |
9949 | if (!username->used|| !realm->used) return -1; | |
f26f9fd5 | 9950 | - |
f673a614 | 9951 | + |
2519e6e5 ER |
9952 | if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) { |
9953 | stream f; | |
9954 | char * f_line; | |
9955 | - | |
f673a614 | 9956 | + |
2519e6e5 | 9957 | if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1; |
f26f9fd5 | 9958 | - |
f673a614 | 9959 | + |
2519e6e5 ER |
9960 | if (0 != stream_open(&f, p->conf.auth_htdigest_userfile)) { |
9961 | log_error_write(srv, __FILE__, __LINE__, "sbss", "opening digest-userfile", p->conf.auth_htdigest_userfile, "failed:", strerror(errno)); | |
9962 | - | |
9963 | + | |
9964 | return -1; | |
9965 | } | |
f26f9fd5 | 9966 | - |
f673a614 | 9967 | + |
2519e6e5 ER |
9968 | f_line = f.start; |
9969 | - | |
9970 | + | |
9971 | while (f_line - f.start != f.size) { | |
9972 | char *f_user, *f_pwd, *e, *f_realm; | |
9973 | size_t u_len, pwd_len, r_len; | |
9974 | - | |
9975 | + | |
9976 | f_user = f_line; | |
9977 | - | |
9978 | - /* | |
9979 | + | |
9980 | + /* | |
9981 | * htdigest format | |
9982 | - * | |
9983 | - * user:realm:md5(user:realm:password) | |
9984 | + * | |
9985 | + * user:realm:md5(user:realm:password) | |
9986 | */ | |
9987 | - | |
9988 | + | |
9989 | if (NULL == (f_realm = memchr(f_user, ':', f.size - (f_user - f.start) ))) { | |
9990 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
9991 | - "parsed error in", p->conf.auth_htdigest_userfile, | |
9992 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
9993 | + "parsed error in", p->conf.auth_htdigest_userfile, | |
9994 | "expected 'username:realm:hashed password'"); | |
9995 | - | |
9996 | + | |
9997 | stream_close(&f); | |
9998 | - | |
9999 | + | |
10000 | return -1; | |
f673a614 ER |
10001 | } |
10002 | - | |
f673a614 | 10003 | + |
2519e6e5 ER |
10004 | if (NULL == (f_pwd = memchr(f_realm + 1, ':', f.size - (f_realm + 1 - f.start)))) { |
10005 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
10006 | - "parsed error in", p->conf.auth_plain_userfile, | |
10007 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
10008 | + "parsed error in", p->conf.auth_plain_userfile, | |
10009 | "expected 'username:realm:hashed password'"); | |
10010 | - | |
f673a614 | 10011 | + |
2519e6e5 ER |
10012 | stream_close(&f); |
10013 | - | |
10014 | + | |
10015 | return -1; | |
10016 | } | |
10017 | - | |
10018 | + | |
10019 | /* get pointers to the fields */ | |
10020 | - u_len = f_realm - f_user; | |
10021 | + u_len = f_realm - f_user; | |
10022 | f_realm++; | |
10023 | r_len = f_pwd - f_realm; | |
10024 | f_pwd++; | |
10025 | - | |
10026 | + | |
10027 | if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) { | |
10028 | pwd_len = e - f_pwd; | |
10029 | } else { | |
10030 | pwd_len = f.size - (f_pwd - f.start); | |
10031 | } | |
10032 | - | |
10033 | + | |
10034 | if (username->used - 1 == u_len && | |
10035 | (realm->used - 1 == r_len) && | |
10036 | (0 == strncmp(username->ptr, f_user, u_len)) && | |
10037 | (0 == strncmp(realm->ptr, f_realm, r_len))) { | |
10038 | /* found */ | |
10039 | - | |
10040 | + | |
10041 | buffer_copy_string_len(password, f_pwd, pwd_len); | |
10042 | - | |
10043 | + | |
10044 | ret = 0; | |
10045 | break; | |
10046 | } | |
10047 | - | |
10048 | + | |
10049 | /* EOL */ | |
10050 | if (!e) break; | |
10051 | - | |
10052 | + | |
10053 | f_line = e + 1; | |
10054 | } | |
f26f9fd5 | 10055 | - |
f673a614 | 10056 | + |
2519e6e5 ER |
10057 | stream_close(&f); |
10058 | } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD || | |
10059 | p->conf.auth_backend == AUTH_BACKEND_PLAIN) { | |
10060 | stream f; | |
10061 | char * f_line; | |
10062 | buffer *auth_fn; | |
10063 | - | |
f673a614 | 10064 | + |
2519e6e5 ER |
10065 | auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile; |
10066 | - | |
f673a614 | 10067 | + |
2519e6e5 ER |
10068 | if (buffer_is_empty(auth_fn)) return -1; |
10069 | - | |
f673a614 | 10070 | + |
2519e6e5 ER |
10071 | if (0 != stream_open(&f, auth_fn)) { |
10072 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
10073 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
10074 | "opening plain-userfile", auth_fn, "failed:", strerror(errno)); | |
10075 | - | |
f673a614 | 10076 | + |
2519e6e5 ER |
10077 | return -1; |
10078 | } | |
10079 | - | |
f673a614 | 10080 | + |
2519e6e5 ER |
10081 | f_line = f.start; |
10082 | - | |
f673a614 | 10083 | + |
2519e6e5 ER |
10084 | while (f_line - f.start != f.size) { |
10085 | char *f_user, *f_pwd, *e; | |
10086 | size_t u_len, pwd_len; | |
f26f9fd5 | 10087 | - |
2519e6e5 ER |
10088 | + |
10089 | f_user = f_line; | |
10090 | - | |
10091 | - /* | |
10092 | + | |
10093 | + /* | |
10094 | * htpasswd format | |
10095 | - * | |
10096 | + * | |
10097 | * user:crypted passwd | |
10098 | */ | |
10099 | - | |
10100 | + | |
10101 | if (NULL == (f_pwd = memchr(f_user, ':', f.size - (f_user - f.start) ))) { | |
10102 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
10103 | - "parsed error in", auth_fn, | |
10104 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
10105 | + "parsed error in", auth_fn, | |
10106 | "expected 'username:hashed password'"); | |
10107 | - | |
10108 | + | |
10109 | stream_close(&f); | |
10110 | - | |
10111 | + | |
10112 | return -1; | |
f673a614 | 10113 | } |
2519e6e5 | 10114 | - |
f673a614 | 10115 | + |
2519e6e5 ER |
10116 | /* get pointers to the fields */ |
10117 | - u_len = f_pwd - f_user; | |
10118 | + u_len = f_pwd - f_user; | |
10119 | f_pwd++; | |
10120 | - | |
10121 | + | |
10122 | if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) { | |
10123 | pwd_len = e - f_pwd; | |
10124 | } else { | |
10125 | pwd_len = f.size - (f_pwd - f.start); | |
f26f9fd5 | 10126 | } |
2519e6e5 ER |
10127 | - |
10128 | + | |
10129 | if (username->used - 1 == u_len && | |
10130 | (0 == strncmp(username->ptr, f_user, u_len))) { | |
10131 | /* found */ | |
10132 | - | |
10133 | + | |
10134 | buffer_copy_string_len(password, f_pwd, pwd_len); | |
10135 | - | |
10136 | + | |
10137 | ret = 0; | |
10138 | break; | |
10139 | } | |
10140 | - | |
10141 | + | |
10142 | /* EOL */ | |
10143 | if (!e) break; | |
10144 | - | |
10145 | + | |
10146 | f_line = e + 1; | |
f673a614 | 10147 | } |
2519e6e5 ER |
10148 | - |
10149 | + | |
10150 | stream_close(&f); | |
10151 | } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { | |
10152 | ret = 0; | |
10153 | } else { | |
10154 | return -1; | |
f673a614 | 10155 | } |
2519e6e5 | 10156 | - |
f673a614 | 10157 | + |
2519e6e5 | 10158 | return ret; |
f673a614 ER |
10159 | } |
10160 | ||
2519e6e5 ER |
10161 | @@ -296,7 +286,7 @@ |
10162 | int username_len; | |
10163 | data_string *require; | |
10164 | array *req; | |
10165 | - | |
10166 | + | |
10167 | UNUSED(group); | |
10168 | UNUSED(host); | |
f26f9fd5 | 10169 | |
2519e6e5 ER |
10170 | @@ -304,12 +294,12 @@ |
10171 | /* search auth-directives for path */ | |
10172 | for (i = 0; i < p->conf.auth_require->used; i++) { | |
10173 | if (p->conf.auth_require->data[i]->key->used == 0) continue; | |
10174 | - | |
10175 | + | |
10176 | if (0 == strncmp(url, p->conf.auth_require->data[i]->key->ptr, p->conf.auth_require->data[i]->key->used - 1)) { | |
10177 | break; | |
10178 | } | |
10179 | } | |
f673a614 | 10180 | - |
2519e6e5 ER |
10181 | + |
10182 | if (i == p->conf.auth_require->used) { | |
10183 | return -1; | |
10184 | } | |
10185 | @@ -317,72 +307,72 @@ | |
10186 | req = ((data_array *)(p->conf.auth_require->data[i]))->value; | |
10187 | ||
10188 | require = (data_string *)array_get_element(req, "require"); | |
f673a614 | 10189 | - |
2519e6e5 ER |
10190 | + |
10191 | /* if we get here, the user we got a authed user */ | |
10192 | if (0 == strcmp(require->value->ptr, "valid-user")) { | |
10193 | return 0; | |
10194 | } | |
f673a614 | 10195 | - |
2519e6e5 ER |
10196 | + |
10197 | /* user=name1|group=name3|host=name4 */ | |
10198 | - | |
10199 | + | |
10200 | /* seperate the string by | */ | |
10201 | #if 0 | |
10202 | log_error_write(srv, __FILE__, __LINE__, "sb", "rules", require->value); | |
10203 | -#endif | |
10204 | - | |
10205 | +#endif | |
10206 | + | |
10207 | username_len = username ? strlen(username) : 0; | |
10208 | - | |
10209 | + | |
10210 | r = rules = require->value->ptr; | |
10211 | - | |
10212 | + | |
10213 | while (1) { | |
10214 | const char *eq; | |
10215 | const char *k, *v, *e; | |
10216 | int k_len, v_len, r_len; | |
f673a614 | 10217 | - |
2519e6e5 ER |
10218 | + |
10219 | e = strchr(r, '|'); | |
10220 | - | |
10221 | + | |
10222 | if (e) { | |
10223 | r_len = e - r; | |
10224 | } else { | |
10225 | r_len = strlen(rules) - (r - rules); | |
f673a614 | 10226 | } |
f673a614 | 10227 | - |
2519e6e5 ER |
10228 | + |
10229 | /* from r to r + r_len is a rule */ | |
f673a614 | 10230 | - |
2519e6e5 ER |
10231 | + |
10232 | if (0 == strncmp(r, "valid-user", r_len)) { | |
10233 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
10234 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
10235 | "parsing the 'require' section in 'auth.require' failed: valid-user cannot be combined with other require rules", | |
10236 | require->value); | |
10237 | return -1; | |
10238 | } | |
10239 | - | |
10240 | + | |
10241 | /* search for = in the rules */ | |
10242 | if (NULL == (eq = strchr(r, '='))) { | |
10243 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
10244 | - "parsing the 'require' section in 'auth.require' failed: a = is missing", | |
10245 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
10246 | + "parsing the 'require' section in 'auth.require' failed: a = is missing", | |
10247 | require->value); | |
10248 | return -1; | |
10249 | } | |
10250 | - | |
10251 | + | |
10252 | /* = out of range */ | |
10253 | if (eq > r + r_len) { | |
10254 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
10255 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
10256 | "parsing the 'require' section in 'auth.require' failed: = out of range", | |
10257 | require->value); | |
10258 | - | |
10259 | + | |
10260 | return -1; | |
10261 | } | |
10262 | - | |
10263 | + | |
10264 | /* the part before the = is user|group|host */ | |
10265 | - | |
10266 | + | |
10267 | k = r; | |
10268 | k_len = eq - r; | |
10269 | v = eq + 1; | |
10270 | v_len = r_len - k_len - 1; | |
10271 | - | |
10272 | + | |
10273 | if (k_len == 4) { | |
10274 | if (0 == strncmp(k, "user", k_len)) { | |
10275 | - if (username && | |
10276 | + if (username && | |
10277 | username_len == v_len && | |
10278 | 0 == strncmp(username, v, v_len)) { | |
10279 | return 0; | |
10280 | @@ -404,19 +394,19 @@ | |
10281 | log_error_write(srv, __FILE__, __LINE__, "s", "unknown key"); | |
10282 | return -1; | |
10283 | } | |
10284 | - | |
10285 | + | |
10286 | if (!e) break; | |
10287 | r = e + 1; | |
f673a614 | 10288 | } |
2519e6e5 ER |
10289 | - |
10290 | + | |
10291 | log_error_write(srv, __FILE__, __LINE__, "s", "nothing matched"); | |
10292 | - | |
10293 | + | |
10294 | return -1; | |
10295 | } | |
f673a614 | 10296 | |
2519e6e5 ER |
10297 | /** |
10298 | - * | |
10299 | - * | |
10300 | + * | |
10301 | + * | |
10302 | * @param password password-string from the auth-backend | |
10303 | * @param pw password-string from the client | |
10304 | */ | |
10305 | @@ -426,16 +416,16 @@ | |
10306 | UNUSED(req); | |
f673a614 | 10307 | |
2519e6e5 ER |
10308 | if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) { |
10309 | - /* | |
10310 | + /* | |
10311 | * htdigest format | |
10312 | - * | |
10313 | - * user:realm:md5(user:realm:password) | |
10314 | + * | |
10315 | + * user:realm:md5(user:realm:password) | |
10316 | */ | |
10317 | - | |
10318 | + | |
10319 | MD5_CTX Md5Ctx; | |
10320 | HASH HA1; | |
10321 | char a1[256]; | |
10322 | - | |
10323 | + | |
10324 | MD5_Init(&Md5Ctx); | |
10325 | MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1); | |
10326 | MD5_Update(&Md5Ctx, (unsigned char *)":", 1); | |
10327 | @@ -443,24 +433,24 @@ | |
10328 | MD5_Update(&Md5Ctx, (unsigned char *)":", 1); | |
10329 | MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw)); | |
10330 | MD5_Final(HA1, &Md5Ctx); | |
10331 | - | |
10332 | + | |
10333 | CvtHex(HA1, a1); | |
10334 | - | |
10335 | + | |
10336 | if (0 == strcmp(password->ptr, a1)) { | |
10337 | return 0; | |
10338 | } | |
10339 | - } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) { | |
10340 | -#ifdef HAVE_CRYPT | |
10341 | + } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) { | |
10342 | +#ifdef HAVE_CRYPT | |
10343 | char salt[32]; | |
10344 | char *crypted; | |
10345 | size_t salt_len = 0; | |
10346 | - /* | |
10347 | + /* | |
10348 | * htpasswd format | |
10349 | - * | |
10350 | + * | |
10351 | * user:crypted password | |
10352 | */ | |
f673a614 | 10353 | |
2519e6e5 ER |
10354 | - /* |
10355 | + /* | |
10356 | * Algorithm Salt | |
10357 | * CRYPT_STD_DES 2-character (Default) | |
10358 | * CRYPT_EXT_DES 9-character | |
10359 | @@ -478,7 +468,7 @@ | |
10360 | salt_len = 2; | |
10361 | } else if (password->ptr[0] == '$' && password->ptr[2] == '$') { | |
10362 | char *dollar = NULL; | |
10363 | - | |
10364 | + | |
10365 | if (NULL == (dollar = strchr(password->ptr + 3, '$'))) { | |
10366 | fprintf(stderr, "%s.%d\n", __FILE__, __LINE__); | |
10367 | return -1; | |
10368 | @@ -495,7 +485,7 @@ | |
10369 | strncpy(salt, password->ptr, salt_len); | |
f673a614 | 10370 | |
2519e6e5 ER |
10371 | salt[salt_len] = '\0'; |
10372 | - | |
10373 | + | |
10374 | crypted = crypt(pw, salt); | |
f673a614 | 10375 | |
2519e6e5 ER |
10376 | if (0 == strcmp(password->ptr, crypted)) { |
10377 | @@ -503,40 +493,13 @@ | |
10378 | } else { | |
10379 | fprintf(stderr, "%s.%d\n", __FILE__, __LINE__); | |
f26f9fd5 | 10380 | } |
2519e6e5 ER |
10381 | - |
10382 | -#endif | |
10383 | - } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) { | |
10384 | + | |
10385 | +#endif | |
10386 | + } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) { | |
10387 | if (0 == strcmp(password->ptr, pw)) { | |
10388 | return 0; | |
f26f9fd5 | 10389 | } |
2519e6e5 ER |
10390 | - } else if (p->conf.auth_backend == AUTH_BACKEND_PAM) { |
10391 | -#ifdef USE_PAM | |
10392 | - pam_handle_t *pamh=NULL; | |
10393 | - int retval; | |
10394 | - | |
10395 | - retval = pam_start("lighttpd", username->ptr, &conv, &pamh); | |
10396 | - | |
10397 | - if (retval == PAM_SUCCESS) | |
10398 | - retval = pam_authenticate(pamh, 0); /* is user really user? */ | |
10399 | - | |
10400 | - if (retval == PAM_SUCCESS) | |
10401 | - retval = pam_acct_mgmt(pamh, 0); /* permitted access? */ | |
10402 | - | |
10403 | - /* This is where we have been authorized or not. */ | |
10404 | - | |
10405 | - if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */ | |
10406 | - pamh = NULL; | |
10407 | - log_error_write(srv, __FILE__, __LINE__, "s", "failed to release authenticator"); | |
f26f9fd5 | 10408 | - } |
2519e6e5 ER |
10409 | - |
10410 | - if (retval == PAM_SUCCESS) { | |
10411 | - log_error_write(srv, __FILE__, __LINE__, "s", "Authenticated"); | |
10412 | - return 0; | |
f26f9fd5 | 10413 | - } else { |
2519e6e5 | 10414 | - log_error_write(srv, __FILE__, __LINE__, "s", "Not Authenticated"); |
f26f9fd5 | 10415 | - } |
2519e6e5 ER |
10416 | -#endif |
10417 | - } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { | |
10418 | + } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { | |
10419 | #ifdef USE_LDAP | |
10420 | LDAP *ldap; | |
10421 | LDAPMessage *lm, *first; | |
10422 | @@ -544,45 +507,45 @@ | |
10423 | int ret; | |
10424 | char *attrs[] = { LDAP_NO_ATTRS, NULL }; | |
10425 | size_t i; | |
f673a614 | 10426 | - |
2519e6e5 ER |
10427 | + |
10428 | /* for now we stay synchronous */ | |
f673a614 | 10429 | - |
2519e6e5 | 10430 | - /* |
f673a614 | 10431 | + |
2519e6e5 ER |
10432 | + /* |
10433 | * 1. connect anonymously (done in plugin init) | |
10434 | * 2. get DN for uid = username | |
10435 | * 3. auth against ldap server | |
10436 | * 4. (optional) check a field | |
10437 | * 5. disconnect | |
10438 | - * | |
10439 | + * | |
10440 | */ | |
10441 | - | |
10442 | + | |
10443 | /* check username | |
10444 | - * | |
10445 | + * | |
10446 | * we have to protect us againt username which modifies out filter in | |
10447 | * a unpleasant way | |
10448 | */ | |
10449 | - | |
10450 | + | |
10451 | for (i = 0; i < username->used - 1; i++) { | |
10452 | char c = username->ptr[i]; | |
10453 | - | |
10454 | + | |
10455 | if (!isalpha(c) && | |
10456 | !isdigit(c)) { | |
10457 | - | |
10458 | - log_error_write(srv, __FILE__, __LINE__, "sbd", | |
10459 | + | |
10460 | + log_error_write(srv, __FILE__, __LINE__, "sbd", | |
10461 | "ldap: invalid character (a-zA-Z0-9 allowed) in username:", username, i); | |
10462 | - | |
10463 | + | |
10464 | return -1; | |
f673a614 | 10465 | } |
f26f9fd5 | 10466 | } |
2519e6e5 ER |
10467 | - |
10468 | - | |
10469 | - | |
f673a614 | 10470 | + |
2519e6e5 ER |
10471 | + |
10472 | + | |
10473 | /* build filter */ | |
10474 | buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre); | |
10475 | buffer_append_string_buffer(p->ldap_filter, username); | |
10476 | buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post); | |
10477 | - | |
10478 | - | |
10479 | + | |
10480 | + | |
10481 | /* 2. */ | |
10482 | if (p->conf.ldap == NULL || | |
10483 | LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { | |
10484 | @@ -590,71 +553,71 @@ | |
10485 | return -1; | |
10486 | if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { | |
f673a614 | 10487 | |
2519e6e5 ER |
10488 | - log_error_write(srv, __FILE__, __LINE__, "sssb", |
10489 | + log_error_write(srv, __FILE__, __LINE__, "sssb", | |
10490 | "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter); | |
10491 | - | |
10492 | + | |
10493 | return -1; | |
f26f9fd5 ER |
10494 | } |
10495 | } | |
2519e6e5 | 10496 | - |
f673a614 | 10497 | + |
2519e6e5 ER |
10498 | if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) { |
10499 | log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); | |
10500 | - | |
f673a614 | 10501 | + |
2519e6e5 ER |
10502 | ldap_msgfree(lm); |
10503 | - | |
10504 | + | |
10505 | return -1; | |
f26f9fd5 | 10506 | } |
2519e6e5 | 10507 | - |
f673a614 | 10508 | + |
2519e6e5 ER |
10509 | if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) { |
10510 | log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); | |
10511 | - | |
10512 | + | |
10513 | ldap_msgfree(lm); | |
10514 | - | |
10515 | + | |
10516 | return -1; | |
f26f9fd5 | 10517 | } |
2519e6e5 ER |
10518 | - |
10519 | + | |
10520 | ldap_msgfree(lm); | |
10521 | - | |
10522 | - | |
10523 | + | |
10524 | + | |
10525 | /* 3. */ | |
10526 | if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) { | |
10527 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); | |
10528 | return -1; | |
f26f9fd5 | 10529 | } |
2519e6e5 ER |
10530 | - |
10531 | + | |
10532 | ret = LDAP_VERSION3; | |
10533 | if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { | |
10534 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); | |
10535 | - | |
10536 | + | |
10537 | ldap_unbind_s(ldap); | |
10538 | - | |
10539 | + | |
10540 | return -1; | |
f26f9fd5 | 10541 | } |
2519e6e5 ER |
10542 | - |
10543 | + | |
10544 | if (p->conf.auth_ldap_starttls == 1) { | |
10545 | if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL, NULL))) { | |
10546 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); | |
10547 | - | |
10548 | + | |
10549 | ldap_unbind_s(ldap); | |
10550 | - | |
10551 | + | |
10552 | return -1; | |
10553 | } | |
10554 | } | |
f26f9fd5 | 10555 | |
2519e6e5 ER |
10556 | - |
10557 | + | |
10558 | if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) { | |
10559 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); | |
10560 | - | |
10561 | + | |
10562 | ldap_unbind_s(ldap); | |
10563 | - | |
10564 | + | |
10565 | return -1; | |
f26f9fd5 | 10566 | } |
2519e6e5 | 10567 | - |
f673a614 | 10568 | + |
2519e6e5 ER |
10569 | /* 5. */ |
10570 | ldap_unbind_s(ldap); | |
10571 | - | |
f673a614 | 10572 | + |
2519e6e5 ER |
10573 | /* everything worked, good, access granted */ |
10574 | - | |
f673a614 | 10575 | + |
2519e6e5 ER |
10576 | return 0; |
10577 | #endif | |
10578 | } | |
10579 | @@ -664,65 +627,65 @@ | |
10580 | int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) { | |
10581 | buffer *username, *password; | |
10582 | char *pw; | |
10583 | - | |
f673a614 | 10584 | + |
2519e6e5 ER |
10585 | data_string *realm; |
10586 | - | |
f673a614 | 10587 | + |
2519e6e5 ER |
10588 | realm = (data_string *)array_get_element(req, "realm"); |
10589 | - | |
f673a614 | 10590 | + |
2519e6e5 ER |
10591 | username = buffer_init(); |
10592 | password = buffer_init(); | |
10593 | - | |
10594 | + | |
10595 | base64_decode(username, realm_str); | |
10596 | - | |
10597 | + | |
10598 | /* r2 == user:password */ | |
10599 | if (NULL == (pw = strchr(username->ptr, ':'))) { | |
10600 | buffer_free(username); | |
10601 | - | |
10602 | + | |
10603 | log_error_write(srv, __FILE__, __LINE__, "sb", ": is missing in", username); | |
10604 | - | |
10605 | + | |
10606 | return 0; | |
f26f9fd5 | 10607 | } |
2519e6e5 | 10608 | - |
f673a614 | 10609 | + |
2519e6e5 ER |
10610 | *pw++ = '\0'; |
10611 | - | |
10612 | + | |
10613 | username->used = pw - username->ptr; | |
10614 | - | |
10615 | + | |
10616 | /* copy password to r1 */ | |
10617 | if (http_auth_get_password(srv, p, username, realm->value, password)) { | |
10618 | buffer_free(username); | |
10619 | buffer_free(password); | |
f26f9fd5 | 10620 | - |
2519e6e5 ER |
10621 | + |
10622 | log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed"); | |
f26f9fd5 | 10623 | - |
2519e6e5 ER |
10624 | + |
10625 | return 0; | |
10626 | } | |
10627 | - | |
10628 | + | |
10629 | /* password doesn't match */ | |
10630 | if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw)) { | |
10631 | log_error_write(srv, __FILE__, __LINE__, "sbb", "password doesn't match for", con->uri.path, username); | |
10632 | - | |
10633 | + | |
10634 | buffer_free(username); | |
10635 | buffer_free(password); | |
10636 | - | |
10637 | + | |
10638 | return 0; | |
10639 | } | |
10640 | - | |
10641 | + | |
10642 | /* value is our allow-rules */ | |
10643 | if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL)) { | |
10644 | buffer_free(username); | |
10645 | buffer_free(password); | |
10646 | - | |
10647 | + | |
10648 | log_error_write(srv, __FILE__, __LINE__, "s", "rules didn't match"); | |
10649 | - | |
10650 | + | |
10651 | return 0; | |
10652 | } | |
10653 | - | |
10654 | + | |
10655 | /* remember the username */ | |
10656 | buffer_copy_string_buffer(p->auth_user, username); | |
10657 | - | |
10658 | + | |
10659 | buffer_free(username); | |
10660 | buffer_free(password); | |
10661 | - | |
10662 | + | |
10663 | return 1; | |
f673a614 | 10664 | } |
f673a614 | 10665 | |
2519e6e5 ER |
10666 | @@ -735,7 +698,7 @@ |
10667 | int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) { | |
10668 | char a1[256]; | |
10669 | char a2[256]; | |
10670 | - | |
10671 | + | |
10672 | char *username; | |
10673 | char *realm; | |
10674 | char *nonce; | |
10675 | @@ -745,18 +708,18 @@ | |
10676 | char *cnonce; | |
10677 | char *nc; | |
10678 | char *respons; | |
10679 | - | |
10680 | + | |
10681 | char *e, *c; | |
10682 | const char *m = NULL; | |
10683 | int i; | |
10684 | buffer *password, *b, *username_buf, *realm_buf; | |
10685 | - | |
10686 | + | |
10687 | MD5_CTX Md5Ctx; | |
10688 | HASH HA1; | |
10689 | HASH HA2; | |
10690 | HASH RespHash; | |
10691 | HASHHEX HA2Hex; | |
10692 | - | |
10693 | + | |
f673a614 | 10694 | |
2519e6e5 ER |
10695 | /* init pointers */ |
10696 | #define S(x) \ | |
10697 | @@ -771,11 +734,11 @@ | |
10698 | { S("cnonce=") }, | |
10699 | { S("nc=") }, | |
10700 | { S("response=") }, | |
f673a614 | 10701 | - |
2519e6e5 ER |
10702 | + |
10703 | { NULL, 0, NULL } | |
10704 | }; | |
10705 | #undef S | |
10706 | - | |
10707 | + | |
10708 | dkv[0].ptr = &username; | |
10709 | dkv[1].ptr = &realm; | |
10710 | dkv[2].ptr = &nonce; | |
10711 | @@ -786,24 +749,24 @@ | |
10712 | dkv[7].ptr = &nc; | |
10713 | dkv[8].ptr = &respons; | |
10714 | dkv[9].ptr = NULL; | |
10715 | - | |
10716 | + | |
10717 | UNUSED(req); | |
10718 | - | |
10719 | + | |
10720 | for (i = 0; dkv[i].key; i++) { | |
10721 | *(dkv[i].ptr) = NULL; | |
10722 | } | |
10723 | - | |
10724 | - | |
10725 | + | |
10726 | + | |
10727 | if (p->conf.auth_backend != AUTH_BACKEND_HTDIGEST && | |
10728 | p->conf.auth_backend != AUTH_BACKEND_PLAIN) { | |
10729 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
10730 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
10731 | "digest: unsupported backend (only htdigest or plain)"); | |
10732 | - | |
10733 | + | |
10734 | return -1; | |
10735 | } | |
10736 | - | |
10737 | + | |
10738 | b = buffer_init_string(realm_str); | |
10739 | - | |
10740 | + | |
10741 | /* parse credentials from client */ | |
10742 | for (c = b->ptr; *c; c++) { | |
10743 | /* skip whitespaces */ | |
10744 | @@ -812,18 +775,18 @@ | |
10745 | ||
10746 | for (i = 0; dkv[i].key; i++) { | |
10747 | if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) { | |
10748 | - if ((c[dkv[i].key_len] == '"') && | |
10749 | + if ((c[dkv[i].key_len] == '"') && | |
10750 | (NULL != (e = strchr(c + dkv[i].key_len + 1, '"')))) { | |
10751 | /* value with "..." */ | |
10752 | *(dkv[i].ptr) = c + dkv[i].key_len + 1; | |
10753 | c = e; | |
10754 | - | |
10755 | + | |
10756 | *e = '\0'; | |
10757 | } else if (NULL != (e = strchr(c + dkv[i].key_len, ','))) { | |
10758 | /* value without "...", terminated by ',' */ | |
10759 | *(dkv[i].ptr) = c + dkv[i].key_len; | |
10760 | c = e; | |
f26f9fd5 | 10761 | - |
2519e6e5 ER |
10762 | + |
10763 | *e = '\0'; | |
10764 | } else { | |
10765 | /* value without "...", terminated by EOL */ | |
10766 | @@ -833,7 +796,7 @@ | |
10767 | } | |
f673a614 | 10768 | } |
2519e6e5 ER |
10769 | } |
10770 | - | |
10771 | + | |
10772 | if (p->conf.auth_debug > 1) { | |
10773 | log_error_write(srv, __FILE__, __LINE__, "ss", "username", username); | |
10774 | log_error_write(srv, __FILE__, __LINE__, "ss", "realm", realm); | |
10775 | @@ -845,22 +808,22 @@ | |
10776 | log_error_write(srv, __FILE__, __LINE__, "ss", "nc", nc); | |
10777 | log_error_write(srv, __FILE__, __LINE__, "ss", "response", respons); | |
10778 | } | |
10779 | - | |
10780 | + | |
10781 | /* check if everything is transmitted */ | |
10782 | - if (!username || | |
10783 | + if (!username || | |
10784 | !realm || | |
10785 | !nonce || | |
10786 | !uri || | |
10787 | (qop && (!nc || !cnonce)) || | |
10788 | !respons ) { | |
10789 | /* missing field */ | |
10790 | - | |
10791 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
10792 | + | |
f26f9fd5 | 10793 | + log_error_write(srv, __FILE__, __LINE__, "s", |
2519e6e5 ER |
10794 | "digest: missing field"); |
10795 | return -1; | |
f673a614 | 10796 | } |
f673a614 | 10797 | |
2519e6e5 ER |
10798 | - m = get_http_method_name(con->request.http_method); |
10799 | + m = get_http_method_name(con->request.http_method); | |
10800 | ||
10801 | /* password-string == HA1 */ | |
10802 | password = buffer_init(); | |
10803 | @@ -873,10 +836,10 @@ | |
10804 | buffer_free(realm_buf); | |
10805 | return 0; | |
10806 | } | |
f673a614 | 10807 | - |
2519e6e5 ER |
10808 | + |
10809 | buffer_free(username_buf); | |
10810 | buffer_free(realm_buf); | |
f673a614 | 10811 | - |
2519e6e5 ER |
10812 | + |
10813 | if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) { | |
10814 | /* generate password from plain-text */ | |
10815 | MD5_Init(&Md5Ctx); | |
10816 | @@ -890,16 +853,16 @@ | |
10817 | /* HA1 */ | |
10818 | /* transform the 32-byte-hex-md5 to a 16-byte-md5 */ | |
10819 | for (i = 0; i < HASHLEN; i++) { | |
10820 | - HA1[i] = hex2int(password->ptr[i*2]) << 4; | |
10821 | - HA1[i] |= hex2int(password->ptr[i*2+1]); | |
10822 | + HA1[i] = hex2int(password->ptr[i*2]) << 4; | |
10823 | + HA1[i] |= hex2int(password->ptr[i*2+1]); | |
10824 | } | |
10825 | } else { | |
10826 | /* we already check that above */ | |
10827 | SEGFAULT(); | |
10828 | } | |
f673a614 | 10829 | - |
2519e6e5 ER |
10830 | + |
10831 | buffer_free(password); | |
f673a614 | 10832 | - |
2519e6e5 ER |
10833 | + |
10834 | if (algorithm && | |
10835 | strcasecmp(algorithm, "md5-sess") == 0) { | |
10836 | MD5_Init(&Md5Ctx); | |
10837 | @@ -910,9 +873,9 @@ | |
10838 | MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce)); | |
10839 | MD5_Final(HA1, &Md5Ctx); | |
10840 | } | |
f673a614 | 10841 | - |
2519e6e5 ER |
10842 | + |
10843 | CvtHex(HA1, a1); | |
f26f9fd5 | 10844 | - |
2519e6e5 ER |
10845 | + |
10846 | /* calculate H(A2) */ | |
10847 | MD5_Init(&Md5Ctx); | |
10848 | MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m)); | |
10849 | @@ -924,7 +887,7 @@ | |
10850 | } | |
10851 | MD5_Final(HA2, &Md5Ctx); | |
10852 | CvtHex(HA2, HA2Hex); | |
10853 | - | |
10854 | + | |
10855 | /* calculate response */ | |
10856 | MD5_Init(&Md5Ctx); | |
10857 | MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN); | |
10858 | @@ -942,39 +905,39 @@ | |
10859 | MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN); | |
10860 | MD5_Final(RespHash, &Md5Ctx); | |
10861 | CvtHex(RespHash, a2); | |
10862 | - | |
10863 | + | |
10864 | if (0 != strcmp(a2, respons)) { | |
10865 | /* digest not ok */ | |
f673a614 | 10866 | - |
2519e6e5 ER |
10867 | + |
10868 | if (p->conf.auth_debug) { | |
10869 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
10870 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
10871 | "digest: digest mismatch", a2, respons); | |
10872 | } | |
f673a614 | 10873 | - |
2519e6e5 ER |
10874 | - log_error_write(srv, __FILE__, __LINE__, "sss", |
10875 | + | |
10876 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
10877 | "digest: auth failed for", username, "wrong password"); | |
f673a614 | 10878 | - |
2519e6e5 ER |
10879 | + |
10880 | buffer_free(b); | |
10881 | return 0; | |
10882 | } | |
f673a614 | 10883 | - |
2519e6e5 ER |
10884 | + |
10885 | /* value is our allow-rules */ | |
10886 | if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) { | |
10887 | buffer_free(b); | |
f26f9fd5 | 10888 | - |
2519e6e5 ER |
10889 | - log_error_write(srv, __FILE__, __LINE__, "s", |
10890 | + | |
10891 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
10892 | "digest: rules did match"); | |
10893 | - | |
10894 | + | |
10895 | return 0; | |
10896 | } | |
f673a614 | 10897 | - |
2519e6e5 ER |
10898 | + |
10899 | /* remember the username */ | |
10900 | buffer_copy_string(p->auth_user, username); | |
f673a614 | 10901 | - |
2519e6e5 ER |
10902 | + |
10903 | buffer_free(b); | |
f673a614 | 10904 | - |
2519e6e5 ER |
10905 | + |
10906 | if (p->conf.auth_debug) { | |
10907 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
10908 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
10909 | "digest: auth ok"); | |
10910 | } | |
10911 | return 1; | |
10912 | @@ -985,23 +948,23 @@ | |
10913 | HASH h; | |
10914 | MD5_CTX Md5Ctx; | |
10915 | char hh[32]; | |
f673a614 | 10916 | - |
2519e6e5 ER |
10917 | + |
10918 | UNUSED(p); | |
f673a614 | 10919 | |
2519e6e5 ER |
10920 | /* generate shared-secret */ |
10921 | MD5_Init(&Md5Ctx); | |
10922 | MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1); | |
10923 | MD5_Update(&Md5Ctx, (unsigned char *)"+", 1); | |
10924 | - | |
10925 | + | |
10926 | /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */ | |
10927 | ltostr(hh, srv->cur_ts); | |
10928 | MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); | |
10929 | ltostr(hh, rand()); | |
10930 | MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); | |
10931 | - | |
10932 | + | |
10933 | MD5_Final(h, &Md5Ctx); | |
10934 | - | |
10935 | + | |
10936 | CvtHex(h, out); | |
10937 | - | |
10938 | + | |
10939 | return 0; | |
10940 | } | |
1175ccec | 10941 | --- ../lighttpd-1.4.11/src/http_auth.h 2005-08-14 17:12:31.000000000 +0300 |
36e2a29e | 10942 | +++ lighttpd-1.4.12/src/http_auth.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
10943 | @@ -9,22 +9,26 @@ |
10944 | # include <ldap.h> | |
f673a614 | 10945 | #endif |
2519e6e5 ER |
10946 | |
10947 | -typedef enum { AUTH_BACKEND_UNSET, AUTH_BACKEND_PLAIN, | |
10948 | - AUTH_BACKEND_LDAP, AUTH_BACKEND_HTPASSWD, | |
10949 | - AUTH_BACKEND_HTDIGEST, AUTH_BACKEND_PAM } auth_backend_t; | |
10950 | +typedef enum { | |
10951 | + AUTH_BACKEND_UNSET, | |
10952 | + AUTH_BACKEND_PLAIN, | |
10953 | + AUTH_BACKEND_LDAP, | |
10954 | + AUTH_BACKEND_HTPASSWD, | |
10955 | + AUTH_BACKEND_HTDIGEST | |
10956 | +} auth_backend_t; | |
10957 | ||
10958 | typedef struct { | |
10959 | /* auth */ | |
10960 | array *auth_require; | |
10961 | - | |
f26f9fd5 | 10962 | + |
2519e6e5 ER |
10963 | buffer *auth_plain_groupfile; |
10964 | buffer *auth_plain_userfile; | |
10965 | - | |
10966 | + | |
10967 | buffer *auth_htdigest_userfile; | |
10968 | buffer *auth_htpasswd_userfile; | |
10969 | - | |
10970 | + | |
10971 | buffer *auth_backend_conf; | |
10972 | - | |
10973 | + | |
10974 | buffer *auth_ldap_hostname; | |
10975 | buffer *auth_ldap_basedn; | |
10976 | buffer *auth_ldap_binddn; | |
10977 | @@ -32,15 +36,15 @@ | |
10978 | buffer *auth_ldap_filter; | |
10979 | buffer *auth_ldap_cafile; | |
10980 | unsigned short auth_ldap_starttls; | |
10981 | - | |
10982 | + | |
10983 | unsigned short auth_debug; | |
10984 | - | |
10985 | + | |
10986 | /* generated */ | |
10987 | auth_backend_t auth_backend; | |
10988 | - | |
10989 | + | |
10990 | #ifdef USE_LDAP | |
10991 | LDAP *ldap; | |
10992 | - | |
10993 | + | |
10994 | buffer *ldap_filter_pre; | |
10995 | buffer *ldap_filter_post; | |
10996 | #endif | |
10997 | @@ -49,15 +53,15 @@ | |
10998 | typedef struct { | |
10999 | PLUGIN_DATA; | |
11000 | buffer *tmp_buf; | |
11001 | - | |
11002 | + | |
11003 | buffer *auth_user; | |
f26f9fd5 | 11004 | |
2519e6e5 ER |
11005 | #ifdef USE_LDAP |
11006 | buffer *ldap_filter; | |
f26f9fd5 | 11007 | #endif |
2519e6e5 | 11008 | - |
f673a614 | 11009 | + |
2519e6e5 ER |
11010 | mod_auth_plugin_config **config_storage; |
11011 | - | |
f26f9fd5 | 11012 | + |
2519e6e5 ER |
11013 | mod_auth_plugin_config conf; /* this is only used as long as no handler_ctx is setup */ |
11014 | } mod_auth_plugin_data; | |
f26f9fd5 | 11015 | |
1175ccec | 11016 | --- ../lighttpd-1.4.11/src/http_auth_digest.h 2006-01-05 00:54:01.000000000 +0200 |
36e2a29e | 11017 | +++ lighttpd-1.4.12/src/http_auth_digest.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
11018 | @@ -12,7 +12,7 @@ |
11019 | #ifdef USE_OPENSSL | |
11020 | #define IN const | |
11021 | #else | |
11022 | -#define IN | |
11023 | +#define IN | |
11024 | #endif | |
11025 | #define OUT | |
11026 | ||
1175ccec | 11027 | --- ../lighttpd-1.4.11/src/http_chunk.c 2005-08-11 01:26:50.000000000 +0300 |
36e2a29e | 11028 | +++ lighttpd-1.4.12/src/http_chunk.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
11029 | @@ -1,7 +1,7 @@ |
11030 | /** | |
11031 | * the HTTP chunk-API | |
11032 | - * | |
11033 | - * | |
11034 | + * | |
11035 | + * | |
11036 | */ | |
f26f9fd5 | 11037 | |
f26f9fd5 | 11038 | #include <sys/types.h> |
2519e6e5 | 11039 | @@ -9,7 +9,6 @@ |
f26f9fd5 | 11040 | |
2519e6e5 ER |
11041 | #include <stdlib.h> |
11042 | #include <fcntl.h> | |
11043 | -#include <unistd.h> | |
f26f9fd5 | 11044 | |
2519e6e5 ER |
11045 | #include <stdio.h> |
11046 | #include <errno.h> | |
11047 | @@ -23,19 +22,19 @@ | |
11048 | static int http_chunk_append_len(server *srv, connection *con, size_t len) { | |
11049 | size_t i, olen = len, j; | |
11050 | buffer *b; | |
11051 | - | |
11052 | + | |
11053 | b = srv->tmp_chunk_len; | |
11054 | - | |
11055 | + | |
11056 | if (len == 0) { | |
11057 | buffer_copy_string(b, "0"); | |
11058 | } else { | |
11059 | for (i = 0; i < 8 && len; i++) { | |
11060 | len >>= 4; | |
11061 | } | |
11062 | - | |
11063 | + | |
11064 | /* i is the number of hex digits we have */ | |
11065 | buffer_prepare_copy(b, i + 1); | |
11066 | - | |
11067 | + | |
11068 | for (j = i-1, len = olen; j+1 > 0; j--) { | |
11069 | b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10); | |
11070 | len >>= 4; | |
11071 | @@ -43,61 +42,61 @@ | |
11072 | b->used = i; | |
11073 | b->ptr[b->used++] = '\0'; | |
11074 | } | |
11075 | - | |
11076 | + | |
11077 | buffer_append_string(b, "\r\n"); | |
11078 | chunkqueue_append_buffer(con->write_queue, b); | |
11079 | - | |
11080 | + | |
11081 | return 0; | |
11082 | } | |
f26f9fd5 | 11083 | |
f26f9fd5 | 11084 | |
2519e6e5 ER |
11085 | int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) { |
11086 | chunkqueue *cq; | |
11087 | - | |
f673a614 | 11088 | + |
2519e6e5 ER |
11089 | if (!con) return -1; |
11090 | - | |
f673a614 | 11091 | + |
2519e6e5 ER |
11092 | cq = con->write_queue; |
11093 | - | |
f673a614 | 11094 | + |
2519e6e5 ER |
11095 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { |
11096 | http_chunk_append_len(srv, con, len); | |
f26f9fd5 | 11097 | } |
2519e6e5 ER |
11098 | - |
11099 | + | |
11100 | chunkqueue_append_file(cq, fn, offset, len); | |
11101 | - | |
11102 | + | |
11103 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) { | |
11104 | chunkqueue_append_mem(cq, "\r\n", 2 + 1); | |
11105 | } | |
11106 | - | |
11107 | + | |
f26f9fd5 ER |
11108 | return 0; |
11109 | } | |
f673a614 | 11110 | |
2519e6e5 ER |
11111 | int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) { |
11112 | chunkqueue *cq; | |
11113 | - | |
11114 | + | |
11115 | if (!con) return -1; | |
11116 | - | |
11117 | + | |
11118 | cq = con->write_queue; | |
11119 | - | |
11120 | + | |
11121 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { | |
11122 | http_chunk_append_len(srv, con, mem->used - 1); | |
11123 | } | |
11124 | - | |
11125 | + | |
11126 | chunkqueue_append_buffer(cq, mem); | |
11127 | - | |
11128 | + | |
11129 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) { | |
11130 | chunkqueue_append_mem(cq, "\r\n", 2 + 1); | |
11131 | } | |
11132 | - | |
11133 | + | |
11134 | return 0; | |
f26f9fd5 ER |
11135 | } |
11136 | ||
2519e6e5 ER |
11137 | int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) { |
11138 | chunkqueue *cq; | |
11139 | - | |
11140 | + | |
11141 | if (!con) return -1; | |
11142 | - | |
11143 | + | |
11144 | cq = con->write_queue; | |
11145 | - | |
11146 | + | |
11147 | if (len == 0) { | |
11148 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { | |
11149 | http_chunk_append_len(srv, con, 0); | |
11150 | @@ -107,17 +106,17 @@ | |
f26f9fd5 | 11151 | } |
2519e6e5 | 11152 | return 0; |
f26f9fd5 | 11153 | } |
2519e6e5 ER |
11154 | - |
11155 | + | |
11156 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { | |
11157 | http_chunk_append_len(srv, con, len - 1); | |
11158 | } | |
11159 | - | |
11160 | + | |
11161 | chunkqueue_append_mem(cq, mem, len); | |
11162 | - | |
11163 | + | |
11164 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { | |
11165 | chunkqueue_append_mem(cq, "\r\n", 2 + 1); | |
11166 | } | |
11167 | - | |
11168 | + | |
f26f9fd5 ER |
11169 | return 0; |
11170 | } | |
f26f9fd5 | 11171 | |
2519e6e5 ER |
11172 | @@ -125,9 +124,9 @@ |
11173 | off_t http_chunkqueue_length(server *srv, connection *con) { | |
11174 | if (!con) { | |
11175 | log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!"); | |
11176 | - | |
11177 | + | |
11178 | return 0; | |
11179 | } | |
11180 | - | |
11181 | + | |
11182 | return chunkqueue_length(con->write_queue); | |
f26f9fd5 | 11183 | } |
1175ccec ER |
11184 | --- ../lighttpd-1.4.11/src/http_resp.c 1970-01-01 03:00:00.000000000 +0300 |
11185 | +++ lighttpd-1.4.12/src/http_resp.c 2006-07-15 22:43:21.000000000 +0300 | |
11186 | @@ -0,0 +1,274 @@ | |
2519e6e5 ER |
11187 | +#include <string.h> |
11188 | +#include <stdlib.h> | |
11189 | +#include <stdio.h> | |
11190 | +#include <assert.h> | |
11191 | + | |
11192 | +#include "http_resp.h" | |
11193 | +#include "http_resp_parser.h" | |
11194 | + | |
11195 | +/* declare prototypes for the parser */ | |
11196 | +void *http_resp_parserAlloc(void *(*mallocProc)(size_t)); | |
11197 | +void http_resp_parserFree(void *p, void (*freeProc)(void*)); | |
11198 | +void http_resp_parserTrace(FILE *TraceFILE, char *zTracePrompt); | |
11199 | +void http_resp_parser(void *, int, buffer *, http_resp_ctx_t *); | |
11200 | + | |
11201 | +typedef struct { | |
11202 | + chunkqueue *cq; | |
11203 | + | |
11204 | + chunk *c; /* current chunk in the chunkqueue */ | |
1175ccec | 11205 | + size_t offset; /* current offset in current chunk */ |
2519e6e5 | 11206 | + |
1175ccec ER |
11207 | + chunk *lookup_c; |
11208 | + size_t lookup_offset; | |
2519e6e5 | 11209 | + |
1175ccec ER |
11210 | + int is_key; |
11211 | + int is_statusline; | |
2519e6e5 ER |
11212 | +} http_resp_tokenizer_t; |
11213 | + | |
11214 | +http_resp *http_response_init(void) { | |
1175ccec | 11215 | + http_resp *resp = calloc(1, sizeof(*resp)); |
2519e6e5 | 11216 | + |
1175ccec ER |
11217 | + resp->reason = buffer_init(); |
11218 | + resp->headers = array_init(); | |
2519e6e5 | 11219 | + |
1175ccec | 11220 | + return resp; |
2519e6e5 ER |
11221 | +} |
11222 | + | |
11223 | +void http_response_reset(http_resp *resp) { | |
1175ccec | 11224 | + if (!resp) return; |
2519e6e5 | 11225 | + |
1175ccec ER |
11226 | + buffer_reset(resp->reason); |
11227 | + array_reset(resp->headers); | |
2519e6e5 ER |
11228 | + |
11229 | +} | |
11230 | + | |
11231 | +void http_response_free(http_resp *resp) { | |
1175ccec | 11232 | + if (!resp) return; |
2519e6e5 | 11233 | + |
1175ccec ER |
11234 | + buffer_free(resp->reason); |
11235 | + array_free(resp->headers); | |
2519e6e5 | 11236 | + |
1175ccec | 11237 | + free(resp); |
2519e6e5 ER |
11238 | +} |
11239 | + | |
11240 | +static int http_resp_get_next_char(http_resp_tokenizer_t *t, unsigned char *c) { | |
1175ccec ER |
11241 | + if (t->offset == t->c->mem->used - 1) { |
11242 | + /* end of chunk, open next chunk */ | |
2519e6e5 | 11243 | + |
1175ccec | 11244 | + if (!t->c->next) return -1; |
2519e6e5 | 11245 | + |
1175ccec ER |
11246 | + t->c = t->c->next; |
11247 | + t->offset = 0; | |
11248 | + } | |
2519e6e5 | 11249 | + |
1175ccec | 11250 | + *c = t->c->mem->ptr[t->offset++]; |
2519e6e5 | 11251 | + |
1175ccec ER |
11252 | + t->lookup_offset = t->offset; |
11253 | + t->lookup_c = t->c; | |
2519e6e5 | 11254 | + |
1175ccec ER |
11255 | +#if 0 |
11256 | + fprintf(stderr, "%s.%d: get: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->offset - 1); | |
11257 | +#endif | |
2519e6e5 | 11258 | + |
1175ccec | 11259 | + return 0; |
2519e6e5 ER |
11260 | +} |
11261 | + | |
11262 | +static int http_resp_lookup_next_char(http_resp_tokenizer_t *t, unsigned char *c) { | |
1175ccec ER |
11263 | + if (t->lookup_offset == t->lookup_c->mem->used - 1) { |
11264 | + /* end of chunk, open next chunk */ | |
2519e6e5 | 11265 | + |
1175ccec | 11266 | + if (!t->lookup_c->next) return -1; |
2519e6e5 | 11267 | + |
1175ccec ER |
11268 | + t->lookup_c = t->lookup_c->next; |
11269 | + t->lookup_offset = 0; | |
11270 | + } | |
36e2a29e | 11271 | + |
1175ccec ER |
11272 | + *c = t->lookup_c->mem->ptr[t->lookup_offset++]; |
11273 | +#if 0 | |
11274 | + fprintf(stderr, "%s.%d: lookup: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->lookup_offset - 1); | |
11275 | +#endif | |
2519e6e5 | 11276 | + |
1175ccec | 11277 | + return 0; |
2519e6e5 ER |
11278 | +} |
11279 | + | |
11280 | + | |
11281 | +static int http_resp_tokenizer( | |
1175ccec ER |
11282 | + http_resp_tokenizer_t *t, |
11283 | + int *token_id, | |
11284 | + buffer *token | |
2519e6e5 | 11285 | +) { |
1175ccec ER |
11286 | + unsigned char c; |
11287 | + int tid = 0; | |
11288 | + | |
11289 | + /* push the token to the parser */ | |
11290 | + | |
11291 | + while (tid == 0 && 0 == http_resp_get_next_char(t, &c)) { | |
11292 | + switch (c) { | |
11293 | + case ':': | |
11294 | + tid = TK_COLON; | |
11295 | + | |
11296 | + t->is_key = 0; | |
11297 | + | |
11298 | + break; | |
11299 | + case ' ': | |
11300 | + case '\t': | |
11301 | + /* ignore WS */ | |
11302 | + | |
11303 | + break; | |
11304 | + case '\r': | |
11305 | + if (0 != http_resp_lookup_next_char(t, &c)) return -1; | |
11306 | + | |
11307 | + if (c == '\n') { | |
11308 | + tid = TK_CRLF; | |
11309 | + | |
11310 | + t->c = t->lookup_c; | |
11311 | + t->offset = t->lookup_offset; | |
11312 | + | |
11313 | + t->is_statusline = 0; | |
11314 | + t->is_key = 1; | |
11315 | + } else { | |
11316 | + fprintf(stderr, "%s.%d: CR with out LF\r\n", __FILE__, __LINE__); | |
11317 | + return -1; | |
11318 | + } | |
11319 | + break; | |
11320 | + case '\n': | |
11321 | + tid = TK_CRLF; | |
11322 | + | |
11323 | + t->is_statusline = 0; | |
11324 | + t->is_key = 1; | |
11325 | + | |
11326 | + break; | |
11327 | + default: | |
11328 | + while (c >= 32 && c != 127 && c != 255) { | |
11329 | + if (t->is_statusline) { | |
11330 | + if (c == ':') { t->is_statusline = 0; break; } /* this is not a status line by a real header */ | |
11331 | + if (c == 32) break; /* the space is a splitter in the statusline */ | |
11332 | + } else { | |
11333 | + if (t->is_key) { | |
11334 | + if (c == ':') break; /* the : is the splitter between key and value */ | |
11335 | + } | |
11336 | + } | |
11337 | + if (0 != http_resp_lookup_next_char(t, &c)) return -1; | |
11338 | + } | |
11339 | + | |
11340 | + if (t->c == t->lookup_c && | |
11341 | + t->offset == t->lookup_offset + 1) { | |
11342 | + | |
11343 | + fprintf(stderr, "%s.%d: invalid char in string\n", __FILE__, __LINE__); | |
11344 | + return -1; | |
11345 | + } | |
11346 | + | |
11347 | + tid = TK_STRING; | |
11348 | + | |
11349 | + /* the lookup points to the first invalid char */ | |
11350 | + t->lookup_offset--; | |
11351 | + | |
11352 | + /* no overlapping string */ | |
11353 | + if (t->c == t->lookup_c) { | |
11354 | + buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->lookup_offset - t->offset + 1); | |
11355 | + } else { | |
11356 | + /* first chunk */ | |
11357 | + buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->c->mem->used - t->offset); | |
11358 | + | |
11359 | + /* chunks in the middle */ | |
11360 | + for (t->c = t->c->next; t->c != t->lookup_c; t->c = t->c->next) { | |
11361 | + buffer_append_string_buffer(token, t->c->mem); | |
11362 | + t->offset = t->c->mem->used - 1; | |
11363 | + } | |
11364 | + | |
11365 | + /* last chunk */ | |
11366 | + buffer_append_string_len(token, t->c->mem->ptr, t->lookup_offset); | |
11367 | + } | |
11368 | + | |
11369 | + t->offset = t->lookup_offset; | |
11370 | + | |
11371 | + break; | |
11372 | + } | |
2519e6e5 ER |
11373 | + } |
11374 | + | |
1175ccec | 11375 | + if (tid) { |
2519e6e5 ER |
11376 | + *token_id = tid; |
11377 | + | |
1175ccec ER |
11378 | + return 1; |
11379 | + } | |
2519e6e5 | 11380 | + |
1175ccec | 11381 | + return -1; |
2519e6e5 ER |
11382 | +} |
11383 | + | |
11384 | +parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *resp) { | |
1175ccec | 11385 | + http_resp_tokenizer_t t; |
2519e6e5 ER |
11386 | + void *pParser = NULL; |
11387 | + int token_id = 0; | |
11388 | + buffer *token = NULL; | |
11389 | + http_resp_ctx_t context; | |
1175ccec ER |
11390 | + parse_status_t ret = PARSE_UNSET; |
11391 | + int last_token_id = 0; | |
2519e6e5 ER |
11392 | + |
11393 | + t.cq = cq; | |
1175ccec ER |
11394 | + t.c = cq->first; |
11395 | + t.offset = t.c->offset; | |
11396 | + t.is_key = 0; | |
11397 | + t.is_statusline = 1; | |
2519e6e5 ER |
11398 | + |
11399 | + context.ok = 1; | |
1175ccec ER |
11400 | + context.errmsg = buffer_init(); |
11401 | + context.resp = resp; | |
2519e6e5 ER |
11402 | + |
11403 | + pParser = http_resp_parserAlloc( malloc ); | |
11404 | + token = buffer_init(); | |
1175ccec ER |
11405 | +#if 0 |
11406 | + http_resp_parserTrace(stderr, "http-response: "); | |
11407 | +#endif | |
2519e6e5 ER |
11408 | + |
11409 | + while((1 == http_resp_tokenizer(&t, &token_id, token)) && context.ok) { | |
11410 | + http_resp_parser(pParser, token_id, token, &context); | |
11411 | + | |
11412 | + token = buffer_init(); | |
11413 | + | |
1175ccec ER |
11414 | + /* CRLF CRLF ... the header end sequence */ |
11415 | + if (last_token_id == TK_CRLF && | |
11416 | + token_id == TK_CRLF) break; | |
2519e6e5 | 11417 | + |
1175ccec | 11418 | + last_token_id = token_id; |
2519e6e5 ER |
11419 | + } |
11420 | + | |
1175ccec ER |
11421 | + /* oops, the parser failed */ |
11422 | + if (context.ok == 0) { | |
11423 | + ret = PARSE_ERROR; | |
2519e6e5 | 11424 | + |
1175ccec ER |
11425 | + fprintf(stderr, "%s.%d: parsing failed at: ...%20s\r\n", |
11426 | + __FILE__, __LINE__, t.c->mem->ptr + t.offset); | |
11427 | + } | |
2519e6e5 ER |
11428 | + |
11429 | + http_resp_parser(pParser, 0, token, &context); | |
11430 | + http_resp_parserFree(pParser, free ); | |
11431 | + | |
1175ccec ER |
11432 | + if (context.ok == 0) { |
11433 | + /* we are missing the some tokens */ | |
2519e6e5 | 11434 | + |
1175ccec ER |
11435 | + if (!buffer_is_empty(context.errmsg)) { |
11436 | + fprintf(stderr, "%s.%d: hmm, %20s\r\n", | |
11437 | + __FILE__, __LINE__, context.errmsg->ptr); | |
11438 | + } | |
2519e6e5 | 11439 | + |
1175ccec ER |
11440 | + if (ret == PARSE_UNSET) { |
11441 | + ret = buffer_is_empty(context.errmsg) ? PARSE_NEED_MORE : PARSE_ERROR; | |
11442 | + } | |
11443 | + } else { | |
11444 | + chunk *c; | |
11445 | + | |
11446 | + for (c = cq->first; c != t.c; c = c->next) { | |
11447 | + c->offset = c->mem->used - 1; | |
11448 | + } | |
2519e6e5 | 11449 | + |
1175ccec | 11450 | + c->offset = t.offset; |
2519e6e5 | 11451 | + |
1175ccec ER |
11452 | + ret = PARSE_SUCCESS; |
11453 | + } | |
2519e6e5 | 11454 | + |
1175ccec ER |
11455 | + buffer_free(token); |
11456 | + buffer_free(context.errmsg); | |
2519e6e5 | 11457 | + |
1175ccec | 11458 | + return ret; |
2519e6e5 ER |
11459 | +} |
11460 | + | |
1175ccec | 11461 | --- ../lighttpd-1.4.11/src/http_resp.h 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 11462 | +++ lighttpd-1.4.12/src/http_resp.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
11463 | @@ -0,0 +1,34 @@ |
11464 | +#ifndef _HTTP_RESP_H_ | |
11465 | +#define _HTTP_RESP_H_ | |
11466 | + | |
11467 | +#include "array.h" | |
11468 | +#include "chunk.h" | |
11469 | + | |
11470 | +typedef enum { | |
11471 | + PARSE_UNSET, | |
11472 | + PARSE_SUCCESS, | |
11473 | + PARSE_ERROR, | |
11474 | + PARSE_NEED_MORE | |
11475 | +} parse_status_t; | |
11476 | + | |
11477 | +typedef struct { | |
11478 | + int protocol; /* http/1.0, http/1.1 */ | |
11479 | + int status; /* e.g. 200 */ | |
11480 | + buffer *reason; /* e.g. Ok */ | |
11481 | + array *headers; | |
11482 | +} http_resp; | |
11483 | + | |
11484 | +typedef struct { | |
11485 | + int ok; | |
11486 | + buffer *errmsg; | |
11487 | + | |
11488 | + http_resp *resp; | |
11489 | +} http_resp_ctx_t; | |
11490 | + | |
11491 | +http_resp *http_response_init(void); | |
11492 | +void http_response_free(http_resp *resp); | |
11493 | +void http_response_reset(http_resp *resp); | |
11494 | + | |
11495 | +parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *http_response); | |
11496 | + | |
11497 | +#endif | |
1175ccec ER |
11498 | --- ../lighttpd-1.4.11/src/http_resp_parser.c 1970-01-01 03:00:00.000000000 +0300 |
11499 | +++ lighttpd-1.4.12/src/http_resp_parser.c 2006-07-15 22:44:07.000000000 +0300 | |
11500 | @@ -0,0 +1,895 @@ | |
2519e6e5 ER |
11501 | +/* Driver template for the LEMON parser generator. |
11502 | +** The author disclaims copyright to this source code. | |
11503 | +*/ | |
11504 | +/* First off, code is include which follows the "include" declaration | |
11505 | +** in the input file. */ | |
11506 | +#include <stdio.h> | |
11507 | +#line 6 "./http_resp_parser.y" | |
11508 | + | |
11509 | +#include <assert.h> | |
11510 | +#include <string.h> | |
11511 | +#include "http_resp.h" | |
11512 | +#include "keyvalue.h" | |
11513 | +#include "array.h" | |
11514 | + | |
11515 | +#line 16 "http_resp_parser.c" | |
11516 | +/* Next is all token values, in a form suitable for use by makeheaders. | |
11517 | +** This section will be null unless lemon is run with the -m switch. | |
11518 | +*/ | |
11519 | +/* | |
11520 | +** These constants (all generated automatically by the parser generator) | |
11521 | +** specify the various kinds of tokens (terminals) that the parser | |
11522 | +** understands. | |
11523 | +** | |
11524 | +** Each symbol here is a terminal symbol in the grammar. | |
11525 | +*/ | |
11526 | +/* Make sure the INTERFACE macro is defined. | |
11527 | +*/ | |
11528 | +#ifndef INTERFACE | |
11529 | +# define INTERFACE 1 | |
11530 | +#endif | |
11531 | +/* The next thing included is series of defines which control | |
11532 | +** various aspects of the generated parser. | |
11533 | +** YYCODETYPE is the data type used for storing terminal | |
11534 | +** and nonterminal numbers. "unsigned char" is | |
11535 | +** used if there are fewer than 250 terminals | |
11536 | +** and nonterminals. "int" is used otherwise. | |
11537 | +** YYNOCODE is a number of type YYCODETYPE which corresponds | |
11538 | +** to no legal terminal or nonterminal number. This | |
11539 | +** number is used to fill in empty slots of the hash | |
11540 | +** table. | |
11541 | +** YYFALLBACK If defined, this indicates that one or more tokens | |
11542 | +** have fall-back values which should be used if the | |
11543 | +** original value of the token will not parse. | |
11544 | +** YYACTIONTYPE is the data type used for storing terminal | |
11545 | +** and nonterminal numbers. "unsigned char" is | |
11546 | +** used if there are fewer than 250 rules and | |
11547 | +** states combined. "int" is used otherwise. | |
11548 | +** http_resp_parserTOKENTYPE is the data type used for minor tokens given | |
11549 | +** directly to the parser from the tokenizer. | |
11550 | +** YYMINORTYPE is the data type used for all minor tokens. | |
11551 | +** This is typically a union of many types, one of | |
11552 | +** which is http_resp_parserTOKENTYPE. The entry in the union | |
11553 | +** for base tokens is called "yy0". | |
11554 | +** YYSTACKDEPTH is the maximum depth of the parser's stack. | |
11555 | +** http_resp_parserARG_SDECL A static variable declaration for the %extra_argument | |
11556 | +** http_resp_parserARG_PDECL A parameter declaration for the %extra_argument | |
11557 | +** http_resp_parserARG_STORE Code to store %extra_argument into yypParser | |
11558 | +** http_resp_parserARG_FETCH Code to extract %extra_argument from yypParser | |
11559 | +** YYNSTATE the combined number of states. | |
11560 | +** YYNRULE the number of rules in the grammar | |
11561 | +** YYERRORSYMBOL is the code number of the error symbol. If not | |
11562 | +** defined, then do no error processing. | |
11563 | +*/ | |
11564 | +/* \ 1 */ | |
11565 | +#define YYCODETYPE unsigned char | |
11566 | +#define YYNOCODE 12 | |
11567 | +#define YYACTIONTYPE unsigned char | |
11568 | +#define http_resp_parserTOKENTYPE buffer * | |
11569 | +typedef union { | |
11570 | + http_resp_parserTOKENTYPE yy0; | |
11571 | + http_resp * yy2; | |
11572 | + data_string * yy9; | |
11573 | + array * yy12; | |
11574 | + int yy20; | |
11575 | + int yy23; | |
11576 | +} YYMINORTYPE; | |
11577 | +#define YYSTACKDEPTH 100 | |
11578 | +#define http_resp_parserARG_SDECL http_resp_ctx_t *ctx; | |
11579 | +#define http_resp_parserARG_PDECL ,http_resp_ctx_t *ctx | |
11580 | +#define http_resp_parserARG_FETCH http_resp_ctx_t *ctx = yypParser->ctx | |
11581 | +#define http_resp_parserARG_STORE yypParser->ctx = ctx | |
11582 | +#define YYNSTATE 19 | |
11583 | +#define YYNRULE 9 | |
11584 | +#define YYERRORSYMBOL 4 | |
11585 | +#define YYERRSYMDT yy23 | |
11586 | +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) | |
11587 | +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) | |
11588 | +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) | |
11589 | + | |
11590 | +/* Next are that tables used to determine what action to take based on the | |
11591 | +** current state and lookahead token. These tables are used to implement | |
11592 | +** functions that take a state number and lookahead value and return an | |
11593 | +** action integer. | |
11594 | +** | |
11595 | +** Suppose the action integer is N. Then the action is determined as | |
11596 | +** follows | |
11597 | +** | |
11598 | +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead | |
11599 | +** token onto the stack and goto state N. | |
11600 | +** | |
11601 | +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. | |
11602 | +** | |
11603 | +** N == YYNSTATE+YYNRULE A syntax error has occurred. | |
11604 | +** | |
11605 | +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. | |
11606 | +** | |
11607 | +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused | |
11608 | +** slots in the yy_action[] table. | |
11609 | +** | |
11610 | +** The action table is constructed as a single large table named yy_action[]. | |
11611 | +** Given state S and lookahead X, the action is computed as | |
11612 | +** | |
11613 | +** yy_action[ yy_shift_ofst[S] + X ] | |
11614 | +** | |
11615 | +** If the index value yy_shift_ofst[S]+X is out of range or if the value | |
11616 | +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] | |
11617 | +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table | |
11618 | +** and that yy_default[S] should be used instead. | |
11619 | +** | |
11620 | +** The formula above is for computing the action when the lookahead is | |
11621 | +** a terminal symbol. If the lookahead is a non-terminal (as occurs after | |
11622 | +** a reduce action) then the yy_reduce_ofst[] array is used in place of | |
11623 | +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of | |
11624 | +** YY_SHIFT_USE_DFLT. | |
11625 | +** | |
11626 | +** The following are the tables generated in this section: | |
11627 | +** | |
11628 | +** yy_action[] A single table containing all actions. | |
11629 | +** yy_lookahead[] A table containing the lookahead for each entry in | |
11630 | +** yy_action. Used to detect hash collisions. | |
11631 | +** yy_shift_ofst[] For each state, the offset into yy_action for | |
11632 | +** shifting terminals. | |
11633 | +** yy_reduce_ofst[] For each state, the offset into yy_action for | |
11634 | +** shifting non-terminals after a reduce. | |
11635 | +** yy_default[] Default action for each state. | |
11636 | +*/ | |
11637 | +static YYACTIONTYPE yy_action[] = { | |
11638 | + /* 0 */ 8, 29, 18, 1, 14, 2, 4, 11, 15, 12, | |
11639 | + /* 10 */ 14, 13, 4, 21, 5, 19, 3, 5, 6, 7, | |
11640 | + /* 20 */ 9, 17, 16, 4, 20, 22, 22, 10, | |
11641 | +}; | |
11642 | +static YYCODETYPE yy_lookahead[] = { | |
11643 | + /* 0 */ 5, 6, 2, 8, 9, 1, 2, 1, 2, 8, | |
11644 | + /* 10 */ 9, 1, 2, 2, 3, 0, 9, 3, 2, 1, | |
11645 | + /* 20 */ 7, 2, 2, 2, 0, 2, 11, 10, | |
11646 | +}; | |
11647 | +#define YY_SHIFT_USE_DFLT (-1) | |
11648 | +static signed char yy_shift_ofst[] = { | |
11649 | + /* 0 */ 0, 4, 15, -1, 14, 16, 18, -1, 19, 20, | |
11650 | + /* 10 */ 6, 21, 10, 24, -1, -1, -1, 23, 11, | |
11651 | +}; | |
11652 | +#define YY_REDUCE_USE_DFLT (-6) | |
11653 | +static signed char yy_reduce_ofst[] = { | |
11654 | + /* 0 */ -5, 7, -6, -6, -6, -6, -6, -6, 13, 17, | |
11655 | + /* 10 */ -6, 1, 7, -6, -6, -6, -6, -6, -6, | |
11656 | +}; | |
11657 | +static YYACTIONTYPE yy_default[] = { | |
11658 | + /* 0 */ 28, 28, 28, 25, 28, 28, 28, 27, 28, 28, | |
11659 | + /* 10 */ 28, 28, 28, 28, 26, 24, 23, 28, 28, | |
11660 | +}; | |
11661 | +#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) | |
11662 | + | |
11663 | +/* The next table maps tokens into fallback tokens. If a construct | |
11664 | +** like the following: | |
11665 | +** | |
11666 | +** %fallback ID X Y Z. | |
11667 | +** | |
11668 | +** appears in the grammer, then ID becomes a fallback token for X, Y, | |
11669 | +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser | |
11670 | +** but it does not parse, the type of the token is changed to ID and | |
11671 | +** the parse is retried before an error is thrown. | |
11672 | +*/ | |
11673 | +#ifdef YYFALLBACK | |
11674 | +static const YYCODETYPE yyFallback[] = { | |
11675 | +}; | |
11676 | +#endif /* YYFALLBACK */ | |
11677 | + | |
11678 | +/* The following structure represents a single element of the | |
11679 | +** parser's stack. Information stored includes: | |
11680 | +** | |
11681 | +** + The state number for the parser at this level of the stack. | |
11682 | +** | |
11683 | +** + The value of the token stored at this level of the stack. | |
11684 | +** (In other words, the "major" token.) | |
11685 | +** | |
11686 | +** + The semantic value stored at this level of the stack. This is | |
11687 | +** the information used by the action routines in the grammar. | |
11688 | +** It is sometimes called the "minor" token. | |
11689 | +*/ | |
11690 | +struct yyStackEntry { | |
11691 | + int stateno; /* The state-number */ | |
11692 | + int major; /* The major token value. This is the code | |
11693 | + ** number for the token at this stack level */ | |
11694 | + YYMINORTYPE minor; /* The user-supplied minor token value. This | |
11695 | + ** is the value of the token */ | |
11696 | +}; | |
11697 | +typedef struct yyStackEntry yyStackEntry; | |
11698 | + | |
11699 | +/* The state of the parser is completely contained in an instance of | |
11700 | +** the following structure */ | |
11701 | +struct yyParser { | |
11702 | + int yyidx; /* Index of top element in stack */ | |
11703 | + int yyerrcnt; /* Shifts left before out of the error */ | |
11704 | + http_resp_parserARG_SDECL /* A place to hold %extra_argument */ | |
11705 | + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ | |
11706 | +}; | |
11707 | +typedef struct yyParser yyParser; | |
11708 | + | |
11709 | +#ifndef NDEBUG | |
11710 | +#include <stdio.h> | |
11711 | +static FILE *yyTraceFILE = 0; | |
11712 | +static char *yyTracePrompt = 0; | |
11713 | +#endif /* NDEBUG */ | |
11714 | + | |
11715 | +#ifndef NDEBUG | |
11716 | +/* | |
11717 | +** Turn parser tracing on by giving a stream to which to write the trace | |
11718 | +** and a prompt to preface each trace message. Tracing is turned off | |
11719 | +** by making either argument NULL | |
11720 | +** | |
11721 | +** Inputs: | |
11722 | +** <ul> | |
11723 | +** <li> A FILE* to which trace output should be written. | |
11724 | +** If NULL, then tracing is turned off. | |
11725 | +** <li> A prefix string written at the beginning of every | |
11726 | +** line of trace output. If NULL, then tracing is | |
11727 | +** turned off. | |
11728 | +** </ul> | |
11729 | +** | |
11730 | +** Outputs: | |
11731 | +** None. | |
11732 | +*/ | |
11733 | +void http_resp_parserTrace(FILE *TraceFILE, char *zTracePrompt){ | |
11734 | + yyTraceFILE = TraceFILE; | |
11735 | + yyTracePrompt = zTracePrompt; | |
11736 | + if( yyTraceFILE==0 ) yyTracePrompt = 0; | |
11737 | + else if( yyTracePrompt==0 ) yyTraceFILE = 0; | |
11738 | +} | |
11739 | +#endif /* NDEBUG */ | |
11740 | + | |
11741 | +#ifndef NDEBUG | |
11742 | +/* For tracing shifts, the names of all terminals and nonterminals | |
11743 | +** are required. The following table supplies these names */ | |
11744 | +static const char *yyTokenName[] = { | |
11745 | + "$", "CRLF", "STRING", "COLON", | |
11746 | + "error", "protocol", "response_hdr", "number", | |
11747 | + "headers", "header", "reason", | |
11748 | +}; | |
11749 | +#endif /* NDEBUG */ | |
11750 | + | |
11751 | +#ifndef NDEBUG | |
11752 | +/* For tracing reduce actions, the names of all rules are required. | |
11753 | +*/ | |
11754 | +static const char *yyRuleName[] = { | |
11755 | + /* 0 */ "response_hdr ::= headers CRLF", | |
11756 | + /* 1 */ "response_hdr ::= protocol number reason CRLF headers CRLF", | |
11757 | + /* 2 */ "protocol ::= STRING", | |
11758 | + /* 3 */ "number ::= STRING", | |
11759 | + /* 4 */ "reason ::= STRING", | |
11760 | + /* 5 */ "reason ::= reason STRING", | |
11761 | + /* 6 */ "headers ::= headers header", | |
11762 | + /* 7 */ "headers ::= header", | |
11763 | + /* 8 */ "header ::= STRING COLON STRING CRLF", | |
11764 | +}; | |
11765 | +#endif /* NDEBUG */ | |
11766 | + | |
11767 | +/* | |
11768 | +** This function returns the symbolic name associated with a token | |
11769 | +** value. | |
11770 | +*/ | |
11771 | +const char *http_resp_parserTokenName(int tokenType){ | |
11772 | +#ifndef NDEBUG | |
11773 | + if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){ | |
11774 | + return yyTokenName[tokenType]; | |
11775 | + }else{ | |
11776 | + return "Unknown"; | |
11777 | + } | |
11778 | +#else | |
11779 | + return ""; | |
11780 | +#endif | |
11781 | +} | |
11782 | + | |
11783 | +/* | |
11784 | +** This function allocates a new parser. | |
11785 | +** The only argument is a pointer to a function which works like | |
11786 | +** malloc. | |
11787 | +** | |
11788 | +** Inputs: | |
11789 | +** A pointer to the function used to allocate memory. | |
11790 | +** | |
11791 | +** Outputs: | |
11792 | +** A pointer to a parser. This pointer is used in subsequent calls | |
11793 | +** to http_resp_parser and http_resp_parserFree. | |
11794 | +*/ | |
11795 | +void *http_resp_parserAlloc(void *(*mallocProc)(size_t)){ | |
11796 | + yyParser *pParser; | |
11797 | + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); | |
11798 | + if( pParser ){ | |
11799 | + pParser->yyidx = -1; | |
11800 | + } | |
11801 | + return pParser; | |
11802 | +} | |
11803 | + | |
11804 | +/* The following function deletes the value associated with a | |
11805 | +** symbol. The symbol can be either a terminal or nonterminal. | |
11806 | +** "yymajor" is the symbol code, and "yypminor" is a pointer to | |
11807 | +** the value. | |
11808 | +*/ | |
11809 | +static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ | |
11810 | + switch( yymajor ){ | |
11811 | + /* Here is inserted the actions which take place when a | |
11812 | + ** terminal or non-terminal is destroyed. This can happen | |
11813 | + ** when the symbol is popped from the stack during a | |
11814 | + ** reduce or during error processing or when a parser is | |
11815 | + ** being destroyed before it is finished parsing. | |
11816 | + ** | |
11817 | + ** Note: during a reduce, the only symbols destroyed are those | |
11818 | + ** which appear on the RHS of the rule, but which are not used | |
11819 | + ** inside the C code. | |
11820 | + */ | |
11821 | + case 1: | |
11822 | + case 2: | |
11823 | + case 3: | |
11824 | +#line 23 "./http_resp_parser.y" | |
11825 | +{ buffer_free((yypminor->yy0)); } | |
11826 | +#line 326 "http_resp_parser.c" | |
11827 | + break; | |
11828 | + default: break; /* If no destructor action specified: do nothing */ | |
11829 | + } | |
11830 | +} | |
11831 | + | |
11832 | +/* | |
11833 | +** Pop the parser's stack once. | |
11834 | +** | |
11835 | +** If there is a destructor routine associated with the token which | |
11836 | +** is popped from the stack, then call it. | |
11837 | +** | |
11838 | +** Return the major token number for the symbol popped. | |
11839 | +*/ | |
11840 | +static int yy_pop_parser_stack(yyParser *pParser){ | |
11841 | + YYCODETYPE yymajor; | |
11842 | + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; | |
11843 | + | |
11844 | + if( pParser->yyidx<0 ) return 0; | |
11845 | +#ifndef NDEBUG | |
11846 | + if( yyTraceFILE && pParser->yyidx>=0 ){ | |
11847 | + fprintf(yyTraceFILE,"%sPopping %s\n", | |
11848 | + yyTracePrompt, | |
11849 | + yyTokenName[yytos->major]); | |
11850 | + } | |
11851 | +#endif | |
11852 | + yymajor = yytos->major; | |
11853 | + yy_destructor( yymajor, &yytos->minor); | |
11854 | + pParser->yyidx--; | |
11855 | + return yymajor; | |
11856 | +} | |
11857 | + | |
11858 | +/* | |
11859 | +** Deallocate and destroy a parser. Destructors are all called for | |
11860 | +** all stack elements before shutting the parser down. | |
11861 | +** | |
11862 | +** Inputs: | |
11863 | +** <ul> | |
11864 | +** <li> A pointer to the parser. This should be a pointer | |
11865 | +** obtained from http_resp_parserAlloc. | |
11866 | +** <li> A pointer to a function used to reclaim memory obtained | |
11867 | +** from malloc. | |
11868 | +** </ul> | |
11869 | +*/ | |
11870 | +void http_resp_parserFree( | |
11871 | + void *p, /* The parser to be deleted */ | |
11872 | + void (*freeProc)(void*) /* Function used to reclaim memory */ | |
11873 | +){ | |
11874 | + yyParser *pParser = (yyParser*)p; | |
11875 | + if( pParser==0 ) return; | |
11876 | + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); | |
11877 | + (*freeProc)((void*)pParser); | |
11878 | +} | |
11879 | + | |
11880 | +/* | |
11881 | +** Find the appropriate action for a parser given the terminal | |
11882 | +** look-ahead token iLookAhead. | |
11883 | +** | |
11884 | +** If the look-ahead token is YYNOCODE, then check to see if the action is | |
11885 | +** independent of the look-ahead. If it is, return the action, otherwise | |
11886 | +** return YY_NO_ACTION. | |
11887 | +*/ | |
11888 | +static int yy_find_shift_action( | |
11889 | + yyParser *pParser, /* The parser */ | |
11890 | + int iLookAhead /* The look-ahead token */ | |
11891 | +){ | |
11892 | + int i; | |
11893 | + int stateno = pParser->yystack[pParser->yyidx].stateno; | |
11894 | + | |
11895 | + /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */ | |
11896 | + i = yy_shift_ofst[stateno]; | |
11897 | + if( i==YY_SHIFT_USE_DFLT ){ | |
11898 | + return yy_default[stateno]; | |
11899 | + } | |
11900 | + if( iLookAhead==YYNOCODE ){ | |
11901 | + return YY_NO_ACTION; | |
11902 | + } | |
11903 | + i += iLookAhead; | |
11904 | + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ | |
11905 | +#ifdef YYFALLBACK | |
11906 | + int iFallback; /* Fallback token */ | |
11907 | + if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) | |
11908 | + && (iFallback = yyFallback[iLookAhead])!=0 ){ | |
11909 | +#ifndef NDEBUG | |
11910 | + if( yyTraceFILE ){ | |
11911 | + fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", | |
11912 | + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); | |
11913 | + } | |
11914 | +#endif | |
11915 | + return yy_find_shift_action(pParser, iFallback); | |
11916 | + } | |
11917 | +#endif | |
11918 | + return yy_default[stateno]; | |
11919 | + }else{ | |
11920 | + return yy_action[i]; | |
11921 | + } | |
11922 | +} | |
11923 | + | |
11924 | +/* | |
11925 | +** Find the appropriate action for a parser given the non-terminal | |
11926 | +** look-ahead token iLookAhead. | |
11927 | +** | |
11928 | +** If the look-ahead token is YYNOCODE, then check to see if the action is | |
11929 | +** independent of the look-ahead. If it is, return the action, otherwise | |
11930 | +** return YY_NO_ACTION. | |
11931 | +*/ | |
11932 | +static int yy_find_reduce_action( | |
11933 | + yyParser *pParser, /* The parser */ | |
11934 | + int iLookAhead /* The look-ahead token */ | |
11935 | +){ | |
11936 | + int i; | |
11937 | + int stateno = pParser->yystack[pParser->yyidx].stateno; | |
11938 | + | |
11939 | + i = yy_reduce_ofst[stateno]; | |
11940 | + if( i==YY_REDUCE_USE_DFLT ){ | |
11941 | + return yy_default[stateno]; | |
11942 | + } | |
11943 | + if( iLookAhead==YYNOCODE ){ | |
11944 | + return YY_NO_ACTION; | |
11945 | + } | |
11946 | + i += iLookAhead; | |
11947 | + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ | |
11948 | + return yy_default[stateno]; | |
11949 | + }else{ | |
11950 | + return yy_action[i]; | |
11951 | + } | |
11952 | +} | |
11953 | + | |
11954 | +/* | |
11955 | +** Perform a shift action. | |
11956 | +*/ | |
11957 | +static void yy_shift( | |
11958 | + yyParser *yypParser, /* The parser to be shifted */ | |
11959 | + int yyNewState, /* The new state to shift in */ | |
11960 | + int yyMajor, /* The major token to shift in */ | |
11961 | + YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ | |
11962 | +){ | |
11963 | + yyStackEntry *yytos; | |
11964 | + yypParser->yyidx++; | |
11965 | + if( yypParser->yyidx>=YYSTACKDEPTH ){ | |
11966 | + http_resp_parserARG_FETCH; | |
11967 | + yypParser->yyidx--; | |
11968 | +#ifndef NDEBUG | |
11969 | + if( yyTraceFILE ){ | |
11970 | + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); | |
11971 | + } | |
11972 | +#endif | |
11973 | + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); | |
11974 | + /* Here code is inserted which will execute if the parser | |
11975 | + ** stack every overflows */ | |
11976 | + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument var */ | |
11977 | + return; | |
11978 | + } | |
11979 | + yytos = &yypParser->yystack[yypParser->yyidx]; | |
11980 | + yytos->stateno = yyNewState; | |
11981 | + yytos->major = yyMajor; | |
11982 | + yytos->minor = *yypMinor; | |
11983 | +#ifndef NDEBUG | |
11984 | + if( yyTraceFILE && yypParser->yyidx>0 ){ | |
11985 | + int i; | |
11986 | + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); | |
11987 | + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); | |
11988 | + for(i=1; i<=yypParser->yyidx; i++) | |
11989 | + fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); | |
11990 | + fprintf(yyTraceFILE,"\n"); | |
11991 | + } | |
11992 | +#endif | |
11993 | +} | |
11994 | + | |
11995 | +/* The following table contains information about every rule that | |
11996 | +** is used during the reduce. | |
11997 | +*/ | |
11998 | +static struct { | |
11999 | + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ | |
12000 | + unsigned char nrhs; /* Number of right-hand side symbols in the rule */ | |
12001 | +} yyRuleInfo[] = { | |
12002 | + { 6, 2 }, | |
12003 | + { 6, 6 }, | |
12004 | + { 5, 1 }, | |
12005 | + { 7, 1 }, | |
12006 | + { 10, 1 }, | |
12007 | + { 10, 2 }, | |
12008 | + { 8, 2 }, | |
12009 | + { 8, 1 }, | |
12010 | + { 9, 4 }, | |
12011 | +}; | |
12012 | + | |
12013 | +static void yy_accept(yyParser*); /* Forward Declaration */ | |
12014 | + | |
12015 | +/* | |
12016 | +** Perform a reduce action and the shift that must immediately | |
12017 | +** follow the reduce. | |
12018 | +*/ | |
12019 | +static void yy_reduce( | |
12020 | + yyParser *yypParser, /* The parser */ | |
12021 | + int yyruleno /* Number of the rule by which to reduce */ | |
12022 | +){ | |
12023 | + int yygoto; /* The next state */ | |
12024 | + int yyact; /* The next action */ | |
12025 | + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ | |
12026 | + yyStackEntry *yymsp; /* The top of the parser's stack */ | |
12027 | + int yysize; /* Amount to pop the stack */ | |
12028 | + http_resp_parserARG_FETCH; | |
12029 | + yymsp = &yypParser->yystack[yypParser->yyidx]; | |
12030 | +#ifndef NDEBUG | |
12031 | + if( yyTraceFILE && yyruleno>=0 | |
12032 | + && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){ | |
12033 | + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, | |
12034 | + yyRuleName[yyruleno]); | |
12035 | + } | |
12036 | +#endif /* NDEBUG */ | |
12037 | + | |
12038 | + switch( yyruleno ){ | |
12039 | + /* Beginning here are the reduction cases. A typical example | |
12040 | + ** follows: | |
12041 | + ** case 0: | |
12042 | + ** #line <lineno> <grammarfile> | |
12043 | + ** { ... } // User supplied code | |
12044 | + ** #line <lineno> <thisfile> | |
12045 | + ** break; | |
12046 | + */ | |
12047 | + case 0: | |
12048 | +#line 26 "./http_resp_parser.y" | |
12049 | +{ | |
12050 | + http_resp *resp = ctx->resp; | |
12051 | + data_string *ds; | |
12052 | + | |
12053 | + resp->protocol = HTTP_VERSION_UNSET; | |
12054 | + | |
12055 | + buffer_copy_string(resp->reason, ""); /* no reason */ | |
12056 | + array_free(resp->headers); | |
12057 | + resp->headers = yymsp[-1].minor.yy12; | |
12058 | + | |
12059 | + if (NULL == (ds = (data_string *)array_get_element(yymsp[-1].minor.yy12, "Status"))) { | |
12060 | + resp->status = 0; | |
12061 | + } else { | |
12062 | + char *err; | |
12063 | + resp->status = strtol(ds->value->ptr, &err, 10); | |
1175ccec ER |
12064 | + |
12065 | + if (*err != '\0' && *err != ' ') { | |
2519e6e5 ER |
12066 | + buffer_copy_string(ctx->errmsg, "expected a number: "); |
12067 | + buffer_append_string_buffer(ctx->errmsg, ds->value); | |
1175ccec | 12068 | + buffer_append_string(ctx->errmsg, err); |
2519e6e5 ER |
12069 | + |
12070 | + ctx->ok = 0; | |
12071 | + } | |
2519e6e5 ER |
12072 | + } |
12073 | + | |
12074 | + yymsp[-1].minor.yy12 = NULL; | |
12075 | +} | |
12076 | +#line 576 "http_resp_parser.c" | |
12077 | + yy_destructor(1,&yymsp[0].minor); | |
12078 | + break; | |
12079 | + case 1: | |
12080 | +#line 54 "./http_resp_parser.y" | |
12081 | +{ | |
12082 | + http_resp *resp = ctx->resp; | |
12083 | + | |
12084 | + resp->status = yymsp[-4].minor.yy20; | |
12085 | + resp->protocol = yymsp[-5].minor.yy20; | |
12086 | + buffer_copy_string_buffer(resp->reason, yymsp[-3].minor.yy0); | |
12087 | + | |
12088 | + array_free(resp->headers); | |
12089 | + | |
12090 | + resp->headers = yymsp[-1].minor.yy12; | |
12091 | + | |
12092 | + yymsp[-1].minor.yy12 = NULL; | |
12093 | +} | |
12094 | +#line 594 "http_resp_parser.c" | |
12095 | + yy_destructor(1,&yymsp[-2].minor); | |
12096 | + yy_destructor(1,&yymsp[0].minor); | |
12097 | + break; | |
12098 | + case 2: | |
12099 | +#line 68 "./http_resp_parser.y" | |
12100 | +{ | |
12101 | + if (buffer_is_equal_string(yymsp[0].minor.yy0, CONST_STR_LEN("HTTP/1.0"))) { | |
12102 | + yygotominor.yy20 = HTTP_VERSION_1_0; | |
12103 | + } else if (buffer_is_equal_string(yymsp[0].minor.yy0, CONST_STR_LEN("HTTP/1.1"))) { | |
12104 | + yygotominor.yy20 = HTTP_VERSION_1_1; | |
12105 | + } else { | |
12106 | + buffer_copy_string(ctx->errmsg, "unknown protocol: "); | |
12107 | + buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0); | |
12108 | + | |
12109 | + ctx->ok = 0; | |
12110 | + } | |
12111 | +} | |
12112 | +#line 612 "http_resp_parser.c" | |
12113 | + break; | |
12114 | + case 3: | |
12115 | +#line 81 "./http_resp_parser.y" | |
12116 | +{ | |
12117 | + char *err; | |
12118 | + yygotominor.yy20 = strtol(yymsp[0].minor.yy0->ptr, &err, 10); | |
12119 | + | |
12120 | + if (*err != '\0') { | |
12121 | + buffer_copy_string(ctx->errmsg, "expected a number: "); | |
12122 | + buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0); | |
12123 | + | |
12124 | + ctx->ok = 0; | |
12125 | + } | |
12126 | +} | |
12127 | +#line 627 "http_resp_parser.c" | |
12128 | + break; | |
12129 | + case 4: | |
12130 | +#line 93 "./http_resp_parser.y" | |
12131 | +{ | |
1175ccec ER |
12132 | + yygotominor.yy0 = yymsp[0].minor.yy0; |
12133 | + yymsp[0].minor.yy0 = NULL; | |
2519e6e5 | 12134 | +} |
1175ccec | 12135 | +#line 635 "http_resp_parser.c" |
2519e6e5 ER |
12136 | + break; |
12137 | + case 5: | |
1175ccec | 12138 | +#line 98 "./http_resp_parser.y" |
2519e6e5 ER |
12139 | +{ |
12140 | + yygotominor.yy0 = yymsp[-1].minor.yy0; | |
12141 | + | |
12142 | + buffer_append_string(yygotominor.yy0, " "); | |
12143 | + buffer_append_string_buffer(yygotominor.yy0, yymsp[0].minor.yy0); | |
12144 | + | |
12145 | + yymsp[-1].minor.yy0 = NULL; | |
12146 | +} | |
1175ccec | 12147 | +#line 647 "http_resp_parser.c" |
2519e6e5 ER |
12148 | + break; |
12149 | + case 6: | |
1175ccec | 12150 | +#line 107 "./http_resp_parser.y" |
2519e6e5 ER |
12151 | +{ |
12152 | + yygotominor.yy12 = yymsp[-1].minor.yy12; | |
12153 | + | |
12154 | + array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9); | |
12155 | + | |
12156 | + yymsp[-1].minor.yy12 = NULL; | |
12157 | +} | |
1175ccec | 12158 | +#line 658 "http_resp_parser.c" |
2519e6e5 ER |
12159 | + break; |
12160 | + case 7: | |
1175ccec | 12161 | +#line 115 "./http_resp_parser.y" |
2519e6e5 ER |
12162 | +{ |
12163 | + yygotominor.yy12 = array_init(); | |
12164 | + | |
12165 | + array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9); | |
12166 | +} | |
1175ccec | 12167 | +#line 667 "http_resp_parser.c" |
2519e6e5 ER |
12168 | + break; |
12169 | + case 8: | |
1175ccec | 12170 | +#line 120 "./http_resp_parser.y" |
2519e6e5 ER |
12171 | +{ |
12172 | + yygotominor.yy9 = data_string_init(); | |
12173 | + | |
12174 | + buffer_copy_string_buffer(yygotominor.yy9->key, yymsp[-3].minor.yy0); | |
12175 | + buffer_copy_string_buffer(yygotominor.yy9->value, yymsp[-1].minor.yy0); | |
12176 | +} | |
1175ccec | 12177 | +#line 677 "http_resp_parser.c" |
2519e6e5 ER |
12178 | + yy_destructor(3,&yymsp[-2].minor); |
12179 | + yy_destructor(1,&yymsp[0].minor); | |
12180 | + break; | |
12181 | + }; | |
12182 | + yygoto = yyRuleInfo[yyruleno].lhs; | |
12183 | + yysize = yyRuleInfo[yyruleno].nrhs; | |
12184 | + yypParser->yyidx -= yysize; | |
12185 | + yyact = yy_find_reduce_action(yypParser,yygoto); | |
12186 | + if( yyact < YYNSTATE ){ | |
12187 | + yy_shift(yypParser,yyact,yygoto,&yygotominor); | |
12188 | + }else if( yyact == YYNSTATE + YYNRULE + 1 ){ | |
12189 | + yy_accept(yypParser); | |
12190 | + } | |
12191 | +} | |
12192 | + | |
12193 | +/* | |
12194 | +** The following code executes when the parse fails | |
12195 | +*/ | |
12196 | +static void yy_parse_failed( | |
12197 | + yyParser *yypParser /* The parser */ | |
12198 | +){ | |
12199 | + http_resp_parserARG_FETCH; | |
12200 | +#ifndef NDEBUG | |
12201 | + if( yyTraceFILE ){ | |
12202 | + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); | |
12203 | + } | |
12204 | +#endif | |
12205 | + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); | |
12206 | + /* Here code is inserted which will be executed whenever the | |
12207 | + ** parser fails */ | |
12208 | +#line 14 "./http_resp_parser.y" | |
12209 | + | |
12210 | + ctx->ok = 0; | |
12211 | + | |
1175ccec | 12212 | +#line 712 "http_resp_parser.c" |
2519e6e5 ER |
12213 | + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */ |
12214 | +} | |
12215 | + | |
12216 | +/* | |
12217 | +** The following code executes when a syntax error first occurs. | |
12218 | +*/ | |
12219 | +static void yy_syntax_error( | |
12220 | + yyParser *yypParser, /* The parser */ | |
12221 | + int yymajor, /* The major type of the error token */ | |
12222 | + YYMINORTYPE yyminor /* The minor type of the error token */ | |
12223 | +){ | |
12224 | + http_resp_parserARG_FETCH; | |
12225 | +#define TOKEN (yyminor.yy0) | |
12226 | + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */ | |
12227 | +} | |
12228 | + | |
12229 | +/* | |
12230 | +** The following is executed when the parser accepts | |
12231 | +*/ | |
12232 | +static void yy_accept( | |
12233 | + yyParser *yypParser /* The parser */ | |
12234 | +){ | |
12235 | + http_resp_parserARG_FETCH; | |
12236 | +#ifndef NDEBUG | |
12237 | + if( yyTraceFILE ){ | |
12238 | + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); | |
12239 | + } | |
12240 | +#endif | |
12241 | + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); | |
12242 | + /* Here code is inserted which will be executed whenever the | |
12243 | + ** parser accepts */ | |
12244 | + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */ | |
12245 | +} | |
12246 | + | |
12247 | +/* The main parser program. | |
12248 | +** The first argument is a pointer to a structure obtained from | |
12249 | +** "http_resp_parserAlloc" which describes the current state of the parser. | |
12250 | +** The second argument is the major token number. The third is | |
12251 | +** the minor token. The fourth optional argument is whatever the | |
12252 | +** user wants (and specified in the grammar) and is available for | |
12253 | +** use by the action routines. | |
12254 | +** | |
12255 | +** Inputs: | |
12256 | +** <ul> | |
12257 | +** <li> A pointer to the parser (an opaque structure.) | |
12258 | +** <li> The major token number. | |
12259 | +** <li> The minor token number. | |
12260 | +** <li> An option argument of a grammar-specified type. | |
12261 | +** </ul> | |
12262 | +** | |
12263 | +** Outputs: | |
12264 | +** None. | |
12265 | +*/ | |
12266 | +void http_resp_parser( | |
12267 | + void *yyp, /* The parser */ | |
12268 | + int yymajor, /* The major token code number */ | |
12269 | + http_resp_parserTOKENTYPE yyminor /* The value for the token */ | |
12270 | + http_resp_parserARG_PDECL /* Optional %extra_argument parameter */ | |
12271 | +){ | |
12272 | + YYMINORTYPE yyminorunion; | |
12273 | + int yyact; /* The parser action. */ | |
12274 | + int yyendofinput; /* True if we are at the end of input */ | |
12275 | + int yyerrorhit = 0; /* True if yymajor has invoked an error */ | |
12276 | + yyParser *yypParser; /* The parser */ | |
12277 | + | |
12278 | + /* (re)initialize the parser, if necessary */ | |
12279 | + yypParser = (yyParser*)yyp; | |
12280 | + if( yypParser->yyidx<0 ){ | |
12281 | + if( yymajor==0 ) return; | |
12282 | + yypParser->yyidx = 0; | |
12283 | + yypParser->yyerrcnt = -1; | |
12284 | + yypParser->yystack[0].stateno = 0; | |
12285 | + yypParser->yystack[0].major = 0; | |
12286 | + } | |
12287 | + yyminorunion.yy0 = yyminor; | |
12288 | + yyendofinput = (yymajor==0); | |
12289 | + http_resp_parserARG_STORE; | |
12290 | + | |
12291 | +#ifndef NDEBUG | |
12292 | + if( yyTraceFILE ){ | |
12293 | + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); | |
12294 | + } | |
12295 | +#endif | |
12296 | + | |
12297 | + do{ | |
12298 | + yyact = yy_find_shift_action(yypParser,yymajor); | |
12299 | + if( yyact<YYNSTATE ){ | |
12300 | + yy_shift(yypParser,yyact,yymajor,&yyminorunion); | |
12301 | + yypParser->yyerrcnt--; | |
12302 | + if( yyendofinput && yypParser->yyidx>=0 ){ | |
12303 | + yymajor = 0; | |
12304 | + }else{ | |
12305 | + yymajor = YYNOCODE; | |
12306 | + } | |
12307 | + }else if( yyact < YYNSTATE + YYNRULE ){ | |
12308 | + yy_reduce(yypParser,yyact-YYNSTATE); | |
12309 | + }else if( yyact == YY_ERROR_ACTION ){ | |
12310 | + int yymx; | |
12311 | +#ifndef NDEBUG | |
12312 | + if( yyTraceFILE ){ | |
12313 | + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); | |
12314 | + } | |
12315 | +#endif | |
12316 | +#ifdef YYERRORSYMBOL | |
12317 | + /* A syntax error has occurred. | |
12318 | + ** The response to an error depends upon whether or not the | |
12319 | + ** grammar defines an error token "ERROR". | |
12320 | + ** | |
12321 | + ** This is what we do if the grammar does define ERROR: | |
12322 | + ** | |
12323 | + ** * Call the %syntax_error function. | |
12324 | + ** | |
12325 | + ** * Begin popping the stack until we enter a state where | |
12326 | + ** it is legal to shift the error symbol, then shift | |
12327 | + ** the error symbol. | |
12328 | + ** | |
12329 | + ** * Set the error count to three. | |
12330 | + ** | |
12331 | + ** * Begin accepting and shifting new tokens. No new error | |
12332 | + ** processing will occur until three tokens have been | |
12333 | + ** shifted successfully. | |
12334 | + ** | |
12335 | + */ | |
12336 | + if( yypParser->yyerrcnt<0 ){ | |
12337 | + yy_syntax_error(yypParser,yymajor,yyminorunion); | |
12338 | + } | |
12339 | + yymx = yypParser->yystack[yypParser->yyidx].major; | |
12340 | + if( yymx==YYERRORSYMBOL || yyerrorhit ){ | |
12341 | +#ifndef NDEBUG | |
12342 | + if( yyTraceFILE ){ | |
12343 | + fprintf(yyTraceFILE,"%sDiscard input token %s\n", | |
12344 | + yyTracePrompt,yyTokenName[yymajor]); | |
12345 | + } | |
12346 | +#endif | |
12347 | + yy_destructor(yymajor,&yyminorunion); | |
12348 | + yymajor = YYNOCODE; | |
12349 | + }else{ | |
12350 | + while( | |
12351 | + yypParser->yyidx >= 0 && | |
12352 | + yymx != YYERRORSYMBOL && | |
12353 | + (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE | |
12354 | + ){ | |
12355 | + yy_pop_parser_stack(yypParser); | |
12356 | + } | |
12357 | + if( yypParser->yyidx < 0 || yymajor==0 ){ | |
12358 | + yy_destructor(yymajor,&yyminorunion); | |
12359 | + yy_parse_failed(yypParser); | |
12360 | + yymajor = YYNOCODE; | |
12361 | + }else if( yymx!=YYERRORSYMBOL ){ | |
12362 | + YYMINORTYPE u2; | |
12363 | + u2.YYERRSYMDT = 0; | |
12364 | + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); | |
12365 | + } | |
12366 | + } | |
12367 | + yypParser->yyerrcnt = 3; | |
12368 | + yyerrorhit = 1; | |
12369 | +#else /* YYERRORSYMBOL is not defined */ | |
12370 | + /* This is what we do if the grammar does not define ERROR: | |
12371 | + ** | |
12372 | + ** * Report an error message, and throw away the input token. | |
12373 | + ** | |
12374 | + ** * If the input token is $, then fail the parse. | |
12375 | + ** | |
12376 | + ** As before, subsequent error messages are suppressed until | |
12377 | + ** three input tokens have been successfully shifted. | |
12378 | + */ | |
12379 | + if( yypParser->yyerrcnt<=0 ){ | |
12380 | + yy_syntax_error(yypParser,yymajor,yyminorunion); | |
12381 | + } | |
12382 | + yypParser->yyerrcnt = 3; | |
12383 | + yy_destructor(yymajor,&yyminorunion); | |
12384 | + if( yyendofinput ){ | |
12385 | + yy_parse_failed(yypParser); | |
12386 | + } | |
12387 | + yymajor = YYNOCODE; | |
12388 | +#endif | |
12389 | + }else{ | |
12390 | + yy_accept(yypParser); | |
12391 | + yymajor = YYNOCODE; | |
12392 | + } | |
12393 | + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); | |
12394 | + return; | |
12395 | +} | |
1175ccec | 12396 | --- ../lighttpd-1.4.11/src/inet_ntop_cache.c 2005-08-11 01:26:38.000000000 +0300 |
36e2a29e | 12397 | +++ lighttpd-1.4.12/src/inet_ntop_cache.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
12398 | @@ -8,7 +8,7 @@ |
12399 | #include "sys-socket.h" | |
12400 | ||
12401 | const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) { | |
12402 | -#ifdef HAVE_IPV6 | |
12403 | +#ifdef HAVE_IPV6 | |
12404 | size_t ndx = 0, i; | |
12405 | for (i = 0; i < INET_NTOP_CACHE_MAX; i++) { | |
12406 | if (srv->inet_ntop_cache[i].ts != 0) { | |
12407 | @@ -20,31 +20,31 @@ | |
12408 | srv->inet_ntop_cache[i].addr.ipv4.s_addr == addr->ipv4.sin_addr.s_addr) { | |
12409 | /* IPv4 found in cache */ | |
12410 | break; | |
12411 | - | |
12412 | + | |
12413 | } | |
12414 | } | |
12415 | } | |
12416 | - | |
12417 | + | |
12418 | if (i == INET_NTOP_CACHE_MAX) { | |
12419 | /* not found in cache */ | |
12420 | - | |
12421 | + | |
12422 | i = ndx; | |
12423 | - inet_ntop(addr->plain.sa_family, | |
12424 | - addr->plain.sa_family == AF_INET6 ? | |
12425 | + inet_ntop(addr->plain.sa_family, | |
12426 | + addr->plain.sa_family == AF_INET6 ? | |
12427 | (const void *) &(addr->ipv6.sin6_addr) : | |
12428 | (const void *) &(addr->ipv4.sin_addr), | |
12429 | srv->inet_ntop_cache[i].b2, INET6_ADDRSTRLEN); | |
12430 | - | |
12431 | + | |
12432 | srv->inet_ntop_cache[i].ts = srv->cur_ts; | |
12433 | srv->inet_ntop_cache[i].family = addr->plain.sa_family; | |
12434 | - | |
12435 | + | |
12436 | if (srv->inet_ntop_cache[i].family == AF_INET) { | |
12437 | srv->inet_ntop_cache[i].addr.ipv4.s_addr = addr->ipv4.sin_addr.s_addr; | |
12438 | } else if (srv->inet_ntop_cache[i].family == AF_INET6) { | |
12439 | memcpy(srv->inet_ntop_cache[i].addr.ipv6.s6_addr, addr->ipv6.sin6_addr.s6_addr, 16); | |
12440 | } | |
12441 | } | |
12442 | - | |
12443 | + | |
12444 | return srv->inet_ntop_cache[i].b2; | |
12445 | #else | |
12446 | UNUSED(srv); | |
1175ccec | 12447 | --- ../lighttpd-1.4.11/src/joblist.c 2005-08-11 01:26:41.000000000 +0300 |
36e2a29e | 12448 | +++ lighttpd-1.4.12/src/joblist.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
12449 | @@ -7,7 +7,7 @@ |
12450 | ||
12451 | int joblist_append(server *srv, connection *con) { | |
12452 | if (con->in_joblist) return 0; | |
12453 | - | |
12454 | + | |
12455 | if (srv->joblist->size == 0) { | |
12456 | srv->joblist->size = 16; | |
12457 | srv->joblist->ptr = malloc(sizeof(*srv->joblist->ptr) * srv->joblist->size); | |
12458 | @@ -15,15 +15,15 @@ | |
12459 | srv->joblist->size += 16; | |
12460 | srv->joblist->ptr = realloc(srv->joblist->ptr, sizeof(*srv->joblist->ptr) * srv->joblist->size); | |
12461 | } | |
12462 | - | |
12463 | + | |
12464 | srv->joblist->ptr[srv->joblist->used++] = con; | |
12465 | - | |
12466 | + | |
12467 | return 0; | |
12468 | } | |
12469 | ||
12470 | void joblist_free(server *srv, connections *joblist) { | |
12471 | UNUSED(srv); | |
12472 | - | |
12473 | + | |
12474 | free(joblist->ptr); | |
12475 | free(joblist); | |
12476 | } | |
12477 | @@ -31,14 +31,14 @@ | |
12478 | connection *fdwaitqueue_unshift(server *srv, connections *fdwaitqueue) { | |
12479 | connection *con; | |
12480 | UNUSED(srv); | |
12481 | - | |
12482 | - | |
12483 | + | |
12484 | + | |
12485 | if (fdwaitqueue->used == 0) return NULL; | |
12486 | - | |
12487 | + | |
12488 | con = fdwaitqueue->ptr[0]; | |
12489 | - | |
12490 | + | |
12491 | memmove(fdwaitqueue->ptr, &(fdwaitqueue->ptr[1]), --fdwaitqueue->used * sizeof(*(fdwaitqueue->ptr))); | |
12492 | - | |
12493 | + | |
12494 | return con; | |
12495 | } | |
12496 | ||
12497 | @@ -50,9 +50,9 @@ | |
12498 | srv->fdwaitqueue->size += 16; | |
12499 | srv->fdwaitqueue->ptr = realloc(srv->fdwaitqueue->ptr, sizeof(*(srv->fdwaitqueue->ptr)) * srv->fdwaitqueue->size); | |
12500 | } | |
12501 | - | |
12502 | + | |
12503 | srv->fdwaitqueue->ptr[srv->fdwaitqueue->used++] = con; | |
12504 | - | |
12505 | + | |
12506 | return 0; | |
12507 | } | |
12508 | ||
1175ccec | 12509 | --- ../lighttpd-1.4.11/src/keyvalue.c 2006-03-02 16:08:06.000000000 +0200 |
36e2a29e | 12510 | +++ lighttpd-1.4.12/src/keyvalue.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
12511 | @@ -87,7 +87,8 @@ |
12512 | { 504, "Gateway Timeout" }, | |
12513 | { 505, "HTTP Version Not Supported" }, | |
12514 | { 507, "Insufficient Storage" }, /* WebDAV */ | |
12515 | - | |
12516 | + { 509, "Bandwidth Limit exceeded" }, | |
12517 | + | |
12518 | { -1, NULL } | |
12519 | }; | |
12520 | ||
12521 | @@ -102,12 +103,12 @@ | |
12522 | { 501, "501.html" }, | |
12523 | { 503, "503.html" }, | |
12524 | { 505, "505.html" }, | |
12525 | - | |
12526 | + | |
12527 | { -1, NULL } | |
12528 | }; | |
12529 | ||
12530 | ||
12531 | -const char *keyvalue_get_value(keyvalue *kv, int k) { | |
12532 | +const char *keyvalue_get_value(keyvalue *kv, int k) { | |
12533 | int i; | |
12534 | for (i = 0; kv[i].value; i++) { | |
12535 | if (kv[i].key == k) return kv[i].value; | |
12536 | @@ -115,7 +116,7 @@ | |
12537 | return NULL; | |
12538 | } | |
12539 | ||
12540 | -int keyvalue_get_key(keyvalue *kv, const char *s) { | |
12541 | +int keyvalue_get_key(keyvalue *kv, const char *s) { | |
12542 | int i; | |
12543 | for (i = 0; kv[i].value; i++) { | |
12544 | if (0 == strcmp(kv[i].value, s)) return kv[i].key; | |
12545 | @@ -125,9 +126,9 @@ | |
12546 | ||
12547 | keyvalue_buffer *keyvalue_buffer_init(void) { | |
12548 | keyvalue_buffer *kvb; | |
12549 | - | |
12550 | + | |
12551 | kvb = calloc(1, sizeof(*kvb)); | |
12552 | - | |
12553 | + | |
12554 | return kvb; | |
12555 | } | |
12556 | ||
12557 | @@ -135,49 +136,49 @@ | |
12558 | size_t i; | |
12559 | if (kvb->size == 0) { | |
12560 | kvb->size = 4; | |
12561 | - | |
12562 | + | |
12563 | kvb->kv = malloc(kvb->size * sizeof(*kvb->kv)); | |
12564 | - | |
12565 | + | |
12566 | for(i = 0; i < kvb->size; i++) { | |
12567 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12568 | } | |
12569 | } else if (kvb->used == kvb->size) { | |
12570 | kvb->size += 4; | |
12571 | - | |
12572 | + | |
12573 | kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv)); | |
12574 | - | |
12575 | + | |
12576 | for(i = kvb->used; i < kvb->size; i++) { | |
12577 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12578 | } | |
12579 | } | |
12580 | - | |
12581 | + | |
12582 | kvb->kv[kvb->used]->key = key; | |
12583 | kvb->kv[kvb->used]->value = strdup(value); | |
12584 | - | |
12585 | + | |
12586 | kvb->used++; | |
12587 | - | |
12588 | + | |
12589 | return 0; | |
12590 | } | |
12591 | ||
12592 | void keyvalue_buffer_free(keyvalue_buffer *kvb) { | |
12593 | size_t i; | |
12594 | - | |
12595 | + | |
12596 | for (i = 0; i < kvb->size; i++) { | |
12597 | if (kvb->kv[i]->value) free(kvb->kv[i]->value); | |
12598 | free(kvb->kv[i]); | |
12599 | } | |
12600 | - | |
12601 | + | |
12602 | if (kvb->kv) free(kvb->kv); | |
12603 | - | |
12604 | + | |
12605 | free(kvb); | |
12606 | } | |
12607 | ||
12608 | ||
12609 | s_keyvalue_buffer *s_keyvalue_buffer_init(void) { | |
12610 | s_keyvalue_buffer *kvb; | |
12611 | - | |
12612 | + | |
12613 | kvb = calloc(1, sizeof(*kvb)); | |
12614 | - | |
12615 | + | |
12616 | return kvb; | |
12617 | } | |
12618 | ||
12619 | @@ -186,50 +187,50 @@ | |
12620 | if (kvb->size == 0) { | |
12621 | kvb->size = 4; | |
12622 | kvb->used = 0; | |
12623 | - | |
12624 | + | |
12625 | kvb->kv = malloc(kvb->size * sizeof(*kvb->kv)); | |
12626 | - | |
12627 | + | |
12628 | for(i = 0; i < kvb->size; i++) { | |
12629 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12630 | } | |
12631 | } else if (kvb->used == kvb->size) { | |
12632 | kvb->size += 4; | |
12633 | - | |
12634 | + | |
12635 | kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv)); | |
12636 | - | |
12637 | + | |
12638 | for(i = kvb->used; i < kvb->size; i++) { | |
12639 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12640 | } | |
12641 | } | |
12642 | - | |
12643 | + | |
12644 | kvb->kv[kvb->used]->key = key ? strdup(key) : NULL; | |
12645 | kvb->kv[kvb->used]->value = strdup(value); | |
12646 | - | |
12647 | + | |
12648 | kvb->used++; | |
12649 | - | |
12650 | + | |
12651 | return 0; | |
12652 | } | |
12653 | ||
12654 | void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) { | |
12655 | size_t i; | |
12656 | - | |
12657 | + | |
12658 | for (i = 0; i < kvb->size; i++) { | |
12659 | if (kvb->kv[i]->key) free(kvb->kv[i]->key); | |
12660 | if (kvb->kv[i]->value) free(kvb->kv[i]->value); | |
12661 | free(kvb->kv[i]); | |
12662 | } | |
12663 | - | |
12664 | + | |
12665 | if (kvb->kv) free(kvb->kv); | |
12666 | - | |
12667 | + | |
12668 | free(kvb); | |
12669 | } | |
12670 | ||
12671 | ||
12672 | httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) { | |
12673 | httpauth_keyvalue_buffer *kvb; | |
12674 | - | |
12675 | + | |
12676 | kvb = calloc(1, sizeof(*kvb)); | |
12677 | - | |
12678 | + | |
12679 | return kvb; | |
12680 | } | |
12681 | ||
12682 | @@ -237,42 +238,42 @@ | |
12683 | size_t i; | |
12684 | if (kvb->size == 0) { | |
12685 | kvb->size = 4; | |
12686 | - | |
12687 | + | |
12688 | kvb->kv = malloc(kvb->size * sizeof(*kvb->kv)); | |
12689 | - | |
12690 | + | |
12691 | for(i = 0; i < kvb->size; i++) { | |
12692 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12693 | } | |
12694 | } else if (kvb->used == kvb->size) { | |
12695 | kvb->size += 4; | |
12696 | - | |
12697 | + | |
12698 | kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv)); | |
12699 | - | |
12700 | + | |
12701 | for(i = kvb->used; i < kvb->size; i++) { | |
12702 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12703 | } | |
12704 | } | |
12705 | - | |
12706 | + | |
12707 | kvb->kv[kvb->used]->key = strdup(key); | |
12708 | kvb->kv[kvb->used]->realm = strdup(realm); | |
12709 | kvb->kv[kvb->used]->type = type; | |
12710 | - | |
12711 | + | |
12712 | kvb->used++; | |
12713 | - | |
12714 | + | |
12715 | return 0; | |
12716 | } | |
12717 | ||
12718 | void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) { | |
12719 | size_t i; | |
12720 | - | |
12721 | + | |
12722 | for (i = 0; i < kvb->size; i++) { | |
12723 | if (kvb->kv[i]->key) free(kvb->kv[i]->key); | |
12724 | if (kvb->kv[i]->realm) free(kvb->kv[i]->realm); | |
12725 | free(kvb->kv[i]); | |
12726 | } | |
12727 | - | |
12728 | + | |
12729 | if (kvb->kv) free(kvb->kv); | |
12730 | - | |
12731 | + | |
12732 | free(kvb); | |
12733 | } | |
12734 | ||
12735 | @@ -306,9 +307,9 @@ | |
12736 | ||
12737 | pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) { | |
12738 | pcre_keyvalue_buffer *kvb; | |
12739 | - | |
12740 | + | |
12741 | kvb = calloc(1, sizeof(*kvb)); | |
12742 | - | |
12743 | + | |
12744 | return kvb; | |
12745 | } | |
12746 | ||
12747 | @@ -319,46 +320,46 @@ | |
12748 | int erroff; | |
12749 | pcre_keyvalue *kv; | |
12750 | #endif | |
12751 | - | |
12752 | + | |
12753 | if (!key) return -1; | |
12754 | ||
12755 | #ifdef HAVE_PCRE_H | |
12756 | if (kvb->size == 0) { | |
12757 | kvb->size = 4; | |
12758 | kvb->used = 0; | |
12759 | - | |
12760 | + | |
12761 | kvb->kv = malloc(kvb->size * sizeof(*kvb->kv)); | |
12762 | - | |
12763 | + | |
12764 | for(i = 0; i < kvb->size; i++) { | |
12765 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12766 | } | |
12767 | } else if (kvb->used == kvb->size) { | |
12768 | kvb->size += 4; | |
12769 | - | |
12770 | + | |
12771 | kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv)); | |
12772 | - | |
12773 | + | |
12774 | for(i = kvb->used; i < kvb->size; i++) { | |
12775 | kvb->kv[i] = calloc(1, sizeof(**kvb->kv)); | |
12776 | } | |
12777 | } | |
12778 | - | |
12779 | + | |
12780 | kv = kvb->kv[kvb->used]; | |
12781 | if (NULL == (kv->key = pcre_compile(key, | |
12782 | 0, &errptr, &erroff, NULL))) { | |
12783 | - | |
12784 | + | |
12785 | fprintf(stderr, "%s.%d: rexexp compilation error at %s\n", __FILE__, __LINE__, errptr); | |
12786 | return -1; | |
12787 | } | |
12788 | ||
12789 | - if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) && | |
12790 | + if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) && | |
12791 | errptr != NULL) { | |
12792 | return -1; | |
12793 | } | |
12794 | - | |
12795 | + | |
12796 | kv->value = buffer_init_string(value); | |
12797 | - | |
12798 | + | |
12799 | kvb->used++; | |
12800 | - | |
12801 | + | |
12802 | return 0; | |
12803 | #else | |
12804 | UNUSED(kvb); | |
12805 | @@ -380,9 +381,9 @@ | |
12806 | if (kv->value) buffer_free(kv->value); | |
12807 | free(kv); | |
12808 | } | |
12809 | - | |
12810 | + | |
12811 | if (kvb->kv) free(kvb->kv); | |
12812 | #endif | |
12813 | - | |
12814 | + | |
12815 | free(kvb); | |
12816 | } | |
1175ccec | 12817 | --- ../lighttpd-1.4.11/src/keyvalue.h 2006-03-02 16:08:06.000000000 +0200 |
36e2a29e | 12818 | +++ lighttpd-1.4.12/src/keyvalue.h 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
12819 | @@ -9,19 +9,19 @@ |
12820 | # include <pcre.h> | |
12821 | #endif | |
12822 | ||
12823 | -typedef enum { | |
12824 | - HTTP_METHOD_UNSET = -1, | |
12825 | - HTTP_METHOD_GET, | |
12826 | - HTTP_METHOD_POST, | |
12827 | - HTTP_METHOD_HEAD, | |
12828 | - HTTP_METHOD_OPTIONS, | |
12829 | +typedef enum { | |
12830 | + HTTP_METHOD_UNSET = -1, | |
12831 | + HTTP_METHOD_GET, | |
12832 | + HTTP_METHOD_POST, | |
12833 | + HTTP_METHOD_HEAD, | |
12834 | + HTTP_METHOD_OPTIONS, | |
12835 | HTTP_METHOD_PROPFIND, /* WebDAV */ | |
12836 | - HTTP_METHOD_MKCOL, | |
12837 | - HTTP_METHOD_PUT, | |
12838 | - HTTP_METHOD_DELETE, | |
12839 | - HTTP_METHOD_COPY, | |
12840 | - HTTP_METHOD_MOVE, | |
12841 | - HTTP_METHOD_PROPPATCH, | |
12842 | + HTTP_METHOD_MKCOL, | |
12843 | + HTTP_METHOD_PUT, | |
12844 | + HTTP_METHOD_DELETE, | |
12845 | + HTTP_METHOD_COPY, | |
12846 | + HTTP_METHOD_MOVE, | |
12847 | + HTTP_METHOD_PROPPATCH, | |
12848 | HTTP_METHOD_REPORT, /* DeltaV */ | |
12849 | HTTP_METHOD_CHECKOUT, | |
12850 | HTTP_METHOD_CHECKIN, | |
12851 | @@ -39,13 +39,13 @@ | |
12852 | ||
12853 | typedef struct { | |
12854 | int key; | |
12855 | - | |
12856 | + | |
12857 | char *value; | |
12858 | } keyvalue; | |
12859 | ||
12860 | typedef struct { | |
12861 | char *key; | |
12862 | - | |
12863 | + | |
12864 | char *value; | |
12865 | } s_keyvalue; | |
12866 | ||
12867 | @@ -54,7 +54,7 @@ | |
12868 | pcre *key; | |
12869 | pcre_extra *key_extra; | |
12870 | #endif | |
12871 | - | |
12872 | + | |
12873 | buffer *value; | |
12874 | } pcre_keyvalue; | |
12875 | ||
12876 | @@ -62,7 +62,7 @@ | |
12877 | ||
12878 | typedef struct { | |
12879 | char *key; | |
12880 | - | |
12881 | + | |
12882 | char *realm; | |
12883 | httpauth_type type; | |
12884 | } httpauth_keyvalue; | |
1175ccec | 12885 | --- ../lighttpd-1.4.11/src/lemon.c 2005-09-01 00:21:34.000000000 +0300 |
36e2a29e | 12886 | +++ lighttpd-1.4.12/src/lemon.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
12887 | @@ -579,7 +579,7 @@ |
12888 | */ | |
12889 | ||
12890 | /* Find a precedence symbol of every rule in the grammar. | |
12891 | -** | |
12892 | +** | |
12893 | ** Those rules which have a precedence symbol coded in the input | |
12894 | ** grammar using the "[symbol]" construct will already have the | |
12895 | ** rp->precsym field filled. Other rules take as their precedence | |
12896 | @@ -869,7 +869,7 @@ | |
12897 | cfp->status = INCOMPLETE; | |
12898 | } | |
12899 | } | |
12900 | - | |
12901 | + | |
12902 | do{ | |
12903 | progress = 0; | |
12904 | for(i=0; i<lemp->nstate; i++){ | |
12905 | @@ -900,7 +900,7 @@ | |
12906 | struct symbol *sp; | |
12907 | struct rule *rp; | |
12908 | ||
12909 | - /* Add all of the reduce actions | |
12910 | + /* Add all of the reduce actions | |
12911 | ** A reduce action is added for each element of the followset of | |
12912 | ** a configuration which has its dot at the extreme right. | |
12913 | */ | |
12914 | @@ -1017,7 +1017,7 @@ | |
12915 | apx->type = RD_RESOLVED; | |
12916 | } | |
12917 | }else{ | |
12918 | - assert( | |
12919 | + assert( | |
12920 | apx->type==SH_RESOLVED || | |
12921 | apx->type==RD_RESOLVED || | |
12922 | apx->type==CONFLICT || | |
12923 | @@ -1350,7 +1350,7 @@ | |
12924 | OptInit(argv,options,stderr); | |
12925 | if( version ){ | |
12926 | printf("Lemon version 1.0\n"); | |
12927 | - exit(0); | |
12928 | + exit(0); | |
12929 | } | |
12930 | if( OptNArgs() < 1 ){ | |
12931 | fprintf(stderr,"Exactly one filename argument is required.\n"); | |
12932 | @@ -2031,7 +2031,7 @@ | |
12933 | case IN_RHS: | |
12934 | if( x[0]=='.' ){ | |
12935 | struct rule *rp; | |
12936 | - rp = (struct rule *)malloc( sizeof(struct rule) + | |
12937 | + rp = (struct rule *)malloc( sizeof(struct rule) + | |
12938 | sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs ); | |
12939 | if( rp==0 ){ | |
12940 | ErrorMsg(psp->filename,psp->tokenlineno, | |
12941 | @@ -2546,7 +2546,7 @@ | |
12942 | return fp; | |
12943 | } | |
12944 | ||
12945 | -/* Duplicate the input file without comments and without actions | |
12946 | +/* Duplicate the input file without comments and without actions | |
12947 | ** on rules */ | |
12948 | void Reprint(lemp) | |
12949 | struct lemon *lemp; | |
12950 | @@ -2822,7 +2822,7 @@ | |
12951 | PRIVATE FILE *tplt_open(lemp) | |
12952 | struct lemon *lemp; | |
12953 | { | |
12954 | - | |
12955 | + | |
12956 | char buf[1000]; | |
12957 | FILE *in; | |
12958 | char *tpltname; | |
12959 | @@ -2930,7 +2930,7 @@ | |
12960 | return ret; | |
12961 | } | |
12962 | ||
12963 | -/* | |
12964 | +/* | |
12965 | ** Generate code which executes when the rule "rp" is reduced. Write | |
12966 | ** the code to "out". Make sure lineno stays up-to-date. | |
12967 | */ | |
12968 | @@ -3384,7 +3384,7 @@ | |
12969 | ||
12970 | /* Output the yy_shift_ofst[] table */ | |
12971 | fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; | |
12972 | - fprintf(out, "static %s yy_shift_ofst[] = {\n", | |
12973 | + fprintf(out, "static %s yy_shift_ofst[] = {\n", | |
12974 | minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; | |
12975 | n = lemp->nstate; | |
12976 | for(i=j=0; i<n; i++){ | |
12977 | @@ -3405,7 +3405,7 @@ | |
12978 | ||
12979 | /* Output the yy_reduce_ofst[] table */ | |
12980 | fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; | |
12981 | - fprintf(out, "static %s yy_reduce_ofst[] = {\n", | |
12982 | + fprintf(out, "static %s yy_reduce_ofst[] = {\n", | |
12983 | minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; | |
12984 | n = lemp->nstate; | |
12985 | for(i=j=0; i<n; i++){ | |
12986 | @@ -3480,7 +3480,7 @@ | |
12987 | tplt_xfer(lemp->name,in,out,&lineno); | |
12988 | ||
12989 | /* Generate code which executes every time a symbol is popped from | |
12990 | - ** the stack while processing errors or while destroying the parser. | |
12991 | + ** the stack while processing errors or while destroying the parser. | |
12992 | ** (In other words, generate the %destructor actions) | |
12993 | */ | |
12994 | if( lemp->tokendest ){ | |
12995 | @@ -3522,7 +3522,7 @@ | |
12996 | tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno); | |
12997 | tplt_xfer(lemp->name,in,out,&lineno); | |
12998 | ||
12999 | - /* Generate the table of rule information | |
13000 | + /* Generate the table of rule information | |
13001 | ** | |
13002 | ** Note: This code depends on the fact that rules are number | |
13003 | ** sequentually beginning with 0. | |
13004 | @@ -3589,7 +3589,7 @@ | |
13005 | for(i=1; i<lemp->nterminal; i++){ | |
13006 | fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); | |
13007 | } | |
13008 | - fclose(out); | |
13009 | + fclose(out); | |
13010 | } | |
13011 | return; | |
13012 | } | |
13013 | @@ -3630,7 +3630,7 @@ | |
13014 | rbest = rp; | |
13015 | } | |
13016 | } | |
13017 | - | |
13018 | + | |
13019 | /* Do not make a default if the number of rules to default | |
13020 | ** is not at least 2 */ | |
13021 | if( nbest<2 ) continue; | |
13022 | @@ -3781,7 +3781,7 @@ | |
13023 | if( x1a ){ | |
13024 | x1a->size = 1024; | |
13025 | x1a->count = 0; | |
13026 | - x1a->tbl = (x1node*)malloc( | |
13027 | + x1a->tbl = (x1node*)malloc( | |
13028 | (sizeof(x1node) + sizeof(x1node*))*1024 ); | |
13029 | if( x1a->tbl==0 ){ | |
13030 | free(x1a); | |
13031 | @@ -3943,7 +3943,7 @@ | |
13032 | if( x2a ){ | |
13033 | x2a->size = 128; | |
13034 | x2a->count = 0; | |
13035 | - x2a->tbl = (x2node*)malloc( | |
13036 | + x2a->tbl = (x2node*)malloc( | |
13037 | (sizeof(x2node) + sizeof(x2node*))*128 ); | |
13038 | if( x2a->tbl==0 ){ | |
13039 | free(x2a); | |
13040 | @@ -4149,7 +4149,7 @@ | |
13041 | if( x3a ){ | |
13042 | x3a->size = 128; | |
13043 | x3a->count = 0; | |
13044 | - x3a->tbl = (x3node*)malloc( | |
13045 | + x3a->tbl = (x3node*)malloc( | |
13046 | (sizeof(x3node) + sizeof(x3node*))*128 ); | |
13047 | if( x3a->tbl==0 ){ | |
13048 | free(x3a); | |
13049 | @@ -4295,7 +4295,7 @@ | |
13050 | if( x4a ){ | |
13051 | x4a->size = 64; | |
13052 | x4a->count = 0; | |
13053 | - x4a->tbl = (x4node*)malloc( | |
13054 | + x4a->tbl = (x4node*)malloc( | |
13055 | (sizeof(x4node) + sizeof(x4node*))*64 ); | |
13056 | if( x4a->tbl==0 ){ | |
13057 | free(x4a); | |
1175ccec | 13058 | --- ../lighttpd-1.4.11/src/lempar.c 2005-08-11 01:26:40.000000000 +0300 |
36e2a29e | 13059 | +++ lighttpd-1.4.12/src/lempar.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
13060 | @@ -8,10 +8,10 @@ |
13061 | /* Next is all token values, in a form suitable for use by makeheaders. | |
13062 | ** This section will be null unless lemon is run with the -m switch. | |
13063 | */ | |
13064 | -/* | |
13065 | +/* | |
13066 | ** These constants (all generated automatically by the parser generator) | |
13067 | ** specify the various kinds of tokens (terminals) that the parser | |
13068 | -** understands. | |
13069 | +** understands. | |
13070 | ** | |
13071 | ** Each symbol here is a terminal symbol in the grammar. | |
13072 | */ | |
13073 | @@ -29,7 +29,7 @@ | |
13074 | ** and nonterminals. "int" is used otherwise. | |
13075 | ** YYNOCODE is a number of type YYCODETYPE which corresponds | |
13076 | ** to no legal terminal or nonterminal number. This | |
13077 | -** number is used to fill in empty slots of the hash | |
13078 | +** number is used to fill in empty slots of the hash | |
13079 | ** table. | |
13080 | ** YYFALLBACK If defined, this indicates that one or more tokens | |
13081 | ** have fall-back values which should be used if the | |
13082 | @@ -38,7 +38,7 @@ | |
13083 | ** and nonterminal numbers. "unsigned char" is | |
13084 | ** used if there are fewer than 250 rules and | |
13085 | ** states combined. "int" is used otherwise. | |
13086 | -** ParseTOKENTYPE is the data type used for minor tokens given | |
13087 | +** ParseTOKENTYPE is the data type used for minor tokens given | |
13088 | ** directly to the parser from the tokenizer. | |
13089 | ** YYMINORTYPE is the data type used for all minor tokens. | |
13090 | ** This is typically a union of many types, one of | |
13091 | @@ -62,7 +62,7 @@ | |
13092 | /* Next are that tables used to determine what action to take based on the | |
13093 | ** current state and lookahead token. These tables are used to implement | |
13094 | ** functions that take a state number and lookahead value and return an | |
13095 | -** action integer. | |
13096 | +** action integer. | |
13097 | ** | |
13098 | ** Suppose the action integer is N. Then the action is determined as | |
13099 | ** follows | |
13100 | @@ -87,7 +87,7 @@ | |
13101 | ** If the index value yy_shift_ofst[S]+X is out of range or if the value | |
13102 | ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] | |
13103 | ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table | |
13104 | -** and that yy_default[S] should be used instead. | |
13105 | +** and that yy_default[S] should be used instead. | |
13106 | ** | |
13107 | ** The formula above is for computing the action when the lookahead is | |
13108 | ** a terminal symbol. If the lookahead is a non-terminal (as occurs after | |
13109 | @@ -111,7 +111,7 @@ | |
13110 | ||
13111 | /* The next table maps tokens into fallback tokens. If a construct | |
13112 | ** like the following: | |
13113 | -** | |
13114 | +** | |
13115 | ** %fallback ID X Y Z. | |
13116 | ** | |
13117 | ** appears in the grammer, then ID becomes a fallback token for X, Y, | |
13118 | @@ -163,10 +163,10 @@ | |
13119 | #endif /* NDEBUG */ | |
13120 | ||
13121 | #ifndef NDEBUG | |
13122 | -/* | |
13123 | +/* | |
13124 | ** Turn parser tracing on by giving a stream to which to write the trace | |
13125 | ** and a prompt to preface each trace message. Tracing is turned off | |
13126 | -** by making either argument NULL | |
13127 | +** by making either argument NULL | |
13128 | ** | |
13129 | ** Inputs: | |
13130 | ** <ul> | |
13131 | @@ -191,7 +191,7 @@ | |
13132 | #ifndef NDEBUG | |
13133 | /* For tracing shifts, the names of all terminals and nonterminals | |
13134 | ** are required. The following table supplies these names */ | |
13135 | -static const char *yyTokenName[] = { | |
13136 | +static const char *yyTokenName[] = { | |
13137 | %% | |
13138 | }; | |
13139 | #endif /* NDEBUG */ | |
13140 | @@ -220,7 +220,7 @@ | |
13141 | #endif | |
13142 | } | |
13143 | ||
13144 | -/* | |
13145 | +/* | |
13146 | ** This function allocates a new parser. | |
13147 | ** The only argument is a pointer to a function which works like | |
13148 | ** malloc. | |
13149 | @@ -251,7 +251,7 @@ | |
13150 | /* Here is inserted the actions which take place when a | |
13151 | ** terminal or non-terminal is destroyed. This can happen | |
13152 | ** when the symbol is popped from the stack during a | |
13153 | - ** reduce or during error processing or when a parser is | |
13154 | + ** reduce or during error processing or when a parser is | |
13155 | ** being destroyed before it is finished parsing. | |
13156 | ** | |
13157 | ** Note: during a reduce, the only symbols destroyed are those | |
13158 | @@ -289,7 +289,7 @@ | |
13159 | return yymajor; | |
13160 | } | |
13161 | ||
13162 | -/* | |
13163 | +/* | |
13164 | ** Deallocate and destroy a parser. Destructors are all called for | |
13165 | ** all stack elements before shutting the parser down. | |
13166 | ** | |
13167 | @@ -325,7 +325,7 @@ | |
13168 | ){ | |
13169 | int i; | |
13170 | int stateno = pParser->yystack[pParser->yyidx].stateno; | |
13171 | - | |
13172 | + | |
13173 | /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */ | |
13174 | i = yy_shift_ofst[stateno]; | |
13175 | if( i==YY_SHIFT_USE_DFLT ){ | |
13176 | @@ -369,7 +369,7 @@ | |
13177 | ){ | |
13178 | int i; | |
13179 | int stateno = pParser->yystack[pParser->yyidx].stateno; | |
13180 | - | |
13181 | + | |
13182 | i = yy_reduce_ofst[stateno]; | |
13183 | if( i==YY_REDUCE_USE_DFLT ){ | |
13184 | return yy_default[stateno]; | |
13185 | @@ -455,7 +455,7 @@ | |
13186 | ParseARG_FETCH; | |
13187 | yymsp = &yypParser->yystack[yypParser->yyidx]; | |
13188 | #ifndef NDEBUG | |
13189 | - if( yyTraceFILE && yyruleno>=0 | |
13190 | + if( yyTraceFILE && yyruleno>=0 | |
13191 | && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){ | |
13192 | fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, | |
13193 | yyRuleName[yyruleno]); | |
13194 | @@ -608,7 +608,7 @@ | |
13195 | #ifdef YYERRORSYMBOL | |
13196 | /* A syntax error has occurred. | |
13197 | ** The response to an error depends upon whether or not the | |
13198 | - ** grammar defines an error token "ERROR". | |
13199 | + ** grammar defines an error token "ERROR". | |
13200 | ** | |
13201 | ** This is what we do if the grammar does define ERROR: | |
13202 | ** | |
1175ccec ER |
13203 | --- ../lighttpd-1.4.11/src/log.c 2005-11-07 15:01:35.000000000 +0200 |
13204 | +++ lighttpd-1.4.12/src/log.c 2006-07-15 22:43:21.000000000 +0300 | |
13205 | @@ -5,7 +5,6 @@ | |
2519e6e5 ER |
13206 | #include <errno.h> |
13207 | #include <fcntl.h> | |
13208 | #include <time.h> | |
13209 | -#include <unistd.h> | |
13210 | #include <string.h> | |
13211 | #include <stdlib.h> | |
13212 | ||
1175ccec | 13213 | @@ -16,6 +15,10 @@ |
2519e6e5 ER |
13214 | #include "config.h" |
13215 | #endif | |
13216 | ||
13217 | +#ifdef _WIN32 | |
13218 | +#undef HAVE_SYSLOG_H | |
13219 | +#endif | |
13220 | + | |
13221 | #ifdef HAVE_SYSLOG_H | |
13222 | #include <syslog.h> | |
13223 | #endif | |
1175ccec | 13224 | @@ -23,6 +26,8 @@ |
2519e6e5 ER |
13225 | #include "log.h" |
13226 | #include "array.h" | |
13227 | ||
13228 | +#include "sys-files.h" | |
13229 | + | |
13230 | #ifdef HAVE_VALGRIND_VALGRIND_H | |
13231 | #include <valgrind/valgrind.h> | |
13232 | #endif | |
1175ccec | 13233 | @@ -31,38 +36,38 @@ |
2519e6e5 ER |
13234 | # define O_LARGEFILE 0 |
13235 | #endif | |
13236 | ||
13237 | -/** | |
13238 | +/** | |
13239 | * open the errorlog | |
13240 | - * | |
13241 | + * | |
13242 | * we have 3 possibilities: | |
13243 | * - stderr (default) | |
13244 | - * - syslog | |
13245 | + * - syslog | |
13246 | * - logfile | |
13247 | - * | |
13248 | + * | |
13249 | * if the open failed, report to the user and die | |
13250 | - * | |
13251 | + * | |
13252 | */ | |
13253 | ||
13254 | int log_error_open(server *srv) { | |
13255 | int fd; | |
13256 | int close_stderr = 1; | |
13257 | - | |
13258 | + | |
13259 | #ifdef HAVE_SYSLOG_H | |
13260 | /* perhaps someone wants to use syslog() */ | |
13261 | openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON); | |
13262 | #endif | |
13263 | srv->errorlog_mode = ERRORLOG_STDERR; | |
13264 | - | |
13265 | + | |
13266 | if (srv->srvconf.errorlog_use_syslog) { | |
13267 | srv->errorlog_mode = ERRORLOG_SYSLOG; | |
13268 | } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) { | |
13269 | const char *logfile = srv->srvconf.errorlog_file->ptr; | |
13270 | - | |
13271 | + | |
13272 | if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { | |
13273 | - log_error_write(srv, __FILE__, __LINE__, "SSSS", | |
13274 | + log_error_write(srv, __FILE__, __LINE__, "SSSS", | |
13275 | "opening errorlog '", logfile, | |
13276 | "' failed: ", strerror(errno)); | |
13277 | - | |
13278 | + | |
13279 | return -1; | |
13280 | } | |
13281 | #ifdef FD_CLOEXEC | |
1175ccec | 13282 | @@ -71,15 +76,15 @@ |
2519e6e5 ER |
13283 | #endif |
13284 | srv->errorlog_mode = ERRORLOG_FILE; | |
13285 | } | |
13286 | - | |
13287 | + | |
13288 | log_error_write(srv, __FILE__, __LINE__, "s", "server started"); | |
13289 | - | |
13290 | + | |
13291 | #ifdef HAVE_VALGRIND_VALGRIND_H | |
13292 | /* don't close stderr for debugging purposes if run in valgrind */ | |
13293 | if (RUNNING_ON_VALGRIND) close_stderr = 0; | |
13294 | #endif | |
13295 | if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0; | |
13296 | - | |
13297 | + | |
13298 | /* move stderr to /dev/null */ | |
13299 | if (close_stderr && | |
13300 | -1 != (fd = open("/dev/null", O_WRONLY))) { | |
1175ccec | 13301 | @@ -90,33 +95,33 @@ |
2519e6e5 ER |
13302 | return 0; |
13303 | } | |
13304 | ||
13305 | -/** | |
13306 | +/** | |
13307 | * open the errorlog | |
13308 | - * | |
13309 | + * | |
13310 | * if the open failed, report to the user and die | |
13311 | * if no filename is given, use syslog instead | |
13312 | - * | |
13313 | + * | |
13314 | */ | |
13315 | ||
13316 | int log_error_cycle(server *srv) { | |
13317 | /* only cycle if we are not in syslog-mode */ | |
13318 | - | |
13319 | + | |
13320 | if (srv->errorlog_mode == ERRORLOG_FILE) { | |
13321 | const char *logfile = srv->srvconf.errorlog_file->ptr; | |
13322 | /* already check of opening time */ | |
13323 | - | |
13324 | + | |
13325 | int new_fd; | |
13326 | - | |
13327 | + | |
13328 | if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { | |
13329 | /* write to old log */ | |
13330 | - log_error_write(srv, __FILE__, __LINE__, "SSSSS", | |
13331 | + log_error_write(srv, __FILE__, __LINE__, "SSSSS", | |
13332 | "cycling errorlog '", logfile, | |
13333 | "' failed: ", strerror(errno), | |
13334 | ", falling back to syslog()"); | |
13335 | - | |
13336 | + | |
13337 | close(srv->errorlog_fd); | |
13338 | srv->errorlog_fd = -1; | |
13339 | -#ifdef HAVE_SYSLOG_H | |
13340 | +#ifdef HAVE_SYSLOG_H | |
13341 | srv->errorlog_mode = ERRORLOG_SYSLOG; | |
13342 | #endif | |
13343 | } else { | |
1175ccec | 13344 | @@ -125,15 +130,15 @@ |
2519e6e5 ER |
13345 | srv->errorlog_fd = new_fd; |
13346 | } | |
13347 | } | |
13348 | - | |
13349 | + | |
13350 | log_error_write(srv, __FILE__, __LINE__, "s", "logfiles cycled"); | |
13351 | - | |
13352 | + | |
13353 | return 0; | |
13354 | } | |
13355 | ||
13356 | int log_error_close(server *srv) { | |
13357 | log_error_write(srv, __FILE__, __LINE__, "s", "server stopped"); | |
13358 | - | |
13359 | + | |
13360 | switch(srv->errorlog_mode) { | |
13361 | case ERRORLOG_FILE: | |
13362 | close(srv->errorlog_fd); | |
1175ccec | 13363 | @@ -146,13 +151,13 @@ |
2519e6e5 ER |
13364 | case ERRORLOG_STDERR: |
13365 | break; | |
13366 | } | |
13367 | - | |
13368 | + | |
13369 | return 0; | |
13370 | } | |
13371 | ||
13372 | int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) { | |
13373 | va_list ap; | |
13374 | - | |
13375 | + | |
13376 | switch(srv->errorlog_mode) { | |
13377 | case ERRORLOG_FILE: | |
13378 | case ERRORLOG_STDERR: | |
1175ccec | 13379 | @@ -161,7 +166,7 @@ |
2519e6e5 ER |
13380 | buffer_prepare_copy(srv->ts_debug_str, 255); |
13381 | strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts))); | |
13382 | srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1; | |
13383 | - | |
13384 | + | |
13385 | srv->last_generated_debug_ts = srv->cur_ts; | |
13386 | } | |
13387 | ||
1175ccec | 13388 | @@ -173,19 +178,19 @@ |
2519e6e5 ER |
13389 | BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "("); |
13390 | break; | |
13391 | } | |
13392 | - | |
13393 | + | |
13394 | buffer_append_string(srv->errorlog_buf, filename); | |
13395 | BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "."); | |
13396 | buffer_append_long(srv->errorlog_buf, line); | |
13397 | BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") "); | |
13398 | - | |
13399 | - | |
13400 | + | |
13401 | + | |
13402 | for(va_start(ap, fmt); *fmt; fmt++) { | |
13403 | int d; | |
13404 | char *s; | |
13405 | buffer *b; | |
13406 | off_t o; | |
13407 | - | |
13408 | + | |
13409 | switch(*fmt) { | |
13410 | case 's': /* string */ | |
13411 | s = va_arg(ap, char *); | |
1175ccec | 13412 | @@ -227,7 +232,7 @@ |
2519e6e5 ER |
13413 | break; |
13414 | case '(': | |
13415 | case ')': | |
13416 | - case '<': | |
13417 | + case '<': | |
13418 | case '>': | |
13419 | case ',': | |
13420 | case ' ': | |
1175ccec | 13421 | @@ -236,7 +241,7 @@ |
2519e6e5 ER |
13422 | } |
13423 | } | |
13424 | va_end(ap); | |
13425 | - | |
13426 | + | |
13427 | switch(srv->errorlog_mode) { | |
13428 | case ERRORLOG_FILE: | |
13429 | BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n"); | |
1175ccec | 13430 | @@ -246,11 +251,13 @@ |
2519e6e5 ER |
13431 | BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n"); |
13432 | write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1); | |
13433 | break; | |
13434 | +#ifdef HAVE_SYSLOG_H | |
13435 | case ERRORLOG_SYSLOG: | |
13436 | syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr); | |
13437 | break; | |
13438 | +#endif | |
13439 | } | |
13440 | - | |
13441 | + | |
13442 | return 0; | |
13443 | } | |
13444 | ||
1175ccec | 13445 | --- ../lighttpd-1.4.11/src/log.h 2005-08-11 01:26:36.000000000 +0300 |
36e2a29e | 13446 | +++ lighttpd-1.4.12/src/log.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
13447 | @@ -9,5 +9,5 @@ |
13448 | int log_error_close(server *srv); | |
13449 | int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...); | |
13450 | int log_error_cycle(server *srv); | |
13451 | - | |
13452 | + | |
13453 | #endif | |
1175ccec | 13454 | --- ../lighttpd-1.4.11/src/md5.h 2005-11-17 16:20:40.000000000 +0200 |
36e2a29e | 13455 | +++ lighttpd-1.4.12/src/md5.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
13456 | @@ -30,9 +30,15 @@ |
13457 | # include <inttypes.h> | |
13458 | #endif | |
13459 | ||
13460 | +#ifdef _WIN32 | |
13461 | +#define UINT4 unsigned __int32 | |
13462 | +#define UINT2 unsigned __int16 | |
13463 | +#define POINTER unsigned char * | |
13464 | +#else | |
13465 | #define UINT4 uint32_t | |
13466 | #define UINT2 uint16_t | |
13467 | #define POINTER unsigned char * | |
13468 | +#endif | |
13469 | ||
13470 | /* MD5 context. */ | |
13471 | typedef struct { | |
1175ccec | 13472 | --- ../lighttpd-1.4.11/src/mod_access.c 2006-01-14 19:44:54.000000000 +0200 |
36e2a29e | 13473 | +++ lighttpd-1.4.12/src/mod_access.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
13474 | @@ -8,126 +8,125 @@ |
13475 | ||
13476 | #include "plugin.h" | |
13477 | ||
13478 | +#include "sys-strings.h" | |
13479 | + | |
13480 | typedef struct { | |
13481 | array *access_deny; | |
13482 | } plugin_config; | |
13483 | ||
13484 | typedef struct { | |
13485 | PLUGIN_DATA; | |
13486 | - | |
13487 | + | |
13488 | plugin_config **config_storage; | |
13489 | - | |
13490 | - plugin_config conf; | |
13491 | + | |
13492 | + plugin_config conf; | |
13493 | } plugin_data; | |
13494 | ||
13495 | INIT_FUNC(mod_access_init) { | |
13496 | plugin_data *p; | |
13497 | - | |
13498 | + | |
13499 | p = calloc(1, sizeof(*p)); | |
13500 | - | |
13501 | + | |
13502 | return p; | |
13503 | } | |
13504 | ||
13505 | FREE_FUNC(mod_access_free) { | |
13506 | plugin_data *p = p_d; | |
13507 | - | |
13508 | + | |
13509 | UNUSED(srv); | |
13510 | ||
13511 | if (!p) return HANDLER_GO_ON; | |
13512 | - | |
13513 | + | |
13514 | if (p->config_storage) { | |
13515 | size_t i; | |
13516 | for (i = 0; i < srv->config_context->used; i++) { | |
13517 | plugin_config *s = p->config_storage[i]; | |
13518 | - | |
13519 | + | |
13520 | array_free(s->access_deny); | |
13521 | - | |
13522 | + | |
13523 | free(s); | |
13524 | } | |
13525 | free(p->config_storage); | |
13526 | } | |
13527 | - | |
13528 | + | |
13529 | free(p); | |
13530 | - | |
13531 | + | |
13532 | return HANDLER_GO_ON; | |
13533 | } | |
13534 | ||
13535 | SETDEFAULTS_FUNC(mod_access_set_defaults) { | |
13536 | plugin_data *p = p_d; | |
13537 | size_t i = 0; | |
13538 | - | |
13539 | - config_values_t cv[] = { | |
13540 | + | |
13541 | + config_values_t cv[] = { | |
13542 | { "url.access-deny", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, | |
13543 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
13544 | }; | |
13545 | - | |
13546 | + | |
13547 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
13548 | - | |
13549 | + | |
13550 | for (i = 0; i < srv->config_context->used; i++) { | |
13551 | plugin_config *s; | |
13552 | - | |
13553 | + | |
13554 | s = calloc(1, sizeof(plugin_config)); | |
13555 | s->access_deny = array_init(); | |
13556 | - | |
13557 | + | |
13558 | cv[0].destination = s->access_deny; | |
13559 | - | |
13560 | + | |
13561 | p->config_storage[i] = s; | |
13562 | - | |
13563 | + | |
13564 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
13565 | return HANDLER_ERROR; | |
13566 | } | |
13567 | } | |
13568 | - | |
13569 | + | |
13570 | return HANDLER_GO_ON; | |
13571 | } | |
13572 | ||
13573 | -#define PATCH(x) \ | |
13574 | - p->conf.x = s->x; | |
13575 | static int mod_access_patch_connection(server *srv, connection *con, plugin_data *p) { | |
13576 | size_t i, j; | |
13577 | plugin_config *s = p->config_storage[0]; | |
13578 | ||
13579 | - PATCH(access_deny); | |
13580 | - | |
13581 | + PATCH_OPTION(access_deny); | |
13582 | + | |
13583 | /* skip the first, the global context */ | |
13584 | for (i = 1; i < srv->config_context->used; i++) { | |
13585 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
13586 | s = p->config_storage[i]; | |
13587 | - | |
13588 | + | |
13589 | /* condition didn't match */ | |
13590 | if (!config_check_cond(srv, con, dc)) continue; | |
13591 | - | |
13592 | + | |
13593 | /* merge config */ | |
13594 | for (j = 0; j < dc->value->used; j++) { | |
13595 | data_unset *du = dc->value->data[j]; | |
13596 | - | |
13597 | + | |
13598 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-deny"))) { | |
13599 | - PATCH(access_deny); | |
13600 | + PATCH_OPTION(access_deny); | |
13601 | } | |
13602 | } | |
13603 | } | |
13604 | - | |
13605 | + | |
13606 | return 0; | |
13607 | } | |
13608 | -#undef PATCH | |
13609 | ||
13610 | URIHANDLER_FUNC(mod_access_uri_handler) { | |
13611 | plugin_data *p = p_d; | |
13612 | int s_len; | |
13613 | size_t k; | |
13614 | - | |
13615 | + | |
13616 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
13617 | - | |
13618 | + | |
13619 | mod_access_patch_connection(srv, con, p); | |
13620 | - | |
13621 | + | |
13622 | s_len = con->uri.path->used - 1; | |
13623 | - | |
13624 | + | |
13625 | for (k = 0; k < p->conf.access_deny->used; k++) { | |
13626 | data_string *ds = (data_string *)p->conf.access_deny->data[k]; | |
13627 | int ct_len = ds->value->used - 1; | |
13628 | - | |
13629 | + | |
13630 | if (ct_len > s_len) continue; | |
13631 | - | |
13632 | + | |
13633 | if (ds->value->used == 0) continue; | |
13634 | ||
13635 | /* if we have a case-insensitive FS we have to lower-case the URI here too */ | |
13636 | @@ -135,18 +134,18 @@ | |
13637 | if (con->conf.force_lowercase_filenames) { | |
13638 | if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { | |
13639 | con->http_status = 403; | |
13640 | - | |
13641 | + | |
13642 | return HANDLER_FINISHED; | |
13643 | } | |
13644 | } else { | |
13645 | if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { | |
13646 | con->http_status = 403; | |
13647 | - | |
13648 | + | |
13649 | return HANDLER_FINISHED; | |
13650 | } | |
13651 | } | |
13652 | } | |
13653 | - | |
13654 | + | |
13655 | /* not found */ | |
13656 | return HANDLER_GO_ON; | |
13657 | } | |
13658 | @@ -155,13 +154,13 @@ | |
13659 | int mod_access_plugin_init(plugin *p) { | |
13660 | p->version = LIGHTTPD_VERSION_ID; | |
13661 | p->name = buffer_init_string("access"); | |
13662 | - | |
13663 | + | |
13664 | p->init = mod_access_init; | |
13665 | p->set_defaults = mod_access_set_defaults; | |
13666 | p->handle_uri_clean = mod_access_uri_handler; | |
13667 | p->cleanup = mod_access_free; | |
13668 | - | |
13669 | + | |
13670 | p->data = NULL; | |
13671 | - | |
13672 | + | |
13673 | return 0; | |
13674 | } | |
1175ccec | 13675 | --- ../lighttpd-1.4.11/src/mod_accesslog.c 2006-01-31 14:01:43.000000000 +0200 |
36e2a29e | 13676 | +++ lighttpd-1.4.12/src/mod_accesslog.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
13677 | @@ -6,8 +6,7 @@ |
13678 | #include <ctype.h> | |
13679 | #include <stdlib.h> | |
13680 | #include <string.h> | |
13681 | -#include <fcntl.h> | |
13682 | -#include <unistd.h> | |
13683 | +#include <fcntl.h> /* only the defines on windows */ | |
13684 | #include <errno.h> | |
13685 | #include <time.h> | |
13686 | ||
13687 | @@ -22,6 +21,7 @@ | |
13688 | #include "inet_ntop_cache.h" | |
13689 | ||
13690 | #include "sys-socket.h" | |
13691 | +#include "sys-files.h" | |
13692 | ||
13693 | #ifdef HAVE_SYSLOG_H | |
13694 | # include <syslog.h> | |
13695 | @@ -29,7 +29,7 @@ | |
13696 | ||
13697 | typedef struct { | |
13698 | char key; | |
13699 | - enum { | |
13700 | + enum { | |
13701 | FORMAT_UNSET, | |
13702 | FORMAT_UNSUPPORTED, | |
13703 | FORMAT_PERCENT, | |
13704 | @@ -41,7 +41,7 @@ | |
13705 | FORMAT_STATUS, | |
13706 | FORMAT_BYTES_OUT_NO_HEADER, | |
13707 | FORMAT_HEADER, | |
13708 | - | |
13709 | + | |
13710 | FORMAT_REMOTE_ADDR, | |
13711 | FORMAT_LOCAL_ADDR, | |
13712 | FORMAT_COOKIE, | |
13713 | @@ -59,20 +59,20 @@ | |
13714 | FORMAT_CONNECTION_STATUS, | |
13715 | FORMAT_BYTES_IN, | |
13716 | FORMAT_BYTES_OUT, | |
13717 | - | |
13718 | + | |
13719 | FORMAT_RESPONSE_HEADER | |
13720 | } type; | |
13721 | } format_mapping; | |
13722 | ||
13723 | /** | |
13724 | - * | |
13725 | - * | |
13726 | + * | |
13727 | + * | |
13728 | * "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" | |
13729 | - * | |
13730 | + * | |
13731 | */ | |
13732 | ||
13733 | -const format_mapping fmap[] = | |
13734 | -{ | |
13735 | +const format_mapping fmap[] = | |
13736 | +{ | |
13737 | { '%', FORMAT_PERCENT }, | |
13738 | { 'h', FORMAT_REMOTE_HOST }, | |
13739 | { 'l', FORMAT_REMOTE_IDENT }, | |
13740 | @@ -82,7 +82,7 @@ | |
13741 | { 's', FORMAT_STATUS }, | |
13742 | { 'b', FORMAT_BYTES_OUT_NO_HEADER }, | |
13743 | { 'i', FORMAT_HEADER }, | |
13744 | - | |
13745 | + | |
13746 | { 'a', FORMAT_REMOTE_ADDR }, | |
13747 | { 'A', FORMAT_LOCAL_ADDR }, | |
13748 | { 'B', FORMAT_BYTES_OUT_NO_HEADER }, | |
13749 | @@ -103,23 +103,23 @@ | |
13750 | { 'X', FORMAT_CONNECTION_STATUS }, | |
13751 | { 'I', FORMAT_BYTES_IN }, | |
13752 | { 'O', FORMAT_BYTES_OUT }, | |
13753 | - | |
13754 | + | |
13755 | { 'o', FORMAT_RESPONSE_HEADER }, | |
13756 | - | |
13757 | + | |
13758 | { '\0', FORMAT_UNSET } | |
13759 | }; | |
13760 | ||
13761 | ||
13762 | typedef struct { | |
13763 | enum { FIELD_UNSET, FIELD_STRING, FIELD_FORMAT } type; | |
13764 | - | |
13765 | + | |
13766 | buffer *string; | |
13767 | int field; | |
13768 | } format_field; | |
13769 | ||
13770 | typedef struct { | |
13771 | format_field **ptr; | |
13772 | - | |
13773 | + | |
13774 | size_t used; | |
13775 | size_t size; | |
13776 | } format_fields; | |
13777 | @@ -128,39 +128,39 @@ | |
13778 | buffer *access_logfile; | |
13779 | buffer *format; | |
13780 | unsigned short use_syslog; | |
13781 | - | |
13782 | - | |
13783 | + | |
13784 | + | |
13785 | int log_access_fd; | |
13786 | time_t last_generated_accesslog_ts; | |
13787 | time_t *last_generated_accesslog_ts_ptr; | |
13788 | - | |
13789 | - | |
13790 | + | |
13791 | + | |
13792 | buffer *access_logbuffer; | |
13793 | buffer *ts_accesslog_str; | |
13794 | - | |
13795 | + | |
13796 | format_fields *parsed_format; | |
13797 | } plugin_config; | |
13798 | ||
13799 | typedef struct { | |
13800 | PLUGIN_DATA; | |
13801 | - | |
13802 | + | |
13803 | plugin_config **config_storage; | |
13804 | - plugin_config conf; | |
13805 | + plugin_config conf; | |
13806 | } plugin_data; | |
13807 | ||
13808 | INIT_FUNC(mod_accesslog_init) { | |
13809 | plugin_data *p; | |
13810 | - | |
13811 | + | |
13812 | p = calloc(1, sizeof(*p)); | |
13813 | - | |
13814 | + | |
13815 | return p; | |
13816 | } | |
13817 | ||
13818 | int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) { | |
13819 | size_t i, j, k = 0, start = 0; | |
13820 | - | |
13821 | + | |
13822 | for (i = 0; i < format->used - 1; i++) { | |
13823 | - | |
13824 | + | |
13825 | switch(format->ptr[i]) { | |
13826 | case '%': | |
13827 | if (start != i) { | |
13828 | @@ -173,19 +173,19 @@ | |
13829 | fields->size += 16; | |
13830 | fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * )); | |
13831 | } | |
13832 | - | |
13833 | + | |
13834 | fields->ptr[fields->used] = malloc(sizeof(format_fields)); | |
13835 | fields->ptr[fields->used]->type = FIELD_STRING; | |
13836 | fields->ptr[fields->used]->string = buffer_init(); | |
13837 | - | |
13838 | + | |
13839 | buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start); | |
13840 | - | |
13841 | + | |
13842 | fields->used++; | |
13843 | } | |
13844 | - | |
13845 | - | |
13846 | + | |
13847 | + | |
13848 | /* we need a new field */ | |
13849 | - | |
13850 | + | |
13851 | if (fields->size == 0) { | |
13852 | fields->size = 16; | |
13853 | fields->used = 0; | |
13854 | @@ -194,43 +194,43 @@ | |
13855 | fields->size += 16; | |
13856 | fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * )); | |
13857 | } | |
13858 | - | |
13859 | + | |
13860 | /* search for the terminating command */ | |
13861 | switch (format->ptr[i+1]) { | |
13862 | case '>': | |
13863 | case '<': | |
13864 | /* only for s */ | |
13865 | - | |
13866 | + | |
13867 | for (j = 0; fmap[j].key != '\0'; j++) { | |
13868 | if (fmap[j].key != format->ptr[i+2]) continue; | |
13869 | - | |
13870 | + | |
13871 | /* found key */ | |
13872 | - | |
13873 | + | |
13874 | fields->ptr[fields->used] = malloc(sizeof(format_fields)); | |
13875 | fields->ptr[fields->used]->type = FIELD_FORMAT; | |
13876 | fields->ptr[fields->used]->field = fmap[j].type; | |
13877 | fields->ptr[fields->used]->string = NULL; | |
13878 | - | |
13879 | + | |
13880 | fields->used++; | |
13881 | - | |
13882 | + | |
13883 | break; | |
13884 | } | |
13885 | - | |
13886 | + | |
13887 | if (fmap[j].key == '\0') { | |
13888 | log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); | |
13889 | return -1; | |
13890 | } | |
13891 | - | |
13892 | + | |
13893 | start = i + 3; | |
13894 | - | |
13895 | + | |
13896 | break; | |
13897 | case '{': | |
13898 | /* go forward to } */ | |
13899 | - | |
13900 | + | |
13901 | for (k = i+2; k < format->used - 1; k++) { | |
13902 | if (format->ptr[k] == '}') break; | |
13903 | } | |
13904 | - | |
13905 | + | |
13906 | if (k == format->used - 1) { | |
13907 | log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); | |
13908 | return -1; | |
13909 | @@ -239,62 +239,62 @@ | |
13910 | log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); | |
13911 | return -1; | |
13912 | } | |
13913 | - | |
13914 | + | |
13915 | for (j = 0; fmap[j].key != '\0'; j++) { | |
13916 | if (fmap[j].key != format->ptr[k+1]) continue; | |
13917 | - | |
13918 | + | |
13919 | /* found key */ | |
13920 | - | |
13921 | + | |
13922 | fields->ptr[fields->used] = malloc(sizeof(format_fields)); | |
13923 | fields->ptr[fields->used]->type = FIELD_FORMAT; | |
13924 | fields->ptr[fields->used]->field = fmap[j].type; | |
13925 | fields->ptr[fields->used]->string = buffer_init(); | |
13926 | - | |
13927 | + | |
13928 | buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + i + 2, k - (i + 2)); | |
13929 | - | |
13930 | + | |
13931 | fields->used++; | |
13932 | - | |
13933 | + | |
13934 | break; | |
13935 | } | |
13936 | - | |
13937 | + | |
13938 | if (fmap[j].key == '\0') { | |
13939 | log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); | |
13940 | return -1; | |
13941 | } | |
13942 | - | |
13943 | + | |
13944 | start = k + 2; | |
13945 | - | |
13946 | + | |
13947 | break; | |
13948 | default: | |
13949 | for (j = 0; fmap[j].key != '\0'; j++) { | |
13950 | if (fmap[j].key != format->ptr[i+1]) continue; | |
13951 | - | |
13952 | + | |
13953 | /* found key */ | |
13954 | - | |
13955 | + | |
13956 | fields->ptr[fields->used] = malloc(sizeof(format_fields)); | |
13957 | fields->ptr[fields->used]->type = FIELD_FORMAT; | |
13958 | fields->ptr[fields->used]->field = fmap[j].type; | |
13959 | fields->ptr[fields->used]->string = NULL; | |
13960 | - | |
13961 | + | |
13962 | fields->used++; | |
13963 | - | |
13964 | + | |
13965 | break; | |
13966 | } | |
13967 | - | |
13968 | + | |
13969 | if (fmap[j].key == '\0') { | |
13970 | log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); | |
13971 | return -1; | |
13972 | } | |
13973 | - | |
13974 | + | |
13975 | start = i + 2; | |
13976 | - | |
13977 | + | |
13978 | break; | |
13979 | } | |
13980 | - | |
13981 | + | |
13982 | break; | |
13983 | } | |
13984 | } | |
13985 | - | |
13986 | + | |
13987 | if (start < i) { | |
13988 | /* copy the string */ | |
13989 | if (fields->size == 0) { | |
13990 | @@ -305,32 +305,32 @@ | |
13991 | fields->size += 16; | |
13992 | fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * )); | |
13993 | } | |
13994 | - | |
13995 | + | |
13996 | fields->ptr[fields->used] = malloc(sizeof(format_fields)); | |
13997 | fields->ptr[fields->used]->type = FIELD_STRING; | |
13998 | fields->ptr[fields->used]->string = buffer_init(); | |
13999 | - | |
14000 | + | |
14001 | buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start); | |
14002 | - | |
14003 | + | |
14004 | fields->used++; | |
14005 | } | |
14006 | - | |
14007 | + | |
14008 | return 0; | |
14009 | } | |
14010 | ||
14011 | FREE_FUNC(mod_accesslog_free) { | |
14012 | plugin_data *p = p_d; | |
14013 | size_t i; | |
14014 | - | |
14015 | + | |
14016 | if (!p) return HANDLER_GO_ON; | |
14017 | - | |
14018 | + | |
14019 | if (p->config_storage) { | |
14020 | - | |
14021 | + | |
14022 | for (i = 0; i < srv->config_context->used; i++) { | |
14023 | plugin_config *s = p->config_storage[i]; | |
14024 | ||
14025 | if (!s) continue; | |
14026 | - | |
14027 | + | |
14028 | if (s->access_logbuffer->used) { | |
14029 | if (s->use_syslog) { | |
14030 | # ifdef HAVE_SYSLOG_H | |
14031 | @@ -342,14 +342,14 @@ | |
14032 | write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1); | |
14033 | } | |
14034 | } | |
14035 | - | |
14036 | + | |
14037 | if (s->log_access_fd != -1) close(s->log_access_fd); | |
14038 | - | |
14039 | + | |
14040 | buffer_free(s->ts_accesslog_str); | |
14041 | buffer_free(s->access_logbuffer); | |
14042 | buffer_free(s->format); | |
14043 | buffer_free(s->access_logfile); | |
14044 | - | |
14045 | + | |
14046 | if (s->parsed_format) { | |
14047 | size_t j; | |
14048 | for (j = 0; j < s->parsed_format->used; j++) { | |
14049 | @@ -359,36 +359,36 @@ | |
14050 | free(s->parsed_format->ptr); | |
14051 | free(s->parsed_format); | |
14052 | } | |
14053 | - | |
14054 | + | |
14055 | free(s); | |
14056 | } | |
14057 | - | |
14058 | + | |
14059 | free(p->config_storage); | |
14060 | } | |
14061 | - | |
14062 | + | |
14063 | free(p); | |
14064 | - | |
14065 | + | |
14066 | return HANDLER_GO_ON; | |
14067 | } | |
14068 | ||
14069 | SETDEFAULTS_FUNC(log_access_open) { | |
14070 | plugin_data *p = p_d; | |
14071 | size_t i = 0; | |
14072 | - | |
14073 | - config_values_t cv[] = { | |
14074 | + | |
14075 | + config_values_t cv[] = { | |
14076 | { "accesslog.filename", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
14077 | { "accesslog.use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, | |
14078 | { "accesslog.format", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
14079 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
14080 | }; | |
14081 | - | |
14082 | + | |
14083 | if (!p) return HANDLER_ERROR; | |
14084 | - | |
14085 | + | |
14086 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
14087 | - | |
14088 | + | |
14089 | for (i = 0; i < srv->config_context->used; i++) { | |
14090 | plugin_config *s; | |
14091 | - | |
14092 | + | |
14093 | s = calloc(1, sizeof(plugin_config)); | |
14094 | s->access_logfile = buffer_init(); | |
14095 | s->format = buffer_init(); | |
14096 | @@ -397,44 +397,44 @@ | |
14097 | s->log_access_fd = -1; | |
14098 | s->last_generated_accesslog_ts = 0; | |
14099 | s->last_generated_accesslog_ts_ptr = &(s->last_generated_accesslog_ts); | |
14100 | - | |
14101 | - | |
14102 | + | |
14103 | + | |
14104 | cv[0].destination = s->access_logfile; | |
14105 | cv[1].destination = &(s->use_syslog); | |
14106 | cv[2].destination = s->format; | |
14107 | - | |
14108 | + | |
14109 | p->config_storage[i] = s; | |
14110 | - | |
14111 | + | |
14112 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
14113 | return HANDLER_ERROR; | |
14114 | } | |
14115 | - | |
14116 | + | |
14117 | if (i == 0 && buffer_is_empty(s->format)) { | |
14118 | /* set a default logfile string */ | |
14119 | - | |
14120 | + | |
14121 | buffer_copy_string(s->format, "%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""); | |
14122 | } | |
14123 | - | |
14124 | + | |
14125 | /* parse */ | |
14126 | - | |
14127 | + | |
14128 | if (s->format->used) { | |
14129 | s->parsed_format = calloc(1, sizeof(*(s->parsed_format))); | |
14130 | - | |
14131 | + | |
14132 | if (-1 == accesslog_parse_format(srv, s->parsed_format, s->format)) { | |
14133 | ||
14134 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
14135 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
14136 | "parsing accesslog-definition failed:", s->format); | |
14137 | ||
14138 | return HANDLER_ERROR; | |
14139 | } | |
14140 | #if 0 | |
14141 | - /* debugging */ | |
14142 | + /* debugging */ | |
14143 | for (j = 0; j < s->parsed_format->used; j++) { | |
14144 | switch (s->parsed_format->ptr[j]->type) { | |
14145 | case FIELD_FORMAT: | |
14146 | - log_error_write(srv, __FILE__, __LINE__, "ssds", | |
14147 | + log_error_write(srv, __FILE__, __LINE__, "ssds", | |
14148 | "config:", "format", s->parsed_format->ptr[j]->field, | |
14149 | - s->parsed_format->ptr[j]->string ? | |
14150 | + s->parsed_format->ptr[j]->string ? | |
14151 | s->parsed_format->ptr[j]->string->ptr : "" ); | |
14152 | break; | |
14153 | case FIELD_STRING: | |
14154 | @@ -446,52 +446,52 @@ | |
14155 | } | |
14156 | #endif | |
14157 | } | |
14158 | - | |
14159 | + | |
14160 | if (s->use_syslog) { | |
14161 | /* ignore the next checks */ | |
14162 | continue; | |
14163 | } | |
14164 | - | |
14165 | + | |
14166 | if (buffer_is_empty(s->access_logfile)) continue; | |
14167 | - | |
14168 | + | |
14169 | if (s->access_logfile->ptr[0] == '|') { | |
14170 | #ifdef HAVE_FORK | |
14171 | /* create write pipe and spawn process */ | |
14172 | - | |
14173 | + | |
14174 | int to_log_fds[2]; | |
14175 | pid_t pid; | |
14176 | - | |
14177 | + | |
14178 | if (pipe(to_log_fds)) { | |
14179 | log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno)); | |
14180 | return HANDLER_ERROR; | |
14181 | } | |
14182 | - | |
14183 | + | |
14184 | /* fork, execve */ | |
14185 | switch (pid = fork()) { | |
14186 | - case 0: | |
14187 | + case 0: | |
14188 | /* child */ | |
14189 | - | |
14190 | + | |
14191 | close(STDIN_FILENO); | |
14192 | dup2(to_log_fds[0], STDIN_FILENO); | |
14193 | close(to_log_fds[0]); | |
14194 | /* not needed */ | |
14195 | close(to_log_fds[1]); | |
14196 | - | |
14197 | + | |
14198 | /* we don't need the client socket */ | |
14199 | for (i = 3; i < 256; i++) { | |
14200 | close(i); | |
14201 | } | |
14202 | - | |
14203 | - /* exec the log-process (skip the | ) | |
14204 | - * | |
14205 | + | |
14206 | + /* exec the log-process (skip the | ) | |
14207 | + * | |
14208 | */ | |
14209 | - | |
14210 | + | |
14211 | execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, NULL); | |
14212 | ||
14213 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
14214 | - "spawning log-process failed: ", strerror(errno), | |
14215 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
14216 | + "spawning log-process failed: ", strerror(errno), | |
14217 | s->access_logfile->ptr + 1); | |
14218 | - | |
14219 | + | |
14220 | exit(-1); | |
14221 | break; | |
14222 | case -1: | |
14223 | @@ -500,27 +500,28 @@ | |
14224 | break; | |
14225 | default: | |
14226 | close(to_log_fds[0]); | |
14227 | - | |
14228 | + | |
14229 | s->log_access_fd = to_log_fds[1]; | |
14230 | - | |
14231 | + | |
14232 | break; | |
14233 | } | |
14234 | #else | |
14235 | return -1; | |
14236 | #endif | |
14237 | - } else if (-1 == (s->log_access_fd = | |
14238 | + } else if (-1 == (s->log_access_fd = | |
14239 | open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { | |
14240 | - | |
14241 | - log_error_write(srv, __FILE__, __LINE__, "ssb", | |
14242 | - "opening access-log failed:", | |
14243 | + | |
14244 | + log_error_write(srv, __FILE__, __LINE__, "ssb", | |
14245 | + "opening access-log failed:", | |
14246 | strerror(errno), s->access_logfile); | |
14247 | - | |
14248 | + | |
14249 | return HANDLER_ERROR; | |
14250 | } | |
14251 | +#ifndef _WIN32 | |
14252 | fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC); | |
14253 | - | |
14254 | +#endif | |
14255 | } | |
14256 | - | |
14257 | + | |
14258 | return HANDLER_GO_ON; | |
14259 | } | |
14260 | ||
14261 | @@ -529,7 +530,7 @@ | |
14262 | size_t i; | |
14263 | ||
14264 | if (!p->config_storage) return HANDLER_GO_ON; | |
14265 | - | |
14266 | + | |
14267 | for (i = 0; i < srv->config_context->used; i++) { | |
14268 | plugin_config *s = p->config_storage[i]; | |
14269 | ||
14270 | @@ -544,90 +545,87 @@ | |
14271 | } else if (s->log_access_fd != -1) { | |
14272 | write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1); | |
14273 | } | |
14274 | - | |
14275 | + | |
14276 | buffer_reset(s->access_logbuffer); | |
14277 | } | |
14278 | - | |
14279 | + | |
14280 | if (s->use_syslog == 0 && | |
14281 | !buffer_is_empty(s->access_logfile) && | |
14282 | s->access_logfile->ptr[0] != '|') { | |
14283 | - | |
14284 | + | |
14285 | close(s->log_access_fd); | |
14286 | - | |
14287 | - if (-1 == (s->log_access_fd = | |
14288 | + | |
14289 | + if (-1 == (s->log_access_fd = | |
14290 | open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { | |
14291 | - | |
14292 | + | |
14293 | log_error_write(srv, __FILE__, __LINE__, "ss", "cycling access-log failed:", strerror(errno)); | |
14294 | - | |
14295 | + | |
14296 | return HANDLER_ERROR; | |
14297 | } | |
14298 | } | |
14299 | } | |
14300 | - | |
14301 | + | |
14302 | return HANDLER_GO_ON; | |
14303 | } | |
14304 | ||
14305 | -#define PATCH(x) \ | |
14306 | - p->conf.x = s->x; | |
14307 | static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_data *p) { | |
14308 | size_t i, j; | |
14309 | plugin_config *s = p->config_storage[0]; | |
14310 | - | |
14311 | - PATCH(access_logfile); | |
14312 | - PATCH(format); | |
14313 | - PATCH(log_access_fd); | |
14314 | - PATCH(last_generated_accesslog_ts_ptr); | |
14315 | - PATCH(access_logbuffer); | |
14316 | - PATCH(ts_accesslog_str); | |
14317 | - PATCH(parsed_format); | |
14318 | - PATCH(use_syslog); | |
14319 | - | |
14320 | + | |
14321 | + PATCH_OPTION(access_logfile); | |
14322 | + PATCH_OPTION(format); | |
14323 | + PATCH_OPTION(log_access_fd); | |
14324 | + PATCH_OPTION(last_generated_accesslog_ts_ptr); | |
14325 | + PATCH_OPTION(access_logbuffer); | |
14326 | + PATCH_OPTION(ts_accesslog_str); | |
14327 | + PATCH_OPTION(parsed_format); | |
14328 | + PATCH_OPTION(use_syslog); | |
14329 | + | |
14330 | /* skip the first, the global context */ | |
14331 | for (i = 1; i < srv->config_context->used; i++) { | |
14332 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
14333 | s = p->config_storage[i]; | |
14334 | - | |
14335 | + | |
14336 | /* condition didn't match */ | |
14337 | if (!config_check_cond(srv, con, dc)) continue; | |
14338 | - | |
14339 | + | |
14340 | /* merge config */ | |
14341 | for (j = 0; j < dc->value->used; j++) { | |
14342 | data_unset *du = dc->value->data[j]; | |
14343 | - | |
14344 | + | |
14345 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) { | |
14346 | - PATCH(access_logfile); | |
14347 | - PATCH(log_access_fd); | |
14348 | - PATCH(last_generated_accesslog_ts_ptr); | |
14349 | - PATCH(access_logbuffer); | |
14350 | - PATCH(ts_accesslog_str); | |
14351 | + PATCH_OPTION(access_logfile); | |
14352 | + PATCH_OPTION(log_access_fd); | |
14353 | + PATCH_OPTION(last_generated_accesslog_ts_ptr); | |
14354 | + PATCH_OPTION(access_logbuffer); | |
14355 | + PATCH_OPTION(ts_accesslog_str); | |
14356 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) { | |
14357 | - PATCH(format); | |
14358 | - PATCH(parsed_format); | |
14359 | + PATCH_OPTION(format); | |
14360 | + PATCH_OPTION(parsed_format); | |
14361 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) { | |
14362 | - PATCH(use_syslog); | |
14363 | + PATCH_OPTION(use_syslog); | |
14364 | } | |
14365 | } | |
14366 | } | |
14367 | - | |
14368 | + | |
14369 | return 0; | |
14370 | } | |
14371 | -#undef PATCH | |
14372 | ||
14373 | REQUESTDONE_FUNC(log_access_write) { | |
14374 | plugin_data *p = p_d; | |
14375 | buffer *b; | |
14376 | size_t j; | |
14377 | - | |
14378 | + | |
14379 | int newts = 0; | |
14380 | data_string *ds; | |
14381 | - | |
14382 | + | |
14383 | mod_accesslog_patch_connection(srv, con, p); | |
14384 | - | |
14385 | + | |
14386 | b = p->conf.access_logbuffer; | |
14387 | if (b->used == 0) { | |
14388 | buffer_copy_string(b, ""); | |
14389 | } | |
14390 | - | |
14391 | + | |
14392 | for (j = 0; j < p->conf.parsed_format->used; j++) { | |
14393 | switch(p->conf.parsed_format->ptr[j]->type) { | |
14394 | case FIELD_STRING: | |
14395 | @@ -636,14 +634,14 @@ | |
14396 | case FIELD_FORMAT: | |
14397 | switch(p->conf.parsed_format->ptr[j]->field) { | |
14398 | case FORMAT_TIMESTAMP: | |
14399 | - | |
14400 | + | |
14401 | /* cache the generated timestamp */ | |
14402 | if (srv->cur_ts != *(p->conf.last_generated_accesslog_ts_ptr)) { | |
14403 | struct tm tm; | |
14404 | #if defined(HAVE_STRUCT_TM_GMTOFF) | |
14405 | long scd, hrs, min; | |
14406 | #endif | |
14407 | - | |
14408 | + | |
14409 | buffer_prepare_copy(p->conf.ts_accesslog_str, 255); | |
14410 | #if defined(HAVE_STRUCT_TM_GMTOFF) | |
14411 | # ifdef HAVE_LOCALTIME_R | |
14412 | @@ -653,17 +651,17 @@ | |
14413 | strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime_r(&(srv->cur_ts))); | |
14414 | # endif | |
14415 | p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1; | |
14416 | - | |
14417 | + | |
14418 | buffer_append_string(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-"); | |
14419 | - | |
14420 | + | |
14421 | scd = abs(tm.tm_gmtoff); | |
14422 | hrs = scd / 3600; | |
14423 | min = (scd % 3600) / 60; | |
14424 | - | |
14425 | + | |
14426 | /* hours */ | |
14427 | if (hrs < 10) buffer_append_string(p->conf.ts_accesslog_str, "0"); | |
14428 | buffer_append_long(p->conf.ts_accesslog_str, hrs); | |
14429 | - | |
14430 | + | |
14431 | if (min < 10) buffer_append_string(p->conf.ts_accesslog_str, "0"); | |
14432 | buffer_append_long(p->conf.ts_accesslog_str, min); | |
14433 | BUFFER_APPEND_STRING_CONST(p->conf.ts_accesslog_str, "]"); | |
14434 | @@ -676,20 +674,20 @@ | |
14435 | #endif | |
14436 | p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1; | |
14437 | #endif | |
14438 | - | |
14439 | + | |
14440 | *(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts; | |
14441 | newts = 1; | |
14442 | } | |
14443 | - | |
14444 | + | |
14445 | buffer_append_string_buffer(b, p->conf.ts_accesslog_str); | |
14446 | - | |
14447 | + | |
14448 | break; | |
14449 | case FORMAT_REMOTE_HOST: | |
14450 | - | |
14451 | + | |
14452 | /* handle inet_ntop cache */ | |
14453 | - | |
14454 | + | |
14455 | buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(con->dst_addr))); | |
14456 | - | |
14457 | + | |
14458 | break; | |
14459 | case FORMAT_REMOTE_IDENT: | |
14460 | /* ident */ | |
14461 | @@ -710,10 +708,10 @@ | |
14462 | case FORMAT_STATUS: | |
14463 | buffer_append_long(b, con->http_status); | |
14464 | break; | |
14465 | - | |
14466 | + | |
14467 | case FORMAT_BYTES_OUT_NO_HEADER: | |
14468 | if (con->bytes_written > 0) { | |
14469 | - buffer_append_off_t(b, | |
14470 | + buffer_append_off_t(b, | |
14471 | con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header); | |
14472 | } else { | |
14473 | BUFFER_APPEND_STRING_CONST(b, "-"); | |
14474 | @@ -772,7 +770,7 @@ | |
14475 | } | |
14476 | break; | |
14477 | case FORMAT_REQUEST_PROTOCOL: | |
14478 | - buffer_append_string(b, | |
14479 | + buffer_append_string(b, | |
14480 | con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0"); | |
14481 | break; | |
14482 | case FORMAT_REQUEST_METHOD: | |
14483 | @@ -801,7 +799,7 @@ | |
14484 | { 'D', FORMAT_TIME_USED_MS }, | |
14485 | { 'e', FORMAT_ENV }, | |
14486 | */ | |
14487 | - | |
14488 | + | |
14489 | break; | |
14490 | } | |
14491 | break; | |
14492 | @@ -809,7 +807,7 @@ | |
14493 | break; | |
14494 | } | |
14495 | } | |
14496 | - | |
14497 | + | |
14498 | BUFFER_APPEND_STRING_CONST(b, "\n"); | |
14499 | ||
14500 | if (p->conf.use_syslog || /* syslog doesn't cache */ | |
14501 | @@ -828,7 +826,7 @@ | |
14502 | } | |
14503 | buffer_reset(b); | |
14504 | } | |
14505 | - | |
14506 | + | |
14507 | return HANDLER_GO_ON; | |
14508 | } | |
14509 | ||
14510 | @@ -836,15 +834,15 @@ | |
14511 | int mod_accesslog_plugin_init(plugin *p) { | |
14512 | p->version = LIGHTTPD_VERSION_ID; | |
14513 | p->name = buffer_init_string("accesslog"); | |
14514 | - | |
14515 | + | |
14516 | p->init = mod_accesslog_init; | |
14517 | p->set_defaults= log_access_open; | |
14518 | p->cleanup = mod_accesslog_free; | |
14519 | - | |
14520 | + | |
14521 | p->handle_request_done = log_access_write; | |
14522 | p->handle_sighup = log_access_cycle; | |
14523 | - | |
14524 | + | |
14525 | p->data = NULL; | |
14526 | - | |
14527 | + | |
14528 | return 0; | |
14529 | } | |
1175ccec | 14530 | --- ../lighttpd-1.4.11/src/mod_alias.c 2006-03-01 23:18:51.000000000 +0200 |
36e2a29e | 14531 | +++ lighttpd-1.4.12/src/mod_alias.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
14532 | @@ -8,6 +8,7 @@ |
14533 | #include "buffer.h" | |
14534 | ||
14535 | #include "plugin.h" | |
14536 | +#include "sys-strings.h" | |
14537 | ||
14538 | /* plugin config for all request/connections */ | |
14539 | typedef struct { | |
14540 | @@ -16,44 +17,44 @@ | |
14541 | ||
14542 | typedef struct { | |
14543 | PLUGIN_DATA; | |
14544 | - | |
14545 | + | |
14546 | plugin_config **config_storage; | |
14547 | - | |
14548 | - plugin_config conf; | |
14549 | + | |
14550 | + plugin_config conf; | |
14551 | } plugin_data; | |
14552 | ||
14553 | /* init the plugin data */ | |
14554 | INIT_FUNC(mod_alias_init) { | |
14555 | plugin_data *p; | |
14556 | - | |
14557 | + | |
14558 | p = calloc(1, sizeof(*p)); | |
14559 | - | |
14560 | - | |
14561 | - | |
14562 | + | |
14563 | + | |
14564 | + | |
14565 | return p; | |
14566 | } | |
14567 | ||
14568 | /* detroy the plugin data */ | |
14569 | FREE_FUNC(mod_alias_free) { | |
14570 | plugin_data *p = p_d; | |
14571 | - | |
14572 | + | |
14573 | if (!p) return HANDLER_GO_ON; | |
14574 | - | |
14575 | + | |
14576 | if (p->config_storage) { | |
14577 | size_t i; | |
14578 | - | |
14579 | + | |
14580 | for (i = 0; i < srv->config_context->used; i++) { | |
14581 | plugin_config *s = p->config_storage[i]; | |
14582 | - | |
14583 | + | |
14584 | array_free(s->alias); | |
14585 | - | |
14586 | + | |
14587 | free(s); | |
14588 | } | |
14589 | free(p->config_storage); | |
14590 | } | |
14591 | - | |
14592 | + | |
14593 | free(p); | |
14594 | - | |
14595 | + | |
14596 | return HANDLER_GO_ON; | |
14597 | } | |
14598 | ||
14599 | @@ -62,25 +63,25 @@ | |
14600 | SETDEFAULTS_FUNC(mod_alias_set_defaults) { | |
14601 | plugin_data *p = p_d; | |
14602 | size_t i = 0; | |
14603 | - | |
14604 | - config_values_t cv[] = { | |
14605 | + | |
14606 | + config_values_t cv[] = { | |
14607 | { "alias.url", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
14608 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
14609 | }; | |
14610 | - | |
14611 | + | |
14612 | if (!p) return HANDLER_ERROR; | |
14613 | - | |
14614 | + | |
14615 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
14616 | - | |
14617 | + | |
14618 | for (i = 0; i < srv->config_context->used; i++) { | |
14619 | plugin_config *s; | |
14620 | - | |
14621 | + | |
14622 | s = calloc(1, sizeof(plugin_config)); | |
14623 | - s->alias = array_init(); | |
14624 | + s->alias = array_init(); | |
14625 | cv[0].destination = s->alias; | |
14626 | - | |
14627 | + | |
14628 | p->config_storage[i] = s; | |
14629 | - | |
14630 | + | |
14631 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
14632 | return HANDLER_ERROR; | |
14633 | } | |
14634 | @@ -110,76 +111,73 @@ | |
14635 | } | |
14636 | } | |
14637 | } | |
14638 | - | |
14639 | + | |
14640 | return HANDLER_GO_ON; | |
14641 | } | |
14642 | ||
14643 | -#define PATCH(x) \ | |
14644 | - p->conf.x = s->x; | |
14645 | static int mod_alias_patch_connection(server *srv, connection *con, plugin_data *p) { | |
14646 | size_t i, j; | |
14647 | plugin_config *s = p->config_storage[0]; | |
14648 | - | |
14649 | - PATCH(alias); | |
14650 | - | |
14651 | + | |
14652 | + PATCH_OPTION(alias); | |
14653 | + | |
14654 | /* skip the first, the global context */ | |
14655 | for (i = 1; i < srv->config_context->used; i++) { | |
14656 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
14657 | s = p->config_storage[i]; | |
14658 | - | |
14659 | + | |
14660 | /* condition didn't match */ | |
14661 | if (!config_check_cond(srv, con, dc)) continue; | |
14662 | - | |
14663 | + | |
14664 | /* merge config */ | |
14665 | for (j = 0; j < dc->value->used; j++) { | |
14666 | data_unset *du = dc->value->data[j]; | |
14667 | - | |
14668 | + | |
14669 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("alias.url"))) { | |
14670 | - PATCH(alias); | |
14671 | + PATCH_OPTION(alias); | |
14672 | } | |
14673 | } | |
14674 | } | |
14675 | - | |
14676 | + | |
14677 | return 0; | |
14678 | } | |
14679 | -#undef PATCH | |
14680 | ||
14681 | PHYSICALPATH_FUNC(mod_alias_physical_handler) { | |
14682 | plugin_data *p = p_d; | |
14683 | int uri_len, basedir_len; | |
14684 | char *uri_ptr; | |
14685 | size_t k; | |
14686 | - | |
14687 | + | |
14688 | if (con->physical.path->used == 0) return HANDLER_GO_ON; | |
14689 | - | |
14690 | + | |
14691 | mod_alias_patch_connection(srv, con, p); | |
14692 | - | |
14693 | + | |
14694 | /* not to include the tailing slash */ | |
14695 | basedir_len = (con->physical.basedir->used - 1) - 1; | |
14696 | uri_len = con->physical.path->used - 1 - basedir_len; | |
14697 | uri_ptr = con->physical.path->ptr + basedir_len; | |
14698 | - | |
14699 | + | |
14700 | for (k = 0; k < p->conf.alias->used; k++) { | |
14701 | data_string *ds = (data_string *)p->conf.alias->data[k]; | |
14702 | int alias_len = ds->key->used - 1; | |
14703 | - | |
14704 | + | |
14705 | if (alias_len > uri_len) continue; | |
14706 | if (ds->key->used == 0) continue; | |
14707 | - | |
14708 | + | |
14709 | if (0 == (con->conf.force_lowercase_filenames ? | |
14710 | strncasecmp(uri_ptr, ds->key->ptr, alias_len) : | |
14711 | strncmp(uri_ptr, ds->key->ptr, alias_len))) { | |
14712 | /* matched */ | |
14713 | - | |
14714 | + | |
14715 | buffer_copy_string_buffer(con->physical.basedir, ds->value); | |
14716 | buffer_copy_string_buffer(srv->tmp_buf, ds->value); | |
14717 | buffer_append_string(srv->tmp_buf, uri_ptr + alias_len); | |
14718 | buffer_copy_string_buffer(con->physical.path, srv->tmp_buf); | |
14719 | - | |
14720 | + | |
14721 | return HANDLER_GO_ON; | |
14722 | } | |
14723 | } | |
14724 | - | |
14725 | + | |
14726 | /* not found */ | |
14727 | return HANDLER_GO_ON; | |
14728 | } | |
14729 | @@ -189,13 +187,13 @@ | |
14730 | int mod_alias_plugin_init(plugin *p) { | |
14731 | p->version = LIGHTTPD_VERSION_ID; | |
14732 | p->name = buffer_init_string("alias"); | |
14733 | - | |
14734 | + | |
14735 | p->init = mod_alias_init; | |
14736 | p->handle_physical= mod_alias_physical_handler; | |
14737 | p->set_defaults = mod_alias_set_defaults; | |
14738 | p->cleanup = mod_alias_free; | |
14739 | - | |
14740 | + | |
14741 | p->data = NULL; | |
14742 | - | |
14743 | + | |
14744 | return 0; | |
14745 | } | |
1175ccec | 14746 | --- ../lighttpd-1.4.11/src/mod_auth.c 2006-02-15 20:01:31.000000000 +0200 |
36e2a29e | 14747 | +++ lighttpd-1.4.12/src/mod_auth.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
14748 | @@ -5,168 +5,167 @@ |
14749 | #include <string.h> | |
14750 | #include <errno.h> | |
14751 | #include <fcntl.h> | |
14752 | -#include <unistd.h> | |
14753 | ||
14754 | #include "plugin.h" | |
14755 | #include "http_auth.h" | |
14756 | #include "log.h" | |
14757 | #include "response.h" | |
14758 | ||
14759 | +#include "sys-strings.h" | |
14760 | +#include "sys-files.h" | |
14761 | + | |
14762 | handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s); | |
14763 | ||
14764 | ||
14765 | /** | |
14766 | * the basic and digest auth framework | |
14767 | - * | |
14768 | + * | |
14769 | * - config handling | |
14770 | * - protocol handling | |
14771 | - * | |
14772 | - * http_auth.c | |
14773 | - * http_auth_digest.c | |
14774 | - * | |
14775 | + * | |
14776 | + * http_auth.c | |
14777 | + * http_auth_digest.c | |
14778 | + * | |
14779 | * do the real work | |
14780 | */ | |
14781 | ||
14782 | INIT_FUNC(mod_auth_init) { | |
14783 | mod_auth_plugin_data *p; | |
14784 | - | |
14785 | + | |
14786 | p = calloc(1, sizeof(*p)); | |
14787 | - | |
14788 | + | |
14789 | p->tmp_buf = buffer_init(); | |
14790 | - | |
14791 | + | |
14792 | p->auth_user = buffer_init(); | |
14793 | #ifdef USE_LDAP | |
14794 | p->ldap_filter = buffer_init(); | |
14795 | #endif | |
14796 | - | |
14797 | + | |
14798 | return p; | |
14799 | } | |
14800 | ||
14801 | FREE_FUNC(mod_auth_free) { | |
14802 | mod_auth_plugin_data *p = p_d; | |
14803 | - | |
14804 | + | |
14805 | UNUSED(srv); | |
14806 | ||
14807 | if (!p) return HANDLER_GO_ON; | |
14808 | - | |
14809 | + | |
14810 | buffer_free(p->tmp_buf); | |
14811 | buffer_free(p->auth_user); | |
14812 | #ifdef USE_LDAP | |
14813 | buffer_free(p->ldap_filter); | |
14814 | #endif | |
14815 | - | |
14816 | + | |
14817 | if (p->config_storage) { | |
14818 | size_t i; | |
14819 | for (i = 0; i < srv->config_context->used; i++) { | |
14820 | mod_auth_plugin_config *s = p->config_storage[i]; | |
14821 | - | |
14822 | + | |
14823 | if (!s) continue; | |
14824 | - | |
14825 | + | |
14826 | array_free(s->auth_require); | |
14827 | buffer_free(s->auth_plain_groupfile); | |
14828 | buffer_free(s->auth_plain_userfile); | |
14829 | buffer_free(s->auth_htdigest_userfile); | |
14830 | buffer_free(s->auth_htpasswd_userfile); | |
14831 | buffer_free(s->auth_backend_conf); | |
14832 | - | |
14833 | + | |
14834 | buffer_free(s->auth_ldap_hostname); | |
14835 | buffer_free(s->auth_ldap_basedn); | |
14836 | buffer_free(s->auth_ldap_binddn); | |
14837 | buffer_free(s->auth_ldap_bindpw); | |
14838 | buffer_free(s->auth_ldap_filter); | |
14839 | buffer_free(s->auth_ldap_cafile); | |
14840 | - | |
14841 | + | |
14842 | #ifdef USE_LDAP | |
14843 | buffer_free(s->ldap_filter_pre); | |
14844 | buffer_free(s->ldap_filter_post); | |
14845 | - | |
14846 | + | |
14847 | if (s->ldap) ldap_unbind_s(s->ldap); | |
14848 | #endif | |
14849 | - | |
14850 | + | |
14851 | free(s); | |
14852 | } | |
14853 | free(p->config_storage); | |
14854 | } | |
14855 | - | |
14856 | + | |
14857 | free(p); | |
14858 | - | |
14859 | + | |
14860 | return HANDLER_GO_ON; | |
14861 | } | |
14862 | ||
14863 | -#define PATCH(x) \ | |
14864 | - p->conf.x = s->x; | |
14865 | static int mod_auth_patch_connection(server *srv, connection *con, mod_auth_plugin_data *p) { | |
14866 | size_t i, j; | |
14867 | mod_auth_plugin_config *s = p->config_storage[0]; | |
14868 | ||
14869 | - PATCH(auth_backend); | |
14870 | - PATCH(auth_plain_groupfile); | |
14871 | - PATCH(auth_plain_userfile); | |
14872 | - PATCH(auth_htdigest_userfile); | |
14873 | - PATCH(auth_htpasswd_userfile); | |
14874 | - PATCH(auth_require); | |
14875 | - PATCH(auth_debug); | |
14876 | - PATCH(auth_ldap_hostname); | |
14877 | - PATCH(auth_ldap_basedn); | |
14878 | - PATCH(auth_ldap_binddn); | |
14879 | - PATCH(auth_ldap_bindpw); | |
14880 | - PATCH(auth_ldap_filter); | |
14881 | - PATCH(auth_ldap_cafile); | |
14882 | - PATCH(auth_ldap_starttls); | |
14883 | + PATCH_OPTION(auth_backend); | |
14884 | + PATCH_OPTION(auth_plain_groupfile); | |
14885 | + PATCH_OPTION(auth_plain_userfile); | |
14886 | + PATCH_OPTION(auth_htdigest_userfile); | |
14887 | + PATCH_OPTION(auth_htpasswd_userfile); | |
14888 | + PATCH_OPTION(auth_require); | |
14889 | + PATCH_OPTION(auth_debug); | |
14890 | + PATCH_OPTION(auth_ldap_hostname); | |
14891 | + PATCH_OPTION(auth_ldap_basedn); | |
14892 | + PATCH_OPTION(auth_ldap_binddn); | |
14893 | + PATCH_OPTION(auth_ldap_bindpw); | |
14894 | + PATCH_OPTION(auth_ldap_filter); | |
14895 | + PATCH_OPTION(auth_ldap_cafile); | |
14896 | + PATCH_OPTION(auth_ldap_starttls); | |
14897 | #ifdef USE_LDAP | |
14898 | - PATCH(ldap); | |
14899 | - PATCH(ldap_filter_pre); | |
14900 | - PATCH(ldap_filter_post); | |
14901 | + PATCH_OPTION(ldap); | |
14902 | + PATCH_OPTION(ldap_filter_pre); | |
14903 | + PATCH_OPTION(ldap_filter_post); | |
14904 | #endif | |
14905 | - | |
14906 | + | |
14907 | /* skip the first, the global context */ | |
14908 | for (i = 1; i < srv->config_context->used; i++) { | |
14909 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
14910 | s = p->config_storage[i]; | |
14911 | - | |
14912 | + | |
14913 | /* condition didn't match */ | |
14914 | if (!config_check_cond(srv, con, dc)) continue; | |
14915 | - | |
14916 | + | |
14917 | /* merge config */ | |
14918 | for (j = 0; j < dc->value->used; j++) { | |
14919 | data_unset *du = dc->value->data[j]; | |
14920 | - | |
14921 | + | |
14922 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend"))) { | |
14923 | - PATCH(auth_backend); | |
14924 | + PATCH_OPTION(auth_backend); | |
14925 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.groupfile"))) { | |
14926 | - PATCH(auth_plain_groupfile); | |
14927 | + PATCH_OPTION(auth_plain_groupfile); | |
14928 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.userfile"))) { | |
14929 | - PATCH(auth_plain_userfile); | |
14930 | + PATCH_OPTION(auth_plain_userfile); | |
14931 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htdigest.userfile"))) { | |
14932 | - PATCH(auth_htdigest_userfile); | |
14933 | + PATCH_OPTION(auth_htdigest_userfile); | |
14934 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htpasswd.userfile"))) { | |
14935 | - PATCH(auth_htpasswd_userfile); | |
14936 | + PATCH_OPTION(auth_htpasswd_userfile); | |
14937 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.require"))) { | |
14938 | - PATCH(auth_require); | |
14939 | + PATCH_OPTION(auth_require); | |
14940 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.debug"))) { | |
14941 | - PATCH(auth_debug); | |
14942 | + PATCH_OPTION(auth_debug); | |
14943 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.hostname"))) { | |
14944 | - PATCH(auth_ldap_hostname); | |
14945 | + PATCH_OPTION(auth_ldap_hostname); | |
14946 | #ifdef USE_LDAP | |
14947 | - PATCH(ldap); | |
14948 | - PATCH(ldap_filter_pre); | |
14949 | - PATCH(ldap_filter_post); | |
14950 | + PATCH_OPTION(ldap); | |
14951 | + PATCH_OPTION(ldap_filter_pre); | |
14952 | + PATCH_OPTION(ldap_filter_post); | |
14953 | #endif | |
14954 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) { | |
14955 | - PATCH(auth_ldap_basedn); | |
14956 | + PATCH_OPTION(auth_ldap_basedn); | |
14957 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) { | |
14958 | - PATCH(auth_ldap_filter); | |
14959 | + PATCH_OPTION(auth_ldap_filter); | |
14960 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) { | |
14961 | - PATCH(auth_ldap_cafile); | |
14962 | + PATCH_OPTION(auth_ldap_cafile); | |
14963 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) { | |
14964 | - PATCH(auth_ldap_starttls); | |
14965 | + PATCH_OPTION(auth_ldap_starttls); | |
14966 | } | |
14967 | } | |
14968 | } | |
14969 | - | |
14970 | + | |
14971 | return 0; | |
14972 | } | |
14973 | -#undef PATCH | |
14974 | ||
14975 | static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) { | |
14976 | size_t k; | |
14977 | @@ -175,22 +174,22 @@ | |
14978 | data_string *ds; | |
14979 | mod_auth_plugin_data *p = p_d; | |
14980 | array *req; | |
14981 | - | |
14982 | + | |
14983 | /* select the right config */ | |
14984 | mod_auth_patch_connection(srv, con, p); | |
14985 | - | |
14986 | + | |
14987 | if (p->conf.auth_require == NULL) return HANDLER_GO_ON; | |
14988 | - | |
14989 | + | |
14990 | /* | |
14991 | * AUTH | |
14992 | - * | |
14993 | + * | |
14994 | */ | |
14995 | - | |
14996 | + | |
14997 | /* do we have to ask for auth ? */ | |
14998 | - | |
14999 | + | |
15000 | auth_required = 0; | |
15001 | auth_satisfied = 0; | |
15002 | - | |
15003 | + | |
15004 | /* search auth-directives for path */ | |
15005 | for (k = 0; k < p->conf.auth_require->used; k++) { | |
15006 | buffer *req = p->conf.auth_require->data[k]->key; | |
15007 | @@ -212,31 +211,31 @@ | |
15008 | } | |
15009 | } | |
15010 | } | |
15011 | - | |
15012 | + | |
15013 | /* nothing to do for us */ | |
15014 | if (auth_required == 0) return HANDLER_GO_ON; | |
15015 | - | |
15016 | + | |
15017 | req = ((data_array *)(p->conf.auth_require->data[k]))->value; | |
15018 | - | |
15019 | + | |
15020 | /* try to get Authorization-header */ | |
15021 | - | |
15022 | + | |
15023 | if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization"))) { | |
15024 | http_authorization = ds->value->ptr; | |
15025 | } | |
15026 | - | |
15027 | + | |
15028 | if (ds && ds->value && ds->value->used) { | |
15029 | char *auth_realm; | |
15030 | data_string *method; | |
15031 | - | |
15032 | + | |
15033 | method = (data_string *)array_get_element(req, "method"); | |
15034 | - | |
15035 | + | |
15036 | /* parse auth-header */ | |
15037 | if (NULL != (auth_realm = strchr(http_authorization, ' '))) { | |
15038 | int auth_type_len = auth_realm - http_authorization; | |
15039 | - | |
15040 | + | |
15041 | if ((auth_type_len == 5) && | |
15042 | (0 == strncmp(http_authorization, "Basic", auth_type_len))) { | |
15043 | - | |
15044 | + | |
15045 | if (0 == strcmp(method->value->ptr, "basic")) { | |
15046 | auth_satisfied = http_auth_basic_check(srv, con, p, req, con->uri.path, auth_realm+1); | |
15047 | } | |
15048 | @@ -245,43 +244,43 @@ | |
15049 | if (0 == strcmp(method->value->ptr, "digest")) { | |
15050 | if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, con->uri.path, auth_realm+1))) { | |
15051 | con->http_status = 400; | |
15052 | - | |
15053 | + | |
15054 | /* a field was missing */ | |
15055 | - | |
15056 | + | |
15057 | return HANDLER_FINISHED; | |
15058 | } | |
15059 | } | |
15060 | } else { | |
15061 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
15062 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
15063 | "unknown authentification type:", | |
15064 | http_authorization); | |
15065 | } | |
15066 | } | |
15067 | } | |
15068 | - | |
15069 | + | |
15070 | if (!auth_satisfied) { | |
15071 | data_string *method, *realm; | |
15072 | method = (data_string *)array_get_element(req, "method"); | |
15073 | realm = (data_string *)array_get_element(req, "realm"); | |
15074 | - | |
15075 | + | |
15076 | con->http_status = 401; | |
15077 | - | |
15078 | + | |
15079 | if (0 == strcmp(method->value->ptr, "basic")) { | |
15080 | buffer_copy_string(p->tmp_buf, "Basic realm=\""); | |
15081 | buffer_append_string_buffer(p->tmp_buf, realm->value); | |
15082 | buffer_append_string(p->tmp_buf, "\""); | |
15083 | - | |
15084 | + | |
15085 | response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf)); | |
15086 | } else if (0 == strcmp(method->value->ptr, "digest")) { | |
15087 | char hh[33]; | |
15088 | http_auth_digest_generate_nonce(srv, p, srv->tmp_buf, hh); | |
15089 | - | |
15090 | + | |
15091 | buffer_copy_string(p->tmp_buf, "Digest realm=\""); | |
15092 | buffer_append_string_buffer(p->tmp_buf, realm->value); | |
15093 | buffer_append_string(p->tmp_buf, "\", nonce=\""); | |
15094 | buffer_append_string(p->tmp_buf, hh); | |
15095 | buffer_append_string(p->tmp_buf, "\", qop=\"auth\""); | |
15096 | - | |
15097 | + | |
15098 | response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf)); | |
15099 | } else { | |
15100 | /* evil */ | |
15101 | @@ -289,18 +288,18 @@ | |
15102 | return HANDLER_FINISHED; | |
15103 | } else { | |
15104 | /* the REMOTE_USER header */ | |
15105 | - | |
15106 | + | |
15107 | buffer_copy_string_buffer(con->authed_user, p->auth_user); | |
15108 | } | |
15109 | - | |
15110 | + | |
15111 | return HANDLER_GO_ON; | |
15112 | } | |
15113 | ||
15114 | SETDEFAULTS_FUNC(mod_auth_set_defaults) { | |
15115 | mod_auth_plugin_data *p = p_d; | |
15116 | size_t i; | |
15117 | - | |
15118 | - config_values_t cv[] = { | |
15119 | + | |
15120 | + config_values_t cv[] = { | |
15121 | { "auth.backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
15122 | { "auth.backend.plain.groupfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
15123 | { "auth.backend.plain.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
15124 | @@ -317,7 +316,7 @@ | |
15125 | { "auth.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 13 */ | |
15126 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
15127 | }; | |
15128 | - | |
15129 | + | |
15130 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
15131 | ||
15132 | for (i = 0; i < srv->config_context->used; i++) { | |
15133 | @@ -325,14 +324,14 @@ | |
15134 | size_t n; | |
15135 | data_array *da; | |
15136 | array *ca; | |
15137 | - | |
15138 | + | |
15139 | s = calloc(1, sizeof(mod_auth_plugin_config)); | |
15140 | s->auth_plain_groupfile = buffer_init(); | |
15141 | s->auth_plain_userfile = buffer_init(); | |
15142 | s->auth_htdigest_userfile = buffer_init(); | |
15143 | s->auth_htpasswd_userfile = buffer_init(); | |
15144 | s->auth_backend_conf = buffer_init(); | |
15145 | - | |
15146 | + | |
15147 | s->auth_ldap_hostname = buffer_init(); | |
15148 | s->auth_ldap_basedn = buffer_init(); | |
15149 | s->auth_ldap_binddn = buffer_init(); | |
15150 | @@ -341,15 +340,15 @@ | |
15151 | s->auth_ldap_cafile = buffer_init(); | |
15152 | s->auth_ldap_starttls = 0; | |
15153 | s->auth_debug = 0; | |
15154 | - | |
15155 | + | |
15156 | s->auth_require = array_init(); | |
15157 | - | |
15158 | + | |
15159 | #ifdef USE_LDAP | |
15160 | s->ldap_filter_pre = buffer_init(); | |
15161 | s->ldap_filter_post = buffer_init(); | |
15162 | s->ldap = NULL; | |
15163 | #endif | |
15164 | - | |
15165 | + | |
15166 | cv[0].destination = s->auth_backend_conf; | |
15167 | cv[1].destination = s->auth_plain_groupfile; | |
15168 | cv[2].destination = s->auth_plain_userfile; | |
15169 | @@ -364,14 +363,14 @@ | |
15170 | cv[11].destination = s->auth_htdigest_userfile; | |
15171 | cv[12].destination = s->auth_htpasswd_userfile; | |
15172 | cv[13].destination = &(s->auth_debug); | |
15173 | - | |
15174 | + | |
15175 | p->config_storage[i] = s; | |
15176 | ca = ((data_config *)srv->config_context->data[i])->value; | |
15177 | - | |
15178 | + | |
15179 | if (0 != config_insert_values_global(srv, ca, cv)) { | |
15180 | return HANDLER_ERROR; | |
15181 | } | |
15182 | - | |
15183 | + | |
15184 | if (s->auth_backend_conf->used) { | |
15185 | if (0 == strcmp(s->auth_backend_conf->ptr, "htpasswd")) { | |
15186 | s->auth_backend = AUTH_BACKEND_HTPASSWD; | |
15187 | @@ -383,31 +382,31 @@ | |
15188 | s->auth_backend = AUTH_BACKEND_LDAP; | |
15189 | } else { | |
15190 | log_error_write(srv, __FILE__, __LINE__, "sb", "auth.backend not supported:", s->auth_backend_conf); | |
15191 | - | |
15192 | + | |
15193 | return HANDLER_ERROR; | |
15194 | } | |
15195 | } | |
15196 | ||
15197 | /* no auth.require for this section */ | |
15198 | if (NULL == (da = (data_array *)array_get_element(ca, "auth.require"))) continue; | |
15199 | - | |
15200 | + | |
15201 | if (da->type != TYPE_ARRAY) continue; | |
15202 | - | |
15203 | + | |
15204 | for (n = 0; n < da->value->used; n++) { | |
15205 | size_t m; | |
15206 | data_array *da_file = (data_array *)da->value->data[n]; | |
15207 | const char *method, *realm, *require; | |
15208 | - | |
15209 | + | |
15210 | if (da->value->data[n]->type != TYPE_ARRAY) { | |
15211 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
15212 | - "auth.require should contain an array as in:", | |
15213 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
15214 | + "auth.require should contain an array as in:", | |
15215 | "auth.require = ( \"...\" => ( ..., ...) )"); | |
15216 | ||
15217 | return HANDLER_ERROR; | |
15218 | } | |
15219 | - | |
15220 | + | |
15221 | method = realm = require = NULL; | |
15222 | - | |
15223 | + | |
15224 | for (m = 0; m < da_file->value->used; m++) { | |
15225 | if (da_file->value->data[m]->type == TYPE_STRING) { | |
15226 | if (0 == strcmp(da_file->value->data[m]->key->ptr, "method")) { | |
15227 | @@ -417,8 +416,8 @@ | |
15228 | } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "require")) { | |
15229 | require = ((data_string *)(da_file->value->data[m]))->value->ptr; | |
15230 | } else { | |
15231 | - log_error_write(srv, __FILE__, __LINE__, "ssbs", | |
15232 | - "the field is unknown in:", | |
15233 | + log_error_write(srv, __FILE__, __LINE__, "ssbs", | |
15234 | + "the field is unknown in:", | |
15235 | "auth.require = ( \"...\" => ( ..., -> \"", | |
15236 | da_file->value->data[m]->key, | |
15237 | "\" <- => \"...\" ) )"); | |
15238 | @@ -426,19 +425,19 @@ | |
15239 | return HANDLER_ERROR; | |
15240 | } | |
15241 | } else { | |
15242 | - log_error_write(srv, __FILE__, __LINE__, "ssbs", | |
15243 | - "a string was expected for:", | |
15244 | + log_error_write(srv, __FILE__, __LINE__, "ssbs", | |
15245 | + "a string was expected for:", | |
15246 | "auth.require = ( \"...\" => ( ..., -> \"", | |
15247 | da_file->value->data[m]->key, | |
15248 | "\" <- => \"...\" ) )"); | |
15249 | - | |
15250 | + | |
15251 | return HANDLER_ERROR; | |
15252 | } | |
15253 | } | |
15254 | - | |
15255 | + | |
15256 | if (method == NULL) { | |
15257 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
15258 | - "the require field is missing in:", | |
15259 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
15260 | + "the require field is missing in:", | |
15261 | "auth.require = ( \"...\" => ( ..., \"method\" => \"...\" ) )"); | |
15262 | return HANDLER_ERROR; | |
15263 | } else { | |
15264 | @@ -450,60 +449,60 @@ | |
15265 | return HANDLER_ERROR; | |
15266 | } | |
15267 | } | |
15268 | - | |
15269 | + | |
15270 | if (realm == NULL) { | |
15271 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
15272 | - "the require field is missing in:", | |
15273 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
15274 | + "the require field is missing in:", | |
15275 | "auth.require = ( \"...\" => ( ..., \"realm\" => \"...\" ) )"); | |
15276 | return HANDLER_ERROR; | |
15277 | } | |
15278 | - | |
15279 | + | |
15280 | if (require == NULL) { | |
15281 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
15282 | - "the require field is missing in:", | |
15283 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
15284 | + "the require field is missing in:", | |
15285 | "auth.require = ( \"...\" => ( ..., \"require\" => \"...\" ) )"); | |
15286 | return HANDLER_ERROR; | |
15287 | } | |
15288 | - | |
15289 | + | |
15290 | if (method && realm && require) { | |
15291 | data_string *ds; | |
15292 | data_array *a; | |
15293 | - | |
15294 | + | |
15295 | a = data_array_init(); | |
15296 | buffer_copy_string_buffer(a->key, da_file->key); | |
15297 | - | |
15298 | + | |
15299 | ds = data_string_init(); | |
15300 | - | |
15301 | + | |
15302 | buffer_copy_string(ds->key, "method"); | |
15303 | buffer_copy_string(ds->value, method); | |
15304 | - | |
15305 | + | |
15306 | array_insert_unique(a->value, (data_unset *)ds); | |
15307 | - | |
15308 | + | |
15309 | ds = data_string_init(); | |
15310 | - | |
15311 | + | |
15312 | buffer_copy_string(ds->key, "realm"); | |
15313 | buffer_copy_string(ds->value, realm); | |
15314 | - | |
15315 | + | |
15316 | array_insert_unique(a->value, (data_unset *)ds); | |
15317 | - | |
15318 | + | |
15319 | ds = data_string_init(); | |
15320 | - | |
15321 | + | |
15322 | buffer_copy_string(ds->key, "require"); | |
15323 | buffer_copy_string(ds->value, require); | |
15324 | - | |
15325 | + | |
15326 | array_insert_unique(a->value, (data_unset *)ds); | |
15327 | - | |
15328 | + | |
15329 | array_insert_unique(s->auth_require, (data_unset *)a); | |
15330 | } | |
15331 | } | |
15332 | - | |
15333 | + | |
15334 | switch(s->auth_backend) { | |
15335 | case AUTH_BACKEND_PLAIN: | |
15336 | if (s->auth_plain_userfile->used) { | |
15337 | int fd; | |
15338 | /* try to read */ | |
15339 | if (-1 == (fd = open(s->auth_plain_userfile->ptr, O_RDONLY))) { | |
15340 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
15341 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
15342 | "opening auth.backend.plain.userfile:", s->auth_plain_userfile, | |
15343 | "failed:", strerror(errno)); | |
15344 | return HANDLER_ERROR; | |
15345 | @@ -516,7 +515,7 @@ | |
15346 | int fd; | |
15347 | /* try to read */ | |
15348 | if (-1 == (fd = open(s->auth_htpasswd_userfile->ptr, O_RDONLY))) { | |
15349 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
15350 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
15351 | "opening auth.backend.htpasswd.userfile:", s->auth_htpasswd_userfile, | |
15352 | "failed:", strerror(errno)); | |
15353 | return HANDLER_ERROR; | |
15354 | @@ -529,7 +528,7 @@ | |
15355 | int fd; | |
15356 | /* try to read */ | |
15357 | if (-1 == (fd = open(s->auth_htdigest_userfile->ptr, O_RDONLY))) { | |
15358 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
15359 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
15360 | "opening auth.backend.htdigest.userfile:", s->auth_htdigest_userfile, | |
15361 | "failed:", strerror(errno)); | |
15362 | return HANDLER_ERROR; | |
15363 | @@ -554,75 +553,75 @@ | |
15364 | handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) { | |
15365 | #ifdef USE_LDAP | |
15366 | int ret; | |
15367 | -#if 0 | |
15368 | +#if 0 | |
15369 | if (s->auth_ldap_basedn->used == 0) { | |
15370 | log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set"); | |
15371 | - | |
15372 | + | |
15373 | return HANDLER_ERROR; | |
15374 | } | |
15375 | #endif | |
15376 | - | |
15377 | + | |
15378 | if (s->auth_ldap_filter->used) { | |
15379 | char *dollar; | |
15380 | - | |
15381 | + | |
15382 | /* parse filter */ | |
15383 | - | |
15384 | + | |
15385 | if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) { | |
15386 | log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'"); | |
15387 | - | |
15388 | + | |
15389 | return HANDLER_ERROR; | |
15390 | } | |
15391 | - | |
15392 | + | |
15393 | buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr); | |
15394 | buffer_copy_string(s->ldap_filter_post, dollar+1); | |
15395 | } | |
15396 | - | |
15397 | + | |
15398 | if (s->auth_ldap_hostname->used) { | |
15399 | if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) { | |
15400 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); | |
15401 | - | |
15402 | + | |
15403 | return HANDLER_ERROR; | |
15404 | } | |
15405 | - | |
15406 | + | |
15407 | ret = LDAP_VERSION3; | |
15408 | if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { | |
15409 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); | |
15410 | - | |
15411 | + | |
15412 | return HANDLER_ERROR; | |
15413 | } | |
15414 | ||
15415 | if (s->auth_ldap_starttls) { | |
15416 | - /* if no CA file is given, it is ok, as we will use encryption | |
15417 | + /* if no CA file is given, it is ok, as we will use encryption | |
15418 | * if the server requires a CAfile it will tell us */ | |
15419 | if (!buffer_is_empty(s->auth_ldap_cafile)) { | |
15420 | - if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, | |
15421 | + if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, | |
15422 | s->auth_ldap_cafile->ptr))) { | |
15423 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
15424 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
15425 | "Loading CA certificate failed:", ldap_err2string(ret)); | |
15426 | - | |
15427 | + | |
15428 | return HANDLER_ERROR; | |
15429 | } | |
15430 | } | |
15431 | - | |
15432 | + | |
15433 | if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL, NULL))) { | |
15434 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); | |
15435 | - | |
15436 | + | |
15437 | return HANDLER_ERROR; | |
15438 | } | |
15439 | } | |
15440 | - | |
15441 | - | |
15442 | + | |
15443 | + | |
15444 | /* 1. */ | |
15445 | if (s->auth_ldap_binddn->used) { | |
15446 | if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) { | |
15447 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); | |
15448 | - | |
15449 | + | |
15450 | return HANDLER_ERROR; | |
15451 | } | |
15452 | } else { | |
15453 | if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) { | |
15454 | log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); | |
15455 | - | |
15456 | + | |
15457 | return HANDLER_ERROR; | |
15458 | } | |
15459 | } | |
15460 | @@ -641,8 +640,8 @@ | |
15461 | p->set_defaults = mod_auth_set_defaults; | |
15462 | p->handle_uri_clean = mod_auth_uri_handler; | |
15463 | p->cleanup = mod_auth_free; | |
15464 | - | |
15465 | + | |
15466 | p->data = NULL; | |
15467 | - | |
15468 | + | |
15469 | return 0; | |
15470 | } | |
1175ccec | 15471 | --- ../lighttpd-1.4.11/src/mod_cgi.c 2006-02-22 15:15:10.000000000 +0200 |
36e2a29e | 15472 | +++ lighttpd-1.4.12/src/mod_cgi.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
15473 | @@ -1,21 +1,8 @@ |
15474 | #include <sys/types.h> | |
15475 | -#ifdef __WIN32 | |
15476 | -#include <winsock2.h> | |
15477 | -#else | |
15478 | -#include <sys/socket.h> | |
15479 | -#include <sys/wait.h> | |
15480 | -#include <sys/mman.h> | |
15481 | - | |
15482 | -#include <netinet/in.h> | |
15483 | - | |
15484 | -#include <arpa/inet.h> | |
15485 | -#endif | |
15486 | ||
15487 | -#include <unistd.h> | |
15488 | #include <errno.h> | |
15489 | #include <stdlib.h> | |
15490 | #include <string.h> | |
15491 | -#include <fdevent.h> | |
15492 | #include <signal.h> | |
15493 | #include <ctype.h> | |
15494 | #include <assert.h> | |
15495 | @@ -29,9 +16,16 @@ | |
15496 | #include "connections.h" | |
15497 | #include "joblist.h" | |
15498 | #include "http_chunk.h" | |
15499 | +#include "fdevent.h" | |
15500 | ||
15501 | #include "plugin.h" | |
15502 | ||
15503 | +#include "sys-files.h" | |
15504 | +#include "sys-mmap.h" | |
15505 | +#include "sys-socket.h" | |
15506 | +#include "sys-strings.h" | |
15507 | +#include "sys-process.h" | |
15508 | + | |
15509 | #ifdef HAVE_SYS_FILIO_H | |
15510 | # include <sys/filio.h> | |
15511 | #endif | |
15512 | @@ -40,11 +34,12 @@ | |
15513 | ||
15514 | typedef struct { | |
15515 | char **ptr; | |
15516 | - | |
15517 | + | |
15518 | size_t size; | |
15519 | size_t used; | |
15520 | } char_array; | |
15521 | ||
15522 | +#define pid_t int | |
15523 | typedef struct { | |
15524 | pid_t *ptr; | |
15525 | size_t used; | |
15526 | @@ -58,23 +53,23 @@ | |
15527 | typedef struct { | |
15528 | PLUGIN_DATA; | |
15529 | buffer_pid_t cgi_pid; | |
15530 | - | |
15531 | + | |
15532 | buffer *tmp_buf; | |
15533 | buffer *parse_response; | |
15534 | - | |
15535 | + | |
15536 | plugin_config **config_storage; | |
15537 | - | |
15538 | - plugin_config conf; | |
15539 | + | |
15540 | + plugin_config conf; | |
15541 | } plugin_data; | |
15542 | ||
15543 | typedef struct { | |
15544 | pid_t pid; | |
15545 | int fd; | |
15546 | int fde_ndx; /* index into the fd-event buffer */ | |
15547 | - | |
15548 | + | |
15549 | connection *remote_conn; /* dumb pointer */ | |
15550 | plugin_data *plugin_data; /* dumb pointer */ | |
15551 | - | |
15552 | + | |
15553 | buffer *response; | |
15554 | buffer *response_header; | |
15555 | } handler_ctx; | |
15556 | @@ -83,17 +78,17 @@ | |
15557 | handler_ctx *hctx = calloc(1, sizeof(*hctx)); | |
15558 | ||
15559 | assert(hctx); | |
15560 | - | |
15561 | + | |
15562 | hctx->response = buffer_init(); | |
15563 | hctx->response_header = buffer_init(); | |
15564 | - | |
15565 | + | |
15566 | return hctx; | |
15567 | } | |
15568 | ||
15569 | static void cgi_handler_ctx_free(handler_ctx *hctx) { | |
15570 | buffer_free(hctx->response); | |
15571 | buffer_free(hctx->response_header); | |
15572 | - | |
15573 | + | |
15574 | free(hctx); | |
15575 | } | |
15576 | ||
15577 | @@ -101,14 +96,14 @@ | |
15578 | ||
15579 | INIT_FUNC(mod_cgi_init) { | |
15580 | plugin_data *p; | |
15581 | - | |
15582 | + | |
15583 | p = calloc(1, sizeof(*p)); | |
15584 | ||
15585 | assert(p); | |
15586 | - | |
15587 | + | |
15588 | p->tmp_buf = buffer_init(); | |
15589 | p->parse_response = buffer_init(); | |
15590 | - | |
15591 | + | |
15592 | return p; | |
15593 | } | |
15594 | ||
15595 | @@ -116,62 +111,62 @@ | |
15596 | FREE_FUNC(mod_cgi_free) { | |
15597 | plugin_data *p = p_d; | |
15598 | buffer_pid_t *r = &(p->cgi_pid); | |
15599 | - | |
15600 | + | |
15601 | UNUSED(srv); | |
15602 | - | |
15603 | + | |
15604 | if (p->config_storage) { | |
15605 | size_t i; | |
15606 | for (i = 0; i < srv->config_context->used; i++) { | |
15607 | plugin_config *s = p->config_storage[i]; | |
15608 | - | |
15609 | + | |
15610 | array_free(s->cgi); | |
15611 | - | |
15612 | + | |
15613 | free(s); | |
15614 | } | |
15615 | free(p->config_storage); | |
15616 | } | |
15617 | - | |
15618 | + | |
15619 | ||
15620 | if (r->ptr) free(r->ptr); | |
15621 | - | |
15622 | + | |
15623 | buffer_free(p->tmp_buf); | |
15624 | buffer_free(p->parse_response); | |
15625 | - | |
15626 | + | |
15627 | free(p); | |
15628 | - | |
15629 | + | |
15630 | return HANDLER_GO_ON; | |
15631 | } | |
15632 | ||
15633 | SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) { | |
15634 | plugin_data *p = p_d; | |
15635 | size_t i = 0; | |
15636 | - | |
15637 | - config_values_t cv[] = { | |
15638 | + | |
15639 | + config_values_t cv[] = { | |
15640 | { "cgi.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
15641 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET} | |
15642 | }; | |
15643 | ||
15644 | if (!p) return HANDLER_ERROR; | |
15645 | - | |
15646 | + | |
15647 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
15648 | - | |
15649 | + | |
15650 | for (i = 0; i < srv->config_context->used; i++) { | |
15651 | plugin_config *s; | |
15652 | - | |
15653 | + | |
15654 | s = calloc(1, sizeof(plugin_config)); | |
15655 | assert(s); | |
15656 | - | |
15657 | + | |
15658 | s->cgi = array_init(); | |
15659 | - | |
15660 | + | |
15661 | cv[0].destination = s->cgi; | |
15662 | - | |
15663 | + | |
15664 | p->config_storage[i] = s; | |
15665 | - | |
15666 | + | |
15667 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
15668 | return HANDLER_ERROR; | |
15669 | } | |
15670 | } | |
15671 | - | |
15672 | + | |
15673 | return HANDLER_GO_ON; | |
15674 | } | |
15675 | ||
15676 | @@ -180,13 +175,13 @@ | |
15677 | int m = -1; | |
15678 | size_t i; | |
15679 | buffer_pid_t *r = &(p->cgi_pid); | |
15680 | - | |
15681 | + | |
15682 | UNUSED(srv); | |
15683 | ||
15684 | for (i = 0; i < r->used; i++) { | |
15685 | if (r->ptr[i] > m) m = r->ptr[i]; | |
15686 | } | |
15687 | - | |
15688 | + | |
15689 | if (r->size == 0) { | |
15690 | r->size = 16; | |
15691 | r->ptr = malloc(sizeof(*r->ptr) * r->size); | |
15692 | @@ -194,31 +189,31 @@ | |
15693 | r->size += 16; | |
15694 | r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size); | |
15695 | } | |
15696 | - | |
15697 | + | |
15698 | r->ptr[r->used++] = pid; | |
15699 | - | |
15700 | + | |
15701 | return m; | |
15702 | } | |
15703 | ||
15704 | static int cgi_pid_del(server *srv, plugin_data *p, pid_t pid) { | |
15705 | size_t i; | |
15706 | buffer_pid_t *r = &(p->cgi_pid); | |
15707 | - | |
15708 | + | |
15709 | UNUSED(srv); | |
15710 | ||
15711 | for (i = 0; i < r->used; i++) { | |
15712 | if (r->ptr[i] == pid) break; | |
15713 | } | |
15714 | - | |
15715 | + | |
15716 | if (i != r->used) { | |
15717 | /* found */ | |
15718 | - | |
15719 | + | |
15720 | if (i != r->used - 1) { | |
15721 | r->ptr[i] = r->ptr[r->used - 1]; | |
15722 | } | |
15723 | r->used--; | |
15724 | } | |
15725 | - | |
15726 | + | |
15727 | return 0; | |
15728 | } | |
15729 | ||
15730 | @@ -226,32 +221,32 @@ | |
15731 | char *ns; | |
15732 | const char *s; | |
15733 | int line = 0; | |
15734 | - | |
15735 | + | |
15736 | UNUSED(srv); | |
15737 | - | |
15738 | + | |
15739 | buffer_copy_string_buffer(p->parse_response, in); | |
15740 | - | |
15741 | - for (s = p->parse_response->ptr; | |
15742 | - NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); | |
15743 | + | |
15744 | + for (s = p->parse_response->ptr; | |
15745 | + NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); | |
15746 | s = ns + (eol == EOL_RN ? 2 : 1), line++) { | |
15747 | const char *key, *value; | |
15748 | int key_len; | |
15749 | data_string *ds; | |
15750 | - | |
15751 | + | |
15752 | ns[0] = '\0'; | |
15753 | - | |
15754 | - if (line == 0 && | |
15755 | + | |
15756 | + if (line == 0 && | |
15757 | 0 == strncmp(s, "HTTP/1.", 7)) { | |
15758 | /* non-parsed header ... we parse them anyway */ | |
15759 | - | |
15760 | + | |
15761 | if ((s[7] == '1' || | |
15762 | s[7] == '0') && | |
15763 | s[8] == ' ') { | |
15764 | int status; | |
15765 | /* after the space should be a status code for us */ | |
15766 | - | |
15767 | + | |
15768 | status = strtol(s+9, NULL, 10); | |
15769 | - | |
15770 | + | |
15771 | if (con->http_status >= 100 && | |
15772 | con->http_status < 1000) { | |
15773 | /* we expected 3 digits and didn't got them */ | |
15774 | @@ -260,27 +255,27 @@ | |
15775 | } | |
15776 | } | |
15777 | } else { | |
15778 | - | |
15779 | + | |
15780 | key = s; | |
15781 | if (NULL == (value = strchr(s, ':'))) { | |
15782 | /* we expect: "<key>: <value>\r\n" */ | |
15783 | continue; | |
15784 | } | |
15785 | - | |
15786 | + | |
15787 | key_len = value - key; | |
15788 | value += 1; | |
15789 | - | |
15790 | + | |
15791 | /* skip LWS */ | |
15792 | while (*value == ' ' || *value == '\t') value++; | |
15793 | - | |
15794 | + | |
15795 | if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { | |
15796 | ds = data_response_init(); | |
15797 | } | |
15798 | buffer_copy_string_len(ds->key, key, key_len); | |
15799 | buffer_copy_string(ds->value, value); | |
15800 | - | |
15801 | + | |
15802 | array_insert_unique(con->response.headers, (data_unset *)ds); | |
15803 | - | |
15804 | + | |
15805 | switch(key_len) { | |
15806 | case 4: | |
15807 | if (0 == strncasecmp(key, "Date", key_len)) { | |
15808 | @@ -315,13 +310,13 @@ | |
15809 | } | |
15810 | } | |
15811 | } | |
15812 | - | |
15813 | + | |
15814 | /* CGI/1.1 rev 03 - 7.2.1.2 */ | |
15815 | if ((con->parsed_response & HTTP_LOCATION) && | |
15816 | !(con->parsed_response & HTTP_STATUS)) { | |
15817 | con->http_status = 302; | |
15818 | } | |
15819 | - | |
15820 | + | |
15821 | return 0; | |
15822 | } | |
15823 | ||
15824 | @@ -329,10 +324,10 @@ | |
15825 | static int cgi_demux_response(server *srv, handler_ctx *hctx) { | |
15826 | plugin_data *p = hctx->plugin_data; | |
15827 | connection *con = hctx->remote_conn; | |
15828 | - | |
15829 | + | |
15830 | while(1) { | |
15831 | int n; | |
15832 | - | |
15833 | + | |
15834 | buffer_prepare_copy(hctx->response, 1024); | |
15835 | if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) { | |
15836 | if (errno == EAGAIN || errno == EINTR) { | |
15837 | @@ -343,125 +338,125 @@ | |
15838 | log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd); | |
15839 | return FDEVENT_HANDLED_ERROR; | |
15840 | } | |
15841 | - | |
15842 | + | |
15843 | if (n == 0) { | |
15844 | /* read finished */ | |
15845 | - | |
15846 | + | |
15847 | con->file_finished = 1; | |
15848 | - | |
15849 | + | |
15850 | /* send final chunk */ | |
15851 | http_chunk_append_mem(srv, con, NULL, 0); | |
15852 | joblist_append(srv, con); | |
15853 | - | |
15854 | + | |
15855 | return FDEVENT_HANDLED_FINISHED; | |
15856 | } | |
15857 | - | |
15858 | + | |
15859 | hctx->response->ptr[n] = '\0'; | |
15860 | hctx->response->used = n+1; | |
15861 | - | |
15862 | + | |
15863 | /* split header from body */ | |
15864 | - | |
15865 | + | |
15866 | if (con->file_started == 0) { | |
15867 | char *c; | |
15868 | int in_header = 0; | |
15869 | int header_end = 0; | |
15870 | int cp, eol = EOL_UNSET; | |
15871 | size_t used = 0; | |
15872 | - | |
15873 | + | |
15874 | buffer_append_string_buffer(hctx->response_header, hctx->response); | |
15875 | - | |
15876 | + | |
15877 | /* nph (non-parsed headers) */ | |
15878 | if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1; | |
15879 | - | |
15880 | + | |
15881 | /* search for the \r\n\r\n or \n\n in the string */ | |
15882 | for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) { | |
15883 | if (*c == ':') in_header = 1; | |
15884 | else if (*c == '\n') { | |
15885 | if (in_header == 0) { | |
15886 | /* got a response without a response header */ | |
15887 | - | |
15888 | + | |
15889 | c = NULL; | |
15890 | header_end = 1; | |
15891 | break; | |
15892 | } | |
15893 | - | |
15894 | + | |
15895 | if (eol == EOL_UNSET) eol = EOL_N; | |
15896 | - | |
15897 | + | |
15898 | if (*(c+1) == '\n') { | |
15899 | header_end = 1; | |
15900 | break; | |
15901 | } | |
15902 | - | |
15903 | + | |
15904 | } else if (used > 1 && *c == '\r' && *(c+1) == '\n') { | |
15905 | if (in_header == 0) { | |
15906 | /* got a response without a response header */ | |
15907 | - | |
15908 | + | |
15909 | c = NULL; | |
15910 | header_end = 1; | |
15911 | break; | |
15912 | } | |
15913 | - | |
15914 | + | |
15915 | if (eol == EOL_UNSET) eol = EOL_RN; | |
15916 | - | |
15917 | + | |
15918 | if (used > 3 && | |
15919 | - *(c+2) == '\r' && | |
15920 | + *(c+2) == '\r' && | |
15921 | *(c+3) == '\n') { | |
15922 | header_end = 1; | |
15923 | break; | |
15924 | } | |
15925 | - | |
15926 | + | |
15927 | /* skip the \n */ | |
15928 | c++; | |
15929 | cp++; | |
15930 | used--; | |
15931 | } | |
15932 | } | |
15933 | - | |
15934 | + | |
15935 | if (header_end) { | |
15936 | if (c == NULL) { | |
15937 | /* no header, but a body */ | |
15938 | - | |
15939 | + | |
15940 | if (con->request.http_version == HTTP_VERSION_1_1) { | |
15941 | con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
15942 | } | |
15943 | - | |
15944 | + | |
15945 | http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used); | |
15946 | joblist_append(srv, con); | |
15947 | } else { | |
15948 | size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2); | |
15949 | size_t blen = hctx->response_header->used - hlen - 1; | |
15950 | - | |
15951 | + | |
15952 | /* a small hack: terminate after at the second \r */ | |
15953 | hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1); | |
15954 | hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0'; | |
15955 | - | |
15956 | + | |
15957 | /* parse the response header */ | |
15958 | cgi_response_parse(srv, con, p, hctx->response_header, eol); | |
15959 | - | |
15960 | + | |
15961 | /* enable chunked-transfer-encoding */ | |
15962 | if (con->request.http_version == HTTP_VERSION_1_1 && | |
15963 | !(con->parsed_response & HTTP_CONTENT_LENGTH)) { | |
15964 | con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
15965 | } | |
15966 | - | |
15967 | + | |
15968 | if ((hctx->response->used != hlen) && blen > 0) { | |
15969 | http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1); | |
15970 | joblist_append(srv, con); | |
15971 | } | |
15972 | } | |
15973 | - | |
15974 | + | |
15975 | con->file_started = 1; | |
15976 | } | |
15977 | } else { | |
15978 | http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used); | |
15979 | joblist_append(srv, con); | |
15980 | } | |
15981 | - | |
15982 | -#if 0 | |
15983 | + | |
15984 | +#if 0 | |
15985 | log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr); | |
15986 | #endif | |
15987 | } | |
15988 | - | |
15989 | + | |
15990 | return FDEVENT_HANDLED_NOT_FINISHED; | |
15991 | } | |
15992 | ||
15993 | @@ -470,45 +465,46 @@ | |
15994 | pid_t pid; | |
15995 | plugin_data *p; | |
15996 | connection *con; | |
15997 | - | |
15998 | + | |
15999 | if (NULL == hctx) return HANDLER_GO_ON; | |
16000 | - | |
16001 | + | |
16002 | p = hctx->plugin_data; | |
16003 | con = hctx->remote_conn; | |
16004 | - | |
16005 | + | |
16006 | if (con->mode != p->id) return HANDLER_GO_ON; | |
16007 | ||
16008 | -#ifndef __WIN32 | |
16009 | - | |
16010 | +#ifndef _WIN32 | |
16011 | + | |
16012 | /* the connection to the browser went away, but we still have a connection | |
16013 | - * to the CGI script | |
16014 | + * to the CGI script | |
16015 | * | |
16016 | * close cgi-connection | |
16017 | */ | |
16018 | - | |
16019 | + | |
16020 | if (hctx->fd != -1) { | |
16021 | /* close connection to the cgi-script */ | |
16022 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
16023 | fdevent_unregister(srv->ev, hctx->fd); | |
16024 | - | |
16025 | + | |
16026 | if (close(hctx->fd)) { | |
16027 | log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno)); | |
16028 | } | |
16029 | - | |
16030 | + | |
16031 | hctx->fd = -1; | |
16032 | hctx->fde_ndx = -1; | |
16033 | } | |
16034 | - | |
16035 | + | |
16036 | pid = hctx->pid; | |
16037 | - | |
16038 | + | |
16039 | con->plugin_ctx[p->id] = NULL; | |
16040 | - | |
16041 | + | |
16042 | /* is this a good idea ? */ | |
16043 | cgi_handler_ctx_free(hctx); | |
16044 | - | |
16045 | + | |
16046 | /* if waitpid hasn't been called by response.c yet, do it here */ | |
16047 | if (pid) { | |
16048 | /* check if the CGI-script is already gone */ | |
16049 | +#ifndef _WIN32 | |
16050 | switch(waitpid(pid, &status, WNOHANG)) { | |
16051 | case 0: | |
16052 | /* not finished yet */ | |
16053 | @@ -519,19 +515,19 @@ | |
16054 | case -1: | |
16055 | /* */ | |
16056 | if (errno == EINTR) break; | |
16057 | - | |
16058 | - /* | |
16059 | - * errno == ECHILD happens if _subrequest catches the process-status before | |
16060 | + | |
16061 | + /* | |
16062 | + * errno == ECHILD happens if _subrequest catches the process-status before | |
16063 | * we have read the response of the cgi process | |
16064 | - * | |
16065 | + * | |
16066 | * -> catch status | |
16067 | * -> WAIT_FOR_EVENT | |
16068 | * -> read response | |
16069 | * -> we get here with waitpid == ECHILD | |
16070 | - * | |
16071 | + * | |
16072 | */ | |
16073 | if (errno == ECHILD) return HANDLER_GO_ON; | |
16074 | - | |
16075 | + | |
16076 | log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno)); | |
16077 | return HANDLER_ERROR; | |
16078 | default: | |
16079 | @@ -541,13 +537,13 @@ | |
16080 | con->http_status = 500; | |
16081 | con->mode = DIRECT; | |
16082 | } | |
16083 | - | |
16084 | + | |
16085 | if (WIFEXITED(status)) { | |
16086 | #if 0 | |
16087 | log_error_write(srv, __FILE__, __LINE__, "sd", "(debug) cgi exited fine, pid:", pid); | |
16088 | #endif | |
16089 | pid = 0; | |
16090 | - | |
16091 | + | |
16092 | return HANDLER_GO_ON; | |
16093 | } else { | |
16094 | log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid); | |
16095 | @@ -555,20 +551,20 @@ | |
16096 | return HANDLER_GO_ON; | |
16097 | } | |
16098 | } | |
16099 | - | |
16100 | - | |
16101 | + | |
16102 | + | |
16103 | kill(pid, SIGTERM); | |
16104 | - | |
16105 | +#endif | |
16106 | /* cgi-script is still alive, queue the PID for removal */ | |
16107 | cgi_pid_add(srv, p, pid); | |
16108 | } | |
16109 | -#endif | |
16110 | +#endif | |
16111 | return HANDLER_GO_ON; | |
16112 | } | |
16113 | ||
16114 | static handler_t cgi_connection_close_callback(server *srv, connection *con, void *p_d) { | |
16115 | plugin_data *p = p_d; | |
16116 | - | |
16117 | + | |
16118 | return cgi_connection_close(srv, con->plugin_ctx[p->id]); | |
16119 | } | |
16120 | ||
16121 | @@ -577,43 +573,43 @@ | |
16122 | server *srv = (server *)s; | |
16123 | handler_ctx *hctx = ctx; | |
16124 | connection *con = hctx->remote_conn; | |
16125 | - | |
16126 | + | |
16127 | joblist_append(srv, con); | |
16128 | - | |
16129 | + | |
16130 | if (hctx->fd == -1) { | |
16131 | log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "invalid cgi-fd"); | |
16132 | - | |
16133 | + | |
16134 | return HANDLER_ERROR; | |
16135 | } | |
16136 | - | |
16137 | + | |
16138 | if (revents & FDEVENT_IN) { | |
16139 | switch (cgi_demux_response(srv, hctx)) { | |
16140 | case FDEVENT_HANDLED_NOT_FINISHED: | |
16141 | break; | |
16142 | case FDEVENT_HANDLED_FINISHED: | |
16143 | /* we are done */ | |
16144 | - | |
16145 | + | |
16146 | #if 0 | |
16147 | log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "finished"); | |
16148 | #endif | |
16149 | cgi_connection_close(srv, hctx); | |
16150 | - | |
16151 | - /* if we get a IN|HUP and have read everything don't exec the close twice */ | |
16152 | + | |
16153 | + /* if we get a IN|HUP and have read everything don't exec the close twice */ | |
16154 | return HANDLER_FINISHED; | |
16155 | case FDEVENT_HANDLED_ERROR: | |
16156 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
16157 | con->http_status = 500; | |
16158 | con->mode = DIRECT; | |
16159 | - | |
16160 | + | |
16161 | log_error_write(srv, __FILE__, __LINE__, "s", "demuxer failed: "); | |
16162 | break; | |
16163 | } | |
16164 | } | |
16165 | - | |
16166 | + | |
16167 | if (revents & FDEVENT_OUT) { | |
16168 | /* nothing to do */ | |
16169 | } | |
16170 | - | |
16171 | + | |
16172 | /* perhaps this issue is already handled */ | |
16173 | if (revents & FDEVENT_HUP) { | |
16174 | /* check if we still have a unfinished header package which is a body in reality */ | |
16175 | @@ -623,54 +619,54 @@ | |
16176 | http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used); | |
16177 | joblist_append(srv, con); | |
16178 | } | |
16179 | - | |
16180 | + | |
16181 | if (con->file_finished == 0) { | |
16182 | http_chunk_append_mem(srv, con, NULL, 0); | |
16183 | joblist_append(srv, con); | |
16184 | } | |
16185 | - | |
16186 | + | |
16187 | con->file_finished = 1; | |
16188 | - | |
16189 | + | |
16190 | if (chunkqueue_is_empty(con->write_queue)) { | |
16191 | /* there is nothing left to write */ | |
16192 | connection_set_state(srv, con, CON_STATE_RESPONSE_END); | |
16193 | } else { | |
16194 | /* used the write-handler to finish the request on demand */ | |
16195 | - | |
16196 | + | |
16197 | } | |
16198 | - | |
16199 | + | |
16200 | # if 0 | |
16201 | log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents); | |
16202 | # endif | |
16203 | - | |
16204 | + | |
16205 | /* rtsigs didn't liked the close */ | |
16206 | cgi_connection_close(srv, hctx); | |
16207 | } else if (revents & FDEVENT_ERR) { | |
16208 | con->file_finished = 1; | |
16209 | - | |
16210 | + | |
16211 | /* kill all connections to the cgi process */ | |
16212 | cgi_connection_close(srv, hctx); | |
16213 | #if 1 | |
16214 | log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR"); | |
16215 | -#endif | |
16216 | +#endif | |
16217 | return HANDLER_ERROR; | |
16218 | } | |
16219 | - | |
16220 | + | |
16221 | return HANDLER_FINISHED; | |
16222 | } | |
16223 | ||
16224 | ||
16225 | static int cgi_env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) { | |
16226 | char *dst; | |
16227 | - | |
16228 | + | |
16229 | if (!key || !val) return -1; | |
16230 | - | |
16231 | + | |
16232 | dst = malloc(key_len + val_len + 3); | |
16233 | memcpy(dst, key, key_len); | |
16234 | dst[key_len] = '='; | |
16235 | /* add the \0 from the value */ | |
16236 | memcpy(dst + key_len + 1, val, val_len + 1); | |
16237 | - | |
16238 | + | |
16239 | if (env->size == 0) { | |
16240 | env->size = 16; | |
16241 | env->ptr = malloc(env->size * sizeof(*env->ptr)); | |
16242 | @@ -678,45 +674,45 @@ | |
16243 | env->size += 16; | |
16244 | env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr)); | |
16245 | } | |
16246 | - | |
16247 | + | |
16248 | env->ptr[env->used++] = dst; | |
16249 | - | |
16250 | + | |
16251 | return 0; | |
16252 | } | |
16253 | ||
16254 | static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *cgi_handler) { | |
16255 | pid_t pid; | |
16256 | - | |
16257 | + | |
16258 | #ifdef HAVE_IPV6 | |
16259 | char b2[INET6_ADDRSTRLEN + 1]; | |
16260 | #endif | |
16261 | - | |
16262 | + | |
16263 | int to_cgi_fds[2]; | |
16264 | int from_cgi_fds[2]; | |
16265 | struct stat st; | |
16266 | - | |
16267 | -#ifndef __WIN32 | |
16268 | - | |
16269 | + | |
16270 | +#ifndef _WIN32 | |
16271 | + | |
16272 | if (cgi_handler->used > 1) { | |
16273 | /* stat the exec file */ | |
16274 | if (-1 == (stat(cgi_handler->ptr, &st))) { | |
16275 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
16276 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
16277 | "stat for cgi-handler", cgi_handler, | |
16278 | "failed:", strerror(errno)); | |
16279 | return -1; | |
16280 | } | |
16281 | } | |
16282 | - | |
16283 | + | |
16284 | if (pipe(to_cgi_fds)) { | |
16285 | log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno)); | |
16286 | return -1; | |
16287 | } | |
16288 | - | |
16289 | + | |
16290 | if (pipe(from_cgi_fds)) { | |
16291 | log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno)); | |
16292 | return -1; | |
16293 | } | |
16294 | - | |
16295 | + | |
16296 | /* fork, execve */ | |
16297 | switch (pid = fork()) { | |
16298 | case 0: { | |
16299 | @@ -730,22 +726,22 @@ | |
16300 | char *c; | |
16301 | const char *s; | |
16302 | server_socket *srv_sock = con->srv_socket; | |
16303 | - | |
16304 | + | |
16305 | /* move stdout to from_cgi_fd[1] */ | |
16306 | close(STDOUT_FILENO); | |
16307 | dup2(from_cgi_fds[1], STDOUT_FILENO); | |
16308 | close(from_cgi_fds[1]); | |
16309 | /* not needed */ | |
16310 | close(from_cgi_fds[0]); | |
16311 | - | |
16312 | + | |
16313 | /* move the stdin to to_cgi_fd[0] */ | |
16314 | close(STDIN_FILENO); | |
16315 | dup2(to_cgi_fds[0], STDIN_FILENO); | |
16316 | close(to_cgi_fds[0]); | |
16317 | /* not needed */ | |
16318 | close(to_cgi_fds[1]); | |
16319 | - | |
16320 | - /* HACK: | |
16321 | + | |
16322 | + /* HACK: | |
16323 | * this is not nice, but it works | |
16324 | * | |
16325 | * we feed the stderr of the CGI to our errorlog, if possible | |
16326 | @@ -754,20 +750,20 @@ | |
16327 | close(STDERR_FILENO); | |
16328 | dup2(srv->errorlog_fd, STDERR_FILENO); | |
16329 | } | |
16330 | - | |
16331 | + | |
16332 | /* create environment */ | |
16333 | env.ptr = NULL; | |
16334 | env.size = 0; | |
16335 | env.used = 0; | |
16336 | - | |
16337 | + | |
16338 | cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION)); | |
16339 | ||
16340 | if (!buffer_is_empty(con->server_name)) { | |
16341 | cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name)); | |
16342 | } else { | |
16343 | #ifdef HAVE_IPV6 | |
16344 | - s = inet_ntop(srv_sock->addr.plain.sa_family, | |
16345 | - srv_sock->addr.plain.sa_family == AF_INET6 ? | |
16346 | + s = inet_ntop(srv_sock->addr.plain.sa_family, | |
16347 | + srv_sock->addr.plain.sa_family == AF_INET6 ? | |
16348 | (const void *) &(srv_sock->addr.ipv6.sin6_addr) : | |
16349 | (const void *) &(srv_sock->addr.ipv4.sin_addr), | |
16350 | b2, sizeof(b2)-1); | |
16351 | @@ -779,10 +775,10 @@ | |
16352 | cgi_env_add(&env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")); | |
16353 | ||
16354 | s = get_http_version_name(con->request.http_version); | |
16355 | - | |
16356 | + | |
16357 | cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s)); | |
16358 | - | |
16359 | - ltostr(buf, | |
16360 | + | |
16361 | + ltostr(buf, | |
16362 | #ifdef HAVE_IPV6 | |
16363 | ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port) | |
16364 | #else | |
16365 | @@ -790,10 +786,10 @@ | |
16366 | #endif | |
16367 | ); | |
16368 | cgi_env_add(&env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf)); | |
16369 | - | |
16370 | + | |
16371 | #ifdef HAVE_IPV6 | |
16372 | - s = inet_ntop(srv_sock->addr.plain.sa_family, | |
16373 | - srv_sock->addr.plain.sa_family == AF_INET6 ? | |
16374 | + s = inet_ntop(srv_sock->addr.plain.sa_family, | |
16375 | + srv_sock->addr.plain.sa_family == AF_INET6 ? | |
16376 | (const void *) &(srv_sock->addr.ipv6.sin6_addr) : | |
16377 | (const void *) &(srv_sock->addr.ipv4.sin_addr), | |
16378 | b2, sizeof(b2)-1); | |
16379 | @@ -811,15 +807,18 @@ | |
16380 | cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); | |
16381 | if (!buffer_is_empty(con->uri.query)) { | |
16382 | cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query)); | |
16383 | + } else { | |
16384 | + /* set a empty QUERY_STRING */ | |
16385 | + cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN("")); | |
16386 | } | |
16387 | if (!buffer_is_empty(con->request.orig_uri)) { | |
16388 | cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)); | |
16389 | } | |
16390 | - | |
16391 | - | |
16392 | + | |
16393 | + | |
16394 | #ifdef HAVE_IPV6 | |
16395 | - s = inet_ntop(con->dst_addr.plain.sa_family, | |
16396 | - con->dst_addr.plain.sa_family == AF_INET6 ? | |
16397 | + s = inet_ntop(con->dst_addr.plain.sa_family, | |
16398 | + con->dst_addr.plain.sa_family == AF_INET6 ? | |
16399 | (const void *) &(con->dst_addr.ipv6.sin6_addr) : | |
16400 | (const void *) &(con->dst_addr.ipv4.sin_addr), | |
16401 | b2, sizeof(b2)-1); | |
16402 | @@ -828,7 +827,7 @@ | |
16403 | #endif | |
16404 | cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s)); | |
16405 | ||
16406 | - ltostr(buf, | |
16407 | + ltostr(buf, | |
16408 | #ifdef HAVE_IPV6 | |
16409 | ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port) | |
16410 | #else | |
16411 | @@ -836,19 +835,19 @@ | |
16412 | #endif | |
16413 | ); | |
16414 | cgi_env_add(&env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf)); | |
16415 | - | |
16416 | + | |
16417 | if (!buffer_is_empty(con->authed_user)) { | |
16418 | cgi_env_add(&env, CONST_STR_LEN("REMOTE_USER"), | |
16419 | CONST_BUF_LEN(con->authed_user)); | |
16420 | } | |
16421 | - | |
16422 | + | |
16423 | /* request.content_length < SSIZE_MAX, see request.c */ | |
16424 | ltostr(buf, con->request.content_length); | |
16425 | cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)); | |
16426 | cgi_env_add(&env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path)); | |
16427 | cgi_env_add(&env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)); | |
16428 | cgi_env_add(&env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root)); | |
16429 | - | |
16430 | + | |
16431 | /* for valgrind */ | |
16432 | if (NULL != (s = getenv("LD_PRELOAD"))) { | |
16433 | cgi_env_add(&env, CONST_STR_LEN("LD_PRELOAD"), s, strlen(s)); | |
16434 | @@ -863,24 +862,24 @@ | |
16435 | cgi_env_add(&env, CONST_STR_LEN("SYSTEMROOT"), s, strlen(s)); | |
16436 | } | |
16437 | #endif | |
16438 | - | |
16439 | + | |
16440 | for (n = 0; n < con->request.headers->used; n++) { | |
16441 | data_string *ds; | |
16442 | - | |
16443 | + | |
16444 | ds = (data_string *)con->request.headers->data[n]; | |
16445 | - | |
16446 | + | |
16447 | if (ds->value->used && ds->key->used) { | |
16448 | size_t j; | |
16449 | - | |
16450 | + | |
16451 | buffer_reset(p->tmp_buf); | |
16452 | - | |
16453 | + | |
16454 | if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { | |
16455 | buffer_copy_string(p->tmp_buf, "HTTP_"); | |
16456 | p->tmp_buf->used--; /* strip \0 after HTTP_ */ | |
16457 | } | |
16458 | - | |
16459 | + | |
16460 | buffer_prepare_append(p->tmp_buf, ds->key->used + 2); | |
16461 | - | |
16462 | + | |
16463 | for (j = 0; j < ds->key->used - 1; j++) { | |
16464 | char cr = '_'; | |
16465 | if (light_isalpha(ds->key->ptr[j])) { | |
16466 | @@ -893,46 +892,46 @@ | |
16467 | p->tmp_buf->ptr[p->tmp_buf->used++] = cr; | |
16468 | } | |
16469 | p->tmp_buf->ptr[p->tmp_buf->used++] = '\0'; | |
16470 | - | |
16471 | + | |
16472 | cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value)); | |
16473 | } | |
16474 | } | |
16475 | - | |
16476 | + | |
16477 | for (n = 0; n < con->environment->used; n++) { | |
16478 | data_string *ds; | |
16479 | - | |
16480 | + | |
16481 | ds = (data_string *)con->environment->data[n]; | |
16482 | - | |
16483 | + | |
16484 | if (ds->value->used && ds->key->used) { | |
16485 | size_t j; | |
16486 | - | |
16487 | + | |
16488 | buffer_reset(p->tmp_buf); | |
16489 | - | |
16490 | + | |
16491 | buffer_prepare_append(p->tmp_buf, ds->key->used + 2); | |
16492 | - | |
16493 | + | |
16494 | for (j = 0; j < ds->key->used - 1; j++) { | |
16495 | - p->tmp_buf->ptr[p->tmp_buf->used++] = | |
16496 | - isalpha((unsigned char)ds->key->ptr[j]) ? | |
16497 | + p->tmp_buf->ptr[p->tmp_buf->used++] = | |
16498 | + isalpha((unsigned char)ds->key->ptr[j]) ? | |
16499 | toupper((unsigned char)ds->key->ptr[j]) : '_'; | |
16500 | } | |
16501 | p->tmp_buf->ptr[p->tmp_buf->used++] = '\0'; | |
16502 | - | |
16503 | + | |
16504 | cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value)); | |
16505 | } | |
16506 | } | |
16507 | - | |
16508 | + | |
16509 | if (env.size == env.used) { | |
16510 | env.size += 16; | |
16511 | env.ptr = realloc(env.ptr, env.size * sizeof(*env.ptr)); | |
16512 | } | |
16513 | - | |
16514 | + | |
16515 | env.ptr[env.used] = NULL; | |
16516 | - | |
16517 | + | |
16518 | /* set up args */ | |
16519 | argc = 3; | |
16520 | args = malloc(sizeof(*args) * argc); | |
16521 | i = 0; | |
16522 | - | |
16523 | + | |
16524 | if (cgi_handler->used > 1) { | |
16525 | args[i++] = cgi_handler->ptr; | |
16526 | } | |
16527 | @@ -942,7 +941,7 @@ | |
16528 | /* search for the last / */ | |
16529 | if (NULL != (c = strrchr(con->physical.path->ptr, '/'))) { | |
16530 | *c = '\0'; | |
16531 | - | |
16532 | + | |
16533 | /* change to the physical directory */ | |
16534 | if (-1 == chdir(con->physical.path->ptr)) { | |
16535 | log_error_write(srv, __FILE__, __LINE__, "ssb", "chdir failed:", strerror(errno), con->physical.path); | |
16536 | @@ -954,12 +953,12 @@ | |
16537 | for (i = 3; i < 256; i++) { | |
16538 | if (i != srv->errorlog_fd) close(i); | |
16539 | } | |
16540 | - | |
16541 | + | |
16542 | /* exec the cgi */ | |
16543 | execve(args[0], args, env.ptr); | |
16544 | - | |
16545 | + | |
16546 | log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]); | |
16547 | - | |
16548 | + | |
16549 | /* */ | |
16550 | SEGFAULT(); | |
16551 | break; | |
16552 | @@ -974,11 +973,11 @@ | |
16553 | ||
16554 | close(from_cgi_fds[1]); | |
16555 | close(to_cgi_fds[0]); | |
16556 | - | |
16557 | + | |
16558 | if (con->request.content_length) { | |
16559 | chunkqueue *cq = con->request_content_queue; | |
16560 | chunk *c; | |
16561 | - | |
16562 | + | |
16563 | assert(chunkqueue_length(cq) == (off_t)con->request.content_length); | |
16564 | ||
16565 | /* there is content to send */ | |
16566 | @@ -993,16 +992,16 @@ | |
16567 | if (-1 == c->file.fd && /* open the file if not already open */ | |
16568 | -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { | |
16569 | log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
16570 | - | |
16571 | + | |
16572 | close(from_cgi_fds[0]); | |
16573 | close(to_cgi_fds[1]); | |
16574 | return -1; | |
16575 | } | |
16576 | ||
16577 | c->file.mmap.length = c->file.length; | |
16578 | - | |
16579 | + | |
16580 | if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.mmap.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) { | |
16581 | - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", | |
16582 | + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", | |
16583 | strerror(errno), c->file.name, c->file.fd); | |
16584 | ||
16585 | close(from_cgi_fds[0]); | |
16586 | @@ -1012,7 +1011,7 @@ | |
16587 | ||
16588 | close(c->file.fd); | |
16589 | c->file.fd = -1; | |
16590 | - | |
16591 | + | |
16592 | /* chunk_reset() or chunk_free() will cleanup for us */ | |
16593 | } | |
16594 | ||
16595 | @@ -1020,7 +1019,7 @@ | |
16596 | switch(errno) { | |
16597 | case ENOSPC: | |
16598 | con->http_status = 507; | |
16599 | - | |
16600 | + | |
16601 | break; | |
16602 | default: | |
16603 | con->http_status = 403; | |
16604 | @@ -1033,7 +1032,7 @@ | |
16605 | switch(errno) { | |
16606 | case ENOSPC: | |
16607 | con->http_status = 507; | |
16608 | - | |
16609 | + | |
16610 | break; | |
16611 | default: | |
16612 | con->http_status = 403; | |
16613 | @@ -1056,103 +1055,100 @@ | |
16614 | } | |
16615 | ||
16616 | close(to_cgi_fds[1]); | |
16617 | - | |
16618 | + | |
16619 | /* register PID and wait for them asyncronously */ | |
16620 | con->mode = p->id; | |
16621 | buffer_reset(con->physical.path); | |
16622 | - | |
16623 | + | |
16624 | hctx = cgi_handler_ctx_init(); | |
16625 | - | |
16626 | + | |
16627 | hctx->remote_conn = con; | |
16628 | hctx->plugin_data = p; | |
16629 | hctx->pid = pid; | |
16630 | hctx->fd = from_cgi_fds[0]; | |
16631 | hctx->fde_ndx = -1; | |
16632 | - | |
16633 | + | |
16634 | con->plugin_ctx[p->id] = hctx; | |
16635 | - | |
16636 | + | |
16637 | fdevent_register(srv->ev, hctx->fd, cgi_handle_fdevent, hctx); | |
16638 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN); | |
16639 | - | |
16640 | + | |
16641 | if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) { | |
16642 | log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno)); | |
16643 | - | |
16644 | + | |
16645 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
16646 | fdevent_unregister(srv->ev, hctx->fd); | |
16647 | - | |
16648 | + | |
16649 | log_error_write(srv, __FILE__, __LINE__, "sd", "cgi close:", hctx->fd); | |
16650 | - | |
16651 | + | |
16652 | close(hctx->fd); | |
16653 | - | |
16654 | + | |
16655 | cgi_handler_ctx_free(hctx); | |
16656 | - | |
16657 | + | |
16658 | con->plugin_ctx[p->id] = NULL; | |
16659 | - | |
16660 | + | |
16661 | return -1; | |
16662 | } | |
16663 | - | |
16664 | + | |
16665 | break; | |
16666 | } | |
16667 | } | |
16668 | - | |
16669 | + | |
16670 | return 0; | |
16671 | #else | |
16672 | return -1; | |
16673 | #endif | |
16674 | } | |
16675 | ||
16676 | -#define PATCH(x) \ | |
16677 | - p->conf.x = s->x; | |
16678 | static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p) { | |
16679 | size_t i, j; | |
16680 | plugin_config *s = p->config_storage[0]; | |
16681 | - | |
16682 | - PATCH(cgi); | |
16683 | - | |
16684 | + | |
16685 | + PATCH_OPTION(cgi); | |
16686 | + | |
16687 | /* skip the first, the global context */ | |
16688 | for (i = 1; i < srv->config_context->used; i++) { | |
16689 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
16690 | s = p->config_storage[i]; | |
16691 | - | |
16692 | + | |
16693 | /* condition didn't match */ | |
16694 | if (!config_check_cond(srv, con, dc)) continue; | |
16695 | - | |
16696 | + | |
16697 | /* merge config */ | |
16698 | for (j = 0; j < dc->value->used; j++) { | |
16699 | data_unset *du = dc->value->data[j]; | |
16700 | - | |
16701 | + | |
16702 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.assign"))) { | |
16703 | - PATCH(cgi); | |
16704 | + PATCH_OPTION(cgi); | |
16705 | } | |
16706 | } | |
16707 | } | |
16708 | - | |
16709 | + | |
16710 | return 0; | |
16711 | } | |
16712 | -#undef PATCH | |
16713 | ||
16714 | URIHANDLER_FUNC(cgi_is_handled) { | |
16715 | size_t k, s_len; | |
16716 | plugin_data *p = p_d; | |
16717 | buffer *fn = con->physical.path; | |
16718 | - | |
16719 | + | |
16720 | if (fn->used == 0) return HANDLER_GO_ON; | |
16721 | - | |
16722 | + | |
16723 | mod_cgi_patch_connection(srv, con, p); | |
16724 | - | |
16725 | + | |
16726 | s_len = fn->used - 1; | |
16727 | - | |
16728 | + | |
16729 | for (k = 0; k < p->conf.cgi->used; k++) { | |
16730 | data_string *ds = (data_string *)p->conf.cgi->data[k]; | |
16731 | size_t ct_len = ds->key->used - 1; | |
16732 | - | |
16733 | + | |
16734 | if (ds->key->used == 0) continue; | |
16735 | if (s_len < ct_len) continue; | |
16736 | - | |
16737 | + | |
16738 | if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) { | |
16739 | if (cgi_create_env(srv, con, p, ds->value)) { | |
16740 | con->http_status = 500; | |
16741 | - | |
16742 | + | |
16743 | buffer_reset(con->physical.path); | |
16744 | return HANDLER_FINISHED; | |
16745 | } | |
16746 | @@ -1160,7 +1156,7 @@ | |
16747 | break; | |
16748 | } | |
16749 | } | |
16750 | - | |
16751 | + | |
16752 | return HANDLER_GO_ON; | |
16753 | } | |
16754 | ||
16755 | @@ -1168,11 +1164,11 @@ | |
16756 | plugin_data *p = p_d; | |
16757 | size_t ndx; | |
16758 | /* the trigger handle only cares about lonely PID which we have to wait for */ | |
16759 | -#ifndef __WIN32 | |
16760 | +#ifndef _WIN32 | |
16761 | ||
16762 | for (ndx = 0; ndx < p->cgi_pid.used; ndx++) { | |
16763 | int status; | |
16764 | - | |
16765 | + | |
16766 | switch(waitpid(p->cgi_pid.ptr[ndx], &status, WNOHANG)) { | |
16767 | case 0: | |
16768 | /* not finished yet */ | |
16769 | @@ -1182,7 +1178,7 @@ | |
16770 | break; | |
16771 | case -1: | |
16772 | log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno)); | |
16773 | - | |
16774 | + | |
16775 | return HANDLER_ERROR; | |
16776 | default: | |
16777 | ||
16778 | @@ -1193,16 +1189,16 @@ | |
16779 | } else { | |
16780 | log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?"); | |
16781 | } | |
16782 | - | |
16783 | + | |
16784 | cgi_pid_del(srv, p, p->cgi_pid.ptr[ndx]); | |
16785 | - /* del modified the buffer structure | |
16786 | + /* del modified the buffer structure | |
16787 | * and copies the last entry to the current one | |
16788 | * -> recheck the current index | |
16789 | */ | |
16790 | ndx--; | |
16791 | } | |
16792 | } | |
16793 | -#endif | |
16794 | +#endif | |
16795 | return HANDLER_GO_ON; | |
16796 | } | |
16797 | ||
16798 | @@ -1210,15 +1206,15 @@ | |
16799 | int status; | |
16800 | plugin_data *p = p_d; | |
16801 | handler_ctx *hctx = con->plugin_ctx[p->id]; | |
16802 | - | |
16803 | + | |
16804 | if (con->mode != p->id) return HANDLER_GO_ON; | |
16805 | if (NULL == hctx) return HANDLER_GO_ON; | |
16806 | - | |
16807 | + | |
16808 | #if 0 | |
16809 | log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid); | |
16810 | -#endif | |
16811 | +#endif | |
16812 | if (hctx->pid == 0) return HANDLER_FINISHED; | |
16813 | -#ifndef __WIN32 | |
16814 | +#ifndef _WIN32 | |
16815 | switch(waitpid(hctx->pid, &status, WNOHANG)) { | |
16816 | case 0: | |
16817 | /* we only have for events here if we don't have the header yet, | |
16818 | @@ -1228,61 +1224,61 @@ | |
16819 | return HANDLER_WAIT_FOR_EVENT; | |
16820 | case -1: | |
16821 | if (errno == EINTR) return HANDLER_WAIT_FOR_EVENT; | |
16822 | - | |
16823 | + | |
16824 | if (errno == ECHILD && con->file_started == 0) { | |
16825 | /* | |
16826 | - * second round but still not response | |
16827 | + * second round but still not response | |
16828 | */ | |
16829 | - return HANDLER_WAIT_FOR_EVENT; | |
16830 | + return HANDLER_WAIT_FOR_EVENT; | |
16831 | } | |
16832 | - | |
16833 | + | |
16834 | log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno)); | |
16835 | con->mode = DIRECT; | |
16836 | con->http_status = 500; | |
16837 | - | |
16838 | + | |
16839 | hctx->pid = 0; | |
16840 | - | |
16841 | + | |
16842 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
16843 | fdevent_unregister(srv->ev, hctx->fd); | |
16844 | - | |
16845 | + | |
16846 | if (close(hctx->fd)) { | |
16847 | log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno)); | |
16848 | } | |
16849 | - | |
16850 | + | |
16851 | cgi_handler_ctx_free(hctx); | |
16852 | - | |
16853 | + | |
16854 | con->plugin_ctx[p->id] = NULL; | |
16855 | - | |
16856 | + | |
16857 | return HANDLER_FINISHED; | |
16858 | default: | |
16859 | - /* cgi process exited cleanly | |
16860 | - * | |
16861 | - * check if we already got the response | |
16862 | + /* cgi process exited cleanly | |
16863 | + * | |
16864 | + * check if we already got the response | |
16865 | */ | |
16866 | - | |
16867 | + | |
16868 | if (!con->file_started) return HANDLER_WAIT_FOR_EVENT; | |
16869 | - | |
16870 | + | |
16871 | if (WIFEXITED(status)) { | |
16872 | /* nothing */ | |
16873 | } else { | |
16874 | log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?"); | |
16875 | - | |
16876 | + | |
16877 | con->mode = DIRECT; | |
16878 | con->http_status = 500; | |
16879 | - | |
16880 | + | |
16881 | } | |
16882 | - | |
16883 | + | |
16884 | hctx->pid = 0; | |
16885 | - | |
16886 | + | |
16887 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
16888 | fdevent_unregister(srv->ev, hctx->fd); | |
16889 | - | |
16890 | + | |
16891 | if (close(hctx->fd)) { | |
16892 | log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno)); | |
16893 | } | |
16894 | - | |
16895 | + | |
16896 | cgi_handler_ctx_free(hctx); | |
16897 | - | |
16898 | + | |
16899 | con->plugin_ctx[p->id] = NULL; | |
16900 | return HANDLER_FINISHED; | |
16901 | } | |
16902 | @@ -1306,8 +1302,8 @@ | |
16903 | p->init = mod_cgi_init; | |
16904 | p->cleanup = mod_cgi_free; | |
16905 | p->set_defaults = mod_fastcgi_set_defaults; | |
16906 | - | |
16907 | + | |
16908 | p->data = NULL; | |
16909 | - | |
16910 | + | |
16911 | return 0; | |
16912 | } | |
1175ccec | 16913 | --- ../lighttpd-1.4.11/src/mod_cml.c 2006-01-30 13:51:48.000000000 +0200 |
36e2a29e | 16914 | +++ lighttpd-1.4.12/src/mod_cml.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
16915 | @@ -4,7 +4,6 @@ |
16916 | #include <stdlib.h> | |
16917 | #include <string.h> | |
16918 | #include <errno.h> | |
16919 | -#include <unistd.h> | |
16920 | #include <stdio.h> | |
16921 | ||
16922 | #include "buffer.h" | |
16923 | @@ -20,50 +19,50 @@ | |
16924 | /* init the plugin data */ | |
16925 | INIT_FUNC(mod_cml_init) { | |
16926 | plugin_data *p; | |
16927 | - | |
16928 | + | |
16929 | p = calloc(1, sizeof(*p)); | |
16930 | - | |
16931 | + | |
16932 | p->basedir = buffer_init(); | |
16933 | p->baseurl = buffer_init(); | |
16934 | p->trigger_handler = buffer_init(); | |
16935 | - | |
16936 | + | |
16937 | return p; | |
16938 | } | |
16939 | ||
16940 | /* detroy the plugin data */ | |
16941 | FREE_FUNC(mod_cml_free) { | |
16942 | plugin_data *p = p_d; | |
16943 | - | |
16944 | + | |
16945 | UNUSED(srv); | |
16946 | ||
16947 | if (!p) return HANDLER_GO_ON; | |
16948 | - | |
16949 | + | |
16950 | if (p->config_storage) { | |
16951 | size_t i; | |
16952 | for (i = 0; i < srv->config_context->used; i++) { | |
16953 | plugin_config *s = p->config_storage[i]; | |
16954 | - | |
16955 | + | |
16956 | buffer_free(s->ext); | |
16957 | - | |
16958 | + | |
16959 | buffer_free(s->mc_namespace); | |
16960 | buffer_free(s->power_magnet); | |
16961 | array_free(s->mc_hosts); | |
16962 | - | |
16963 | + | |
16964 | #if defined(HAVE_MEMCACHE_H) | |
16965 | if (s->mc) mc_free(s->mc); | |
16966 | #endif | |
16967 | - | |
16968 | + | |
16969 | free(s); | |
16970 | } | |
16971 | free(p->config_storage); | |
16972 | } | |
16973 | - | |
16974 | + | |
16975 | buffer_free(p->trigger_handler); | |
16976 | buffer_free(p->basedir); | |
16977 | buffer_free(p->baseurl); | |
16978 | - | |
16979 | + | |
16980 | free(p); | |
16981 | - | |
16982 | + | |
16983 | return HANDLER_GO_ON; | |
16984 | } | |
16985 | ||
16986 | @@ -72,22 +71,22 @@ | |
16987 | SETDEFAULTS_FUNC(mod_cml_set_defaults) { | |
16988 | plugin_data *p = p_d; | |
16989 | size_t i = 0; | |
16990 | - | |
16991 | - config_values_t cv[] = { | |
16992 | + | |
16993 | + config_values_t cv[] = { | |
16994 | { "cml.extension", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
16995 | { "cml.memcache-hosts", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
16996 | { "cml.memcache-namespace", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
16997 | { "cml.power-magnet", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ | |
16998 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
16999 | }; | |
17000 | - | |
17001 | + | |
17002 | if (!p) return HANDLER_ERROR; | |
17003 | - | |
17004 | + | |
17005 | p->config_storage = malloc(srv->config_context->used * sizeof(specific_config *)); | |
17006 | - | |
17007 | + | |
17008 | for (i = 0; i < srv->config_context->used; i++) { | |
17009 | plugin_config *s; | |
17010 | - | |
17011 | + | |
17012 | s = malloc(sizeof(plugin_config)); | |
17013 | s->ext = buffer_init(); | |
17014 | s->mc_hosts = array_init(); | |
17015 | @@ -96,87 +95,84 @@ | |
17016 | #if defined(HAVE_MEMCACHE_H) | |
17017 | s->mc = NULL; | |
17018 | #endif | |
17019 | - | |
17020 | + | |
17021 | cv[0].destination = s->ext; | |
17022 | cv[1].destination = s->mc_hosts; | |
17023 | cv[2].destination = s->mc_namespace; | |
17024 | cv[3].destination = s->power_magnet; | |
17025 | - | |
17026 | + | |
17027 | p->config_storage[i] = s; | |
17028 | - | |
17029 | + | |
17030 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
17031 | return HANDLER_ERROR; | |
17032 | } | |
17033 | - | |
17034 | + | |
17035 | if (s->mc_hosts->used) { | |
17036 | #if defined(HAVE_MEMCACHE_H) | |
17037 | size_t k; | |
17038 | s->mc = mc_new(); | |
17039 | - | |
17040 | + | |
17041 | for (k = 0; k < s->mc_hosts->used; k++) { | |
17042 | data_string *ds = (data_string *)s->mc_hosts->data[k]; | |
17043 | - | |
17044 | + | |
17045 | if (0 != mc_server_add4(s->mc, ds->value->ptr)) { | |
17046 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
17047 | - "connection to host failed:", | |
17048 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
17049 | + "connection to host failed:", | |
17050 | ds->value); | |
17051 | - | |
17052 | + | |
17053 | return HANDLER_ERROR; | |
17054 | } | |
17055 | } | |
17056 | #else | |
17057 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
17058 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
17059 | "memcache support is not compiled in but cml.memcache-hosts is set, aborting"); | |
17060 | return HANDLER_ERROR; | |
17061 | #endif | |
17062 | } | |
17063 | } | |
17064 | - | |
17065 | + | |
17066 | return HANDLER_GO_ON; | |
17067 | } | |
17068 | ||
17069 | -#define PATCH(x) \ | |
17070 | - p->conf.x = s->x; | |
17071 | static int mod_cml_patch_connection(server *srv, connection *con, plugin_data *p) { | |
17072 | size_t i, j; | |
17073 | plugin_config *s = p->config_storage[0]; | |
17074 | - | |
17075 | - PATCH(ext); | |
17076 | + | |
17077 | + PATCH_OPTION(ext); | |
17078 | #if defined(HAVE_MEMCACHE_H) | |
17079 | - PATCH(mc); | |
17080 | + PATCH_OPTION(mc); | |
17081 | #endif | |
17082 | - PATCH(mc_namespace); | |
17083 | - PATCH(power_magnet); | |
17084 | - | |
17085 | + PATCH_OPTION(mc_namespace); | |
17086 | + PATCH_OPTION(power_magnet); | |
17087 | + | |
17088 | /* skip the first, the global context */ | |
17089 | for (i = 1; i < srv->config_context->used; i++) { | |
17090 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
17091 | s = p->config_storage[i]; | |
17092 | - | |
17093 | + | |
17094 | /* condition didn't match */ | |
17095 | if (!config_check_cond(srv, con, dc)) continue; | |
17096 | - | |
17097 | + | |
17098 | /* merge config */ | |
17099 | for (j = 0; j < dc->value->used; j++) { | |
17100 | data_unset *du = dc->value->data[j]; | |
17101 | - | |
17102 | + | |
17103 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.extension"))) { | |
17104 | - PATCH(ext); | |
17105 | + PATCH_OPTION(ext); | |
17106 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-hosts"))) { | |
17107 | #if defined(HAVE_MEMCACHE_H) | |
17108 | - PATCH(mc); | |
17109 | + PATCH_OPTION(mc); | |
17110 | #endif | |
17111 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-namespace"))) { | |
17112 | - PATCH(mc_namespace); | |
17113 | + PATCH_OPTION(mc_namespace); | |
17114 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.power-magnet"))) { | |
17115 | - PATCH(power_magnet); | |
17116 | + PATCH_OPTION(power_magnet); | |
17117 | } | |
17118 | } | |
17119 | } | |
17120 | - | |
17121 | + | |
17122 | return 0; | |
17123 | } | |
17124 | -#undef PATCH | |
17125 | ||
17126 | int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) { | |
17127 | buffer *b; | |
17128 | @@ -187,57 +183,57 @@ | |
17129 | b = p->baseurl; | |
17130 | buffer_copy_string_buffer(b, con->uri.path); | |
17131 | for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--); | |
17132 | - | |
17133 | + | |
17134 | if (*c == '/') { | |
17135 | b->used = c - b->ptr + 2; | |
17136 | *(c+1) = '\0'; | |
17137 | } | |
17138 | - | |
17139 | + | |
17140 | b = p->basedir; | |
17141 | buffer_copy_string_buffer(b, con->physical.path); | |
17142 | for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--); | |
17143 | - | |
17144 | + | |
17145 | if (*c == '/') { | |
17146 | b->used = c - b->ptr + 2; | |
17147 | *(c+1) = '\0'; | |
17148 | } | |
17149 | - | |
17150 | + | |
17151 | ||
17152 | /* prepare variables | |
17153 | * - cookie-based | |
17154 | * - get-param-based | |
17155 | */ | |
17156 | - | |
17157 | + | |
17158 | return cache_parse_lua(srv, con, p, cml_file); | |
17159 | - | |
17160 | + | |
17161 | } | |
17162 | ||
17163 | URIHANDLER_FUNC(mod_cml_power_magnet) { | |
17164 | plugin_data *p = p_d; | |
17165 | - | |
17166 | + | |
17167 | mod_cml_patch_connection(srv, con, p); | |
17168 | - | |
17169 | + | |
17170 | buffer_reset(p->basedir); | |
17171 | buffer_reset(p->baseurl); | |
17172 | buffer_reset(p->trigger_handler); | |
17173 | ||
17174 | if (buffer_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON; | |
17175 | - | |
17176 | - /* | |
17177 | + | |
17178 | + /* | |
17179 | * power-magnet: | |
17180 | * cml.power-magnet = server.docroot + "/rewrite.cml" | |
17181 | * | |
17182 | * is called on EACH request, take the original REQUEST_URI and modifies the | |
17183 | - * request header as neccesary. | |
17184 | + * request header as neccesary. | |
17185 | * | |
17186 | * First use: | |
17187 | * if file_exists("/maintainance.html") { | |
17188 | * output_include = ( "/maintainance.html" ) | |
17189 | - * return CACHE_HIT | |
17190 | + * return CACHE_HIT | |
17191 | * } | |
17192 | * | |
17193 | * as we only want to rewrite HTML like requests we should cover it in a conditional | |
17194 | - * | |
17195 | + * | |
17196 | * */ | |
17197 | ||
17198 | switch(cache_call_lua(srv, con, p, p->conf.power_magnet)) { | |
17199 | @@ -266,20 +262,20 @@ | |
17200 | ||
17201 | URIHANDLER_FUNC(mod_cml_is_handled) { | |
17202 | plugin_data *p = p_d; | |
17203 | - | |
17204 | + | |
17205 | if (buffer_is_empty(con->physical.path)) return HANDLER_ERROR; | |
17206 | - | |
17207 | + | |
17208 | mod_cml_patch_connection(srv, con, p); | |
17209 | - | |
17210 | + | |
17211 | buffer_reset(p->basedir); | |
17212 | buffer_reset(p->baseurl); | |
17213 | buffer_reset(p->trigger_handler); | |
17214 | ||
17215 | if (buffer_is_empty(p->conf.ext)) return HANDLER_GO_ON; | |
17216 | - | |
17217 | + | |
17218 | if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, p->conf.ext->used - 1)) { | |
17219 | return HANDLER_GO_ON; | |
17220 | - } | |
17221 | + } | |
17222 | ||
17223 | switch(cache_call_lua(srv, con, p, con->physical.path)) { | |
17224 | case -1: | |
17225 | @@ -311,15 +307,15 @@ | |
17226 | int mod_cml_plugin_init(plugin *p) { | |
17227 | p->version = LIGHTTPD_VERSION_ID; | |
17228 | p->name = buffer_init_string("cache"); | |
17229 | - | |
17230 | + | |
17231 | p->init = mod_cml_init; | |
17232 | p->cleanup = mod_cml_free; | |
17233 | p->set_defaults = mod_cml_set_defaults; | |
17234 | - | |
17235 | + | |
17236 | p->handle_subrequest_start = mod_cml_is_handled; | |
17237 | p->handle_physical = mod_cml_power_magnet; | |
17238 | - | |
17239 | + | |
17240 | p->data = NULL; | |
17241 | - | |
17242 | + | |
17243 | return 0; | |
17244 | } | |
1175ccec | 17245 | --- ../lighttpd-1.4.11/src/mod_cml.h 2006-01-30 13:51:35.000000000 +0200 |
36e2a29e | 17246 | +++ lighttpd-1.4.12/src/mod_cml.h 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
17247 | @@ -16,10 +16,10 @@ |
17248 | ||
17249 | typedef struct { | |
17250 | buffer *ext; | |
17251 | - | |
17252 | + | |
17253 | array *mc_hosts; | |
17254 | buffer *mc_namespace; | |
17255 | -#if defined(HAVE_MEMCACHE_H) | |
17256 | +#if defined(HAVE_MEMCACHE_H) | |
17257 | struct memcache *mc; | |
17258 | #endif | |
17259 | buffer *power_magnet; | |
17260 | @@ -27,15 +27,15 @@ | |
17261 | ||
17262 | typedef struct { | |
17263 | PLUGIN_DATA; | |
17264 | - | |
17265 | + | |
17266 | buffer *basedir; | |
17267 | buffer *baseurl; | |
17268 | - | |
17269 | + | |
17270 | buffer *trigger_handler; | |
17271 | - | |
17272 | + | |
17273 | plugin_config **config_storage; | |
17274 | - | |
17275 | - plugin_config conf; | |
17276 | + | |
17277 | + plugin_config conf; | |
17278 | } plugin_data; | |
17279 | ||
17280 | int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn); | |
1175ccec | 17281 | --- ../lighttpd-1.4.11/src/mod_cml_funcs.c 2005-11-17 16:15:08.000000000 +0200 |
36e2a29e | 17282 | +++ lighttpd-1.4.12/src/mod_cml_funcs.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
17283 | @@ -4,8 +4,7 @@ |
17284 | #include <stdlib.h> | |
17285 | #include <string.h> | |
17286 | #include <errno.h> | |
17287 | -#include <unistd.h> | |
17288 | -#include <dirent.h> | |
17289 | + | |
17290 | #include <stdio.h> | |
17291 | ||
17292 | #include "buffer.h" | |
17293 | @@ -13,6 +12,7 @@ | |
17294 | #include "log.h" | |
17295 | #include "plugin.h" | |
17296 | #include "response.h" | |
17297 | +#include "sys-files.h" | |
17298 | ||
17299 | #include "mod_cml.h" | |
17300 | #include "mod_cml_funcs.h" | |
17301 | @@ -30,7 +30,7 @@ | |
17302 | #ifdef USE_OPENSSL | |
17303 | #define IN const | |
17304 | #else | |
17305 | -#define IN | |
17306 | +#define IN | |
17307 | #endif | |
17308 | #define OUT | |
17309 | ||
17310 | @@ -42,29 +42,29 @@ | |
17311 | buffer b; | |
17312 | char hex[33]; | |
17313 | int n = lua_gettop(L); | |
17314 | - | |
17315 | + | |
17316 | b.ptr = hex; | |
17317 | b.used = 0; | |
17318 | b.size = sizeof(hex); | |
17319 | - | |
17320 | + | |
17321 | if (n != 1) { | |
17322 | lua_pushstring(L, "md5: expected one argument"); | |
17323 | lua_error(L); | |
17324 | } | |
17325 | - | |
17326 | + | |
17327 | if (!lua_isstring(L, 1)) { | |
17328 | lua_pushstring(L, "md5: argument has to be a string"); | |
17329 | lua_error(L); | |
17330 | } | |
17331 | - | |
17332 | + | |
17333 | MD5_Init(&Md5Ctx); | |
17334 | MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1)); | |
17335 | MD5_Final(HA1, &Md5Ctx); | |
17336 | - | |
17337 | + | |
17338 | buffer_copy_string_hex(&b, (char *)HA1, 16); | |
17339 | - | |
17340 | + | |
17341 | lua_pushstring(L, b.ptr); | |
17342 | - | |
17343 | + | |
17344 | return 1; | |
17345 | } | |
17346 | ||
17347 | @@ -72,37 +72,37 @@ | |
17348 | int f_file_mtime(lua_State *L) { | |
17349 | struct stat st; | |
17350 | int n = lua_gettop(L); | |
17351 | - | |
17352 | + | |
17353 | if (n != 1) { | |
17354 | lua_pushstring(L, "file_mtime: expected one argument"); | |
17355 | lua_error(L); | |
17356 | } | |
17357 | - | |
17358 | + | |
17359 | if (!lua_isstring(L, 1)) { | |
17360 | lua_pushstring(L, "file_mtime: argument has to be a string"); | |
17361 | lua_error(L); | |
17362 | } | |
17363 | - | |
17364 | + | |
17365 | if (-1 == stat(lua_tostring(L, 1), &st)) { | |
17366 | lua_pushnil(L); | |
17367 | return 1; | |
17368 | } | |
17369 | - | |
17370 | + | |
17371 | lua_pushnumber(L, st.st_mtime); | |
17372 | - | |
17373 | + | |
17374 | return 1; | |
17375 | } | |
17376 | - | |
17377 | +#ifndef _WIN32 | |
17378 | int f_dir_files_iter(lua_State *L) { | |
17379 | DIR *d; | |
17380 | struct dirent *de; | |
17381 | - | |
17382 | + | |
17383 | d = lua_touserdata(L, lua_upvalueindex(1)); | |
17384 | - | |
17385 | + | |
17386 | if (NULL == (de = readdir(d))) { | |
17387 | /* EOF */ | |
17388 | closedir(d); | |
17389 | - | |
17390 | + | |
17391 | return 0; | |
17392 | } else { | |
17393 | lua_pushstring(L, de->d_name); | |
17394 | @@ -113,75 +113,75 @@ | |
17395 | int f_dir_files(lua_State *L) { | |
17396 | DIR *d; | |
17397 | int n = lua_gettop(L); | |
17398 | - | |
17399 | + | |
17400 | if (n != 1) { | |
17401 | lua_pushstring(L, "dir_files: expected one argument"); | |
17402 | lua_error(L); | |
17403 | } | |
17404 | - | |
17405 | + | |
17406 | if (!lua_isstring(L, 1)) { | |
17407 | lua_pushstring(L, "dir_files: argument has to be a string"); | |
17408 | lua_error(L); | |
17409 | } | |
17410 | - | |
17411 | - /* check if there is a valid DIR handle on the stack */ | |
17412 | + | |
17413 | + /* check if there is a valid DIR handle on the stack */ | |
17414 | if (NULL == (d = opendir(lua_tostring(L, 1)))) { | |
17415 | lua_pushnil(L); | |
17416 | return 1; | |
17417 | } | |
17418 | - | |
17419 | + | |
17420 | /* push d into registry */ | |
17421 | lua_pushlightuserdata(L, d); | |
17422 | lua_pushcclosure(L, f_dir_files_iter, 1); | |
17423 | - | |
17424 | + | |
17425 | return 1; | |
17426 | } | |
17427 | - | |
17428 | +#endif | |
17429 | int f_file_isreg(lua_State *L) { | |
17430 | struct stat st; | |
17431 | int n = lua_gettop(L); | |
17432 | - | |
17433 | + | |
17434 | if (n != 1) { | |
17435 | lua_pushstring(L, "file_isreg: expected one argument"); | |
17436 | lua_error(L); | |
17437 | } | |
17438 | - | |
17439 | + | |
17440 | if (!lua_isstring(L, 1)) { | |
17441 | lua_pushstring(L, "file_isreg: argument has to be a string"); | |
17442 | lua_error(L); | |
17443 | } | |
17444 | - | |
17445 | + | |
17446 | if (-1 == stat(lua_tostring(L, 1), &st)) { | |
17447 | lua_pushnil(L); | |
17448 | return 1; | |
17449 | } | |
17450 | - | |
17451 | + | |
17452 | lua_pushnumber(L, S_ISREG(st.st_mode)); | |
17453 | - | |
17454 | + | |
17455 | return 1; | |
17456 | } | |
17457 | ||
17458 | int f_file_isdir(lua_State *L) { | |
17459 | struct stat st; | |
17460 | int n = lua_gettop(L); | |
17461 | - | |
17462 | + | |
17463 | if (n != 1) { | |
17464 | lua_pushstring(L, "file_isreg: expected one argument"); | |
17465 | lua_error(L); | |
17466 | } | |
17467 | - | |
17468 | + | |
17469 | if (!lua_isstring(L, 1)) { | |
17470 | lua_pushstring(L, "file_isreg: argument has to be a string"); | |
17471 | lua_error(L); | |
17472 | } | |
17473 | - | |
17474 | + | |
17475 | if (-1 == stat(lua_tostring(L, 1), &st)) { | |
17476 | lua_pushnil(L); | |
17477 | return 1; | |
17478 | } | |
17479 | - | |
17480 | + | |
17481 | lua_pushnumber(L, S_ISDIR(st.st_mode)); | |
17482 | - | |
17483 | + | |
17484 | return 1; | |
17485 | } | |
17486 | ||
17487 | @@ -192,33 +192,33 @@ | |
17488 | char *r; | |
17489 | int n = lua_gettop(L); | |
17490 | struct memcache *mc; | |
17491 | - | |
17492 | + | |
17493 | if (!lua_islightuserdata(L, lua_upvalueindex(1))) { | |
17494 | lua_pushstring(L, "where is my userdata ?"); | |
17495 | lua_error(L); | |
17496 | } | |
17497 | - | |
17498 | + | |
17499 | mc = lua_touserdata(L, lua_upvalueindex(1)); | |
17500 | - | |
17501 | + | |
17502 | if (n != 1) { | |
17503 | lua_pushstring(L, "expected one argument"); | |
17504 | lua_error(L); | |
17505 | } | |
17506 | - | |
17507 | + | |
17508 | if (!lua_isstring(L, 1)) { | |
17509 | lua_pushstring(L, "argument has to be a string"); | |
17510 | lua_error(L); | |
17511 | } | |
17512 | - | |
17513 | - if (NULL == (r = mc_aget(mc, | |
17514 | + | |
17515 | + if (NULL == (r = mc_aget(mc, | |
17516 | lua_tostring(L, 1), lua_strlen(L, 1)))) { | |
17517 | - | |
17518 | + | |
17519 | lua_pushboolean(L, 0); | |
17520 | return 1; | |
17521 | } | |
17522 | - | |
17523 | + | |
17524 | free(r); | |
17525 | - | |
17526 | + | |
17527 | lua_pushboolean(L, 1); | |
17528 | return 1; | |
17529 | } | |
17530 | @@ -226,74 +226,74 @@ | |
17531 | int f_memcache_get_string(lua_State *L) { | |
17532 | char *r; | |
17533 | int n = lua_gettop(L); | |
17534 | - | |
17535 | + | |
17536 | struct memcache *mc; | |
17537 | - | |
17538 | + | |
17539 | if (!lua_islightuserdata(L, lua_upvalueindex(1))) { | |
17540 | lua_pushstring(L, "where is my userdata ?"); | |
17541 | lua_error(L); | |
17542 | } | |
17543 | - | |
17544 | + | |
17545 | mc = lua_touserdata(L, lua_upvalueindex(1)); | |
17546 | - | |
17547 | - | |
17548 | + | |
17549 | + | |
17550 | if (n != 1) { | |
17551 | lua_pushstring(L, "expected one argument"); | |
17552 | lua_error(L); | |
17553 | } | |
17554 | - | |
17555 | + | |
17556 | if (!lua_isstring(L, 1)) { | |
17557 | lua_pushstring(L, "argument has to be a string"); | |
17558 | lua_error(L); | |
17559 | } | |
17560 | - | |
17561 | - if (NULL == (r = mc_aget(mc, | |
17562 | + | |
17563 | + if (NULL == (r = mc_aget(mc, | |
17564 | lua_tostring(L, 1), lua_strlen(L, 1)))) { | |
17565 | lua_pushnil(L); | |
17566 | return 1; | |
17567 | } | |
17568 | - | |
17569 | + | |
17570 | lua_pushstring(L, r); | |
17571 | - | |
17572 | + | |
17573 | free(r); | |
17574 | - | |
17575 | + | |
17576 | return 1; | |
17577 | } | |
17578 | ||
17579 | int f_memcache_get_long(lua_State *L) { | |
17580 | char *r; | |
17581 | int n = lua_gettop(L); | |
17582 | - | |
17583 | + | |
17584 | struct memcache *mc; | |
17585 | - | |
17586 | + | |
17587 | if (!lua_islightuserdata(L, lua_upvalueindex(1))) { | |
17588 | lua_pushstring(L, "where is my userdata ?"); | |
17589 | lua_error(L); | |
17590 | } | |
17591 | - | |
17592 | + | |
17593 | mc = lua_touserdata(L, lua_upvalueindex(1)); | |
17594 | - | |
17595 | - | |
17596 | + | |
17597 | + | |
17598 | if (n != 1) { | |
17599 | lua_pushstring(L, "expected one argument"); | |
17600 | lua_error(L); | |
17601 | } | |
17602 | - | |
17603 | + | |
17604 | if (!lua_isstring(L, 1)) { | |
17605 | lua_pushstring(L, "argument has to be a string"); | |
17606 | lua_error(L); | |
17607 | } | |
17608 | - | |
17609 | - if (NULL == (r = mc_aget(mc, | |
17610 | + | |
17611 | + if (NULL == (r = mc_aget(mc, | |
17612 | lua_tostring(L, 1), lua_strlen(L, 1)))) { | |
17613 | lua_pushnil(L); | |
17614 | return 1; | |
17615 | } | |
17616 | - | |
17617 | + | |
17618 | lua_pushnumber(L, strtol(r, NULL, 10)); | |
17619 | - | |
17620 | + | |
17621 | free(r); | |
17622 | - | |
17623 | + | |
17624 | return 1; | |
17625 | } | |
17626 | #endif | |
1175ccec | 17627 | --- ../lighttpd-1.4.11/src/mod_cml_lua.c 2006-01-30 13:56:40.000000000 +0200 |
36e2a29e | 17628 | +++ lighttpd-1.4.12/src/mod_cml_lua.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
17629 | @@ -23,7 +23,7 @@ |
17630 | #ifdef USE_OPENSSL | |
17631 | #define IN const | |
17632 | #else | |
17633 | -#define IN | |
17634 | +#define IN | |
17635 | #endif | |
17636 | #define OUT | |
17637 | ||
17638 | @@ -31,6 +31,7 @@ | |
17639 | ||
17640 | #include <lua.h> | |
17641 | #include <lualib.h> | |
17642 | +#include <lauxlib.h> | |
17643 | ||
17644 | typedef struct { | |
17645 | stream st; | |
17646 | @@ -39,11 +40,11 @@ | |
17647 | ||
17648 | static const char * load_file(lua_State *L, void *data, size_t *size) { | |
17649 | readme *rm = data; | |
17650 | - | |
17651 | + | |
17652 | UNUSED(L); | |
17653 | - | |
17654 | + | |
17655 | if (rm->done) return 0; | |
17656 | - | |
17657 | + | |
17658 | *size = rm->st.size; | |
17659 | rm->done = 1; | |
17660 | return rm->st.start; | |
17661 | @@ -51,47 +52,47 @@ | |
17662 | ||
17663 | static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) { | |
17664 | int curelem; | |
17665 | - | |
17666 | + | |
17667 | lua_pushstring(L, varname); | |
17668 | - | |
17669 | + | |
17670 | curelem = lua_gettop(L); | |
17671 | lua_gettable(L, LUA_GLOBALSINDEX); | |
17672 | - | |
17673 | + | |
17674 | /* it should be a table */ | |
17675 | if (!lua_isstring(L, curelem)) { | |
17676 | lua_settop(L, curelem - 1); | |
17677 | - | |
17678 | + | |
17679 | return -1; | |
17680 | } | |
17681 | - | |
17682 | + | |
17683 | buffer_copy_string(b, lua_tostring(L, curelem)); | |
17684 | - | |
17685 | + | |
17686 | lua_pop(L, 1); | |
17687 | - | |
17688 | + | |
17689 | assert(curelem - 1 == lua_gettop(L)); | |
17690 | - | |
17691 | + | |
17692 | return 0; | |
17693 | } | |
17694 | ||
17695 | static int lua_to_c_is_table(lua_State *L, const char *varname) { | |
17696 | int curelem; | |
17697 | - | |
17698 | + | |
17699 | lua_pushstring(L, varname); | |
17700 | - | |
17701 | + | |
17702 | curelem = lua_gettop(L); | |
17703 | lua_gettable(L, LUA_GLOBALSINDEX); | |
17704 | - | |
17705 | + | |
17706 | /* it should be a table */ | |
17707 | if (!lua_istable(L, curelem)) { | |
17708 | lua_settop(L, curelem - 1); | |
17709 | - | |
17710 | + | |
17711 | return 0; | |
17712 | } | |
17713 | - | |
17714 | + | |
17715 | lua_settop(L, curelem - 1); | |
17716 | - | |
17717 | + | |
17718 | assert(curelem - 1 == lua_gettop(L)); | |
17719 | - | |
17720 | + | |
17721 | return 1; | |
17722 | } | |
17723 | ||
17724 | @@ -99,7 +100,7 @@ | |
17725 | lua_pushlstring(L, key, key_len); | |
17726 | lua_pushlstring(L, val, val_len); | |
17727 | lua_settable(L, tbl); | |
17728 | - | |
17729 | + | |
17730 | return 0; | |
17731 | } | |
17732 | ||
17733 | @@ -108,21 +109,21 @@ | |
17734 | size_t is_key = 1; | |
17735 | size_t i; | |
17736 | char *key = NULL, *val = NULL; | |
17737 | - | |
17738 | + | |
17739 | key = qrystr->ptr; | |
17740 | - | |
17741 | + | |
17742 | /* we need the \0 */ | |
17743 | for (i = 0; i < qrystr->used; i++) { | |
17744 | switch(qrystr->ptr[i]) { | |
17745 | case '=': | |
17746 | if (is_key) { | |
17747 | val = qrystr->ptr + i + 1; | |
17748 | - | |
17749 | + | |
17750 | qrystr->ptr[i] = '\0'; | |
17751 | - | |
17752 | + | |
17753 | is_key = 0; | |
17754 | } | |
17755 | - | |
17756 | + | |
17757 | break; | |
17758 | case '&': | |
17759 | case '\0': /* fin symbol */ | |
17760 | @@ -131,19 +132,19 @@ | |
17761 | ||
17762 | /* terminate the value */ | |
17763 | qrystr->ptr[i] = '\0'; | |
17764 | - | |
17765 | - c_to_lua_push(L, tbl, | |
17766 | + | |
17767 | + c_to_lua_push(L, tbl, | |
17768 | key, strlen(key), | |
17769 | val, strlen(val)); | |
17770 | } | |
17771 | - | |
17772 | + | |
17773 | key = qrystr->ptr + i + 1; | |
17774 | val = NULL; | |
17775 | is_key = 1; | |
17776 | break; | |
17777 | } | |
17778 | } | |
17779 | - | |
17780 | + | |
17781 | return 0; | |
17782 | } | |
17783 | #if 0 | |
17784 | @@ -151,21 +152,21 @@ | |
17785 | data_unset *d; | |
17786 | ||
17787 | UNUSED(srv); | |
17788 | - | |
17789 | + | |
17790 | if (NULL != (d = array_get_element(con->request.headers, "Cookie"))) { | |
17791 | data_string *ds = (data_string *)d; | |
17792 | size_t key = 0, value = 0; | |
17793 | size_t is_key = 1, is_sid = 0; | |
17794 | size_t i; | |
17795 | - | |
17796 | + | |
17797 | /* found COOKIE */ | |
17798 | if (!DATA_IS_STRING(d)) return -1; | |
17799 | if (ds->value->used == 0) return -1; | |
17800 | - | |
17801 | + | |
17802 | if (ds->value->ptr[0] == '\0' || | |
17803 | ds->value->ptr[0] == '=' || | |
17804 | ds->value->ptr[0] == ';') return -1; | |
17805 | - | |
17806 | + | |
17807 | buffer_reset(p->session_id); | |
17808 | for (i = 0; i < ds->value->used; i++) { | |
17809 | switch(ds->value->ptr[i]) { | |
17810 | @@ -176,16 +177,16 @@ | |
17811 | is_sid = 1; | |
17812 | } | |
17813 | value = i + 1; | |
17814 | - | |
17815 | + | |
17816 | is_key = 0; | |
17817 | } | |
17818 | - | |
17819 | + | |
17820 | break; | |
17821 | case ';': | |
17822 | if (is_sid) { | |
17823 | buffer_copy_string_len(p->session_id, ds->value->ptr + value, i - value); | |
17824 | } | |
17825 | - | |
17826 | + | |
17827 | is_sid = 0; | |
17828 | key = i + 1; | |
17829 | value = 0; | |
17830 | @@ -204,48 +205,43 @@ | |
17831 | } | |
17832 | } | |
17833 | } | |
17834 | - | |
17835 | + | |
17836 | return 0; | |
17837 | } | |
17838 | #endif | |
17839 | ||
17840 | int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) { | |
17841 | - lua_State *L; | |
17842 | + lua_State *L; | |
17843 | readme rm; | |
17844 | int ret = -1; | |
17845 | buffer *b = buffer_init(); | |
17846 | int header_tbl = 0; | |
17847 | - | |
17848 | + | |
17849 | rm.done = 0; | |
17850 | stream_open(&rm.st, fn); | |
17851 | - | |
17852 | + | |
17853 | /* push the lua file to the interpreter and see what happends */ | |
17854 | - L = lua_open(); | |
17855 | - | |
17856 | - luaopen_base(L); | |
17857 | - luaopen_table(L); | |
17858 | - luaopen_string(L); | |
17859 | - luaopen_math(L); | |
17860 | - luaopen_io(L); | |
17861 | - | |
17862 | + L = luaL_newstate(); | |
17863 | + luaL_openlibs(L); | |
17864 | + | |
17865 | /* register functions */ | |
17866 | lua_register(L, "md5", f_crypto_md5); | |
17867 | lua_register(L, "file_mtime", f_file_mtime); | |
17868 | lua_register(L, "file_isreg", f_file_isreg); | |
17869 | lua_register(L, "file_isdir", f_file_isreg); | |
17870 | lua_register(L, "dir_files", f_dir_files); | |
17871 | - | |
17872 | + | |
17873 | #ifdef HAVE_MEMCACHE_H | |
17874 | lua_pushliteral(L, "memcache_get_long"); | |
17875 | lua_pushlightuserdata(L, p->conf.mc); | |
17876 | lua_pushcclosure(L, f_memcache_get_long, 1); | |
17877 | lua_settable(L, LUA_GLOBALSINDEX); | |
17878 | - | |
17879 | + | |
17880 | lua_pushliteral(L, "memcache_get_string"); | |
17881 | lua_pushlightuserdata(L, p->conf.mc); | |
17882 | lua_pushcclosure(L, f_memcache_get_string, 1); | |
17883 | lua_settable(L, LUA_GLOBALSINDEX); | |
17884 | - | |
17885 | + | |
17886 | lua_pushliteral(L, "memcache_exists"); | |
17887 | lua_pushlightuserdata(L, p->conf.mc); | |
17888 | lua_pushcclosure(L, f_memcache_exists, 1); | |
17889 | @@ -255,11 +251,11 @@ | |
17890 | lua_pushliteral(L, "request"); | |
17891 | lua_newtable(L); | |
17892 | lua_settable(L, LUA_GLOBALSINDEX); | |
17893 | - | |
17894 | + | |
17895 | lua_pushliteral(L, "request"); | |
17896 | header_tbl = lua_gettop(L); | |
17897 | lua_gettable(L, LUA_GLOBALSINDEX); | |
17898 | - | |
17899 | + | |
17900 | c_to_lua_push(L, header_tbl, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)); | |
17901 | c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)); | |
17902 | c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path)); | |
17903 | @@ -267,84 +263,84 @@ | |
17904 | if (!buffer_is_empty(con->request.pathinfo)) { | |
17905 | c_to_lua_push(L, header_tbl, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo)); | |
17906 | } | |
17907 | - | |
17908 | + | |
17909 | c_to_lua_push(L, header_tbl, CONST_STR_LEN("CWD"), CONST_BUF_LEN(p->basedir)); | |
17910 | c_to_lua_push(L, header_tbl, CONST_STR_LEN("BASEURL"), CONST_BUF_LEN(p->baseurl)); | |
17911 | - | |
17912 | + | |
17913 | /* register GET parameter */ | |
17914 | lua_pushliteral(L, "get"); | |
17915 | lua_newtable(L); | |
17916 | lua_settable(L, LUA_GLOBALSINDEX); | |
17917 | - | |
17918 | + | |
17919 | lua_pushliteral(L, "get"); | |
17920 | header_tbl = lua_gettop(L); | |
17921 | lua_gettable(L, LUA_GLOBALSINDEX); | |
17922 | - | |
17923 | + | |
17924 | buffer_copy_string_buffer(b, con->uri.query); | |
17925 | cache_export_get_params(L, header_tbl, b); | |
17926 | buffer_reset(b); | |
17927 | ||
17928 | - /* 2 default constants */ | |
17929 | + /* 2 default constants */ | |
17930 | lua_pushliteral(L, "CACHE_HIT"); | |
17931 | lua_pushboolean(L, 0); | |
17932 | lua_settable(L, LUA_GLOBALSINDEX); | |
17933 | - | |
17934 | + | |
17935 | lua_pushliteral(L, "CACHE_MISS"); | |
17936 | lua_pushboolean(L, 1); | |
17937 | lua_settable(L, LUA_GLOBALSINDEX); | |
17938 | - | |
17939 | + | |
17940 | /* load lua program */ | |
17941 | if (lua_load(L, load_file, &rm, fn->ptr) || lua_pcall(L,0,1,0)) { | |
17942 | log_error_write(srv, __FILE__, __LINE__, "s", | |
17943 | lua_tostring(L,-1)); | |
17944 | - | |
17945 | + | |
17946 | goto error; | |
17947 | } | |
17948 | - | |
17949 | + | |
17950 | /* get return value */ | |
17951 | ret = (int)lua_tonumber(L, -1); | |
17952 | lua_pop(L, 1); | |
17953 | - | |
17954 | - /* fetch the data from lua */ | |
17955 | + | |
17956 | + /* fetch the data from lua */ | |
17957 | lua_to_c_get_string(L, "trigger_handler", p->trigger_handler); | |
17958 | - | |
17959 | + | |
17960 | if (0 == lua_to_c_get_string(L, "output_contenttype", b)) { | |
17961 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(b)); | |
17962 | } | |
17963 | - | |
17964 | + | |
17965 | if (ret == 0) { | |
17966 | /* up to now it is a cache-hit, check if all files exist */ | |
17967 | - | |
17968 | + | |
17969 | int curelem; | |
17970 | time_t mtime = 0; | |
17971 | - | |
17972 | + | |
17973 | if (!lua_to_c_is_table(L, "output_include")) { | |
17974 | log_error_write(srv, __FILE__, __LINE__, "s", | |
17975 | "output_include is missing or not a table"); | |
17976 | ret = -1; | |
17977 | - | |
17978 | + | |
17979 | goto error; | |
17980 | } | |
17981 | - | |
17982 | + | |
17983 | lua_pushstring(L, "output_include"); | |
17984 | - | |
17985 | + | |
17986 | curelem = lua_gettop(L); | |
17987 | lua_gettable(L, LUA_GLOBALSINDEX); | |
17988 | ||
17989 | /* HOW-TO build a etag ? | |
17990 | - * as we don't just have one file we have to take the stat() | |
17991 | + * as we don't just have one file we have to take the stat() | |
17992 | * from all base files, merge them and build the etag from | |
17993 | * it later. | |
17994 | - * | |
17995 | + * | |
17996 | * The mtime of the content is the mtime of the freshest base file | |
17997 | - * | |
17998 | + * | |
17999 | * */ | |
18000 | - | |
18001 | + | |
18002 | lua_pushnil(L); /* first key */ | |
18003 | while (lua_next(L, curelem) != 0) { | |
18004 | stat_cache_entry *sce = NULL; | |
18005 | /* key' is at index -2 and value' at index -1 */ | |
18006 | - | |
18007 | + | |
18008 | if (lua_isstring(L, -1)) { | |
18009 | const char *s = lua_tostring(L, -1); | |
18010 | ||
18011 | @@ -364,18 +360,18 @@ | |
18012 | /* a file is missing, call the handler to generate it */ | |
18013 | if (!buffer_is_empty(p->trigger_handler)) { | |
18014 | ret = 1; /* cache-miss */ | |
18015 | - | |
18016 | + | |
18017 | log_error_write(srv, __FILE__, __LINE__, "s", | |
18018 | "a file is missing, calling handler"); | |
18019 | - | |
18020 | + | |
18021 | break; | |
18022 | } else { | |
18023 | /* handler not set -> 500 */ | |
18024 | ret = -1; | |
18025 | - | |
18026 | + | |
18027 | log_error_write(srv, __FILE__, __LINE__, "s", | |
18028 | "a file missing and no handler set"); | |
18029 | - | |
18030 | + | |
18031 | break; | |
18032 | } | |
18033 | break; | |
18034 | @@ -393,12 +389,12 @@ | |
18035 | "not a string"); | |
18036 | break; | |
18037 | } | |
18038 | - | |
18039 | + | |
18040 | lua_pop(L, 1); /* removes value'; keeps key' for next iteration */ | |
18041 | } | |
18042 | - | |
18043 | + | |
18044 | lua_settop(L, curelem - 1); | |
18045 | - | |
18046 | + | |
18047 | if (ret == 0) { | |
18048 | data_string *ds; | |
18049 | char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")]; | |
18050 | @@ -410,9 +406,9 @@ | |
18051 | ||
18052 | /* no Last-Modified specified */ | |
18053 | if ((mtime) && (NULL == ds)) { | |
18054 | - | |
18055 | + | |
18056 | strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime)); | |
18057 | - | |
18058 | + | |
18059 | response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), timebuf, sizeof(timebuf) - 1); | |
18060 | ||
18061 | ||
18062 | @@ -428,9 +424,9 @@ | |
18063 | tbuf.used = 0; | |
18064 | tbuf.ptr = NULL; | |
18065 | } | |
18066 | - | |
18067 | + | |
18068 | if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, &tbuf)) { | |
18069 | - /* ok, the client already has our content, | |
18070 | + /* ok, the client already has our content, | |
18071 | * no need to send it again */ | |
18072 | ||
18073 | chunkqueue_reset(con->write_queue); | |
18074 | @@ -440,24 +436,24 @@ | |
18075 | chunkqueue_reset(con->write_queue); | |
18076 | } | |
18077 | } | |
18078 | - | |
18079 | + | |
18080 | if (ret == 1 && !buffer_is_empty(p->trigger_handler)) { | |
18081 | /* cache-miss */ | |
18082 | buffer_copy_string_buffer(con->uri.path, p->baseurl); | |
18083 | buffer_append_string_buffer(con->uri.path, p->trigger_handler); | |
18084 | - | |
18085 | + | |
18086 | buffer_copy_string_buffer(con->physical.path, p->basedir); | |
18087 | buffer_append_string_buffer(con->physical.path, p->trigger_handler); | |
18088 | - | |
18089 | + | |
18090 | chunkqueue_reset(con->write_queue); | |
18091 | } | |
18092 | - | |
18093 | + | |
18094 | error: | |
18095 | lua_close(L); | |
18096 | - | |
18097 | + | |
18098 | stream_close(&rm.st); | |
18099 | buffer_free(b); | |
18100 | - | |
18101 | + | |
18102 | return ret /* cache-error */; | |
18103 | } | |
18104 | #else | |
1175ccec | 18105 | --- ../lighttpd-1.4.11/src/mod_compress.c 2005-11-18 13:49:14.000000000 +0200 |
36e2a29e | 18106 | +++ lighttpd-1.4.12/src/mod_compress.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
18107 | @@ -2,7 +2,6 @@ |
18108 | #include <sys/stat.h> | |
18109 | ||
18110 | #include <fcntl.h> | |
18111 | -#include <unistd.h> | |
18112 | #include <ctype.h> | |
18113 | #include <stdlib.h> | |
18114 | #include <string.h> | |
18115 | @@ -14,6 +13,7 @@ | |
18116 | #include "buffer.h" | |
18117 | #include "response.h" | |
18118 | #include "stat_cache.h" | |
18119 | +#include "http_chunk.h" | |
18120 | ||
18121 | #include "plugin.h" | |
18122 | ||
18123 | @@ -33,6 +33,7 @@ | |
18124 | #endif | |
18125 | ||
18126 | #include "sys-mmap.h" | |
18127 | +#include "sys-files.h" | |
18128 | ||
18129 | /* request: accept-encoding */ | |
18130 | #define HTTP_ACCEPT_ENCODING_IDENTITY BV(0) | |
18131 | @@ -55,97 +56,127 @@ | |
18132 | PLUGIN_DATA; | |
18133 | buffer *ofn; | |
18134 | buffer *b; | |
18135 | - | |
18136 | + | |
18137 | plugin_config **config_storage; | |
18138 | - plugin_config conf; | |
18139 | + plugin_config conf; | |
18140 | } plugin_data; | |
18141 | ||
18142 | INIT_FUNC(mod_compress_init) { | |
18143 | plugin_data *p; | |
18144 | - | |
18145 | + | |
18146 | p = calloc(1, sizeof(*p)); | |
18147 | - | |
18148 | + | |
18149 | p->ofn = buffer_init(); | |
18150 | p->b = buffer_init(); | |
18151 | - | |
18152 | + | |
18153 | return p; | |
18154 | } | |
18155 | ||
18156 | FREE_FUNC(mod_compress_free) { | |
18157 | plugin_data *p = p_d; | |
18158 | - | |
18159 | + | |
18160 | UNUSED(srv); | |
18161 | ||
18162 | if (!p) return HANDLER_GO_ON; | |
18163 | - | |
18164 | + | |
18165 | buffer_free(p->ofn); | |
18166 | buffer_free(p->b); | |
18167 | - | |
18168 | + | |
18169 | if (p->config_storage) { | |
18170 | size_t i; | |
18171 | for (i = 0; i < srv->config_context->used; i++) { | |
18172 | plugin_config *s = p->config_storage[i]; | |
18173 | ||
18174 | if (!s) continue; | |
18175 | - | |
18176 | + | |
18177 | array_free(s->compress); | |
18178 | buffer_free(s->compress_cache_dir); | |
18179 | - | |
18180 | + | |
18181 | free(s); | |
18182 | } | |
18183 | free(p->config_storage); | |
18184 | } | |
18185 | - | |
18186 | - | |
18187 | + | |
18188 | + | |
18189 | free(p); | |
18190 | - | |
18191 | + | |
18192 | return HANDLER_GO_ON; | |
18193 | } | |
18194 | ||
18195 | +void mkdir_recursive(const char *dir) { | |
18196 | + | |
18197 | + char dir_copy[256]; | |
18198 | + char *p = dir_copy; | |
18199 | + | |
18200 | + if (!dir || !dir[0]) | |
18201 | + return; | |
18202 | + | |
18203 | + strncpy(dir_copy, dir, sizeof(dir_copy) / sizeof(dir_copy[0])); | |
18204 | + | |
18205 | + while ((p = strchr(p + 1, '/')) != NULL) { | |
18206 | + | |
18207 | + *p = '\0'; | |
18208 | + if ((mkdir(dir_copy, 0700) != 0) && (errno != EEXIST)) | |
18209 | + return; | |
18210 | + | |
18211 | + *p++ = '/'; | |
18212 | + } | |
18213 | + | |
18214 | + mkdir(dir, 0700); | |
18215 | +} | |
18216 | + | |
18217 | SETDEFAULTS_FUNC(mod_compress_setdefaults) { | |
18218 | plugin_data *p = p_d; | |
18219 | size_t i = 0; | |
18220 | - | |
18221 | - config_values_t cv[] = { | |
18222 | + | |
18223 | + config_values_t cv[] = { | |
18224 | { "compress.cache-dir", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
18225 | { "compress.filetype", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, | |
18226 | { "compress.max-filesize", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, | |
18227 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
18228 | }; | |
18229 | - | |
18230 | + | |
18231 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
18232 | - | |
18233 | + | |
18234 | for (i = 0; i < srv->config_context->used; i++) { | |
18235 | plugin_config *s; | |
18236 | - | |
18237 | + | |
18238 | s = calloc(1, sizeof(plugin_config)); | |
18239 | s->compress_cache_dir = buffer_init(); | |
18240 | s->compress = array_init(); | |
18241 | s->compress_max_filesize = 0; | |
18242 | - | |
18243 | + | |
18244 | cv[0].destination = s->compress_cache_dir; | |
18245 | cv[1].destination = s->compress; | |
18246 | cv[2].destination = &(s->compress_max_filesize); | |
18247 | - | |
18248 | + | |
18249 | p->config_storage[i] = s; | |
18250 | - | |
18251 | + | |
18252 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
18253 | return HANDLER_ERROR; | |
18254 | } | |
18255 | - | |
18256 | + | |
18257 | if (!buffer_is_empty(s->compress_cache_dir)) { | |
18258 | struct stat st; | |
18259 | if (0 != stat(s->compress_cache_dir->ptr, &st)) { | |
18260 | - log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir", | |
18261 | + | |
18262 | + log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, attempting to create", | |
18263 | s->compress_cache_dir, strerror(errno)); | |
18264 | - | |
18265 | - return HANDLER_ERROR; | |
18266 | + mkdir_recursive(s->compress_cache_dir->ptr); | |
18267 | + | |
18268 | + if (0 != stat(s->compress_cache_dir->ptr, &st)) { | |
18269 | + | |
18270 | + log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, create failed", | |
18271 | + s->compress_cache_dir, strerror(errno)); | |
18272 | + | |
18273 | + return HANDLER_ERROR; | |
18274 | + } | |
18275 | } | |
18276 | } | |
18277 | } | |
18278 | - | |
18279 | + | |
18280 | return HANDLER_GO_ON; | |
18281 | - | |
18282 | + | |
18283 | } | |
18284 | ||
18285 | #ifdef USE_ZLIB | |
18286 | @@ -153,32 +184,32 @@ | |
18287 | unsigned char *c; | |
18288 | unsigned long crc; | |
18289 | z_stream z; | |
18290 | - | |
18291 | + | |
18292 | UNUSED(srv); | |
18293 | UNUSED(con); | |
18294 | ||
18295 | z.zalloc = Z_NULL; | |
18296 | z.zfree = Z_NULL; | |
18297 | z.opaque = Z_NULL; | |
18298 | - | |
18299 | - if (Z_OK != deflateInit2(&z, | |
18300 | + | |
18301 | + if (Z_OK != deflateInit2(&z, | |
18302 | Z_DEFAULT_COMPRESSION, | |
18303 | - Z_DEFLATED, | |
18304 | + Z_DEFLATED, | |
18305 | -MAX_WBITS, /* supress zlib-header */ | |
18306 | 8, | |
18307 | Z_DEFAULT_STRATEGY)) { | |
18308 | return -1; | |
18309 | } | |
18310 | - | |
18311 | + | |
18312 | z.next_in = (unsigned char *)start; | |
18313 | z.avail_in = st_size; | |
18314 | z.total_in = 0; | |
18315 | - | |
18316 | - | |
18317 | + | |
18318 | + | |
18319 | buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12 + 18); | |
18320 | - | |
18321 | + | |
18322 | /* write gzip header */ | |
18323 | - | |
18324 | + | |
18325 | c = (unsigned char *)p->b->ptr; | |
18326 | c[0] = 0x1f; | |
18327 | c[1] = 0x8b; | |
18328 | @@ -190,24 +221,24 @@ | |
18329 | c[7] = (mtime >> 24) & 0xff; | |
18330 | c[8] = 0x00; /* extra flags */ | |
18331 | c[9] = 0x03; /* UNIX */ | |
18332 | - | |
18333 | + | |
18334 | p->b->used = 10; | |
18335 | z.next_out = (unsigned char *)p->b->ptr + p->b->used; | |
18336 | z.avail_out = p->b->size - p->b->used - 8; | |
18337 | z.total_out = 0; | |
18338 | - | |
18339 | + | |
18340 | if (Z_STREAM_END != deflate(&z, Z_FINISH)) { | |
18341 | deflateEnd(&z); | |
18342 | return -1; | |
18343 | } | |
18344 | - | |
18345 | + | |
18346 | /* trailer */ | |
18347 | p->b->used += z.total_out; | |
18348 | - | |
18349 | + | |
18350 | crc = generate_crc32c(start, st_size); | |
18351 | - | |
18352 | + | |
18353 | c = (unsigned char *)p->b->ptr + p->b->used; | |
18354 | - | |
18355 | + | |
18356 | c[0] = (crc >> 0) & 0xff; | |
18357 | c[1] = (crc >> 8) & 0xff; | |
18358 | c[2] = (crc >> 16) & 0xff; | |
18359 | @@ -221,51 +252,51 @@ | |
18360 | if (Z_OK != deflateEnd(&z)) { | |
18361 | return -1; | |
18362 | } | |
18363 | - | |
18364 | + | |
18365 | return 0; | |
18366 | } | |
18367 | ||
18368 | static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) { | |
18369 | z_stream z; | |
18370 | - | |
18371 | + | |
18372 | UNUSED(srv); | |
18373 | UNUSED(con); | |
18374 | ||
18375 | z.zalloc = Z_NULL; | |
18376 | z.zfree = Z_NULL; | |
18377 | z.opaque = Z_NULL; | |
18378 | - | |
18379 | - if (Z_OK != deflateInit2(&z, | |
18380 | + | |
18381 | + if (Z_OK != deflateInit2(&z, | |
18382 | Z_DEFAULT_COMPRESSION, | |
18383 | - Z_DEFLATED, | |
18384 | + Z_DEFLATED, | |
18385 | -MAX_WBITS, /* supress zlib-header */ | |
18386 | 8, | |
18387 | Z_DEFAULT_STRATEGY)) { | |
18388 | return -1; | |
18389 | } | |
18390 | - | |
18391 | + | |
18392 | z.next_in = start; | |
18393 | z.avail_in = st_size; | |
18394 | z.total_in = 0; | |
18395 | - | |
18396 | + | |
18397 | buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12); | |
18398 | - | |
18399 | + | |
18400 | z.next_out = (unsigned char *)p->b->ptr; | |
18401 | z.avail_out = p->b->size; | |
18402 | z.total_out = 0; | |
18403 | - | |
18404 | + | |
18405 | if (Z_STREAM_END != deflate(&z, Z_FINISH)) { | |
18406 | deflateEnd(&z); | |
18407 | return -1; | |
18408 | } | |
18409 | - | |
18410 | + | |
18411 | /* trailer */ | |
18412 | p->b->used += z.total_out; | |
18413 | - | |
18414 | + | |
18415 | if (Z_OK != deflateEnd(&z)) { | |
18416 | return -1; | |
18417 | } | |
18418 | - | |
18419 | + | |
18420 | return 0; | |
18421 | } | |
18422 | ||
18423 | @@ -274,48 +305,48 @@ | |
18424 | #ifdef USE_BZ2LIB | |
18425 | static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) { | |
18426 | bz_stream bz; | |
18427 | - | |
18428 | + | |
18429 | UNUSED(srv); | |
18430 | UNUSED(con); | |
18431 | ||
18432 | bz.bzalloc = NULL; | |
18433 | bz.bzfree = NULL; | |
18434 | bz.opaque = NULL; | |
18435 | - | |
18436 | - if (BZ_OK != BZ2_bzCompressInit(&bz, | |
18437 | + | |
18438 | + if (BZ_OK != BZ2_bzCompressInit(&bz, | |
18439 | 9, /* blocksize = 900k */ | |
18440 | 0, /* no output */ | |
18441 | 0)) { /* workFactor: default */ | |
18442 | return -1; | |
18443 | } | |
18444 | - | |
18445 | + | |
18446 | bz.next_in = (char *)start; | |
18447 | bz.avail_in = st_size; | |
18448 | bz.total_in_lo32 = 0; | |
18449 | bz.total_in_hi32 = 0; | |
18450 | - | |
18451 | + | |
18452 | buffer_prepare_copy(p->b, (bz.avail_in * 1.1) + 12); | |
18453 | - | |
18454 | + | |
18455 | bz.next_out = p->b->ptr; | |
18456 | bz.avail_out = p->b->size; | |
18457 | bz.total_out_lo32 = 0; | |
18458 | bz.total_out_hi32 = 0; | |
18459 | - | |
18460 | + | |
18461 | if (BZ_STREAM_END != BZ2_bzCompress(&bz, BZ_FINISH)) { | |
18462 | BZ2_bzCompressEnd(&bz); | |
18463 | return -1; | |
18464 | } | |
18465 | - | |
18466 | + | |
18467 | /* file is too large for now */ | |
18468 | if (bz.total_out_hi32) return -1; | |
18469 | - | |
18470 | + | |
18471 | /* trailer */ | |
18472 | p->b->used = bz.total_out_lo32; | |
18473 | - | |
18474 | + | |
18475 | if (BZ_OK != BZ2_bzCompressEnd(&bz)) { | |
18476 | return -1; | |
18477 | } | |
18478 | - | |
18479 | + | |
18480 | return 0; | |
18481 | } | |
18482 | #endif | |
18483 | @@ -326,47 +357,50 @@ | |
18484 | void *start; | |
18485 | const char *filename = fn->ptr; | |
18486 | ssize_t r; | |
18487 | - | |
18488 | + stat_cache_entry *compressed_sce = NULL; | |
18489 | + | |
18490 | + if (buffer_is_empty(p->conf.compress_cache_dir)) return -1; | |
18491 | + | |
18492 | /* overflow */ | |
18493 | if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1; | |
18494 | - | |
18495 | - /* don't mmap files > 128Mb | |
18496 | - * | |
18497 | + | |
18498 | + /* don't mmap files > 128Mb | |
18499 | + * | |
18500 | * we could use a sliding window, but currently there is no need for it | |
18501 | */ | |
18502 | - | |
18503 | + | |
18504 | if (sce->st.st_size > 128 * 1024 * 1024) return -1; | |
18505 | - | |
18506 | + | |
18507 | buffer_reset(p->ofn); | |
18508 | buffer_copy_string_buffer(p->ofn, p->conf.compress_cache_dir); | |
18509 | - BUFFER_APPEND_SLASH(p->ofn); | |
18510 | - | |
18511 | + PATHNAME_APPEND_SLASH(p->ofn); | |
18512 | + | |
18513 | if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) { | |
18514 | size_t offset = p->ofn->used - 1; | |
18515 | char *dir, *nextdir; | |
18516 | - | |
18517 | + | |
18518 | buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1); | |
18519 | - | |
18520 | + | |
18521 | buffer_copy_string_buffer(p->b, p->ofn); | |
18522 | - | |
18523 | + | |
18524 | /* mkdir -p ... */ | |
18525 | for (dir = p->b->ptr + offset; NULL != (nextdir = strchr(dir, '/')); dir = nextdir + 1) { | |
18526 | *nextdir = '\0'; | |
18527 | - | |
18528 | + | |
18529 | if (-1 == mkdir(p->b->ptr, 0700)) { | |
18530 | if (errno != EEXIST) { | |
18531 | log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cache-directory", p->b, "failed", strerror(errno)); | |
18532 | - | |
18533 | + | |
18534 | return -1; | |
18535 | } | |
18536 | } | |
18537 | - | |
18538 | + | |
18539 | *nextdir = '/'; | |
18540 | } | |
18541 | } else { | |
18542 | buffer_append_string_buffer(p->ofn, con->uri.path); | |
18543 | } | |
18544 | - | |
18545 | + | |
18546 | switch(type) { | |
18547 | case HTTP_ACCEPT_ENCODING_GZIP: | |
18548 | buffer_append_string(p->ofn, "-gzip-"); | |
18549 | @@ -381,55 +415,64 @@ | |
18550 | log_error_write(srv, __FILE__, __LINE__, "sd", "unknown compression type", type); | |
18551 | return -1; | |
18552 | } | |
18553 | - | |
18554 | + | |
18555 | buffer_append_string_buffer(p->ofn, sce->etag); | |
18556 | - | |
18557 | + | |
18558 | + | |
18559 | + if (HANDLER_ERROR != stat_cache_get_entry(srv, con, p->ofn, &compressed_sce)) { | |
18560 | + /* file exists */ | |
18561 | + | |
18562 | + http_chunk_append_file(srv, con, p->ofn, 0, compressed_sce->st.st_size); | |
18563 | + con->file_finished = 1; | |
18564 | + | |
18565 | + return 0; | |
18566 | + } | |
18567 | + | |
18568 | if (-1 == (ofd = open(p->ofn->ptr, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))) { | |
18569 | if (errno == EEXIST) { | |
18570 | /* cache-entry exists */ | |
18571 | -#if 0 | |
18572 | - log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit"); | |
18573 | -#endif | |
18574 | - buffer_copy_string_buffer(con->physical.path, p->ofn); | |
18575 | - | |
18576 | - return 0; | |
18577 | + | |
18578 | } | |
18579 | - | |
18580 | - log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cachefile", p->ofn, "failed", strerror(errno)); | |
18581 | - | |
18582 | + | |
18583 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
18584 | + "creating cachefile", p->ofn, | |
18585 | + "failed", strerror(errno)); | |
18586 | + | |
18587 | return -1; | |
18588 | } | |
18589 | -#if 0 | |
18590 | - log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache miss"); | |
18591 | -#endif | |
18592 | + | |
18593 | if (-1 == (ifd = open(filename, O_RDONLY | O_BINARY))) { | |
18594 | - log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno)); | |
18595 | - | |
18596 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
18597 | + "opening plain-file", fn, | |
18598 | + "failed", strerror(errno)); | |
18599 | + | |
18600 | close(ofd); | |
18601 | - | |
18602 | + | |
18603 | return -1; | |
18604 | } | |
18605 | - | |
18606 | - | |
18607 | + | |
18608 | + | |
18609 | if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { | |
18610 | - log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno)); | |
18611 | - | |
18612 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
18613 | + "mmaping", fn, | |
18614 | + "failed", strerror(errno)); | |
18615 | + | |
18616 | close(ofd); | |
18617 | close(ifd); | |
18618 | return -1; | |
18619 | } | |
18620 | - | |
18621 | + | |
18622 | switch(type) { | |
18623 | #ifdef USE_ZLIB | |
18624 | - case HTTP_ACCEPT_ENCODING_GZIP: | |
18625 | + case HTTP_ACCEPT_ENCODING_GZIP: | |
18626 | ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime); | |
18627 | break; | |
18628 | - case HTTP_ACCEPT_ENCODING_DEFLATE: | |
18629 | + case HTTP_ACCEPT_ENCODING_DEFLATE: | |
18630 | ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size); | |
18631 | break; | |
18632 | #endif | |
18633 | #ifdef USE_BZ2LIB | |
18634 | - case HTTP_ACCEPT_ENCODING_BZIP2: | |
18635 | + case HTTP_ACCEPT_ENCODING_BZIP2: | |
18636 | ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size); | |
18637 | break; | |
18638 | #endif | |
18639 | @@ -437,26 +480,27 @@ | |
18640 | ret = -1; | |
18641 | break; | |
18642 | } | |
18643 | - | |
18644 | + | |
18645 | if (-1 == (r = write(ofd, p->b->ptr, p->b->used))) { | |
18646 | - munmap(start, sce->st.st_size); | |
18647 | + munmap(start, sce->st.st_size); | |
18648 | close(ofd); | |
18649 | close(ifd); | |
18650 | return -1; | |
18651 | } | |
18652 | - | |
18653 | + | |
18654 | if ((size_t)r != p->b->used) { | |
18655 | - | |
18656 | + | |
18657 | } | |
18658 | - | |
18659 | + | |
18660 | munmap(start, sce->st.st_size); | |
18661 | close(ofd); | |
18662 | close(ifd); | |
18663 | - | |
18664 | + | |
18665 | if (ret != 0) return -1; | |
18666 | - | |
18667 | - buffer_copy_string_buffer(con->physical.path, p->ofn); | |
18668 | - | |
18669 | + | |
18670 | + http_chunk_append_file(srv, con, p->ofn, 0, r); | |
18671 | + con->file_finished = 1; | |
18672 | + | |
18673 | return 0; | |
18674 | } | |
18675 | ||
18676 | @@ -465,43 +509,44 @@ | |
18677 | int ret = -1; | |
18678 | void *start; | |
18679 | buffer *b; | |
18680 | - | |
18681 | + | |
18682 | /* overflow */ | |
18683 | if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1; | |
18684 | - | |
18685 | + | |
18686 | /* don't mmap files > 128M | |
18687 | - * | |
18688 | + * | |
18689 | * we could use a sliding window, but currently there is no need for it | |
18690 | */ | |
18691 | - | |
18692 | + | |
18693 | if (sce->st.st_size > 128 * 1024 * 1024) return -1; | |
18694 | - | |
18695 | - | |
18696 | + | |
18697 | if (-1 == (ifd = open(fn->ptr, O_RDONLY | O_BINARY))) { | |
18698 | log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno)); | |
18699 | - | |
18700 | + | |
18701 | return -1; | |
18702 | } | |
18703 | - | |
18704 | - | |
18705 | - if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { | |
18706 | + | |
18707 | + start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0); | |
18708 | + | |
18709 | + close(ifd); | |
18710 | + | |
18711 | + if (MAP_FAILED == start) { | |
18712 | log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno)); | |
18713 | - | |
18714 | - close(ifd); | |
18715 | + | |
18716 | return -1; | |
18717 | } | |
18718 | - | |
18719 | + | |
18720 | switch(type) { | |
18721 | #ifdef USE_ZLIB | |
18722 | - case HTTP_ACCEPT_ENCODING_GZIP: | |
18723 | + case HTTP_ACCEPT_ENCODING_GZIP: | |
18724 | ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime); | |
18725 | break; | |
18726 | - case HTTP_ACCEPT_ENCODING_DEFLATE: | |
18727 | + case HTTP_ACCEPT_ENCODING_DEFLATE: | |
18728 | ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size); | |
18729 | break; | |
18730 | #endif | |
18731 | #ifdef USE_BZ2LIB | |
18732 | - case HTTP_ACCEPT_ENCODING_BZIP2: | |
18733 | + case HTTP_ACCEPT_ENCODING_BZIP2: | |
18734 | ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size); | |
18735 | break; | |
18736 | #endif | |
18737 | @@ -509,69 +554,64 @@ | |
18738 | ret = -1; | |
18739 | break; | |
18740 | } | |
18741 | - | |
18742 | + | |
18743 | munmap(start, sce->st.st_size); | |
18744 | - close(ifd); | |
18745 | - | |
18746 | + | |
18747 | if (ret != 0) return -1; | |
18748 | - | |
18749 | + | |
18750 | chunkqueue_reset(con->write_queue); | |
18751 | b = chunkqueue_get_append_buffer(con->write_queue); | |
18752 | buffer_copy_memory(b, p->b->ptr, p->b->used + 1); | |
18753 | - | |
18754 | + | |
18755 | buffer_reset(con->physical.path); | |
18756 | - | |
18757 | + | |
18758 | con->file_finished = 1; | |
18759 | con->file_started = 1; | |
18760 | - | |
18761 | + | |
18762 | return 0; | |
18763 | } | |
18764 | ||
18765 | - | |
18766 | -#define PATCH(x) \ | |
18767 | - p->conf.x = s->x; | |
18768 | static int mod_compress_patch_connection(server *srv, connection *con, plugin_data *p) { | |
18769 | size_t i, j; | |
18770 | plugin_config *s = p->config_storage[0]; | |
18771 | ||
18772 | - PATCH(compress_cache_dir); | |
18773 | - PATCH(compress); | |
18774 | - PATCH(compress_max_filesize); | |
18775 | - | |
18776 | + PATCH_OPTION(compress_cache_dir); | |
18777 | + PATCH_OPTION(compress); | |
18778 | + PATCH_OPTION(compress_max_filesize); | |
18779 | + | |
18780 | /* skip the first, the global context */ | |
18781 | for (i = 1; i < srv->config_context->used; i++) { | |
18782 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
18783 | s = p->config_storage[i]; | |
18784 | - | |
18785 | + | |
18786 | /* condition didn't match */ | |
18787 | if (!config_check_cond(srv, con, dc)) continue; | |
18788 | - | |
18789 | + | |
18790 | /* merge config */ | |
18791 | for (j = 0; j < dc->value->used; j++) { | |
18792 | data_unset *du = dc->value->data[j]; | |
18793 | - | |
18794 | + | |
18795 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.cache-dir"))) { | |
18796 | - PATCH(compress_cache_dir); | |
18797 | + PATCH_OPTION(compress_cache_dir); | |
18798 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.filetype"))) { | |
18799 | - PATCH(compress); | |
18800 | + PATCH_OPTION(compress); | |
18801 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.max-filesize"))) { | |
18802 | - PATCH(compress_max_filesize); | |
18803 | + PATCH_OPTION(compress_max_filesize); | |
18804 | } | |
18805 | } | |
18806 | } | |
18807 | - | |
18808 | + | |
18809 | return 0; | |
18810 | } | |
18811 | -#undef PATCH | |
18812 | ||
18813 | PHYSICALPATH_FUNC(mod_compress_physical) { | |
18814 | plugin_data *p = p_d; | |
18815 | size_t m; | |
18816 | off_t max_fsize; | |
18817 | stat_cache_entry *sce = NULL; | |
18818 | - | |
18819 | + | |
18820 | /* only GET and POST can get compressed */ | |
18821 | - if (con->request.http_method != HTTP_METHOD_GET && | |
18822 | + if (con->request.http_method != HTTP_METHOD_GET && | |
18823 | con->request.http_method != HTTP_METHOD_POST) { | |
18824 | return HANDLER_GO_ON; | |
18825 | } | |
18826 | @@ -579,46 +619,49 @@ | |
18827 | if (buffer_is_empty(con->physical.path)) { | |
18828 | return HANDLER_GO_ON; | |
18829 | } | |
18830 | - | |
18831 | + | |
18832 | mod_compress_patch_connection(srv, con, p); | |
18833 | - | |
18834 | + | |
18835 | max_fsize = p->conf.compress_max_filesize; | |
18836 | ||
18837 | stat_cache_get_entry(srv, con, con->physical.path, &sce); | |
18838 | ||
18839 | /* don't compress files that are too large as we need to much time to handle them */ | |
18840 | if (max_fsize && (sce->st.st_size >> 10) > max_fsize) return HANDLER_GO_ON; | |
18841 | - | |
18842 | + | |
18843 | + /* compressing the file might lead to larger files instead */ | |
18844 | + if (sce->st.st_size < 128) return HANDLER_GO_ON; | |
18845 | + | |
18846 | /* check if mimetype is in compress-config */ | |
18847 | for (m = 0; m < p->conf.compress->used; m++) { | |
18848 | data_string *compress_ds = (data_string *)p->conf.compress->data[m]; | |
18849 | - | |
18850 | + | |
18851 | if (!compress_ds) { | |
18852 | log_error_write(srv, __FILE__, __LINE__, "sbb", "evil", con->physical.path, con->uri.path); | |
18853 | - | |
18854 | + | |
18855 | return HANDLER_GO_ON; | |
18856 | } | |
18857 | - | |
18858 | + | |
18859 | if (buffer_is_equal(compress_ds->value, sce->content_type)) { | |
18860 | /* mimetype found */ | |
18861 | data_string *ds; | |
18862 | - | |
18863 | + | |
18864 | /* the response might change according to Accept-Encoding */ | |
18865 | response_header_insert(srv, con, CONST_STR_LEN("Vary"), CONST_STR_LEN("Accept-Encoding")); | |
18866 | - | |
18867 | + | |
18868 | if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Encoding"))) { | |
18869 | int accept_encoding = 0; | |
18870 | char *value = ds->value->ptr; | |
18871 | int srv_encodings = 0; | |
18872 | int matched_encodings = 0; | |
18873 | - | |
18874 | + | |
18875 | /* get client side support encodings */ | |
18876 | if (NULL != strstr(value, "gzip")) accept_encoding |= HTTP_ACCEPT_ENCODING_GZIP; | |
18877 | if (NULL != strstr(value, "deflate")) accept_encoding |= HTTP_ACCEPT_ENCODING_DEFLATE; | |
18878 | if (NULL != strstr(value, "compress")) accept_encoding |= HTTP_ACCEPT_ENCODING_COMPRESS; | |
18879 | if (NULL != strstr(value, "bzip2")) accept_encoding |= HTTP_ACCEPT_ENCODING_BZIP2; | |
18880 | if (NULL != strstr(value, "identity")) accept_encoding |= HTTP_ACCEPT_ENCODING_IDENTITY; | |
18881 | - | |
18882 | + | |
18883 | /* get server side supported ones */ | |
18884 | #ifdef USE_BZ2LIB | |
18885 | srv_encodings |= HTTP_ACCEPT_ENCODING_BZIP2; | |
18886 | @@ -627,18 +670,31 @@ | |
18887 | srv_encodings |= HTTP_ACCEPT_ENCODING_GZIP; | |
18888 | srv_encodings |= HTTP_ACCEPT_ENCODING_DEFLATE; | |
18889 | #endif | |
18890 | - | |
18891 | + | |
18892 | /* find matching entries */ | |
18893 | matched_encodings = accept_encoding & srv_encodings; | |
18894 | - | |
18895 | + | |
18896 | if (matched_encodings) { | |
18897 | const char *dflt_gzip = "gzip"; | |
18898 | const char *dflt_deflate = "deflate"; | |
18899 | const char *dflt_bzip2 = "bzip2"; | |
18900 | - | |
18901 | + | |
18902 | const char *compression_name = NULL; | |
18903 | int compression_type = 0; | |
18904 | - | |
18905 | + buffer *mtime; | |
18906 | + | |
18907 | + mtime = strftime_cache_get(srv, sce->st.st_mtime); | |
18908 | + etag_mutate(con->physical.etag, sce->etag); | |
18909 | + | |
18910 | + response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); | |
18911 | + response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); | |
18912 | + | |
18913 | + /* perhaps we don't even have to compress the file as the browser still has the | |
18914 | + * current version */ | |
18915 | + if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) { | |
18916 | + return HANDLER_FINISHED; | |
18917 | + } | |
18918 | + | |
18919 | /* select best matching encoding */ | |
18920 | if (matched_encodings & HTTP_ACCEPT_ENCODING_BZIP2) { | |
18921 | compression_type = HTTP_ACCEPT_ENCODING_BZIP2; | |
18922 | @@ -650,31 +706,21 @@ | |
18923 | compression_type = HTTP_ACCEPT_ENCODING_DEFLATE; | |
18924 | compression_name = dflt_deflate; | |
18925 | } | |
18926 | - | |
18927 | - /* deflate it */ | |
18928 | - if (p->conf.compress_cache_dir->used) { | |
18929 | - if (0 == deflate_file_to_file(srv, con, p, | |
18930 | - con->physical.path, sce, compression_type)) { | |
18931 | - buffer *mtime; | |
18932 | - | |
18933 | - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name)); | |
18934 | - | |
18935 | - mtime = strftime_cache_get(srv, sce->st.st_mtime); | |
18936 | - response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); | |
18937 | - | |
18938 | - etag_mutate(con->physical.etag, sce->etag); | |
18939 | - response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); | |
18940 | - | |
18941 | - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); | |
18942 | - | |
18943 | - return HANDLER_GO_ON; | |
18944 | - } | |
18945 | - } else if (0 == deflate_file_to_buffer(srv, con, p, | |
18946 | - con->physical.path, sce, compression_type)) { | |
18947 | - | |
18948 | - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name)); | |
18949 | - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); | |
18950 | - | |
18951 | + | |
18952 | + /* deflate it to file (cached) or to memory */ | |
18953 | + if (0 == deflate_file_to_file(srv, con, p, | |
18954 | + con->physical.path, sce, compression_type) || | |
18955 | + 0 == deflate_file_to_buffer(srv, con, p, | |
18956 | + con->physical.path, sce, compression_type)) { | |
18957 | + | |
18958 | + response_header_overwrite(srv, con, | |
18959 | + CONST_STR_LEN("Content-Encoding"), | |
18960 | + compression_name, strlen(compression_name)); | |
18961 | + | |
18962 | + response_header_overwrite(srv, con, | |
18963 | + CONST_STR_LEN("Content-Type"), | |
18964 | + CONST_BUF_LEN(sce->content_type)); | |
18965 | + | |
18966 | return HANDLER_FINISHED; | |
18967 | } | |
18968 | break; | |
18969 | @@ -682,20 +728,20 @@ | |
18970 | } | |
18971 | } | |
18972 | } | |
18973 | - | |
18974 | + | |
18975 | return HANDLER_GO_ON; | |
18976 | } | |
18977 | ||
18978 | int mod_compress_plugin_init(plugin *p) { | |
18979 | p->version = LIGHTTPD_VERSION_ID; | |
18980 | p->name = buffer_init_string("compress"); | |
18981 | - | |
18982 | + | |
18983 | p->init = mod_compress_init; | |
18984 | p->set_defaults = mod_compress_setdefaults; | |
18985 | p->handle_subrequest_start = mod_compress_physical; | |
18986 | p->cleanup = mod_compress_free; | |
18987 | - | |
18988 | + | |
18989 | p->data = NULL; | |
18990 | - | |
18991 | + | |
18992 | return 0; | |
18993 | } | |
1175ccec ER |
18994 | --- ../lighttpd-1.4.11/src/mod_dirlisting.c 2006-01-13 00:00:45.000000000 +0200 |
18995 | +++ lighttpd-1.4.12/src/mod_dirlisting.c 2006-07-15 22:43:21.000000000 +0300 | |
2519e6e5 ER |
18996 | @@ -1,11 +1,9 @@ |
18997 | #include <ctype.h> | |
18998 | #include <stdlib.h> | |
18999 | #include <string.h> | |
19000 | -#include <dirent.h> | |
19001 | #include <assert.h> | |
19002 | #include <errno.h> | |
19003 | #include <stdio.h> | |
19004 | -#include <unistd.h> | |
19005 | #include <time.h> | |
19006 | ||
19007 | #include "base.h" | |
1175ccec ER |
19008 | @@ -17,6 +15,9 @@ |
19009 | #include "response.h" | |
19010 | #include "stat_cache.h" | |
19011 | #include "stream.h" | |
19012 | +#include "etag.h" | |
19013 | + | |
19014 | +#include "sys-strings.h" | |
19015 | ||
19016 | /** | |
19017 | * this is a dirlisting for a lighttpd plugin | |
19018 | @@ -27,10 +28,13 @@ | |
19019 | #include <sys/syslimits.h> | |
19020 | #endif | |
19021 | ||
19022 | -#ifdef HAVE_ATTR_ATTRIBUTES_H | |
19023 | +#ifdef HAVE_XATTR | |
2519e6e5 ER |
19024 | #include <attr/attributes.h> |
19025 | #endif | |
19026 | ||
19027 | +#include "sys-files.h" | |
19028 | +#include "sys-strings.h" | |
19029 | + | |
19030 | /* plugin config for all request/connections */ | |
19031 | ||
19032 | typedef struct { | |
1175ccec | 19033 | @@ -54,7 +58,7 @@ |
2519e6e5 ER |
19034 | unsigned short hide_readme_file; |
19035 | unsigned short show_header; | |
19036 | unsigned short hide_header_file; | |
19037 | - | |
19038 | + | |
19039 | excludes_buffer *excludes; | |
19040 | ||
19041 | buffer *external_css; | |
1175ccec | 19042 | @@ -63,13 +67,14 @@ |
2519e6e5 ER |
19043 | |
19044 | typedef struct { | |
19045 | PLUGIN_DATA; | |
19046 | - | |
19047 | + | |
19048 | buffer *tmp_buf; | |
19049 | buffer *content_charset; | |
19050 | - | |
1175ccec | 19051 | + buffer *path; |
2519e6e5 ER |
19052 | + |
19053 | plugin_config **config_storage; | |
19054 | - | |
19055 | - plugin_config conf; | |
19056 | + | |
19057 | + plugin_config conf; | |
19058 | } plugin_data; | |
19059 | ||
19060 | excludes_buffer *excludes_buffer_init(void) { | |
1175ccec | 19061 | @@ -146,44 +151,46 @@ |
2519e6e5 ER |
19062 | /* init the plugin data */ |
19063 | INIT_FUNC(mod_dirlisting_init) { | |
19064 | plugin_data *p; | |
19065 | - | |
19066 | + | |
19067 | p = calloc(1, sizeof(*p)); | |
19068 | ||
19069 | p->tmp_buf = buffer_init(); | |
19070 | p->content_charset = buffer_init(); | |
19071 | - | |
1175ccec | 19072 | + p->path = buffer_init(); |
2519e6e5 ER |
19073 | + |
19074 | return p; | |
19075 | } | |
19076 | ||
19077 | /* detroy the plugin data */ | |
19078 | FREE_FUNC(mod_dirlisting_free) { | |
19079 | plugin_data *p = p_d; | |
19080 | - | |
19081 | + | |
19082 | UNUSED(srv); | |
19083 | ||
19084 | if (!p) return HANDLER_GO_ON; | |
19085 | - | |
19086 | + | |
19087 | if (p->config_storage) { | |
19088 | size_t i; | |
19089 | for (i = 0; i < srv->config_context->used; i++) { | |
19090 | plugin_config *s = p->config_storage[i]; | |
19091 | - | |
19092 | + | |
19093 | if (!s) continue; | |
19094 | - | |
19095 | + | |
19096 | excludes_buffer_free(s->excludes); | |
19097 | buffer_free(s->external_css); | |
19098 | buffer_free(s->encoding); | |
19099 | - | |
19100 | + | |
19101 | free(s); | |
19102 | } | |
19103 | free(p->config_storage); | |
19104 | } | |
19105 | - | |
19106 | + | |
19107 | buffer_free(p->tmp_buf); | |
1175ccec | 19108 | + buffer_free(p->path); |
2519e6e5 ER |
19109 | buffer_free(p->content_charset); |
19110 | - | |
19111 | + | |
19112 | free(p); | |
19113 | - | |
19114 | + | |
19115 | return HANDLER_GO_ON; | |
19116 | } | |
19117 | ||
1175ccec | 19118 | @@ -215,10 +222,10 @@ |
2519e6e5 ER |
19119 | if (0 != excludes_buffer_append(s->excludes, |
19120 | ((data_string *)(da->value->data[j]))->value)) { | |
19121 | #ifdef HAVE_PCRE_H | |
19122 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
19123 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
19124 | "pcre-compile failed for", ((data_string *)(da->value->data[j]))->value); | |
19125 | #else | |
19126 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
19127 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
19128 | "pcre support is missing, please install libpcre and the headers"); | |
19129 | #endif | |
19130 | } | |
1175ccec | 19131 | @@ -233,8 +240,8 @@ |
2519e6e5 ER |
19132 | SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) { |
19133 | plugin_data *p = p_d; | |
19134 | size_t i = 0; | |
19135 | - | |
19136 | - config_values_t cv[] = { | |
19137 | + | |
19138 | + config_values_t cv[] = { | |
19139 | { "dir-listing.exclude", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
19140 | { "dir-listing.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
19141 | { "dir-listing.hide-dotfiles", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
1175ccec | 19142 | @@ -245,18 +252,18 @@ |
2519e6e5 ER |
19143 | { "dir-listing.show-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */ |
19144 | { "dir-listing.hide-header-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */ | |
19145 | { "server.dir-listing", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 9 */ | |
19146 | - | |
19147 | + | |
19148 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
19149 | }; | |
19150 | - | |
19151 | + | |
19152 | if (!p) return HANDLER_ERROR; | |
19153 | - | |
19154 | + | |
19155 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
19156 | - | |
19157 | + | |
19158 | for (i = 0; i < srv->config_context->used; i++) { | |
19159 | plugin_config *s; | |
19160 | array *ca; | |
19161 | - | |
19162 | + | |
19163 | s = calloc(1, sizeof(plugin_config)); | |
19164 | s->excludes = excludes_buffer_init(); | |
19165 | s->dir_listing = 0; | |
1175ccec | 19166 | @@ -267,7 +274,7 @@ |
2519e6e5 ER |
19167 | s->show_header = 0; |
19168 | s->hide_header_file = 0; | |
19169 | s->encoding = buffer_init(); | |
19170 | - | |
19171 | + | |
19172 | cv[0].destination = s->excludes; | |
19173 | cv[1].destination = &(s->dir_listing); | |
19174 | cv[2].destination = &(s->hide_dot_files); | |
1175ccec | 19175 | @@ -292,60 +299,57 @@ |
2519e6e5 ER |
19176 | return HANDLER_GO_ON; |
19177 | } | |
19178 | ||
19179 | -#define PATCH(x) \ | |
19180 | - p->conf.x = s->x; | |
19181 | static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_data *p) { | |
19182 | size_t i, j; | |
19183 | plugin_config *s = p->config_storage[0]; | |
19184 | ||
19185 | - PATCH(dir_listing); | |
19186 | - PATCH(external_css); | |
19187 | - PATCH(hide_dot_files); | |
19188 | - PATCH(encoding); | |
19189 | - PATCH(show_readme); | |
19190 | - PATCH(hide_readme_file); | |
19191 | - PATCH(show_header); | |
19192 | - PATCH(hide_header_file); | |
19193 | - PATCH(excludes); | |
19194 | - | |
19195 | + PATCH_OPTION(dir_listing); | |
19196 | + PATCH_OPTION(external_css); | |
19197 | + PATCH_OPTION(hide_dot_files); | |
19198 | + PATCH_OPTION(encoding); | |
19199 | + PATCH_OPTION(show_readme); | |
19200 | + PATCH_OPTION(hide_readme_file); | |
19201 | + PATCH_OPTION(show_header); | |
19202 | + PATCH_OPTION(hide_header_file); | |
19203 | + PATCH_OPTION(excludes); | |
19204 | + | |
19205 | /* skip the first, the global context */ | |
19206 | for (i = 1; i < srv->config_context->used; i++) { | |
19207 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
19208 | s = p->config_storage[i]; | |
19209 | - | |
19210 | + | |
19211 | /* condition didn't match */ | |
19212 | if (!config_check_cond(srv, con, dc)) continue; | |
19213 | - | |
19214 | + | |
19215 | /* merge config */ | |
19216 | for (j = 0; j < dc->value->used; j++) { | |
19217 | data_unset *du = dc->value->data[j]; | |
19218 | - | |
19219 | + | |
19220 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.activate")) || | |
19221 | buffer_is_equal_string(du->key, CONST_STR_LEN("server.dir-listing"))) { | |
19222 | - PATCH(dir_listing); | |
19223 | + PATCH_OPTION(dir_listing); | |
19224 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-dotfiles"))) { | |
19225 | - PATCH(hide_dot_files); | |
19226 | + PATCH_OPTION(hide_dot_files); | |
19227 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.external-css"))) { | |
19228 | - PATCH(external_css); | |
19229 | + PATCH_OPTION(external_css); | |
19230 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.encoding"))) { | |
19231 | - PATCH(encoding); | |
19232 | + PATCH_OPTION(encoding); | |
19233 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-readme"))) { | |
19234 | - PATCH(show_readme); | |
19235 | + PATCH_OPTION(show_readme); | |
19236 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-readme-file"))) { | |
19237 | - PATCH(hide_readme_file); | |
19238 | + PATCH_OPTION(hide_readme_file); | |
19239 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-header"))) { | |
19240 | - PATCH(show_header); | |
19241 | + PATCH_OPTION(show_header); | |
19242 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-header-file"))) { | |
19243 | - PATCH(hide_header_file); | |
19244 | + PATCH_OPTION(hide_header_file); | |
19245 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.excludes"))) { | |
19246 | - PATCH(excludes); | |
19247 | + PATCH_OPTION(excludes); | |
19248 | } | |
19249 | } | |
19250 | } | |
19251 | - | |
19252 | + | |
19253 | return 0; | |
19254 | } | |
19255 | -#undef PATCH | |
19256 | ||
19257 | typedef struct { | |
19258 | size_t namelen; | |
1175ccec | 19259 | @@ -432,7 +436,7 @@ |
2519e6e5 ER |
19260 | |
19261 | static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) { | |
19262 | UNUSED(srv); | |
19263 | - | |
19264 | + | |
19265 | BUFFER_APPEND_STRING_CONST(out, | |
19266 | "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n" | |
19267 | "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n" | |
1175ccec | 19268 | @@ -492,11 +496,11 @@ |
2519e6e5 ER |
19269 | if (p->conf.show_header) { |
19270 | stream s; | |
19271 | /* if we have a HEADER file, display it in <pre class="header"></pre> */ | |
19272 | - | |
19273 | + | |
19274 | buffer_copy_string_buffer(p->tmp_buf, con->physical.path); | |
19275 | - BUFFER_APPEND_SLASH(p->tmp_buf); | |
19276 | + PATHNAME_APPEND_SLASH(p->tmp_buf); | |
19277 | BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt"); | |
19278 | - | |
19279 | + | |
19280 | if (-1 != stream_open(&s, p->tmp_buf)) { | |
19281 | BUFFER_APPEND_STRING_CONST(out, "<pre class=\"header\">"); | |
19282 | buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML); | |
1175ccec | 19283 | @@ -531,21 +535,21 @@ |
2519e6e5 ER |
19284 | |
19285 | static void http_list_directory_footer(server *srv, connection *con, plugin_data *p, buffer *out) { | |
19286 | UNUSED(srv); | |
19287 | - | |
19288 | + | |
19289 | BUFFER_APPEND_STRING_CONST(out, | |
19290 | "</tbody>\n" | |
19291 | "</table>\n" | |
19292 | "</div>\n" | |
19293 | ); | |
19294 | - | |
19295 | + | |
19296 | if (p->conf.show_readme) { | |
19297 | stream s; | |
19298 | /* if we have a README file, display it in <pre class="readme"></pre> */ | |
19299 | - | |
19300 | + | |
19301 | buffer_copy_string_buffer(p->tmp_buf, con->physical.path); | |
19302 | - BUFFER_APPEND_SLASH(p->tmp_buf); | |
19303 | + PATHNAME_APPEND_SLASH(p->tmp_buf); | |
19304 | BUFFER_APPEND_STRING_CONST(p->tmp_buf, "README.txt"); | |
19305 | - | |
19306 | + | |
19307 | if (-1 != stream_open(&s, p->tmp_buf)) { | |
19308 | BUFFER_APPEND_STRING_CONST(out, "<pre class=\"readme\">"); | |
19309 | buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML); | |
1175ccec | 19310 | @@ -553,7 +557,7 @@ |
2519e6e5 ER |
19311 | } |
19312 | stream_close(&s); | |
19313 | } | |
19314 | - | |
19315 | + | |
19316 | BUFFER_APPEND_STRING_CONST(out, | |
19317 | "<div class=\"foot\">" | |
19318 | ); | |
1175ccec ER |
19319 | @@ -576,7 +580,6 @@ |
19320 | buffer *out; | |
19321 | struct dirent *dent; | |
19322 | struct stat st; | |
19323 | - char *path, *path_file; | |
19324 | size_t i; | |
19325 | int hide_dotfiles = p->conf.hide_dot_files; | |
19326 | dirls_list_t dirs, files, *list; | |
19327 | @@ -586,6 +589,7 @@ | |
19328 | size_t k; | |
19329 | const char *content_type; | |
19330 | long name_max; | |
19331 | + | |
19332 | #ifdef HAVE_XATTR | |
19333 | char attrval[128]; | |
19334 | int attrlen; | |
19335 | @@ -594,10 +598,10 @@ | |
19336 | struct tm tm; | |
2519e6e5 ER |
19337 | #endif |
19338 | ||
1175ccec | 19339 | - if (dir->used == 0) return -1; |
2519e6e5 | 19340 | - |
1175ccec ER |
19341 | - i = dir->used - 1; |
19342 | + /* empty pathname, never ... */ | |
19343 | + if (buffer_is_empty(dir)) return -1; | |
2519e6e5 | 19344 | |
1175ccec | 19345 | + /* max-length for the opendir */ |
2519e6e5 | 19346 | #ifdef HAVE_PATHCONF |
1175ccec ER |
19347 | if (-1 == (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) { |
19348 | #ifdef NAME_MAX | |
19349 | @@ -606,22 +610,24 @@ | |
2519e6e5 ER |
19350 | name_max = 256; /* stupid default */ |
19351 | #endif | |
19352 | } | |
19353 | -#elif defined __WIN32 | |
19354 | +#elif defined _WIN32 | |
19355 | name_max = FILENAME_MAX; | |
19356 | #else | |
19357 | name_max = NAME_MAX; | |
19358 | #endif | |
19359 | - | |
1175ccec ER |
19360 | - path = malloc(dir->used + name_max); |
19361 | - assert(path); | |
19362 | - strcpy(path, dir->ptr); | |
19363 | - path_file = path + i; | |
19364 | ||
19365 | - if (NULL == (dp = opendir(path))) { | |
19366 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
19367 | + buffer_copy_string_buffer(p->path, dir); | |
19368 | + PATHNAME_APPEND_SLASH(p->path); | |
2519e6e5 | 19369 | + |
2519e6e5 | 19370 | +#ifdef _WIN32 |
1175ccec ER |
19371 | + /* append *.* to the path */ |
19372 | + buffer_append_string(path, "*.*"); | |
2519e6e5 | 19373 | +#endif |
1175ccec ER |
19374 | + |
19375 | + if (NULL == (dp = opendir(p->path->ptr))) { | |
2519e6e5 ER |
19376 | + log_error_write(srv, __FILE__, __LINE__, "sbs", |
19377 | "opendir failed:", dir, strerror(errno)); | |
19378 | ||
1175ccec ER |
19379 | - free(path); |
19380 | return -1; | |
19381 | } | |
19382 | ||
19383 | @@ -633,7 +639,7 @@ | |
2519e6e5 ER |
19384 | assert(files.ent); |
19385 | files.size = DIRLIST_BLOB_SIZE; | |
19386 | files.used = 0; | |
19387 | - | |
19388 | + | |
19389 | while ((dent = readdir(dp)) != NULL) { | |
19390 | unsigned short exclude_match = 0; | |
19391 | ||
1175ccec | 19392 | @@ -686,15 +692,21 @@ |
2519e6e5 ER |
19393 | #endif |
19394 | ||
19395 | i = strlen(dent->d_name); | |
19396 | - | |
19397 | + | |
19398 | /* NOTE: the manual says, d_name is never more than NAME_MAX | |
19399 | * so this should actually not be a buffer-overflow-risk | |
19400 | */ | |
19401 | if (i > (size_t)name_max) continue; | |
19402 | - | |
1175ccec | 19403 | - memcpy(path_file, dent->d_name, i + 1); |
2519e6e5 | 19404 | - if (stat(path, &st) != 0) |
1175ccec ER |
19405 | + |
19406 | + /* build the dirname */ | |
19407 | + buffer_copy_string_buffer(p->path, dir); | |
19408 | + PATHNAME_APPEND_SLASH(p->path); | |
19409 | + buffer_append_string(p->path, dent->d_name); | |
19410 | + | |
19411 | + if (stat(p->path->ptr, &st) != 0) { | |
19412 | + fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, p->path->ptr, strerror(errno)); | |
2519e6e5 | 19413 | continue; |
1175ccec | 19414 | + } |
2519e6e5 ER |
19415 | |
19416 | list = &files; | |
19417 | if (S_ISDIR(st.st_mode)) | |
1175ccec | 19418 | @@ -740,7 +752,7 @@ |
2519e6e5 ER |
19419 | #else |
19420 | strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime))); | |
19421 | #endif | |
19422 | - | |
19423 | + | |
19424 | BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\""); | |
19425 | buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART); | |
19426 | BUFFER_APPEND_STRING_CONST(out, "/\">"); | |
1175ccec ER |
19427 | @@ -757,18 +769,22 @@ |
19428 | tmp = files.ent[i]; | |
2519e6e5 ER |
19429 | |
19430 | content_type = NULL; | |
1175ccec | 19431 | + |
2519e6e5 ER |
19432 | #ifdef HAVE_XATTR |
19433 | - | |
2519e6e5 | 19434 | if (con->conf.use_xattr) { |
1175ccec ER |
19435 | - memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1); |
19436 | + /* build the dirname */ | |
19437 | + buffer_copy_string_buffer(p->path, dir); | |
19438 | + PATHNAME_APPEND_SLASH(p->path); | |
19439 | + buffer_append_string_len(p->path, DIRLIST_ENT_NAME(tmp), tmp->namelen); | |
19440 | + | |
2519e6e5 | 19441 | attrlen = sizeof(attrval) - 1; |
1175ccec ER |
19442 | - if (attr_get(path, "Content-Type", attrval, &attrlen, 0) == 0) { |
19443 | + if (attr_get(p->path->ptr, "Content-Type", attrval, &attrlen, 0) == 0) { | |
19444 | attrval[attrlen] = '\0'; | |
19445 | content_type = attrval; | |
2519e6e5 ER |
19446 | } |
19447 | } | |
19448 | #endif | |
19449 | - | |
19450 | + | |
19451 | if (content_type == NULL) { | |
19452 | content_type = "application/octet-stream"; | |
19453 | for (k = 0; k < con->conf.mimetypes->used; k++) { | |
1175ccec | 19454 | @@ -788,7 +804,7 @@ |
2519e6e5 ER |
19455 | } |
19456 | } | |
19457 | } | |
19458 | - | |
19459 | + | |
19460 | #ifdef HAVE_LOCALTIME_R | |
19461 | localtime_r(&(tmp->mtime), &tm); | |
19462 | strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm); | |
1175ccec ER |
19463 | @@ -814,7 +830,6 @@ |
19464 | ||
19465 | free(files.ent); | |
19466 | free(dirs.ent); | |
19467 | - free(path); | |
19468 | ||
19469 | http_list_directory_footer(srv, con, p, out); | |
19470 | ||
19471 | @@ -837,36 +852,55 @@ | |
2519e6e5 ER |
19472 | URIHANDLER_FUNC(mod_dirlisting_subrequest) { |
19473 | plugin_data *p = p_d; | |
19474 | stat_cache_entry *sce = NULL; | |
19475 | - | |
1175ccec | 19476 | - UNUSED(srv); |
2519e6e5 | 19477 | - |
1175ccec ER |
19478 | - if (con->physical.path->used == 0) return HANDLER_GO_ON; |
19479 | - if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
19480 | + buffer *mtime; | |
19481 | + data_string *ds; | |
2519e6e5 | 19482 | + |
1175ccec | 19483 | + if (con->uri.path->used < 2) return HANDLER_GO_ON; |
2519e6e5 ER |
19484 | if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON; |
19485 | - | |
1175ccec | 19486 | + if (con->physical.path->used == 0) return HANDLER_GO_ON; |
2519e6e5 ER |
19487 | + |
19488 | mod_dirlisting_patch_connection(srv, con, p); | |
19489 | ||
19490 | if (!p->conf.dir_listing) return HANDLER_GO_ON; | |
19491 | - | |
1175ccec ER |
19492 | + |
19493 | + if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) { | |
19494 | + /* just a second ago the file was still there */ | |
19495 | + return HANDLER_GO_ON; | |
19496 | + } | |
19497 | + | |
19498 | + if (!S_ISDIR(sce->st.st_mode)) return HANDLER_GO_ON; | |
2519e6e5 ER |
19499 | + |
19500 | if (con->conf.log_request_handling) { | |
19501 | log_error_write(srv, __FILE__, __LINE__, "s", "-- handling the request as Dir-Listing"); | |
19502 | log_error_write(srv, __FILE__, __LINE__, "sb", "URI :", con->uri.path); | |
19503 | } | |
19504 | - | |
1175ccec ER |
19505 | - if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) { |
19506 | - fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, con->physical.path->ptr); | |
19507 | - SEGFAULT(); | |
2519e6e5 | 19508 | + |
1175ccec ER |
19509 | + /* perhaps this a cachable request |
19510 | + * - we use the etag of the directory | |
19511 | + * */ | |
19512 | + | |
19513 | + etag_mutate(con->physical.etag, sce->etag); | |
19514 | + response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); | |
19515 | + | |
19516 | + /* prepare header */ | |
19517 | + if (NULL == (ds = (data_string *)array_get_element(con->response.headers, "Last-Modified"))) { | |
19518 | + mtime = strftime_cache_get(srv, sce->st.st_mtime); | |
19519 | + response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); | |
19520 | + } else { | |
19521 | + mtime = ds->value; | |
2519e6e5 ER |
19522 | } |
19523 | - | |
1175ccec | 19524 | - if (!S_ISDIR(sce->st.st_mode)) return HANDLER_GO_ON; |
2519e6e5 | 19525 | - |
1175ccec ER |
19526 | + |
19527 | + if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) { | |
19528 | + return HANDLER_FINISHED; | |
19529 | + } | |
2519e6e5 ER |
19530 | + |
19531 | if (http_list_directory(srv, con, p, con->physical.path)) { | |
19532 | /* dirlisting failed */ | |
19533 | con->http_status = 403; | |
19534 | } | |
19535 | - | |
19536 | + | |
19537 | buffer_reset(con->physical.path); | |
19538 | - | |
19539 | + | |
19540 | /* not found */ | |
19541 | return HANDLER_FINISHED; | |
19542 | } | |
1175ccec | 19543 | @@ -876,13 +910,13 @@ |
2519e6e5 ER |
19544 | int mod_dirlisting_plugin_init(plugin *p) { |
19545 | p->version = LIGHTTPD_VERSION_ID; | |
19546 | p->name = buffer_init_string("dirlisting"); | |
19547 | - | |
19548 | + | |
19549 | p->init = mod_dirlisting_init; | |
19550 | p->handle_subrequest_start = mod_dirlisting_subrequest; | |
19551 | p->set_defaults = mod_dirlisting_set_defaults; | |
19552 | p->cleanup = mod_dirlisting_free; | |
19553 | - | |
19554 | + | |
19555 | p->data = NULL; | |
19556 | - | |
19557 | + | |
19558 | return 0; | |
19559 | } | |
1175ccec | 19560 | --- ../lighttpd-1.4.11/src/mod_evasive.c 2006-01-04 15:24:51.000000000 +0200 |
36e2a29e | 19561 | +++ lighttpd-1.4.12/src/mod_evasive.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
19562 | @@ -31,100 +31,97 @@ |
19563 | ||
19564 | typedef struct { | |
19565 | PLUGIN_DATA; | |
19566 | - | |
19567 | + | |
19568 | plugin_config **config_storage; | |
19569 | - | |
19570 | - plugin_config conf; | |
19571 | + | |
19572 | + plugin_config conf; | |
19573 | } plugin_data; | |
19574 | ||
19575 | INIT_FUNC(mod_evasive_init) { | |
19576 | plugin_data *p; | |
19577 | - | |
19578 | + | |
19579 | p = calloc(1, sizeof(*p)); | |
19580 | - | |
19581 | + | |
19582 | return p; | |
19583 | } | |
19584 | ||
19585 | FREE_FUNC(mod_evasive_free) { | |
19586 | plugin_data *p = p_d; | |
19587 | - | |
19588 | + | |
19589 | UNUSED(srv); | |
19590 | ||
19591 | if (!p) return HANDLER_GO_ON; | |
19592 | - | |
19593 | + | |
19594 | if (p->config_storage) { | |
19595 | size_t i; | |
19596 | for (i = 0; i < srv->config_context->used; i++) { | |
19597 | plugin_config *s = p->config_storage[i]; | |
19598 | - | |
19599 | + | |
19600 | free(s); | |
19601 | } | |
19602 | free(p->config_storage); | |
19603 | } | |
19604 | - | |
19605 | + | |
19606 | free(p); | |
19607 | - | |
19608 | + | |
19609 | return HANDLER_GO_ON; | |
19610 | } | |
19611 | ||
19612 | SETDEFAULTS_FUNC(mod_evasive_set_defaults) { | |
19613 | plugin_data *p = p_d; | |
19614 | size_t i = 0; | |
19615 | - | |
19616 | - config_values_t cv[] = { | |
19617 | + | |
19618 | + config_values_t cv[] = { | |
19619 | { "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, | |
19620 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
19621 | }; | |
19622 | - | |
19623 | + | |
19624 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
19625 | - | |
19626 | + | |
19627 | for (i = 0; i < srv->config_context->used; i++) { | |
19628 | plugin_config *s; | |
19629 | - | |
19630 | + | |
19631 | s = calloc(1, sizeof(plugin_config)); | |
19632 | s->max_conns = 0; | |
19633 | - | |
19634 | + | |
19635 | cv[0].destination = &(s->max_conns); | |
19636 | - | |
19637 | + | |
19638 | p->config_storage[i] = s; | |
19639 | - | |
19640 | + | |
19641 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
19642 | return HANDLER_ERROR; | |
19643 | } | |
19644 | } | |
19645 | - | |
19646 | + | |
19647 | return HANDLER_GO_ON; | |
19648 | } | |
19649 | ||
19650 | -#define PATCH(x) \ | |
19651 | - p->conf.x = s->x; | |
19652 | static int mod_evasive_patch_connection(server *srv, connection *con, plugin_data *p) { | |
19653 | size_t i, j; | |
19654 | plugin_config *s = p->config_storage[0]; | |
19655 | ||
19656 | - PATCH(max_conns); | |
19657 | - | |
19658 | + PATCH_OPTION(max_conns); | |
19659 | + | |
19660 | /* skip the first, the global context */ | |
19661 | for (i = 1; i < srv->config_context->used; i++) { | |
19662 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
19663 | s = p->config_storage[i]; | |
19664 | - | |
19665 | + | |
19666 | /* condition didn't match */ | |
19667 | if (!config_check_cond(srv, con, dc)) continue; | |
19668 | - | |
19669 | + | |
19670 | /* merge config */ | |
19671 | for (j = 0; j < dc->value->used; j++) { | |
19672 | data_unset *du = dc->value->data[j]; | |
19673 | - | |
19674 | + | |
19675 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) { | |
19676 | - PATCH(max_conns); | |
19677 | + PATCH_OPTION(max_conns); | |
19678 | } | |
19679 | } | |
19680 | } | |
19681 | - | |
19682 | + | |
19683 | return 0; | |
19684 | } | |
19685 | -#undef PATCH | |
19686 | ||
19687 | URIHANDLER_FUNC(mod_evasive_uri_handler) { | |
19688 | plugin_data *p = p_d; | |
19689 | @@ -132,10 +129,10 @@ | |
19690 | size_t j; | |
19691 | ||
19692 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
19693 | - | |
19694 | + | |
19695 | mod_evasive_patch_connection(srv, con, p); | |
19696 | - | |
19697 | - /* no limit set, nothing to block */ | |
19698 | + | |
19699 | + /* no limit set, nothing to block */ | |
19700 | if (p->conf.max_conns == 0) return HANDLER_GO_ON; | |
19701 | ||
19702 | for (j = 0; j < srv->conns->used; j++) { | |
19703 | @@ -147,7 +144,7 @@ | |
19704 | if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr && | |
19705 | c->state > CON_STATE_REQUEST_END) { | |
19706 | conns_by_ip++; | |
19707 | - | |
19708 | + | |
19709 | if (conns_by_ip > p->conf.max_conns) { | |
19710 | log_error_write(srv, __FILE__, __LINE__, "ss", | |
19711 | inet_ntop_cache_get_ip(srv, &(con->dst_addr)), | |
19712 | @@ -158,7 +155,7 @@ | |
19713 | } | |
19714 | } | |
19715 | } | |
19716 | - | |
19717 | + | |
19718 | return HANDLER_GO_ON; | |
19719 | } | |
19720 | ||
19721 | @@ -166,13 +163,13 @@ | |
19722 | int mod_evasive_plugin_init(plugin *p) { | |
19723 | p->version = LIGHTTPD_VERSION_ID; | |
19724 | p->name = buffer_init_string("evasive"); | |
19725 | - | |
19726 | + | |
19727 | p->init = mod_evasive_init; | |
19728 | p->set_defaults = mod_evasive_set_defaults; | |
19729 | p->handle_uri_clean = mod_evasive_uri_handler; | |
19730 | p->cleanup = mod_evasive_free; | |
19731 | - | |
19732 | + | |
19733 | p->data = NULL; | |
19734 | - | |
19735 | + | |
19736 | return 0; | |
19737 | } | |
1175ccec | 19738 | --- ../lighttpd-1.4.11/src/mod_evhost.c 2005-08-17 10:42:03.000000000 +0300 |
36e2a29e | 19739 | +++ lighttpd-1.4.12/src/mod_evhost.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
19740 | @@ -7,10 +7,12 @@ |
19741 | #include "response.h" | |
19742 | #include "stat_cache.h" | |
19743 | ||
19744 | +#include "sys-files.h" | |
19745 | + | |
19746 | typedef struct { | |
19747 | /* unparsed pieces */ | |
19748 | buffer *path_pieces_raw; | |
19749 | - | |
19750 | + | |
19751 | /* pieces for path creation */ | |
19752 | size_t len; | |
19753 | buffer **path_pieces; | |
19754 | @@ -21,14 +23,14 @@ | |
19755 | buffer *tmp_buf; | |
19756 | ||
19757 | plugin_config **config_storage; | |
19758 | - plugin_config conf; | |
19759 | + plugin_config conf; | |
19760 | } plugin_data; | |
19761 | ||
19762 | INIT_FUNC(mod_evhost_init) { | |
19763 | plugin_data *p; | |
19764 | - | |
19765 | + | |
19766 | p = calloc(1, sizeof(*p)); | |
19767 | - | |
19768 | + | |
19769 | p->tmp_buf = buffer_init(); | |
19770 | ||
19771 | return p; | |
19772 | @@ -36,34 +38,34 @@ | |
19773 | ||
19774 | FREE_FUNC(mod_evhost_free) { | |
19775 | plugin_data *p = p_d; | |
19776 | - | |
19777 | + | |
19778 | UNUSED(srv); | |
19779 | ||
19780 | if (!p) return HANDLER_GO_ON; | |
19781 | - | |
19782 | + | |
19783 | if (p->config_storage) { | |
19784 | size_t i; | |
19785 | for (i = 0; i < srv->config_context->used; i++) { | |
19786 | plugin_config *s = p->config_storage[i]; | |
19787 | ||
19788 | if (!s) continue; | |
19789 | - | |
19790 | + | |
19791 | if(s->path_pieces) { | |
19792 | size_t j; | |
19793 | for (j = 0; j < s->len; j++) { | |
19794 | buffer_free(s->path_pieces[j]); | |
19795 | } | |
19796 | - | |
19797 | + | |
19798 | free(s->path_pieces); | |
19799 | } | |
19800 | - | |
19801 | + | |
19802 | buffer_free(s->path_pieces_raw); | |
19803 | - | |
19804 | + | |
19805 | free(s); | |
19806 | } | |
19807 | free(p->config_storage); | |
19808 | } | |
19809 | - | |
19810 | + | |
19811 | buffer_free(p->tmp_buf); | |
19812 | ||
19813 | free(p); | |
19814 | @@ -73,30 +75,30 @@ | |
19815 | ||
19816 | static void mod_evhost_parse_pattern(plugin_config *s) { | |
19817 | char *ptr = s->path_pieces_raw->ptr,*pos; | |
19818 | - | |
19819 | + | |
19820 | s->path_pieces = NULL; | |
19821 | - | |
19822 | + | |
19823 | for(pos=ptr;*ptr;ptr++) { | |
19824 | if(*ptr == '%') { | |
19825 | s->path_pieces = realloc(s->path_pieces,(s->len+2) * sizeof(*s->path_pieces)); | |
19826 | s->path_pieces[s->len] = buffer_init(); | |
19827 | s->path_pieces[s->len+1] = buffer_init(); | |
19828 | - | |
19829 | + | |
19830 | buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos); | |
19831 | pos = ptr + 2; | |
19832 | - | |
19833 | + | |
19834 | buffer_copy_string_len(s->path_pieces[s->len+1],ptr++,2); | |
19835 | - | |
19836 | + | |
19837 | s->len += 2; | |
19838 | } | |
19839 | } | |
19840 | - | |
19841 | + | |
19842 | if(*pos != '\0') { | |
19843 | s->path_pieces = realloc(s->path_pieces,(s->len+1) * sizeof(*s->path_pieces)); | |
19844 | s->path_pieces[s->len] = buffer_init(); | |
19845 | - | |
19846 | + | |
19847 | buffer_append_memory(s->path_pieces[s->len],pos,ptr-pos); | |
19848 | - | |
19849 | + | |
19850 | s->len += 1; | |
19851 | } | |
19852 | } | |
19853 | @@ -104,9 +106,9 @@ | |
19854 | SETDEFAULTS_FUNC(mod_evhost_set_defaults) { | |
19855 | plugin_data *p = p_d; | |
19856 | size_t i; | |
19857 | - | |
19858 | + | |
19859 | /** | |
19860 | - * | |
19861 | + * | |
19862 | * # | |
19863 | * # define a pattern for the host url finding | |
19864 | * # %% => % sign | |
19865 | @@ -117,39 +119,39 @@ | |
19866 | * # %4 => subdomain 2 name | |
19867 | * # | |
19868 | * evhost.path-pattern = "/home/ckruse/dev/www/%3/htdocs/" | |
19869 | - * | |
19870 | + * | |
19871 | */ | |
19872 | - | |
19873 | - config_values_t cv[] = { | |
19874 | + | |
19875 | + config_values_t cv[] = { | |
19876 | { "evhost.path-pattern", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
19877 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
19878 | }; | |
19879 | - | |
19880 | + | |
19881 | if (!p) return HANDLER_ERROR; | |
19882 | - | |
19883 | + | |
19884 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
19885 | - | |
19886 | + | |
19887 | for (i = 0; i < srv->config_context->used; i++) { | |
19888 | plugin_config *s; | |
19889 | - | |
19890 | + | |
19891 | s = calloc(1, sizeof(plugin_config)); | |
19892 | s->path_pieces_raw = buffer_init(); | |
19893 | s->path_pieces = NULL; | |
19894 | s->len = 0; | |
19895 | - | |
19896 | + | |
19897 | cv[0].destination = s->path_pieces_raw; | |
19898 | - | |
19899 | + | |
19900 | p->config_storage[i] = s; | |
19901 | - | |
19902 | + | |
19903 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
19904 | return HANDLER_ERROR; | |
19905 | } | |
19906 | - | |
19907 | + | |
19908 | if (s->path_pieces_raw->used != 0) { | |
19909 | mod_evhost_parse_pattern(s); | |
19910 | } | |
19911 | } | |
19912 | - | |
19913 | + | |
19914 | return HANDLER_GO_ON; | |
19915 | } | |
19916 | ||
19917 | @@ -158,7 +160,7 @@ | |
19918 | * - %0 - full hostname (authority w/o port) | |
19919 | * - %1 - tld | |
19920 | * - %2 - domain.tld | |
19921 | - * - %3 - | |
19922 | + * - %3 - | |
19923 | */ | |
19924 | ||
19925 | static int mod_evhost_parse_host(connection *con,array *host) { | |
19926 | @@ -168,7 +170,7 @@ | |
19927 | int first = 1; | |
19928 | data_string *ds; | |
19929 | int i; | |
19930 | - | |
19931 | + | |
19932 | /* first, find the domain + tld */ | |
19933 | for(;ptr > con->uri.authority->ptr;ptr--) { | |
19934 | if(*ptr == '.') { | |
19935 | @@ -179,18 +181,18 @@ | |
19936 | first = 1; | |
19937 | } | |
19938 | } | |
19939 | - | |
19940 | + | |
19941 | ds = data_string_init(); | |
19942 | buffer_copy_string(ds->key,"%0"); | |
19943 | - | |
19944 | + | |
19945 | /* if we stopped at a dot, skip the dot */ | |
19946 | if (*ptr == '.') ptr++; | |
19947 | buffer_copy_string_len(ds->value, ptr, colon-ptr); | |
19948 | - | |
19949 | + | |
19950 | array_insert_unique(host,(data_unset *)ds); | |
19951 | - | |
19952 | + | |
19953 | /* if the : is not the start of the authority, go on parsing the hostname */ | |
19954 | - | |
19955 | + | |
19956 | if (colon != con->uri.authority->ptr) { | |
19957 | for(ptr = colon - 1, i = 1; ptr > con->uri.authority->ptr; ptr--) { | |
19958 | if(*ptr == '.') { | |
19959 | @@ -200,59 +202,55 @@ | |
19960 | buffer_copy_string(ds->key,"%"); | |
19961 | buffer_append_long(ds->key, i++); | |
19962 | buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1); | |
19963 | - | |
19964 | + | |
19965 | array_insert_unique(host,(data_unset *)ds); | |
19966 | } | |
19967 | colon = ptr; | |
19968 | } | |
19969 | } | |
19970 | - | |
19971 | + | |
19972 | /* if the . is not the first charactor of the hostname */ | |
19973 | if (colon != ptr) { | |
19974 | ds = data_string_init(); | |
19975 | buffer_copy_string(ds->key,"%"); | |
19976 | buffer_append_long(ds->key, i++); | |
19977 | buffer_copy_string_len(ds->value,ptr,colon-ptr); | |
19978 | - | |
19979 | + | |
19980 | array_insert_unique(host,(data_unset *)ds); | |
19981 | } | |
19982 | } | |
19983 | - | |
19984 | + | |
19985 | return 0; | |
19986 | } | |
19987 | ||
19988 | -#define PATCH(x) \ | |
19989 | - p->conf.x = s->x; | |
19990 | static int mod_evhost_patch_connection(server *srv, connection *con, plugin_data *p) { | |
19991 | size_t i, j; | |
19992 | plugin_config *s = p->config_storage[0]; | |
19993 | - | |
19994 | - PATCH(path_pieces); | |
19995 | - PATCH(len); | |
19996 | - | |
19997 | + | |
19998 | + PATCH_OPTION(path_pieces); | |
19999 | + PATCH_OPTION(len); | |
20000 | + | |
20001 | /* skip the first, the global context */ | |
20002 | for (i = 1; i < srv->config_context->used; i++) { | |
20003 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
20004 | s = p->config_storage[i]; | |
20005 | - | |
20006 | + | |
20007 | /* condition didn't match */ | |
20008 | if (!config_check_cond(srv, con, dc)) continue; | |
20009 | - | |
20010 | + | |
20011 | /* merge config */ | |
20012 | for (j = 0; j < dc->value->used; j++) { | |
20013 | data_unset *du = dc->value->data[j]; | |
20014 | - | |
20015 | + | |
20016 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("evhost.path-pattern"))) { | |
20017 | - PATCH(path_pieces); | |
20018 | - PATCH(len); | |
20019 | + PATCH_OPTION(path_pieces); | |
20020 | + PATCH_OPTION(len); | |
20021 | } | |
20022 | } | |
20023 | } | |
20024 | - | |
20025 | + | |
20026 | return 0; | |
20027 | } | |
20028 | -#undef PATCH | |
20029 | - | |
20030 | ||
20031 | static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d) { | |
20032 | plugin_data *p = p_d; | |
20033 | @@ -261,29 +259,29 @@ | |
20034 | register char *ptr; | |
20035 | int not_good = 0; | |
20036 | stat_cache_entry *sce = NULL; | |
20037 | - | |
20038 | + | |
20039 | /* not authority set */ | |
20040 | if (con->uri.authority->used == 0) return HANDLER_GO_ON; | |
20041 | - | |
20042 | + | |
20043 | mod_evhost_patch_connection(srv, con, p); | |
20044 | - | |
20045 | + | |
20046 | /* missing even default(global) conf */ | |
20047 | if (0 == p->conf.len) { | |
20048 | return HANDLER_GO_ON; | |
20049 | } | |
20050 | ||
20051 | parsed_host = array_init(); | |
20052 | - | |
20053 | + | |
20054 | mod_evhost_parse_host(con, parsed_host); | |
20055 | - | |
20056 | + | |
20057 | /* build document-root */ | |
20058 | buffer_reset(p->tmp_buf); | |
20059 | - | |
20060 | + | |
20061 | for (i = 0; i < p->conf.len; i++) { | |
20062 | ptr = p->conf.path_pieces[i]->ptr; | |
20063 | if (*ptr == '%') { | |
20064 | data_string *ds; | |
20065 | - | |
20066 | + | |
20067 | if (*(ptr+1) == '%') { | |
20068 | /* %% */ | |
20069 | BUFFER_APPEND_STRING_CONST(p->tmp_buf,"%"); | |
20070 | @@ -298,11 +296,11 @@ | |
20071 | buffer_append_string_buffer(p->tmp_buf,p->conf.path_pieces[i]); | |
20072 | } | |
20073 | } | |
20074 | - | |
20075 | - BUFFER_APPEND_SLASH(p->tmp_buf); | |
20076 | - | |
20077 | + | |
20078 | + PATHNAME_APPEND_SLASH(p->tmp_buf); | |
20079 | + | |
20080 | array_free(parsed_host); | |
20081 | - | |
20082 | + | |
20083 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) { | |
20084 | log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf); | |
20085 | not_good = 1; | |
20086 | @@ -310,11 +308,11 @@ | |
20087 | log_error_write(srv, __FILE__, __LINE__, "sb", "not a directory:", p->tmp_buf); | |
20088 | not_good = 1; | |
20089 | } | |
20090 | - | |
20091 | + | |
20092 | if (!not_good) { | |
20093 | buffer_copy_string_buffer(con->physical.doc_root, p->tmp_buf); | |
20094 | } | |
20095 | - | |
20096 | + | |
20097 | return HANDLER_GO_ON; | |
20098 | } | |
20099 | ||
20100 | @@ -325,9 +323,9 @@ | |
20101 | p->set_defaults = mod_evhost_set_defaults; | |
20102 | p->handle_docroot = mod_evhost_uri_handler; | |
20103 | p->cleanup = mod_evhost_free; | |
20104 | - | |
20105 | + | |
20106 | p->data = NULL; | |
20107 | - | |
20108 | + | |
20109 | return 0; | |
20110 | } | |
20111 | ||
1175ccec | 20112 | --- ../lighttpd-1.4.11/src/mod_expire.c 2005-11-03 09:52:13.000000000 +0200 |
36e2a29e | 20113 | +++ lighttpd-1.4.12/src/mod_expire.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
20114 | @@ -12,8 +12,8 @@ |
20115 | #include "stat_cache.h" | |
20116 | ||
20117 | /** | |
20118 | - * this is a expire module for a lighttpd | |
20119 | - * | |
20120 | + * this is a expire module for a lighttpd | |
20121 | + * | |
20122 | * set 'Expires:' HTTP Headers on demand | |
20123 | */ | |
20124 | ||
20125 | @@ -27,51 +27,51 @@ | |
20126 | ||
20127 | typedef struct { | |
20128 | PLUGIN_DATA; | |
20129 | - | |
20130 | + | |
20131 | buffer *expire_tstmp; | |
20132 | - | |
20133 | + | |
20134 | plugin_config **config_storage; | |
20135 | - | |
20136 | - plugin_config conf; | |
20137 | + | |
20138 | + plugin_config conf; | |
20139 | } plugin_data; | |
20140 | ||
20141 | /* init the plugin data */ | |
20142 | INIT_FUNC(mod_expire_init) { | |
20143 | plugin_data *p; | |
20144 | - | |
20145 | + | |
20146 | p = calloc(1, sizeof(*p)); | |
20147 | - | |
20148 | + | |
20149 | p->expire_tstmp = buffer_init(); | |
20150 | - | |
20151 | + | |
20152 | buffer_prepare_copy(p->expire_tstmp, 255); | |
20153 | - | |
20154 | + | |
20155 | return p; | |
20156 | } | |
20157 | ||
20158 | /* detroy the plugin data */ | |
20159 | FREE_FUNC(mod_expire_free) { | |
20160 | plugin_data *p = p_d; | |
20161 | - | |
20162 | + | |
20163 | UNUSED(srv); | |
20164 | ||
20165 | if (!p) return HANDLER_GO_ON; | |
20166 | - | |
20167 | + | |
20168 | buffer_free(p->expire_tstmp); | |
20169 | - | |
20170 | + | |
20171 | if (p->config_storage) { | |
20172 | size_t i; | |
20173 | for (i = 0; i < srv->config_context->used; i++) { | |
20174 | plugin_config *s = p->config_storage[i]; | |
20175 | - | |
20176 | + | |
20177 | array_free(s->expire_url); | |
20178 | - | |
20179 | + | |
20180 | free(s); | |
20181 | } | |
20182 | free(p->config_storage); | |
20183 | } | |
20184 | - | |
20185 | + | |
20186 | free(p); | |
20187 | - | |
20188 | + | |
20189 | return HANDLER_GO_ON; | |
20190 | } | |
20191 | ||
20192 | @@ -79,25 +79,25 @@ | |
20193 | char *ts; | |
20194 | int type = -1; | |
20195 | int retts = 0; | |
20196 | - | |
20197 | + | |
20198 | UNUSED(p); | |
20199 | ||
20200 | - /* | |
20201 | + /* | |
20202 | * parse | |
20203 | - * | |
20204 | + * | |
20205 | * '(access|modification) [plus] {<num> <type>}*' | |
20206 | - * | |
20207 | + * | |
20208 | * e.g. 'access 1 years' | |
20209 | */ | |
20210 | - | |
20211 | + | |
20212 | if (expire->used == 0) { | |
20213 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
20214 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
20215 | "empty:"); | |
20216 | return -1; | |
20217 | } | |
20218 | - | |
20219 | + | |
20220 | ts = expire->ptr; | |
20221 | - | |
20222 | + | |
20223 | if (0 == strncmp(ts, "access ", 7)) { | |
20224 | type = 0; | |
20225 | ts += 7; | |
20226 | @@ -110,39 +110,39 @@ | |
20227 | "invalid <base>:", ts); | |
20228 | return -1; | |
20229 | } | |
20230 | - | |
20231 | + | |
20232 | if (0 == strncmp(ts, "plus ", 5)) { | |
20233 | /* skip the optional plus */ | |
20234 | ts += 5; | |
20235 | } | |
20236 | - | |
20237 | + | |
20238 | /* the rest is just <number> (years|months|days|hours|minutes|seconds) */ | |
20239 | while (1) { | |
20240 | char *space, *err; | |
20241 | int num; | |
20242 | - | |
20243 | + | |
20244 | if (NULL == (space = strchr(ts, ' '))) { | |
20245 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
20246 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
20247 | "missing space after <num>:", ts); | |
20248 | return -1; | |
20249 | } | |
20250 | - | |
20251 | + | |
20252 | num = strtol(ts, &err, 10); | |
20253 | if (*err != ' ') { | |
20254 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
20255 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
20256 | "missing <type> after <num>:", ts); | |
20257 | return -1; | |
20258 | } | |
20259 | - | |
20260 | + | |
20261 | ts = space + 1; | |
20262 | - | |
20263 | + | |
20264 | if (NULL != (space = strchr(ts, ' '))) { | |
20265 | int slen; | |
20266 | /* */ | |
20267 | - | |
20268 | + | |
20269 | slen = space - ts; | |
20270 | - | |
20271 | - if (slen == 5 && | |
20272 | + | |
20273 | + if (slen == 5 && | |
20274 | 0 == strncmp(ts, "years", slen)) { | |
20275 | num *= 60 * 60 * 24 * 30 * 12; | |
20276 | } else if (slen == 6 && | |
20277 | @@ -161,13 +161,13 @@ | |
20278 | 0 == strncmp(ts, "seconds", slen)) { | |
20279 | num *= 1; | |
20280 | } else { | |
20281 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
20282 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
20283 | "unknown type:", ts); | |
20284 | return -1; | |
20285 | } | |
20286 | - | |
20287 | + | |
20288 | retts += num; | |
20289 | - | |
20290 | + | |
20291 | ts = space + 1; | |
20292 | } else { | |
20293 | if (0 == strcmp(ts, "years")) { | |
20294 | @@ -183,19 +183,19 @@ | |
20295 | } else if (0 == strcmp(ts, "seconds")) { | |
20296 | num *= 1; | |
20297 | } else { | |
20298 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
20299 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
20300 | "unknown type:", ts); | |
20301 | return -1; | |
20302 | } | |
20303 | - | |
20304 | + | |
20305 | retts += num; | |
20306 | - | |
20307 | + | |
20308 | break; | |
20309 | } | |
20310 | } | |
20311 | - | |
20312 | + | |
20313 | if (offset != NULL) *offset = retts; | |
20314 | - | |
20315 | + | |
20316 | return type; | |
20317 | } | |
20318 | ||
20319 | @@ -205,102 +205,99 @@ | |
20320 | SETDEFAULTS_FUNC(mod_expire_set_defaults) { | |
20321 | plugin_data *p = p_d; | |
20322 | size_t i = 0, k; | |
20323 | - | |
20324 | - config_values_t cv[] = { | |
20325 | + | |
20326 | + config_values_t cv[] = { | |
20327 | { "expire.url", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
20328 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
20329 | }; | |
20330 | - | |
20331 | + | |
20332 | if (!p) return HANDLER_ERROR; | |
20333 | - | |
20334 | + | |
20335 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
20336 | - | |
20337 | + | |
20338 | for (i = 0; i < srv->config_context->used; i++) { | |
20339 | plugin_config *s; | |
20340 | - | |
20341 | + | |
20342 | s = calloc(1, sizeof(plugin_config)); | |
20343 | s->expire_url = array_init(); | |
20344 | - | |
20345 | + | |
20346 | cv[0].destination = s->expire_url; | |
20347 | - | |
20348 | + | |
20349 | p->config_storage[i] = s; | |
20350 | - | |
20351 | + | |
20352 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
20353 | return HANDLER_ERROR; | |
20354 | } | |
20355 | - | |
20356 | + | |
20357 | for (k = 0; k < s->expire_url->used; k++) { | |
20358 | data_string *ds = (data_string *)s->expire_url->data[k]; | |
20359 | - | |
20360 | + | |
20361 | /* parse lines */ | |
20362 | if (-1 == mod_expire_get_offset(srv, p, ds->value, NULL)) { | |
20363 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
20364 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
20365 | "parsing expire.url failed:", ds->value); | |
20366 | return HANDLER_ERROR; | |
20367 | } | |
20368 | } | |
20369 | } | |
20370 | - | |
20371 | - | |
20372 | + | |
20373 | + | |
20374 | return HANDLER_GO_ON; | |
20375 | } | |
20376 | ||
20377 | -#define PATCH(x) \ | |
20378 | - p->conf.x = s->x; | |
20379 | static int mod_expire_patch_connection(server *srv, connection *con, plugin_data *p) { | |
20380 | size_t i, j; | |
20381 | plugin_config *s = p->config_storage[0]; | |
20382 | - | |
20383 | - PATCH(expire_url); | |
20384 | - | |
20385 | + | |
20386 | + PATCH_OPTION(expire_url); | |
20387 | + | |
20388 | /* skip the first, the global context */ | |
20389 | for (i = 1; i < srv->config_context->used; i++) { | |
20390 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
20391 | s = p->config_storage[i]; | |
20392 | - | |
20393 | + | |
20394 | /* condition didn't match */ | |
20395 | if (!config_check_cond(srv, con, dc)) continue; | |
20396 | - | |
20397 | + | |
20398 | /* merge config */ | |
20399 | for (j = 0; j < dc->value->used; j++) { | |
20400 | data_unset *du = dc->value->data[j]; | |
20401 | - | |
20402 | + | |
20403 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("expire.url"))) { | |
20404 | - PATCH(expire_url); | |
20405 | + PATCH_OPTION(expire_url); | |
20406 | } | |
20407 | } | |
20408 | } | |
20409 | - | |
20410 | + | |
20411 | return 0; | |
20412 | } | |
20413 | -#undef PATCH | |
20414 | ||
20415 | URIHANDLER_FUNC(mod_expire_path_handler) { | |
20416 | plugin_data *p = p_d; | |
20417 | int s_len; | |
20418 | size_t k; | |
20419 | - | |
20420 | + | |
20421 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
20422 | - | |
20423 | + | |
20424 | mod_expire_patch_connection(srv, con, p); | |
20425 | - | |
20426 | + | |
20427 | s_len = con->uri.path->used - 1; | |
20428 | - | |
20429 | + | |
20430 | for (k = 0; k < p->conf.expire_url->used; k++) { | |
20431 | data_string *ds = (data_string *)p->conf.expire_url->data[k]; | |
20432 | int ct_len = ds->key->used - 1; | |
20433 | - | |
20434 | + | |
20435 | if (ct_len > s_len) continue; | |
20436 | if (ds->key->used == 0) continue; | |
20437 | - | |
20438 | + | |
20439 | if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) { | |
20440 | int ts; | |
20441 | time_t t; | |
20442 | size_t len; | |
20443 | stat_cache_entry *sce = NULL; | |
20444 | - | |
20445 | + | |
20446 | stat_cache_get_entry(srv, con, con->physical.path, &sce); | |
20447 | - | |
20448 | + | |
20449 | switch(mod_expire_get_offset(srv, p, ds->value, &ts)) { | |
20450 | case 0: | |
20451 | /* access */ | |
20452 | @@ -308,38 +305,38 @@ | |
20453 | break; | |
20454 | case 1: | |
20455 | /* modification */ | |
20456 | - | |
20457 | + | |
20458 | t = (ts + sce->st.st_mtime); | |
20459 | break; | |
20460 | default: | |
20461 | /* -1 is handled at parse-time */ | |
20462 | break; | |
20463 | } | |
20464 | - | |
20465 | - | |
20466 | - if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1, | |
20467 | + | |
20468 | + | |
20469 | + if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1, | |
20470 | "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(t))))) { | |
20471 | /* could not set expire header, out of mem */ | |
20472 | - | |
20473 | + | |
20474 | return HANDLER_GO_ON; | |
20475 | - | |
20476 | + | |
20477 | } | |
20478 | - | |
20479 | + | |
20480 | p->expire_tstmp->used = len + 1; | |
20481 | - | |
20482 | - /* HTTP/1.0 */ | |
20483 | + | |
20484 | + /* HTTP/1.0 */ | |
20485 | response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_BUF_LEN(p->expire_tstmp)); | |
20486 | ||
20487 | - /* HTTP/1.1 */ | |
20488 | + /* HTTP/1.1 */ | |
20489 | buffer_copy_string(p->expire_tstmp, "max-age="); | |
20490 | buffer_append_long(p->expire_tstmp, ts); | |
20491 | - | |
20492 | + | |
20493 | response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp)); | |
20494 | - | |
20495 | + | |
20496 | return HANDLER_GO_ON; | |
20497 | } | |
20498 | } | |
20499 | - | |
20500 | + | |
20501 | /* not found */ | |
20502 | return HANDLER_GO_ON; | |
20503 | } | |
20504 | @@ -349,13 +346,13 @@ | |
20505 | int mod_expire_plugin_init(plugin *p) { | |
20506 | p->version = LIGHTTPD_VERSION_ID; | |
20507 | p->name = buffer_init_string("expire"); | |
20508 | - | |
20509 | + | |
20510 | p->init = mod_expire_init; | |
20511 | p->handle_subrequest_start = mod_expire_path_handler; | |
20512 | p->set_defaults = mod_expire_set_defaults; | |
20513 | p->cleanup = mod_expire_free; | |
20514 | - | |
20515 | + | |
20516 | p->data = NULL; | |
20517 | - | |
20518 | + | |
20519 | return 0; | |
20520 | } | |
1175ccec | 20521 | --- ../lighttpd-1.4.11/src/mod_fastcgi.c 2006-03-09 13:18:39.000000000 +0200 |
36e2a29e | 20522 | +++ lighttpd-1.4.12/src/mod_fastcgi.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
20523 | @@ -1,5 +1,4 @@ |
20524 | #include <sys/types.h> | |
20525 | -#include <unistd.h> | |
20526 | #include <errno.h> | |
20527 | #include <fcntl.h> | |
20528 | #include <string.h> | |
20529 | @@ -24,7 +23,7 @@ | |
20530 | #include "inet_ntop_cache.h" | |
20531 | #include "stat_cache.h" | |
20532 | ||
20533 | -#include <fastcgi.h> | |
20534 | +#include "fastcgi.h" | |
20535 | #include <stdio.h> | |
20536 | ||
20537 | #ifdef HAVE_SYS_FILIO_H | |
20538 | @@ -32,7 +31,11 @@ | |
20539 | #endif | |
20540 | ||
20541 | #include "sys-socket.h" | |
20542 | +#include "sys-files.h" | |
20543 | +#include "sys-strings.h" | |
20544 | +#include "sys-process.h" | |
20545 | ||
20546 | +#include "http_resp.h" | |
20547 | ||
20548 | #ifndef UNIX_PATH_MAX | |
20549 | # define UNIX_PATH_MAX 108 | |
20550 | @@ -45,14 +48,13 @@ | |
20551 | #include <sys/wait.h> | |
20552 | #endif | |
20553 | ||
20554 | - | |
20555 | /* | |
20556 | - * | |
20557 | + * | |
20558 | * TODO: | |
20559 | - * | |
20560 | + * | |
20561 | * - add timeout for a connect to a non-fastcgi process | |
20562 | * (use state_timestamp + state) | |
20563 | - * | |
20564 | + * | |
20565 | */ | |
20566 | ||
20567 | typedef struct fcgi_proc { | |
20568 | @@ -61,7 +63,7 @@ | |
20569 | unsigned port; /* config.port + pno */ | |
20570 | ||
20571 | buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debuggin purposes */ | |
20572 | - | |
20573 | + | |
20574 | pid_t pid; /* PID of the spawned process (0 if not spawned locally) */ | |
20575 | ||
20576 | ||
20577 | @@ -70,20 +72,20 @@ | |
20578 | time_t last_used; /* see idle_timeout */ | |
20579 | size_t requests; /* see max_requests */ | |
20580 | struct fcgi_proc *prev, *next; /* see first */ | |
20581 | - | |
20582 | + | |
20583 | time_t disabled_until; /* this proc is disabled until, use something else until than */ | |
20584 | - | |
20585 | + | |
20586 | int is_local; | |
20587 | ||
20588 | - enum { | |
20589 | + enum { | |
20590 | PROC_STATE_UNSET, /* init-phase */ | |
20591 | PROC_STATE_RUNNING, /* alive */ | |
20592 | - PROC_STATE_OVERLOADED, /* listen-queue is full, | |
20593 | + PROC_STATE_OVERLOADED, /* listen-queue is full, | |
20594 | don't send something to this proc for the next 2 seconds */ | |
20595 | PROC_STATE_DIED_WAIT_FOR_PID, /* */ | |
20596 | PROC_STATE_DIED, /* marked as dead, should be restarted */ | |
20597 | PROC_STATE_KILLED /* was killed as we don't have the load anymore */ | |
20598 | - } state; | |
20599 | + } state; | |
20600 | } fcgi_proc; | |
20601 | ||
20602 | typedef struct { | |
20603 | @@ -94,20 +96,20 @@ | |
20604 | * sorted by lowest load | |
20605 | * | |
20606 | * whenever a job is done move it up in the list | |
20607 | - * until it is sorted, move it down as soon as the | |
20608 | + * until it is sorted, move it down as soon as the | |
20609 | * job is started | |
20610 | */ | |
20611 | - fcgi_proc *first; | |
20612 | - fcgi_proc *unused_procs; | |
20613 | + fcgi_proc *first; | |
20614 | + fcgi_proc *unused_procs; | |
20615 | ||
20616 | - /* | |
20617 | + /* | |
20618 | * spawn at least min_procs, at max_procs. | |
20619 | * | |
20620 | - * as soon as the load of the first entry | |
20621 | + * as soon as the load of the first entry | |
20622 | * is max_load_per_proc we spawn a new one | |
20623 | - * and add it to the first entry and give it | |
20624 | + * and add it to the first entry and give it | |
20625 | * the load | |
20626 | - * | |
20627 | + * | |
20628 | */ | |
20629 | ||
20630 | unsigned short min_procs; | |
20631 | @@ -119,44 +121,44 @@ | |
20632 | ||
20633 | /* | |
20634 | * kick the process from the list if it was not | |
20635 | - * used for idle_timeout until min_procs is | |
20636 | + * used for idle_timeout until min_procs is | |
20637 | * reached. this helps to get the processlist | |
20638 | * small again we had a small peak load. | |
20639 | * | |
20640 | */ | |
20641 | - | |
20642 | + | |
20643 | unsigned short idle_timeout; | |
20644 | - | |
20645 | + | |
20646 | /* | |
20647 | * time after a disabled remote connection is tried to be re-enabled | |
20648 | - * | |
20649 | - * | |
20650 | + * | |
20651 | + * | |
20652 | */ | |
20653 | - | |
20654 | + | |
20655 | unsigned short disable_time; | |
20656 | ||
20657 | /* | |
20658 | * same fastcgi processes get a little bit larger | |
20659 | - * than wanted. max_requests_per_proc kills a | |
20660 | + * than wanted. max_requests_per_proc kills a | |
20661 | * process after a number of handled requests. | |
20662 | * | |
20663 | */ | |
20664 | size_t max_requests_per_proc; | |
20665 | - | |
20666 | + | |
20667 | ||
20668 | /* config */ | |
20669 | ||
20670 | - /* | |
20671 | - * host:port | |
20672 | + /* | |
20673 | + * host:port | |
20674 | * | |
20675 | - * if host is one of the local IP adresses the | |
20676 | + * if host is one of the local IP adresses the | |
20677 | * whole connection is local | |
20678 | * | |
20679 | * if tcp/ip should be used host AND port have | |
20680 | - * to be specified | |
20681 | - * | |
20682 | - */ | |
20683 | - buffer *host; | |
20684 | + * to be specified | |
20685 | + * | |
20686 | + */ | |
20687 | + buffer *host; | |
20688 | unsigned short port; | |
20689 | ||
20690 | /* | |
20691 | @@ -169,7 +171,7 @@ | |
20692 | */ | |
20693 | buffer *unixsocket; | |
20694 | ||
20695 | - /* if socket is local we can start the fastcgi | |
20696 | + /* if socket is local we can start the fastcgi | |
20697 | * process ourself | |
20698 | * | |
20699 | * bin-path is the path to the binary | |
20700 | @@ -177,19 +179,19 @@ | |
20701 | * check min_procs and max_procs for the number | |
20702 | * of process to start-up | |
20703 | */ | |
20704 | - buffer *bin_path; | |
20705 | - | |
20706 | - /* bin-path is set bin-environment is taken to | |
20707 | + buffer *bin_path; | |
20708 | + | |
20709 | + /* bin-path is set bin-environment is taken to | |
20710 | * create the environement before starting the | |
20711 | * FastCGI process | |
20712 | - * | |
20713 | + * | |
20714 | */ | |
20715 | array *bin_env; | |
20716 | - | |
20717 | + | |
20718 | array *bin_env_copy; | |
20719 | - | |
20720 | + | |
20721 | /* | |
20722 | - * docroot-translation between URL->phys and the | |
20723 | + * docroot-translation between URL->phys and the | |
20724 | * remote host | |
20725 | * | |
20726 | * reasons: | |
20727 | @@ -208,7 +210,7 @@ | |
20728 | unsigned short mode; | |
20729 | ||
20730 | /* | |
20731 | - * check_local tell you if the phys file is stat()ed | |
20732 | + * check_local tell you if the phys file is stat()ed | |
20733 | * or not. FastCGI doesn't care if the service is | |
20734 | * remote. If the web-server side doesn't contain | |
20735 | * the fastcgi-files we should not stat() for them | |
20736 | @@ -218,11 +220,11 @@ | |
20737 | ||
20738 | /* | |
20739 | * append PATH_INFO to SCRIPT_FILENAME | |
20740 | - * | |
20741 | + * | |
20742 | * php needs this if cgi.fix_pathinfo is provied | |
20743 | - * | |
20744 | + * | |
20745 | */ | |
20746 | - | |
20747 | + | |
20748 | unsigned short break_scriptfilename_for_php; | |
20749 | ||
20750 | /* | |
20751 | @@ -231,12 +233,12 @@ | |
20752 | * | |
20753 | */ | |
20754 | unsigned short allow_xsendfile; | |
20755 | - | |
20756 | + | |
20757 | ssize_t load; /* replace by host->load */ | |
20758 | ||
20759 | size_t max_id; /* corresponds most of the time to | |
20760 | num_procs. | |
20761 | - | |
20762 | + | |
20763 | only if a process is killed max_id waits for the process itself | |
20764 | to die and decrements its afterwards */ | |
20765 | ||
20766 | @@ -245,17 +247,17 @@ | |
20767 | ||
20768 | /* | |
20769 | * one extension can have multiple hosts assigned | |
20770 | - * one host can spawn additional processes on the same | |
20771 | + * one host can spawn additional processes on the same | |
20772 | * socket (if we control it) | |
20773 | * | |
20774 | * ext -> host -> procs | |
20775 | * 1:n 1:n | |
20776 | * | |
20777 | - * if the fastcgi process is remote that whole goes down | |
20778 | + * if the fastcgi process is remote that whole goes down | |
20779 | * to | |
20780 | * | |
20781 | * ext -> host -> procs | |
20782 | - * 1:n 1:1 | |
20783 | + * 1:n 1:1 | |
20784 | * | |
20785 | * in case of PHP and FCGI_CHILDREN we have again a procs | |
20786 | * but we don't control it directly. | |
20787 | @@ -268,7 +270,7 @@ | |
20788 | int note_is_sent; | |
20789 | ||
20790 | fcgi_extension_host **hosts; | |
20791 | - | |
20792 | + | |
20793 | size_t used; | |
20794 | size_t size; | |
20795 | } fcgi_extension; | |
20796 | @@ -282,10 +284,10 @@ | |
20797 | ||
20798 | ||
20799 | typedef struct { | |
20800 | - fcgi_exts *exts; | |
20801 | + fcgi_exts *exts; | |
20802 | ||
20803 | array *ext_mapping; | |
20804 | - | |
20805 | + | |
20806 | int debug; | |
20807 | } plugin_config; | |
20808 | ||
20809 | @@ -297,7 +299,7 @@ | |
20810 | ||
20811 | typedef struct { | |
20812 | char **ptr; | |
20813 | - | |
20814 | + | |
20815 | size_t size; | |
20816 | size_t used; | |
20817 | } char_array; | |
20818 | @@ -306,44 +308,44 @@ | |
20819 | typedef struct { | |
20820 | PLUGIN_DATA; | |
20821 | buffer_uint fcgi_request_id; | |
20822 | - | |
20823 | + | |
20824 | buffer *fcgi_env; | |
20825 | - | |
20826 | + | |
20827 | buffer *path; | |
20828 | - buffer *parse_response; | |
20829 | ||
20830 | buffer *statuskey; | |
20831 | - | |
20832 | + | |
20833 | + http_resp *resp; | |
20834 | + | |
20835 | plugin_config **config_storage; | |
20836 | - | |
20837 | + | |
20838 | plugin_config conf; /* this is only used as long as no handler_ctx is setup */ | |
20839 | } plugin_data; | |
20840 | ||
20841 | /* connection specific data */ | |
20842 | -typedef enum { | |
20843 | +typedef enum { | |
20844 | FCGI_STATE_UNSET, | |
20845 | - FCGI_STATE_INIT, | |
20846 | - FCGI_STATE_CONNECT_DELAYED, | |
20847 | - FCGI_STATE_PREPARE_WRITE, | |
20848 | - FCGI_STATE_WRITE, | |
20849 | - FCGI_STATE_READ | |
20850 | + FCGI_STATE_INIT, | |
20851 | + FCGI_STATE_CONNECT_DELAYED, | |
20852 | + FCGI_STATE_PREPARE_WRITE, | |
20853 | + FCGI_STATE_WRITE, | |
20854 | + FCGI_STATE_READ | |
20855 | } fcgi_connection_state_t; | |
20856 | ||
20857 | typedef struct { | |
20858 | fcgi_proc *proc; | |
20859 | fcgi_extension_host *host; | |
20860 | fcgi_extension *ext; | |
20861 | - | |
20862 | + | |
20863 | fcgi_connection_state_t state; | |
20864 | time_t state_timestamp; | |
20865 | - | |
20866 | + | |
20867 | int reconnects; /* number of reconnect attempts */ | |
20868 | - | |
20869 | - chunkqueue *rb; /* read queue */ | |
20870 | + | |
20871 | + chunkqueue *rb; /* the raw fcgi read-queue */ | |
20872 | + chunkqueue *http_rb; /* the decoded read-queue for http-parsing */ | |
20873 | chunkqueue *wb; /* write queue */ | |
20874 | - | |
20875 | - buffer *response_header; | |
20876 | - | |
20877 | + | |
20878 | size_t request_id; | |
20879 | int fd; /* fd to the fastcgi process */ | |
20880 | int fde_ndx; /* index into the fd-event buffer */ | |
20881 | @@ -352,9 +354,9 @@ | |
20882 | int got_proc; | |
20883 | ||
20884 | int send_content_body; | |
20885 | - | |
20886 | + | |
20887 | plugin_config conf; | |
20888 | - | |
20889 | + | |
20890 | connection *remote_conn; /* dumb pointer */ | |
20891 | plugin_data *plugin_data; /* dumb pointer */ | |
20892 | } handler_ctx; | |
20893 | @@ -380,7 +382,7 @@ | |
20894 | return di; | |
20895 | } | |
20896 | ||
20897 | -/* dummies of the statistic framework functions | |
20898 | +/* dummies of the statistic framework functions | |
20899 | * they will be moved to a statistics.c later */ | |
20900 | int status_counter_inc(server *srv, const char *s, size_t len) { | |
20901 | data_integer *di = status_counter_get_counter(srv, s, len); | |
20902 | @@ -429,7 +431,7 @@ | |
20903 | CLEAN(".connected"); | |
20904 | CLEAN(".load"); | |
20905 | ||
20906 | -#undef CLEAN | |
20907 | +#undef CLEAN | |
20908 | ||
20909 | #define CLEAN(x) \ | |
20910 | fastcgi_status_copy_procname(b, host, NULL); \ | |
20911 | @@ -438,33 +440,32 @@ | |
20912 | ||
20913 | CLEAN(".load"); | |
20914 | ||
20915 | -#undef CLEAN | |
20916 | +#undef CLEAN | |
20917 | ||
20918 | return 0; | |
20919 | } | |
20920 | ||
20921 | static handler_ctx * handler_ctx_init() { | |
20922 | handler_ctx * hctx; | |
20923 | - | |
20924 | + | |
20925 | hctx = calloc(1, sizeof(*hctx)); | |
20926 | assert(hctx); | |
20927 | - | |
20928 | + | |
20929 | hctx->fde_ndx = -1; | |
20930 | - | |
20931 | - hctx->response_header = buffer_init(); | |
20932 | - | |
20933 | + | |
20934 | hctx->request_id = 0; | |
20935 | hctx->state = FCGI_STATE_INIT; | |
20936 | hctx->proc = NULL; | |
20937 | - | |
20938 | + | |
20939 | hctx->fd = -1; | |
20940 | - | |
20941 | + | |
20942 | hctx->reconnects = 0; | |
20943 | hctx->send_content_body = 1; | |
20944 | ||
20945 | hctx->rb = chunkqueue_init(); | |
20946 | + hctx->http_rb = chunkqueue_init(); | |
20947 | hctx->wb = chunkqueue_init(); | |
20948 | - | |
20949 | + | |
20950 | return hctx; | |
20951 | } | |
20952 | ||
20953 | @@ -473,10 +474,9 @@ | |
20954 | hctx->host->load--; | |
20955 | hctx->host = NULL; | |
20956 | } | |
20957 | - | |
20958 | - buffer_free(hctx->response_header); | |
20959 | ||
20960 | chunkqueue_free(hctx->rb); | |
20961 | + chunkqueue_free(hctx->http_rb); | |
20962 | chunkqueue_free(hctx->wb); | |
20963 | ||
20964 | free(hctx); | |
20965 | @@ -488,21 +488,21 @@ | |
20966 | f = calloc(1, sizeof(*f)); | |
20967 | f->unixsocket = buffer_init(); | |
20968 | f->connection_name = buffer_init(); | |
20969 | - | |
20970 | + | |
20971 | f->prev = NULL; | |
20972 | f->next = NULL; | |
20973 | - | |
20974 | + | |
20975 | return f; | |
20976 | } | |
20977 | ||
20978 | void fastcgi_process_free(fcgi_proc *f) { | |
20979 | if (!f) return; | |
20980 | - | |
20981 | + | |
20982 | fastcgi_process_free(f->next); | |
20983 | - | |
20984 | + | |
20985 | buffer_free(f->unixsocket); | |
20986 | buffer_free(f->connection_name); | |
20987 | - | |
20988 | + | |
20989 | free(f); | |
20990 | } | |
20991 | ||
20992 | @@ -519,13 +519,13 @@ | |
20993 | f->bin_env = array_init(); | |
20994 | f->bin_env_copy = array_init(); | |
20995 | f->strip_request_uri = buffer_init(); | |
20996 | - | |
20997 | + | |
20998 | return f; | |
20999 | } | |
21000 | ||
21001 | void fastcgi_host_free(fcgi_extension_host *h) { | |
21002 | if (!h) return; | |
21003 | - | |
21004 | + | |
21005 | buffer_free(h->id); | |
21006 | buffer_free(h->host); | |
21007 | buffer_free(h->unixsocket); | |
21008 | @@ -534,49 +534,49 @@ | |
21009 | buffer_free(h->strip_request_uri); | |
21010 | array_free(h->bin_env); | |
21011 | array_free(h->bin_env_copy); | |
21012 | - | |
21013 | + | |
21014 | fastcgi_process_free(h->first); | |
21015 | fastcgi_process_free(h->unused_procs); | |
21016 | - | |
21017 | + | |
21018 | free(h); | |
21019 | - | |
21020 | + | |
21021 | } | |
21022 | ||
21023 | fcgi_exts *fastcgi_extensions_init() { | |
21024 | fcgi_exts *f; | |
21025 | ||
21026 | f = calloc(1, sizeof(*f)); | |
21027 | - | |
21028 | + | |
21029 | return f; | |
21030 | } | |
21031 | ||
21032 | void fastcgi_extensions_free(fcgi_exts *f) { | |
21033 | size_t i; | |
21034 | - | |
21035 | + | |
21036 | if (!f) return; | |
21037 | - | |
21038 | + | |
21039 | for (i = 0; i < f->used; i++) { | |
21040 | fcgi_extension *fe; | |
21041 | size_t j; | |
21042 | - | |
21043 | + | |
21044 | fe = f->exts[i]; | |
21045 | - | |
21046 | + | |
21047 | for (j = 0; j < fe->used; j++) { | |
21048 | fcgi_extension_host *h; | |
21049 | - | |
21050 | + | |
21051 | h = fe->hosts[j]; | |
21052 | - | |
21053 | + | |
21054 | fastcgi_host_free(h); | |
21055 | } | |
21056 | - | |
21057 | + | |
21058 | buffer_free(fe->key); | |
21059 | free(fe->hosts); | |
21060 | - | |
21061 | + | |
21062 | free(fe); | |
21063 | } | |
21064 | - | |
21065 | + | |
21066 | free(f->exts); | |
21067 | - | |
21068 | + | |
21069 | free(f); | |
21070 | } | |
21071 | ||
21072 | @@ -625,24 +625,25 @@ | |
21073 | assert(fe->hosts); | |
21074 | } | |
21075 | ||
21076 | - fe->hosts[fe->used++] = fh; | |
21077 | + fe->hosts[fe->used++] = fh; | |
21078 | ||
21079 | return 0; | |
21080 | - | |
21081 | + | |
21082 | } | |
21083 | ||
21084 | INIT_FUNC(mod_fastcgi_init) { | |
21085 | plugin_data *p; | |
21086 | - | |
21087 | + | |
21088 | p = calloc(1, sizeof(*p)); | |
21089 | - | |
21090 | + | |
21091 | p->fcgi_env = buffer_init(); | |
21092 | - | |
21093 | + | |
21094 | p->path = buffer_init(); | |
21095 | - p->parse_response = buffer_init(); | |
21096 | + | |
21097 | + p->resp = http_response_init(); | |
21098 | ||
21099 | p->statuskey = buffer_init(); | |
21100 | - | |
21101 | + | |
21102 | return p; | |
21103 | } | |
21104 | ||
21105 | @@ -650,81 +651,82 @@ | |
21106 | FREE_FUNC(mod_fastcgi_free) { | |
21107 | plugin_data *p = p_d; | |
21108 | buffer_uint *r = &(p->fcgi_request_id); | |
21109 | - | |
21110 | + | |
21111 | UNUSED(srv); | |
21112 | ||
21113 | if (r->ptr) free(r->ptr); | |
21114 | - | |
21115 | + | |
21116 | buffer_free(p->fcgi_env); | |
21117 | buffer_free(p->path); | |
21118 | - buffer_free(p->parse_response); | |
21119 | buffer_free(p->statuskey); | |
21120 | - | |
21121 | + | |
21122 | + http_response_free(p->resp); | |
21123 | + | |
21124 | if (p->config_storage) { | |
21125 | size_t i, j, n; | |
21126 | for (i = 0; i < srv->config_context->used; i++) { | |
21127 | plugin_config *s = p->config_storage[i]; | |
21128 | fcgi_exts *exts; | |
21129 | - | |
21130 | + | |
21131 | if (!s) continue; | |
21132 | - | |
21133 | + | |
21134 | exts = s->exts; | |
21135 | ||
21136 | for (j = 0; j < exts->used; j++) { | |
21137 | fcgi_extension *ex; | |
21138 | - | |
21139 | + | |
21140 | ex = exts->exts[j]; | |
21141 | - | |
21142 | + | |
21143 | for (n = 0; n < ex->used; n++) { | |
21144 | fcgi_proc *proc; | |
21145 | fcgi_extension_host *host; | |
21146 | - | |
21147 | + | |
21148 | host = ex->hosts[n]; | |
21149 | - | |
21150 | + | |
21151 | for (proc = host->first; proc; proc = proc->next) { | |
21152 | if (proc->pid != 0) kill(proc->pid, SIGTERM); | |
21153 | - | |
21154 | - if (proc->is_local && | |
21155 | + | |
21156 | + if (proc->is_local && | |
21157 | !buffer_is_empty(proc->unixsocket)) { | |
21158 | unlink(proc->unixsocket->ptr); | |
21159 | } | |
21160 | } | |
21161 | - | |
21162 | + | |
21163 | for (proc = host->unused_procs; proc; proc = proc->next) { | |
21164 | if (proc->pid != 0) kill(proc->pid, SIGTERM); | |
21165 | - | |
21166 | - if (proc->is_local && | |
21167 | + | |
21168 | + if (proc->is_local && | |
21169 | !buffer_is_empty(proc->unixsocket)) { | |
21170 | unlink(proc->unixsocket->ptr); | |
21171 | } | |
21172 | } | |
21173 | } | |
21174 | } | |
21175 | - | |
21176 | + | |
21177 | fastcgi_extensions_free(s->exts); | |
21178 | array_free(s->ext_mapping); | |
21179 | - | |
21180 | + | |
21181 | free(s); | |
21182 | } | |
21183 | free(p->config_storage); | |
21184 | } | |
21185 | - | |
21186 | + | |
21187 | free(p); | |
21188 | - | |
21189 | + | |
21190 | return HANDLER_GO_ON; | |
21191 | } | |
21192 | ||
21193 | static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) { | |
21194 | char *dst; | |
21195 | - | |
21196 | + | |
21197 | if (!key || !val) return -1; | |
21198 | - | |
21199 | + | |
21200 | dst = malloc(key_len + val_len + 3); | |
21201 | memcpy(dst, key, key_len); | |
21202 | dst[key_len] = '='; | |
21203 | /* add the \0 from the value */ | |
21204 | memcpy(dst + key_len + 1, val, val_len + 1); | |
21205 | - | |
21206 | + | |
21207 | if (env->size == 0) { | |
21208 | env->size = 16; | |
21209 | env->ptr = malloc(env->size * sizeof(*env->ptr)); | |
21210 | @@ -732,9 +734,9 @@ | |
21211 | env->size += 16; | |
21212 | env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr)); | |
21213 | } | |
21214 | - | |
21215 | + | |
21216 | env->ptr[env->used++] = dst; | |
21217 | - | |
21218 | + | |
21219 | return 0; | |
21220 | } | |
21221 | ||
21222 | @@ -753,15 +755,15 @@ | |
21223 | if (env->size == 0) { | |
21224 | env->size = 16; | |
21225 | env->ptr = malloc(env->size * sizeof(*env->ptr)); | |
21226 | - } else if (env->size == env->used) { | |
21227 | + } else if (env->size == env->used) { | |
21228 | env->size += 16; | |
21229 | env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr)); | |
21230 | } | |
21231 | - | |
21232 | + | |
21233 | b->ptr[i] = '\0'; | |
21234 | ||
21235 | env->ptr[env->used++] = start; | |
21236 | - | |
21237 | + | |
21238 | start = b->ptr + i + 1; | |
21239 | break; | |
21240 | default: | |
21241 | @@ -794,7 +796,7 @@ | |
21242 | return 0; | |
21243 | } | |
21244 | ||
21245 | -static int fcgi_spawn_connection(server *srv, | |
21246 | +static int fcgi_spawn_connection(server *srv, | |
21247 | plugin_data *p, | |
21248 | fcgi_extension_host *host, | |
21249 | fcgi_proc *proc) { | |
21250 | @@ -806,31 +808,27 @@ | |
21251 | #endif | |
21252 | struct sockaddr_in fcgi_addr_in; | |
21253 | struct sockaddr *fcgi_addr; | |
21254 | - | |
21255 | + | |
21256 | socklen_t servlen; | |
21257 | - | |
21258 | + | |
21259 | #ifndef HAVE_FORK | |
21260 | return -1; | |
21261 | #endif | |
21262 | - | |
21263 | + | |
21264 | if (p->conf.debug) { | |
21265 | log_error_write(srv, __FILE__, __LINE__, "sdb", | |
21266 | "new proc, socket:", proc->port, proc->unixsocket); | |
21267 | } | |
21268 | - | |
21269 | + | |
21270 | if (!buffer_is_empty(proc->unixsocket)) { | |
21271 | memset(&fcgi_addr, 0, sizeof(fcgi_addr)); | |
21272 | - | |
21273 | + | |
21274 | #ifdef HAVE_SYS_UN_H | |
21275 | fcgi_addr_un.sun_family = AF_UNIX; | |
21276 | strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr); | |
21277 | - | |
21278 | -#ifdef SUN_LEN | |
21279 | + | |
21280 | servlen = SUN_LEN(&fcgi_addr_un); | |
21281 | -#else | |
21282 | - /* stevens says: */ | |
21283 | - servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family); | |
21284 | -#endif | |
21285 | + | |
21286 | socket_type = AF_UNIX; | |
21287 | fcgi_addr = (struct sockaddr *) &fcgi_addr_un; | |
21288 | ||
21289 | @@ -844,108 +842,108 @@ | |
21290 | #endif | |
21291 | } else { | |
21292 | fcgi_addr_in.sin_family = AF_INET; | |
21293 | - | |
21294 | + | |
21295 | if (buffer_is_empty(host->host)) { | |
21296 | fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); | |
21297 | } else { | |
21298 | struct hostent *he; | |
21299 | - | |
21300 | + | |
21301 | /* set a usefull default */ | |
21302 | fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); | |
21303 | - | |
21304 | - | |
21305 | + | |
21306 | + | |
21307 | if (NULL == (he = gethostbyname(host->host->ptr))) { | |
21308 | - log_error_write(srv, __FILE__, __LINE__, | |
21309 | - "sdb", "gethostbyname failed: ", | |
21310 | + log_error_write(srv, __FILE__, __LINE__, | |
21311 | + "sdb", "gethostbyname failed: ", | |
21312 | h_errno, host->host); | |
21313 | return -1; | |
21314 | } | |
21315 | - | |
21316 | + | |
21317 | if (he->h_addrtype != AF_INET) { | |
21318 | log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype); | |
21319 | return -1; | |
21320 | } | |
21321 | - | |
21322 | + | |
21323 | if (he->h_length != sizeof(struct in_addr)) { | |
21324 | log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length); | |
21325 | return -1; | |
21326 | } | |
21327 | - | |
21328 | + | |
21329 | memcpy(&(fcgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length); | |
21330 | - | |
21331 | + | |
21332 | } | |
21333 | fcgi_addr_in.sin_port = htons(proc->port); | |
21334 | servlen = sizeof(fcgi_addr_in); | |
21335 | - | |
21336 | + | |
21337 | socket_type = AF_INET; | |
21338 | fcgi_addr = (struct sockaddr *) &fcgi_addr_in; | |
21339 | - | |
21340 | + | |
21341 | buffer_copy_string(proc->connection_name, "tcp:"); | |
21342 | buffer_append_string_buffer(proc->connection_name, host->host); | |
21343 | buffer_append_string(proc->connection_name, ":"); | |
21344 | buffer_append_long(proc->connection_name, proc->port); | |
21345 | } | |
21346 | - | |
21347 | + | |
21348 | if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { | |
21349 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
21350 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
21351 | "failed:", strerror(errno)); | |
21352 | return -1; | |
21353 | } | |
21354 | - | |
21355 | + | |
21356 | if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) { | |
21357 | /* server is not up, spawn in */ | |
21358 | pid_t child; | |
21359 | int val; | |
21360 | - | |
21361 | - if (errno != ENOENT && | |
21362 | + | |
21363 | + if (errno != ENOENT && | |
21364 | !buffer_is_empty(proc->unixsocket)) { | |
21365 | unlink(proc->unixsocket->ptr); | |
21366 | } | |
21367 | - | |
21368 | + | |
21369 | close(fcgi_fd); | |
21370 | - | |
21371 | + | |
21372 | /* reopen socket */ | |
21373 | if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { | |
21374 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
21375 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
21376 | "socket failed:", strerror(errno)); | |
21377 | return -1; | |
21378 | } | |
21379 | - | |
21380 | + | |
21381 | val = 1; | |
21382 | if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { | |
21383 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
21384 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
21385 | "socketsockopt failed:", strerror(errno)); | |
21386 | return -1; | |
21387 | } | |
21388 | - | |
21389 | + | |
21390 | /* create socket */ | |
21391 | if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) { | |
21392 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
21393 | - "bind failed for:", | |
21394 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
21395 | + "bind failed for:", | |
21396 | proc->connection_name, | |
21397 | strerror(errno)); | |
21398 | return -1; | |
21399 | } | |
21400 | - | |
21401 | + | |
21402 | if (-1 == listen(fcgi_fd, 1024)) { | |
21403 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
21404 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
21405 | "listen failed:", strerror(errno)); | |
21406 | return -1; | |
21407 | } | |
21408 | - | |
21409 | -#ifdef HAVE_FORK | |
21410 | + | |
21411 | +#ifndef _WIN32 | |
21412 | switch ((child = fork())) { | |
21413 | case 0: { | |
21414 | size_t i = 0; | |
21415 | char *c; | |
21416 | char_array env; | |
21417 | char_array arg; | |
21418 | - | |
21419 | + | |
21420 | /* create environment */ | |
21421 | env.ptr = NULL; | |
21422 | env.size = 0; | |
21423 | env.used = 0; | |
21424 | - | |
21425 | + | |
21426 | arg.ptr = NULL; | |
21427 | arg.size = 0; | |
21428 | arg.used = 0; | |
21429 | @@ -955,18 +953,18 @@ | |
21430 | dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO); | |
21431 | close(fcgi_fd); | |
21432 | } | |
21433 | - | |
21434 | + | |
21435 | /* we don't need the client socket */ | |
21436 | for (i = 3; i < 256; i++) { | |
21437 | close(i); | |
21438 | } | |
21439 | - | |
21440 | + | |
21441 | /* build clean environment */ | |
21442 | if (host->bin_env_copy->used) { | |
21443 | for (i = 0; i < host->bin_env_copy->used; i++) { | |
21444 | data_string *ds = (data_string *)host->bin_env_copy->data[i]; | |
21445 | char *ge; | |
21446 | - | |
21447 | + | |
21448 | if (NULL != (ge = getenv(ds->value->ptr))) { | |
21449 | env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge)); | |
21450 | } | |
21451 | @@ -974,39 +972,39 @@ | |
21452 | } else { | |
21453 | for (i = 0; environ[i]; i++) { | |
21454 | char *eq; | |
21455 | - | |
21456 | + | |
21457 | if (NULL != (eq = strchr(environ[i], '='))) { | |
21458 | env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1)); | |
21459 | } | |
21460 | } | |
21461 | } | |
21462 | - | |
21463 | + | |
21464 | /* create environment */ | |
21465 | for (i = 0; i < host->bin_env->used; i++) { | |
21466 | data_string *ds = (data_string *)host->bin_env->data[i]; | |
21467 | - | |
21468 | + | |
21469 | env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value)); | |
21470 | } | |
21471 | - | |
21472 | + | |
21473 | for (i = 0; i < env.used; i++) { | |
21474 | /* search for PHP_FCGI_CHILDREN */ | |
21475 | if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break; | |
21476 | } | |
21477 | - | |
21478 | + | |
21479 | /* not found, add a default */ | |
21480 | if (i == env.used) { | |
21481 | env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1")); | |
21482 | } | |
21483 | - | |
21484 | + | |
21485 | env.ptr[env.used] = NULL; | |
21486 | ||
21487 | parse_binpath(&arg, host->bin_path); | |
21488 | - | |
21489 | + | |
21490 | /* chdir into the base of the bin-path, | |
21491 | * search for the last / */ | |
21492 | if (NULL != (c = strrchr(arg.ptr[0], '/'))) { | |
21493 | *c = '\0'; | |
21494 | - | |
21495 | + | |
21496 | /* change to the physical directory */ | |
21497 | if (-1 == chdir(arg.ptr[0])) { | |
21498 | *c = '/'; | |
21499 | @@ -1018,12 +1016,12 @@ | |
21500 | ||
21501 | /* exec the cgi */ | |
21502 | execve(arg.ptr[0], arg.ptr, env.ptr); | |
21503 | - | |
21504 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
21505 | + | |
21506 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
21507 | "execve failed for:", host->bin_path, strerror(errno)); | |
21508 | - | |
21509 | + | |
21510 | exit(errno); | |
21511 | - | |
21512 | + | |
21513 | break; | |
21514 | } | |
21515 | case -1: | |
21516 | @@ -1031,17 +1029,17 @@ | |
21517 | break; | |
21518 | default: | |
21519 | /* father */ | |
21520 | - | |
21521 | + | |
21522 | /* wait */ | |
21523 | select(0, NULL, NULL, NULL, &tv); | |
21524 | - | |
21525 | + | |
21526 | switch (waitpid(child, &status, WNOHANG)) { | |
21527 | case 0: | |
21528 | /* child still running after timeout, good */ | |
21529 | break; | |
21530 | case -1: | |
21531 | /* no PID found ? should never happen */ | |
21532 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
21533 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
21534 | "pid not found:", strerror(errno)); | |
21535 | return -1; | |
21536 | default: | |
21537 | @@ -1049,10 +1047,10 @@ | |
21538 | "the fastcgi-backend", host->bin_path, "failed to start:"); | |
21539 | /* the child should not terminate at all */ | |
21540 | if (WIFEXITED(status)) { | |
21541 | - log_error_write(srv, __FILE__, __LINE__, "sdb", | |
21542 | - "child exited with status", | |
21543 | + log_error_write(srv, __FILE__, __LINE__, "sdb", | |
21544 | + "child exited with status", | |
21545 | WEXITSTATUS(status), host->bin_path); | |
21546 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
21547 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
21548 | "if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.\n" | |
21549 | "You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' " | |
21550 | "in the output, NOT (cgi) NOR (cli)\n" | |
21551 | @@ -1060,8 +1058,8 @@ | |
21552 | log_error_write(srv, __FILE__, __LINE__, "s", | |
21553 | "If this is PHP on Gentoo add fastcgi to the USE flags"); | |
21554 | } else if (WIFSIGNALED(status)) { | |
21555 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
21556 | - "terminated by signal:", | |
21557 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
21558 | + "terminated by signal:", | |
21559 | WTERMSIG(status)); | |
21560 | ||
21561 | if (WTERMSIG(status) == 11) { | |
21562 | @@ -1071,8 +1069,8 @@ | |
21563 | "If this is PHP try to remove the byte-code caches for now and try again."); | |
21564 | } | |
21565 | } else { | |
21566 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
21567 | - "child died somehow:", | |
21568 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
21569 | + "child died somehow:", | |
21570 | status); | |
21571 | } | |
21572 | return -1; | |
21573 | @@ -1082,26 +1080,26 @@ | |
21574 | proc->pid = child; | |
21575 | proc->last_used = srv->cur_ts; | |
21576 | proc->is_local = 1; | |
21577 | - | |
21578 | + | |
21579 | break; | |
21580 | } | |
21581 | #endif | |
21582 | } else { | |
21583 | proc->is_local = 0; | |
21584 | proc->pid = 0; | |
21585 | - | |
21586 | + | |
21587 | if (p->conf.debug) { | |
21588 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
21589 | "(debug) socket is already used, won't spawn:", | |
21590 | proc->connection_name); | |
21591 | } | |
21592 | } | |
21593 | - | |
21594 | + | |
21595 | proc->state = PROC_STATE_RUNNING; | |
21596 | host->active_procs++; | |
21597 | - | |
21598 | + | |
21599 | close(fcgi_fd); | |
21600 | - | |
21601 | + | |
21602 | return 0; | |
21603 | } | |
21604 | ||
21605 | @@ -1111,93 +1109,93 @@ | |
21606 | data_unset *du; | |
21607 | size_t i = 0; | |
21608 | buffer *fcgi_mode = buffer_init(); | |
21609 | - | |
21610 | - config_values_t cv[] = { | |
21611 | + | |
21612 | + config_values_t cv[] = { | |
21613 | { "fastcgi.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
21614 | { "fastcgi.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
21615 | { "fastcgi.map-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
21616 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
21617 | }; | |
21618 | - | |
21619 | + | |
21620 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
21621 | - | |
21622 | + | |
21623 | for (i = 0; i < srv->config_context->used; i++) { | |
21624 | plugin_config *s; | |
21625 | array *ca; | |
21626 | - | |
21627 | + | |
21628 | s = malloc(sizeof(plugin_config)); | |
21629 | s->exts = fastcgi_extensions_init(); | |
21630 | s->debug = 0; | |
21631 | s->ext_mapping = array_init(); | |
21632 | - | |
21633 | + | |
21634 | cv[0].destination = s->exts; | |
21635 | cv[1].destination = &(s->debug); | |
21636 | cv[2].destination = s->ext_mapping; | |
21637 | - | |
21638 | + | |
21639 | p->config_storage[i] = s; | |
21640 | ca = ((data_config *)srv->config_context->data[i])->value; | |
21641 | - | |
21642 | + | |
21643 | if (0 != config_insert_values_global(srv, ca, cv)) { | |
21644 | return HANDLER_ERROR; | |
21645 | } | |
21646 | - | |
21647 | - /* | |
21648 | + | |
21649 | + /* | |
21650 | * <key> = ( ... ) | |
21651 | */ | |
21652 | - | |
21653 | + | |
21654 | if (NULL != (du = array_get_element(ca, "fastcgi.server"))) { | |
21655 | size_t j; | |
21656 | data_array *da = (data_array *)du; | |
21657 | - | |
21658 | + | |
21659 | if (du->type != TYPE_ARRAY) { | |
21660 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
21661 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
21662 | "unexpected type for key: ", "fastcgi.server", "array of strings"); | |
21663 | - | |
21664 | + | |
21665 | return HANDLER_ERROR; | |
21666 | } | |
21667 | - | |
21668 | - | |
21669 | - /* | |
21670 | - * fastcgi.server = ( "<ext>" => ( ... ), | |
21671 | + | |
21672 | + | |
21673 | + /* | |
21674 | + * fastcgi.server = ( "<ext>" => ( ... ), | |
21675 | * "<ext>" => ( ... ) ) | |
21676 | */ | |
21677 | - | |
21678 | + | |
21679 | for (j = 0; j < da->value->used; j++) { | |
21680 | size_t n; | |
21681 | data_array *da_ext = (data_array *)da->value->data[j]; | |
21682 | - | |
21683 | + | |
21684 | if (da->value->data[j]->type != TYPE_ARRAY) { | |
21685 | - log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
21686 | - "unexpected type for key: ", "fastcgi.server", | |
21687 | + log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
21688 | + "unexpected type for key: ", "fastcgi.server", | |
21689 | "[", da->value->data[j]->key, "](string)"); | |
21690 | - | |
21691 | + | |
21692 | return HANDLER_ERROR; | |
21693 | } | |
21694 | - | |
21695 | - /* | |
21696 | - * da_ext->key == name of the extension | |
21697 | + | |
21698 | + /* | |
21699 | + * da_ext->key == name of the extension | |
21700 | */ | |
21701 | - | |
21702 | - /* | |
21703 | - * fastcgi.server = ( "<ext>" => | |
21704 | - * ( "<host>" => ( ... ), | |
21705 | + | |
21706 | + /* | |
21707 | + * fastcgi.server = ( "<ext>" => | |
21708 | + * ( "<host>" => ( ... ), | |
21709 | * "<host>" => ( ... ) | |
21710 | - * ), | |
21711 | + * ), | |
21712 | * "<ext>" => ... ) | |
21713 | */ | |
21714 | - | |
21715 | + | |
21716 | for (n = 0; n < da_ext->value->used; n++) { | |
21717 | data_array *da_host = (data_array *)da_ext->value->data[n]; | |
21718 | - | |
21719 | + | |
21720 | fcgi_extension_host *host; | |
21721 | - | |
21722 | - config_values_t fcv[] = { | |
21723 | + | |
21724 | + config_values_t fcv[] = { | |
21725 | { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
21726 | { "docroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
21727 | { "mode", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
21728 | { "socket", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ | |
21729 | { "bin-path", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */ | |
21730 | - | |
21731 | + | |
21732 | { "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 5 */ | |
21733 | { "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 6 */ | |
21734 | { "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */ | |
21735 | @@ -1205,28 +1203,28 @@ | |
21736 | { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */ | |
21737 | { "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */ | |
21738 | { "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 11 */ | |
21739 | - | |
21740 | + | |
21741 | { "bin-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ | |
21742 | { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 13 */ | |
21743 | - | |
21744 | + | |
21745 | { "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 14 */ | |
21746 | { "allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */ | |
21747 | { "strip-request-uri", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 16 */ | |
21748 | - | |
21749 | + | |
21750 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
21751 | }; | |
21752 | - | |
21753 | + | |
21754 | if (da_host->type != TYPE_ARRAY) { | |
21755 | - log_error_write(srv, __FILE__, __LINE__, "ssSBS", | |
21756 | - "unexpected type for key:", | |
21757 | - "fastcgi.server", | |
21758 | + log_error_write(srv, __FILE__, __LINE__, "ssSBS", | |
21759 | + "unexpected type for key:", | |
21760 | + "fastcgi.server", | |
21761 | "[", da_host->key, "](string)"); | |
21762 | - | |
21763 | + | |
21764 | return HANDLER_ERROR; | |
21765 | } | |
21766 | - | |
21767 | + | |
21768 | host = fastcgi_host_init(); | |
21769 | - | |
21770 | + | |
21771 | buffer_copy_string_buffer(host->id, da_host->key); | |
21772 | ||
21773 | host->check_local = 1; | |
21774 | @@ -1238,13 +1236,13 @@ | |
21775 | host->disable_time = 60; | |
21776 | host->break_scriptfilename_for_php = 0; | |
21777 | host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */ | |
21778 | - | |
21779 | + | |
21780 | fcv[0].destination = host->host; | |
21781 | fcv[1].destination = host->docroot; | |
21782 | fcv[2].destination = fcgi_mode; | |
21783 | fcv[3].destination = host->unixsocket; | |
21784 | fcv[4].destination = host->bin_path; | |
21785 | - | |
21786 | + | |
21787 | fcv[5].destination = &(host->check_local); | |
21788 | fcv[6].destination = &(host->port); | |
21789 | fcv[7].destination = &(host->min_procs); | |
21790 | @@ -1252,35 +1250,35 @@ | |
21791 | fcv[9].destination = &(host->max_load_per_proc); | |
21792 | fcv[10].destination = &(host->idle_timeout); | |
21793 | fcv[11].destination = &(host->disable_time); | |
21794 | - | |
21795 | + | |
21796 | fcv[12].destination = host->bin_env; | |
21797 | fcv[13].destination = host->bin_env_copy; | |
21798 | fcv[14].destination = &(host->break_scriptfilename_for_php); | |
21799 | fcv[15].destination = &(host->allow_xsendfile); | |
21800 | fcv[16].destination = host->strip_request_uri; | |
21801 | - | |
21802 | + | |
21803 | if (0 != config_insert_values_internal(srv, da_host->value, fcv)) { | |
21804 | return HANDLER_ERROR; | |
21805 | } | |
21806 | - | |
21807 | - if ((!buffer_is_empty(host->host) || host->port) && | |
21808 | + | |
21809 | + if ((!buffer_is_empty(host->host) || host->port) && | |
21810 | !buffer_is_empty(host->unixsocket)) { | |
21811 | - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21812 | + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21813 | "either host/port or socket have to be set in:", | |
21814 | - da->key, "= (", | |
21815 | + da->key, "= (", | |
21816 | da_ext->key, " => (", | |
21817 | da_host->key, " ( ..."); | |
21818 | ||
21819 | return HANDLER_ERROR; | |
21820 | } | |
21821 | - | |
21822 | + | |
21823 | if (!buffer_is_empty(host->unixsocket)) { | |
21824 | /* unix domain socket */ | |
21825 | - | |
21826 | + | |
21827 | if (host->unixsocket->used > UNIX_PATH_MAX - 2) { | |
21828 | - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21829 | + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21830 | "unixsocket is too long in:", | |
21831 | - da->key, "= (", | |
21832 | + da->key, "= (", | |
21833 | da_ext->key, " => (", | |
21834 | da_host->key, " ( ..."); | |
21835 | ||
21836 | @@ -1288,37 +1286,37 @@ | |
21837 | } | |
21838 | } else { | |
21839 | /* tcp/ip */ | |
21840 | - | |
21841 | - if (buffer_is_empty(host->host) && | |
21842 | + | |
21843 | + if (buffer_is_empty(host->host) && | |
21844 | buffer_is_empty(host->bin_path)) { | |
21845 | - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21846 | + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21847 | "host or binpath have to be set in:", | |
21848 | - da->key, "= (", | |
21849 | + da->key, "= (", | |
21850 | da_ext->key, " => (", | |
21851 | da_host->key, " ( ..."); | |
21852 | - | |
21853 | + | |
21854 | return HANDLER_ERROR; | |
21855 | } else if (host->port == 0) { | |
21856 | - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21857 | + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", | |
21858 | "port has to be set in:", | |
21859 | - da->key, "= (", | |
21860 | + da->key, "= (", | |
21861 | da_ext->key, " => (", | |
21862 | da_host->key, " ( ..."); | |
21863 | ||
21864 | return HANDLER_ERROR; | |
21865 | } | |
21866 | } | |
21867 | - | |
21868 | - if (!buffer_is_empty(host->bin_path)) { | |
21869 | + | |
21870 | + if (!buffer_is_empty(host->bin_path)) { | |
21871 | /* a local socket + self spawning */ | |
21872 | size_t pno; | |
21873 | ||
21874 | /* HACK: just to make sure the adaptive spawing is disabled */ | |
21875 | host->min_procs = host->max_procs; | |
21876 | - | |
21877 | + | |
21878 | if (host->min_procs > host->max_procs) host->max_procs = host->min_procs; | |
21879 | if (host->max_load_per_proc < 1) host->max_load_per_proc = 0; | |
21880 | - | |
21881 | + | |
21882 | if (s->debug) { | |
21883 | log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd", | |
21884 | "--- fastcgi spawning local", | |
21885 | @@ -1328,7 +1326,7 @@ | |
21886 | "\n\tmin-procs:", host->min_procs, | |
21887 | "\n\tmax-procs:", host->max_procs); | |
21888 | } | |
21889 | - | |
21890 | + | |
21891 | for (pno = 0; pno < host->min_procs; pno++) { | |
21892 | fcgi_proc *proc; | |
21893 | ||
21894 | @@ -1343,7 +1341,7 @@ | |
21895 | buffer_append_string(proc->unixsocket, "-"); | |
21896 | buffer_append_long(proc->unixsocket, pno); | |
21897 | } | |
21898 | - | |
21899 | + | |
21900 | if (s->debug) { | |
21901 | log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd", | |
21902 | "--- fastcgi spawning", | |
21903 | @@ -1351,7 +1349,7 @@ | |
21904 | "\n\tsocket", host->unixsocket, | |
21905 | "\n\tcurrent:", pno, "/", host->min_procs); | |
21906 | } | |
21907 | - | |
21908 | + | |
21909 | if (fcgi_spawn_connection(srv, p, host, proc)) { | |
21910 | log_error_write(srv, __FILE__, __LINE__, "s", | |
21911 | "[ERROR]: spawning fcgi failed."); | |
21912 | @@ -1359,35 +1357,35 @@ | |
21913 | } | |
21914 | ||
21915 | fastcgi_status_init(srv, p->statuskey, host, proc); | |
21916 | - | |
21917 | + | |
21918 | proc->next = host->first; | |
21919 | if (host->first) host->first->prev = proc; | |
21920 | - | |
21921 | + | |
21922 | host->first = proc; | |
21923 | } | |
21924 | } else { | |
21925 | fcgi_proc *proc; | |
21926 | - | |
21927 | + | |
21928 | proc = fastcgi_process_init(); | |
21929 | proc->id = host->num_procs++; | |
21930 | host->max_id++; | |
21931 | host->active_procs++; | |
21932 | proc->state = PROC_STATE_RUNNING; | |
21933 | - | |
21934 | + | |
21935 | if (buffer_is_empty(host->unixsocket)) { | |
21936 | proc->port = host->port; | |
21937 | } else { | |
21938 | buffer_copy_string_buffer(proc->unixsocket, host->unixsocket); | |
21939 | } | |
21940 | - | |
21941 | + | |
21942 | fastcgi_status_init(srv, p->statuskey, host, proc); | |
21943 | ||
21944 | host->first = proc; | |
21945 | - | |
21946 | + | |
21947 | host->min_procs = 1; | |
21948 | host->max_procs = 1; | |
21949 | } | |
21950 | - | |
21951 | + | |
21952 | if (!buffer_is_empty(fcgi_mode)) { | |
21953 | if (strcmp(fcgi_mode->ptr, "responder") == 0) { | |
21954 | host->mode = FCGI_RESPONDER; | |
21955 | @@ -1411,16 +1409,16 @@ | |
21956 | } | |
21957 | } | |
21958 | } | |
21959 | - | |
21960 | + | |
21961 | buffer_free(fcgi_mode); | |
21962 | - | |
21963 | + | |
21964 | return HANDLER_GO_ON; | |
21965 | } | |
21966 | ||
21967 | static int fcgi_set_state(server *srv, handler_ctx *hctx, fcgi_connection_state_t state) { | |
21968 | hctx->state = state; | |
21969 | hctx->state_timestamp = srv->cur_ts; | |
21970 | - | |
21971 | + | |
21972 | return 0; | |
21973 | } | |
21974 | ||
21975 | @@ -1429,13 +1427,13 @@ | |
21976 | size_t m = 0; | |
21977 | size_t i; | |
21978 | buffer_uint *r = &(p->fcgi_request_id); | |
21979 | - | |
21980 | + | |
21981 | UNUSED(srv); | |
21982 | ||
21983 | for (i = 0; i < r->used; i++) { | |
21984 | if (r->ptr[i] > m) m = r->ptr[i]; | |
21985 | } | |
21986 | - | |
21987 | + | |
21988 | if (r->size == 0) { | |
21989 | r->size = 16; | |
21990 | r->ptr = malloc(sizeof(*r->ptr) * r->size); | |
21991 | @@ -1443,54 +1441,54 @@ | |
21992 | r->size += 16; | |
21993 | r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size); | |
21994 | } | |
21995 | - | |
21996 | + | |
21997 | r->ptr[r->used++] = ++m; | |
21998 | - | |
21999 | + | |
22000 | return m; | |
22001 | } | |
22002 | ||
22003 | static int fcgi_requestid_del(server *srv, plugin_data *p, size_t request_id) { | |
22004 | size_t i; | |
22005 | buffer_uint *r = &(p->fcgi_request_id); | |
22006 | - | |
22007 | + | |
22008 | UNUSED(srv); | |
22009 | ||
22010 | for (i = 0; i < r->used; i++) { | |
22011 | if (r->ptr[i] == request_id) break; | |
22012 | } | |
22013 | - | |
22014 | + | |
22015 | if (i != r->used) { | |
22016 | /* found */ | |
22017 | - | |
22018 | + | |
22019 | if (i != r->used - 1) { | |
22020 | r->ptr[i] = r->ptr[r->used - 1]; | |
22021 | } | |
22022 | r->used--; | |
22023 | } | |
22024 | - | |
22025 | + | |
22026 | return 0; | |
22027 | } | |
22028 | void fcgi_connection_close(server *srv, handler_ctx *hctx) { | |
22029 | plugin_data *p; | |
22030 | connection *con; | |
22031 | - | |
22032 | + | |
22033 | if (NULL == hctx) return; | |
22034 | - | |
22035 | + | |
22036 | p = hctx->plugin_data; | |
22037 | con = hctx->remote_conn; | |
22038 | - | |
22039 | + | |
22040 | if (con->mode != p->id) { | |
22041 | WP(); | |
22042 | return; | |
22043 | } | |
22044 | - | |
22045 | + | |
22046 | if (hctx->fd != -1) { | |
22047 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
22048 | fdevent_unregister(srv->ev, hctx->fd); | |
22049 | close(hctx->fd); | |
22050 | srv->cur_fds--; | |
22051 | } | |
22052 | - | |
22053 | + | |
22054 | if (hctx->request_id != 0) { | |
22055 | fcgi_requestid_del(srv, p, hctx->request_id); | |
22056 | } | |
22057 | @@ -1499,7 +1497,7 @@ | |
22058 | if (hctx->got_proc) { | |
22059 | /* after the connect the process gets a load */ | |
22060 | hctx->proc->load--; | |
22061 | - | |
22062 | + | |
22063 | status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests")); | |
22064 | ||
22065 | fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); | |
22066 | @@ -1509,39 +1507,39 @@ | |
22067 | ||
22068 | if (p->conf.debug) { | |
22069 | log_error_write(srv, __FILE__, __LINE__, "ssdsbsd", | |
22070 | - "released proc:", | |
22071 | - "pid:", hctx->proc->pid, | |
22072 | - "socket:", hctx->proc->connection_name, | |
22073 | + "released proc:", | |
22074 | + "pid:", hctx->proc->pid, | |
22075 | + "socket:", hctx->proc->connection_name, | |
22076 | "load:", hctx->proc->load); | |
22077 | } | |
22078 | } | |
22079 | } | |
22080 | ||
22081 | - | |
22082 | + | |
22083 | handler_ctx_free(hctx); | |
22084 | - con->plugin_ctx[p->id] = NULL; | |
22085 | + con->plugin_ctx[p->id] = NULL; | |
22086 | } | |
22087 | ||
22088 | static int fcgi_reconnect(server *srv, handler_ctx *hctx) { | |
22089 | plugin_data *p = hctx->plugin_data; | |
22090 | - | |
22091 | - /* child died | |
22092 | - * | |
22093 | - * 1. | |
22094 | - * | |
22095 | + | |
22096 | + /* child died | |
22097 | + * | |
22098 | + * 1. | |
22099 | + * | |
22100 | * connect was ok, connection was accepted | |
22101 | * but the php accept loop checks after the accept if it should die or not. | |
22102 | - * | |
22103 | - * if yes we can only detect it at a write() | |
22104 | - * | |
22105 | + * | |
22106 | + * if yes we can only detect it at a write() | |
22107 | + * | |
22108 | * next step is resetting this attemp and setup a connection again | |
22109 | - * | |
22110 | + * | |
22111 | * if we have more then 5 reconnects for the same request, die | |
22112 | - * | |
22113 | - * 2. | |
22114 | - * | |
22115 | + * | |
22116 | + * 2. | |
22117 | + * | |
22118 | * we have a connection but the child died by some other reason | |
22119 | - * | |
22120 | + * | |
22121 | */ | |
22122 | ||
22123 | if (hctx->fd != -1) { | |
22124 | @@ -1551,59 +1549,59 @@ | |
22125 | srv->cur_fds--; | |
22126 | hctx->fd = -1; | |
22127 | } | |
22128 | - | |
22129 | + | |
22130 | fcgi_requestid_del(srv, p, hctx->request_id); | |
22131 | - | |
22132 | + | |
22133 | fcgi_set_state(srv, hctx, FCGI_STATE_INIT); | |
22134 | - | |
22135 | + | |
22136 | hctx->request_id = 0; | |
22137 | hctx->reconnects++; | |
22138 | - | |
22139 | + | |
22140 | if (p->conf.debug > 2) { | |
22141 | if (hctx->proc) { | |
22142 | log_error_write(srv, __FILE__, __LINE__, "sdb", | |
22143 | - "release proc for reconnect:", | |
22144 | + "release proc for reconnect:", | |
22145 | hctx->proc->pid, hctx->proc->connection_name); | |
22146 | } else { | |
22147 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
22148 | - "release proc for reconnect:", | |
22149 | + "release proc for reconnect:", | |
22150 | hctx->host->unixsocket); | |
22151 | } | |
22152 | } | |
22153 | ||
22154 | - if (hctx->proc && hctx->got_proc) { | |
22155 | + if (hctx->proc && hctx->got_proc) { | |
22156 | hctx->proc->load--; | |
22157 | } | |
22158 | ||
22159 | /* perhaps another host gives us more luck */ | |
22160 | hctx->host->load--; | |
22161 | hctx->host = NULL; | |
22162 | - | |
22163 | + | |
22164 | return 0; | |
22165 | } | |
22166 | ||
22167 | ||
22168 | static handler_t fcgi_connection_reset(server *srv, connection *con, void *p_d) { | |
22169 | plugin_data *p = p_d; | |
22170 | - | |
22171 | + | |
22172 | fcgi_connection_close(srv, con->plugin_ctx[p->id]); | |
22173 | - | |
22174 | + | |
22175 | return HANDLER_GO_ON; | |
22176 | } | |
22177 | ||
22178 | ||
22179 | static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) { | |
22180 | size_t len; | |
22181 | - | |
22182 | + | |
22183 | if (!key || !val) return -1; | |
22184 | - | |
22185 | + | |
22186 | len = key_len + val_len; | |
22187 | - | |
22188 | + | |
22189 | len += key_len > 127 ? 4 : 1; | |
22190 | len += val_len > 127 ? 4 : 1; | |
22191 | - | |
22192 | + | |
22193 | buffer_prepare_append(env, len); | |
22194 | - | |
22195 | + | |
22196 | if (key_len > 127) { | |
22197 | env->ptr[env->used++] = ((key_len >> 24) & 0xff) | 0x80; | |
22198 | env->ptr[env->used++] = (key_len >> 16) & 0xff; | |
22199 | @@ -1612,7 +1610,7 @@ | |
22200 | } else { | |
22201 | env->ptr[env->used++] = (key_len >> 0) & 0xff; | |
22202 | } | |
22203 | - | |
22204 | + | |
22205 | if (val_len > 127) { | |
22206 | env->ptr[env->used++] = ((val_len >> 24) & 0xff) | 0x80; | |
22207 | env->ptr[env->used++] = (val_len >> 16) & 0xff; | |
22208 | @@ -1621,12 +1619,12 @@ | |
22209 | } else { | |
22210 | env->ptr[env->used++] = (val_len >> 0) & 0xff; | |
22211 | } | |
22212 | - | |
22213 | + | |
22214 | memcpy(env->ptr + env->used, key, key_len); | |
22215 | env->used += key_len; | |
22216 | memcpy(env->ptr + env->used, val, val_len); | |
22217 | env->used += val_len; | |
22218 | - | |
22219 | + | |
22220 | return 0; | |
22221 | } | |
22222 | ||
22223 | @@ -1639,11 +1637,11 @@ | |
22224 | header->contentLengthB1 = (contentLength >> 8) & 0xff; | |
22225 | header->paddingLength = paddingLength; | |
22226 | header->reserved = 0; | |
22227 | - | |
22228 | + | |
22229 | return 0; | |
22230 | } | |
22231 | /** | |
22232 | - * | |
22233 | + * | |
22234 | * returns | |
22235 | * -1 error | |
22236 | * 0 connected | |
22237 | @@ -1665,26 +1663,23 @@ | |
22238 | struct sockaddr_un fcgi_addr_un; | |
22239 | #endif | |
22240 | socklen_t servlen; | |
22241 | - | |
22242 | + | |
22243 | fcgi_extension_host *host = hctx->host; | |
22244 | fcgi_proc *proc = hctx->proc; | |
22245 | int fcgi_fd = hctx->fd; | |
22246 | - | |
22247 | + | |
22248 | memset(&fcgi_addr, 0, sizeof(fcgi_addr)); | |
22249 | - | |
22250 | + | |
22251 | if (!buffer_is_empty(proc->unixsocket)) { | |
22252 | #ifdef HAVE_SYS_UN_H | |
22253 | /* use the unix domain socket */ | |
22254 | fcgi_addr_un.sun_family = AF_UNIX; | |
22255 | strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr); | |
22256 | -#ifdef SUN_LEN | |
22257 | + | |
22258 | servlen = SUN_LEN(&fcgi_addr_un); | |
22259 | -#else | |
22260 | - /* stevens says: */ | |
22261 | - servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family); | |
22262 | -#endif | |
22263 | + | |
22264 | fcgi_addr = (struct sockaddr *) &fcgi_addr_un; | |
22265 | - | |
22266 | + | |
22267 | if (buffer_is_empty(proc->connection_name)) { | |
22268 | /* on remote spawing we have to set the connection-name now */ | |
22269 | buffer_copy_string(proc->connection_name, "unix:"); | |
22270 | @@ -1695,16 +1690,18 @@ | |
22271 | #endif | |
22272 | } else { | |
22273 | fcgi_addr_in.sin_family = AF_INET; | |
22274 | + | |
22275 | if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) { | |
22276 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
22277 | - "converting IP-adress failed for", host->host, | |
22278 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
22279 | + "converting IP-adress failed for", host->host, | |
22280 | "\nBe sure to specify an IP address here"); | |
22281 | - | |
22282 | + | |
22283 | return -1; | |
22284 | } | |
22285 | + | |
22286 | fcgi_addr_in.sin_port = htons(proc->port); | |
22287 | servlen = sizeof(fcgi_addr_in); | |
22288 | - | |
22289 | + | |
22290 | fcgi_addr = (struct sockaddr *) &fcgi_addr_in; | |
22291 | ||
22292 | if (buffer_is_empty(proc->connection_name)) { | |
22293 | @@ -1715,20 +1712,20 @@ | |
22294 | buffer_append_long(proc->connection_name, proc->port); | |
22295 | } | |
22296 | } | |
22297 | - | |
22298 | + | |
22299 | if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) { | |
22300 | - if (errno == EINPROGRESS || | |
22301 | + if (errno == EINPROGRESS || | |
22302 | errno == EALREADY || | |
22303 | errno == EINTR) { | |
22304 | if (hctx->conf.debug > 2) { | |
22305 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
22306 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
22307 | "connect delayed, will continue later:", proc->connection_name); | |
22308 | } | |
22309 | - | |
22310 | + | |
22311 | return CONNECTION_DELAYED; | |
22312 | } else if (errno == EAGAIN) { | |
22313 | if (hctx->conf.debug) { | |
22314 | - log_error_write(srv, __FILE__, __LINE__, "sbsd", | |
22315 | + log_error_write(srv, __FILE__, __LINE__, "sbsd", | |
22316 | "This means that the you have more incoming requests than your fastcgi-backend can handle in parallel. " | |
22317 | "Perhaps it helps to spawn more fastcgi backend or php-children, if not decrease server.max-connections." | |
22318 | "The load for this fastcgi backend", proc->connection_name, "is", proc->load); | |
22319 | @@ -1736,8 +1733,8 @@ | |
22320 | ||
22321 | return CONNECTION_OVERLOADED; | |
22322 | } else { | |
22323 | - log_error_write(srv, __FILE__, __LINE__, "sssb", | |
22324 | - "connect failed:", | |
22325 | + log_error_write(srv, __FILE__, __LINE__, "sssb", | |
22326 | + "connect failed:", | |
22327 | strerror(errno), "on", | |
22328 | proc->connection_name); | |
22329 | ||
22330 | @@ -1747,7 +1744,7 @@ | |
22331 | ||
22332 | hctx->reconnects = 0; | |
22333 | if (hctx->conf.debug > 1) { | |
22334 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
22335 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
22336 | "connect succeeded: ", fcgi_fd); | |
22337 | } | |
22338 | ||
22339 | @@ -1756,21 +1753,21 @@ | |
22340 | ||
22341 | static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) { | |
22342 | size_t i; | |
22343 | - | |
22344 | + | |
22345 | for (i = 0; i < con->request.headers->used; i++) { | |
22346 | data_string *ds; | |
22347 | - | |
22348 | + | |
22349 | ds = (data_string *)con->request.headers->data[i]; | |
22350 | - | |
22351 | + | |
22352 | if (ds->value->used && ds->key->used) { | |
22353 | size_t j; | |
22354 | buffer_reset(srv->tmp_buf); | |
22355 | - | |
22356 | + | |
22357 | if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { | |
22358 | BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_"); | |
22359 | srv->tmp_buf->used--; | |
22360 | } | |
22361 | - | |
22362 | + | |
22363 | buffer_prepare_append(srv->tmp_buf, ds->key->used + 2); | |
22364 | for (j = 0; j < ds->key->used - 1; j++) { | |
22365 | char c = '_'; | |
22366 | @@ -1784,20 +1781,20 @@ | |
22367 | srv->tmp_buf->ptr[srv->tmp_buf->used++] = c; | |
22368 | } | |
22369 | srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0'; | |
22370 | - | |
22371 | + | |
22372 | fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)); | |
22373 | } | |
22374 | } | |
22375 | - | |
22376 | + | |
22377 | for (i = 0; i < con->environment->used; i++) { | |
22378 | data_string *ds; | |
22379 | - | |
22380 | + | |
22381 | ds = (data_string *)con->environment->data[i]; | |
22382 | - | |
22383 | + | |
22384 | if (ds->value->used && ds->key->used) { | |
22385 | size_t j; | |
22386 | buffer_reset(srv->tmp_buf); | |
22387 | - | |
22388 | + | |
22389 | buffer_prepare_append(srv->tmp_buf, ds->key->used + 2); | |
22390 | for (j = 0; j < ds->key->used - 1; j++) { | |
22391 | char c = '_'; | |
22392 | @@ -1811,11 +1808,11 @@ | |
22393 | srv->tmp_buf->ptr[srv->tmp_buf->used++] = c; | |
22394 | } | |
22395 | srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0'; | |
22396 | - | |
22397 | + | |
22398 | fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)); | |
22399 | } | |
22400 | } | |
22401 | - | |
22402 | + | |
22403 | return 0; | |
22404 | } | |
22405 | ||
22406 | @@ -1824,24 +1821,24 @@ | |
22407 | FCGI_BeginRequestRecord beginRecord; | |
22408 | FCGI_Header header; | |
22409 | buffer *b; | |
22410 | - | |
22411 | + | |
22412 | char buf[32]; | |
22413 | const char *s; | |
22414 | #ifdef HAVE_IPV6 | |
22415 | char b2[INET6_ADDRSTRLEN + 1]; | |
22416 | #endif | |
22417 | - | |
22418 | + | |
22419 | plugin_data *p = hctx->plugin_data; | |
22420 | fcgi_extension_host *host= hctx->host; | |
22421 | ||
22422 | connection *con = hctx->remote_conn; | |
22423 | server_socket *srv_sock = con->srv_socket; | |
22424 | - | |
22425 | + | |
22426 | sock_addr our_addr; | |
22427 | socklen_t our_addr_len; | |
22428 | - | |
22429 | + | |
22430 | /* send FCGI_BEGIN_REQUEST */ | |
22431 | - | |
22432 | + | |
22433 | fcgi_header(&(beginRecord.header), FCGI_BEGIN_REQUEST, request_id, sizeof(beginRecord.body), 0); | |
22434 | beginRecord.body.roleB0 = host->mode; | |
22435 | beginRecord.body.roleB1 = 0; | |
22436 | @@ -1849,21 +1846,21 @@ | |
22437 | memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved)); | |
22438 | ||
22439 | b = chunkqueue_get_append_buffer(hctx->wb); | |
22440 | - | |
22441 | + | |
22442 | buffer_copy_memory(b, (const char *)&beginRecord, sizeof(beginRecord)); | |
22443 | - | |
22444 | + | |
22445 | /* send FCGI_PARAMS */ | |
22446 | buffer_prepare_copy(p->fcgi_env, 1024); | |
22447 | ||
22448 | ||
22449 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION)); | |
22450 | - | |
22451 | + | |
22452 | if (con->server_name->used) { | |
22453 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name)); | |
22454 | } else { | |
22455 | #ifdef HAVE_IPV6 | |
22456 | - s = inet_ntop(srv_sock->addr.plain.sa_family, | |
22457 | - srv_sock->addr.plain.sa_family == AF_INET6 ? | |
22458 | + s = inet_ntop(srv_sock->addr.plain.sa_family, | |
22459 | + srv_sock->addr.plain.sa_family == AF_INET6 ? | |
22460 | (const void *) &(srv_sock->addr.ipv6.sin6_addr) : | |
22461 | (const void *) &(srv_sock->addr.ipv4.sin_addr), | |
22462 | b2, sizeof(b2)-1); | |
22463 | @@ -1872,50 +1869,50 @@ | |
22464 | #endif | |
22465 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s)); | |
22466 | } | |
22467 | - | |
22468 | + | |
22469 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")); | |
22470 | - | |
22471 | - ltostr(buf, | |
22472 | + | |
22473 | + ltostr(buf, | |
22474 | #ifdef HAVE_IPV6 | |
22475 | ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port) | |
22476 | #else | |
22477 | ntohs(srv_sock->addr.ipv4.sin_port) | |
22478 | #endif | |
22479 | ); | |
22480 | - | |
22481 | + | |
22482 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf)); | |
22483 | - | |
22484 | + | |
22485 | /* get the server-side of the connection to the client */ | |
22486 | our_addr_len = sizeof(our_addr); | |
22487 | - | |
22488 | + | |
22489 | if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) { | |
22490 | s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr)); | |
22491 | } else { | |
22492 | s = inet_ntop_cache_get_ip(srv, &(our_addr)); | |
22493 | } | |
22494 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s)); | |
22495 | - | |
22496 | - ltostr(buf, | |
22497 | + | |
22498 | + ltostr(buf, | |
22499 | #ifdef HAVE_IPV6 | |
22500 | ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port) | |
22501 | #else | |
22502 | ntohs(con->dst_addr.ipv4.sin_port) | |
22503 | #endif | |
22504 | ); | |
22505 | - | |
22506 | + | |
22507 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf)); | |
22508 | - | |
22509 | + | |
22510 | s = inet_ntop_cache_get_ip(srv, &(con->dst_addr)); | |
22511 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s)); | |
22512 | - | |
22513 | + | |
22514 | if (!buffer_is_empty(con->authed_user)) { | |
22515 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"), | |
22516 | CONST_BUF_LEN(con->authed_user)); | |
22517 | } | |
22518 | - | |
22519 | + | |
22520 | if (con->request.content_length > 0 && host->mode != FCGI_AUTHORIZER) { | |
22521 | /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */ | |
22522 | - | |
22523 | + | |
22524 | /* request.content_length < SSIZE_MAX, see request.c */ | |
22525 | ltostr(buf, con->request.content_length); | |
22526 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)); | |
22527 | @@ -1930,12 +1927,12 @@ | |
22528 | */ | |
22529 | ||
22530 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)); | |
22531 | - | |
22532 | + | |
22533 | if (!buffer_is_empty(con->request.pathinfo)) { | |
22534 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo)); | |
22535 | - | |
22536 | + | |
22537 | /* PATH_TRANSLATED is only defined if PATH_INFO is set */ | |
22538 | - | |
22539 | + | |
22540 | if (!buffer_is_empty(host->docroot)) { | |
22541 | buffer_copy_string_buffer(p->path, host->docroot); | |
22542 | } else { | |
22543 | @@ -1957,27 +1954,27 @@ | |
22544 | */ | |
22545 | ||
22546 | if (!buffer_is_empty(host->docroot)) { | |
22547 | - /* | |
22548 | - * rewrite SCRIPT_FILENAME | |
22549 | - * | |
22550 | + /* | |
22551 | + * rewrite SCRIPT_FILENAME | |
22552 | + * | |
22553 | */ | |
22554 | - | |
22555 | + | |
22556 | buffer_copy_string_buffer(p->path, host->docroot); | |
22557 | buffer_append_string_buffer(p->path, con->uri.path); | |
22558 | - | |
22559 | + | |
22560 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)); | |
22561 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot)); | |
22562 | } else { | |
22563 | buffer_copy_string_buffer(p->path, con->physical.path); | |
22564 | - | |
22565 | - /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself | |
22566 | - * | |
22567 | + | |
22568 | + /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself | |
22569 | + * | |
22570 | * see src/sapi/cgi_main.c, init_request_info() | |
22571 | */ | |
22572 | if (host->break_scriptfilename_for_php) { | |
22573 | buffer_append_string_buffer(p->path, con->request.pathinfo); | |
22574 | } | |
22575 | - | |
22576 | + | |
22577 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)); | |
22578 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root)); | |
22579 | } | |
22580 | @@ -1987,7 +1984,7 @@ | |
22581 | /** | |
22582 | * /app1/index/list | |
22583 | * | |
22584 | - * stripping /app1 or /app1/ should lead to | |
22585 | + * stripping /app1 or /app1/ should lead to | |
22586 | * | |
22587 | * /index/list | |
22588 | * | |
22589 | @@ -2001,7 +1998,7 @@ | |
22590 | 0 == strncmp(con->request.orig_uri->ptr, host->strip_request_uri->ptr, host->strip_request_uri->used - 1)) { | |
22591 | /* the left is the same */ | |
22592 | ||
22593 | - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), | |
22594 | + fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), | |
22595 | con->request.orig_uri->ptr + (host->strip_request_uri->used - 2), | |
22596 | con->request.orig_uri->used - (host->strip_request_uri->used - 2)); | |
22597 | } else { | |
22598 | @@ -2018,26 +2015,26 @@ | |
22599 | } else { | |
22600 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN("")); | |
22601 | } | |
22602 | - | |
22603 | + | |
22604 | s = get_http_method_name(con->request.http_method); | |
22605 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s)); | |
22606 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */ | |
22607 | s = get_http_version_name(con->request.http_version); | |
22608 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s)); | |
22609 | - | |
22610 | + | |
22611 | #ifdef USE_OPENSSL | |
22612 | if (srv_sock->is_ssl) { | |
22613 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); | |
22614 | } | |
22615 | #endif | |
22616 | - | |
22617 | - | |
22618 | + | |
22619 | + | |
22620 | fcgi_env_add_request_headers(srv, con, p); | |
22621 | - | |
22622 | + | |
22623 | fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0); | |
22624 | buffer_append_memory(b, (const char *)&header, sizeof(header)); | |
22625 | buffer_append_memory(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used); | |
22626 | - | |
22627 | + | |
22628 | fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0); | |
22629 | buffer_append_memory(b, (const char *)&header, sizeof(header)); | |
22630 | ||
22631 | @@ -2057,7 +2054,7 @@ | |
22632 | ||
22633 | /* we announce toWrite octects | |
22634 | * now take all the request_content chunk that we need to fill this request | |
22635 | - * */ | |
22636 | + * */ | |
22637 | ||
22638 | b = chunkqueue_get_append_buffer(hctx->wb); | |
22639 | fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0); | |
22640 | @@ -2080,16 +2077,16 @@ | |
22641 | if (weHave > weWant - written) weHave = weWant - written; | |
22642 | ||
22643 | if (p->conf.debug > 10) { | |
22644 | - fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n", | |
22645 | - __FILE__, __LINE__, | |
22646 | - weHave, | |
22647 | - req_c->offset, | |
22648 | - req_c->file.length, | |
22649 | + fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n", | |
22650 | + __FILE__, __LINE__, | |
22651 | + weHave, | |
22652 | + req_c->offset, | |
22653 | + req_c->file.length, | |
22654 | req_c->file.name->ptr); | |
22655 | } | |
22656 | ||
22657 | assert(weHave != 0); | |
22658 | - | |
22659 | + | |
22660 | chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave); | |
22661 | ||
22662 | req_c->offset += weHave; | |
22663 | @@ -2104,7 +2101,7 @@ | |
22664 | * - we reference the tempfile from the request-content-queue several times | |
22665 | * if the req_c is larger than FCGI_MAX_LENGTH | |
22666 | * - we can't simply cleanup the request-content-queue as soon as possible | |
22667 | - * as it would remove the tempfiles | |
22668 | + * as it would remove the tempfiles | |
22669 | * - the idea is to 'steal' the tempfiles and attach the is_temp flag to the last | |
22670 | * referencing chunk of the fastcgi-write-queue | |
22671 | * | |
22672 | @@ -2141,7 +2138,7 @@ | |
22673 | req_c->offset += weHave; | |
22674 | req_cq->bytes_out += weHave; | |
22675 | written += weHave; | |
22676 | - | |
22677 | + | |
22678 | hctx->wb->bytes_in += weHave; | |
22679 | ||
22680 | if (req_c->offset == req_c->mem->used - 1) { | |
22681 | @@ -2155,12 +2152,12 @@ | |
22682 | break; | |
22683 | } | |
22684 | } | |
22685 | - | |
22686 | + | |
22687 | b->used++; /* add virtual \0 */ | |
22688 | offset += weWant; | |
22689 | } | |
22690 | } | |
22691 | - | |
22692 | + | |
22693 | b = chunkqueue_get_append_buffer(hctx->wb); | |
22694 | /* terminate STDIN */ | |
22695 | fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0); | |
22696 | @@ -2175,118 +2172,19 @@ | |
22697 | if ((i+1) % 16 == 0) { | |
22698 | size_t j; | |
22699 | for (j = i-15; j <= i; j++) { | |
22700 | - fprintf(stderr, "%c", | |
22701 | + fprintf(stderr, "%c", | |
22702 | isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.'); | |
22703 | } | |
22704 | fprintf(stderr, "\n"); | |
22705 | } | |
22706 | } | |
22707 | #endif | |
22708 | - | |
22709 | - return 0; | |
22710 | -} | |
22711 | - | |
22712 | -static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) { | |
22713 | - char *s, *ns; | |
22714 | - | |
22715 | - handler_ctx *hctx = con->plugin_ctx[p->id]; | |
22716 | - fcgi_extension_host *host= hctx->host; | |
22717 | - | |
22718 | - UNUSED(srv); | |
22719 | ||
22720 | - buffer_copy_string_buffer(p->parse_response, in); | |
22721 | - | |
22722 | - /* search for \n */ | |
22723 | - for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) { | |
22724 | - char *key, *value; | |
22725 | - int key_len; | |
22726 | - data_string *ds; | |
22727 | - | |
22728 | - /* a good day. Someone has read the specs and is sending a \r\n to us */ | |
22729 | - | |
22730 | - if (ns > p->parse_response->ptr && | |
22731 | - *(ns-1) == '\r') { | |
22732 | - *(ns-1) = '\0'; | |
22733 | - } | |
22734 | - | |
22735 | - ns[0] = '\0'; | |
22736 | - | |
22737 | - key = s; | |
22738 | - if (NULL == (value = strchr(s, ':'))) { | |
22739 | - /* we expect: "<key>: <value>\n" */ | |
22740 | - continue; | |
22741 | - } | |
22742 | - | |
22743 | - key_len = value - key; | |
22744 | - | |
22745 | - value++; | |
22746 | - /* strip WS */ | |
22747 | - while (*value == ' ' || *value == '\t') value++; | |
22748 | - | |
22749 | - if (host->mode != FCGI_AUTHORIZER || | |
22750 | - !(con->http_status == 0 || | |
22751 | - con->http_status == 200)) { | |
22752 | - /* authorizers shouldn't affect the response headers sent back to the client */ | |
22753 | - | |
22754 | - /* don't forward Status: */ | |
22755 | - if (0 != strncasecmp(key, "Status", key_len)) { | |
22756 | - if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { | |
22757 | - ds = data_response_init(); | |
22758 | - } | |
22759 | - buffer_copy_string_len(ds->key, key, key_len); | |
22760 | - buffer_copy_string(ds->value, value); | |
22761 | - | |
22762 | - array_insert_unique(con->response.headers, (data_unset *)ds); | |
22763 | - } | |
22764 | - } | |
22765 | - | |
22766 | - switch(key_len) { | |
22767 | - case 4: | |
22768 | - if (0 == strncasecmp(key, "Date", key_len)) { | |
22769 | - con->parsed_response |= HTTP_DATE; | |
22770 | - } | |
22771 | - break; | |
22772 | - case 6: | |
22773 | - if (0 == strncasecmp(key, "Status", key_len)) { | |
22774 | - con->http_status = strtol(value, NULL, 10); | |
22775 | - con->parsed_response |= HTTP_STATUS; | |
22776 | - } | |
22777 | - break; | |
22778 | - case 8: | |
22779 | - if (0 == strncasecmp(key, "Location", key_len)) { | |
22780 | - con->parsed_response |= HTTP_LOCATION; | |
22781 | - } | |
22782 | - break; | |
22783 | - case 10: | |
22784 | - if (0 == strncasecmp(key, "Connection", key_len)) { | |
22785 | - con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0; | |
22786 | - con->parsed_response |= HTTP_CONNECTION; | |
22787 | - } | |
22788 | - break; | |
22789 | - case 14: | |
22790 | - if (0 == strncasecmp(key, "Content-Length", key_len)) { | |
22791 | - con->response.content_length = strtol(value, NULL, 10); | |
22792 | - con->parsed_response |= HTTP_CONTENT_LENGTH; | |
22793 | - | |
22794 | - if (con->response.content_length < 0) con->response.content_length = 0; | |
22795 | - } | |
22796 | - break; | |
22797 | - default: | |
22798 | - break; | |
22799 | - } | |
22800 | - } | |
22801 | - | |
22802 | - /* CGI/1.1 rev 03 - 7.2.1.2 */ | |
22803 | - if ((con->parsed_response & HTTP_LOCATION) && | |
22804 | - !(con->parsed_response & HTTP_STATUS)) { | |
22805 | - con->http_status = 302; | |
22806 | - } | |
22807 | - | |
22808 | return 0; | |
22809 | } | |
22810 | ||
22811 | typedef struct { | |
22812 | - buffer *b; | |
22813 | + buffer *b; | |
22814 | size_t len; | |
22815 | int type; | |
22816 | int padding; | |
22817 | @@ -2327,9 +2225,9 @@ | |
22818 | return -1; | |
22819 | } | |
22820 | ||
22821 | - /* we have at least a header, now check how much me have to fetch */ | |
22822 | + /* we have at least a header, now check how much me have to fetch */ | |
22823 | header = (FCGI_Header *)(packet->b->ptr); | |
22824 | - | |
22825 | + | |
22826 | packet->len = (header->contentLengthB0 | (header->contentLengthB1 << 8)) + header->paddingLength; | |
22827 | packet->request_id = (header->requestIdB0 | (header->requestIdB1 << 8)); | |
22828 | packet->type = header->type; | |
22829 | @@ -2348,7 +2246,7 @@ | |
22830 | size_t weHave = c->mem->used - c->offset - offset - 1; | |
22831 | ||
22832 | if (weHave > weWant) weHave = weWant; | |
22833 | - | |
22834 | + | |
22835 | buffer_append_string_len(packet->b, c->mem->ptr + c->offset + offset, weHave); | |
22836 | ||
22837 | /* we only skipped the first 8 bytes as they are the fcgi header */ | |
22838 | @@ -2380,65 +2278,37 @@ | |
22839 | } | |
22840 | ||
22841 | chunkqueue_remove_finished_chunks(hctx->rb); | |
22842 | - | |
22843 | + | |
22844 | return 0; | |
22845 | } | |
22846 | ||
22847 | static int fcgi_demux_response(server *srv, handler_ctx *hctx) { | |
22848 | int fin = 0; | |
22849 | - int toread; | |
22850 | - ssize_t r; | |
22851 | - | |
22852 | + | |
22853 | plugin_data *p = hctx->plugin_data; | |
22854 | connection *con = hctx->remote_conn; | |
22855 | - int fcgi_fd = hctx->fd; | |
22856 | fcgi_extension_host *host= hctx->host; | |
22857 | fcgi_proc *proc = hctx->proc; | |
22858 | - | |
22859 | - /* | |
22860 | - * check how much we have to read | |
22861 | - */ | |
22862 | - if (ioctl(hctx->fd, FIONREAD, &toread)) { | |
22863 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
22864 | - "unexpected end-of-file (perhaps the fastcgi process died):", | |
22865 | - fcgi_fd); | |
22866 | - return -1; | |
22867 | - } | |
22868 | - | |
22869 | - /* init read-buffer */ | |
22870 | - | |
22871 | - if (toread > 0) { | |
22872 | - buffer *b; | |
22873 | - | |
22874 | - b = chunkqueue_get_append_buffer(hctx->rb); | |
22875 | - buffer_prepare_copy(b, toread + 1); | |
22876 | - | |
22877 | - /* append to read-buffer */ | |
22878 | - if (-1 == (r = read(hctx->fd, b->ptr, toread))) { | |
22879 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
22880 | - "unexpected end-of-file (perhaps the fastcgi process died):", | |
22881 | - fcgi_fd, strerror(errno)); | |
22882 | - return -1; | |
22883 | - } | |
22884 | - | |
22885 | - /* this should be catched by the b > 0 above */ | |
22886 | - assert(r); | |
22887 | ||
22888 | - b->used = r + 1; /* one extra for the fake \0 */ | |
22889 | - b->ptr[b->used - 1] = '\0'; | |
22890 | - } else { | |
22891 | - log_error_write(srv, __FILE__, __LINE__, "ssdsb", | |
22892 | + switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) { | |
22893 | + case NETWORK_STATUS_WAIT_FOR_EVENT: | |
22894 | + /* we are only triggered when there is a event */ | |
22895 | + log_error_write(srv, __FILE__, __LINE__, "ssdsb", | |
22896 | "unexpected end-of-file (perhaps the fastcgi process died):", | |
22897 | "pid:", proc->pid, | |
22898 | "socket:", proc->connection_name); | |
22899 | - | |
22900 | + return -1; | |
22901 | + case NETWORK_STATUS_SUCCESS: | |
22902 | + break; | |
22903 | + default: | |
22904 | + log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi-read failed"); | |
22905 | return -1; | |
22906 | } | |
22907 | ||
22908 | /* | |
22909 | * parse the fastcgi packets and forward the content to the write-queue | |
22910 | * | |
22911 | - */ | |
22912 | + */ | |
22913 | while (fin == 0) { | |
22914 | fastcgi_response_packet packet; | |
22915 | ||
22916 | @@ -2454,92 +2324,135 @@ | |
22917 | ||
22918 | /* is the header already finished */ | |
22919 | if (0 == con->file_started) { | |
22920 | - char *c; | |
22921 | - size_t blen; | |
22922 | - data_string *ds; | |
22923 | - | |
22924 | - /* search for header terminator | |
22925 | - * | |
22926 | - * if we start with \r\n check if last packet terminated with \r\n | |
22927 | - * if we start with \n check if last packet terminated with \n | |
22928 | - * search for \r\n\r\n | |
22929 | - * search for \n\n | |
22930 | - */ | |
22931 | - | |
22932 | - if (hctx->response_header->used == 0) { | |
22933 | - buffer_copy_string_buffer(hctx->response_header, packet.b); | |
22934 | - } else { | |
22935 | - buffer_append_string_buffer(hctx->response_header, packet.b); | |
22936 | - } | |
22937 | - | |
22938 | - if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) { | |
22939 | - blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4; | |
22940 | - hctx->response_header->used = (c - hctx->response_header->ptr) + 3; | |
22941 | - c += 4; /* point the the start of the response */ | |
22942 | - } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) { | |
22943 | - blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2; | |
22944 | - hctx->response_header->used = c - hctx->response_header->ptr + 2; | |
22945 | - c += 2; /* point the the start of the response */ | |
22946 | - } else { | |
22947 | - /* no luck, no header found */ | |
22948 | + int have_content_length = 0; | |
22949 | + int need_more = 0; | |
22950 | + size_t i; | |
22951 | + | |
22952 | + /* append the current packet to the chunk queue */ | |
22953 | + chunkqueue_append_buffer(hctx->http_rb, packet.b); | |
22954 | + http_response_reset(p->resp); | |
22955 | + | |
22956 | + switch(http_response_parse_cq(hctx->http_rb, p->resp)) { | |
22957 | + case PARSE_ERROR: | |
22958 | + /* parsing the response header failed */ | |
22959 | + | |
22960 | + con->http_status = 502; /* Bad Gateway */ | |
22961 | + | |
22962 | + return 1; | |
22963 | + case PARSE_NEED_MORE: | |
22964 | + need_more = 1; | |
22965 | + break; /* leave the loop */ | |
22966 | + case PARSE_SUCCESS: | |
22967 | break; | |
22968 | + default: | |
22969 | + /* should not happen */ | |
22970 | + SEGFAULT(); | |
22971 | } | |
22972 | ||
22973 | - /* parse the response header */ | |
22974 | - fcgi_response_parse(srv, con, p, hctx->response_header); | |
22975 | + if (need_more) break; | |
22976 | ||
22977 | - con->file_started = 1; | |
22978 | + chunkqueue_remove_finished_chunks(hctx->http_rb); | |
22979 | ||
22980 | - if (host->mode == FCGI_AUTHORIZER && | |
22981 | - (con->http_status == 0 || | |
22982 | - con->http_status == 200)) { | |
22983 | - /* a authorizer with approved the static request, ignore the content here */ | |
22984 | - hctx->send_content_body = 0; | |
22985 | - } | |
22986 | - | |
22987 | - if (host->allow_xsendfile && | |
22988 | - NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file"))) { | |
22989 | - stat_cache_entry *sce; | |
22990 | - | |
22991 | - if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) { | |
22992 | - /* found */ | |
22993 | - | |
22994 | - http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size); | |
22995 | - hctx->send_content_body = 0; /* ignore the content */ | |
22996 | - joblist_append(srv, con); | |
22997 | + con->http_status = p->resp->status; | |
22998 | + | |
22999 | + /* handle the header fields */ | |
23000 | + if (host->mode == FCGI_AUTHORIZER) { | |
23001 | + /* auth mode is a bit different */ | |
23002 | + | |
23003 | + if (con->http_status == 0 || | |
23004 | + con->http_status == 200) { | |
23005 | + /* a authorizer with approved the static request, ignore the content here */ | |
23006 | + hctx->send_content_body = 0; | |
23007 | } | |
23008 | } | |
23009 | ||
23010 | + /* copy the http-headers */ | |
23011 | + for (i = 0; i < p->resp->headers->used; i++) { | |
23012 | + const char *ign[] = { "Status", NULL }; | |
23013 | + size_t j; | |
23014 | + data_string *ds; | |
23015 | + | |
23016 | + data_string *header = (data_string *)p->resp->headers->data[i]; | |
23017 | + | |
23018 | + /* ignore all headers in AUTHORIZER mode */ | |
23019 | + if (host->mode == FCGI_AUTHORIZER) continue; | |
23020 | + | |
23021 | + /* some headers are ignored by default */ | |
23022 | + for (j = 0; ign[j]; j++) { | |
23023 | + if (0 == strcasecmp(ign[j], header->key->ptr)) break; | |
23024 | + } | |
23025 | + if (ign[j]) continue; | |
23026 | + | |
23027 | + if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) { | |
23028 | + /* CGI/1.1 rev 03 - 7.2.1.2 */ | |
23029 | + con->http_status = 302; | |
23030 | + } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) { | |
23031 | + have_content_length = 1; | |
23032 | + } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Sendfile")) || | |
23033 | + 0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-LIGHTTPD-send-file"))) { | |
23034 | + | |
23035 | + stat_cache_entry *sce; | |
23036 | ||
23037 | - if (hctx->send_content_body && blen > 1) { | |
23038 | - /* enable chunked-transfer-encoding */ | |
23039 | + if (host->allow_xsendfile && | |
23040 | + HANDLER_ERROR != stat_cache_get_entry(srv, con, header->value, &sce)) { | |
23041 | + http_chunk_append_file(srv, con, header->value, 0, sce->st.st_size); | |
23042 | + hctx->send_content_body = 0; /* ignore the content */ | |
23043 | + | |
23044 | + joblist_append(srv, con); | |
23045 | + } | |
23046 | + | |
23047 | + continue; /* ignore header */ | |
23048 | + } | |
23049 | + | |
23050 | + if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { | |
23051 | + ds = data_response_init(); | |
23052 | + } | |
23053 | + buffer_copy_string_buffer(ds->key, header->key); | |
23054 | + buffer_copy_string_buffer(ds->value, header->value); | |
23055 | + | |
23056 | + array_insert_unique(con->response.headers, (data_unset *)ds); | |
23057 | + } | |
23058 | + | |
23059 | + /* header is complete ... go on with the body */ | |
23060 | + | |
23061 | + con->file_started = 1; | |
23062 | + | |
23063 | + if (hctx->send_content_body) { | |
23064 | + chunk *c = hctx->http_rb->first; | |
23065 | + | |
23066 | + /* if we don't have a content-length enable chunked encoding | |
23067 | + * if possible | |
23068 | + * | |
23069 | + * TODO: move this to a later stage in the filter-queue | |
23070 | + * */ | |
23071 | if (con->request.http_version == HTTP_VERSION_1_1 && | |
23072 | - !(con->parsed_response & HTTP_CONTENT_LENGTH)) { | |
23073 | + !have_content_length) { | |
23074 | con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
23075 | } | |
23076 | ||
23077 | - http_chunk_append_mem(srv, con, c, blen); | |
23078 | + /* copy the rest of the data */ | |
23079 | + for (c = hctx->http_rb->first; c; c = c->next) { | |
23080 | + if (c->mem->used > 1) { | |
23081 | + http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset); | |
23082 | + c->offset = c->mem->used - 1; | |
23083 | + } | |
23084 | + } | |
23085 | + chunkqueue_remove_finished_chunks(hctx->http_rb); | |
23086 | joblist_append(srv, con); | |
23087 | } | |
23088 | } else if (hctx->send_content_body && packet.b->used > 1) { | |
23089 | - if (con->request.http_version == HTTP_VERSION_1_1 && | |
23090 | - !(con->parsed_response & HTTP_CONTENT_LENGTH)) { | |
23091 | - /* enable chunked-transfer-encoding */ | |
23092 | - con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
23093 | - } | |
23094 | - | |
23095 | http_chunk_append_mem(srv, con, packet.b->ptr, packet.b->used); | |
23096 | joblist_append(srv, con); | |
23097 | } | |
23098 | break; | |
23099 | case FCGI_STDERR: | |
23100 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
23101 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
23102 | "FastCGI-stderr:", packet.b); | |
23103 | - | |
23104 | + | |
23105 | break; | |
23106 | case FCGI_END_REQUEST: | |
23107 | con->file_finished = 1; | |
23108 | - | |
23109 | + | |
23110 | if (host->mode != FCGI_AUTHORIZER || | |
23111 | !(con->http_status == 0 || | |
23112 | con->http_status == 200)) { | |
23113 | @@ -2547,39 +2460,39 @@ | |
23114 | http_chunk_append_mem(srv, con, NULL, 0); | |
23115 | joblist_append(srv, con); | |
23116 | } | |
23117 | - | |
23118 | + | |
23119 | fin = 1; | |
23120 | break; | |
23121 | default: | |
23122 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23123 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23124 | "FastCGI: header.type not handled: ", packet.type); | |
23125 | break; | |
23126 | } | |
23127 | buffer_free(packet.b); | |
23128 | } | |
23129 | - | |
23130 | + | |
23131 | return fin; | |
23132 | } | |
23133 | ||
23134 | static int fcgi_restart_dead_procs(server *srv, plugin_data *p, fcgi_extension_host *host) { | |
23135 | fcgi_proc *proc; | |
23136 | - | |
23137 | + | |
23138 | for (proc = host->first; proc; proc = proc->next) { | |
23139 | int status; | |
23140 | ||
23141 | if (p->conf.debug > 2) { | |
23142 | - log_error_write(srv, __FILE__, __LINE__, "sbdddd", | |
23143 | - "proc:", | |
23144 | + log_error_write(srv, __FILE__, __LINE__, "sbdddd", | |
23145 | + "proc:", | |
23146 | proc->connection_name, | |
23147 | proc->state, | |
23148 | proc->is_local, | |
23149 | proc->load, | |
23150 | proc->pid); | |
23151 | } | |
23152 | - | |
23153 | - /* | |
23154 | + | |
23155 | + /* | |
23156 | * if the remote side is overloaded, we check back after <n> seconds | |
23157 | - * | |
23158 | + * | |
23159 | */ | |
23160 | switch (proc->state) { | |
23161 | case PROC_STATE_KILLED: | |
23162 | @@ -2592,13 +2505,13 @@ | |
23163 | break; | |
23164 | case PROC_STATE_OVERLOADED: | |
23165 | if (srv->cur_ts <= proc->disabled_until) break; | |
23166 | - | |
23167 | + | |
23168 | proc->state = PROC_STATE_RUNNING; | |
23169 | host->active_procs++; | |
23170 | - | |
23171 | - log_error_write(srv, __FILE__, __LINE__, "sbdb", | |
23172 | - "fcgi-server re-enabled:", | |
23173 | - host->host, host->port, | |
23174 | + | |
23175 | + log_error_write(srv, __FILE__, __LINE__, "sbdb", | |
23176 | + "fcgi-server re-enabled:", | |
23177 | + host->host, host->port, | |
23178 | host->unixsocket); | |
23179 | break; | |
23180 | case PROC_STATE_DIED_WAIT_FOR_PID: | |
23181 | @@ -2606,7 +2519,7 @@ | |
23182 | if (!proc->is_local) break; | |
23183 | ||
23184 | /* the child should not terminate at all */ | |
23185 | - | |
23186 | +#ifndef _WIN32 | |
23187 | switch(waitpid(proc->pid, &status, WNOHANG)) { | |
23188 | case 0: | |
23189 | /* child is still alive */ | |
23190 | @@ -2616,45 +2529,45 @@ | |
23191 | default: | |
23192 | if (WIFEXITED(status)) { | |
23193 | #if 0 | |
23194 | - log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
23195 | + log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
23196 | "child exited, pid:", proc->pid, | |
23197 | "status:", WEXITSTATUS(status)); | |
23198 | #endif | |
23199 | } else if (WIFSIGNALED(status)) { | |
23200 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23201 | - "child signaled:", | |
23202 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23203 | + "child signaled:", | |
23204 | WTERMSIG(status)); | |
23205 | } else { | |
23206 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23207 | - "child died somehow:", | |
23208 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23209 | + "child died somehow:", | |
23210 | status); | |
23211 | } | |
23212 | - | |
23213 | + | |
23214 | proc->state = PROC_STATE_DIED; | |
23215 | break; | |
23216 | } | |
23217 | - | |
23218 | +#endif | |
23219 | /* fall through if we have a dead proc now */ | |
23220 | if (proc->state != PROC_STATE_DIED) break; | |
23221 | ||
23222 | case PROC_STATE_DIED: | |
23223 | - /* local proc get restarted by us, | |
23224 | + /* local proc get restarted by us, | |
23225 | * remote ones hopefully by the admin */ | |
23226 | - | |
23227 | + | |
23228 | if (proc->is_local) { | |
23229 | /* we still have connections bound to this proc, | |
23230 | * let them terminate first */ | |
23231 | if (proc->load != 0) break; | |
23232 | - | |
23233 | + | |
23234 | /* restart the child */ | |
23235 | - | |
23236 | + | |
23237 | if (p->conf.debug) { | |
23238 | log_error_write(srv, __FILE__, __LINE__, "ssbsdsd", | |
23239 | "--- fastcgi spawning", | |
23240 | "\n\tsocket", proc->connection_name, | |
23241 | "\n\tcurrent:", 1, "/", host->min_procs); | |
23242 | } | |
23243 | - | |
23244 | + | |
23245 | if (fcgi_spawn_connection(srv, p, host, proc)) { | |
23246 | log_error_write(srv, __FILE__, __LINE__, "s", | |
23247 | "ERROR: spawning fcgi failed."); | |
23248 | @@ -2662,18 +2575,18 @@ | |
23249 | } | |
23250 | } else { | |
23251 | if (srv->cur_ts <= proc->disabled_until) break; | |
23252 | - | |
23253 | + | |
23254 | proc->state = PROC_STATE_RUNNING; | |
23255 | host->active_procs++; | |
23256 | - | |
23257 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
23258 | - "fcgi-server re-enabled:", | |
23259 | + | |
23260 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
23261 | + "fcgi-server re-enabled:", | |
23262 | proc->connection_name); | |
23263 | } | |
23264 | break; | |
23265 | } | |
23266 | } | |
23267 | - | |
23268 | + | |
23269 | return 0; | |
23270 | } | |
23271 | ||
23272 | @@ -2682,19 +2595,19 @@ | |
23273 | fcgi_extension_host *host= hctx->host; | |
23274 | connection *con = hctx->remote_conn; | |
23275 | fcgi_proc *proc; | |
23276 | - | |
23277 | + | |
23278 | int ret; | |
23279 | ||
23280 | - /* sanity check */ | |
23281 | + /* sanity check */ | |
23282 | if (!host || | |
23283 | ((!host->host->used || !host->port) && !host->unixsocket->used)) { | |
23284 | - log_error_write(srv, __FILE__, __LINE__, "sxddd", | |
23285 | + log_error_write(srv, __FILE__, __LINE__, "sxddd", | |
23286 | "write-req: error", | |
23287 | host, | |
23288 | host->host->used, | |
23289 | host->port, | |
23290 | host->unixsocket->used); | |
23291 | - | |
23292 | + | |
23293 | hctx->proc->disabled_until = srv->cur_ts + 10; | |
23294 | hctx->proc->state = PROC_STATE_DIED; | |
23295 | ||
23296 | @@ -2705,12 +2618,12 @@ | |
23297 | if (hctx->state == FCGI_STATE_CONNECT_DELAYED) { | |
23298 | int socket_error; | |
23299 | socklen_t socket_error_len = sizeof(socket_error); | |
23300 | - | |
23301 | + | |
23302 | /* try to finish the connect() */ | |
23303 | if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) { | |
23304 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
23305 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
23306 | "getsockopt failed:", strerror(errno)); | |
23307 | - | |
23308 | + | |
23309 | hctx->proc->disabled_until = srv->cur_ts + 10; | |
23310 | hctx->proc->state = PROC_STATE_DIED; | |
23311 | ||
23312 | @@ -2719,12 +2632,12 @@ | |
23313 | if (socket_error != 0) { | |
23314 | if (!hctx->proc->is_local || p->conf.debug) { | |
23315 | /* local procs get restarted */ | |
23316 | - | |
23317 | + | |
23318 | log_error_write(srv, __FILE__, __LINE__, "sssb", | |
23319 | - "establishing connection failed:", strerror(socket_error), | |
23320 | + "establishing connection failed:", strerror(socket_error), | |
23321 | "socket:", hctx->proc->connection_name); | |
23322 | } | |
23323 | - | |
23324 | + | |
23325 | hctx->proc->disabled_until = srv->cur_ts + 5; | |
23326 | ||
23327 | if (hctx->proc->is_local) { | |
23328 | @@ -2732,17 +2645,17 @@ | |
23329 | } else { | |
23330 | hctx->proc->state = PROC_STATE_DIED; | |
23331 | } | |
23332 | - | |
23333 | + | |
23334 | hctx->proc->state = PROC_STATE_DIED; | |
23335 | - | |
23336 | + | |
23337 | fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); | |
23338 | buffer_append_string(p->statuskey, ".died"); | |
23339 | ||
23340 | status_counter_inc(srv, CONST_BUF_LEN(p->statuskey)); | |
23341 | - | |
23342 | + | |
23343 | return HANDLER_ERROR; | |
23344 | } | |
23345 | - /* go on with preparing the request */ | |
23346 | + /* go on with preparing the request */ | |
23347 | hctx->state = FCGI_STATE_PREPARE_WRITE; | |
23348 | } | |
23349 | ||
23350 | @@ -2755,14 +2668,14 @@ | |
23351 | /* do we have a running process for this host (max-procs) ? */ | |
23352 | hctx->proc = NULL; | |
23353 | ||
23354 | - for (proc = hctx->host->first; | |
23355 | - proc && proc->state != PROC_STATE_RUNNING; | |
23356 | + for (proc = hctx->host->first; | |
23357 | + proc && proc->state != PROC_STATE_RUNNING; | |
23358 | proc = proc->next); | |
23359 | - | |
23360 | + | |
23361 | /* all childs are dead */ | |
23362 | if (proc == NULL) { | |
23363 | hctx->fde_ndx = -1; | |
23364 | - | |
23365 | + | |
23366 | return HANDLER_ERROR; | |
23367 | } | |
23368 | ||
23369 | @@ -2775,50 +2688,50 @@ | |
23370 | } | |
23371 | ||
23372 | ret = host->unixsocket->used ? AF_UNIX : AF_INET; | |
23373 | - | |
23374 | + | |
23375 | if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) { | |
23376 | if (errno == EMFILE || | |
23377 | errno == EINTR) { | |
23378 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23379 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23380 | "wait for fd at connection:", con->fd); | |
23381 | - | |
23382 | + | |
23383 | return HANDLER_WAIT_FOR_FD; | |
23384 | } | |
23385 | - | |
23386 | - log_error_write(srv, __FILE__, __LINE__, "ssdd", | |
23387 | + | |
23388 | + log_error_write(srv, __FILE__, __LINE__, "ssdd", | |
23389 | "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds); | |
23390 | return HANDLER_ERROR; | |
23391 | } | |
23392 | hctx->fde_ndx = -1; | |
23393 | - | |
23394 | + | |
23395 | srv->cur_fds++; | |
23396 | - | |
23397 | + | |
23398 | fdevent_register(srv->ev, hctx->fd, fcgi_handle_fdevent, hctx); | |
23399 | - | |
23400 | + | |
23401 | if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) { | |
23402 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
23403 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
23404 | "fcntl failed:", strerror(errno)); | |
23405 | - | |
23406 | + | |
23407 | return HANDLER_ERROR; | |
23408 | } | |
23409 | - | |
23410 | + | |
23411 | if (hctx->proc->is_local) { | |
23412 | hctx->pid = hctx->proc->pid; | |
23413 | } | |
23414 | - | |
23415 | + | |
23416 | switch (fcgi_establish_connection(srv, hctx)) { | |
23417 | case CONNECTION_DELAYED: | |
23418 | /* connection is in progress, wait for an event and call getsockopt() below */ | |
23419 | - | |
23420 | + | |
23421 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
23422 | - | |
23423 | + | |
23424 | fcgi_set_state(srv, hctx, FCGI_STATE_CONNECT_DELAYED); | |
23425 | return HANDLER_WAIT_FOR_EVENT; | |
23426 | case CONNECTION_OVERLOADED: | |
23427 | /* cool down the backend, it is overloaded | |
23428 | * -> EAGAIN */ | |
23429 | ||
23430 | - log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
23431 | + log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
23432 | "backend is overloaded, we disable it for a 2 seconds and send the request to another backend instead:", | |
23433 | "reconnects:", hctx->reconnects, | |
23434 | "load:", host->load); | |
23435 | @@ -2831,7 +2744,7 @@ | |
23436 | buffer_append_string(p->statuskey, ".overloaded"); | |
23437 | ||
23438 | status_counter_inc(srv, CONST_BUF_LEN(p->statuskey)); | |
23439 | - | |
23440 | + | |
23441 | return HANDLER_ERROR; | |
23442 | case CONNECTION_DEAD: | |
23443 | /* we got a hard error from the backend like | |
23444 | @@ -2840,19 +2753,19 @@ | |
23445 | * | |
23446 | * for check if the host is back in 5 seconds | |
23447 | * */ | |
23448 | - | |
23449 | + | |
23450 | hctx->proc->disabled_until = srv->cur_ts + 5; | |
23451 | if (hctx->proc->is_local) { | |
23452 | hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID; | |
23453 | } else { | |
23454 | hctx->proc->state = PROC_STATE_DIED; | |
23455 | } | |
23456 | - | |
23457 | - log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
23458 | + | |
23459 | + log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
23460 | "backend died, we disable it for a 5 seconds and send the request to another backend instead:", | |
23461 | "reconnects:", hctx->reconnects, | |
23462 | "load:", host->load); | |
23463 | - | |
23464 | + | |
23465 | fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); | |
23466 | buffer_append_string(p->statuskey, ".died"); | |
23467 | ||
23468 | @@ -2863,19 +2776,19 @@ | |
23469 | /* everything is ok, go on */ | |
23470 | ||
23471 | fcgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE); | |
23472 | - | |
23473 | + | |
23474 | break; | |
23475 | case CONNECTION_UNSET: | |
23476 | break; | |
23477 | } | |
23478 | - | |
23479 | + | |
23480 | case FCGI_STATE_PREPARE_WRITE: | |
23481 | /* ok, we have the connection */ | |
23482 | - | |
23483 | + | |
23484 | hctx->proc->load++; | |
23485 | hctx->proc->last_used = srv->cur_ts; | |
23486 | hctx->got_proc = 1; | |
23487 | - | |
23488 | + | |
23489 | status_counter_inc(srv, CONST_STR_LEN("fastcgi.requests")); | |
23490 | status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests")); | |
23491 | ||
23492 | @@ -2898,9 +2811,9 @@ | |
23493 | ||
23494 | if (p->conf.debug) { | |
23495 | log_error_write(srv, __FILE__, __LINE__, "ssdsbsd", | |
23496 | - "got proc:", | |
23497 | - "pid:", hctx->proc->pid, | |
23498 | - "socket:", hctx->proc->connection_name, | |
23499 | + "got proc:", | |
23500 | + "pid:", hctx->proc->pid, | |
23501 | + "socket:", hctx->proc->connection_name, | |
23502 | "load:", hctx->proc->load); | |
23503 | } | |
23504 | ||
23505 | @@ -2908,62 +2821,63 @@ | |
23506 | if (hctx->request_id == 0) { | |
23507 | hctx->request_id = fcgi_requestid_new(srv, p); | |
23508 | } else { | |
23509 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23510 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23511 | "fcgi-request is already in use:", hctx->request_id); | |
23512 | } | |
23513 | - | |
23514 | + | |
23515 | /* fall through */ | |
23516 | fcgi_create_env(srv, hctx, hctx->request_id); | |
23517 | - | |
23518 | + | |
23519 | fcgi_set_state(srv, hctx, FCGI_STATE_WRITE); | |
23520 | - | |
23521 | + | |
23522 | /* fall through */ | |
23523 | case FCGI_STATE_WRITE: | |
23524 | - ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); | |
23525 | + ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); | |
23526 | ||
23527 | chunkqueue_remove_finished_chunks(hctx->wb); | |
23528 | - | |
23529 | + | |
23530 | if (ret < 0) { | |
23531 | switch(errno) { | |
23532 | case ENOTCONN: | |
23533 | - /* the connection got dropped after accept() | |
23534 | - * | |
23535 | - * this is most of the time a PHP which dies | |
23536 | + /* the connection got dropped after accept() | |
23537 | + * | |
23538 | + * this is most of the time a PHP which dies | |
23539 | * after PHP_FCGI_MAX_REQUESTS | |
23540 | - * | |
23541 | - */ | |
23542 | + * | |
23543 | + */ | |
23544 | if (hctx->wb->bytes_out == 0 && | |
23545 | hctx->reconnects < 5) { | |
23546 | - usleep(10000); /* take away the load of the webserver | |
23547 | - * to let the php a chance to restart | |
23548 | +#ifndef _WIN32 | |
23549 | + usleep(10000); /* take away the load of the webserver | |
23550 | + * to let the php a chance to restart | |
23551 | */ | |
23552 | - | |
23553 | +#endif | |
23554 | fcgi_reconnect(srv, hctx); | |
23555 | - | |
23556 | + | |
23557 | return HANDLER_WAIT_FOR_FD; | |
23558 | } | |
23559 | - | |
23560 | + | |
23561 | /* not reconnected ... why | |
23562 | - * | |
23563 | + * | |
23564 | * far@#lighttpd report this for FreeBSD | |
23565 | - * | |
23566 | + * | |
23567 | */ | |
23568 | - | |
23569 | - log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
23570 | + | |
23571 | + log_error_write(srv, __FILE__, __LINE__, "ssosd", | |
23572 | "[REPORT ME] connection was dropped after accept(). reconnect() denied:", | |
23573 | "write-offset:", hctx->wb->bytes_out, | |
23574 | "reconnect attempts:", hctx->reconnects); | |
23575 | - | |
23576 | + | |
23577 | return HANDLER_ERROR; | |
23578 | case EAGAIN: | |
23579 | case EINTR: | |
23580 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
23581 | - | |
23582 | + | |
23583 | return HANDLER_WAIT_FOR_EVENT; | |
23584 | default: | |
23585 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
23586 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
23587 | "write failed:", strerror(errno), errno); | |
23588 | - | |
23589 | + | |
23590 | return HANDLER_ERROR; | |
23591 | } | |
23592 | } | |
23593 | @@ -2975,7 +2889,7 @@ | |
23594 | fcgi_set_state(srv, hctx, FCGI_STATE_READ); | |
23595 | } else { | |
23596 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
23597 | - | |
23598 | + | |
23599 | return HANDLER_WAIT_FOR_EVENT; | |
23600 | } | |
23601 | ||
23602 | @@ -2987,7 +2901,7 @@ | |
23603 | log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state"); | |
23604 | return HANDLER_ERROR; | |
23605 | } | |
23606 | - | |
23607 | + | |
23608 | return HANDLER_WAIT_FOR_EVENT; | |
23609 | } | |
23610 | ||
23611 | @@ -2996,18 +2910,18 @@ | |
23612 | * */ | |
23613 | SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) { | |
23614 | plugin_data *p = p_d; | |
23615 | - | |
23616 | + | |
23617 | handler_ctx *hctx = con->plugin_ctx[p->id]; | |
23618 | fcgi_proc *proc; | |
23619 | fcgi_extension_host *host; | |
23620 | - | |
23621 | + | |
23622 | if (NULL == hctx) return HANDLER_GO_ON; | |
23623 | - | |
23624 | + | |
23625 | /* not my job */ | |
23626 | if (con->mode != p->id) return HANDLER_GO_ON; | |
23627 | ||
23628 | /* we don't have a host yet, choose one | |
23629 | - * -> this happens in the first round | |
23630 | + * -> this happens in the first round | |
23631 | * and when the host died and we have to select a new one */ | |
23632 | if (hctx->host == NULL) { | |
23633 | size_t k; | |
23634 | @@ -3016,23 +2930,23 @@ | |
23635 | /* get best server */ | |
23636 | for (k = 0, ndx = -1; k < hctx->ext->used; k++) { | |
23637 | host = hctx->ext->hosts[k]; | |
23638 | - | |
23639 | + | |
23640 | /* we should have at least one proc that can do something */ | |
23641 | if (host->active_procs == 0) continue; | |
23642 | ||
23643 | if (used == -1 || host->load < used) { | |
23644 | used = host->load; | |
23645 | - | |
23646 | + | |
23647 | ndx = k; | |
23648 | } | |
23649 | } | |
23650 | - | |
23651 | + | |
23652 | /* found a server */ | |
23653 | if (ndx == -1) { | |
23654 | /* all hosts are down */ | |
23655 | ||
23656 | fcgi_connection_close(srv, hctx); | |
23657 | - | |
23658 | + | |
23659 | con->http_status = 500; | |
23660 | con->mode = DIRECT; | |
23661 | ||
23662 | @@ -3040,16 +2954,16 @@ | |
23663 | } | |
23664 | ||
23665 | host = hctx->ext->hosts[ndx]; | |
23666 | - | |
23667 | - /* | |
23668 | - * if check-local is disabled, use the uri.path handler | |
23669 | - * | |
23670 | + | |
23671 | + /* | |
23672 | + * if check-local is disabled, use the uri.path handler | |
23673 | + * | |
23674 | */ | |
23675 | - | |
23676 | + | |
23677 | /* init handler-context */ | |
23678 | hctx->host = host; | |
23679 | ||
23680 | - /* we put a connection on this host, move the other new connections to other hosts | |
23681 | + /* we put a connection on this host, move the other new connections to other hosts | |
23682 | * | |
23683 | * as soon as hctx->host is unassigned, decrease the load again */ | |
23684 | hctx->host->load++; | |
23685 | @@ -3063,7 +2977,7 @@ | |
23686 | case HANDLER_ERROR: | |
23687 | proc = hctx->proc; | |
23688 | host = hctx->host; | |
23689 | - | |
23690 | + | |
23691 | if (hctx->state == FCGI_STATE_INIT || | |
23692 | hctx->state == FCGI_STATE_CONNECT_DELAYED) { | |
23693 | if (proc) host->active_procs--; | |
23694 | @@ -3078,7 +2992,7 @@ | |
23695 | return HANDLER_WAIT_FOR_FD; | |
23696 | } else { | |
23697 | fcgi_connection_close(srv, hctx); | |
23698 | - | |
23699 | + | |
23700 | buffer_reset(con->physical.path); | |
23701 | con->mode = DIRECT; | |
23702 | con->http_status = 500; | |
23703 | @@ -3088,12 +3002,12 @@ | |
23704 | } | |
23705 | } else { | |
23706 | fcgi_connection_close(srv, hctx); | |
23707 | - | |
23708 | + | |
23709 | buffer_reset(con->physical.path); | |
23710 | con->mode = DIRECT; | |
23711 | con->http_status = 503; | |
23712 | joblist_append(srv, con); /* really ? */ | |
23713 | - | |
23714 | + | |
23715 | return HANDLER_FINISHED; | |
23716 | } | |
23717 | case HANDLER_WAIT_FOR_EVENT: | |
23718 | @@ -3115,7 +3029,7 @@ | |
23719 | handler_ctx *hctx = ctx; | |
23720 | connection *con = hctx->remote_conn; | |
23721 | plugin_data *p = hctx->plugin_data; | |
23722 | - | |
23723 | + | |
23724 | fcgi_proc *proc = hctx->proc; | |
23725 | fcgi_extension_host *host= hctx->host; | |
23726 | ||
23727 | @@ -3125,8 +3039,8 @@ | |
23728 | case 0: | |
23729 | break; | |
23730 | case 1: | |
23731 | - | |
23732 | - if (host->mode == FCGI_AUTHORIZER && | |
23733 | + | |
23734 | + if (host->mode == FCGI_AUTHORIZER && | |
23735 | (con->http_status == 200 || | |
23736 | con->http_status == 0)) { | |
23737 | /* | |
23738 | @@ -3136,26 +3050,26 @@ | |
23739 | */ | |
23740 | ||
23741 | buffer_copy_string_buffer(con->physical.doc_root, host->docroot); | |
23742 | - | |
23743 | + | |
23744 | buffer_copy_string_buffer(con->physical.path, host->docroot); | |
23745 | buffer_append_string_buffer(con->physical.path, con->uri.path); | |
23746 | fcgi_connection_close(srv, hctx); | |
23747 | - | |
23748 | + | |
23749 | con->mode = DIRECT; | |
23750 | con->file_started = 1; /* fcgi_extension won't touch the request afterwards */ | |
23751 | } else { | |
23752 | /* we are done */ | |
23753 | fcgi_connection_close(srv, hctx); | |
23754 | } | |
23755 | - | |
23756 | + | |
23757 | joblist_append(srv, con); | |
23758 | return HANDLER_FINISHED; | |
23759 | case -1: | |
23760 | if (proc->pid && proc->state != PROC_STATE_DIED) { | |
23761 | int status; | |
23762 | - | |
23763 | + | |
23764 | /* only fetch the zombie if it is not already done */ | |
23765 | - | |
23766 | +#ifndef _WIN32 | |
23767 | switch(waitpid(proc->pid, &status, WNOHANG)) { | |
23768 | case 0: | |
23769 | /* child is still alive */ | |
23770 | @@ -3165,60 +3079,61 @@ | |
23771 | default: | |
23772 | /* the child should not terminate at all */ | |
23773 | if (WIFEXITED(status)) { | |
23774 | - log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
23775 | + log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
23776 | "child exited, pid:", proc->pid, | |
23777 | "status:", WEXITSTATUS(status)); | |
23778 | } else if (WIFSIGNALED(status)) { | |
23779 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23780 | - "child signaled:", | |
23781 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23782 | + "child signaled:", | |
23783 | WTERMSIG(status)); | |
23784 | } else { | |
23785 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23786 | - "child died somehow:", | |
23787 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23788 | + "child died somehow:", | |
23789 | status); | |
23790 | } | |
23791 | - | |
23792 | + | |
23793 | if (p->conf.debug) { | |
23794 | log_error_write(srv, __FILE__, __LINE__, "ssbsdsd", | |
23795 | "--- fastcgi spawning", | |
23796 | "\n\tsocket", proc->connection_name, | |
23797 | "\n\tcurrent:", 1, "/", host->min_procs); | |
23798 | } | |
23799 | - | |
23800 | + | |
23801 | if (fcgi_spawn_connection(srv, p, host, proc)) { | |
23802 | /* respawning failed, retry later */ | |
23803 | proc->state = PROC_STATE_DIED; | |
23804 | ||
23805 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
23806 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
23807 | "respawning failed, will retry later"); | |
23808 | } | |
23809 | - | |
23810 | + | |
23811 | break; | |
23812 | } | |
23813 | +#endif | |
23814 | } | |
23815 | ||
23816 | if (con->file_started == 0) { | |
23817 | /* nothing has been send out yet, try to use another child */ | |
23818 | - | |
23819 | + | |
23820 | if (hctx->wb->bytes_out == 0 && | |
23821 | hctx->reconnects < 5) { | |
23822 | fcgi_reconnect(srv, hctx); | |
23823 | - | |
23824 | - log_error_write(srv, __FILE__, __LINE__, "ssbsbs", | |
23825 | + | |
23826 | + log_error_write(srv, __FILE__, __LINE__, "ssbsbs", | |
23827 | "response not received, request not sent", | |
23828 | - "on socket:", proc->connection_name, | |
23829 | + "on socket:", proc->connection_name, | |
23830 | "for", con->uri.path, ", reconnecting"); | |
23831 | - | |
23832 | + | |
23833 | return HANDLER_WAIT_FOR_FD; | |
23834 | } | |
23835 | - | |
23836 | - log_error_write(srv, __FILE__, __LINE__, "sosbsbs", | |
23837 | + | |
23838 | + log_error_write(srv, __FILE__, __LINE__, "sosbsbs", | |
23839 | "response not received, request sent:", hctx->wb->bytes_out, | |
23840 | - "on socket:", proc->connection_name, | |
23841 | + "on socket:", proc->connection_name, | |
23842 | "for", con->uri.path, ", closing connection"); | |
23843 | - | |
23844 | + | |
23845 | fcgi_connection_close(srv, hctx); | |
23846 | - | |
23847 | + | |
23848 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
23849 | buffer_reset(con->physical.path); | |
23850 | con->http_status = 500; | |
23851 | @@ -3226,76 +3141,76 @@ | |
23852 | } else { | |
23853 | /* response might have been already started, kill the connection */ | |
23854 | fcgi_connection_close(srv, hctx); | |
23855 | - | |
23856 | - log_error_write(srv, __FILE__, __LINE__, "ssbsbs", | |
23857 | + | |
23858 | + log_error_write(srv, __FILE__, __LINE__, "ssbsbs", | |
23859 | "response already sent out, but backend returned error", | |
23860 | - "on socket:", proc->connection_name, | |
23861 | + "on socket:", proc->connection_name, | |
23862 | "for", con->uri.path, ", terminating connection"); | |
23863 | - | |
23864 | + | |
23865 | connection_set_state(srv, con, CON_STATE_ERROR); | |
23866 | } | |
23867 | ||
23868 | /* */ | |
23869 | - | |
23870 | - | |
23871 | + | |
23872 | + | |
23873 | joblist_append(srv, con); | |
23874 | return HANDLER_FINISHED; | |
23875 | } | |
23876 | } | |
23877 | - | |
23878 | + | |
23879 | if (revents & FDEVENT_OUT) { | |
23880 | if (hctx->state == FCGI_STATE_CONNECT_DELAYED || | |
23881 | hctx->state == FCGI_STATE_WRITE) { | |
23882 | /* we are allowed to send something out | |
23883 | - * | |
23884 | + * | |
23885 | * 1. in a unfinished connect() call | |
23886 | * 2. in a unfinished write() call (long POST request) | |
23887 | */ | |
23888 | return mod_fastcgi_handle_subrequest(srv, con, p); | |
23889 | } else { | |
23890 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
23891 | - "got a FDEVENT_OUT and didn't know why:", | |
23892 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
23893 | + "got a FDEVENT_OUT and didn't know why:", | |
23894 | hctx->state); | |
23895 | } | |
23896 | } | |
23897 | - | |
23898 | + | |
23899 | /* perhaps this issue is already handled */ | |
23900 | if (revents & FDEVENT_HUP) { | |
23901 | if (hctx->state == FCGI_STATE_CONNECT_DELAYED) { | |
23902 | /* getoptsock will catch this one (right ?) | |
23903 | - * | |
23904 | - * if we are in connect we might get a EINPROGRESS | |
23905 | - * in the first call and a FDEVENT_HUP in the | |
23906 | + * | |
23907 | + * if we are in connect we might get a EINPROGRESS | |
23908 | + * in the first call and a FDEVENT_HUP in the | |
23909 | * second round | |
23910 | - * | |
23911 | + * | |
23912 | * FIXME: as it is a bit ugly. | |
23913 | - * | |
23914 | + * | |
23915 | */ | |
23916 | return mod_fastcgi_handle_subrequest(srv, con, p); | |
23917 | } else if (hctx->state == FCGI_STATE_READ && | |
23918 | hctx->proc->port == 0) { | |
23919 | /* FIXME: | |
23920 | - * | |
23921 | + * | |
23922 | * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket | |
23923 | * even if the FCGI_FIN packet is not received yet | |
23924 | */ | |
23925 | } else { | |
23926 | - log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", | |
23927 | - "error: unexpected close of fastcgi connection for", | |
23928 | + log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", | |
23929 | + "error: unexpected close of fastcgi connection for", | |
23930 | con->uri.path, | |
23931 | - "(no fastcgi process on host:", | |
23932 | + "(no fastcgi process on host:", | |
23933 | host->host, | |
23934 | - ", port: ", | |
23935 | + ", port: ", | |
23936 | host->port, | |
23937 | " ?)", | |
23938 | hctx->state); | |
23939 | - | |
23940 | + | |
23941 | connection_set_state(srv, con, CON_STATE_ERROR); | |
23942 | fcgi_connection_close(srv, hctx); | |
23943 | joblist_append(srv, con); | |
23944 | } | |
23945 | } else if (revents & FDEVENT_ERR) { | |
23946 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
23947 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
23948 | "fcgi: got a FDEVENT_ERR. Don't know why."); | |
23949 | /* kill all connections to the fastcgi process */ | |
23950 | ||
23951 | @@ -3304,45 +3219,42 @@ | |
23952 | fcgi_connection_close(srv, hctx); | |
23953 | joblist_append(srv, con); | |
23954 | } | |
23955 | - | |
23956 | + | |
23957 | return HANDLER_FINISHED; | |
23958 | } | |
23959 | -#define PATCH(x) \ | |
23960 | - p->conf.x = s->x; | |
23961 | + | |
23962 | static int fcgi_patch_connection(server *srv, connection *con, plugin_data *p) { | |
23963 | size_t i, j; | |
23964 | plugin_config *s = p->config_storage[0]; | |
23965 | - | |
23966 | - PATCH(exts); | |
23967 | - PATCH(debug); | |
23968 | - PATCH(ext_mapping); | |
23969 | - | |
23970 | + | |
23971 | + PATCH_OPTION(exts); | |
23972 | + PATCH_OPTION(debug); | |
23973 | + PATCH_OPTION(ext_mapping); | |
23974 | + | |
23975 | /* skip the first, the global context */ | |
23976 | for (i = 1; i < srv->config_context->used; i++) { | |
23977 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
23978 | s = p->config_storage[i]; | |
23979 | - | |
23980 | + | |
23981 | /* condition didn't match */ | |
23982 | if (!config_check_cond(srv, con, dc)) continue; | |
23983 | - | |
23984 | + | |
23985 | /* merge config */ | |
23986 | for (j = 0; j < dc->value->used; j++) { | |
23987 | data_unset *du = dc->value->data[j]; | |
23988 | - | |
23989 | + | |
23990 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.server"))) { | |
23991 | - PATCH(exts); | |
23992 | + PATCH_OPTION(exts); | |
23993 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.debug"))) { | |
23994 | - PATCH(debug); | |
23995 | + PATCH_OPTION(debug); | |
23996 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.map-extensions"))) { | |
23997 | - PATCH(ext_mapping); | |
23998 | + PATCH_OPTION(ext_mapping); | |
23999 | } | |
24000 | } | |
24001 | } | |
24002 | - | |
24003 | + | |
24004 | return 0; | |
24005 | } | |
24006 | -#undef PATCH | |
24007 | - | |
24008 | ||
24009 | static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) { | |
24010 | plugin_data *p = p_d; | |
24011 | @@ -3351,16 +3263,16 @@ | |
24012 | buffer *fn; | |
24013 | fcgi_extension *extension = NULL; | |
24014 | fcgi_extension_host *host = NULL; | |
24015 | - | |
24016 | + | |
24017 | /* Possibly, we processed already this request */ | |
24018 | if (con->file_started == 1) return HANDLER_GO_ON; | |
24019 | ||
24020 | fn = uri_path_handler ? con->uri.path : con->physical.path; | |
24021 | ||
24022 | if (buffer_is_empty(fn)) return HANDLER_GO_ON; | |
24023 | - | |
24024 | + | |
24025 | s_len = fn->used - 1; | |
24026 | - | |
24027 | + | |
24028 | fcgi_patch_connection(srv, con, p); | |
24029 | ||
24030 | /* fastcgi.map-extensions maps extensions to existing fastcgi.server entries | |
24031 | @@ -3368,24 +3280,24 @@ | |
24032 | * fastcgi.map-extensions = ( ".php3" => ".php" ) | |
24033 | * | |
24034 | * fastcgi.server = ( ".php" => ... ) | |
24035 | - * | |
24036 | + * | |
24037 | * */ | |
24038 | ||
24039 | /* check if extension-mapping matches */ | |
24040 | for (k = 0; k < p->conf.ext_mapping->used; k++) { | |
24041 | data_string *ds = (data_string *)p->conf.ext_mapping->data[k]; | |
24042 | size_t ct_len; /* length of the config entry */ | |
24043 | - | |
24044 | + | |
24045 | if (ds->key->used == 0) continue; | |
24046 | - | |
24047 | + | |
24048 | ct_len = ds->key->used - 1; | |
24049 | - | |
24050 | + | |
24051 | if (s_len < ct_len) continue; | |
24052 | - | |
24053 | + | |
24054 | /* found a mapping */ | |
24055 | if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) { | |
24056 | /* check if we know the extension */ | |
24057 | - | |
24058 | + | |
24059 | /* we can reuse k here */ | |
24060 | for (k = 0; k < p->conf.exts->used; k++) { | |
24061 | extension = p->conf.exts->exts[k]; | |
24062 | @@ -3407,15 +3319,15 @@ | |
24063 | /* check if extension matches */ | |
24064 | for (k = 0; k < p->conf.exts->used; k++) { | |
24065 | size_t ct_len; /* length of the config entry */ | |
24066 | - | |
24067 | + | |
24068 | extension = p->conf.exts->exts[k]; | |
24069 | - | |
24070 | + | |
24071 | if (extension->key->used == 0) continue; | |
24072 | - | |
24073 | + | |
24074 | ct_len = extension->key->used - 1; | |
24075 | - | |
24076 | + | |
24077 | if (s_len < ct_len) continue; | |
24078 | - | |
24079 | + | |
24080 | /* check extension in the form "/fcgi_pattern" */ | |
24081 | if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) { | |
24082 | break; | |
24083 | @@ -3441,10 +3353,10 @@ | |
24084 | continue; | |
24085 | } | |
24086 | ||
24087 | - /* we found one host that is alive */ | |
24088 | + /* we found one host that is alive */ | |
24089 | break; | |
24090 | } | |
24091 | - | |
24092 | + | |
24093 | if (!host) { | |
24094 | /* sorry, we don't have a server alive for this ext */ | |
24095 | buffer_reset(con->physical.path); | |
24096 | @@ -3459,72 +3371,72 @@ | |
24097 | "on", extension->key, | |
24098 | "are down."); | |
24099 | } | |
24100 | - | |
24101 | + | |
24102 | return HANDLER_FINISHED; | |
24103 | } | |
24104 | ||
24105 | /* a note about no handler is not sent yey */ | |
24106 | extension->note_is_sent = 0; | |
24107 | ||
24108 | - /* | |
24109 | - * if check-local is disabled, use the uri.path handler | |
24110 | - * | |
24111 | + /* | |
24112 | + * if check-local is disabled, use the uri.path handler | |
24113 | + * | |
24114 | */ | |
24115 | - | |
24116 | + | |
24117 | /* init handler-context */ | |
24118 | if (uri_path_handler) { | |
24119 | if (host->check_local == 0) { | |
24120 | handler_ctx *hctx; | |
24121 | char *pathinfo; | |
24122 | - | |
24123 | + | |
24124 | hctx = handler_ctx_init(); | |
24125 | - | |
24126 | + | |
24127 | hctx->remote_conn = con; | |
24128 | hctx->plugin_data = p; | |
24129 | hctx->proc = NULL; | |
24130 | hctx->ext = extension; | |
24131 | - | |
24132 | + | |
24133 | ||
24134 | hctx->conf.exts = p->conf.exts; | |
24135 | hctx->conf.debug = p->conf.debug; | |
24136 | - | |
24137 | + | |
24138 | con->plugin_ctx[p->id] = hctx; | |
24139 | - | |
24140 | + | |
24141 | con->mode = p->id; | |
24142 | - | |
24143 | + | |
24144 | if (con->conf.log_request_handling) { | |
24145 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
24146 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
24147 | "handling it in mod_fastcgi"); | |
24148 | } | |
24149 | - | |
24150 | - /* the prefix is the SCRIPT_NAME, | |
24151 | + | |
24152 | + /* the prefix is the SCRIPT_NAME, | |
24153 | * everthing from start to the next slash | |
24154 | * this is important for check-local = "disable" | |
24155 | - * | |
24156 | + * | |
24157 | * if prefix = /admin.fcgi | |
24158 | - * | |
24159 | + * | |
24160 | * /admin.fcgi/foo/bar | |
24161 | - * | |
24162 | + * | |
24163 | * SCRIPT_NAME = /admin.fcgi | |
24164 | * PATH_INFO = /foo/bar | |
24165 | - * | |
24166 | + * | |
24167 | * if prefix = /fcgi-bin/ | |
24168 | - * | |
24169 | + * | |
24170 | * /fcgi-bin/foo/bar | |
24171 | - * | |
24172 | + * | |
24173 | * SCRIPT_NAME = /fcgi-bin/foo | |
24174 | * PATH_INFO = /bar | |
24175 | - * | |
24176 | + * | |
24177 | */ | |
24178 | - | |
24179 | + | |
24180 | /* the rewrite is only done for /prefix/? matches */ | |
24181 | if (extension->key->ptr[0] == '/' && | |
24182 | con->uri.path->used > extension->key->used && | |
24183 | NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) { | |
24184 | - /* rewrite uri.path and pathinfo */ | |
24185 | - | |
24186 | + /* rewrite uri.path and pathinfo */ | |
24187 | + | |
24188 | buffer_copy_string(con->request.pathinfo, pathinfo); | |
24189 | - | |
24190 | + | |
24191 | con->uri.path->used -= con->request.pathinfo->used - 1; | |
24192 | con->uri.path->ptr[con->uri.path->used - 1] = '\0'; | |
24193 | } | |
24194 | @@ -3532,19 +3444,19 @@ | |
24195 | } else { | |
24196 | handler_ctx *hctx; | |
24197 | hctx = handler_ctx_init(); | |
24198 | - | |
24199 | + | |
24200 | hctx->remote_conn = con; | |
24201 | hctx->plugin_data = p; | |
24202 | hctx->proc = NULL; | |
24203 | hctx->ext = extension; | |
24204 | - | |
24205 | + | |
24206 | hctx->conf.exts = p->conf.exts; | |
24207 | hctx->conf.debug = p->conf.debug; | |
24208 | - | |
24209 | + | |
24210 | con->plugin_ctx[p->id] = hctx; | |
24211 | - | |
24212 | + | |
24213 | con->mode = p->id; | |
24214 | - | |
24215 | + | |
24216 | if (con->conf.log_request_handling) { | |
24217 | log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi"); | |
24218 | } | |
24219 | @@ -3566,19 +3478,19 @@ | |
24220 | JOBLIST_FUNC(mod_fastcgi_handle_joblist) { | |
24221 | plugin_data *p = p_d; | |
24222 | handler_ctx *hctx = con->plugin_ctx[p->id]; | |
24223 | - | |
24224 | + | |
24225 | if (hctx == NULL) return HANDLER_GO_ON; | |
24226 | ||
24227 | if (hctx->fd != -1) { | |
24228 | switch (hctx->state) { | |
24229 | case FCGI_STATE_READ: | |
24230 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN); | |
24231 | - | |
24232 | + | |
24233 | break; | |
24234 | case FCGI_STATE_CONNECT_DELAYED: | |
24235 | case FCGI_STATE_WRITE: | |
24236 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
24237 | - | |
24238 | + | |
24239 | break; | |
24240 | case FCGI_STATE_INIT: | |
24241 | /* at reconnect */ | |
24242 | @@ -3595,7 +3507,7 @@ | |
24243 | ||
24244 | static handler_t fcgi_connection_close_callback(server *srv, connection *con, void *p_d) { | |
24245 | plugin_data *p = p_d; | |
24246 | - | |
24247 | + | |
24248 | fcgi_connection_close(srv, con->plugin_ctx[p->id]); | |
24249 | ||
24250 | return HANDLER_GO_ON; | |
24251 | @@ -3604,16 +3516,39 @@ | |
24252 | TRIGGER_FUNC(mod_fastcgi_handle_trigger) { | |
24253 | plugin_data *p = p_d; | |
24254 | size_t i, j, n; | |
24255 | - | |
24256 | - | |
24257 | + | |
24258 | + | |
24259 | /* perhaps we should kill a connect attempt after 10-15 seconds | |
24260 | - * | |
24261 | + * | |
24262 | * currently we wait for the TCP timeout which is on Linux 180 seconds | |
24263 | - * | |
24264 | - * | |
24265 | - * | |
24266 | + * | |
24267 | */ | |
24268 | ||
24269 | + for (i = 0; i < srv->conns->used; i++) { | |
24270 | + connection *con = srv->conns->ptr[i]; | |
24271 | + handler_ctx *hctx = con->plugin_ctx[p->id]; | |
24272 | + | |
24273 | + /* if a connection is ours and is in handle-req for more than max-request-time | |
24274 | + * kill the connection */ | |
24275 | + | |
24276 | + if (con->mode != p->id) continue; | |
24277 | + if (con->state != CON_STATE_HANDLE_REQUEST) continue; | |
24278 | + if (srv->cur_ts < con->request_start + 60) continue; | |
24279 | + | |
24280 | + /* the request is waiting for a FCGI_STDOUT since 60 seconds */ | |
24281 | + | |
24282 | + /* kill the connection */ | |
24283 | + | |
24284 | + log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi backend didn't responded after 60 seconds"); | |
24285 | + | |
24286 | + fcgi_connection_close(srv, hctx); | |
24287 | + | |
24288 | + con->mode = DIRECT; | |
24289 | + con->http_status = 500; | |
24290 | + | |
24291 | + joblist_append(srv, con); | |
24292 | + } | |
24293 | + | |
24294 | /* check all childs if they are still up */ | |
24295 | ||
24296 | for (i = 0; i < srv->config_context->used; i++) { | |
24297 | @@ -3628,45 +3563,45 @@ | |
24298 | fcgi_extension *ex; | |
24299 | ||
24300 | ex = exts->exts[j]; | |
24301 | - | |
24302 | + | |
24303 | for (n = 0; n < ex->used; n++) { | |
24304 | - | |
24305 | + | |
24306 | fcgi_proc *proc; | |
24307 | unsigned long sum_load = 0; | |
24308 | fcgi_extension_host *host; | |
24309 | - | |
24310 | + | |
24311 | host = ex->hosts[n]; | |
24312 | - | |
24313 | + | |
24314 | fcgi_restart_dead_procs(srv, p, host); | |
24315 | - | |
24316 | + | |
24317 | for (proc = host->first; proc; proc = proc->next) { | |
24318 | sum_load += proc->load; | |
24319 | } | |
24320 | - | |
24321 | + | |
24322 | if (host->num_procs && | |
24323 | host->num_procs < host->max_procs && | |
24324 | (sum_load / host->num_procs) > host->max_load_per_proc) { | |
24325 | /* overload, spawn new child */ | |
24326 | if (p->conf.debug) { | |
24327 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
24328 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
24329 | "overload detected, spawning a new child"); | |
24330 | } | |
24331 | - | |
24332 | + | |
24333 | for (proc = host->unused_procs; proc && proc->pid != 0; proc = proc->next); | |
24334 | - | |
24335 | + | |
24336 | if (proc) { | |
24337 | if (proc == host->unused_procs) host->unused_procs = proc->next; | |
24338 | - | |
24339 | + | |
24340 | if (proc->next) proc->next->prev = NULL; | |
24341 | - | |
24342 | + | |
24343 | host->max_id++; | |
24344 | } else { | |
24345 | proc = fastcgi_process_init(); | |
24346 | proc->id = host->max_id++; | |
24347 | } | |
24348 | - | |
24349 | + | |
24350 | host->num_procs++; | |
24351 | - | |
24352 | + | |
24353 | if (buffer_is_empty(host->unixsocket)) { | |
24354 | proc->port = host->port + proc->id; | |
24355 | } else { | |
24356 | @@ -3674,13 +3609,13 @@ | |
24357 | buffer_append_string(proc->unixsocket, "-"); | |
24358 | buffer_append_long(proc->unixsocket, proc->id); | |
24359 | } | |
24360 | - | |
24361 | + | |
24362 | if (fcgi_spawn_connection(srv, p, host, proc)) { | |
24363 | log_error_write(srv, __FILE__, __LINE__, "s", | |
24364 | "ERROR: spawning fcgi failed."); | |
24365 | return HANDLER_ERROR; | |
24366 | } | |
24367 | - | |
24368 | + | |
24369 | proc->prev = NULL; | |
24370 | proc->next = host->first; | |
24371 | if (host->first) { | |
24372 | @@ -3688,56 +3623,56 @@ | |
24373 | } | |
24374 | host->first = proc; | |
24375 | } | |
24376 | - | |
24377 | + | |
24378 | for (proc = host->first; proc; proc = proc->next) { | |
24379 | if (proc->load != 0) break; | |
24380 | if (host->num_procs <= host->min_procs) break; | |
24381 | if (proc->pid == 0) continue; | |
24382 | - | |
24383 | + | |
24384 | if (srv->cur_ts - proc->last_used > host->idle_timeout) { | |
24385 | /* a proc is idling for a long time now, | |
24386 | * terminated it */ | |
24387 | - | |
24388 | + | |
24389 | if (p->conf.debug) { | |
24390 | - log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
24391 | - "idle-timeout reached, terminating child:", | |
24392 | - "socket:", proc->connection_name, | |
24393 | + log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
24394 | + "idle-timeout reached, terminating child:", | |
24395 | + "socket:", proc->connection_name, | |
24396 | "pid", proc->pid); | |
24397 | } | |
24398 | - | |
24399 | - | |
24400 | + | |
24401 | + | |
24402 | if (proc->next) proc->next->prev = proc->prev; | |
24403 | if (proc->prev) proc->prev->next = proc->next; | |
24404 | - | |
24405 | + | |
24406 | if (proc->prev == NULL) host->first = proc->next; | |
24407 | - | |
24408 | + | |
24409 | proc->prev = NULL; | |
24410 | proc->next = host->unused_procs; | |
24411 | - | |
24412 | + | |
24413 | if (host->unused_procs) host->unused_procs->prev = proc; | |
24414 | host->unused_procs = proc; | |
24415 | - | |
24416 | + | |
24417 | kill(proc->pid, SIGTERM); | |
24418 | - | |
24419 | + | |
24420 | proc->state = PROC_STATE_KILLED; | |
24421 | - | |
24422 | - log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
24423 | - "killed:", | |
24424 | - "socket:", proc->connection_name, | |
24425 | + | |
24426 | + log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
24427 | + "killed:", | |
24428 | + "socket:", proc->connection_name, | |
24429 | "pid", proc->pid); | |
24430 | - | |
24431 | + | |
24432 | host->num_procs--; | |
24433 | - | |
24434 | + | |
24435 | /* proc is now in unused, let the next second handle the next process */ | |
24436 | break; | |
24437 | - } | |
24438 | + } | |
24439 | } | |
24440 | - | |
24441 | + | |
24442 | for (proc = host->unused_procs; proc; proc = proc->next) { | |
24443 | int status; | |
24444 | - | |
24445 | + | |
24446 | if (proc->pid == 0) continue; | |
24447 | - | |
24448 | +#ifndef _WIN32 | |
24449 | switch (waitpid(proc->pid, &status, WNOHANG)) { | |
24450 | case 0: | |
24451 | /* child still running after timeout, good */ | |
24452 | @@ -3745,10 +3680,10 @@ | |
24453 | case -1: | |
24454 | if (errno != EINTR) { | |
24455 | /* no PID found ? should never happen */ | |
24456 | - log_error_write(srv, __FILE__, __LINE__, "sddss", | |
24457 | + log_error_write(srv, __FILE__, __LINE__, "sddss", | |
24458 | "pid ", proc->pid, proc->state, | |
24459 | "not found:", strerror(errno)); | |
24460 | - | |
24461 | + | |
24462 | #if 0 | |
24463 | if (errno == ECHILD) { | |
24464 | /* someone else has cleaned up for us */ | |
24465 | @@ -3762,25 +3697,26 @@ | |
24466 | /* the child should not terminate at all */ | |
24467 | if (WIFEXITED(status)) { | |
24468 | if (proc->state != PROC_STATE_KILLED) { | |
24469 | - log_error_write(srv, __FILE__, __LINE__, "sdb", | |
24470 | - "child exited:", | |
24471 | + log_error_write(srv, __FILE__, __LINE__, "sdb", | |
24472 | + "child exited:", | |
24473 | WEXITSTATUS(status), proc->connection_name); | |
24474 | } | |
24475 | } else if (WIFSIGNALED(status)) { | |
24476 | if (WTERMSIG(status) != SIGTERM) { | |
24477 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
24478 | - "child signaled:", | |
24479 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
24480 | + "child signaled:", | |
24481 | WTERMSIG(status)); | |
24482 | } | |
24483 | } else { | |
24484 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
24485 | - "child died somehow:", | |
24486 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
24487 | + "child died somehow:", | |
24488 | status); | |
24489 | } | |
24490 | proc->pid = 0; | |
24491 | proc->state = PROC_STATE_UNSET; | |
24492 | host->max_id--; | |
24493 | } | |
24494 | +#endif | |
24495 | } | |
24496 | } | |
24497 | } | |
24498 | @@ -3804,8 +3740,8 @@ | |
24499 | p->handle_subrequest = mod_fastcgi_handle_subrequest; | |
24500 | p->handle_joblist = mod_fastcgi_handle_joblist; | |
24501 | p->handle_trigger = mod_fastcgi_handle_trigger; | |
24502 | - | |
24503 | + | |
24504 | p->data = NULL; | |
24505 | - | |
24506 | + | |
24507 | return 0; | |
24508 | } | |
1175ccec | 24509 | --- ../lighttpd-1.4.11/src/mod_flv_streaming.c 2006-03-07 14:06:26.000000000 +0200 |
36e2a29e | 24510 | +++ lighttpd-1.4.12/src/mod_flv_streaming.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
24511 | @@ -23,35 +23,35 @@ |
24512 | ||
24513 | typedef struct { | |
24514 | PLUGIN_DATA; | |
24515 | - | |
24516 | + | |
24517 | buffer *query_str; | |
24518 | array *get_params; | |
24519 | - | |
24520 | + | |
24521 | plugin_config **config_storage; | |
24522 | - | |
24523 | - plugin_config conf; | |
24524 | + | |
24525 | + plugin_config conf; | |
24526 | } plugin_data; | |
24527 | ||
24528 | /* init the plugin data */ | |
24529 | INIT_FUNC(mod_flv_streaming_init) { | |
24530 | plugin_data *p; | |
24531 | - | |
24532 | + | |
24533 | p = calloc(1, sizeof(*p)); | |
24534 | - | |
24535 | + | |
24536 | p->query_str = buffer_init(); | |
24537 | p->get_params = array_init(); | |
24538 | - | |
24539 | + | |
24540 | return p; | |
24541 | } | |
24542 | ||
24543 | /* detroy the plugin data */ | |
24544 | FREE_FUNC(mod_flv_streaming_free) { | |
24545 | plugin_data *p = p_d; | |
24546 | - | |
24547 | + | |
24548 | UNUSED(srv); | |
24549 | ||
24550 | if (!p) return HANDLER_GO_ON; | |
24551 | - | |
24552 | + | |
24553 | if (p->config_storage) { | |
24554 | size_t i; | |
24555 | ||
24556 | @@ -59,19 +59,19 @@ | |
24557 | plugin_config *s = p->config_storage[i]; | |
24558 | ||
24559 | if (!s) continue; | |
24560 | - | |
24561 | + | |
24562 | array_free(s->extensions); | |
24563 | - | |
24564 | + | |
24565 | free(s); | |
24566 | } | |
24567 | free(p->config_storage); | |
24568 | } | |
24569 | - | |
24570 | + | |
24571 | buffer_free(p->query_str); | |
24572 | array_free(p->get_params); | |
24573 | - | |
24574 | + | |
24575 | free(p); | |
24576 | - | |
24577 | + | |
24578 | return HANDLER_GO_ON; | |
24579 | } | |
24580 | ||
24581 | @@ -80,83 +80,80 @@ | |
24582 | SETDEFAULTS_FUNC(mod_flv_streaming_set_defaults) { | |
24583 | plugin_data *p = p_d; | |
24584 | size_t i = 0; | |
24585 | - | |
24586 | - config_values_t cv[] = { | |
24587 | + | |
24588 | + config_values_t cv[] = { | |
24589 | { "flv-streaming.extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
24590 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
24591 | }; | |
24592 | - | |
24593 | + | |
24594 | if (!p) return HANDLER_ERROR; | |
24595 | - | |
24596 | + | |
24597 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
24598 | - | |
24599 | + | |
24600 | for (i = 0; i < srv->config_context->used; i++) { | |
24601 | plugin_config *s; | |
24602 | - | |
24603 | + | |
24604 | s = calloc(1, sizeof(plugin_config)); | |
24605 | s->extensions = array_init(); | |
24606 | - | |
24607 | + | |
24608 | cv[0].destination = s->extensions; | |
24609 | - | |
24610 | + | |
24611 | p->config_storage[i] = s; | |
24612 | - | |
24613 | + | |
24614 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
24615 | return HANDLER_ERROR; | |
24616 | } | |
24617 | } | |
24618 | - | |
24619 | + | |
24620 | return HANDLER_GO_ON; | |
24621 | } | |
24622 | ||
24623 | -#define PATCH(x) \ | |
24624 | - p->conf.x = s->x; | |
24625 | static int mod_flv_streaming_patch_connection(server *srv, connection *con, plugin_data *p) { | |
24626 | size_t i, j; | |
24627 | plugin_config *s = p->config_storage[0]; | |
24628 | - | |
24629 | - PATCH(extensions); | |
24630 | - | |
24631 | + | |
24632 | + PATCH_OPTION(extensions); | |
24633 | + | |
24634 | /* skip the first, the global context */ | |
24635 | for (i = 1; i < srv->config_context->used; i++) { | |
24636 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
24637 | s = p->config_storage[i]; | |
24638 | - | |
24639 | + | |
24640 | /* condition didn't match */ | |
24641 | if (!config_check_cond(srv, con, dc)) continue; | |
24642 | - | |
24643 | + | |
24644 | /* merge config */ | |
24645 | for (j = 0; j < dc->value->used; j++) { | |
24646 | data_unset *du = dc->value->data[j]; | |
24647 | - | |
24648 | + | |
24649 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("flv-streaming.extensions"))) { | |
24650 | - PATCH(extensions); | |
24651 | + PATCH_OPTION(extensions); | |
24652 | } | |
24653 | } | |
24654 | } | |
24655 | - | |
24656 | + | |
24657 | return 0; | |
24658 | } | |
24659 | -#undef PATCH | |
24660 | ||
24661 | -static int split_get_params(server *srv, connection *con, array *get_params, buffer *qrystr) { | |
24662 | +static int split_get_params(array *get_params, buffer *qrystr) { | |
24663 | size_t is_key = 1; | |
24664 | size_t i; | |
24665 | char *key = NULL, *val = NULL; | |
24666 | - | |
24667 | + | |
24668 | key = qrystr->ptr; | |
24669 | - | |
24670 | + | |
24671 | /* we need the \0 */ | |
24672 | for (i = 0; i < qrystr->used; i++) { | |
24673 | switch(qrystr->ptr[i]) { | |
24674 | case '=': | |
24675 | if (is_key) { | |
24676 | val = qrystr->ptr + i + 1; | |
24677 | - | |
24678 | + | |
24679 | qrystr->ptr[i] = '\0'; | |
24680 | - | |
24681 | + | |
24682 | is_key = 0; | |
24683 | } | |
24684 | - | |
24685 | + | |
24686 | break; | |
24687 | case '&': | |
24688 | case '\0': /* fin symbol */ | |
24689 | @@ -167,7 +164,7 @@ | |
24690 | /* terminate the value */ | |
24691 | qrystr->ptr[i] = '\0'; | |
24692 | ||
24693 | - if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { | |
24694 | + if (NULL == (ds = (data_string *)array_get_unused_element(get_params, TYPE_STRING))) { | |
24695 | ds = data_string_init(); | |
24696 | } | |
24697 | buffer_copy_string_len(ds->key, key, strlen(key)); | |
24698 | @@ -175,14 +172,14 @@ | |
24699 | ||
24700 | array_insert_unique(get_params, (data_unset *)ds); | |
24701 | } | |
24702 | - | |
24703 | + | |
24704 | key = qrystr->ptr + i + 1; | |
24705 | val = NULL; | |
24706 | is_key = 1; | |
24707 | break; | |
24708 | } | |
24709 | } | |
24710 | - | |
24711 | + | |
24712 | return 0; | |
24713 | } | |
24714 | ||
24715 | @@ -190,34 +187,34 @@ | |
24716 | plugin_data *p = p_d; | |
24717 | int s_len; | |
24718 | size_t k; | |
24719 | - | |
24720 | + | |
24721 | UNUSED(srv); | |
24722 | ||
24723 | if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; | |
24724 | - | |
24725 | + | |
24726 | mod_flv_streaming_patch_connection(srv, con, p); | |
24727 | ||
24728 | s_len = con->physical.path->used - 1; | |
24729 | - | |
24730 | + | |
24731 | for (k = 0; k < p->conf.extensions->used; k++) { | |
24732 | data_string *ds = (data_string *)p->conf.extensions->data[k]; | |
24733 | int ct_len = ds->value->used - 1; | |
24734 | - | |
24735 | + | |
24736 | if (ct_len > s_len) continue; | |
24737 | if (ds->value->used == 0) continue; | |
24738 | - | |
24739 | + | |
24740 | if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { | |
24741 | data_string *get_param; | |
24742 | stat_cache_entry *sce = NULL; | |
24743 | buffer *b; | |
24744 | int start; | |
24745 | char *err = NULL; | |
24746 | - /* if there is a start=[0-9]+ in the header use it as start, | |
24747 | + /* if there is a start=[0-9]+ in the header use it as start, | |
24748 | * otherwise send the full file */ | |
24749 | ||
24750 | array_reset(p->get_params); | |
24751 | buffer_copy_string_buffer(p->query_str, con->uri.query); | |
24752 | - split_get_params(srv, con, p->get_params, p->query_str); | |
24753 | + split_get_params(p->get_params, p->query_str); | |
24754 | ||
24755 | if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) { | |
24756 | return HANDLER_GO_ON; | |
24757 | @@ -256,7 +253,7 @@ | |
24758 | return HANDLER_FINISHED; | |
24759 | } | |
24760 | } | |
24761 | - | |
24762 | + | |
24763 | /* not found */ | |
24764 | return HANDLER_GO_ON; | |
24765 | } | |
24766 | @@ -266,13 +263,13 @@ | |
24767 | int mod_flv_streaming_plugin_init(plugin *p) { | |
24768 | p->version = LIGHTTPD_VERSION_ID; | |
24769 | p->name = buffer_init_string("flv_streaming"); | |
24770 | - | |
24771 | + | |
24772 | p->init = mod_flv_streaming_init; | |
24773 | p->handle_physical = mod_flv_streaming_path_handler; | |
24774 | p->set_defaults = mod_flv_streaming_set_defaults; | |
24775 | p->cleanup = mod_flv_streaming_free; | |
24776 | - | |
24777 | + | |
24778 | p->data = NULL; | |
24779 | - | |
24780 | + | |
24781 | return 0; | |
24782 | } | |
1175ccec ER |
24783 | --- ../lighttpd-1.4.11/src/mod_indexfile.c 2005-09-30 01:08:53.000000000 +0300 |
24784 | +++ lighttpd-1.4.12/src/mod_indexfile.c 2006-07-15 22:43:21.000000000 +0300 | |
24785 | @@ -12,6 +12,8 @@ | |
24786 | ||
24787 | #include "stat_cache.h" | |
24788 | ||
24789 | +#include "sys-strings.h" | |
24790 | +#include "sys-files.h" | |
24791 | /* plugin config for all request/connections */ | |
24792 | ||
24793 | typedef struct { | |
24794 | @@ -20,51 +22,51 @@ | |
2519e6e5 ER |
24795 | |
24796 | typedef struct { | |
24797 | PLUGIN_DATA; | |
24798 | - | |
24799 | + | |
24800 | buffer *tmp_buf; | |
24801 | - | |
24802 | + | |
24803 | plugin_config **config_storage; | |
24804 | - | |
24805 | - plugin_config conf; | |
24806 | + | |
24807 | + plugin_config conf; | |
24808 | } plugin_data; | |
24809 | ||
24810 | /* init the plugin data */ | |
24811 | INIT_FUNC(mod_indexfile_init) { | |
24812 | plugin_data *p; | |
24813 | - | |
24814 | + | |
24815 | p = calloc(1, sizeof(*p)); | |
24816 | - | |
24817 | + | |
24818 | p->tmp_buf = buffer_init(); | |
24819 | - | |
24820 | + | |
24821 | return p; | |
24822 | } | |
24823 | ||
24824 | /* detroy the plugin data */ | |
24825 | FREE_FUNC(mod_indexfile_free) { | |
24826 | plugin_data *p = p_d; | |
24827 | - | |
24828 | + | |
24829 | UNUSED(srv); | |
24830 | ||
24831 | if (!p) return HANDLER_GO_ON; | |
24832 | - | |
24833 | + | |
24834 | if (p->config_storage) { | |
24835 | size_t i; | |
24836 | for (i = 0; i < srv->config_context->used; i++) { | |
24837 | plugin_config *s = p->config_storage[i]; | |
24838 | ||
24839 | if (!s) continue; | |
24840 | - | |
24841 | + | |
24842 | array_free(s->indexfiles); | |
24843 | - | |
24844 | + | |
24845 | free(s); | |
24846 | } | |
24847 | free(p->config_storage); | |
24848 | } | |
24849 | - | |
24850 | + | |
24851 | buffer_free(p->tmp_buf); | |
24852 | - | |
24853 | + | |
24854 | free(p); | |
24855 | - | |
24856 | + | |
24857 | return HANDLER_GO_ON; | |
24858 | } | |
24859 | ||
1175ccec | 24860 | @@ -73,131 +75,139 @@ |
2519e6e5 ER |
24861 | SETDEFAULTS_FUNC(mod_indexfile_set_defaults) { |
24862 | plugin_data *p = p_d; | |
24863 | size_t i = 0; | |
24864 | - | |
24865 | - config_values_t cv[] = { | |
24866 | + | |
24867 | + config_values_t cv[] = { | |
24868 | { "index-file.names", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
24869 | { "server.indexfiles", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
24870 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
24871 | }; | |
24872 | - | |
24873 | + | |
24874 | if (!p) return HANDLER_ERROR; | |
24875 | - | |
24876 | + | |
24877 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
24878 | - | |
24879 | + | |
24880 | for (i = 0; i < srv->config_context->used; i++) { | |
24881 | plugin_config *s; | |
24882 | - | |
24883 | + | |
24884 | s = calloc(1, sizeof(plugin_config)); | |
24885 | s->indexfiles = array_init(); | |
24886 | - | |
24887 | + | |
24888 | cv[0].destination = s->indexfiles; | |
24889 | cv[1].destination = s->indexfiles; /* old name for [0] */ | |
24890 | - | |
24891 | + | |
24892 | p->config_storage[i] = s; | |
24893 | - | |
24894 | + | |
24895 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
24896 | return HANDLER_ERROR; | |
24897 | } | |
24898 | } | |
24899 | - | |
24900 | + | |
24901 | return HANDLER_GO_ON; | |
24902 | } | |
24903 | ||
24904 | -#define PATCH(x) \ | |
24905 | - p->conf.x = s->x; | |
24906 | static int mod_indexfile_patch_connection(server *srv, connection *con, plugin_data *p) { | |
24907 | size_t i, j; | |
24908 | plugin_config *s = p->config_storage[0]; | |
24909 | - | |
24910 | - PATCH(indexfiles); | |
24911 | - | |
24912 | + | |
24913 | + PATCH_OPTION(indexfiles); | |
24914 | + | |
24915 | /* skip the first, the global context */ | |
24916 | for (i = 1; i < srv->config_context->used; i++) { | |
24917 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
24918 | s = p->config_storage[i]; | |
24919 | - | |
24920 | + | |
24921 | /* condition didn't match */ | |
24922 | if (!config_check_cond(srv, con, dc)) continue; | |
24923 | - | |
24924 | + | |
24925 | /* merge config */ | |
24926 | for (j = 0; j < dc->value->used; j++) { | |
24927 | data_unset *du = dc->value->data[j]; | |
24928 | - | |
24929 | + | |
24930 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.indexfiles"))) { | |
24931 | - PATCH(indexfiles); | |
24932 | + PATCH_OPTION(indexfiles); | |
24933 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("index-file.names"))) { | |
24934 | - PATCH(indexfiles); | |
24935 | + PATCH_OPTION(indexfiles); | |
24936 | } | |
24937 | } | |
24938 | } | |
24939 | - | |
24940 | + | |
24941 | return 0; | |
24942 | } | |
24943 | -#undef PATCH | |
24944 | ||
24945 | URIHANDLER_FUNC(mod_indexfile_subrequest) { | |
24946 | plugin_data *p = p_d; | |
24947 | size_t k; | |
24948 | stat_cache_entry *sce = NULL; | |
24949 | - | |
24950 | + | |
24951 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
24952 | if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON; | |
24953 | - | |
24954 | + | |
24955 | mod_indexfile_patch_connection(srv, con, p); | |
24956 | - | |
1175ccec ER |
24957 | + |
24958 | + /* is the physical-path really a dir ? */ | |
24959 | + if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) { | |
24960 | + return HANDLER_GO_ON; | |
24961 | + } | |
24962 | + | |
24963 | + if (!S_ISDIR(sce->st.st_mode)) { | |
24964 | + return HANDLER_GO_ON; | |
24965 | + } | |
2519e6e5 ER |
24966 | + |
24967 | if (con->conf.log_request_handling) { | |
24968 | log_error_write(srv, __FILE__, __LINE__, "s", "-- handling the request as Indexfile"); | |
24969 | log_error_write(srv, __FILE__, __LINE__, "sb", "URI :", con->uri.path); | |
24970 | } | |
24971 | - | |
1175ccec | 24972 | + |
2519e6e5 ER |
24973 | + |
24974 | /* indexfile */ | |
24975 | for (k = 0; k < p->conf.indexfiles->used; k++) { | |
24976 | data_string *ds = (data_string *)p->conf.indexfiles->data[k]; | |
24977 | - | |
24978 | + | |
24979 | if (ds->value && ds->value->ptr[0] == '/') { | |
24980 | - /* if the index-file starts with a prefix as use this file as | |
24981 | + /* if the index-file starts with a prefix as use this file as | |
24982 | * index-generator */ | |
24983 | buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root); | |
24984 | } else { | |
24985 | buffer_copy_string_buffer(p->tmp_buf, con->physical.path); | |
1175ccec | 24986 | + PATHNAME_APPEND_SLASH(p->tmp_buf); |
2519e6e5 ER |
24987 | } |
24988 | buffer_append_string_buffer(p->tmp_buf, ds->value); | |
24989 | - | |
24990 | + | |
24991 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) { | |
24992 | if (errno == EACCES) { | |
24993 | con->http_status = 403; | |
24994 | buffer_reset(con->physical.path); | |
24995 | - | |
24996 | + | |
24997 | return HANDLER_FINISHED; | |
24998 | } | |
24999 | - | |
25000 | + | |
25001 | if (errno != ENOENT && | |
25002 | errno != ENOTDIR) { | |
25003 | /* we have no idea what happend. let's tell the user so. */ | |
25004 | - | |
25005 | + | |
25006 | con->http_status = 500; | |
25007 | - | |
25008 | + | |
25009 | log_error_write(srv, __FILE__, __LINE__, "ssbsb", | |
25010 | "file not found ... or so: ", strerror(errno), | |
25011 | con->uri.path, | |
25012 | "->", con->physical.path); | |
25013 | - | |
25014 | + | |
25015 | buffer_reset(con->physical.path); | |
25016 | - | |
25017 | + | |
25018 | return HANDLER_FINISHED; | |
25019 | } | |
25020 | continue; | |
25021 | } | |
25022 | - | |
25023 | + | |
25024 | /* rewrite uri.path to the real path (/ -> /index.php) */ | |
25025 | buffer_append_string_buffer(con->uri.path, ds->value); | |
25026 | buffer_copy_string_buffer(con->physical.path, p->tmp_buf); | |
25027 | - | |
25028 | + | |
25029 | /* fce is already set up a few lines above */ | |
25030 | - | |
25031 | + | |
25032 | return HANDLER_GO_ON; | |
25033 | } | |
25034 | - | |
25035 | + | |
25036 | /* not found */ | |
25037 | return HANDLER_GO_ON; | |
25038 | } | |
1175ccec | 25039 | @@ -207,13 +217,13 @@ |
2519e6e5 ER |
25040 | int mod_indexfile_plugin_init(plugin *p) { |
25041 | p->version = LIGHTTPD_VERSION_ID; | |
25042 | p->name = buffer_init_string("indexfile"); | |
25043 | - | |
25044 | + | |
25045 | p->init = mod_indexfile_init; | |
25046 | p->handle_subrequest_start = mod_indexfile_subrequest; | |
25047 | p->set_defaults = mod_indexfile_set_defaults; | |
25048 | p->cleanup = mod_indexfile_free; | |
25049 | - | |
25050 | + | |
25051 | p->data = NULL; | |
25052 | - | |
25053 | + | |
25054 | return 0; | |
25055 | } | |
1175ccec | 25056 | --- ../lighttpd-1.4.11/src/mod_mysql_vhost.c 2006-01-14 20:35:10.000000000 +0200 |
36e2a29e | 25057 | +++ lighttpd-1.4.12/src/mod_mysql_vhost.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
25058 | @@ -1,13 +1,18 @@ |
25059 | -#include <unistd.h> | |
25060 | #include <stdio.h> | |
25061 | #include <errno.h> | |
25062 | #include <fcntl.h> | |
25063 | -#include <strings.h> | |
25064 | +#include <string.h> | |
25065 | ||
25066 | #ifdef HAVE_CONFIG_H | |
25067 | #include "config.h" | |
25068 | #endif | |
25069 | ||
25070 | +#ifdef HAVE_MYSQL_H | |
25071 | +# ifdef HAVE_LIBMYSQL | |
25072 | +# define HAVE_MYSQL | |
25073 | +# endif | |
25074 | +#endif | |
25075 | + | |
25076 | #ifdef HAVE_MYSQL | |
25077 | #include <mysql.h> | |
25078 | #endif | |
25079 | @@ -16,61 +21,40 @@ | |
25080 | #include "log.h" | |
25081 | ||
25082 | #include "stat_cache.h" | |
25083 | -#ifdef DEBUG_MOD_MYSQL_VHOST | |
25084 | -#define DEBUG | |
25085 | -#endif | |
25086 | +#include "sys-files.h" | |
25087 | ||
25088 | -/* | |
25089 | - * Plugin for lighttpd to use MySQL | |
25090 | - * for domain to directory lookups, | |
25091 | - * i.e virtual hosts (vhosts). | |
25092 | - * | |
25093 | - * Optionally sets fcgi_offset and fcgi_arg | |
25094 | - * in preparation for fcgi.c to handle | |
25095 | - * per-user fcgi chroot jails. | |
25096 | - * | |
25097 | - * /ada@riksnet.se 2004-12-06 | |
25098 | - */ | |
25099 | +#include "mod_sql_vhost_core.h" | |
25100 | ||
25101 | #ifdef HAVE_MYSQL | |
25102 | + | |
25103 | +#define CORE_PLUGIN "mod_sql_vhost_core" | |
25104 | + | |
25105 | typedef struct { | |
25106 | MYSQL *mysql; | |
25107 | - | |
25108 | - buffer *mydb; | |
25109 | - buffer *myuser; | |
25110 | - buffer *mypass; | |
25111 | - buffer *mysock; | |
25112 | - | |
25113 | - buffer *hostname; | |
25114 | - unsigned short port; | |
25115 | - | |
25116 | + | |
25117 | buffer *mysql_pre; | |
25118 | buffer *mysql_post; | |
25119 | + | |
25120 | + mod_sql_vhost_core_plugin_config *core; | |
25121 | } plugin_config; | |
25122 | ||
25123 | /* global plugin data */ | |
25124 | typedef struct { | |
25125 | PLUGIN_DATA; | |
25126 | - | |
25127 | + | |
25128 | buffer *tmp_buf; | |
25129 | - | |
25130 | + | |
25131 | plugin_config **config_storage; | |
25132 | - | |
25133 | - plugin_config conf; | |
25134 | + | |
25135 | + plugin_config conf; | |
25136 | } plugin_data; | |
25137 | ||
25138 | -/* per connection plugin data */ | |
25139 | -typedef struct { | |
25140 | - buffer *server_name; | |
25141 | - buffer *document_root; | |
25142 | - buffer *fcgi_arg; | |
25143 | - unsigned fcgi_offset; | |
25144 | -} plugin_connection_data; | |
25145 | +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost); | |
25146 | ||
25147 | /* init the plugin data */ | |
25148 | INIT_FUNC(mod_mysql_vhost_init) { | |
25149 | plugin_data *p; | |
25150 | - | |
25151 | + | |
25152 | p = calloc(1, sizeof(*p)); | |
25153 | ||
25154 | p->tmp_buf = buffer_init(); | |
25155 | @@ -83,144 +67,77 @@ | |
25156 | plugin_data *p = p_d; | |
25157 | ||
25158 | UNUSED(srv); | |
25159 | - | |
25160 | -#ifdef DEBUG | |
25161 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
25162 | - "mod_mysql_vhost_cleanup", p ? "yes" : "NO"); | |
25163 | -#endif | |
25164 | + | |
25165 | if (!p) return HANDLER_GO_ON; | |
25166 | - | |
25167 | + | |
25168 | if (p->config_storage) { | |
25169 | size_t i; | |
25170 | for (i = 0; i < srv->config_context->used; i++) { | |
25171 | plugin_config *s = p->config_storage[i]; | |
25172 | ||
25173 | if (!s) continue; | |
25174 | - | |
25175 | + | |
25176 | mysql_close(s->mysql); | |
25177 | - | |
25178 | - buffer_free(s->mydb); | |
25179 | - buffer_free(s->myuser); | |
25180 | - buffer_free(s->mypass); | |
25181 | - buffer_free(s->mysock); | |
25182 | + | |
25183 | buffer_free(s->mysql_pre); | |
25184 | buffer_free(s->mysql_post); | |
25185 | - | |
25186 | + | |
25187 | free(s); | |
25188 | } | |
25189 | free(p->config_storage); | |
25190 | } | |
25191 | buffer_free(p->tmp_buf); | |
25192 | - | |
25193 | - free(p); | |
25194 | ||
25195 | - return HANDLER_GO_ON; | |
25196 | -} | |
25197 | - | |
25198 | -/* handle the plugin per connection data */ | |
25199 | -static void* mod_mysql_vhost_connection_data(server *srv, connection *con, void *p_d) | |
25200 | -{ | |
25201 | - plugin_data *p = p_d; | |
25202 | - plugin_connection_data *c = con->plugin_ctx[p->id]; | |
25203 | - | |
25204 | - UNUSED(srv); | |
25205 | - | |
25206 | -#ifdef DEBUG | |
25207 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
25208 | - "mod_mysql_connection_data", c ? "old" : "NEW"); | |
25209 | -#endif | |
25210 | - | |
25211 | - if (c) return c; | |
25212 | - c = calloc(1, sizeof(*c)); | |
25213 | - | |
25214 | - c->server_name = buffer_init(); | |
25215 | - c->document_root = buffer_init(); | |
25216 | - c->fcgi_arg = buffer_init(); | |
25217 | - c->fcgi_offset = 0; | |
25218 | - | |
25219 | - return con->plugin_ctx[p->id] = c; | |
25220 | -} | |
25221 | - | |
25222 | -/* destroy the plugin per connection data */ | |
25223 | -CONNECTION_FUNC(mod_mysql_vhost_handle_connection_close) { | |
25224 | - plugin_data *p = p_d; | |
25225 | - plugin_connection_data *c = con->plugin_ctx[p->id]; | |
25226 | - | |
25227 | - UNUSED(srv); | |
25228 | - | |
25229 | -#ifdef DEBUG | |
25230 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
25231 | - "mod_mysql_vhost_handle_connection_close", c ? "yes" : "NO"); | |
25232 | -#endif | |
25233 | - | |
25234 | - if (!c) return HANDLER_GO_ON; | |
25235 | - | |
25236 | - buffer_free(c->server_name); | |
25237 | - buffer_free(c->document_root); | |
25238 | - buffer_free(c->fcgi_arg); | |
25239 | - c->fcgi_offset = 0; | |
25240 | - | |
25241 | - free(c); | |
25242 | + free(p); | |
25243 | ||
25244 | - con->plugin_ctx[p->id] = NULL; | |
25245 | return HANDLER_GO_ON; | |
25246 | } | |
25247 | ||
25248 | /* set configuration values */ | |
25249 | SERVER_FUNC(mod_mysql_vhost_set_defaults) { | |
25250 | plugin_data *p = p_d; | |
25251 | + mod_sql_vhost_core_plugin_data *core_config; | |
25252 | ||
25253 | - char *qmark; | |
25254 | size_t i = 0; | |
25255 | ||
25256 | - config_values_t cv[] = { | |
25257 | - { "mysql-vhost.db", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, | |
25258 | - { "mysql-vhost.user", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, | |
25259 | - { "mysql-vhost.pass", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, | |
25260 | - { "mysql-vhost.sock", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, | |
25261 | - { "mysql-vhost.sql", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, | |
25262 | - { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER }, | |
25263 | - { "mysql-vhost.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, | |
25264 | - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
25265 | - }; | |
25266 | - | |
25267 | + /* our very own plugin storage, one entry for each conditional | |
25268 | + * | |
25269 | + * srv->config_context->used is the number of conditionals | |
25270 | + * */ | |
25271 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
25272 | - | |
25273 | + | |
25274 | + /* get the config of the core-plugin */ | |
25275 | + core_config = plugin_get_config(srv, CORE_PLUGIN); | |
25276 | + | |
25277 | + | |
25278 | + /* walk through all conditionals and check for assignments */ | |
25279 | for (i = 0; i < srv->config_context->used; i++) { | |
25280 | plugin_config *s; | |
25281 | buffer *sel; | |
25282 | - | |
25283 | - | |
25284 | + char *qmark; | |
25285 | + | |
25286 | + /* get the config from the core plugin for this conditional-context */ | |
25287 | s = calloc(1, sizeof(plugin_config)); | |
25288 | - s->mydb = buffer_init(); | |
25289 | - s->myuser = buffer_init(); | |
25290 | - s->mypass = buffer_init(); | |
25291 | - s->mysock = buffer_init(); | |
25292 | - s->hostname = buffer_init(); | |
25293 | - s->port = 0; /* default port for mysql */ | |
25294 | - sel = buffer_init(); | |
25295 | - s->mysql = NULL; | |
25296 | + | |
25297 | + s->core = core_config->config_storage[i]; | |
25298 | ||
25299 | + s->mysql = NULL; | |
25300 | + | |
25301 | s->mysql_pre = buffer_init(); | |
25302 | s->mysql_post = buffer_init(); | |
25303 | - | |
25304 | - cv[0].destination = s->mydb; | |
25305 | - cv[1].destination = s->myuser; | |
25306 | - cv[2].destination = s->mypass; | |
25307 | - cv[3].destination = s->mysock; | |
25308 | - cv[4].destination = sel; | |
25309 | - cv[5].destination = s->hostname; | |
25310 | - cv[6].destination = &(s->port); | |
25311 | - | |
25312 | + | |
25313 | p->config_storage[i] = s; | |
25314 | - | |
25315 | - if (config_insert_values_global(srv, | |
25316 | - ((data_config *)srv->config_context->data[i])->value, | |
25317 | - cv)) return HANDLER_ERROR; | |
25318 | - | |
25319 | - s->mysql_pre = buffer_init(); | |
25320 | - s->mysql_post = buffer_init(); | |
25321 | - | |
25322 | + | |
25323 | + /* check if we are the plugin for this backend */ | |
25324 | + if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("mysql"))) continue; | |
25325 | + | |
25326 | + /* attach us to the core-plugin */ | |
25327 | + s->core->backend_data = p; | |
25328 | + s->core->get_vhost = mod_mysql_vhost_get_vhost; | |
25329 | + | |
25330 | + sel = buffer_init(); | |
25331 | + buffer_copy_string_buffer(sel, s->core->select_vhost); | |
25332 | + | |
25333 | if (sel->used && (qmark = index(sel->ptr, '?'))) { | |
25334 | *qmark = '\0'; | |
25335 | buffer_copy_string(s->mysql_pre, sel->ptr); | |
25336 | @@ -228,35 +145,35 @@ | |
25337 | } else { | |
25338 | buffer_copy_string_buffer(s->mysql_pre, sel); | |
25339 | } | |
25340 | - | |
25341 | + | |
25342 | /* required: | |
25343 | * - username | |
25344 | - * - database | |
25345 | - * | |
25346 | + * - database | |
25347 | + * | |
25348 | * optional: | |
25349 | * - password, default: empty | |
25350 | * - socket, default: mysql default | |
25351 | * - hostname, if set overrides socket | |
25352 | * - port, default: 3306 | |
25353 | */ | |
25354 | - | |
25355 | + | |
25356 | /* all have to be set */ | |
25357 | - if (!(buffer_is_empty(s->myuser) || | |
25358 | - buffer_is_empty(s->mydb))) { | |
25359 | + if (!(buffer_is_empty(s->core->user) || | |
25360 | + buffer_is_empty(s->core->db))) { | |
25361 | ||
25362 | int fd; | |
25363 | - | |
25364 | + | |
25365 | if (NULL == (s->mysql = mysql_init(NULL))) { | |
25366 | log_error_write(srv, __FILE__, __LINE__, "s", "mysql_init() failed, exiting..."); | |
25367 | - | |
25368 | + | |
25369 | return HANDLER_ERROR; | |
25370 | } | |
25371 | -#define FOO(x) (s->x->used ? s->x->ptr : NULL) | |
25372 | - | |
25373 | - if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass), | |
25374 | - FOO(mydb), s->port, FOO(mysock), 0)) { | |
25375 | +#define FOO(x) (s->core->x->used ? s->core->x->ptr : NULL) | |
25376 | + | |
25377 | + if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(user), FOO(pass), | |
25378 | + FOO(db), s->core->port, FOO(sock), 0)) { | |
25379 | log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(s->mysql)); | |
25380 | - | |
25381 | + | |
25382 | return HANDLER_ERROR; | |
25383 | } | |
25384 | #undef FOO | |
25385 | @@ -265,61 +182,47 @@ | |
25386 | /* otherwise we cannot be sure that mysql is fd i-1 */ | |
25387 | if (-1 == (fd = open("/dev/null", 0))) { | |
25388 | close(fd); | |
25389 | - fcntl(fd-1, F_SETFD, FD_CLOEXEC); | |
25390 | + fcntl(fd-1, F_SETFD, FD_CLOEXEC); | |
25391 | } | |
25392 | } | |
25393 | } | |
25394 | - | |
25395 | - | |
25396 | + | |
25397 | + | |
25398 | ||
25399 | return HANDLER_GO_ON; | |
25400 | } | |
25401 | ||
25402 | -#define PATCH(x) \ | |
25403 | - p->conf.x = s->x; | |
25404 | static int mod_mysql_vhost_patch_connection(server *srv, connection *con, plugin_data *p) { | |
25405 | - size_t i, j; | |
25406 | + size_t i; | |
25407 | plugin_config *s = p->config_storage[0]; | |
25408 | - | |
25409 | - PATCH(mysql_pre); | |
25410 | - PATCH(mysql_post); | |
25411 | -#ifdef HAVE_MYSQL | |
25412 | - PATCH(mysql); | |
25413 | -#endif | |
25414 | - | |
25415 | + | |
25416 | + PATCH_OPTION(mysql_pre); | |
25417 | + PATCH_OPTION(mysql_post); | |
25418 | + PATCH_OPTION(mysql); | |
25419 | + | |
25420 | /* skip the first, the global context */ | |
25421 | for (i = 1; i < srv->config_context->used; i++) { | |
25422 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
25423 | s = p->config_storage[i]; | |
25424 | - | |
25425 | + | |
25426 | /* condition didn't match */ | |
25427 | if (!config_check_cond(srv, con, dc)) continue; | |
25428 | - | |
25429 | - /* merge config */ | |
25430 | - for (j = 0; j < dc->value->used; j++) { | |
25431 | - data_unset *du = dc->value->data[j]; | |
25432 | - | |
25433 | - if (buffer_is_equal_string(du->key, CONST_STR_LEN("mysql-vhost.sql"))) { | |
25434 | - PATCH(mysql_pre); | |
25435 | - PATCH(mysql_post); | |
25436 | - } | |
25437 | - } | |
25438 | - | |
25439 | + | |
25440 | if (s->mysql) { | |
25441 | - PATCH(mysql); | |
25442 | + PATCH_OPTION(mysql); | |
25443 | + PATCH_OPTION(mysql_pre); | |
25444 | + PATCH_OPTION(mysql_post); | |
25445 | } | |
25446 | } | |
25447 | - | |
25448 | + | |
25449 | return 0; | |
25450 | } | |
25451 | -#undef PATCH | |
25452 | ||
25453 | - | |
25454 | -/* handle document root request */ | |
25455 | -CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) { | |
25456 | +/** | |
25457 | + * get the vhost info from the database | |
25458 | + */ | |
25459 | +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost) { | |
25460 | plugin_data *p = p_d; | |
25461 | - plugin_connection_data *c; | |
25462 | - stat_cache_entry *sce; | |
25463 | ||
25464 | unsigned cols; | |
25465 | MYSQL_ROW row; | |
25466 | @@ -332,13 +235,6 @@ | |
25467 | ||
25468 | if (!p->conf.mysql) return HANDLER_GO_ON; | |
25469 | ||
25470 | - /* sets up connection data if not done yet */ | |
25471 | - c = mod_mysql_vhost_connection_data(srv, con, p_d); | |
25472 | - | |
25473 | - /* check if cached this connection */ | |
25474 | - if (c->server_name->used && /* con->uri.authority->used && */ | |
25475 | - buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON; | |
25476 | - | |
25477 | /* build and run SQL query */ | |
25478 | buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre); | |
25479 | if (p->conf.mysql_post->used) { | |
25480 | @@ -347,77 +243,43 @@ | |
25481 | } | |
25482 | if (mysql_query(p->conf.mysql, p->tmp_buf->ptr)) { | |
25483 | log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(p->conf.mysql)); | |
25484 | - goto ERR500; | |
25485 | + | |
25486 | + mysql_free_result(result); | |
25487 | + return HANDLER_GO_ON; | |
25488 | } | |
25489 | result = mysql_store_result(p->conf.mysql); | |
25490 | cols = mysql_num_fields(result); | |
25491 | row = mysql_fetch_row(result); | |
25492 | + | |
25493 | if (!row || cols < 1) { | |
25494 | /* no such virtual host */ | |
25495 | mysql_free_result(result); | |
25496 | return HANDLER_GO_ON; | |
25497 | } | |
25498 | ||
25499 | - /* sanity check that really is a directory */ | |
25500 | - buffer_copy_string(p->tmp_buf, row[0]); | |
25501 | - BUFFER_APPEND_SLASH(p->tmp_buf); | |
25502 | - | |
25503 | - if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) { | |
25504 | - log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf); | |
25505 | - goto ERR500; | |
25506 | - } | |
25507 | - if (!S_ISDIR(sce->st.st_mode)) { | |
25508 | - log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->tmp_buf); | |
25509 | - goto ERR500; | |
25510 | - } | |
25511 | + buffer_copy_string(docroot, row[0]); | |
25512 | ||
25513 | - /* cache the data */ | |
25514 | - buffer_copy_string_buffer(c->server_name, con->uri.authority); | |
25515 | - buffer_copy_string_buffer(c->document_root, p->tmp_buf); | |
25516 | - | |
25517 | - /* fcgi_offset and fcgi_arg are optional */ | |
25518 | - if (cols > 1 && row[1]) { | |
25519 | - c->fcgi_offset = atoi(row[1]); | |
25520 | - | |
25521 | - if (cols > 2 && row[2]) { | |
25522 | - buffer_copy_string(c->fcgi_arg, row[2]); | |
25523 | - } else { | |
25524 | - c->fcgi_arg->used = 0; | |
25525 | - } | |
25526 | - } else { | |
25527 | - c->fcgi_offset = c->fcgi_arg->used = 0; | |
25528 | - } | |
25529 | mysql_free_result(result); | |
25530 | ||
25531 | - /* fix virtual server and docroot */ | |
25532 | -GO_ON: buffer_copy_string_buffer(con->server_name, c->server_name); | |
25533 | - buffer_copy_string_buffer(con->physical.doc_root, c->document_root); | |
25534 | - | |
25535 | -#ifdef DEBUG | |
25536 | - log_error_write(srv, __FILE__, __LINE__, "sbbdb", | |
25537 | - result ? "NOT CACHED" : "cached", | |
25538 | - con->server_name, con->physical.doc_root, | |
25539 | - c->fcgi_offset, c->fcgi_arg); | |
25540 | -#endif | |
25541 | - return HANDLER_GO_ON; | |
25542 | - | |
25543 | -ERR500: if (result) mysql_free_result(result); | |
25544 | - con->http_status = 500; /* Internal Error */ | |
25545 | - return HANDLER_FINISHED; | |
25546 | + return HANDLER_GO_ON; | |
25547 | } | |
25548 | ||
25549 | /* this function is called at dlopen() time and inits the callbacks */ | |
25550 | int mod_mysql_vhost_plugin_init(plugin *p) { | |
25551 | + data_string *ds; | |
25552 | + | |
25553 | p->version = LIGHTTPD_VERSION_ID; | |
25554 | p->name = buffer_init_string("mysql_vhost"); | |
25555 | ||
25556 | p->init = mod_mysql_vhost_init; | |
25557 | p->cleanup = mod_mysql_vhost_cleanup; | |
25558 | - p->handle_request_done = mod_mysql_vhost_handle_connection_close; | |
25559 | ||
25560 | p->set_defaults = mod_mysql_vhost_set_defaults; | |
25561 | - p->handle_docroot = mod_mysql_vhost_handle_docroot; | |
25562 | ||
25563 | + ds = data_string_init(); | |
25564 | + buffer_copy_string(ds->value, CORE_PLUGIN); | |
25565 | + array_insert_unique(p->required_plugins, (data_unset *)ds); | |
25566 | + | |
25567 | return 0; | |
25568 | } | |
25569 | #else | |
1175ccec ER |
25570 | --- ../lighttpd-1.4.11/src/mod_proxy.c 2006-01-31 13:01:22.000000000 +0200 |
25571 | +++ lighttpd-1.4.12/src/mod_proxy.c 2006-07-15 22:43:21.000000000 +0300 | |
2519e6e5 ER |
25572 | @@ -1,6 +1,5 @@ |
25573 | #include <sys/types.h> | |
25574 | ||
25575 | -#include <unistd.h> | |
25576 | #include <errno.h> | |
25577 | #include <fcntl.h> | |
25578 | #include <string.h> | |
25579 | @@ -23,6 +22,9 @@ | |
25580 | ||
25581 | #include "inet_ntop_cache.h" | |
25582 | #include "crc32.h" | |
25583 | +#include "network.h" | |
25584 | + | |
25585 | +#include "http_resp.h" | |
25586 | ||
25587 | #include <stdio.h> | |
25588 | ||
25589 | @@ -31,6 +33,8 @@ | |
25590 | #endif | |
25591 | ||
25592 | #include "sys-socket.h" | |
25593 | +#include "sys-files.h" | |
25594 | +#include "sys-strings.h" | |
25595 | ||
25596 | #define data_proxy data_fastcgi | |
25597 | #define data_proxy_init data_fastcgi_init | |
1175ccec | 25598 | @@ -38,22 +42,25 @@ |
2519e6e5 ER |
25599 | #define PROXY_RETRY_TIMEOUT 60 |
25600 | ||
25601 | /** | |
25602 | - * | |
25603 | - * the proxy module is based on the fastcgi module | |
25604 | - * | |
25605 | + * | |
25606 | + * the proxy module is based on the fastcgi module | |
25607 | + * | |
25608 | * 28.06.2004 Jan Kneschke The first release | |
25609 | * 01.07.2004 Evgeny Rodichev Several bugfixes and cleanups | |
25610 | * - co-ordinate up- and downstream flows correctly (proxy_demux_response | |
25611 | * and proxy_handle_fdevent) | |
25612 | * - correctly transfer upstream http_response_status; | |
25613 | * - some unused structures removed. | |
25614 | - * | |
25615 | + * | |
25616 | * TODO: - delay upstream read if write_queue is too large | |
25617 | * (to prevent memory eating, like in apache). Shoud be | |
25618 | * configurable). | |
1175ccec ER |
25619 | * - persistent connection with upstream servers |
25620 | * - HTTP/1.1 | |
25621 | */ | |
25622 | + | |
25623 | + | |
25624 | + | |
25625 | typedef enum { | |
25626 | PROXY_BALANCE_UNSET, | |
25627 | PROXY_BALANCE_FAIR, | |
25628 | @@ -66,26 +73,33 @@ | |
2519e6e5 ER |
25629 | int debug; |
25630 | ||
25631 | proxy_balance_t balance; | |
25632 | + | |
25633 | + array *last_used_backends; /* "extension" : last_used_backend */ | |
25634 | } plugin_config; | |
25635 | ||
25636 | typedef struct { | |
25637 | PLUGIN_DATA; | |
25638 | - | |
25639 | + | |
25640 | buffer *parse_response; | |
25641 | buffer *balance_buf; | |
25642 | - | |
25643 | + | |
1175ccec ER |
25644 | + http_resp *resp; |
25645 | + | |
2519e6e5 ER |
25646 | + array *ignore_headers; |
25647 | + | |
25648 | plugin_config **config_storage; | |
25649 | - | |
25650 | + | |
25651 | plugin_config conf; | |
25652 | } plugin_data; | |
25653 | ||
25654 | -typedef enum { | |
25655 | - PROXY_STATE_INIT, | |
25656 | - PROXY_STATE_CONNECT, | |
25657 | - PROXY_STATE_PREPARE_WRITE, | |
25658 | - PROXY_STATE_WRITE, | |
25659 | - PROXY_STATE_READ, | |
25660 | - PROXY_STATE_ERROR | |
25661 | +typedef enum { | |
25662 | + PROXY_STATE_INIT, | |
25663 | + PROXY_STATE_CONNECT, | |
25664 | + PROXY_STATE_PREPARE_WRITE, | |
25665 | + PROXY_STATE_WRITE, | |
1175ccec ER |
25666 | + PROXY_STATE_RESPONSE_HEADER, |
25667 | + PROXY_STATE_RESPONSE_CONTENT, | |
2519e6e5 ER |
25668 | + PROXY_STATE_ERROR |
25669 | } proxy_connection_state_t; | |
25670 | ||
25671 | enum { PROXY_STDOUT, PROXY_END_REQUEST }; | |
1175ccec | 25672 | @@ -93,19 +107,17 @@ |
2519e6e5 ER |
25673 | typedef struct { |
25674 | proxy_connection_state_t state; | |
25675 | time_t state_timestamp; | |
25676 | - | |
25677 | + | |
25678 | data_proxy *host; | |
25679 | - | |
1175ccec ER |
25680 | - buffer *response; |
25681 | - buffer *response_header; | |
2519e6e5 ER |
25682 | |
25683 | chunkqueue *wb; | |
25684 | - | |
1175ccec | 25685 | + chunkqueue *rb; |
2519e6e5 ER |
25686 | + |
25687 | int fd; /* fd to the proxy process */ | |
25688 | int fde_ndx; /* index into the fd-event buffer */ | |
25689 | ||
25690 | size_t path_info_offset; /* start of path_info in uri.path */ | |
25691 | - | |
25692 | + | |
25693 | connection *remote_conn; /* dump pointer */ | |
25694 | plugin_data *plugin_data; /* dump pointer */ | |
25695 | } handler_ctx; | |
1175ccec | 25696 | @@ -116,69 +128,88 @@ |
2519e6e5 ER |
25697 | |
25698 | static handler_ctx * handler_ctx_init() { | |
25699 | handler_ctx * hctx; | |
25700 | - | |
25701 | + | |
25702 | ||
25703 | hctx = calloc(1, sizeof(*hctx)); | |
25704 | - | |
25705 | + | |
25706 | hctx->state = PROXY_STATE_INIT; | |
25707 | hctx->host = NULL; | |
25708 | - | |
1175ccec ER |
25709 | - hctx->response = buffer_init(); |
25710 | - hctx->response_header = buffer_init(); | |
2519e6e5 ER |
25711 | |
25712 | hctx->wb = chunkqueue_init(); | |
1175ccec | 25713 | + hctx->rb = chunkqueue_init(); |
2519e6e5 ER |
25714 | |
25715 | hctx->fd = -1; | |
25716 | hctx->fde_ndx = -1; | |
25717 | - | |
25718 | + | |
25719 | return hctx; | |
25720 | } | |
25721 | ||
1175ccec ER |
25722 | static void handler_ctx_free(handler_ctx *hctx) { |
25723 | - buffer_free(hctx->response); | |
25724 | - buffer_free(hctx->response_header); | |
2519e6e5 ER |
25725 | chunkqueue_free(hctx->wb); |
25726 | - | |
1175ccec | 25727 | + chunkqueue_free(hctx->rb); |
2519e6e5 ER |
25728 | + |
25729 | free(hctx); | |
25730 | } | |
25731 | ||
25732 | INIT_FUNC(mod_proxy_init) { | |
25733 | plugin_data *p; | |
25734 | - | |
25735 | + size_t i; | |
25736 | + | |
25737 | + char *hop2hop_headers[] = { | |
25738 | + "Connection", | |
25739 | + "Keep-Alive", | |
25740 | + "Host", | |
25741 | + NULL | |
25742 | + }; | |
25743 | + | |
25744 | p = calloc(1, sizeof(*p)); | |
25745 | - | |
1175ccec | 25746 | - p->parse_response = buffer_init(); |
2519e6e5 | 25747 | + |
2519e6e5 ER |
25748 | p->balance_buf = buffer_init(); |
25749 | - | |
25750 | + p->ignore_headers = array_init(); | |
1175ccec | 25751 | + p->resp = http_response_init(); |
2519e6e5 ER |
25752 | + |
25753 | + for (i = 0; hop2hop_headers[i]; i++) { | |
25754 | + data_string *ds; | |
25755 | + | |
1175ccec | 25756 | + if (NULL == (ds = (data_string *)array_get_unused_element(p->ignore_headers, TYPE_STRING))) { |
2519e6e5 ER |
25757 | + ds = data_string_init(); |
25758 | + } | |
25759 | + | |
1175ccec | 25760 | + buffer_copy_string(ds->key, hop2hop_headers[i]); |
2519e6e5 ER |
25761 | + buffer_copy_string(ds->value, hop2hop_headers[i]); |
25762 | + array_insert_unique(p->ignore_headers, (data_unset *)ds); | |
25763 | + } | |
25764 | + | |
25765 | return p; | |
25766 | } | |
25767 | ||
25768 | ||
25769 | FREE_FUNC(mod_proxy_free) { | |
25770 | plugin_data *p = p_d; | |
25771 | - | |
25772 | + | |
25773 | UNUSED(srv); | |
25774 | ||
1175ccec ER |
25775 | - buffer_free(p->parse_response); |
25776 | - buffer_free(p->balance_buf); | |
2519e6e5 | 25777 | - |
2519e6e5 ER |
25778 | if (p->config_storage) { |
25779 | size_t i; | |
25780 | for (i = 0; i < srv->config_context->used; i++) { | |
25781 | plugin_config *s = p->config_storage[i]; | |
25782 | - | |
25783 | + | |
25784 | if (s) { | |
25785 | - | |
25786 | array_free(s->extensions); | |
25787 | - | |
25788 | + array_free(s->last_used_backends); | |
25789 | + | |
25790 | free(s); | |
25791 | } | |
25792 | } | |
25793 | free(p->config_storage); | |
25794 | } | |
25795 | - | |
25796 | + | |
1175ccec ER |
25797 | + array_free(p->ignore_headers); |
25798 | + buffer_free(p->balance_buf); | |
25799 | + http_response_free(p->resp); | |
2519e6e5 ER |
25800 | + |
25801 | free(p); | |
25802 | - | |
25803 | + | |
25804 | return HANDLER_GO_ON; | |
25805 | } | |
25806 | ||
1175ccec | 25807 | @@ -186,37 +217,38 @@ |
2519e6e5 ER |
25808 | plugin_data *p = p_d; |
25809 | data_unset *du; | |
25810 | size_t i = 0; | |
25811 | - | |
25812 | - config_values_t cv[] = { | |
25813 | + | |
25814 | + config_values_t cv[] = { | |
25815 | { "proxy.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
25816 | { "proxy.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
25817 | { "proxy.balance", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
25818 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
25819 | }; | |
25820 | - | |
25821 | + | |
25822 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
25823 | - | |
25824 | + | |
25825 | for (i = 0; i < srv->config_context->used; i++) { | |
25826 | plugin_config *s; | |
25827 | array *ca; | |
25828 | - | |
25829 | + | |
25830 | s = malloc(sizeof(plugin_config)); | |
25831 | - s->extensions = array_init(); | |
25832 | + s->extensions = array_init(); | |
25833 | + s->last_used_backends = array_init(); | |
25834 | s->debug = 0; | |
25835 | - | |
25836 | + | |
25837 | cv[0].destination = s->extensions; | |
25838 | cv[1].destination = &(s->debug); | |
25839 | cv[2].destination = p->balance_buf; | |
25840 | ||
25841 | buffer_reset(p->balance_buf); | |
25842 | - | |
25843 | + | |
25844 | p->config_storage[i] = s; | |
25845 | ca = ((data_config *)srv->config_context->data[i])->value; | |
25846 | - | |
25847 | + | |
25848 | if (0 != config_insert_values_global(srv, ca, cv)) { | |
25849 | return HANDLER_ERROR; | |
25850 | } | |
25851 | - | |
25852 | + | |
25853 | if (buffer_is_empty(p->balance_buf)) { | |
25854 | s->balance = PROXY_BALANCE_FAIR; | |
25855 | } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) { | |
1175ccec | 25856 | @@ -226,99 +258,99 @@ |
2519e6e5 ER |
25857 | } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("hash"))) { |
25858 | s->balance = PROXY_BALANCE_HASH; | |
25859 | } else { | |
25860 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
1175ccec | 25861 | - "proxy.balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf); |
2519e6e5 | 25862 | + log_error_write(srv, __FILE__, __LINE__, "sb", |
1175ccec | 25863 | + "proxy.balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf); |
2519e6e5 ER |
25864 | return HANDLER_ERROR; |
25865 | } | |
1175ccec | 25866 | |
2519e6e5 ER |
25867 | if (NULL != (du = array_get_element(ca, "proxy.server"))) { |
25868 | size_t j; | |
25869 | data_array *da = (data_array *)du; | |
25870 | - | |
25871 | + | |
25872 | if (du->type != TYPE_ARRAY) { | |
25873 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
25874 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
25875 | "unexpected type for key: ", "proxy.server", "array of strings"); | |
25876 | - | |
25877 | + | |
25878 | return HANDLER_ERROR; | |
25879 | } | |
25880 | - | |
25881 | - /* | |
25882 | + | |
25883 | + /* | |
25884 | * proxy.server = ( "<ext>" => ..., | |
25885 | * "<ext>" => ... ) | |
25886 | */ | |
25887 | - | |
25888 | + | |
25889 | for (j = 0; j < da->value->used; j++) { | |
25890 | data_array *da_ext = (data_array *)da->value->data[j]; | |
25891 | size_t n; | |
25892 | - | |
25893 | + | |
25894 | if (da_ext->type != TYPE_ARRAY) { | |
25895 | - log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
25896 | - "unexpected type for key: ", "proxy.server", | |
25897 | + log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
25898 | + "unexpected type for key: ", "proxy.server", | |
25899 | "[", da->value->data[j]->key, "](string)"); | |
25900 | - | |
25901 | + | |
25902 | return HANDLER_ERROR; | |
25903 | } | |
25904 | - | |
25905 | - /* | |
25906 | - * proxy.server = ( "<ext>" => | |
25907 | - * ( "<host>" => ( ... ), | |
25908 | + | |
25909 | + /* | |
25910 | + * proxy.server = ( "<ext>" => | |
25911 | + * ( "<host>" => ( ... ), | |
25912 | * "<host>" => ( ... ) | |
25913 | - * ), | |
25914 | + * ), | |
25915 | * "<ext>" => ... ) | |
25916 | */ | |
25917 | - | |
25918 | + | |
25919 | for (n = 0; n < da_ext->value->used; n++) { | |
25920 | data_array *da_host = (data_array *)da_ext->value->data[n]; | |
25921 | - | |
25922 | + | |
25923 | data_proxy *df; | |
25924 | data_array *dfa; | |
25925 | - | |
25926 | - config_values_t pcv[] = { | |
25927 | + | |
25928 | + config_values_t pcv[] = { | |
25929 | { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
25930 | { "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
25931 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
25932 | }; | |
25933 | - | |
25934 | + | |
25935 | if (da_host->type != TYPE_ARRAY) { | |
25936 | - log_error_write(srv, __FILE__, __LINE__, "ssSBS", | |
25937 | - "unexpected type for key:", | |
25938 | - "proxy.server", | |
25939 | + log_error_write(srv, __FILE__, __LINE__, "ssSBS", | |
25940 | + "unexpected type for key:", | |
25941 | + "proxy.server", | |
25942 | "[", da_ext->value->data[n]->key, "](string)"); | |
25943 | - | |
25944 | + | |
25945 | return HANDLER_ERROR; | |
25946 | } | |
25947 | - | |
25948 | + | |
25949 | df = data_proxy_init(); | |
25950 | - | |
25951 | + | |
25952 | df->port = 80; | |
25953 | - | |
25954 | + | |
25955 | buffer_copy_string_buffer(df->key, da_host->key); | |
25956 | - | |
25957 | + | |
25958 | pcv[0].destination = df->host; | |
25959 | pcv[1].destination = &(df->port); | |
25960 | - | |
25961 | + | |
25962 | if (0 != config_insert_values_internal(srv, da_host->value, pcv)) { | |
25963 | return HANDLER_ERROR; | |
25964 | } | |
25965 | - | |
25966 | + | |
25967 | if (buffer_is_empty(df->host)) { | |
25968 | - log_error_write(srv, __FILE__, __LINE__, "sbbbs", | |
25969 | - "missing key (string):", | |
25970 | + log_error_write(srv, __FILE__, __LINE__, "sbbbs", | |
25971 | + "missing key (string):", | |
25972 | da->key, | |
25973 | da_ext->key, | |
25974 | da_host->key, | |
25975 | "host"); | |
25976 | - | |
25977 | + | |
25978 | return HANDLER_ERROR; | |
25979 | } | |
25980 | - | |
25981 | + | |
25982 | /* if extension already exists, take it */ | |
25983 | - | |
25984 | + | |
25985 | if (NULL == (dfa = (data_array *)array_get_element(s->extensions, da_ext->key->ptr))) { | |
25986 | dfa = data_array_init(); | |
25987 | - | |
25988 | + | |
25989 | buffer_copy_string_buffer(dfa->key, da_ext->key); | |
25990 | - | |
25991 | + | |
25992 | array_insert_unique(dfa->value, (data_unset *)df); | |
25993 | array_insert_unique(s->extensions, (data_unset *)dfa); | |
25994 | } else { | |
1175ccec | 25995 | @@ -328,19 +360,19 @@ |
2519e6e5 ER |
25996 | } |
25997 | } | |
25998 | } | |
25999 | - | |
26000 | + | |
26001 | return HANDLER_GO_ON; | |
26002 | } | |
26003 | ||
26004 | void proxy_connection_close(server *srv, handler_ctx *hctx) { | |
26005 | plugin_data *p; | |
26006 | connection *con; | |
26007 | - | |
26008 | + | |
26009 | if (NULL == hctx) return; | |
26010 | - | |
26011 | + | |
26012 | p = hctx->plugin_data; | |
26013 | con = hctx->remote_conn; | |
26014 | - | |
26015 | + | |
26016 | if (hctx->fd != -1) { | |
26017 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
26018 | fdevent_unregister(srv->ev, hctx->fd); | |
1175ccec | 26019 | @@ -348,47 +380,56 @@ |
2519e6e5 ER |
26020 | close(hctx->fd); |
26021 | srv->cur_fds--; | |
26022 | } | |
26023 | - | |
26024 | + | |
26025 | handler_ctx_free(hctx); | |
26026 | - con->plugin_ctx[p->id] = NULL; | |
26027 | + con->plugin_ctx[p->id] = NULL; | |
26028 | } | |
26029 | ||
26030 | static int proxy_establish_connection(server *srv, handler_ctx *hctx) { | |
26031 | struct sockaddr *proxy_addr; | |
26032 | struct sockaddr_in proxy_addr_in; | |
26033 | socklen_t servlen; | |
26034 | - | |
26035 | + | |
26036 | plugin_data *p = hctx->plugin_data; | |
26037 | data_proxy *host= hctx->host; | |
26038 | int proxy_fd = hctx->fd; | |
26039 | - | |
26040 | + | |
26041 | memset(&proxy_addr, 0, sizeof(proxy_addr)); | |
26042 | - | |
26043 | + | |
26044 | proxy_addr_in.sin_family = AF_INET; | |
26045 | proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr); | |
26046 | proxy_addr_in.sin_port = htons(host->port); | |
26047 | servlen = sizeof(proxy_addr_in); | |
26048 | - | |
26049 | + | |
26050 | proxy_addr = (struct sockaddr *) &proxy_addr_in; | |
26051 | - | |
26052 | + | |
26053 | if (-1 == connect(proxy_fd, proxy_addr, servlen)) { | |
26054 | - if (errno == EINPROGRESS || errno == EALREADY) { | |
26055 | +#ifdef _WIN32 | |
1175ccec | 26056 | + errno = WSAGetLastError(); |
2519e6e5 | 26057 | +#endif |
1175ccec | 26058 | + switch(errno) { |
2519e6e5 | 26059 | +#ifdef _WIN32 |
1175ccec | 26060 | + case WSAEWOULDBLOCK: |
2519e6e5 | 26061 | +#endif |
1175ccec ER |
26062 | + case EINPROGRESS: |
26063 | + case EALREADY: | |
2519e6e5 ER |
26064 | if (p->conf.debug) { |
26065 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26066 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
26067 | "connect delayed:", proxy_fd); | |
26068 | } | |
26069 | - | |
26070 | + | |
26071 | return 1; | |
26072 | - } else { | |
26073 | - | |
26074 | - log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
26075 | + default: | |
26076 | + | |
26077 | + log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
26078 | "connect failed:", proxy_fd, strerror(errno), errno); | |
26079 | - | |
26080 | + | |
26081 | return -1; | |
26082 | } | |
26083 | } | |
1175ccec | 26084 | + fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, proxy_fd); |
2519e6e5 ER |
26085 | if (p->conf.debug) { |
26086 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26087 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
26088 | "connect succeeded: ", proxy_fd); | |
26089 | } | |
26090 | ||
1175ccec ER |
26091 | @@ -396,51 +437,52 @@ |
26092 | } | |
26093 | ||
26094 | void proxy_set_header(connection *con, const char *key, const char *value) { | |
26095 | - data_string *ds_dst; | |
26096 | + data_string *ds_dst; | |
26097 | ||
26098 | - if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { | |
26099 | - ds_dst = data_string_init(); | |
26100 | - } | |
26101 | - | |
26102 | - buffer_copy_string(ds_dst->key, key); | |
26103 | - buffer_copy_string(ds_dst->value, value); | |
26104 | - array_insert_unique(con->request.headers, (data_unset *)ds_dst); | |
26105 | + if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { | |
26106 | + ds_dst = data_string_init(); | |
26107 | + } | |
26108 | + | |
26109 | + buffer_copy_string(ds_dst->key, key); | |
26110 | + buffer_copy_string(ds_dst->value, value); | |
26111 | + array_insert_unique(con->request.headers, (data_unset *)ds_dst); | |
26112 | } | |
26113 | ||
26114 | void proxy_append_header(connection *con, const char *key, const char *value) { | |
26115 | - data_string *ds_dst; | |
26116 | + data_string *ds_dst; | |
26117 | ||
26118 | - if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { | |
26119 | - ds_dst = data_string_init(); | |
26120 | - } | |
26121 | - | |
26122 | - buffer_copy_string(ds_dst->key, key); | |
26123 | - buffer_append_string(ds_dst->value, value); | |
26124 | - array_insert_unique(con->request.headers, (data_unset *)ds_dst); | |
26125 | + if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { | |
26126 | + ds_dst = data_string_init(); | |
26127 | + } | |
26128 | + | |
26129 | + buffer_copy_string(ds_dst->key, key); | |
26130 | + buffer_append_string(ds_dst->value, value); | |
26131 | + array_insert_unique(con->request.headers, (data_unset *)ds_dst); | |
26132 | } | |
26133 | ||
2519e6e5 ER |
26134 | |
26135 | static int proxy_create_env(server *srv, handler_ctx *hctx) { | |
26136 | size_t i; | |
26137 | - | |
26138 | + | |
26139 | connection *con = hctx->remote_conn; | |
26140 | + plugin_data *p = hctx->plugin_data; | |
26141 | buffer *b; | |
26142 | - | |
26143 | + | |
26144 | /* build header */ | |
26145 | ||
26146 | b = chunkqueue_get_append_buffer(hctx->wb); | |
26147 | - | |
26148 | + | |
26149 | /* request line */ | |
26150 | buffer_copy_string(b, get_http_method_name(con->request.http_method)); | |
26151 | BUFFER_APPEND_STRING_CONST(b, " "); | |
26152 | - | |
26153 | + | |
26154 | buffer_append_string_buffer(b, con->request.uri); | |
26155 | BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n"); | |
26156 | ||
26157 | proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr))); | |
26158 | - /* http_host is NOT is just a pointer to a buffer | |
26159 | + /* http_host is NOT is just a pointer to a buffer | |
26160 | * which is NULL if it is not set */ | |
26161 | - if (con->request.http_host && | |
26162 | + if (con->request.http_host && | |
26163 | !buffer_is_empty(con->request.http_host)) { | |
26164 | proxy_set_header(con, "X-Host", con->request.http_host->ptr); | |
26165 | } | |
1175ccec | 26166 | @@ -449,24 +491,25 @@ |
2519e6e5 ER |
26167 | /* request header */ |
26168 | for (i = 0; i < con->request.headers->used; i++) { | |
26169 | data_string *ds; | |
26170 | - | |
26171 | + | |
26172 | ds = (data_string *)con->request.headers->data[i]; | |
26173 | - | |
1175ccec | 26174 | - if (ds->value->used && ds->key->used) { |
2519e6e5 ER |
26175 | - if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue; |
26176 | - | |
1175ccec ER |
26177 | - buffer_append_string_buffer(b, ds->key); |
26178 | - BUFFER_APPEND_STRING_CONST(b, ": "); | |
26179 | - buffer_append_string_buffer(b, ds->value); | |
26180 | - BUFFER_APPEND_STRING_CONST(b, "\r\n"); | |
26181 | - } | |
2519e6e5 | 26182 | + |
1175ccec | 26183 | + if (buffer_is_empty(ds->value) || buffer_is_empty(ds->key)) continue; |
2519e6e5 | 26184 | + |
1175ccec ER |
26185 | + if (!buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue; |
26186 | + if (!buffer_is_equal_string(ds->key, CONST_STR_LEN("Keep-Alive"))) continue; | |
26187 | + | |
26188 | + buffer_append_string_buffer(b, ds->key); | |
26189 | + BUFFER_APPEND_STRING_CONST(b, ": "); | |
26190 | + buffer_append_string_buffer(b, ds->value); | |
26191 | + BUFFER_APPEND_STRING_CONST(b, "\r\n"); | |
2519e6e5 ER |
26192 | } |
26193 | - | |
26194 | + | |
26195 | BUFFER_APPEND_STRING_CONST(b, "\r\n"); | |
26196 | - | |
26197 | + | |
26198 | hctx->wb->bytes_in += b->used - 1; | |
26199 | /* body */ | |
26200 | - | |
26201 | + | |
26202 | if (con->request.content_length) { | |
26203 | chunkqueue *req_cq = con->request_content_queue; | |
26204 | chunk *req_c; | |
1175ccec | 26205 | @@ -479,7 +522,7 @@ |
2519e6e5 ER |
26206 | |
26207 | /* we announce toWrite octects | |
26208 | * now take all the request_content chunk that we need to fill this request | |
26209 | - * */ | |
26210 | + * */ | |
26211 | ||
26212 | switch (req_c->type) { | |
26213 | case FILE_CHUNK: | |
1175ccec | 26214 | @@ -507,223 +550,161 @@ |
2519e6e5 ER |
26215 | |
26216 | req_c->offset += weHave; | |
26217 | req_cq->bytes_out += weHave; | |
26218 | - | |
26219 | + | |
26220 | hctx->wb->bytes_in += weHave; | |
26221 | ||
26222 | break; | |
26223 | default: | |
26224 | break; | |
26225 | } | |
26226 | - | |
26227 | + | |
26228 | offset += weHave; | |
26229 | } | |
26230 | ||
26231 | } | |
26232 | - | |
26233 | + | |
26234 | return 0; | |
26235 | } | |
26236 | ||
26237 | static int proxy_set_state(server *srv, handler_ctx *hctx, proxy_connection_state_t state) { | |
26238 | hctx->state = state; | |
26239 | hctx->state_timestamp = srv->cur_ts; | |
26240 | - | |
26241 | + | |
26242 | return 0; | |
26243 | } | |
26244 | ||
26245 | ||
26246 | -static int proxy_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) { | |
26247 | - char *s, *ns; | |
26248 | - int http_response_status = -1; | |
26249 | - | |
26250 | - UNUSED(srv); | |
26251 | +static void chunkqueue_print(chunkqueue *cq) { | |
1175ccec | 26252 | + chunk *c; |
2519e6e5 ER |
26253 | |
26254 | - /* \r\n -> \0\0 */ | |
26255 | - | |
26256 | - buffer_copy_string_buffer(p->parse_response, in); | |
26257 | - | |
26258 | - for (s = p->parse_response->ptr; NULL != (ns = strstr(s, "\r\n")); s = ns + 2) { | |
26259 | - char *key, *value; | |
26260 | - int key_len; | |
26261 | - data_string *ds; | |
26262 | - int copy_header; | |
26263 | - | |
26264 | - ns[0] = '\0'; | |
26265 | - ns[1] = '\0'; | |
26266 | - | |
26267 | - if (-1 == http_response_status) { | |
26268 | - /* The first line of a Response message is the Status-Line */ | |
26269 | - | |
26270 | - for (key=s; *key && *key != ' '; key++); | |
26271 | - | |
26272 | - if (*key) { | |
26273 | - http_response_status = (int) strtol(key, NULL, 10); | |
26274 | - if (http_response_status <= 0) http_response_status = 502; | |
26275 | - } else { | |
26276 | - http_response_status = 502; | |
26277 | - } | |
26278 | - | |
26279 | - con->http_status = http_response_status; | |
26280 | - con->parsed_response |= HTTP_STATUS; | |
26281 | - continue; | |
26282 | - } | |
26283 | - | |
26284 | - if (NULL == (value = strchr(s, ':'))) { | |
26285 | - /* now we expect: "<key>: <value>\n" */ | |
26286 | - | |
26287 | - continue; | |
26288 | - } | |
26289 | - | |
26290 | - key = s; | |
26291 | - key_len = value - key; | |
26292 | - | |
26293 | - value++; | |
26294 | - /* strip WS */ | |
26295 | - while (*value == ' ' || *value == '\t') value++; | |
26296 | - | |
26297 | - copy_header = 1; | |
26298 | - | |
26299 | - switch(key_len) { | |
26300 | - case 4: | |
26301 | - if (0 == strncasecmp(key, "Date", key_len)) { | |
26302 | - con->parsed_response |= HTTP_DATE; | |
26303 | - } | |
26304 | - break; | |
26305 | - case 8: | |
26306 | - if (0 == strncasecmp(key, "Location", key_len)) { | |
26307 | - con->parsed_response |= HTTP_LOCATION; | |
26308 | - } | |
26309 | - break; | |
26310 | - case 10: | |
26311 | - if (0 == strncasecmp(key, "Connection", key_len)) { | |
26312 | - copy_header = 0; | |
26313 | - } | |
26314 | - break; | |
26315 | - case 14: | |
26316 | - if (0 == strncasecmp(key, "Content-Length", key_len)) { | |
26317 | - con->response.content_length = strtol(value, NULL, 10); | |
26318 | - con->parsed_response |= HTTP_CONTENT_LENGTH; | |
26319 | - } | |
26320 | - break; | |
26321 | - default: | |
26322 | - break; | |
26323 | - } | |
26324 | - | |
26325 | - if (copy_header) { | |
26326 | - if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { | |
26327 | - ds = data_response_init(); | |
26328 | - } | |
26329 | - buffer_copy_string_len(ds->key, key, key_len); | |
26330 | - buffer_copy_string(ds->value, value); | |
26331 | - | |
26332 | - array_insert_unique(con->response.headers, (data_unset *)ds); | |
26333 | - } | |
1175ccec ER |
26334 | + for (c = cq->first; c; c = c->next) { |
26335 | + fprintf(stderr, "%s", c->mem->ptr + c->offset); | |
26336 | } | |
2519e6e5 ER |
26337 | - |
26338 | - return 0; | |
1175ccec | 26339 | + fprintf(stderr, "\r\n"); |
2519e6e5 ER |
26340 | } |
26341 | ||
26342 | - | |
26343 | static int proxy_demux_response(server *srv, handler_ctx *hctx) { | |
26344 | - int fin = 0; | |
26345 | - int b; | |
26346 | - ssize_t r; | |
26347 | - | |
26348 | plugin_data *p = hctx->plugin_data; | |
26349 | connection *con = hctx->remote_conn; | |
26350 | int proxy_fd = hctx->fd; | |
26351 | - | |
26352 | - /* check how much we have to read */ | |
26353 | - if (ioctl(hctx->fd, FIONREAD, &b)) { | |
26354 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26355 | - "ioctl failed: ", | |
26356 | - proxy_fd); | |
1175ccec ER |
26357 | + chunkqueue *next_queue = NULL; |
26358 | + chunk *c = NULL; | |
26359 | + | |
26360 | + switch(srv->network_backend_read(srv, con, proxy_fd, hctx->rb)) { | |
26361 | + case NETWORK_STATUS_SUCCESS: | |
26362 | + /* we got content */ | |
26363 | + break; | |
26364 | + case NETWORK_STATUS_WAIT_FOR_EVENT: | |
26365 | + /* the ioctl will return WAIT_FOR_EVENT on a read */ | |
26366 | + if (0 == con->file_started) return -1; | |
26367 | + case NETWORK_STATUS_CONNECTION_CLOSE: | |
26368 | + /* we are done, get out of here */ | |
26369 | + con->file_finished = 1; | |
26370 | + | |
26371 | + /* close the chunk-queue with a empty chunk */ | |
26372 | + | |
26373 | + return 1; | |
26374 | + default: | |
26375 | + /* oops */ | |
26376 | return -1; | |
26377 | } | |
26378 | ||
26379 | + /* looks like we got some content | |
26380 | + * | |
26381 | + * split off the header from the incoming stream | |
26382 | + */ | |
2519e6e5 ER |
26383 | |
26384 | - if (p->conf.debug) { | |
26385 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26386 | - "proxy - have to read:", b); | |
26387 | - } | |
1175ccec ER |
26388 | + if (hctx->state == PROXY_STATE_RESPONSE_HEADER) { |
26389 | + size_t i; | |
26390 | + int have_content_length = 0; | |
26391 | ||
2519e6e5 ER |
26392 | - if (b > 0) { |
26393 | - if (hctx->response->used == 0) { | |
26394 | - /* avoid too small buffer */ | |
26395 | - buffer_prepare_append(hctx->response, b + 1); | |
26396 | - hctx->response->used = 1; | |
26397 | - } else { | |
26398 | - buffer_prepare_append(hctx->response, hctx->response->used + b); | |
26399 | - } | |
26400 | - | |
26401 | - if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) { | |
26402 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
26403 | - "unexpected end-of-file (perhaps the proxy process died):", | |
26404 | - proxy_fd, strerror(errno)); | |
26405 | - return -1; | |
26406 | - } | |
26407 | - | |
26408 | - /* this should be catched by the b > 0 above */ | |
26409 | - assert(r); | |
26410 | - | |
26411 | - hctx->response->used += r; | |
26412 | - hctx->response->ptr[hctx->response->used - 1] = '\0'; | |
26413 | - | |
26414 | -#if 0 | |
26415 | - log_error_write(srv, __FILE__, __LINE__, "sdsbs", | |
26416 | - "demux: Response buffer len", hctx->response->used, ":", hctx->response, ":"); | |
26417 | -#endif | |
1175ccec ER |
26418 | + http_response_reset(p->resp); |
26419 | ||
2519e6e5 ER |
26420 | - if (0 == con->got_response) { |
26421 | - con->got_response = 1; | |
26422 | - buffer_prepare_copy(hctx->response_header, 128); | |
26423 | - } | |
26424 | - | |
26425 | - if (0 == con->file_started) { | |
26426 | - char *c; | |
26427 | - | |
26428 | - /* search for the \r\n\r\n in the string */ | |
26429 | - if (NULL != (c = buffer_search_string_len(hctx->response, "\r\n\r\n", 4))) { | |
26430 | - size_t hlen = c - hctx->response->ptr + 4; | |
26431 | - size_t blen = hctx->response->used - hlen - 1; | |
26432 | - /* found */ | |
26433 | - | |
26434 | - buffer_append_string_len(hctx->response_header, hctx->response->ptr, c - hctx->response->ptr + 4); | |
26435 | -#if 0 | |
26436 | - log_error_write(srv, __FILE__, __LINE__, "sb", "Header:", hctx->response_header); | |
26437 | -#endif | |
26438 | - /* parse the response header */ | |
26439 | - proxy_response_parse(srv, con, p, hctx->response_header); | |
26440 | - | |
26441 | - /* enable chunked-transfer-encoding */ | |
26442 | - if (con->request.http_version == HTTP_VERSION_1_1 && | |
26443 | - !(con->parsed_response & HTTP_CONTENT_LENGTH)) { | |
26444 | - con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
1175ccec ER |
26445 | + /* the response header is not fully received yet, |
26446 | + * | |
26447 | + * extract the http-response header from the rb-cq | |
26448 | + */ | |
26449 | + switch (http_response_parse_cq(hctx->rb, p->resp)) { | |
26450 | + case PARSE_ERROR: | |
26451 | + /* parsing failed */ | |
26452 | + | |
26453 | + con->http_status = 502; /* Bad Gateway */ | |
26454 | + return 1; | |
26455 | + case PARSE_NEED_MORE: | |
26456 | + return 0; | |
26457 | + case PARSE_SUCCESS: | |
26458 | + con->http_status = p->resp->status; | |
26459 | + | |
26460 | + chunkqueue_remove_finished_chunks(hctx->rb); | |
26461 | + | |
26462 | + /* copy the http-headers */ | |
26463 | + for (i = 0; i < p->resp->headers->used; i++) { | |
26464 | + const char *ign[] = { "Status", "Connection", NULL }; | |
26465 | + size_t j; | |
26466 | + data_string *ds; | |
26467 | + | |
26468 | + data_string *header = (data_string *)p->resp->headers->data[i]; | |
26469 | + | |
26470 | + /* some headers are ignored by default */ | |
26471 | + for (j = 0; ign[j]; j++) { | |
26472 | + if (0 == strcasecmp(ign[j], header->key->ptr)) break; | |
26473 | } | |
2519e6e5 ER |
26474 | - |
26475 | - con->file_started = 1; | |
26476 | - if (blen) { | |
26477 | - http_chunk_append_mem(srv, con, c + 4, blen + 1); | |
26478 | - joblist_append(srv, con); | |
1175ccec ER |
26479 | + if (ign[j]) continue; |
26480 | + | |
26481 | + if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) { | |
26482 | + /* CGI/1.1 rev 03 - 7.2.1.2 */ | |
26483 | + if (con->http_status == 0) con->http_status = 302; | |
26484 | + } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) { | |
26485 | + have_content_length = 1; | |
26486 | } | |
2519e6e5 | 26487 | - hctx->response->used = 0; |
1175ccec ER |
26488 | + |
26489 | + if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { | |
26490 | + ds = data_response_init(); | |
26491 | + } | |
26492 | + buffer_copy_string_buffer(ds->key, header->key); | |
26493 | + buffer_copy_string_buffer(ds->value, header->value); | |
26494 | + | |
26495 | + array_insert_unique(con->response.headers, (data_unset *)ds); | |
26496 | } | |
2519e6e5 ER |
26497 | - } else { |
26498 | - http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used); | |
26499 | - joblist_append(srv, con); | |
26500 | - hctx->response->used = 0; | |
1175ccec ER |
26501 | + |
26502 | + con->file_started = 1; | |
26503 | + | |
26504 | + if (con->request.http_version == HTTP_VERSION_1_1 && | |
26505 | + !have_content_length) { | |
26506 | + con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
26507 | + } | |
26508 | + | |
26509 | + hctx->state = PROXY_STATE_RESPONSE_CONTENT; | |
26510 | + break; | |
26511 | } | |
2519e6e5 ER |
26512 | - |
26513 | - } else { | |
26514 | - /* reading from upstream done */ | |
1175ccec | 26515 | - con->file_finished = 1; |
2519e6e5 | 26516 | - |
1175ccec ER |
26517 | - http_chunk_append_mem(srv, con, NULL, 0); |
26518 | - joblist_append(srv, con); | |
2519e6e5 ER |
26519 | - |
26520 | - fin = 1; | |
1175ccec ER |
26521 | } |
26522 | - | |
26523 | - return fin; | |
2519e6e5 | 26524 | + |
1175ccec ER |
26525 | + /* FIXME: pass the response-header to the other plugins to |
26526 | + * setup the filter-queue | |
26527 | + * | |
26528 | + * - use next-queue instead of con->write_queue | |
26529 | + */ | |
2519e6e5 | 26530 | + |
1175ccec | 26531 | + next_queue = con->write_queue; |
2519e6e5 | 26532 | + |
1175ccec | 26533 | + assert(hctx->state == PROXY_STATE_RESPONSE_CONTENT); |
2519e6e5 | 26534 | + |
1175ccec ER |
26535 | + /* FIXME: if we have a content-length or chunked-encoding |
26536 | + * handle it. | |
26537 | + * | |
26538 | + * for now we wait for EOF on the socket */ | |
2519e6e5 | 26539 | + |
1175ccec ER |
26540 | + /* copy the content to the next cq */ |
26541 | + for (c = hctx->rb->first; c; c = c->next) { | |
26542 | + http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset); | |
2519e6e5 | 26543 | + |
1175ccec ER |
26544 | + c->offset = c->mem->used - 1; |
26545 | + } | |
2519e6e5 | 26546 | + |
1175ccec ER |
26547 | + chunkqueue_remove_finished_chunks(hctx->rb); |
26548 | + joblist_append(srv, con); | |
2519e6e5 ER |
26549 | + |
26550 | + return 0; | |
26551 | } | |
26552 | ||
26553 | ||
1175ccec | 26554 | @@ -731,12 +712,12 @@ |
2519e6e5 ER |
26555 | data_proxy *host= hctx->host; |
26556 | plugin_data *p = hctx->plugin_data; | |
26557 | connection *con = hctx->remote_conn; | |
26558 | - | |
26559 | + | |
26560 | int ret; | |
26561 | - | |
26562 | - if (!host || | |
1175ccec ER |
26563 | - (!host->host->used || !host->port)) return -1; |
26564 | - | |
2519e6e5 ER |
26565 | + |
26566 | + if (!host || | |
1175ccec | 26567 | + (!host->host->used || !host->port)) return -1; |
2519e6e5 ER |
26568 | + |
26569 | switch(hctx->state) { | |
26570 | case PROXY_STATE_INIT: | |
26571 | if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) { | |
1175ccec | 26572 | @@ -744,19 +725,19 @@ |
2519e6e5 ER |
26573 | return HANDLER_ERROR; |
26574 | } | |
26575 | hctx->fde_ndx = -1; | |
26576 | - | |
26577 | + | |
26578 | srv->cur_fds++; | |
26579 | - | |
26580 | + | |
26581 | fdevent_register(srv->ev, hctx->fd, proxy_handle_fdevent, hctx); | |
26582 | - | |
26583 | + | |
26584 | if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) { | |
26585 | log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno)); | |
26586 | - | |
26587 | + | |
26588 | return HANDLER_ERROR; | |
26589 | } | |
26590 | - | |
26591 | + | |
26592 | /* fall through */ | |
26593 | - | |
26594 | + | |
26595 | case PROXY_STATE_CONNECT: | |
26596 | /* try to finish the connect() */ | |
26597 | if (hctx->state == PROXY_STATE_INIT) { | |
1175ccec | 26598 | @@ -764,16 +745,16 @@ |
2519e6e5 ER |
26599 | switch (proxy_establish_connection(srv, hctx)) { |
26600 | case 1: | |
26601 | proxy_set_state(srv, hctx, PROXY_STATE_CONNECT); | |
26602 | - | |
26603 | + | |
26604 | /* connection is in progress, wait for an event and call getsockopt() below */ | |
26605 | - | |
26606 | + | |
26607 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
26608 | - | |
26609 | + | |
26610 | return HANDLER_WAIT_FOR_EVENT; | |
26611 | case -1: | |
26612 | /* if ECONNREFUSED choose another connection -> FIXME */ | |
26613 | hctx->fde_ndx = -1; | |
26614 | - | |
26615 | + | |
26616 | return HANDLER_ERROR; | |
26617 | default: | |
26618 | /* everything is ok, go on */ | |
1175ccec | 26619 | @@ -782,152 +763,152 @@ |
2519e6e5 ER |
26620 | } else { |
26621 | int socket_error; | |
26622 | socklen_t socket_error_len = sizeof(socket_error); | |
26623 | - | |
26624 | - /* we don't need it anymore */ | |
26625 | + | |
26626 | + /* we don't need it anymore */ | |
26627 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
26628 | ||
26629 | /* try to finish the connect() */ | |
26630 | if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) { | |
26631 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
26632 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
26633 | "getsockopt failed:", strerror(errno)); | |
26634 | - | |
26635 | + | |
26636 | return HANDLER_ERROR; | |
26637 | } | |
26638 | if (socket_error != 0) { | |
26639 | log_error_write(srv, __FILE__, __LINE__, "ss", | |
26640 | - "establishing connection failed:", strerror(socket_error), | |
26641 | + "establishing connection failed:", strerror(socket_error), | |
26642 | "port:", hctx->host->port); | |
26643 | - | |
26644 | + | |
26645 | return HANDLER_ERROR; | |
26646 | } | |
26647 | if (p->conf.debug) { | |
26648 | - log_error_write(srv, __FILE__, __LINE__, "s", "proxy - connect - delayed success"); | |
26649 | + log_error_write(srv, __FILE__, __LINE__, "s", "proxy - connect - delayed success"); | |
26650 | } | |
2519e6e5 ER |
26651 | } |
26652 | - | |
26653 | + | |
26654 | proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE); | |
26655 | /* fall through */ | |
26656 | case PROXY_STATE_PREPARE_WRITE: | |
26657 | proxy_create_env(srv, hctx); | |
26658 | - | |
26659 | + | |
26660 | proxy_set_state(srv, hctx, PROXY_STATE_WRITE); | |
26661 | - | |
26662 | + | |
26663 | /* fall through */ | |
26664 | case PROXY_STATE_WRITE:; | |
26665 | - ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); | |
26666 | + ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); | |
26667 | ||
26668 | chunkqueue_remove_finished_chunks(hctx->wb); | |
26669 | ||
26670 | - if (-1 == ret) { | |
26671 | - if (errno != EAGAIN && | |
26672 | - errno != EINTR) { | |
26673 | - log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno); | |
26674 | - | |
26675 | - return HANDLER_ERROR; | |
26676 | - } else { | |
26677 | - fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
26678 | + switch(ret) { | |
1175ccec | 26679 | + case NETWORK_STATUS_FATAL_ERROR: |
2519e6e5 ER |
26680 | + log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno); |
26681 | ||
26682 | - return HANDLER_WAIT_FOR_EVENT; | |
26683 | - } | |
26684 | + return HANDLER_ERROR; | |
1175ccec | 26685 | + case NETWORK_STATUS_WAIT_FOR_EVENT: |
2519e6e5 ER |
26686 | + |
26687 | + fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
26688 | + | |
26689 | + return HANDLER_WAIT_FOR_EVENT; | |
26690 | } | |
26691 | ||
26692 | if (hctx->wb->bytes_out == hctx->wb->bytes_in) { | |
26693 | - proxy_set_state(srv, hctx, PROXY_STATE_READ); | |
26694 | + proxy_set_state(srv, hctx, PROXY_STATE_RESPONSE_HEADER); | |
26695 | ||
26696 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
26697 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN); | |
26698 | } else { | |
26699 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
26700 | - | |
26701 | + | |
26702 | return HANDLER_WAIT_FOR_EVENT; | |
26703 | } | |
26704 | - | |
26705 | + | |
26706 | return HANDLER_WAIT_FOR_EVENT; | |
26707 | - case PROXY_STATE_READ: | |
1175ccec | 26708 | + case PROXY_STATE_RESPONSE_CONTENT: |
2519e6e5 ER |
26709 | + case PROXY_STATE_RESPONSE_HEADER: |
26710 | /* waiting for a response */ | |
26711 | + | |
26712 | return HANDLER_WAIT_FOR_EVENT; | |
26713 | default: | |
26714 | log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state"); | |
26715 | return HANDLER_ERROR; | |
26716 | } | |
26717 | - | |
26718 | + | |
26719 | return HANDLER_GO_ON; | |
26720 | } | |
26721 | ||
26722 | -#define PATCH(x) \ | |
26723 | - p->conf.x = s->x; | |
26724 | static int mod_proxy_patch_connection(server *srv, connection *con, plugin_data *p) { | |
26725 | size_t i, j; | |
26726 | plugin_config *s = p->config_storage[0]; | |
26727 | - | |
26728 | - PATCH(extensions); | |
26729 | - PATCH(debug); | |
26730 | - PATCH(balance); | |
26731 | - | |
26732 | + | |
26733 | + PATCH_OPTION(extensions); | |
26734 | + PATCH_OPTION(debug); | |
26735 | + PATCH_OPTION(balance); | |
26736 | + PATCH_OPTION(last_used_backends); | |
26737 | + | |
26738 | /* skip the first, the global context */ | |
26739 | for (i = 1; i < srv->config_context->used; i++) { | |
26740 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
26741 | s = p->config_storage[i]; | |
26742 | - | |
26743 | + | |
26744 | /* condition didn't match */ | |
26745 | if (!config_check_cond(srv, con, dc)) continue; | |
26746 | - | |
26747 | + | |
26748 | /* merge config */ | |
26749 | for (j = 0; j < dc->value->used; j++) { | |
26750 | data_unset *du = dc->value->data[j]; | |
26751 | - | |
26752 | + | |
26753 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.server"))) { | |
26754 | - PATCH(extensions); | |
26755 | + PATCH_OPTION(extensions); | |
26756 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) { | |
26757 | - PATCH(debug); | |
26758 | + PATCH_OPTION(debug); | |
26759 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balance"))) { | |
26760 | - PATCH(balance); | |
26761 | + PATCH_OPTION(balance); | |
26762 | + PATCH_OPTION(last_used_backends); | |
26763 | } | |
26764 | } | |
26765 | } | |
26766 | - | |
26767 | + | |
26768 | return 0; | |
26769 | } | |
26770 | -#undef PATCH | |
26771 | ||
26772 | SUBREQUEST_FUNC(mod_proxy_handle_subrequest) { | |
26773 | plugin_data *p = p_d; | |
26774 | - | |
26775 | + | |
26776 | handler_ctx *hctx = con->plugin_ctx[p->id]; | |
26777 | data_proxy *host; | |
26778 | - | |
26779 | + | |
26780 | if (NULL == hctx) return HANDLER_GO_ON; | |
26781 | ||
26782 | mod_proxy_patch_connection(srv, con, p); | |
26783 | - | |
26784 | + | |
26785 | host = hctx->host; | |
26786 | - | |
26787 | + | |
26788 | /* not my job */ | |
26789 | if (con->mode != p->id) return HANDLER_GO_ON; | |
26790 | - | |
26791 | + | |
26792 | /* ok, create the request */ | |
26793 | switch(proxy_write_request(srv, hctx)) { | |
26794 | case HANDLER_ERROR: | |
26795 | - log_error_write(srv, __FILE__, __LINE__, "sbdd", "proxy-server disabled:", | |
26796 | + log_error_write(srv, __FILE__, __LINE__, "sbdd", "proxy-server disabled:", | |
26797 | host->host, | |
26798 | host->port, | |
26799 | hctx->fd); | |
26800 | - | |
26801 | + | |
26802 | /* disable this server */ | |
26803 | host->is_disabled = 1; | |
26804 | host->disable_ts = srv->cur_ts; | |
26805 | - | |
26806 | + | |
26807 | proxy_connection_close(srv, hctx); | |
26808 | - | |
26809 | - /* reset the enviroment and restart the sub-request */ | |
26810 | + | |
26811 | + /* reset the enviroment and restart the sub-request */ | |
26812 | buffer_reset(con->physical.path); | |
26813 | con->mode = DIRECT; | |
26814 | ||
26815 | joblist_append(srv, con); | |
26816 | ||
26817 | - /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop | |
26818 | - * and hope that the childs will be restarted | |
26819 | - * | |
26820 | + /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop | |
26821 | + * and hope that the childs will be restarted | |
26822 | + * | |
26823 | */ | |
26824 | ||
26825 | return HANDLER_WAIT_FOR_FD; | |
1175ccec | 26826 | @@ -938,7 +919,7 @@ |
2519e6e5 ER |
26827 | default: |
26828 | break; | |
26829 | } | |
26830 | - | |
26831 | + | |
26832 | if (con->file_started == 1) { | |
26833 | return HANDLER_FINISHED; | |
26834 | } else { | |
1175ccec | 26835 | @@ -951,13 +932,14 @@ |
2519e6e5 ER |
26836 | handler_ctx *hctx = ctx; |
26837 | connection *con = hctx->remote_conn; | |
26838 | plugin_data *p = hctx->plugin_data; | |
26839 | - | |
26840 | - | |
26841 | + | |
26842 | + | |
26843 | if ((revents & FDEVENT_IN) && | |
26844 | - hctx->state == PROXY_STATE_READ) { | |
1175ccec ER |
26845 | + (hctx->state == PROXY_STATE_RESPONSE_HEADER || |
26846 | + hctx->state == PROXY_STATE_RESPONSE_CONTENT)) { | |
2519e6e5 ER |
26847 | |
26848 | if (p->conf.debug) { | |
26849 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26850 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
26851 | "proxy: fdevent-in", hctx->state); | |
26852 | } | |
26853 | ||
1175ccec ER |
26854 | @@ -965,11 +947,15 @@ |
26855 | case 0: | |
2519e6e5 ER |
26856 | break; |
26857 | case 1: | |
1175ccec ER |
26858 | + log_error_write(srv, __FILE__, __LINE__, "sd", |
26859 | + "proxy: request done", hctx->fd); | |
2519e6e5 ER |
26860 | hctx->host->usage--; |
26861 | - | |
1175ccec ER |
26862 | + |
26863 | + http_chunk_append_mem(srv, con, NULL, 0); | |
2519e6e5 ER |
26864 | + |
26865 | /* we are done */ | |
26866 | proxy_connection_close(srv, hctx); | |
26867 | - | |
26868 | + | |
26869 | joblist_append(srv, con); | |
26870 | return HANDLER_FINISHED; | |
26871 | case -1: | |
1175ccec | 26872 | @@ -982,53 +968,53 @@ |
2519e6e5 ER |
26873 | /* response might have been already started, kill the connection */ |
26874 | connection_set_state(srv, con, CON_STATE_ERROR); | |
26875 | } | |
26876 | - | |
26877 | + | |
26878 | joblist_append(srv, con); | |
26879 | return HANDLER_FINISHED; | |
26880 | } | |
26881 | } | |
26882 | - | |
26883 | + | |
26884 | if (revents & FDEVENT_OUT) { | |
26885 | if (p->conf.debug) { | |
26886 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26887 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
26888 | "proxy: fdevent-out", hctx->state); | |
26889 | } | |
26890 | ||
26891 | if (hctx->state == PROXY_STATE_CONNECT || | |
26892 | hctx->state == PROXY_STATE_WRITE) { | |
26893 | /* we are allowed to send something out | |
26894 | - * | |
26895 | + * | |
26896 | * 1. in a unfinished connect() call | |
26897 | * 2. in a unfinished write() call (long POST request) | |
26898 | */ | |
26899 | return mod_proxy_handle_subrequest(srv, con, p); | |
26900 | } else { | |
26901 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26902 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
26903 | "proxy: out", hctx->state); | |
26904 | } | |
26905 | } | |
26906 | - | |
26907 | + | |
26908 | /* perhaps this issue is already handled */ | |
26909 | if (revents & FDEVENT_HUP) { | |
26910 | if (p->conf.debug) { | |
26911 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
26912 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
26913 | "proxy: fdevent-hup", hctx->state); | |
26914 | } | |
26915 | - | |
26916 | + | |
26917 | if (hctx->state == PROXY_STATE_CONNECT) { | |
26918 | /* connect() -> EINPROGRESS -> HUP */ | |
26919 | - | |
26920 | + | |
26921 | /** | |
26922 | - * what is proxy is doing if it can't reach the next hop ? | |
26923 | - * | |
26924 | + * what is proxy is doing if it can't reach the next hop ? | |
26925 | + * | |
26926 | */ | |
26927 | - | |
26928 | + | |
26929 | proxy_connection_close(srv, hctx); | |
26930 | joblist_append(srv, con); | |
26931 | - | |
26932 | + | |
26933 | con->http_status = 503; | |
26934 | con->mode = DIRECT; | |
26935 | - | |
26936 | + | |
26937 | return HANDLER_FINISHED; | |
26938 | } | |
26939 | ||
1175ccec | 26940 | @@ -1038,13 +1024,13 @@ |
2519e6e5 ER |
26941 | joblist_append(srv, con); |
26942 | } else if (revents & FDEVENT_ERR) { | |
26943 | /* kill all connections to the proxy process */ | |
26944 | - | |
26945 | + | |
26946 | log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_ERR, but no HUP", revents); | |
26947 | ||
26948 | joblist_append(srv, con); | |
26949 | proxy_connection_close(srv, hctx); | |
26950 | } | |
26951 | - | |
26952 | + | |
26953 | return HANDLER_FINISHED; | |
26954 | } | |
26955 | ||
1175ccec | 26956 | @@ -1058,44 +1044,48 @@ |
2519e6e5 ER |
26957 | buffer *fn; |
26958 | data_array *extension = NULL; | |
26959 | size_t path_info_offset; | |
26960 | - | |
26961 | + data_integer *last_used_backend; | |
26962 | + data_proxy *host = NULL; | |
26963 | + handler_ctx *hctx = NULL; | |
26964 | + | |
26965 | + array *backends = NULL; | |
26966 | + | |
26967 | /* Possibly, we processed already this request */ | |
26968 | if (con->file_started == 1) return HANDLER_GO_ON; | |
26969 | - | |
26970 | + | |
26971 | mod_proxy_patch_connection(srv, con, p); | |
26972 | - | |
26973 | + | |
26974 | fn = con->uri.path; | |
26975 | ||
26976 | if (fn->used == 0) { | |
26977 | return HANDLER_ERROR; | |
26978 | } | |
26979 | - | |
26980 | + | |
26981 | s_len = fn->used - 1; | |
26982 | - | |
26983 | - | |
2519e6e5 ER |
26984 | + |
26985 | path_info_offset = 0; | |
26986 | ||
26987 | - if (p->conf.debug) { | |
26988 | + if (p->conf.debug) { | |
26989 | log_error_write(srv, __FILE__, __LINE__, "s", "proxy - start"); | |
26990 | } | |
26991 | ||
26992 | /* check if extension matches */ | |
26993 | for (k = 0; k < p->conf.extensions->used; k++) { | |
26994 | size_t ct_len; | |
26995 | - | |
26996 | + | |
26997 | extension = (data_array *)p->conf.extensions->data[k]; | |
26998 | - | |
26999 | + | |
27000 | if (extension->key->used == 0) continue; | |
27001 | - | |
27002 | + | |
27003 | ct_len = extension->key->used - 1; | |
27004 | - | |
27005 | + | |
27006 | if (s_len < ct_len) continue; | |
27007 | - | |
27008 | + | |
27009 | /* check extension in the form "/proxy_pattern" */ | |
27010 | if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) { | |
27011 | if (s_len > ct_len + 1) { | |
27012 | char *pi_offset; | |
27013 | - | |
27014 | + | |
27015 | if (0 != (pi_offset = strchr(fn->ptr + ct_len + 1, '/'))) { | |
27016 | path_info_offset = pi_offset - fn->ptr; | |
27017 | } | |
1175ccec | 27018 | @@ -1106,12 +1096,14 @@ |
2519e6e5 ER |
27019 | break; |
27020 | } | |
27021 | } | |
27022 | - | |
27023 | + | |
27024 | if (k == p->conf.extensions->used) { | |
27025 | return HANDLER_GO_ON; | |
27026 | } | |
27027 | ||
27028 | - if (p->conf.debug) { | |
27029 | + backends = extension->value; | |
27030 | + | |
27031 | + if (p->conf.debug) { | |
27032 | log_error_write(srv, __FILE__, __LINE__, "s", "proxy - ext found"); | |
27033 | } | |
27034 | ||
1175ccec | 27035 | @@ -1120,34 +1112,34 @@ |
2519e6e5 ER |
27036 | /* hash balancing */ |
27037 | ||
27038 | if (p->conf.debug) { | |
27039 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
27040 | - "proxy - used hash balancing, hosts:", extension->value->used); | |
27041 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
27042 | + "proxy - used hash balancing, hosts:", backends->used); | |
27043 | } | |
27044 | ||
27045 | - for (k = 0, ndx = -1, last_max = ULONG_MAX; k < extension->value->used; k++) { | |
27046 | - data_proxy *host = (data_proxy *)extension->value->data[k]; | |
27047 | + for (k = 0, ndx = -1, last_max = ULONG_MAX; k < backends->used; k++) { | |
27048 | unsigned long cur_max; | |
27049 | ||
27050 | - if (host->is_disabled) continue; | |
27051 | - | |
27052 | + data_proxy *cur = (data_proxy *)backends->data[k]; | |
27053 | + | |
27054 | + if (cur->is_disabled) continue; | |
27055 | + | |
27056 | cur_max = generate_crc32c(CONST_BUF_LEN(con->uri.path)) + | |
27057 | - generate_crc32c(CONST_BUF_LEN(host->host)) + /* we can cache this */ | |
27058 | + generate_crc32c(CONST_BUF_LEN(cur->host)) + /* we can cache this */ | |
27059 | generate_crc32c(CONST_BUF_LEN(con->uri.authority)); | |
27060 | - | |
27061 | + | |
27062 | if (p->conf.debug) { | |
27063 | - log_error_write(srv, __FILE__, __LINE__, "sbbbd", | |
27064 | + log_error_write(srv, __FILE__, __LINE__, "sbbbd", | |
27065 | "proxy - election:", | |
27066 | con->uri.path, | |
27067 | - host->host, | |
27068 | + cur->host, | |
27069 | con->uri.authority, | |
27070 | cur_max); | |
27071 | } | |
27072 | ||
27073 | - if ((last_max == ULONG_MAX) || /* first round */ | |
27074 | - (cur_max > last_max)) { | |
27075 | + if (host == NULL || (cur_max > last_max)) { | |
27076 | last_max = cur_max; | |
27077 | ||
27078 | - ndx = k; | |
27079 | + host = cur; | |
27080 | } | |
27081 | } | |
27082 | ||
1175ccec | 27083 | @@ -1155,19 +1147,20 @@ |
2519e6e5 ER |
27084 | case PROXY_BALANCE_FAIR: |
27085 | /* fair balancing */ | |
27086 | if (p->conf.debug) { | |
27087 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
27088 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
27089 | "proxy - used fair balancing"); | |
27090 | } | |
27091 | ||
27092 | - for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) { | |
27093 | - data_proxy *host = (data_proxy *)extension->value->data[k]; | |
27094 | - | |
27095 | - if (host->is_disabled) continue; | |
27096 | - | |
27097 | - if (host->usage < max_usage) { | |
27098 | - max_usage = host->usage; | |
27099 | - | |
27100 | - ndx = k; | |
27101 | + /* try to find the host with the lowest load */ | |
27102 | + for (k = 0, max_usage = 0; k < backends->used; k++) { | |
27103 | + data_proxy *cur = (data_proxy *)backends->data[k]; | |
27104 | + | |
27105 | + if (cur->is_disabled) continue; | |
27106 | + | |
27107 | + if (NULL == host || cur->usage < max_usage) { | |
27108 | + max_usage = cur->usage; | |
27109 | + | |
27110 | + host = cur; | |
27111 | } | |
27112 | } | |
27113 | ||
1175ccec | 27114 | @@ -1175,89 +1168,100 @@ |
2519e6e5 ER |
27115 | case PROXY_BALANCE_RR: |
27116 | /* round robin */ | |
27117 | if (p->conf.debug) { | |
27118 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
27119 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
27120 | "proxy - used round-robin balancing"); | |
27121 | } | |
27122 | ||
27123 | /* just to be sure */ | |
27124 | - assert(extension->value->used < INT_MAX); | |
27125 | - | |
27126 | - for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) { | |
27127 | - data_proxy *host = (data_proxy *)extension->value->data[k]; | |
27128 | - | |
27129 | - if (host->is_disabled) continue; | |
27130 | - | |
27131 | - /* first usable ndx */ | |
27132 | - if (max_usage == INT_MAX) { | |
27133 | - max_usage = k; | |
27134 | - } | |
27135 | + assert(backends->used < INT_MAX); | |
27136 | ||
27137 | - /* get next ndx */ | |
27138 | - if ((int)k > host->last_used_ndx) { | |
27139 | - ndx = k; | |
27140 | - host->last_used_ndx = k; | |
27141 | + /* send each request to another host: | |
27142 | + * | |
27143 | + * e.g.: | |
27144 | + * | |
27145 | + * if we have three hosts it is | |
27146 | + * | |
27147 | + * 1 .. 2 .. 3 .. 1 .. 2 .. 3 | |
27148 | + * | |
27149 | + **/ | |
27150 | ||
27151 | - break; | |
27152 | - } | |
27153 | + /* walk through the list */ | |
27154 | + last_used_backend = (data_integer *)array_get_element(p->conf.last_used_backends, extension->key->ptr); | |
27155 | + | |
27156 | + if (NULL == last_used_backend) { | |
27157 | + last_used_backend = data_integer_init(); | |
27158 | + | |
27159 | + buffer_copy_string_buffer(last_used_backend->key, extension->key); | |
27160 | + last_used_backend->value = 0; | |
27161 | + | |
27162 | + array_insert_unique(p->conf.last_used_backends, (data_unset *)last_used_backend); | |
27163 | + } | |
27164 | + | |
27165 | + /* scan all but the last host to see if they are up | |
27166 | + * take the first running host */ | |
27167 | + for (k = last_used_backend->value + 1; (int)(k % backends->used) != last_used_backend->value; k++) { | |
27168 | + data_proxy *cur = (data_proxy *)backends->data[k % backends->used]; | |
27169 | + | |
27170 | + if (cur->is_disabled) continue; | |
27171 | + | |
27172 | + host = cur; | |
27173 | + | |
27174 | + last_used_backend->value = k; | |
27175 | + | |
27176 | + break; | |
27177 | } | |
27178 | - | |
27179 | - /* didn't found a higher id, wrap to the start */ | |
27180 | - if (ndx != -1 && max_usage != INT_MAX) { | |
27181 | - ndx = max_usage; | |
27182 | + | |
27183 | + if (NULL == host) { | |
27184 | + /* we found nothing better, fallback to the last used backend | |
27185 | + * and check if it is still up */ | |
27186 | + host = (data_proxy *)backends->data[last_used_backend->value]; | |
27187 | + | |
27188 | + if (host->is_disabled) host = NULL; | |
27189 | } | |
27190 | ||
27191 | break; | |
27192 | default: | |
27193 | break; | |
27194 | } | |
27195 | - | |
27196 | - /* found a server */ | |
27197 | - if (ndx != -1) { | |
27198 | - data_proxy *host = (data_proxy *)extension->value->data[ndx]; | |
27199 | - | |
27200 | - /* | |
27201 | - * if check-local is disabled, use the uri.path handler | |
27202 | - * | |
27203 | - */ | |
27204 | - | |
27205 | - /* init handler-context */ | |
27206 | - handler_ctx *hctx; | |
27207 | - hctx = handler_ctx_init(); | |
27208 | - | |
27209 | - hctx->path_info_offset = path_info_offset; | |
27210 | - hctx->remote_conn = con; | |
27211 | - hctx->plugin_data = p; | |
27212 | - hctx->host = host; | |
27213 | - | |
27214 | - con->plugin_ctx[p->id] = hctx; | |
27215 | - | |
27216 | - host->usage++; | |
27217 | - | |
27218 | - con->mode = p->id; | |
27219 | - | |
27220 | - if (p->conf.debug) { | |
27221 | - log_error_write(srv, __FILE__, __LINE__, "sbd", | |
27222 | - "proxy - found a host", | |
27223 | - host->host, host->port); | |
27224 | - } | |
27225 | ||
27226 | - return HANDLER_GO_ON; | |
27227 | - } else { | |
27228 | - /* no handler found */ | |
27229 | + /* we havn't found a host */ | |
27230 | + if (NULL == host) { | |
27231 | con->http_status = 500; | |
27232 | - | |
27233 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
27234 | - "no proxy-handler found for:", | |
27235 | + | |
27236 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
27237 | + "no proxy-handler found for:", | |
27238 | fn); | |
27239 | - | |
27240 | + | |
27241 | return HANDLER_FINISHED; | |
27242 | } | |
27243 | + | |
27244 | + /* init handler-context */ | |
27245 | + hctx = handler_ctx_init(); | |
27246 | + | |
27247 | + hctx->path_info_offset = path_info_offset; | |
27248 | + hctx->remote_conn = con; | |
27249 | + hctx->plugin_data = p; | |
27250 | + hctx->host = host; | |
27251 | + | |
27252 | + con->plugin_ctx[p->id] = hctx; | |
27253 | + | |
27254 | + host->usage++; | |
27255 | + | |
27256 | + /* we handle this request */ | |
27257 | + con->mode = p->id; | |
27258 | + | |
27259 | + if (p->conf.debug) { | |
27260 | + log_error_write(srv, __FILE__, __LINE__, "sbd", | |
27261 | + "proxy - found a host", | |
27262 | + host->host, host->port); | |
27263 | + } | |
27264 | + | |
27265 | return HANDLER_GO_ON; | |
27266 | } | |
27267 | ||
27268 | static handler_t mod_proxy_connection_close_callback(server *srv, connection *con, void *p_d) { | |
27269 | plugin_data *p = p_d; | |
27270 | - | |
27271 | + | |
27272 | proxy_connection_close(srv, con->plugin_ctx[p->id]); | |
27273 | ||
27274 | return HANDLER_GO_ON; | |
1175ccec | 27275 | @@ -1276,11 +1280,11 @@ |
2519e6e5 ER |
27276 | size_t i, n, k; |
27277 | for (i = 0; i < srv->config_context->used; i++) { | |
27278 | plugin_config *s = p->config_storage[i]; | |
27279 | - | |
27280 | - if (!s) continue; | |
27281 | + | |
27282 | + if (!s) continue; | |
27283 | ||
27284 | /* get the extensions for all configs */ | |
27285 | - | |
27286 | + | |
27287 | for (k = 0; k < s->extensions->used; k++) { | |
27288 | data_array *extension = (data_array *)s->extensions->data[k]; | |
27289 | ||
1175ccec | 27290 | @@ -1290,8 +1294,8 @@ |
2519e6e5 ER |
27291 | |
27292 | if (!host->is_disabled || | |
27293 | srv->cur_ts - host->disable_ts < 5) continue; | |
27294 | - | |
27295 | - log_error_write(srv, __FILE__, __LINE__, "sbd", | |
27296 | + | |
27297 | + log_error_write(srv, __FILE__, __LINE__, "sbd", | |
27298 | "proxy - re-enabled:", | |
27299 | host->host, host->port); | |
27300 | ||
1175ccec | 27301 | @@ -1317,8 +1321,8 @@ |
2519e6e5 ER |
27302 | p->handle_uri_clean = mod_proxy_check_extension; |
27303 | p->handle_subrequest = mod_proxy_handle_subrequest; | |
27304 | p->handle_trigger = mod_proxy_trigger; | |
27305 | - | |
27306 | + | |
27307 | p->data = NULL; | |
27308 | - | |
27309 | + | |
27310 | return 0; | |
27311 | } | |
1175ccec | 27312 | --- ../lighttpd-1.4.11/src/mod_redirect.c 2006-02-08 15:38:06.000000000 +0200 |
36e2a29e | 27313 | +++ lighttpd-1.4.12/src/mod_redirect.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
27314 | @@ -22,35 +22,35 @@ |
27315 | PLUGIN_DATA; | |
27316 | buffer *match_buf; | |
27317 | buffer *location; | |
27318 | - | |
27319 | + | |
27320 | plugin_config **config_storage; | |
27321 | - | |
27322 | - plugin_config conf; | |
27323 | + | |
27324 | + plugin_config conf; | |
27325 | } plugin_data; | |
27326 | ||
27327 | INIT_FUNC(mod_redirect_init) { | |
27328 | plugin_data *p; | |
27329 | - | |
27330 | + | |
27331 | p = calloc(1, sizeof(*p)); | |
27332 | - | |
27333 | + | |
27334 | p->match_buf = buffer_init(); | |
27335 | p->location = buffer_init(); | |
27336 | - | |
27337 | + | |
27338 | return p; | |
27339 | } | |
27340 | ||
27341 | FREE_FUNC(mod_redirect_free) { | |
27342 | plugin_data *p = p_d; | |
27343 | - | |
27344 | + | |
27345 | if (!p) return HANDLER_GO_ON; | |
27346 | ||
27347 | if (p->config_storage) { | |
27348 | size_t i; | |
27349 | for (i = 0; i < srv->config_context->used; i++) { | |
27350 | plugin_config *s = p->config_storage[i]; | |
27351 | - | |
27352 | + | |
27353 | pcre_keyvalue_buffer_free(s->redirect); | |
27354 | - | |
27355 | + | |
27356 | free(s); | |
27357 | } | |
27358 | free(p->config_storage); | |
27359 | @@ -59,9 +59,9 @@ | |
27360 | ||
27361 | buffer_free(p->match_buf); | |
27362 | buffer_free(p->location); | |
27363 | - | |
27364 | + | |
27365 | free(p); | |
27366 | - | |
27367 | + | |
27368 | return HANDLER_GO_ON; | |
27369 | } | |
27370 | ||
27371 | @@ -69,195 +69,137 @@ | |
27372 | plugin_data *p = p_d; | |
27373 | data_unset *du; | |
27374 | size_t i = 0; | |
27375 | - | |
27376 | - config_values_t cv[] = { | |
27377 | + | |
27378 | + config_values_t cv[] = { | |
27379 | { "url.redirect", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
27380 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
27381 | }; | |
27382 | - | |
27383 | + | |
27384 | if (!p) return HANDLER_ERROR; | |
27385 | - | |
27386 | + | |
27387 | /* 0 */ | |
27388 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
27389 | - | |
27390 | + | |
27391 | for (i = 0; i < srv->config_context->used; i++) { | |
27392 | plugin_config *s; | |
27393 | size_t j; | |
27394 | array *ca; | |
27395 | data_array *da = (data_array *)du; | |
27396 | - | |
27397 | + | |
27398 | s = calloc(1, sizeof(plugin_config)); | |
27399 | s->redirect = pcre_keyvalue_buffer_init(); | |
27400 | - | |
27401 | + | |
27402 | cv[0].destination = s->redirect; | |
27403 | - | |
27404 | + | |
27405 | p->config_storage[i] = s; | |
27406 | ca = ((data_config *)srv->config_context->data[i])->value; | |
27407 | - | |
27408 | + | |
27409 | if (0 != config_insert_values_global(srv, ca, cv)) { | |
27410 | return HANDLER_ERROR; | |
27411 | } | |
27412 | - | |
27413 | + | |
27414 | if (NULL == (du = array_get_element(ca, "url.redirect"))) { | |
27415 | /* no url.redirect defined */ | |
27416 | continue; | |
27417 | } | |
27418 | - | |
27419 | + | |
27420 | if (du->type != TYPE_ARRAY) { | |
27421 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
27422 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
27423 | "unexpected type for key: ", "url.redirect", "array of strings"); | |
27424 | - | |
27425 | + | |
27426 | return HANDLER_ERROR; | |
27427 | } | |
27428 | - | |
27429 | + | |
27430 | da = (data_array *)du; | |
27431 | - | |
27432 | + | |
27433 | for (j = 0; j < da->value->used; j++) { | |
27434 | if (da->value->data[j]->type != TYPE_STRING) { | |
27435 | - log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
27436 | - "unexpected type for key: ", | |
27437 | - "url.redirect", | |
27438 | + log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
27439 | + "unexpected type for key: ", | |
27440 | + "url.redirect", | |
27441 | "[", da->value->data[j]->key, "](string)"); | |
27442 | - | |
27443 | + | |
27444 | return HANDLER_ERROR; | |
27445 | } | |
27446 | - | |
27447 | - if (0 != pcre_keyvalue_buffer_append(s->redirect, | |
27448 | + | |
27449 | + if (0 != pcre_keyvalue_buffer_append(s->redirect, | |
27450 | ((data_string *)(da->value->data[j]))->key->ptr, | |
27451 | ((data_string *)(da->value->data[j]))->value->ptr)) { | |
27452 | - | |
27453 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
27454 | + | |
27455 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
27456 | "pcre-compile failed for", da->value->data[j]->key); | |
27457 | } | |
27458 | } | |
27459 | } | |
27460 | - | |
27461 | + | |
27462 | return HANDLER_GO_ON; | |
27463 | } | |
27464 | #ifdef HAVE_PCRE_H | |
27465 | static int mod_redirect_patch_connection(server *srv, connection *con, plugin_data *p) { | |
27466 | size_t i, j; | |
27467 | plugin_config *s = p->config_storage[0]; | |
27468 | - | |
27469 | + | |
27470 | p->conf.redirect = s->redirect; | |
27471 | - | |
27472 | + | |
27473 | /* skip the first, the global context */ | |
27474 | for (i = 1; i < srv->config_context->used; i++) { | |
27475 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
27476 | s = p->config_storage[i]; | |
27477 | - | |
27478 | + | |
27479 | /* condition didn't match */ | |
27480 | if (!config_check_cond(srv, con, dc)) continue; | |
27481 | - | |
27482 | + | |
27483 | /* merge config */ | |
27484 | for (j = 0; j < dc->value->used; j++) { | |
27485 | data_unset *du = dc->value->data[j]; | |
27486 | - | |
27487 | + | |
27488 | if (0 == strcmp(du->key->ptr, "url.redirect")) { | |
27489 | p->conf.redirect = s->redirect; | |
27490 | p->conf.context = dc; | |
27491 | } | |
27492 | } | |
27493 | } | |
27494 | - | |
27495 | + | |
27496 | return 0; | |
27497 | } | |
27498 | #endif | |
27499 | static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) { | |
27500 | #ifdef HAVE_PCRE_H | |
27501 | plugin_data *p = p_data; | |
27502 | - size_t i; | |
27503 | + int i; | |
27504 | ||
27505 | - /* | |
27506 | + /* | |
27507 | * REWRITE URL | |
27508 | - * | |
27509 | + * | |
27510 | * e.g. redirect /base/ to /index.php?section=base | |
27511 | - * | |
27512 | + * | |
27513 | */ | |
27514 | - | |
27515 | + | |
27516 | mod_redirect_patch_connection(srv, con, p); | |
27517 | - | |
27518 | + | |
27519 | buffer_copy_string_buffer(p->match_buf, con->request.uri); | |
27520 | - | |
27521 | - for (i = 0; i < p->conf.redirect->used; i++) { | |
27522 | - pcre *match; | |
27523 | - pcre_extra *extra; | |
27524 | - const char *pattern; | |
27525 | - size_t pattern_len; | |
27526 | - int n; | |
27527 | - pcre_keyvalue *kv = p->conf.redirect->kv[i]; | |
27528 | -# define N 10 | |
27529 | - int ovec[N * 3]; | |
27530 | - | |
27531 | - match = kv->key; | |
27532 | - extra = kv->key_extra; | |
27533 | - pattern = kv->value->ptr; | |
27534 | - pattern_len = kv->value->used - 1; | |
27535 | - | |
27536 | - if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) { | |
27537 | - if (n != PCRE_ERROR_NOMATCH) { | |
27538 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
27539 | - "execution error while matching: ", n); | |
27540 | - return HANDLER_ERROR; | |
27541 | - } | |
27542 | - } else { | |
27543 | - const char **list; | |
27544 | - size_t start, end; | |
27545 | - size_t k; | |
27546 | - | |
27547 | - /* it matched */ | |
27548 | - pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list); | |
27549 | - | |
27550 | - /* search for $[0-9] */ | |
27551 | - | |
27552 | - buffer_reset(p->location); | |
27553 | - | |
27554 | - start = 0; end = pattern_len; | |
27555 | - for (k = 0; k < pattern_len; k++) { | |
27556 | - if ((pattern[k] == '$' || pattern[k] == '%') && | |
27557 | - isdigit((unsigned char)pattern[k + 1])) { | |
27558 | - /* got one */ | |
27559 | - | |
27560 | - size_t num = pattern[k + 1] - '0'; | |
27561 | - | |
27562 | - end = k; | |
27563 | - | |
27564 | - buffer_append_string_len(p->location, pattern + start, end - start); | |
27565 | - | |
27566 | - if (pattern[k] == '$') { | |
27567 | - /* n is always > 0 */ | |
27568 | - if (num < (size_t)n) { | |
27569 | - buffer_append_string(p->location, list[num]); | |
27570 | - } | |
27571 | - } else { | |
27572 | - config_append_cond_match_buffer(con, p->conf.context, p->location, num); | |
27573 | - } | |
27574 | - | |
27575 | - k++; | |
27576 | - start = k + 1; | |
27577 | - } | |
27578 | - } | |
27579 | - | |
27580 | - buffer_append_string_len(p->location, pattern + start, pattern_len - start); | |
27581 | - | |
27582 | - pcre_free(list); | |
27583 | - | |
27584 | - response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location)); | |
27585 | - | |
27586 | - con->http_status = 301; | |
27587 | - con->file_finished = 1; | |
27588 | - | |
27589 | - return HANDLER_FINISHED; | |
27590 | - } | |
27591 | + i = config_exec_pcre_keyvalue_buffer(con, p->conf.redirect, p->conf.context, p->match_buf, p->location); | |
27592 | + | |
27593 | + if (i >= 0) { | |
27594 | + response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location)); | |
27595 | + | |
27596 | + con->http_status = 301; | |
27597 | + con->file_finished = 1; | |
27598 | + | |
27599 | + return HANDLER_FINISHED; | |
27600 | + } | |
27601 | + else if (i != PCRE_ERROR_NOMATCH) { | |
27602 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
27603 | + "execution error while matching", i); | |
27604 | } | |
27605 | #undef N | |
27606 | - | |
27607 | + | |
27608 | #else | |
27609 | UNUSED(srv); | |
27610 | UNUSED(con); | |
27611 | UNUSED(p_data); | |
27612 | #endif | |
27613 | - | |
27614 | + | |
27615 | return HANDLER_GO_ON; | |
27616 | } | |
27617 | ||
27618 | @@ -265,13 +207,13 @@ | |
27619 | int mod_redirect_plugin_init(plugin *p) { | |
27620 | p->version = LIGHTTPD_VERSION_ID; | |
27621 | p->name = buffer_init_string("redirect"); | |
27622 | - | |
27623 | + | |
27624 | p->init = mod_redirect_init; | |
27625 | p->handle_uri_clean = mod_redirect_uri_handler; | |
27626 | p->set_defaults = mod_redirect_set_defaults; | |
27627 | p->cleanup = mod_redirect_free; | |
27628 | - | |
27629 | + | |
27630 | p->data = NULL; | |
27631 | - | |
27632 | + | |
27633 | return 0; | |
27634 | } | |
1175ccec | 27635 | --- ../lighttpd-1.4.11/src/mod_rewrite.c 2005-09-29 20:59:10.000000000 +0300 |
36e2a29e | 27636 | +++ lighttpd-1.4.12/src/mod_rewrite.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
27637 | @@ -13,24 +13,8 @@ |
27638 | #endif | |
27639 | ||
27640 | typedef struct { | |
27641 | -#ifdef HAVE_PCRE_H | |
27642 | - pcre *key; | |
27643 | -#endif | |
27644 | - | |
27645 | - buffer *value; | |
27646 | - | |
27647 | - int once; | |
27648 | -} rewrite_rule; | |
27649 | - | |
27650 | -typedef struct { | |
27651 | - rewrite_rule **ptr; | |
27652 | - | |
27653 | - size_t used; | |
27654 | - size_t size; | |
27655 | -} rewrite_rule_buffer; | |
27656 | - | |
27657 | -typedef struct { | |
27658 | - rewrite_rule_buffer *rewrite; | |
27659 | + pcre_keyvalue_buffer *rewrite; | |
27660 | + buffer *once; | |
27661 | data_config *context; /* to which apply me */ | |
27662 | } plugin_config; | |
27663 | ||
27664 | @@ -42,20 +26,20 @@ | |
27665 | typedef struct { | |
27666 | PLUGIN_DATA; | |
27667 | buffer *match_buf; | |
27668 | - | |
27669 | + | |
27670 | plugin_config **config_storage; | |
27671 | - | |
27672 | - plugin_config conf; | |
27673 | + | |
27674 | + plugin_config conf; | |
27675 | } plugin_data; | |
27676 | ||
27677 | static handler_ctx * handler_ctx_init() { | |
27678 | handler_ctx * hctx; | |
27679 | - | |
27680 | + | |
27681 | hctx = calloc(1, sizeof(*hctx)); | |
27682 | - | |
27683 | + | |
27684 | hctx->state = REWRITE_STATE_UNSET; | |
27685 | hctx->loops = 0; | |
27686 | - | |
27687 | + | |
27688 | return hctx; | |
27689 | } | |
27690 | ||
27691 | @@ -63,207 +47,136 @@ | |
27692 | free(hctx); | |
27693 | } | |
27694 | ||
27695 | -rewrite_rule_buffer *rewrite_rule_buffer_init(void) { | |
27696 | - rewrite_rule_buffer *kvb; | |
27697 | - | |
27698 | - kvb = calloc(1, sizeof(*kvb)); | |
27699 | - | |
27700 | - return kvb; | |
27701 | -} | |
27702 | - | |
27703 | -int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) { | |
27704 | -#ifdef HAVE_PCRE_H | |
27705 | - size_t i; | |
27706 | - const char *errptr; | |
27707 | - int erroff; | |
27708 | - | |
27709 | - if (!key) return -1; | |
27710 | - | |
27711 | - if (kvb->size == 0) { | |
27712 | - kvb->size = 4; | |
27713 | - kvb->used = 0; | |
27714 | - | |
27715 | - kvb->ptr = malloc(kvb->size * sizeof(*kvb->ptr)); | |
27716 | - | |
27717 | - for(i = 0; i < kvb->size; i++) { | |
27718 | - kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr)); | |
27719 | - } | |
27720 | - } else if (kvb->used == kvb->size) { | |
27721 | - kvb->size += 4; | |
27722 | - | |
27723 | - kvb->ptr = realloc(kvb->ptr, kvb->size * sizeof(*kvb->ptr)); | |
27724 | - | |
27725 | - for(i = kvb->used; i < kvb->size; i++) { | |
27726 | - kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr)); | |
27727 | - } | |
27728 | - } | |
27729 | - | |
27730 | - if (NULL == (kvb->ptr[kvb->used]->key = pcre_compile(key->ptr, | |
27731 | - 0, &errptr, &erroff, NULL))) { | |
27732 | - | |
27733 | - return -1; | |
27734 | - } | |
27735 | - | |
27736 | - kvb->ptr[kvb->used]->value = buffer_init(); | |
27737 | - buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value); | |
27738 | - kvb->ptr[kvb->used]->once = once; | |
27739 | - | |
27740 | - kvb->used++; | |
27741 | - | |
27742 | - return 0; | |
27743 | -#else | |
27744 | - UNUSED(kvb); | |
27745 | - UNUSED(value); | |
27746 | - UNUSED(once); | |
27747 | - UNUSED(key); | |
27748 | - | |
27749 | - return -1; | |
27750 | -#endif | |
27751 | -} | |
27752 | - | |
27753 | -void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) { | |
27754 | -#ifdef HAVE_PCRE_H | |
27755 | - size_t i; | |
27756 | - | |
27757 | - for (i = 0; i < kvb->size; i++) { | |
27758 | - if (kvb->ptr[i]->key) pcre_free(kvb->ptr[i]->key); | |
27759 | - if (kvb->ptr[i]->value) buffer_free(kvb->ptr[i]->value); | |
27760 | - free(kvb->ptr[i]); | |
27761 | - } | |
27762 | - | |
27763 | - if (kvb->ptr) free(kvb->ptr); | |
27764 | -#endif | |
27765 | - | |
27766 | - free(kvb); | |
27767 | -} | |
27768 | - | |
27769 | ||
27770 | INIT_FUNC(mod_rewrite_init) { | |
27771 | plugin_data *p; | |
27772 | - | |
27773 | + | |
27774 | p = calloc(1, sizeof(*p)); | |
27775 | - | |
27776 | + | |
27777 | p->match_buf = buffer_init(); | |
27778 | - | |
27779 | + | |
27780 | return p; | |
27781 | } | |
27782 | ||
27783 | FREE_FUNC(mod_rewrite_free) { | |
27784 | plugin_data *p = p_d; | |
27785 | - | |
27786 | + | |
27787 | UNUSED(srv); | |
27788 | ||
27789 | if (!p) return HANDLER_GO_ON; | |
27790 | - | |
27791 | + | |
27792 | buffer_free(p->match_buf); | |
27793 | if (p->config_storage) { | |
27794 | size_t i; | |
27795 | for (i = 0; i < srv->config_context->used; i++) { | |
27796 | plugin_config *s = p->config_storage[i]; | |
27797 | - rewrite_rule_buffer_free(s->rewrite); | |
27798 | - | |
27799 | + pcre_keyvalue_buffer_free(s->rewrite); | |
27800 | + buffer_free(s->once); | |
27801 | + | |
27802 | free(s); | |
27803 | } | |
27804 | free(p->config_storage); | |
27805 | } | |
27806 | - | |
27807 | + | |
27808 | free(p); | |
27809 | - | |
27810 | + | |
27811 | return HANDLER_GO_ON; | |
27812 | } | |
27813 | ||
27814 | static int parse_config_entry(server *srv, plugin_config *s, array *ca, const char *option, int once) { | |
27815 | data_unset *du; | |
27816 | - | |
27817 | + | |
27818 | if (NULL != (du = array_get_element(ca, option))) { | |
27819 | data_array *da = (data_array *)du; | |
27820 | size_t j; | |
27821 | - | |
27822 | + | |
27823 | if (du->type != TYPE_ARRAY) { | |
27824 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
27825 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
27826 | "unexpected type for key: ", option, "array of strings"); | |
27827 | - | |
27828 | + | |
27829 | return HANDLER_ERROR; | |
27830 | } | |
27831 | - | |
27832 | + | |
27833 | da = (data_array *)du; | |
27834 | - | |
27835 | + | |
27836 | for (j = 0; j < da->value->used; j++) { | |
27837 | if (da->value->data[j]->type != TYPE_STRING) { | |
27838 | - log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
27839 | - "unexpected type for key: ", | |
27840 | - option, | |
27841 | + log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
27842 | + "unexpected type for key: ", | |
27843 | + option, | |
27844 | "[", da->value->data[j]->key, "](string)"); | |
27845 | - | |
27846 | + | |
27847 | return HANDLER_ERROR; | |
27848 | } | |
27849 | - | |
27850 | - if (0 != rewrite_rule_buffer_append(s->rewrite, | |
27851 | - ((data_string *)(da->value->data[j]))->key, | |
27852 | - ((data_string *)(da->value->data[j]))->value, | |
27853 | - once)) { | |
27854 | + | |
27855 | + if (0 != pcre_keyvalue_buffer_append(s->rewrite, | |
27856 | + ((data_string *)(da->value->data[j]))->key->ptr, | |
27857 | + ((data_string *)(da->value->data[j]))->value->ptr)) { | |
27858 | #ifdef HAVE_PCRE_H | |
27859 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
27860 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
27861 | "pcre-compile failed for", da->value->data[j]->key); | |
27862 | #else | |
27863 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
27864 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
27865 | "pcre support is missing, please install libpcre and the headers"); | |
27866 | #endif | |
27867 | } | |
27868 | + | |
27869 | + if (once) { | |
27870 | + buffer_append_string_len(s->once, CONST_STR_LEN("1")); | |
27871 | + } else { | |
27872 | + buffer_append_string_len(s->once, CONST_STR_LEN("0")); | |
27873 | + } | |
27874 | } | |
27875 | } | |
27876 | - | |
27877 | + | |
27878 | return 0; | |
27879 | } | |
27880 | ||
27881 | SETDEFAULTS_FUNC(mod_rewrite_set_defaults) { | |
27882 | plugin_data *p = p_d; | |
27883 | size_t i = 0; | |
27884 | - | |
27885 | - config_values_t cv[] = { | |
27886 | + | |
27887 | + config_values_t cv[] = { | |
27888 | { "url.rewrite-repeat", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
27889 | { "url.rewrite-once", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
27890 | - | |
27891 | - /* old names, still supported | |
27892 | - * | |
27893 | + | |
27894 | + /* old names, still supported | |
27895 | + * | |
27896 | * url.rewrite remapped to url.rewrite-once | |
27897 | * url.rewrite-final is url.rewrite-once | |
27898 | - * | |
27899 | + * | |
27900 | */ | |
27901 | { "url.rewrite", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
27902 | { "url.rewrite-final", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ | |
27903 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
27904 | }; | |
27905 | - | |
27906 | + | |
27907 | if (!p) return HANDLER_ERROR; | |
27908 | - | |
27909 | + | |
27910 | /* 0 */ | |
27911 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
27912 | - | |
27913 | + | |
27914 | for (i = 0; i < srv->config_context->used; i++) { | |
27915 | plugin_config *s; | |
27916 | array *ca; | |
27917 | - | |
27918 | + | |
27919 | s = calloc(1, sizeof(plugin_config)); | |
27920 | - s->rewrite = rewrite_rule_buffer_init(); | |
27921 | - | |
27922 | - cv[0].destination = s->rewrite; | |
27923 | - cv[1].destination = s->rewrite; | |
27924 | - cv[2].destination = s->rewrite; | |
27925 | - | |
27926 | + s->rewrite = pcre_keyvalue_buffer_init(); | |
27927 | + s->once = buffer_init(); | |
27928 | + | |
27929 | p->config_storage[i] = s; | |
27930 | ca = ((data_config *)srv->config_context->data[i])->value; | |
27931 | - | |
27932 | + | |
27933 | if (0 != config_insert_values_global(srv, ca, cv)) { | |
27934 | return HANDLER_ERROR; | |
27935 | } | |
27936 | - | |
27937 | + | |
27938 | parse_config_entry(srv, s, ca, "url.rewrite-once", 1); | |
27939 | parse_config_entry(srv, s, ca, "url.rewrite-final", 1); | |
27940 | parse_config_entry(srv, s, ca, "url.rewrite", 1); | |
27941 | parse_config_entry(srv, s, ca, "url.rewrite-repeat", 0); | |
27942 | } | |
27943 | - | |
27944 | + | |
27945 | return HANDLER_GO_ON; | |
27946 | } | |
27947 | #ifdef HAVE_PCRE_H | |
27948 | @@ -271,157 +184,107 @@ | |
27949 | size_t i, j; | |
27950 | plugin_config *s = p->config_storage[0]; | |
27951 | p->conf.rewrite = s->rewrite; | |
27952 | - | |
27953 | + p->conf.once = s->once; | |
27954 | + | |
27955 | /* skip the first, the global context */ | |
27956 | for (i = 1; i < srv->config_context->used; i++) { | |
27957 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
27958 | s = p->config_storage[i]; | |
27959 | - | |
27960 | + | |
27961 | if (COMP_HTTP_URL == dc->comp) continue; | |
27962 | - | |
27963 | + | |
27964 | /* condition didn't match */ | |
27965 | if (!config_check_cond(srv, con, dc)) continue; | |
27966 | - | |
27967 | + | |
27968 | /* merge config */ | |
27969 | for (j = 0; j < dc->value->used; j++) { | |
27970 | data_unset *du = dc->value->data[j]; | |
27971 | - | |
27972 | + | |
27973 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite"))) { | |
27974 | p->conf.rewrite = s->rewrite; | |
27975 | + p->conf.once = s->once; | |
27976 | p->conf.context = dc; | |
27977 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-once"))) { | |
27978 | p->conf.rewrite = s->rewrite; | |
27979 | + p->conf.once = s->once; | |
27980 | p->conf.context = dc; | |
27981 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-repeat"))) { | |
27982 | p->conf.rewrite = s->rewrite; | |
27983 | + p->conf.once = s->once; | |
27984 | p->conf.context = dc; | |
27985 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-final"))) { | |
27986 | p->conf.rewrite = s->rewrite; | |
27987 | + p->conf.once = s->once; | |
27988 | p->conf.context = dc; | |
27989 | } | |
27990 | } | |
27991 | } | |
27992 | - | |
27993 | + | |
27994 | return 0; | |
27995 | } | |
27996 | #endif | |
27997 | URIHANDLER_FUNC(mod_rewrite_con_reset) { | |
27998 | plugin_data *p = p_d; | |
27999 | - | |
28000 | + | |
28001 | UNUSED(srv); | |
28002 | - | |
28003 | + | |
28004 | if (con->plugin_ctx[p->id]) { | |
28005 | handler_ctx_free(con->plugin_ctx[p->id]); | |
28006 | con->plugin_ctx[p->id] = NULL; | |
28007 | } | |
28008 | - | |
28009 | + | |
28010 | return HANDLER_GO_ON; | |
28011 | } | |
28012 | ||
28013 | URIHANDLER_FUNC(mod_rewrite_uri_handler) { | |
28014 | #ifdef HAVE_PCRE_H | |
28015 | plugin_data *p = p_d; | |
28016 | - size_t i; | |
28017 | + int i; | |
28018 | handler_ctx *hctx; | |
28019 | ||
28020 | - /* | |
28021 | + /* | |
28022 | * REWRITE URL | |
28023 | - * | |
28024 | + * | |
28025 | * e.g. rewrite /base/ to /index.php?section=base | |
28026 | - * | |
28027 | + * | |
28028 | */ | |
28029 | - | |
28030 | + | |
28031 | if (con->plugin_ctx[p->id]) { | |
28032 | hctx = con->plugin_ctx[p->id]; | |
28033 | - | |
28034 | + | |
28035 | if (hctx->loops++ > 100) { | |
28036 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
28037 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
28038 | "ENDLESS LOOP IN rewrite-rule DETECTED ... aborting request, perhaps you want to use url.rewrite-once instead of url.rewrite-repeat"); | |
28039 | - | |
28040 | + | |
28041 | return HANDLER_ERROR; | |
28042 | } | |
28043 | - | |
28044 | + | |
28045 | if (hctx->state == REWRITE_STATE_FINISHED) return HANDLER_GO_ON; | |
28046 | } | |
28047 | - | |
28048 | + | |
28049 | mod_rewrite_patch_connection(srv, con, p); | |
28050 | ||
28051 | if (!p->conf.rewrite) return HANDLER_GO_ON; | |
28052 | - | |
28053 | + | |
28054 | buffer_copy_string_buffer(p->match_buf, con->request.uri); | |
28055 | - | |
28056 | - for (i = 0; i < p->conf.rewrite->used; i++) { | |
28057 | - pcre *match; | |
28058 | - const char *pattern; | |
28059 | - size_t pattern_len; | |
28060 | - int n; | |
28061 | - rewrite_rule *rule = p->conf.rewrite->ptr[i]; | |
28062 | -# define N 10 | |
28063 | - int ovec[N * 3]; | |
28064 | - | |
28065 | - match = rule->key; | |
28066 | - pattern = rule->value->ptr; | |
28067 | - pattern_len = rule->value->used - 1; | |
28068 | - | |
28069 | - if ((n = pcre_exec(match, NULL, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) { | |
28070 | - if (n != PCRE_ERROR_NOMATCH) { | |
28071 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
28072 | - "execution error while matching: ", n); | |
28073 | - return HANDLER_ERROR; | |
28074 | - } | |
28075 | - } else { | |
28076 | - const char **list; | |
28077 | - size_t start, end; | |
28078 | - size_t k; | |
28079 | - | |
28080 | - /* it matched */ | |
28081 | - pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list); | |
28082 | - | |
28083 | - /* search for $[0-9] */ | |
28084 | - | |
28085 | - buffer_reset(con->request.uri); | |
28086 | - | |
28087 | - start = 0; end = pattern_len; | |
28088 | - for (k = 0; k < pattern_len; k++) { | |
28089 | - if ((pattern[k] == '$' || pattern[k] == '%') && | |
28090 | - isdigit((unsigned char)pattern[k + 1])) { | |
28091 | - /* got one */ | |
28092 | - | |
28093 | - size_t num = pattern[k + 1] - '0'; | |
28094 | - | |
28095 | - end = k; | |
28096 | - | |
28097 | - buffer_append_string_len(con->request.uri, pattern + start, end - start); | |
28098 | - | |
28099 | - if (pattern[k] == '$') { | |
28100 | - /* n is always > 0 */ | |
28101 | - if (num < (size_t)n) { | |
28102 | - buffer_append_string(con->request.uri, list[num]); | |
28103 | - } | |
28104 | - } else { | |
28105 | - config_append_cond_match_buffer(con, p->conf.context, con->request.uri, num); | |
28106 | - } | |
28107 | - | |
28108 | - k++; | |
28109 | - start = k + 1; | |
28110 | - } | |
28111 | - } | |
28112 | - | |
28113 | - buffer_append_string_len(con->request.uri, pattern + start, pattern_len - start); | |
28114 | - | |
28115 | - pcre_free(list); | |
28116 | - | |
28117 | - hctx = handler_ctx_init(); | |
28118 | - | |
28119 | - con->plugin_ctx[p->id] = hctx; | |
28120 | - | |
28121 | - if (rule->once) hctx->state = REWRITE_STATE_FINISHED; | |
28122 | - | |
28123 | - return HANDLER_COMEBACK; | |
28124 | - } | |
28125 | + i = config_exec_pcre_keyvalue_buffer(con, p->conf.rewrite, p->conf.context, p->match_buf, con->request.uri); | |
28126 | + | |
28127 | + if (i >= 0) { | |
28128 | + hctx = handler_ctx_init(); | |
28129 | + | |
28130 | + con->plugin_ctx[p->id] = hctx; | |
28131 | + | |
28132 | + if (p->conf.once->ptr[i] == '1') | |
28133 | + hctx->state = REWRITE_STATE_FINISHED; | |
28134 | + | |
28135 | + return HANDLER_COMEBACK; | |
28136 | + } | |
28137 | + else if (i != PCRE_ERROR_NOMATCH) { | |
28138 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
28139 | + "execution error while matching", i); | |
28140 | } | |
28141 | #undef N | |
28142 | - | |
28143 | + | |
28144 | #else | |
28145 | UNUSED(srv); | |
28146 | UNUSED(con); | |
28147 | @@ -434,17 +297,17 @@ | |
28148 | int mod_rewrite_plugin_init(plugin *p) { | |
28149 | p->version = LIGHTTPD_VERSION_ID; | |
28150 | p->name = buffer_init_string("rewrite"); | |
28151 | - | |
28152 | + | |
28153 | p->init = mod_rewrite_init; | |
28154 | /* it has to stay _raw as we are matching on uri + querystring | |
28155 | */ | |
28156 | - | |
28157 | + | |
28158 | p->handle_uri_raw = mod_rewrite_uri_handler; | |
28159 | p->set_defaults = mod_rewrite_set_defaults; | |
28160 | p->cleanup = mod_rewrite_free; | |
28161 | p->connection_reset = mod_rewrite_con_reset; | |
28162 | - | |
28163 | + | |
28164 | p->data = NULL; | |
28165 | - | |
28166 | + | |
28167 | return 0; | |
28168 | } | |
1175ccec | 28169 | --- ../lighttpd-1.4.11/src/mod_rrdtool.c 2005-08-22 01:52:24.000000000 +0300 |
36e2a29e | 28170 | +++ lighttpd-1.4.12/src/mod_rrdtool.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
28171 | @@ -5,7 +5,6 @@ |
28172 | #include <stdlib.h> | |
28173 | #include <stdio.h> | |
28174 | #include <string.h> | |
28175 | -#include <unistd.h> | |
28176 | #include <errno.h> | |
28177 | #include <time.h> | |
28178 | ||
28179 | @@ -20,10 +19,14 @@ | |
28180 | /* no need for waitpid if we don't have fork */ | |
28181 | #include <sys/wait.h> | |
28182 | #endif | |
28183 | + | |
28184 | +#include "sys-files.h" | |
28185 | +#include "sys-process.h" | |
28186 | + | |
28187 | typedef struct { | |
28188 | buffer *path_rrdtool_bin; | |
28189 | buffer *path_rrd; | |
28190 | - | |
28191 | + | |
28192 | double requests, *requests_ptr; | |
28193 | double bytes_written, *bytes_written_ptr; | |
28194 | double bytes_read, *bytes_read_ptr; | |
28195 | @@ -31,84 +34,84 @@ | |
28196 | ||
28197 | typedef struct { | |
28198 | PLUGIN_DATA; | |
28199 | - | |
28200 | + | |
28201 | buffer *cmd; | |
28202 | buffer *resp; | |
28203 | - | |
28204 | + | |
28205 | int read_fd, write_fd; | |
28206 | pid_t rrdtool_pid; | |
28207 | - | |
28208 | + | |
28209 | int rrdtool_running; | |
28210 | - | |
28211 | + | |
28212 | plugin_config **config_storage; | |
28213 | plugin_config conf; | |
28214 | } plugin_data; | |
28215 | ||
28216 | INIT_FUNC(mod_rrd_init) { | |
28217 | plugin_data *p; | |
28218 | - | |
28219 | + | |
28220 | p = calloc(1, sizeof(*p)); | |
28221 | - | |
28222 | + | |
28223 | p->resp = buffer_init(); | |
28224 | p->cmd = buffer_init(); | |
28225 | - | |
28226 | + | |
28227 | return p; | |
28228 | } | |
28229 | ||
28230 | FREE_FUNC(mod_rrd_free) { | |
28231 | plugin_data *p = p_d; | |
28232 | size_t i; | |
28233 | - | |
28234 | + | |
28235 | if (!p) return HANDLER_GO_ON; | |
28236 | - | |
28237 | + | |
28238 | if (p->config_storage) { | |
28239 | for (i = 0; i < srv->config_context->used; i++) { | |
28240 | plugin_config *s = p->config_storage[i]; | |
28241 | - | |
28242 | + | |
28243 | buffer_free(s->path_rrdtool_bin); | |
28244 | buffer_free(s->path_rrd); | |
28245 | - | |
28246 | + | |
28247 | free(s); | |
28248 | } | |
28249 | } | |
28250 | buffer_free(p->cmd); | |
28251 | buffer_free(p->resp); | |
28252 | - | |
28253 | + | |
28254 | free(p->config_storage); | |
28255 | - | |
28256 | + | |
28257 | if (p->rrdtool_pid) { | |
28258 | int status; | |
28259 | close(p->read_fd); | |
28260 | close(p->write_fd); | |
28261 | -#ifdef HAVE_FORK | |
28262 | +#ifdef HAVE_FORK | |
28263 | /* collect status */ | |
28264 | waitpid(p->rrdtool_pid, &status, 0); | |
28265 | #endif | |
28266 | } | |
28267 | - | |
28268 | + | |
28269 | free(p); | |
28270 | - | |
28271 | + | |
28272 | return HANDLER_GO_ON; | |
28273 | } | |
28274 | ||
28275 | int mod_rrd_create_pipe(server *srv, plugin_data *p) { | |
28276 | pid_t pid; | |
28277 | - | |
28278 | + | |
28279 | int to_rrdtool_fds[2]; | |
28280 | int from_rrdtool_fds[2]; | |
28281 | -#ifdef HAVE_FORK | |
28282 | +#ifdef HAVE_FORK | |
28283 | if (pipe(to_rrdtool_fds)) { | |
28284 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
28285 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
28286 | "pipe failed: ", strerror(errno)); | |
28287 | return -1; | |
28288 | } | |
28289 | - | |
28290 | + | |
28291 | if (pipe(from_rrdtool_fds)) { | |
28292 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
28293 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
28294 | "pipe failed: ", strerror(errno)); | |
28295 | return -1; | |
28296 | } | |
28297 | - | |
28298 | + | |
28299 | /* fork, execve */ | |
28300 | switch (pid = fork()) { | |
28301 | case 0: { | |
28302 | @@ -117,33 +120,33 @@ | |
28303 | int argc; | |
28304 | int i = 0; | |
28305 | char *dash = "-"; | |
28306 | - | |
28307 | + | |
28308 | /* move stdout to from_rrdtool_fd[1] */ | |
28309 | close(STDOUT_FILENO); | |
28310 | dup2(from_rrdtool_fds[1], STDOUT_FILENO); | |
28311 | close(from_rrdtool_fds[1]); | |
28312 | /* not needed */ | |
28313 | close(from_rrdtool_fds[0]); | |
28314 | - | |
28315 | + | |
28316 | /* move the stdin to to_rrdtool_fd[0] */ | |
28317 | close(STDIN_FILENO); | |
28318 | dup2(to_rrdtool_fds[0], STDIN_FILENO); | |
28319 | close(to_rrdtool_fds[0]); | |
28320 | /* not needed */ | |
28321 | close(to_rrdtool_fds[1]); | |
28322 | - | |
28323 | + | |
28324 | close(STDERR_FILENO); | |
28325 | - | |
28326 | + | |
28327 | if (srv->errorlog_mode == ERRORLOG_FILE) { | |
28328 | dup2(srv->errorlog_fd, STDERR_FILENO); | |
28329 | close(srv->errorlog_fd); | |
28330 | } | |
28331 | - | |
28332 | + | |
28333 | /* set up args */ | |
28334 | argc = 3; | |
28335 | args = malloc(sizeof(*args) * argc); | |
28336 | i = 0; | |
28337 | - | |
28338 | + | |
28339 | args[i++] = p->conf.path_rrdtool_bin->ptr; | |
28340 | args[i++] = dash; | |
28341 | args[i++] = NULL; | |
28342 | @@ -152,12 +155,12 @@ | |
28343 | for (i = 3; i < 256; i++) { | |
28344 | close(i); | |
28345 | } | |
28346 | - | |
28347 | + | |
28348 | /* exec the cgi */ | |
28349 | execv(args[0], args); | |
28350 | - | |
28351 | + | |
28352 | log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]); | |
28353 | - | |
28354 | + | |
28355 | /* */ | |
28356 | SEGFAULT(); | |
28357 | break; | |
28358 | @@ -168,19 +171,19 @@ | |
28359 | break; | |
28360 | default: { | |
28361 | /* father */ | |
28362 | - | |
28363 | + | |
28364 | close(from_rrdtool_fds[1]); | |
28365 | close(to_rrdtool_fds[0]); | |
28366 | - | |
28367 | + | |
28368 | /* register PID and wait for them asyncronously */ | |
28369 | p->write_fd = to_rrdtool_fds[1]; | |
28370 | p->read_fd = from_rrdtool_fds[0]; | |
28371 | p->rrdtool_pid = pid; | |
28372 | - | |
28373 | + | |
28374 | break; | |
28375 | } | |
28376 | } | |
28377 | - | |
28378 | + | |
28379 | return 0; | |
28380 | #else | |
28381 | return -1; | |
28382 | @@ -189,19 +192,19 @@ | |
28383 | ||
28384 | static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) { | |
28385 | struct stat st; | |
28386 | - | |
28387 | + | |
28388 | /* check if DB already exists */ | |
28389 | if (0 == stat(s->path_rrd->ptr, &st)) { | |
28390 | /* check if it is plain file */ | |
28391 | if (!S_ISREG(st.st_mode)) { | |
28392 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
28393 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
28394 | "not a regular file:", s->path_rrd); | |
28395 | return HANDLER_ERROR; | |
28396 | } | |
28397 | } else { | |
28398 | int r ; | |
28399 | /* create a new one */ | |
28400 | - | |
28401 | + | |
28402 | BUFFER_COPY_STRING_CONST(p->cmd, "create "); | |
28403 | buffer_append_string_buffer(p->cmd, s->path_rrd); | |
28404 | buffer_append_string(p->cmd, " --step 60 "); | |
28405 | @@ -220,158 +223,155 @@ | |
28406 | buffer_append_string(p->cmd, "RRA:MIN:0.5:6:700 "); | |
28407 | buffer_append_string(p->cmd, "RRA:MIN:0.5:24:775 "); | |
28408 | buffer_append_string(p->cmd, "RRA:MIN:0.5:288:797\n"); | |
28409 | - | |
28410 | + | |
28411 | if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) { | |
28412 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
28413 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
28414 | "rrdtool-write: failed", strerror(errno)); | |
28415 | - | |
28416 | + | |
28417 | return HANDLER_ERROR; | |
28418 | } | |
28419 | - | |
28420 | + | |
28421 | buffer_prepare_copy(p->resp, 4096); | |
28422 | if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) { | |
28423 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
28424 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
28425 | "rrdtool-read: failed", strerror(errno)); | |
28426 | - | |
28427 | + | |
28428 | return HANDLER_ERROR; | |
28429 | } | |
28430 | - | |
28431 | + | |
28432 | p->resp->used = r; | |
28433 | - | |
28434 | + | |
28435 | if (p->resp->ptr[0] != 'O' || | |
28436 | p->resp->ptr[1] != 'K') { | |
28437 | - log_error_write(srv, __FILE__, __LINE__, "sbb", | |
28438 | + log_error_write(srv, __FILE__, __LINE__, "sbb", | |
28439 | "rrdtool-response:", p->cmd, p->resp); | |
28440 | - | |
28441 | + | |
28442 | return HANDLER_ERROR; | |
28443 | } | |
28444 | } | |
28445 | - | |
28446 | + | |
28447 | return HANDLER_GO_ON; | |
28448 | } | |
28449 | ||
28450 | -#define PATCH(x) \ | |
28451 | - p->conf.x = s->x; | |
28452 | static int mod_rrd_patch_connection(server *srv, connection *con, plugin_data *p) { | |
28453 | size_t i, j; | |
28454 | plugin_config *s = p->config_storage[0]; | |
28455 | - | |
28456 | - PATCH(path_rrdtool_bin); | |
28457 | - PATCH(path_rrd); | |
28458 | - | |
28459 | + | |
28460 | + PATCH_OPTION(path_rrdtool_bin); | |
28461 | + PATCH_OPTION(path_rrd); | |
28462 | + | |
28463 | p->conf.bytes_written_ptr = &(s->bytes_written); | |
28464 | p->conf.bytes_read_ptr = &(s->bytes_read); | |
28465 | p->conf.requests_ptr = &(s->requests); | |
28466 | - | |
28467 | + | |
28468 | /* skip the first, the global context */ | |
28469 | for (i = 1; i < srv->config_context->used; i++) { | |
28470 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
28471 | s = p->config_storage[i]; | |
28472 | - | |
28473 | + | |
28474 | /* condition didn't match */ | |
28475 | if (!config_check_cond(srv, con, dc)) continue; | |
28476 | - | |
28477 | + | |
28478 | /* merge config */ | |
28479 | for (j = 0; j < dc->value->used; j++) { | |
28480 | data_unset *du = dc->value->data[j]; | |
28481 | - | |
28482 | + | |
28483 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("rrdtool.db-name"))) { | |
28484 | - PATCH(path_rrd); | |
28485 | + PATCH_OPTION(path_rrd); | |
28486 | /* get pointers to double values */ | |
28487 | - | |
28488 | + | |
28489 | p->conf.bytes_written_ptr = &(s->bytes_written); | |
28490 | p->conf.bytes_read_ptr = &(s->bytes_read); | |
28491 | p->conf.requests_ptr = &(s->requests); | |
28492 | } | |
28493 | } | |
28494 | } | |
28495 | - | |
28496 | + | |
28497 | return 0; | |
28498 | } | |
28499 | -#undef PATCH | |
28500 | ||
28501 | SETDEFAULTS_FUNC(mod_rrd_set_defaults) { | |
28502 | plugin_data *p = p_d; | |
28503 | size_t i; | |
28504 | - | |
28505 | - config_values_t cv[] = { | |
28506 | + | |
28507 | + config_values_t cv[] = { | |
28508 | { "rrdtool.binary", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, | |
28509 | { "rrdtool.db-name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
28510 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
28511 | }; | |
28512 | - | |
28513 | + | |
28514 | if (!p) return HANDLER_ERROR; | |
28515 | - | |
28516 | + | |
28517 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
28518 | - | |
28519 | + | |
28520 | for (i = 0; i < srv->config_context->used; i++) { | |
28521 | plugin_config *s; | |
28522 | - | |
28523 | + | |
28524 | s = calloc(1, sizeof(plugin_config)); | |
28525 | s->path_rrdtool_bin = buffer_init(); | |
28526 | s->path_rrd = buffer_init(); | |
28527 | s->requests = 0; | |
28528 | s->bytes_written = 0; | |
28529 | s->bytes_read = 0; | |
28530 | - | |
28531 | + | |
28532 | cv[0].destination = s->path_rrdtool_bin; | |
28533 | cv[1].destination = s->path_rrd; | |
28534 | - | |
28535 | + | |
28536 | p->config_storage[i] = s; | |
28537 | - | |
28538 | + | |
28539 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
28540 | return HANDLER_ERROR; | |
28541 | } | |
28542 | - | |
28543 | + | |
28544 | if (i > 0 && !buffer_is_empty(s->path_rrdtool_bin)) { | |
28545 | /* path_rrdtool_bin is a global option */ | |
28546 | - | |
28547 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
28548 | + | |
28549 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
28550 | "rrdtool.binary can only be set as a global option."); | |
28551 | - | |
28552 | + | |
28553 | return HANDLER_ERROR; | |
28554 | } | |
28555 | - | |
28556 | + | |
28557 | } | |
28558 | - | |
28559 | + | |
28560 | p->conf.path_rrdtool_bin = p->config_storage[0]->path_rrdtool_bin; | |
28561 | p->rrdtool_running = 0; | |
28562 | - | |
28563 | + | |
28564 | /* check for dir */ | |
28565 | - | |
28566 | + | |
28567 | if (buffer_is_empty(p->conf.path_rrdtool_bin)) { | |
28568 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
28569 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
28570 | "rrdtool.binary has to be set"); | |
28571 | return HANDLER_ERROR; | |
28572 | } | |
28573 | - | |
28574 | + | |
28575 | /* open the pipe to rrdtool */ | |
28576 | if (mod_rrd_create_pipe(srv, p)) { | |
28577 | return HANDLER_ERROR; | |
28578 | } | |
28579 | - | |
28580 | + | |
28581 | p->rrdtool_running = 1; | |
28582 | - | |
28583 | + | |
28584 | return HANDLER_GO_ON; | |
28585 | } | |
28586 | ||
28587 | TRIGGER_FUNC(mod_rrd_trigger) { | |
28588 | plugin_data *p = p_d; | |
28589 | size_t i; | |
28590 | - | |
28591 | + | |
28592 | if (!p->rrdtool_running) return HANDLER_GO_ON; | |
28593 | if ((srv->cur_ts % 60) != 0) return HANDLER_GO_ON; | |
28594 | - | |
28595 | + | |
28596 | for (i = 0; i < srv->config_context->used; i++) { | |
28597 | plugin_config *s = p->config_storage[i]; | |
28598 | int r; | |
28599 | - | |
28600 | + | |
28601 | if (buffer_is_empty(s->path_rrd)) continue; | |
28602 | - | |
28603 | + | |
28604 | /* write the data down every minute */ | |
28605 | - | |
28606 | + | |
28607 | if (HANDLER_GO_ON != mod_rrdtool_create_rrd(srv, p, s)) return HANDLER_ERROR; | |
28608 | - | |
28609 | + | |
28610 | BUFFER_COPY_STRING_CONST(p->cmd, "update "); | |
28611 | buffer_append_string_buffer(p->cmd, s->path_rrd); | |
28612 | BUFFER_APPEND_STRING_CONST(p->cmd, " N:"); | |
28613 | @@ -381,69 +381,69 @@ | |
28614 | BUFFER_APPEND_STRING_CONST(p->cmd, ":"); | |
28615 | buffer_append_long(p->cmd, s->requests); | |
28616 | BUFFER_APPEND_STRING_CONST(p->cmd, "\n"); | |
28617 | - | |
28618 | + | |
28619 | if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) { | |
28620 | p->rrdtool_running = 0; | |
28621 | - | |
28622 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
28623 | + | |
28624 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
28625 | "rrdtool-write: failed", strerror(errno)); | |
28626 | - | |
28627 | + | |
28628 | return HANDLER_ERROR; | |
28629 | } | |
28630 | - | |
28631 | + | |
28632 | buffer_prepare_copy(p->resp, 4096); | |
28633 | if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) { | |
28634 | p->rrdtool_running = 0; | |
28635 | - | |
28636 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
28637 | + | |
28638 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
28639 | "rrdtool-read: failed", strerror(errno)); | |
28640 | - | |
28641 | + | |
28642 | return HANDLER_ERROR; | |
28643 | } | |
28644 | - | |
28645 | + | |
28646 | p->resp->used = r; | |
28647 | - | |
28648 | + | |
28649 | if (p->resp->ptr[0] != 'O' || | |
28650 | p->resp->ptr[1] != 'K') { | |
28651 | p->rrdtool_running = 0; | |
28652 | - | |
28653 | - log_error_write(srv, __FILE__, __LINE__, "sbb", | |
28654 | + | |
28655 | + log_error_write(srv, __FILE__, __LINE__, "sbb", | |
28656 | "rrdtool-response:", p->cmd, p->resp); | |
28657 | - | |
28658 | + | |
28659 | return HANDLER_ERROR; | |
28660 | } | |
28661 | s->requests = 0; | |
28662 | s->bytes_written = 0; | |
28663 | s->bytes_read = 0; | |
28664 | } | |
28665 | - | |
28666 | + | |
28667 | return HANDLER_GO_ON; | |
28668 | } | |
28669 | ||
28670 | REQUESTDONE_FUNC(mod_rrd_account) { | |
28671 | plugin_data *p = p_d; | |
28672 | - | |
28673 | + | |
28674 | mod_rrd_patch_connection(srv, con, p); | |
28675 | - | |
28676 | + | |
28677 | *(p->conf.requests_ptr) += 1; | |
28678 | *(p->conf.bytes_written_ptr) += con->bytes_written; | |
28679 | *(p->conf.bytes_read_ptr) += con->bytes_read; | |
28680 | - | |
28681 | + | |
28682 | return HANDLER_GO_ON; | |
28683 | } | |
28684 | ||
28685 | int mod_rrdtool_plugin_init(plugin *p) { | |
28686 | p->version = LIGHTTPD_VERSION_ID; | |
28687 | p->name = buffer_init_string("rrd"); | |
28688 | - | |
28689 | + | |
28690 | p->init = mod_rrd_init; | |
28691 | p->cleanup = mod_rrd_free; | |
28692 | p->set_defaults= mod_rrd_set_defaults; | |
28693 | - | |
28694 | + | |
28695 | p->handle_trigger = mod_rrd_trigger; | |
28696 | p->handle_request_done = mod_rrd_account; | |
28697 | - | |
28698 | + | |
28699 | p->data = NULL; | |
28700 | - | |
28701 | + | |
28702 | return 0; | |
28703 | } | |
1175ccec | 28704 | --- ../lighttpd-1.4.11/src/mod_scgi.c 2006-03-04 17:15:26.000000000 +0200 |
36e2a29e | 28705 | +++ lighttpd-1.4.12/src/mod_scgi.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
28706 | @@ -1,5 +1,4 @@ |
28707 | #include <sys/types.h> | |
28708 | -#include <unistd.h> | |
28709 | #include <errno.h> | |
28710 | #include <fcntl.h> | |
28711 | #include <string.h> | |
28712 | @@ -30,7 +29,9 @@ | |
28713 | #endif | |
28714 | ||
28715 | #include "sys-socket.h" | |
28716 | - | |
28717 | +#include "sys-files.h" | |
28718 | +#include "sys-strings.h" | |
28719 | +#include "sys-process.h" | |
28720 | ||
28721 | #ifndef UNIX_PATH_MAX | |
28722 | # define UNIX_PATH_MAX 108 | |
28723 | @@ -46,30 +47,29 @@ | |
28724 | enum {EOL_UNSET, EOL_N, EOL_RN}; | |
28725 | ||
28726 | /* | |
28727 | - * | |
28728 | + * | |
28729 | * TODO: | |
28730 | - * | |
28731 | + * | |
28732 | * - add timeout for a connect to a non-scgi process | |
28733 | * (use state_timestamp + state) | |
28734 | - * | |
28735 | + * | |
28736 | */ | |
28737 | ||
28738 | typedef struct scgi_proc { | |
28739 | size_t id; /* id will be between 1 and max_procs */ | |
28740 | buffer *socket; /* config.socket + "-" + id */ | |
28741 | unsigned port; /* config.port + pno */ | |
28742 | - | |
28743 | - pid_t pid; /* PID of the spawned process (0 if not spawned locally) */ | |
28744 | ||
28745 | + pid_t pid; /* PID of the spawned process (0 if not spawned locally) */ | |
28746 | ||
28747 | size_t load; /* number of requests waiting on this process */ | |
28748 | ||
28749 | time_t last_used; /* see idle_timeout */ | |
28750 | size_t requests; /* see max_requests */ | |
28751 | struct scgi_proc *prev, *next; /* see first */ | |
28752 | - | |
28753 | + | |
28754 | time_t disable_ts; /* replace by host->something */ | |
28755 | - | |
28756 | + | |
28757 | int is_local; | |
28758 | ||
28759 | enum { PROC_STATE_UNSET, /* init-phase */ | |
28760 | @@ -78,7 +78,7 @@ | |
28761 | PROC_STATE_KILLED, /* was killed as we don't have the load anymore */ | |
28762 | PROC_STATE_DIED, /* marked as dead, should be restarted */ | |
28763 | PROC_STATE_DISABLED /* proc disabled as it resulted in an error */ | |
28764 | - } state; | |
28765 | + } state; | |
28766 | } scgi_proc; | |
28767 | ||
28768 | typedef struct { | |
28769 | @@ -86,20 +86,20 @@ | |
28770 | * sorted by lowest load | |
28771 | * | |
28772 | * whenever a job is done move it up in the list | |
28773 | - * until it is sorted, move it down as soon as the | |
28774 | + * until it is sorted, move it down as soon as the | |
28775 | * job is started | |
28776 | */ | |
28777 | - scgi_proc *first; | |
28778 | - scgi_proc *unused_procs; | |
28779 | + scgi_proc *first; | |
28780 | + scgi_proc *unused_procs; | |
28781 | ||
28782 | - /* | |
28783 | + /* | |
28784 | * spawn at least min_procs, at max_procs. | |
28785 | * | |
28786 | - * as soon as the load of the first entry | |
28787 | + * as soon as the load of the first entry | |
28788 | * is max_load_per_proc we spawn a new one | |
28789 | - * and add it to the first entry and give it | |
28790 | + * and add it to the first entry and give it | |
28791 | * the load | |
28792 | - * | |
28793 | + * | |
28794 | */ | |
28795 | ||
28796 | unsigned short min_procs; | |
28797 | @@ -111,44 +111,44 @@ | |
28798 | ||
28799 | /* | |
28800 | * kick the process from the list if it was not | |
28801 | - * used for idle_timeout until min_procs is | |
28802 | + * used for idle_timeout until min_procs is | |
28803 | * reached. this helps to get the processlist | |
28804 | * small again we had a small peak load. | |
28805 | * | |
28806 | */ | |
28807 | - | |
28808 | + | |
28809 | unsigned short idle_timeout; | |
28810 | - | |
28811 | + | |
28812 | /* | |
28813 | * time after a disabled remote connection is tried to be re-enabled | |
28814 | - * | |
28815 | - * | |
28816 | + * | |
28817 | + * | |
28818 | */ | |
28819 | - | |
28820 | + | |
28821 | unsigned short disable_time; | |
28822 | ||
28823 | /* | |
28824 | * same scgi processes get a little bit larger | |
28825 | - * than wanted. max_requests_per_proc kills a | |
28826 | + * than wanted. max_requests_per_proc kills a | |
28827 | * process after a number of handled requests. | |
28828 | * | |
28829 | */ | |
28830 | size_t max_requests_per_proc; | |
28831 | - | |
28832 | + | |
28833 | ||
28834 | /* config */ | |
28835 | ||
28836 | - /* | |
28837 | - * host:port | |
28838 | + /* | |
28839 | + * host:port | |
28840 | * | |
28841 | - * if host is one of the local IP adresses the | |
28842 | + * if host is one of the local IP adresses the | |
28843 | * whole connection is local | |
28844 | * | |
28845 | * if tcp/ip should be used host AND port have | |
28846 | - * to be specified | |
28847 | - * | |
28848 | - */ | |
28849 | - buffer *host; | |
28850 | + * to be specified | |
28851 | + * | |
28852 | + */ | |
28853 | + buffer *host; | |
28854 | unsigned short port; | |
28855 | ||
28856 | /* | |
28857 | @@ -161,7 +161,7 @@ | |
28858 | */ | |
28859 | buffer *unixsocket; | |
28860 | ||
28861 | - /* if socket is local we can start the scgi | |
28862 | + /* if socket is local we can start the scgi | |
28863 | * process ourself | |
28864 | * | |
28865 | * bin-path is the path to the binary | |
28866 | @@ -169,19 +169,19 @@ | |
28867 | * check min_procs and max_procs for the number | |
28868 | * of process to start-up | |
28869 | */ | |
28870 | - buffer *bin_path; | |
28871 | - | |
28872 | - /* bin-path is set bin-environment is taken to | |
28873 | + buffer *bin_path; | |
28874 | + | |
28875 | + /* bin-path is set bin-environment is taken to | |
28876 | * create the environement before starting the | |
28877 | * FastCGI process | |
28878 | - * | |
28879 | + * | |
28880 | */ | |
28881 | array *bin_env; | |
28882 | - | |
28883 | + | |
28884 | array *bin_env_copy; | |
28885 | - | |
28886 | + | |
28887 | /* | |
28888 | - * docroot-translation between URL->phys and the | |
28889 | + * docroot-translation between URL->phys and the | |
28890 | * remote host | |
28891 | * | |
28892 | * reasons: | |
28893 | @@ -192,7 +192,7 @@ | |
28894 | buffer *docroot; | |
28895 | ||
28896 | /* | |
28897 | - * check_local tell you if the phys file is stat()ed | |
28898 | + * check_local tell you if the phys file is stat()ed | |
28899 | * or not. FastCGI doesn't care if the service is | |
28900 | * remote. If the web-server side doesn't contain | |
28901 | * the scgi-files we should not stat() for them | |
28902 | @@ -202,33 +202,33 @@ | |
28903 | ||
28904 | /* | |
28905 | * append PATH_INFO to SCRIPT_FILENAME | |
28906 | - * | |
28907 | + * | |
28908 | * php needs this if cgi.fix_pathinfo is provied | |
28909 | - * | |
28910 | + * | |
28911 | */ | |
28912 | - | |
28913 | + | |
28914 | ssize_t load; /* replace by host->load */ | |
28915 | ||
28916 | size_t max_id; /* corresponds most of the time to | |
28917 | num_procs. | |
28918 | - | |
28919 | + | |
28920 | only if a process is killed max_id waits for the process itself | |
28921 | to die and decrements its afterwards */ | |
28922 | } scgi_extension_host; | |
28923 | ||
28924 | /* | |
28925 | * one extension can have multiple hosts assigned | |
28926 | - * one host can spawn additional processes on the same | |
28927 | + * one host can spawn additional processes on the same | |
28928 | * socket (if we control it) | |
28929 | * | |
28930 | * ext -> host -> procs | |
28931 | * 1:n 1:n | |
28932 | * | |
28933 | - * if the scgi process is remote that whole goes down | |
28934 | + * if the scgi process is remote that whole goes down | |
28935 | * to | |
28936 | * | |
28937 | * ext -> host -> procs | |
28938 | - * 1:n 1:1 | |
28939 | + * 1:n 1:1 | |
28940 | * | |
28941 | * in case of PHP and FCGI_CHILDREN we have again a procs | |
28942 | * but we don't control it directly. | |
28943 | @@ -239,7 +239,7 @@ | |
28944 | buffer *key; /* like .php */ | |
28945 | ||
28946 | scgi_extension_host **hosts; | |
28947 | - | |
28948 | + | |
28949 | size_t used; | |
28950 | size_t size; | |
28951 | } scgi_extension; | |
28952 | @@ -253,14 +253,14 @@ | |
28953 | ||
28954 | ||
28955 | typedef struct { | |
28956 | - scgi_exts *exts; | |
28957 | - | |
28958 | + scgi_exts *exts; | |
28959 | + | |
28960 | int debug; | |
28961 | } plugin_config; | |
28962 | ||
28963 | typedef struct { | |
28964 | char **ptr; | |
28965 | - | |
28966 | + | |
28967 | size_t size; | |
28968 | size_t used; | |
28969 | } char_array; | |
28970 | @@ -268,52 +268,51 @@ | |
28971 | /* generic plugin data, shared between all connections */ | |
28972 | typedef struct { | |
28973 | PLUGIN_DATA; | |
28974 | - | |
28975 | + | |
28976 | buffer *scgi_env; | |
28977 | - | |
28978 | + | |
28979 | buffer *path; | |
28980 | buffer *parse_response; | |
28981 | - | |
28982 | + | |
28983 | plugin_config **config_storage; | |
28984 | - | |
28985 | + | |
28986 | plugin_config conf; /* this is only used as long as no handler_ctx is setup */ | |
28987 | } plugin_data; | |
28988 | ||
28989 | /* connection specific data */ | |
28990 | -typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE, | |
28991 | - FCGI_STATE_WRITE, FCGI_STATE_READ | |
28992 | +typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE, | |
28993 | + FCGI_STATE_WRITE, FCGI_STATE_READ | |
28994 | } scgi_connection_state_t; | |
28995 | ||
28996 | typedef struct { | |
28997 | - buffer *response; | |
28998 | + buffer *response; | |
28999 | size_t response_len; | |
29000 | int response_type; | |
29001 | int response_padding; | |
29002 | - | |
29003 | + | |
29004 | scgi_proc *proc; | |
29005 | scgi_extension_host *host; | |
29006 | - | |
29007 | + | |
29008 | scgi_connection_state_t state; | |
29009 | time_t state_timestamp; | |
29010 | - | |
29011 | + | |
29012 | int reconnects; /* number of reconnect attempts */ | |
29013 | - | |
29014 | + | |
29015 | read_buffer *rb; | |
29016 | chunkqueue *wb; | |
29017 | - | |
29018 | + | |
29019 | buffer *response_header; | |
29020 | - | |
29021 | + | |
29022 | int delayed; /* flag to mark that the connect() is delayed */ | |
29023 | - | |
29024 | + | |
29025 | size_t request_id; | |
29026 | int fd; /* fd to the scgi process */ | |
29027 | int fde_ndx; /* index into the fd-event buffer */ | |
29028 | - | |
29029 | pid_t pid; | |
29030 | int got_proc; | |
29031 | - | |
29032 | + | |
29033 | plugin_config conf; | |
29034 | - | |
29035 | + | |
29036 | connection *remote_conn; /* dumb pointer */ | |
29037 | plugin_data *plugin_data; /* dumb pointer */ | |
29038 | } handler_ctx; | |
29039 | @@ -328,28 +327,28 @@ | |
29040 | ||
29041 | static handler_ctx * handler_ctx_init() { | |
29042 | handler_ctx * hctx; | |
29043 | - | |
29044 | + | |
29045 | hctx = calloc(1, sizeof(*hctx)); | |
29046 | assert(hctx); | |
29047 | - | |
29048 | + | |
29049 | hctx->fde_ndx = -1; | |
29050 | - | |
29051 | + | |
29052 | hctx->response = buffer_init(); | |
29053 | hctx->response_header = buffer_init(); | |
29054 | - | |
29055 | + | |
29056 | hctx->request_id = 0; | |
29057 | hctx->state = FCGI_STATE_INIT; | |
29058 | hctx->proc = NULL; | |
29059 | - | |
29060 | + | |
29061 | hctx->response_len = 0; | |
29062 | hctx->response_type = 0; | |
29063 | hctx->response_padding = 0; | |
29064 | hctx->fd = -1; | |
29065 | - | |
29066 | + | |
29067 | hctx->reconnects = 0; | |
29068 | ||
29069 | hctx->wb = chunkqueue_init(); | |
29070 | - | |
29071 | + | |
29072 | return hctx; | |
29073 | } | |
29074 | ||
29075 | @@ -358,12 +357,12 @@ | |
29076 | buffer_free(hctx->response_header); | |
29077 | ||
29078 | chunkqueue_free(hctx->wb); | |
29079 | - | |
29080 | + | |
29081 | if (hctx->rb) { | |
29082 | if (hctx->rb->ptr) free(hctx->rb->ptr); | |
29083 | free(hctx->rb); | |
29084 | } | |
29085 | - | |
29086 | + | |
29087 | free(hctx); | |
29088 | } | |
29089 | ||
29090 | @@ -372,20 +371,20 @@ | |
29091 | ||
29092 | f = calloc(1, sizeof(*f)); | |
29093 | f->socket = buffer_init(); | |
29094 | - | |
29095 | + | |
29096 | f->prev = NULL; | |
29097 | f->next = NULL; | |
29098 | - | |
29099 | + | |
29100 | return f; | |
29101 | } | |
29102 | ||
29103 | void scgi_process_free(scgi_proc *f) { | |
29104 | if (!f) return; | |
29105 | - | |
29106 | + | |
29107 | scgi_process_free(f->next); | |
29108 | - | |
29109 | + | |
29110 | buffer_free(f->socket); | |
29111 | - | |
29112 | + | |
29113 | free(f); | |
29114 | } | |
29115 | ||
29116 | @@ -400,62 +399,62 @@ | |
29117 | f->bin_path = buffer_init(); | |
29118 | f->bin_env = array_init(); | |
29119 | f->bin_env_copy = array_init(); | |
29120 | - | |
29121 | + | |
29122 | return f; | |
29123 | } | |
29124 | ||
29125 | void scgi_host_free(scgi_extension_host *h) { | |
29126 | if (!h) return; | |
29127 | - | |
29128 | + | |
29129 | buffer_free(h->host); | |
29130 | buffer_free(h->unixsocket); | |
29131 | buffer_free(h->docroot); | |
29132 | buffer_free(h->bin_path); | |
29133 | array_free(h->bin_env); | |
29134 | array_free(h->bin_env_copy); | |
29135 | - | |
29136 | + | |
29137 | scgi_process_free(h->first); | |
29138 | scgi_process_free(h->unused_procs); | |
29139 | - | |
29140 | + | |
29141 | free(h); | |
29142 | - | |
29143 | + | |
29144 | } | |
29145 | ||
29146 | scgi_exts *scgi_extensions_init() { | |
29147 | scgi_exts *f; | |
29148 | ||
29149 | f = calloc(1, sizeof(*f)); | |
29150 | - | |
29151 | + | |
29152 | return f; | |
29153 | } | |
29154 | ||
29155 | void scgi_extensions_free(scgi_exts *f) { | |
29156 | size_t i; | |
29157 | - | |
29158 | + | |
29159 | if (!f) return; | |
29160 | - | |
29161 | + | |
29162 | for (i = 0; i < f->used; i++) { | |
29163 | scgi_extension *fe; | |
29164 | size_t j; | |
29165 | - | |
29166 | + | |
29167 | fe = f->exts[i]; | |
29168 | - | |
29169 | + | |
29170 | for (j = 0; j < fe->used; j++) { | |
29171 | scgi_extension_host *h; | |
29172 | - | |
29173 | + | |
29174 | h = fe->hosts[j]; | |
29175 | - | |
29176 | + | |
29177 | scgi_host_free(h); | |
29178 | } | |
29179 | - | |
29180 | + | |
29181 | buffer_free(fe->key); | |
29182 | free(fe->hosts); | |
29183 | - | |
29184 | + | |
29185 | free(fe); | |
29186 | } | |
29187 | - | |
29188 | + | |
29189 | free(f->exts); | |
29190 | - | |
29191 | + | |
29192 | free(f); | |
29193 | } | |
29194 | ||
29195 | @@ -504,99 +503,103 @@ | |
29196 | assert(fe->hosts); | |
29197 | } | |
29198 | ||
29199 | - fe->hosts[fe->used++] = fh; | |
29200 | + fe->hosts[fe->used++] = fh; | |
29201 | ||
29202 | return 0; | |
29203 | - | |
29204 | + | |
29205 | } | |
29206 | ||
29207 | INIT_FUNC(mod_scgi_init) { | |
29208 | plugin_data *p; | |
29209 | - | |
29210 | + | |
29211 | p = calloc(1, sizeof(*p)); | |
29212 | - | |
29213 | + | |
29214 | p->scgi_env = buffer_init(); | |
29215 | - | |
29216 | + | |
29217 | p->path = buffer_init(); | |
29218 | p->parse_response = buffer_init(); | |
29219 | - | |
29220 | + | |
29221 | return p; | |
29222 | } | |
29223 | ||
29224 | ||
29225 | FREE_FUNC(mod_scgi_free) { | |
29226 | plugin_data *p = p_d; | |
29227 | - | |
29228 | + | |
29229 | UNUSED(srv); | |
29230 | ||
29231 | buffer_free(p->scgi_env); | |
29232 | buffer_free(p->path); | |
29233 | buffer_free(p->parse_response); | |
29234 | - | |
29235 | + | |
29236 | if (p->config_storage) { | |
29237 | size_t i, j, n; | |
29238 | for (i = 0; i < srv->config_context->used; i++) { | |
29239 | plugin_config *s = p->config_storage[i]; | |
29240 | scgi_exts *exts; | |
29241 | - | |
29242 | + | |
29243 | if (!s) continue; | |
29244 | - | |
29245 | + | |
29246 | exts = s->exts; | |
29247 | ||
29248 | for (j = 0; j < exts->used; j++) { | |
29249 | scgi_extension *ex; | |
29250 | - | |
29251 | + | |
29252 | ex = exts->exts[j]; | |
29253 | - | |
29254 | + | |
29255 | for (n = 0; n < ex->used; n++) { | |
29256 | scgi_proc *proc; | |
29257 | scgi_extension_host *host; | |
29258 | - | |
29259 | + | |
29260 | host = ex->hosts[n]; | |
29261 | - | |
29262 | + | |
29263 | for (proc = host->first; proc; proc = proc->next) { | |
29264 | +#ifndef _WIN32 | |
29265 | if (proc->pid != 0) kill(proc->pid, SIGTERM); | |
29266 | - | |
29267 | - if (proc->is_local && | |
29268 | +#endif | |
29269 | + | |
29270 | + if (proc->is_local && | |
29271 | !buffer_is_empty(proc->socket)) { | |
29272 | unlink(proc->socket->ptr); | |
29273 | } | |
29274 | } | |
29275 | - | |
29276 | + | |
29277 | for (proc = host->unused_procs; proc; proc = proc->next) { | |
29278 | +#ifndef _WIN32 | |
29279 | if (proc->pid != 0) kill(proc->pid, SIGTERM); | |
29280 | - | |
29281 | - if (proc->is_local && | |
29282 | +#endif | |
29283 | + | |
29284 | + if (proc->is_local && | |
29285 | !buffer_is_empty(proc->socket)) { | |
29286 | unlink(proc->socket->ptr); | |
29287 | } | |
29288 | } | |
29289 | } | |
29290 | } | |
29291 | - | |
29292 | + | |
29293 | scgi_extensions_free(s->exts); | |
29294 | - | |
29295 | + | |
29296 | free(s); | |
29297 | } | |
29298 | free(p->config_storage); | |
29299 | } | |
29300 | - | |
29301 | + | |
29302 | free(p); | |
29303 | - | |
29304 | + | |
29305 | return HANDLER_GO_ON; | |
29306 | } | |
29307 | ||
29308 | static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) { | |
29309 | char *dst; | |
29310 | - | |
29311 | + | |
29312 | if (!key || !val) return -1; | |
29313 | - | |
29314 | + | |
29315 | dst = malloc(key_len + val_len + 3); | |
29316 | memcpy(dst, key, key_len); | |
29317 | dst[key_len] = '='; | |
29318 | /* add the \0 from the value */ | |
29319 | memcpy(dst + key_len + 1, val, val_len + 1); | |
29320 | - | |
29321 | + | |
29322 | if (env->size == 0) { | |
29323 | env->size = 16; | |
29324 | env->ptr = malloc(env->size * sizeof(*env->ptr)); | |
29325 | @@ -604,13 +607,13 @@ | |
29326 | env->size += 16; | |
29327 | env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr)); | |
29328 | } | |
29329 | - | |
29330 | + | |
29331 | env->ptr[env->used++] = dst; | |
29332 | - | |
29333 | + | |
29334 | return 0; | |
29335 | } | |
29336 | ||
29337 | -static int scgi_spawn_connection(server *srv, | |
29338 | +static int scgi_spawn_connection(server *srv, | |
29339 | plugin_data *p, | |
29340 | scgi_extension_host *host, | |
29341 | scgi_proc *proc) { | |
29342 | @@ -622,31 +625,27 @@ | |
29343 | #endif | |
29344 | struct sockaddr_in scgi_addr_in; | |
29345 | struct sockaddr *scgi_addr; | |
29346 | - | |
29347 | + | |
29348 | socklen_t servlen; | |
29349 | - | |
29350 | + | |
29351 | #ifndef HAVE_FORK | |
29352 | return -1; | |
29353 | #endif | |
29354 | - | |
29355 | + | |
29356 | if (p->conf.debug) { | |
29357 | log_error_write(srv, __FILE__, __LINE__, "sdb", | |
29358 | "new proc, socket:", proc->port, proc->socket); | |
29359 | } | |
29360 | - | |
29361 | + | |
29362 | if (!buffer_is_empty(proc->socket)) { | |
29363 | memset(&scgi_addr, 0, sizeof(scgi_addr)); | |
29364 | - | |
29365 | + | |
29366 | #ifdef HAVE_SYS_UN_H | |
29367 | scgi_addr_un.sun_family = AF_UNIX; | |
29368 | strcpy(scgi_addr_un.sun_path, proc->socket->ptr); | |
29369 | - | |
29370 | -#ifdef SUN_LEN | |
29371 | + | |
29372 | servlen = SUN_LEN(&scgi_addr_un); | |
29373 | -#else | |
29374 | - /* stevens says: */ | |
29375 | - servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family); | |
29376 | -#endif | |
29377 | + | |
29378 | socket_type = AF_UNIX; | |
29379 | scgi_addr = (struct sockaddr *) &scgi_addr_un; | |
29380 | #else | |
29381 | @@ -656,115 +655,115 @@ | |
29382 | #endif | |
29383 | } else { | |
29384 | scgi_addr_in.sin_family = AF_INET; | |
29385 | - | |
29386 | + | |
29387 | if (buffer_is_empty(host->host)) { | |
29388 | scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); | |
29389 | } else { | |
29390 | struct hostent *he; | |
29391 | - | |
29392 | + | |
29393 | /* set a usefull default */ | |
29394 | scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); | |
29395 | - | |
29396 | - | |
29397 | + | |
29398 | + | |
29399 | if (NULL == (he = gethostbyname(host->host->ptr))) { | |
29400 | - log_error_write(srv, __FILE__, __LINE__, | |
29401 | - "sdb", "gethostbyname failed: ", | |
29402 | + log_error_write(srv, __FILE__, __LINE__, | |
29403 | + "sdb", "gethostbyname failed: ", | |
29404 | h_errno, host->host); | |
29405 | return -1; | |
29406 | } | |
29407 | - | |
29408 | + | |
29409 | if (he->h_addrtype != AF_INET) { | |
29410 | log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype); | |
29411 | return -1; | |
29412 | } | |
29413 | - | |
29414 | + | |
29415 | if (he->h_length != sizeof(struct in_addr)) { | |
29416 | log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length); | |
29417 | return -1; | |
29418 | } | |
29419 | - | |
29420 | + | |
29421 | memcpy(&(scgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length); | |
29422 | - | |
29423 | + | |
29424 | } | |
29425 | scgi_addr_in.sin_port = htons(proc->port); | |
29426 | servlen = sizeof(scgi_addr_in); | |
29427 | - | |
29428 | + | |
29429 | socket_type = AF_INET; | |
29430 | scgi_addr = (struct sockaddr *) &scgi_addr_in; | |
29431 | } | |
29432 | - | |
29433 | + | |
29434 | if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) { | |
29435 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
29436 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
29437 | "failed:", strerror(errno)); | |
29438 | return -1; | |
29439 | } | |
29440 | - | |
29441 | + | |
29442 | if (-1 == connect(scgi_fd, scgi_addr, servlen)) { | |
29443 | /* server is not up, spawn in */ | |
29444 | pid_t child; | |
29445 | int val; | |
29446 | - | |
29447 | + | |
29448 | if (!buffer_is_empty(proc->socket)) { | |
29449 | unlink(proc->socket->ptr); | |
29450 | } | |
29451 | - | |
29452 | + | |
29453 | close(scgi_fd); | |
29454 | - | |
29455 | + | |
29456 | /* reopen socket */ | |
29457 | if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) { | |
29458 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
29459 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
29460 | "socket failed:", strerror(errno)); | |
29461 | return -1; | |
29462 | } | |
29463 | - | |
29464 | + | |
29465 | val = 1; | |
29466 | if (setsockopt(scgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { | |
29467 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
29468 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
29469 | "socketsockopt failed:", strerror(errno)); | |
29470 | return -1; | |
29471 | } | |
29472 | - | |
29473 | + | |
29474 | /* create socket */ | |
29475 | if (-1 == bind(scgi_fd, scgi_addr, servlen)) { | |
29476 | - log_error_write(srv, __FILE__, __LINE__, "sbds", | |
29477 | - "bind failed for:", | |
29478 | - proc->socket, | |
29479 | - proc->port, | |
29480 | + log_error_write(srv, __FILE__, __LINE__, "sbds", | |
29481 | + "bind failed for:", | |
29482 | + proc->socket, | |
29483 | + proc->port, | |
29484 | strerror(errno)); | |
29485 | return -1; | |
29486 | } | |
29487 | - | |
29488 | + | |
29489 | if (-1 == listen(scgi_fd, 1024)) { | |
29490 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
29491 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
29492 | "listen failed:", strerror(errno)); | |
29493 | return -1; | |
29494 | } | |
29495 | - | |
29496 | -#ifdef HAVE_FORK | |
29497 | + | |
29498 | +#ifdef HAVE_FORK | |
29499 | switch ((child = fork())) { | |
29500 | case 0: { | |
29501 | buffer *b; | |
29502 | size_t i = 0; | |
29503 | int fd = 0; | |
29504 | char_array env; | |
29505 | - | |
29506 | - | |
29507 | + | |
29508 | + | |
29509 | /* create environment */ | |
29510 | env.ptr = NULL; | |
29511 | env.size = 0; | |
29512 | env.used = 0; | |
29513 | - | |
29514 | + | |
29515 | /* we don't need the client socket */ | |
29516 | for (fd = 3; fd < 256; fd++) { | |
29517 | if (fd != 2 && fd != scgi_fd) close(fd); | |
29518 | } | |
29519 | - | |
29520 | + | |
29521 | /* build clean environment */ | |
29522 | if (host->bin_env_copy->used) { | |
29523 | for (i = 0; i < host->bin_env_copy->used; i++) { | |
29524 | data_string *ds = (data_string *)host->bin_env_copy->data[i]; | |
29525 | char *ge; | |
29526 | - | |
29527 | + | |
29528 | if (NULL != (ge = getenv(ds->value->ptr))) { | |
29529 | env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge)); | |
29530 | } | |
29531 | @@ -772,44 +771,44 @@ | |
29532 | } else { | |
29533 | for (i = 0; environ[i]; i++) { | |
29534 | char *eq; | |
29535 | - | |
29536 | + | |
29537 | if (NULL != (eq = strchr(environ[i], '='))) { | |
29538 | env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1)); | |
29539 | } | |
29540 | } | |
29541 | } | |
29542 | - | |
29543 | + | |
29544 | /* create environment */ | |
29545 | for (i = 0; i < host->bin_env->used; i++) { | |
29546 | data_string *ds = (data_string *)host->bin_env->data[i]; | |
29547 | - | |
29548 | + | |
29549 | env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value)); | |
29550 | } | |
29551 | - | |
29552 | + | |
29553 | for (i = 0; i < env.used; i++) { | |
29554 | /* search for PHP_FCGI_CHILDREN */ | |
29555 | if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break; | |
29556 | } | |
29557 | - | |
29558 | + | |
29559 | /* not found, add a default */ | |
29560 | if (i == env.used) { | |
29561 | env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1")); | |
29562 | } | |
29563 | - | |
29564 | + | |
29565 | env.ptr[env.used] = NULL; | |
29566 | - | |
29567 | + | |
29568 | b = buffer_init(); | |
29569 | buffer_copy_string(b, "exec "); | |
29570 | buffer_append_string_buffer(b, host->bin_path); | |
29571 | - | |
29572 | + | |
29573 | /* exec the cgi */ | |
29574 | execle("/bin/sh", "sh", "-c", b->ptr, NULL, env.ptr); | |
29575 | - | |
29576 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
29577 | + | |
29578 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
29579 | "execl failed for:", host->bin_path, strerror(errno)); | |
29580 | - | |
29581 | + | |
29582 | exit(errno); | |
29583 | - | |
29584 | + | |
29585 | break; | |
29586 | } | |
29587 | case -1: | |
29588 | @@ -817,32 +816,32 @@ | |
29589 | break; | |
29590 | default: | |
29591 | /* father */ | |
29592 | - | |
29593 | + | |
29594 | /* wait */ | |
29595 | select(0, NULL, NULL, NULL, &tv); | |
29596 | - | |
29597 | + | |
29598 | switch (waitpid(child, &status, WNOHANG)) { | |
29599 | case 0: | |
29600 | /* child still running after timeout, good */ | |
29601 | break; | |
29602 | case -1: | |
29603 | /* no PID found ? should never happen */ | |
29604 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
29605 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
29606 | "pid not found:", strerror(errno)); | |
29607 | return -1; | |
29608 | default: | |
29609 | /* the child should not terminate at all */ | |
29610 | if (WIFEXITED(status)) { | |
29611 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
29612 | - "child exited (is this a SCGI binary ?):", | |
29613 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
29614 | + "child exited (is this a SCGI binary ?):", | |
29615 | WEXITSTATUS(status)); | |
29616 | } else if (WIFSIGNALED(status)) { | |
29617 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
29618 | - "child signaled:", | |
29619 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
29620 | + "child signaled:", | |
29621 | WTERMSIG(status)); | |
29622 | } else { | |
29623 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
29624 | - "child died somehow:", | |
29625 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
29626 | + "child died somehow:", | |
29627 | status); | |
29628 | } | |
29629 | return -1; | |
29630 | @@ -852,26 +851,26 @@ | |
29631 | proc->pid = child; | |
29632 | proc->last_used = srv->cur_ts; | |
29633 | proc->is_local = 1; | |
29634 | - | |
29635 | + | |
29636 | break; | |
29637 | } | |
29638 | #endif | |
29639 | } else { | |
29640 | proc->is_local = 0; | |
29641 | proc->pid = 0; | |
29642 | - | |
29643 | + | |
29644 | if (p->conf.debug) { | |
29645 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
29646 | "(debug) socket is already used, won't spawn:", | |
29647 | proc->socket); | |
29648 | } | |
29649 | } | |
29650 | - | |
29651 | + | |
29652 | proc->state = PROC_STATE_RUNNING; | |
29653 | host->active_procs++; | |
29654 | - | |
29655 | + | |
29656 | close(scgi_fd); | |
29657 | - | |
29658 | + | |
29659 | return 0; | |
29660 | } | |
29661 | ||
29662 | @@ -880,89 +879,89 @@ | |
29663 | plugin_data *p = p_d; | |
29664 | data_unset *du; | |
29665 | size_t i = 0; | |
29666 | - | |
29667 | - config_values_t cv[] = { | |
29668 | + | |
29669 | + config_values_t cv[] = { | |
29670 | { "scgi.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
29671 | { "scgi.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
29672 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
29673 | }; | |
29674 | - | |
29675 | + | |
29676 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
29677 | - | |
29678 | + | |
29679 | for (i = 0; i < srv->config_context->used; i++) { | |
29680 | plugin_config *s; | |
29681 | array *ca; | |
29682 | - | |
29683 | + | |
29684 | s = malloc(sizeof(plugin_config)); | |
29685 | s->exts = scgi_extensions_init(); | |
29686 | s->debug = 0; | |
29687 | - | |
29688 | + | |
29689 | cv[0].destination = s->exts; | |
29690 | cv[1].destination = &(s->debug); | |
29691 | - | |
29692 | + | |
29693 | p->config_storage[i] = s; | |
29694 | ca = ((data_config *)srv->config_context->data[i])->value; | |
29695 | - | |
29696 | + | |
29697 | if (0 != config_insert_values_global(srv, ca, cv)) { | |
29698 | return HANDLER_ERROR; | |
29699 | } | |
29700 | - | |
29701 | - /* | |
29702 | + | |
29703 | + /* | |
29704 | * <key> = ( ... ) | |
29705 | */ | |
29706 | - | |
29707 | + | |
29708 | if (NULL != (du = array_get_element(ca, "scgi.server"))) { | |
29709 | size_t j; | |
29710 | data_array *da = (data_array *)du; | |
29711 | - | |
29712 | + | |
29713 | if (du->type != TYPE_ARRAY) { | |
29714 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
29715 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
29716 | "unexpected type for key: ", "scgi.server", "array of strings"); | |
29717 | - | |
29718 | + | |
29719 | return HANDLER_ERROR; | |
29720 | } | |
29721 | - | |
29722 | - | |
29723 | - /* | |
29724 | - * scgi.server = ( "<ext>" => ( ... ), | |
29725 | + | |
29726 | + | |
29727 | + /* | |
29728 | + * scgi.server = ( "<ext>" => ( ... ), | |
29729 | * "<ext>" => ( ... ) ) | |
29730 | */ | |
29731 | - | |
29732 | + | |
29733 | for (j = 0; j < da->value->used; j++) { | |
29734 | size_t n; | |
29735 | data_array *da_ext = (data_array *)da->value->data[j]; | |
29736 | - | |
29737 | + | |
29738 | if (da->value->data[j]->type != TYPE_ARRAY) { | |
29739 | - log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
29740 | - "unexpected type for key: ", "scgi.server", | |
29741 | + log_error_write(srv, __FILE__, __LINE__, "sssbs", | |
29742 | + "unexpected type for key: ", "scgi.server", | |
29743 | "[", da->value->data[j]->key, "](string)"); | |
29744 | - | |
29745 | + | |
29746 | return HANDLER_ERROR; | |
29747 | } | |
29748 | - | |
29749 | - /* | |
29750 | - * da_ext->key == name of the extension | |
29751 | + | |
29752 | + /* | |
29753 | + * da_ext->key == name of the extension | |
29754 | */ | |
29755 | - | |
29756 | - /* | |
29757 | - * scgi.server = ( "<ext>" => | |
29758 | - * ( "<host>" => ( ... ), | |
29759 | + | |
29760 | + /* | |
29761 | + * scgi.server = ( "<ext>" => | |
29762 | + * ( "<host>" => ( ... ), | |
29763 | * "<host>" => ( ... ) | |
29764 | - * ), | |
29765 | + * ), | |
29766 | * "<ext>" => ... ) | |
29767 | */ | |
29768 | - | |
29769 | + | |
29770 | for (n = 0; n < da_ext->value->used; n++) { | |
29771 | data_array *da_host = (data_array *)da_ext->value->data[n]; | |
29772 | - | |
29773 | + | |
29774 | scgi_extension_host *df; | |
29775 | - | |
29776 | - config_values_t fcv[] = { | |
29777 | + | |
29778 | + config_values_t fcv[] = { | |
29779 | { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
29780 | { "docroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
29781 | { "socket", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
29782 | { "bin-path", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ | |
29783 | - | |
29784 | + | |
29785 | { "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 4 */ | |
29786 | { "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 5 */ | |
29787 | { "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */ | |
29788 | @@ -970,37 +969,37 @@ | |
29789 | { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 8 */ | |
29790 | { "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */ | |
29791 | { "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */ | |
29792 | - | |
29793 | + | |
29794 | { "bin-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 11 */ | |
29795 | { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ | |
29796 | - | |
29797 | - | |
29798 | + | |
29799 | + | |
29800 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
29801 | }; | |
29802 | - | |
29803 | + | |
29804 | if (da_host->type != TYPE_ARRAY) { | |
29805 | - log_error_write(srv, __FILE__, __LINE__, "ssSBS", | |
29806 | - "unexpected type for key:", | |
29807 | - "scgi.server", | |
29808 | + log_error_write(srv, __FILE__, __LINE__, "ssSBS", | |
29809 | + "unexpected type for key:", | |
29810 | + "scgi.server", | |
29811 | "[", da_host->key, "](string)"); | |
29812 | - | |
29813 | + | |
29814 | return HANDLER_ERROR; | |
29815 | } | |
29816 | - | |
29817 | + | |
29818 | df = scgi_host_init(); | |
29819 | - | |
29820 | + | |
29821 | df->check_local = 1; | |
29822 | df->min_procs = 4; | |
29823 | df->max_procs = 4; | |
29824 | df->max_load_per_proc = 1; | |
29825 | df->idle_timeout = 60; | |
29826 | df->disable_time = 60; | |
29827 | - | |
29828 | + | |
29829 | fcv[0].destination = df->host; | |
29830 | fcv[1].destination = df->docroot; | |
29831 | fcv[2].destination = df->unixsocket; | |
29832 | fcv[3].destination = df->bin_path; | |
29833 | - | |
29834 | + | |
29835 | fcv[4].destination = &(df->check_local); | |
29836 | fcv[5].destination = &(df->port); | |
29837 | fcv[6].destination = &(df->min_procs); | |
29838 | @@ -1008,47 +1007,47 @@ | |
29839 | fcv[8].destination = &(df->max_load_per_proc); | |
29840 | fcv[9].destination = &(df->idle_timeout); | |
29841 | fcv[10].destination = &(df->disable_time); | |
29842 | - | |
29843 | + | |
29844 | fcv[11].destination = df->bin_env; | |
29845 | fcv[12].destination = df->bin_env_copy; | |
29846 | - | |
29847 | - | |
29848 | + | |
29849 | + | |
29850 | if (0 != config_insert_values_internal(srv, da_host->value, fcv)) { | |
29851 | return HANDLER_ERROR; | |
29852 | } | |
29853 | - | |
29854 | - if ((!buffer_is_empty(df->host) || df->port) && | |
29855 | + | |
29856 | + if ((!buffer_is_empty(df->host) || df->port) && | |
29857 | !buffer_is_empty(df->unixsocket)) { | |
29858 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
29859 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
29860 | "either host+port or socket"); | |
29861 | - | |
29862 | + | |
29863 | return HANDLER_ERROR; | |
29864 | } | |
29865 | - | |
29866 | + | |
29867 | if (!buffer_is_empty(df->unixsocket)) { | |
29868 | /* unix domain socket */ | |
29869 | - | |
29870 | + | |
29871 | if (df->unixsocket->used > UNIX_PATH_MAX - 2) { | |
29872 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
29873 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
29874 | "path of the unixdomain socket is too large"); | |
29875 | return HANDLER_ERROR; | |
29876 | } | |
29877 | } else { | |
29878 | /* tcp/ip */ | |
29879 | - | |
29880 | - if (buffer_is_empty(df->host) && | |
29881 | + | |
29882 | + if (buffer_is_empty(df->host) && | |
29883 | buffer_is_empty(df->bin_path)) { | |
29884 | - log_error_write(srv, __FILE__, __LINE__, "sbbbs", | |
29885 | - "missing key (string):", | |
29886 | + log_error_write(srv, __FILE__, __LINE__, "sbbbs", | |
29887 | + "missing key (string):", | |
29888 | da->key, | |
29889 | da_ext->key, | |
29890 | da_host->key, | |
29891 | "host"); | |
29892 | - | |
29893 | + | |
29894 | return HANDLER_ERROR; | |
29895 | } else if (df->port == 0) { | |
29896 | - log_error_write(srv, __FILE__, __LINE__, "sbbbs", | |
29897 | - "missing key (short):", | |
29898 | + log_error_write(srv, __FILE__, __LINE__, "sbbbs", | |
29899 | + "missing key (short):", | |
29900 | da->key, | |
29901 | da_ext->key, | |
29902 | da_host->key, | |
29903 | @@ -1056,14 +1055,14 @@ | |
29904 | return HANDLER_ERROR; | |
29905 | } | |
29906 | } | |
29907 | - | |
29908 | - if (!buffer_is_empty(df->bin_path)) { | |
29909 | + | |
29910 | + if (!buffer_is_empty(df->bin_path)) { | |
29911 | /* a local socket + self spawning */ | |
29912 | size_t pno; | |
29913 | - | |
29914 | + | |
29915 | if (df->min_procs > df->max_procs) df->max_procs = df->min_procs; | |
29916 | if (df->max_load_per_proc < 1) df->max_load_per_proc = 0; | |
29917 | - | |
29918 | + | |
29919 | if (s->debug) { | |
29920 | log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd", | |
29921 | "--- scgi spawning local", | |
29922 | @@ -1073,7 +1072,7 @@ | |
29923 | "\n\tmin-procs:", df->min_procs, | |
29924 | "\n\tmax-procs:", df->max_procs); | |
29925 | } | |
29926 | - | |
29927 | + | |
29928 | for (pno = 0; pno < df->min_procs; pno++) { | |
29929 | scgi_proc *proc; | |
29930 | ||
29931 | @@ -1088,7 +1087,7 @@ | |
29932 | buffer_append_string(proc->socket, "-"); | |
29933 | buffer_append_long(proc->socket, pno); | |
29934 | } | |
29935 | - | |
29936 | + | |
29937 | if (s->debug) { | |
29938 | log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd", | |
29939 | "--- scgi spawning", | |
29940 | @@ -1096,53 +1095,53 @@ | |
29941 | "\n\tsocket", df->unixsocket, | |
29942 | "\n\tcurrent:", pno, "/", df->min_procs); | |
29943 | } | |
29944 | - | |
29945 | + | |
29946 | if (scgi_spawn_connection(srv, p, df, proc)) { | |
29947 | log_error_write(srv, __FILE__, __LINE__, "s", | |
29948 | "[ERROR]: spawning fcgi failed."); | |
29949 | return HANDLER_ERROR; | |
29950 | } | |
29951 | - | |
29952 | + | |
29953 | proc->next = df->first; | |
29954 | if (df->first) df->first->prev = proc; | |
29955 | - | |
29956 | + | |
29957 | df->first = proc; | |
29958 | } | |
29959 | } else { | |
29960 | scgi_proc *fp; | |
29961 | - | |
29962 | + | |
29963 | fp = scgi_process_init(); | |
29964 | fp->id = df->num_procs++; | |
29965 | df->max_id++; | |
29966 | df->active_procs++; | |
29967 | fp->state = PROC_STATE_RUNNING; | |
29968 | - | |
29969 | + | |
29970 | if (buffer_is_empty(df->unixsocket)) { | |
29971 | fp->port = df->port; | |
29972 | } else { | |
29973 | buffer_copy_string_buffer(fp->socket, df->unixsocket); | |
29974 | } | |
29975 | - | |
29976 | + | |
29977 | df->first = fp; | |
29978 | - | |
29979 | + | |
29980 | df->min_procs = 1; | |
29981 | df->max_procs = 1; | |
29982 | } | |
29983 | - | |
29984 | + | |
29985 | /* if extension already exists, take it */ | |
29986 | scgi_extension_insert(s->exts, da_ext->key, df); | |
29987 | } | |
29988 | } | |
29989 | } | |
29990 | } | |
29991 | - | |
29992 | + | |
29993 | return HANDLER_GO_ON; | |
29994 | } | |
29995 | ||
29996 | static int scgi_set_state(server *srv, handler_ctx *hctx, scgi_connection_state_t state) { | |
29997 | hctx->state = state; | |
29998 | hctx->state_timestamp = srv->cur_ts; | |
29999 | - | |
30000 | + | |
30001 | return 0; | |
30002 | } | |
30003 | ||
30004 | @@ -1150,34 +1149,34 @@ | |
30005 | void scgi_connection_cleanup(server *srv, handler_ctx *hctx) { | |
30006 | plugin_data *p; | |
30007 | connection *con; | |
30008 | - | |
30009 | + | |
30010 | if (NULL == hctx) return; | |
30011 | - | |
30012 | + | |
30013 | p = hctx->plugin_data; | |
30014 | con = hctx->remote_conn; | |
30015 | - | |
30016 | + | |
30017 | if (con->mode != p->id) { | |
30018 | WP(); | |
30019 | return; | |
30020 | } | |
30021 | - | |
30022 | + | |
30023 | if (hctx->fd != -1) { | |
30024 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
30025 | fdevent_unregister(srv->ev, hctx->fd); | |
30026 | close(hctx->fd); | |
30027 | srv->cur_fds--; | |
30028 | } | |
30029 | - | |
30030 | + | |
30031 | if (hctx->host && hctx->proc) { | |
30032 | hctx->host->load--; | |
30033 | - | |
30034 | + | |
30035 | if (hctx->got_proc) { | |
30036 | /* after the connect the process gets a load */ | |
30037 | hctx->proc->load--; | |
30038 | - | |
30039 | + | |
30040 | if (p->conf.debug) { | |
30041 | log_error_write(srv, __FILE__, __LINE__, "sddb", | |
30042 | - "release proc:", | |
30043 | + "release proc:", | |
30044 | hctx->fd, | |
30045 | hctx->proc->pid, hctx->proc->socket); | |
30046 | } | |
30047 | @@ -1186,87 +1185,87 @@ | |
30048 | scgi_proclist_sort_down(srv, hctx->host, hctx->proc); | |
30049 | } | |
30050 | ||
30051 | - | |
30052 | + | |
30053 | handler_ctx_free(hctx); | |
30054 | - con->plugin_ctx[p->id] = NULL; | |
30055 | + con->plugin_ctx[p->id] = NULL; | |
30056 | } | |
30057 | ||
30058 | static int scgi_reconnect(server *srv, handler_ctx *hctx) { | |
30059 | plugin_data *p = hctx->plugin_data; | |
30060 | - | |
30061 | - /* child died | |
30062 | - * | |
30063 | - * 1. | |
30064 | - * | |
30065 | + | |
30066 | + /* child died | |
30067 | + * | |
30068 | + * 1. | |
30069 | + * | |
30070 | * connect was ok, connection was accepted | |
30071 | * but the php accept loop checks after the accept if it should die or not. | |
30072 | - * | |
30073 | - * if yes we can only detect it at a write() | |
30074 | - * | |
30075 | + * | |
30076 | + * if yes we can only detect it at a write() | |
30077 | + * | |
30078 | * next step is resetting this attemp and setup a connection again | |
30079 | - * | |
30080 | + * | |
30081 | * if we have more then 5 reconnects for the same request, die | |
30082 | - * | |
30083 | - * 2. | |
30084 | - * | |
30085 | + * | |
30086 | + * 2. | |
30087 | + * | |
30088 | * we have a connection but the child died by some other reason | |
30089 | - * | |
30090 | + * | |
30091 | */ | |
30092 | - | |
30093 | + | |
30094 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
30095 | fdevent_unregister(srv->ev, hctx->fd); | |
30096 | close(hctx->fd); | |
30097 | srv->cur_fds--; | |
30098 | - | |
30099 | + | |
30100 | scgi_set_state(srv, hctx, FCGI_STATE_INIT); | |
30101 | - | |
30102 | + | |
30103 | hctx->request_id = 0; | |
30104 | hctx->reconnects++; | |
30105 | - | |
30106 | + | |
30107 | if (p->conf.debug) { | |
30108 | log_error_write(srv, __FILE__, __LINE__, "sddb", | |
30109 | - "release proc:", | |
30110 | + "release proc:", | |
30111 | hctx->fd, | |
30112 | hctx->proc->pid, hctx->proc->socket); | |
30113 | } | |
30114 | - | |
30115 | + | |
30116 | hctx->proc->load--; | |
30117 | scgi_proclist_sort_down(srv, hctx->host, hctx->proc); | |
30118 | - | |
30119 | + | |
30120 | return 0; | |
30121 | } | |
30122 | ||
30123 | ||
30124 | static handler_t scgi_connection_reset(server *srv, connection *con, void *p_d) { | |
30125 | plugin_data *p = p_d; | |
30126 | - | |
30127 | + | |
30128 | scgi_connection_cleanup(srv, con->plugin_ctx[p->id]); | |
30129 | - | |
30130 | + | |
30131 | return HANDLER_GO_ON; | |
30132 | } | |
30133 | ||
30134 | ||
30135 | static int scgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) { | |
30136 | size_t len; | |
30137 | - | |
30138 | + | |
30139 | if (!key || !val) return -1; | |
30140 | - | |
30141 | + | |
30142 | len = key_len + val_len + 2; | |
30143 | - | |
30144 | + | |
30145 | buffer_prepare_append(env, len); | |
30146 | ||
30147 | - /* include the NUL */ | |
30148 | + /* include the NUL */ | |
30149 | memcpy(env->ptr + env->used, key, key_len + 1); | |
30150 | env->used += key_len + 1; | |
30151 | memcpy(env->ptr + env->used, val, val_len + 1); | |
30152 | env->used += val_len + 1; | |
30153 | - | |
30154 | + | |
30155 | return 0; | |
30156 | } | |
30157 | ||
30158 | ||
30159 | /** | |
30160 | - * | |
30161 | + * | |
30162 | * returns | |
30163 | * -1 error | |
30164 | * 0 connected | |
30165 | @@ -1280,24 +1279,21 @@ | |
30166 | struct sockaddr_un scgi_addr_un; | |
30167 | #endif | |
30168 | socklen_t servlen; | |
30169 | - | |
30170 | + | |
30171 | scgi_extension_host *host = hctx->host; | |
30172 | scgi_proc *proc = hctx->proc; | |
30173 | int scgi_fd = hctx->fd; | |
30174 | - | |
30175 | + | |
30176 | memset(&scgi_addr, 0, sizeof(scgi_addr)); | |
30177 | - | |
30178 | + | |
30179 | if (!buffer_is_empty(proc->socket)) { | |
30180 | #ifdef HAVE_SYS_UN_H | |
30181 | /* use the unix domain socket */ | |
30182 | scgi_addr_un.sun_family = AF_UNIX; | |
30183 | strcpy(scgi_addr_un.sun_path, proc->socket->ptr); | |
30184 | -#ifdef SUN_LEN | |
30185 | + | |
30186 | servlen = SUN_LEN(&scgi_addr_un); | |
30187 | -#else | |
30188 | - /* stevens says: */ | |
30189 | - servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family); | |
30190 | -#endif | |
30191 | + | |
30192 | scgi_addr = (struct sockaddr *) &scgi_addr_un; | |
30193 | #else | |
30194 | return -1; | |
30195 | @@ -1305,105 +1301,105 @@ | |
30196 | } else { | |
30197 | scgi_addr_in.sin_family = AF_INET; | |
30198 | if (0 == inet_aton(host->host->ptr, &(scgi_addr_in.sin_addr))) { | |
30199 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
30200 | - "converting IP-adress failed for", host->host, | |
30201 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
30202 | + "converting IP-adress failed for", host->host, | |
30203 | "\nBe sure to specify an IP address here"); | |
30204 | - | |
30205 | + | |
30206 | return -1; | |
30207 | } | |
30208 | scgi_addr_in.sin_port = htons(proc->port); | |
30209 | servlen = sizeof(scgi_addr_in); | |
30210 | - | |
30211 | + | |
30212 | scgi_addr = (struct sockaddr *) &scgi_addr_in; | |
30213 | } | |
30214 | - | |
30215 | + | |
30216 | if (-1 == connect(scgi_fd, scgi_addr, servlen)) { | |
30217 | - if (errno == EINPROGRESS || | |
30218 | + if (errno == EINPROGRESS || | |
30219 | errno == EALREADY || | |
30220 | errno == EINTR) { | |
30221 | if (hctx->conf.debug) { | |
30222 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
30223 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
30224 | "connect delayed, will continue later:", scgi_fd); | |
30225 | } | |
30226 | - | |
30227 | + | |
30228 | return 1; | |
30229 | } else { | |
30230 | - log_error_write(srv, __FILE__, __LINE__, "sdsddb", | |
30231 | - "connect failed:", scgi_fd, | |
30232 | + log_error_write(srv, __FILE__, __LINE__, "sdsddb", | |
30233 | + "connect failed:", scgi_fd, | |
30234 | strerror(errno), errno, | |
30235 | proc->port, proc->socket); | |
30236 | ||
30237 | if (errno == EAGAIN) { | |
30238 | /* this is Linux only */ | |
30239 | - | |
30240 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
30241 | + | |
30242 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
30243 | "If this happend on Linux: You have been run out of local ports. " | |
30244 | "Check the manual, section Performance how to handle this."); | |
30245 | - } | |
30246 | - | |
30247 | + } | |
30248 | + | |
30249 | return -1; | |
30250 | } | |
30251 | } | |
30252 | if (hctx->conf.debug > 1) { | |
30253 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
30254 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
30255 | "connect succeeded: ", scgi_fd); | |
30256 | } | |
30257 | ||
30258 | ||
30259 | - | |
30260 | + | |
30261 | return 0; | |
30262 | } | |
30263 | ||
30264 | static int scgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) { | |
30265 | size_t i; | |
30266 | - | |
30267 | + | |
30268 | for (i = 0; i < con->request.headers->used; i++) { | |
30269 | data_string *ds; | |
30270 | - | |
30271 | + | |
30272 | ds = (data_string *)con->request.headers->data[i]; | |
30273 | - | |
30274 | + | |
30275 | if (ds->value->used && ds->key->used) { | |
30276 | size_t j; | |
30277 | buffer_reset(srv->tmp_buf); | |
30278 | - | |
30279 | + | |
30280 | if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { | |
30281 | BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_"); | |
30282 | srv->tmp_buf->used--; | |
30283 | } | |
30284 | - | |
30285 | + | |
30286 | buffer_prepare_append(srv->tmp_buf, ds->key->used + 2); | |
30287 | for (j = 0; j < ds->key->used - 1; j++) { | |
30288 | - srv->tmp_buf->ptr[srv->tmp_buf->used++] = | |
30289 | - light_isalpha(ds->key->ptr[j]) ? | |
30290 | + srv->tmp_buf->ptr[srv->tmp_buf->used++] = | |
30291 | + light_isalpha(ds->key->ptr[j]) ? | |
30292 | ds->key->ptr[j] & ~32 : '_'; | |
30293 | } | |
30294 | srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0'; | |
30295 | - | |
30296 | + | |
30297 | scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)); | |
30298 | } | |
30299 | } | |
30300 | - | |
30301 | + | |
30302 | for (i = 0; i < con->environment->used; i++) { | |
30303 | data_string *ds; | |
30304 | - | |
30305 | + | |
30306 | ds = (data_string *)con->environment->data[i]; | |
30307 | - | |
30308 | + | |
30309 | if (ds->value->used && ds->key->used) { | |
30310 | size_t j; | |
30311 | buffer_reset(srv->tmp_buf); | |
30312 | - | |
30313 | + | |
30314 | buffer_prepare_append(srv->tmp_buf, ds->key->used + 2); | |
30315 | for (j = 0; j < ds->key->used - 1; j++) { | |
30316 | - srv->tmp_buf->ptr[srv->tmp_buf->used++] = | |
30317 | - isalpha((unsigned char)ds->key->ptr[j]) ? | |
30318 | + srv->tmp_buf->ptr[srv->tmp_buf->used++] = | |
30319 | + isalpha((unsigned char)ds->key->ptr[j]) ? | |
30320 | toupper((unsigned char)ds->key->ptr[j]) : '_'; | |
30321 | } | |
30322 | srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0'; | |
30323 | - | |
30324 | + | |
30325 | scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)); | |
30326 | } | |
30327 | } | |
30328 | - | |
30329 | + | |
30330 | return 0; | |
30331 | } | |
30332 | ||
30333 | @@ -1415,20 +1411,20 @@ | |
30334 | char b2[INET6_ADDRSTRLEN + 1]; | |
30335 | #endif | |
30336 | buffer *b; | |
30337 | - | |
30338 | + | |
30339 | plugin_data *p = hctx->plugin_data; | |
30340 | scgi_extension_host *host= hctx->host; | |
30341 | ||
30342 | connection *con = hctx->remote_conn; | |
30343 | server_socket *srv_sock = con->srv_socket; | |
30344 | - | |
30345 | + | |
30346 | sock_addr our_addr; | |
30347 | socklen_t our_addr_len; | |
30348 | - | |
30349 | + | |
30350 | buffer_prepare_copy(p->scgi_env, 1024); | |
30351 | ||
30352 | /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */ | |
30353 | - | |
30354 | + | |
30355 | /* request.content_length < SSIZE_MAX, see request.c */ | |
30356 | ltostr(buf, con->request.content_length); | |
30357 | scgi_env_add(p->scgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)); | |
30358 | @@ -1436,13 +1432,13 @@ | |
30359 | ||
30360 | ||
30361 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION)); | |
30362 | - | |
30363 | + | |
30364 | if (con->server_name->used) { | |
30365 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name)); | |
30366 | } else { | |
30367 | #ifdef HAVE_IPV6 | |
30368 | - s = inet_ntop(srv_sock->addr.plain.sa_family, | |
30369 | - srv_sock->addr.plain.sa_family == AF_INET6 ? | |
30370 | + s = inet_ntop(srv_sock->addr.plain.sa_family, | |
30371 | + srv_sock->addr.plain.sa_family == AF_INET6 ? | |
30372 | (const void *) &(srv_sock->addr.ipv6.sin6_addr) : | |
30373 | (const void *) &(srv_sock->addr.ipv4.sin_addr), | |
30374 | b2, sizeof(b2)-1); | |
30375 | @@ -1451,47 +1447,47 @@ | |
30376 | #endif | |
30377 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s)); | |
30378 | } | |
30379 | - | |
30380 | + | |
30381 | scgi_env_add(p->scgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")); | |
30382 | - | |
30383 | - ltostr(buf, | |
30384 | + | |
30385 | + ltostr(buf, | |
30386 | #ifdef HAVE_IPV6 | |
30387 | ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port) | |
30388 | #else | |
30389 | ntohs(srv_sock->addr.ipv4.sin_port) | |
30390 | #endif | |
30391 | ); | |
30392 | - | |
30393 | + | |
30394 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf)); | |
30395 | - | |
30396 | + | |
30397 | /* get the server-side of the connection to the client */ | |
30398 | our_addr_len = sizeof(our_addr); | |
30399 | - | |
30400 | + | |
30401 | if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) { | |
30402 | s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr)); | |
30403 | } else { | |
30404 | s = inet_ntop_cache_get_ip(srv, &(our_addr)); | |
30405 | } | |
30406 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s)); | |
30407 | - | |
30408 | - ltostr(buf, | |
30409 | + | |
30410 | + ltostr(buf, | |
30411 | #ifdef HAVE_IPV6 | |
30412 | ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port) | |
30413 | #else | |
30414 | ntohs(con->dst_addr.ipv4.sin_port) | |
30415 | #endif | |
30416 | ); | |
30417 | - | |
30418 | + | |
30419 | scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf)); | |
30420 | - | |
30421 | + | |
30422 | s = inet_ntop_cache_get_ip(srv, &(con->dst_addr)); | |
30423 | scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s)); | |
30424 | - | |
30425 | + | |
30426 | if (!buffer_is_empty(con->authed_user)) { | |
30427 | scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_USER"), | |
30428 | CONST_BUF_LEN(con->authed_user)); | |
30429 | } | |
30430 | - | |
30431 | + | |
30432 | ||
30433 | /* | |
30434 | * SCRIPT_NAME, PATH_INFO and PATH_TRANSLATED according to | |
30435 | @@ -1500,12 +1496,12 @@ | |
30436 | */ | |
30437 | ||
30438 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)); | |
30439 | - | |
30440 | + | |
30441 | if (!buffer_is_empty(con->request.pathinfo)) { | |
30442 | scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo)); | |
30443 | - | |
30444 | + | |
30445 | /* PATH_TRANSLATED is only defined if PATH_INFO is set */ | |
30446 | - | |
30447 | + | |
30448 | if (!buffer_is_empty(host->docroot)) { | |
30449 | buffer_copy_string_buffer(p->path, host->docroot); | |
30450 | } else { | |
30451 | @@ -1526,19 +1522,19 @@ | |
30452 | */ | |
30453 | ||
30454 | if (!buffer_is_empty(host->docroot)) { | |
30455 | - /* | |
30456 | - * rewrite SCRIPT_FILENAME | |
30457 | - * | |
30458 | + /* | |
30459 | + * rewrite SCRIPT_FILENAME | |
30460 | + * | |
30461 | */ | |
30462 | - | |
30463 | + | |
30464 | buffer_copy_string_buffer(p->path, host->docroot); | |
30465 | buffer_append_string_buffer(p->path, con->uri.path); | |
30466 | - | |
30467 | + | |
30468 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)); | |
30469 | scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot)); | |
30470 | } else { | |
30471 | buffer_copy_string_buffer(p->path, con->physical.path); | |
30472 | - | |
30473 | + | |
30474 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)); | |
30475 | scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root)); | |
30476 | } | |
30477 | @@ -1551,30 +1547,30 @@ | |
30478 | } else { | |
30479 | scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN("")); | |
30480 | } | |
30481 | - | |
30482 | + | |
30483 | s = get_http_method_name(con->request.http_method); | |
30484 | scgi_env_add(p->scgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s)); | |
30485 | scgi_env_add(p->scgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */ | |
30486 | s = get_http_version_name(con->request.http_version); | |
30487 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s)); | |
30488 | - | |
30489 | + | |
30490 | #ifdef USE_OPENSSL | |
30491 | if (srv_sock->is_ssl) { | |
30492 | scgi_env_add(p->scgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); | |
30493 | } | |
30494 | #endif | |
30495 | - | |
30496 | + | |
30497 | scgi_env_add_request_headers(srv, con, p); | |
30498 | ||
30499 | b = chunkqueue_get_append_buffer(hctx->wb); | |
30500 | - | |
30501 | + | |
30502 | buffer_append_long(b, p->scgi_env->used); | |
30503 | buffer_append_string_len(b, CONST_STR_LEN(":")); | |
30504 | buffer_append_string_len(b, (const char *)p->scgi_env->ptr, p->scgi_env->used); | |
30505 | buffer_append_string_len(b, CONST_STR_LEN(",")); | |
30506 | ||
30507 | hctx->wb->bytes_in += b->used - 1; | |
30508 | - | |
30509 | + | |
30510 | if (con->request.content_length) { | |
30511 | chunkqueue *req_cq = con->request_content_queue; | |
30512 | chunk *req_c; | |
30513 | @@ -1587,7 +1583,7 @@ | |
30514 | ||
30515 | /* we announce toWrite octects | |
30516 | * now take all the request_content chunk that we need to fill this request | |
30517 | - * */ | |
30518 | + * */ | |
30519 | ||
30520 | switch (req_c->type) { | |
30521 | case FILE_CHUNK: | |
30522 | @@ -1615,32 +1611,32 @@ | |
30523 | ||
30524 | req_c->offset += weHave; | |
30525 | req_cq->bytes_out += weHave; | |
30526 | - | |
30527 | + | |
30528 | hctx->wb->bytes_in += weHave; | |
30529 | ||
30530 | break; | |
30531 | default: | |
30532 | break; | |
30533 | } | |
30534 | - | |
30535 | + | |
30536 | offset += weHave; | |
30537 | } | |
30538 | } | |
30539 | - | |
30540 | + | |
30541 | #if 0 | |
30542 | for (i = 0; i < hctx->write_buffer->used; i++) { | |
30543 | fprintf(stderr, "%02x ", hctx->write_buffer->ptr[i]); | |
30544 | if ((i+1) % 16 == 0) { | |
30545 | size_t j; | |
30546 | for (j = i-15; j <= i; j++) { | |
30547 | - fprintf(stderr, "%c", | |
30548 | + fprintf(stderr, "%c", | |
30549 | isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.'); | |
30550 | } | |
30551 | fprintf(stderr, "\n"); | |
30552 | } | |
30553 | } | |
30554 | #endif | |
30555 | - | |
30556 | + | |
30557 | return 0; | |
30558 | } | |
30559 | ||
30560 | @@ -1648,32 +1644,32 @@ | |
30561 | char *ns; | |
30562 | const char *s; | |
30563 | int line = 0; | |
30564 | - | |
30565 | + | |
30566 | UNUSED(srv); | |
30567 | - | |
30568 | + | |
30569 | buffer_copy_string_buffer(p->parse_response, in); | |
30570 | - | |
30571 | - for (s = p->parse_response->ptr; | |
30572 | - NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); | |
30573 | + | |
30574 | + for (s = p->parse_response->ptr; | |
30575 | + NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); | |
30576 | s = ns + (eol == EOL_RN ? 2 : 1), line++) { | |
30577 | const char *key, *value; | |
30578 | int key_len; | |
30579 | data_string *ds; | |
30580 | - | |
30581 | + | |
30582 | ns[0] = '\0'; | |
30583 | - | |
30584 | - if (line == 0 && | |
30585 | + | |
30586 | + if (line == 0 && | |
30587 | 0 == strncmp(s, "HTTP/1.", 7)) { | |
30588 | /* non-parsed header ... we parse them anyway */ | |
30589 | - | |
30590 | + | |
30591 | if ((s[7] == '1' || | |
30592 | s[7] == '0') && | |
30593 | s[8] == ' ') { | |
30594 | int status; | |
30595 | /* after the space should be a status code for us */ | |
30596 | - | |
30597 | + | |
30598 | status = strtol(s+9, NULL, 10); | |
30599 | - | |
30600 | + | |
30601 | if (con->http_status >= 100 && | |
30602 | con->http_status < 1000) { | |
30603 | /* we expected 3 digits and didn't got them */ | |
30604 | @@ -1682,27 +1678,27 @@ | |
30605 | } | |
30606 | } | |
30607 | } else { | |
30608 | - | |
30609 | + | |
30610 | key = s; | |
30611 | if (NULL == (value = strchr(s, ':'))) { | |
30612 | /* we expect: "<key>: <value>\r\n" */ | |
30613 | continue; | |
30614 | } | |
30615 | - | |
30616 | + | |
30617 | key_len = value - key; | |
30618 | value += 1; | |
30619 | - | |
30620 | + | |
30621 | /* skip LWS */ | |
30622 | while (*value == ' ' || *value == '\t') value++; | |
30623 | - | |
30624 | + | |
30625 | if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { | |
30626 | ds = data_response_init(); | |
30627 | } | |
30628 | buffer_copy_string_len(ds->key, key, key_len); | |
30629 | buffer_copy_string(ds->value, value); | |
30630 | - | |
30631 | + | |
30632 | array_insert_unique(con->response.headers, (data_unset *)ds); | |
30633 | - | |
30634 | + | |
30635 | switch(key_len) { | |
30636 | case 4: | |
30637 | if (0 == strncasecmp(key, "Date", key_len)) { | |
30638 | @@ -1737,13 +1733,13 @@ | |
30639 | } | |
30640 | } | |
30641 | } | |
30642 | - | |
30643 | + | |
30644 | /* CGI/1.1 rev 03 - 7.2.1.2 */ | |
30645 | if ((con->parsed_response & HTTP_LOCATION) && | |
30646 | !(con->parsed_response & HTTP_STATUS)) { | |
30647 | con->http_status = 302; | |
30648 | } | |
30649 | - | |
30650 | + | |
30651 | return 0; | |
30652 | } | |
30653 | ||
30654 | @@ -1751,10 +1747,10 @@ | |
30655 | static int scgi_demux_response(server *srv, handler_ctx *hctx) { | |
30656 | plugin_data *p = hctx->plugin_data; | |
30657 | connection *con = hctx->remote_conn; | |
30658 | - | |
30659 | + | |
30660 | while(1) { | |
30661 | int n; | |
30662 | - | |
30663 | + | |
30664 | buffer_prepare_copy(hctx->response, 1024); | |
30665 | if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) { | |
30666 | if (errno == EAGAIN || errno == EINTR) { | |
30667 | @@ -1765,143 +1761,143 @@ | |
30668 | log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd); | |
30669 | return -1; | |
30670 | } | |
30671 | - | |
30672 | + | |
30673 | if (n == 0) { | |
30674 | /* read finished */ | |
30675 | - | |
30676 | + | |
30677 | con->file_finished = 1; | |
30678 | - | |
30679 | + | |
30680 | /* send final chunk */ | |
30681 | http_chunk_append_mem(srv, con, NULL, 0); | |
30682 | joblist_append(srv, con); | |
30683 | - | |
30684 | + | |
30685 | return 1; | |
30686 | } | |
30687 | - | |
30688 | + | |
30689 | hctx->response->ptr[n] = '\0'; | |
30690 | hctx->response->used = n+1; | |
30691 | - | |
30692 | + | |
30693 | /* split header from body */ | |
30694 | - | |
30695 | + | |
30696 | if (con->file_started == 0) { | |
30697 | char *c; | |
30698 | int in_header = 0; | |
30699 | int header_end = 0; | |
30700 | int cp, eol = EOL_UNSET; | |
30701 | size_t used = 0; | |
30702 | - | |
30703 | + | |
30704 | buffer_append_string_buffer(hctx->response_header, hctx->response); | |
30705 | - | |
30706 | + | |
30707 | /* nph (non-parsed headers) */ | |
30708 | if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1; | |
30709 | - | |
30710 | + | |
30711 | /* search for the \r\n\r\n or \n\n in the string */ | |
30712 | for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) { | |
30713 | if (*c == ':') in_header = 1; | |
30714 | else if (*c == '\n') { | |
30715 | if (in_header == 0) { | |
30716 | /* got a response without a response header */ | |
30717 | - | |
30718 | + | |
30719 | c = NULL; | |
30720 | header_end = 1; | |
30721 | break; | |
30722 | } | |
30723 | - | |
30724 | + | |
30725 | if (eol == EOL_UNSET) eol = EOL_N; | |
30726 | - | |
30727 | + | |
30728 | if (*(c+1) == '\n') { | |
30729 | header_end = 1; | |
30730 | break; | |
30731 | } | |
30732 | - | |
30733 | + | |
30734 | } else if (used > 1 && *c == '\r' && *(c+1) == '\n') { | |
30735 | if (in_header == 0) { | |
30736 | /* got a response without a response header */ | |
30737 | - | |
30738 | + | |
30739 | c = NULL; | |
30740 | header_end = 1; | |
30741 | break; | |
30742 | } | |
30743 | - | |
30744 | + | |
30745 | if (eol == EOL_UNSET) eol = EOL_RN; | |
30746 | - | |
30747 | + | |
30748 | if (used > 3 && | |
30749 | - *(c+2) == '\r' && | |
30750 | + *(c+2) == '\r' && | |
30751 | *(c+3) == '\n') { | |
30752 | header_end = 1; | |
30753 | break; | |
30754 | } | |
30755 | - | |
30756 | + | |
30757 | /* skip the \n */ | |
30758 | c++; | |
30759 | cp++; | |
30760 | used--; | |
30761 | } | |
30762 | } | |
30763 | - | |
30764 | + | |
30765 | if (header_end) { | |
30766 | if (c == NULL) { | |
30767 | /* no header, but a body */ | |
30768 | - | |
30769 | + | |
30770 | if (con->request.http_version == HTTP_VERSION_1_1) { | |
30771 | con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
30772 | } | |
30773 | - | |
30774 | + | |
30775 | http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used); | |
30776 | joblist_append(srv, con); | |
30777 | } else { | |
30778 | size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2); | |
30779 | size_t blen = hctx->response_header->used - hlen - 1; | |
30780 | - | |
30781 | + | |
30782 | /* a small hack: terminate after at the second \r */ | |
30783 | hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1); | |
30784 | hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0'; | |
30785 | - | |
30786 | + | |
30787 | /* parse the response header */ | |
30788 | scgi_response_parse(srv, con, p, hctx->response_header, eol); | |
30789 | - | |
30790 | + | |
30791 | /* enable chunked-transfer-encoding */ | |
30792 | if (con->request.http_version == HTTP_VERSION_1_1 && | |
30793 | !(con->parsed_response & HTTP_CONTENT_LENGTH)) { | |
30794 | con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED; | |
30795 | } | |
30796 | - | |
30797 | + | |
30798 | if ((hctx->response->used != hlen) && blen > 0) { | |
30799 | http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1); | |
30800 | joblist_append(srv, con); | |
30801 | } | |
30802 | } | |
30803 | - | |
30804 | + | |
30805 | con->file_started = 1; | |
30806 | } | |
30807 | } else { | |
30808 | http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used); | |
30809 | joblist_append(srv, con); | |
30810 | } | |
30811 | - | |
30812 | -#if 0 | |
30813 | + | |
30814 | +#if 0 | |
30815 | log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr); | |
30816 | #endif | |
30817 | } | |
30818 | - | |
30819 | + | |
30820 | return 0; | |
30821 | } | |
30822 | ||
30823 | ||
30824 | int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) { | |
30825 | scgi_proc *p; | |
30826 | - | |
30827 | + | |
30828 | UNUSED(srv); | |
30829 | - | |
30830 | - /* we have been the smallest of the current list | |
30831 | - * and we want to insert the node sorted as soon | |
30832 | + | |
30833 | + /* we have been the smallest of the current list | |
30834 | + * and we want to insert the node sorted as soon | |
30835 | * possible | |
30836 | * | |
30837 | - * 1 0 0 0 1 1 1 | |
30838 | - * | ^ | |
30839 | + * 1 0 0 0 1 1 1 | |
30840 | + * | ^ | |
30841 | * | | | |
30842 | * +------+ | |
30843 | - * | |
30844 | + * | |
30845 | */ | |
30846 | ||
30847 | /* nothing to sort, only one element */ | |
30848 | @@ -1909,9 +1905,9 @@ | |
30849 | ||
30850 | for (p = proc; p->next && p->next->load < proc->load; p = p->next); | |
30851 | ||
30852 | - /* no need to move something | |
30853 | + /* no need to move something | |
30854 | * | |
30855 | - * 1 2 2 2 3 3 3 | |
30856 | + * 1 2 2 2 3 3 3 | |
30857 | * ^ | |
30858 | * | | |
30859 | * + | |
30860 | @@ -1930,16 +1926,16 @@ | |
30861 | ||
30862 | if (proc->prev) proc->prev->next = proc->next; | |
30863 | if (proc->next) proc->next->prev = proc->prev; | |
30864 | - | |
30865 | + | |
30866 | /* proc should be right of p */ | |
30867 | - | |
30868 | + | |
30869 | proc->next = p->next; | |
30870 | proc->prev = p; | |
30871 | if (p->next) p->next->prev = proc; | |
30872 | p->next = proc; | |
30873 | #if 0 | |
30874 | for(p = host->first; p; p = p->next) { | |
30875 | - log_error_write(srv, __FILE__, __LINE__, "dd", | |
30876 | + log_error_write(srv, __FILE__, __LINE__, "dd", | |
30877 | p->pid, p->load); | |
30878 | } | |
30879 | #else | |
30880 | @@ -1951,21 +1947,21 @@ | |
30881 | ||
30882 | int scgi_proclist_sort_down(server *srv, scgi_extension_host *host, scgi_proc *proc) { | |
30883 | scgi_proc *p; | |
30884 | - | |
30885 | + | |
30886 | UNUSED(srv); | |
30887 | - | |
30888 | - /* we have been the smallest of the current list | |
30889 | - * and we want to insert the node sorted as soon | |
30890 | + | |
30891 | + /* we have been the smallest of the current list | |
30892 | + * and we want to insert the node sorted as soon | |
30893 | * possible | |
30894 | * | |
30895 | - * 0 0 0 0 1 0 1 | |
30896 | + * 0 0 0 0 1 0 1 | |
30897 | * ^ | | |
30898 | * | | | |
30899 | * +----------+ | |
30900 | * | |
30901 | * | |
30902 | * the basic is idea is: | |
30903 | - * - the last active scgi process should be still | |
30904 | + * - the last active scgi process should be still | |
30905 | * in ram and is not swapped out yet | |
30906 | * - processes that are not reused will be killed | |
30907 | * after some time by the trigger-handler | |
30908 | @@ -1975,7 +1971,7 @@ | |
30909 | * ice-cold processes are propably unused since more | |
30910 | * than 'unused-timeout', are swaped out and won't be | |
30911 | * reused in the next seconds anyway. | |
30912 | - * | |
30913 | + * | |
30914 | */ | |
30915 | ||
30916 | /* nothing to sort, only one element */ | |
30917 | @@ -1984,16 +1980,16 @@ | |
30918 | for (p = host->first; p != proc && p->load < proc->load; p = p->next); | |
30919 | ||
30920 | ||
30921 | - /* no need to move something | |
30922 | + /* no need to move something | |
30923 | * | |
30924 | - * 1 2 2 2 3 3 3 | |
30925 | + * 1 2 2 2 3 3 3 | |
30926 | * ^ | |
30927 | * | | |
30928 | * + | |
30929 | * | |
30930 | */ | |
30931 | if (p == proc) return 0; | |
30932 | - | |
30933 | + | |
30934 | /* we have to move left. If we are already the first element | |
30935 | * we are done */ | |
30936 | if (host->first == proc) return 0; | |
30937 | @@ -2009,9 +2005,9 @@ | |
30938 | p->prev = proc; | |
30939 | ||
30940 | if (proc->prev == NULL) host->first = proc; | |
30941 | -#if 0 | |
30942 | +#if 0 | |
30943 | for(p = host->first; p; p = p->next) { | |
30944 | - log_error_write(srv, __FILE__, __LINE__, "dd", | |
30945 | + log_error_write(srv, __FILE__, __LINE__, "dd", | |
30946 | p->pid, p->load); | |
30947 | } | |
30948 | #else | |
30949 | @@ -2023,41 +2019,42 @@ | |
30950 | ||
30951 | static int scgi_restart_dead_procs(server *srv, plugin_data *p, scgi_extension_host *host) { | |
30952 | scgi_proc *proc; | |
30953 | - | |
30954 | + | |
30955 | for (proc = host->first; proc; proc = proc->next) { | |
30956 | if (p->conf.debug) { | |
30957 | - log_error_write(srv, __FILE__, __LINE__, "sbdbdddd", | |
30958 | - "proc:", | |
30959 | - host->host, proc->port, | |
30960 | + log_error_write(srv, __FILE__, __LINE__, "sbdbdddd", | |
30961 | + "proc:", | |
30962 | + host->host, proc->port, | |
30963 | proc->socket, | |
30964 | proc->state, | |
30965 | proc->is_local, | |
30966 | proc->load, | |
30967 | proc->pid); | |
30968 | } | |
30969 | - | |
30970 | + | |
30971 | if (0 == proc->is_local) { | |
30972 | - /* | |
30973 | - * external servers might get disabled | |
30974 | - * | |
30975 | - * enable the server again, perhaps it is back again | |
30976 | + /* | |
30977 | + * external servers might get disabled | |
30978 | + * | |
30979 | + * enable the server again, perhaps it is back again | |
30980 | */ | |
30981 | - | |
30982 | + | |
30983 | if ((proc->state == PROC_STATE_DISABLED) && | |
30984 | (srv->cur_ts - proc->disable_ts > host->disable_time)) { | |
30985 | proc->state = PROC_STATE_RUNNING; | |
30986 | host->active_procs++; | |
30987 | - | |
30988 | - log_error_write(srv, __FILE__, __LINE__, "sbdb", | |
30989 | - "fcgi-server re-enabled:", | |
30990 | - host->host, host->port, | |
30991 | + | |
30992 | + log_error_write(srv, __FILE__, __LINE__, "sbdb", | |
30993 | + "fcgi-server re-enabled:", | |
30994 | + host->host, host->port, | |
30995 | host->unixsocket); | |
30996 | } | |
30997 | } else { | |
30998 | /* the child should not terminate at all */ | |
30999 | int status; | |
31000 | - | |
31001 | + | |
31002 | if (proc->state == PROC_STATE_DIED_WAIT_FOR_PID) { | |
31003 | +#ifndef _WIN32 | |
31004 | switch(waitpid(proc->pid, &status, WNOHANG)) { | |
31005 | case 0: | |
31006 | /* child is still alive */ | |
31007 | @@ -2067,33 +2064,34 @@ | |
31008 | default: | |
31009 | if (WIFEXITED(status)) { | |
31010 | #if 0 | |
31011 | - log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
31012 | + log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
31013 | "child exited, pid:", proc->pid, | |
31014 | "status:", WEXITSTATUS(status)); | |
31015 | #endif | |
31016 | } else if (WIFSIGNALED(status)) { | |
31017 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
31018 | - "child signaled:", | |
31019 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
31020 | + "child signaled:", | |
31021 | WTERMSIG(status)); | |
31022 | } else { | |
31023 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
31024 | - "child died somehow:", | |
31025 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
31026 | + "child died somehow:", | |
31027 | status); | |
31028 | } | |
31029 | - | |
31030 | + | |
31031 | proc->state = PROC_STATE_DIED; | |
31032 | break; | |
31033 | } | |
31034 | +#endif | |
31035 | } | |
31036 | - | |
31037 | - /* | |
31038 | + | |
31039 | + /* | |
31040 | * local servers might died, but we restart them | |
31041 | - * | |
31042 | + * | |
31043 | */ | |
31044 | if (proc->state == PROC_STATE_DIED && | |
31045 | proc->load == 0) { | |
31046 | /* restart the child */ | |
31047 | - | |
31048 | + | |
31049 | if (p->conf.debug) { | |
31050 | log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd", | |
31051 | "--- scgi spawning", | |
31052 | @@ -2101,18 +2099,18 @@ | |
31053 | "\n\tsocket", host->unixsocket, | |
31054 | "\n\tcurrent:", 1, "/", host->min_procs); | |
31055 | } | |
31056 | - | |
31057 | + | |
31058 | if (scgi_spawn_connection(srv, p, host, proc)) { | |
31059 | log_error_write(srv, __FILE__, __LINE__, "s", | |
31060 | "ERROR: spawning fcgi failed."); | |
31061 | return HANDLER_ERROR; | |
31062 | } | |
31063 | - | |
31064 | + | |
31065 | scgi_proclist_sort_down(srv, host, proc); | |
31066 | } | |
31067 | } | |
31068 | } | |
31069 | - | |
31070 | + | |
31071 | return 0; | |
31072 | } | |
31073 | ||
31074 | @@ -2121,13 +2119,13 @@ | |
31075 | plugin_data *p = hctx->plugin_data; | |
31076 | scgi_extension_host *host= hctx->host; | |
31077 | connection *con = hctx->remote_conn; | |
31078 | - | |
31079 | + | |
31080 | int ret; | |
31081 | ||
31082 | - /* sanity check */ | |
31083 | + /* sanity check */ | |
31084 | if (!host || | |
31085 | ((!host->host->used || !host->port) && !host->unixsocket->used)) { | |
31086 | - log_error_write(srv, __FILE__, __LINE__, "sxddd", | |
31087 | + log_error_write(srv, __FILE__, __LINE__, "sxddd", | |
31088 | "write-req: error", | |
31089 | host, | |
31090 | host->host->used, | |
31091 | @@ -2135,179 +2133,180 @@ | |
31092 | host->unixsocket->used); | |
31093 | return HANDLER_ERROR; | |
31094 | } | |
31095 | - | |
31096 | + | |
31097 | ||
31098 | switch(hctx->state) { | |
31099 | case FCGI_STATE_INIT: | |
31100 | ret = host->unixsocket->used ? AF_UNIX : AF_INET; | |
31101 | - | |
31102 | + | |
31103 | if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) { | |
31104 | if (errno == EMFILE || | |
31105 | errno == EINTR) { | |
31106 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
31107 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
31108 | "wait for fd at connection:", con->fd); | |
31109 | - | |
31110 | + | |
31111 | return HANDLER_WAIT_FOR_FD; | |
31112 | } | |
31113 | - | |
31114 | - log_error_write(srv, __FILE__, __LINE__, "ssdd", | |
31115 | + | |
31116 | + log_error_write(srv, __FILE__, __LINE__, "ssdd", | |
31117 | "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds); | |
31118 | return HANDLER_ERROR; | |
31119 | } | |
31120 | hctx->fde_ndx = -1; | |
31121 | - | |
31122 | + | |
31123 | srv->cur_fds++; | |
31124 | - | |
31125 | + | |
31126 | fdevent_register(srv->ev, hctx->fd, scgi_handle_fdevent, hctx); | |
31127 | - | |
31128 | + | |
31129 | if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) { | |
31130 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
31131 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
31132 | "fcntl failed: ", strerror(errno)); | |
31133 | - | |
31134 | + | |
31135 | return HANDLER_ERROR; | |
31136 | } | |
31137 | - | |
31138 | + | |
31139 | /* fall through */ | |
31140 | case FCGI_STATE_CONNECT: | |
31141 | if (hctx->state == FCGI_STATE_INIT) { | |
31142 | - for (hctx->proc = hctx->host->first; | |
31143 | - hctx->proc && hctx->proc->state != PROC_STATE_RUNNING; | |
31144 | + for (hctx->proc = hctx->host->first; | |
31145 | + hctx->proc && hctx->proc->state != PROC_STATE_RUNNING; | |
31146 | hctx->proc = hctx->proc->next); | |
31147 | - | |
31148 | + | |
31149 | /* all childs are dead */ | |
31150 | if (hctx->proc == NULL) { | |
31151 | hctx->fde_ndx = -1; | |
31152 | - | |
31153 | + | |
31154 | return HANDLER_ERROR; | |
31155 | } | |
31156 | - | |
31157 | + | |
31158 | if (hctx->proc->is_local) { | |
31159 | hctx->pid = hctx->proc->pid; | |
31160 | } | |
31161 | - | |
31162 | + | |
31163 | switch (scgi_establish_connection(srv, hctx)) { | |
31164 | case 1: | |
31165 | scgi_set_state(srv, hctx, FCGI_STATE_CONNECT); | |
31166 | - | |
31167 | + | |
31168 | /* connection is in progress, wait for an event and call getsockopt() below */ | |
31169 | - | |
31170 | + | |
31171 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
31172 | - | |
31173 | + | |
31174 | return HANDLER_WAIT_FOR_EVENT; | |
31175 | case -1: | |
31176 | /* if ECONNREFUSED choose another connection -> FIXME */ | |
31177 | hctx->fde_ndx = -1; | |
31178 | - | |
31179 | + | |
31180 | return HANDLER_ERROR; | |
31181 | default: | |
31182 | /* everything is ok, go on */ | |
31183 | break; | |
31184 | } | |
31185 | ||
31186 | - | |
31187 | + | |
31188 | } else { | |
31189 | int socket_error; | |
31190 | socklen_t socket_error_len = sizeof(socket_error); | |
31191 | - | |
31192 | + | |
31193 | /* try to finish the connect() */ | |
31194 | if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) { | |
31195 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
31196 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
31197 | "getsockopt failed:", strerror(errno)); | |
31198 | - | |
31199 | + | |
31200 | return HANDLER_ERROR; | |
31201 | } | |
31202 | if (socket_error != 0) { | |
31203 | if (!hctx->proc->is_local || p->conf.debug) { | |
31204 | /* local procs get restarted */ | |
31205 | - | |
31206 | + | |
31207 | log_error_write(srv, __FILE__, __LINE__, "ss", | |
31208 | - "establishing connection failed:", strerror(socket_error), | |
31209 | + "establishing connection failed:", strerror(socket_error), | |
31210 | "port:", hctx->proc->port); | |
31211 | } | |
31212 | - | |
31213 | + | |
31214 | return HANDLER_ERROR; | |
31215 | } | |
31216 | } | |
31217 | - | |
31218 | + | |
31219 | /* ok, we have the connection */ | |
31220 | - | |
31221 | + | |
31222 | hctx->proc->load++; | |
31223 | hctx->proc->last_used = srv->cur_ts; | |
31224 | hctx->got_proc = 1; | |
31225 | - | |
31226 | + | |
31227 | if (p->conf.debug) { | |
31228 | log_error_write(srv, __FILE__, __LINE__, "sddbdd", | |
31229 | - "got proc:", | |
31230 | + "got proc:", | |
31231 | hctx->fd, | |
31232 | - hctx->proc->pid, | |
31233 | - hctx->proc->socket, | |
31234 | + hctx->proc->pid, | |
31235 | + hctx->proc->socket, | |
31236 | hctx->proc->port, | |
31237 | hctx->proc->load); | |
31238 | } | |
31239 | ||
31240 | /* move the proc-list entry down the list */ | |
31241 | scgi_proclist_sort_up(srv, hctx->host, hctx->proc); | |
31242 | - | |
31243 | + | |
31244 | scgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE); | |
31245 | /* fall through */ | |
31246 | case FCGI_STATE_PREPARE_WRITE: | |
31247 | scgi_create_env(srv, hctx); | |
31248 | - | |
31249 | + | |
31250 | scgi_set_state(srv, hctx, FCGI_STATE_WRITE); | |
31251 | - | |
31252 | + | |
31253 | /* fall through */ | |
31254 | case FCGI_STATE_WRITE: | |
31255 | - ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); | |
31256 | + ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); | |
31257 | ||
31258 | chunkqueue_remove_finished_chunks(hctx->wb); | |
31259 | - | |
31260 | + | |
31261 | if (-1 == ret) { | |
31262 | if (errno == ENOTCONN) { | |
31263 | - /* the connection got dropped after accept() | |
31264 | - * | |
31265 | - * this is most of the time a PHP which dies | |
31266 | + /* the connection got dropped after accept() | |
31267 | + * | |
31268 | + * this is most of the time a PHP which dies | |
31269 | * after PHP_FCGI_MAX_REQUESTS | |
31270 | - * | |
31271 | - */ | |
31272 | + * | |
31273 | + */ | |
31274 | if (hctx->wb->bytes_out == 0 && | |
31275 | hctx->reconnects < 5) { | |
31276 | - usleep(10000); /* take away the load of the webserver | |
31277 | - * to let the php a chance to restart | |
31278 | +#ifndef _WIN32 | |
31279 | + usleep(10000); /* take away the load of the webserver | |
31280 | + * to let the php a chance to restart | |
31281 | */ | |
31282 | - | |
31283 | +#endif | |
31284 | scgi_reconnect(srv, hctx); | |
31285 | - | |
31286 | + | |
31287 | return HANDLER_WAIT_FOR_FD; | |
31288 | } | |
31289 | - | |
31290 | + | |
31291 | /* not reconnected ... why | |
31292 | - * | |
31293 | + * | |
31294 | * far@#lighttpd report this for FreeBSD | |
31295 | - * | |
31296 | + * | |
31297 | */ | |
31298 | - | |
31299 | - log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
31300 | + | |
31301 | + log_error_write(srv, __FILE__, __LINE__, "ssosd", | |
31302 | "[REPORT ME] connection was dropped after accept(). reconnect() denied:", | |
31303 | "write-offset:", hctx->wb->bytes_out, | |
31304 | "reconnect attempts:", hctx->reconnects); | |
31305 | - | |
31306 | + | |
31307 | return HANDLER_ERROR; | |
31308 | } | |
31309 | - | |
31310 | + | |
31311 | if ((errno != EAGAIN) && | |
31312 | (errno != EINTR)) { | |
31313 | - | |
31314 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
31315 | + | |
31316 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
31317 | "write failed:", strerror(errno), errno); | |
31318 | - | |
31319 | + | |
31320 | return HANDLER_ERROR; | |
31321 | } else { | |
31322 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
31323 | - | |
31324 | + | |
31325 | return HANDLER_WAIT_FOR_EVENT; | |
31326 | } | |
31327 | } | |
31328 | - | |
31329 | + | |
31330 | if (hctx->wb->bytes_out == hctx->wb->bytes_in) { | |
31331 | /* we don't need the out event anymore */ | |
31332 | fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); | |
31333 | @@ -2315,10 +2314,10 @@ | |
31334 | scgi_set_state(srv, hctx, FCGI_STATE_READ); | |
31335 | } else { | |
31336 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
31337 | - | |
31338 | + | |
31339 | return HANDLER_WAIT_FOR_EVENT; | |
31340 | } | |
31341 | - | |
31342 | + | |
31343 | break; | |
31344 | case FCGI_STATE_READ: | |
31345 | /* waiting for a response */ | |
31346 | @@ -2327,67 +2326,67 @@ | |
31347 | log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state"); | |
31348 | return HANDLER_ERROR; | |
31349 | } | |
31350 | - | |
31351 | + | |
31352 | return HANDLER_WAIT_FOR_EVENT; | |
31353 | } | |
31354 | ||
31355 | SUBREQUEST_FUNC(mod_scgi_handle_subrequest) { | |
31356 | plugin_data *p = p_d; | |
31357 | - | |
31358 | + | |
31359 | handler_ctx *hctx = con->plugin_ctx[p->id]; | |
31360 | scgi_proc *proc; | |
31361 | scgi_extension_host *host; | |
31362 | - | |
31363 | + | |
31364 | if (NULL == hctx) return HANDLER_GO_ON; | |
31365 | - | |
31366 | + | |
31367 | /* not my job */ | |
31368 | if (con->mode != p->id) return HANDLER_GO_ON; | |
31369 | - | |
31370 | + | |
31371 | /* ok, create the request */ | |
31372 | switch(scgi_write_request(srv, hctx)) { | |
31373 | case HANDLER_ERROR: | |
31374 | proc = hctx->proc; | |
31375 | host = hctx->host; | |
31376 | - | |
31377 | - if (proc && | |
31378 | + | |
31379 | + if (proc && | |
31380 | 0 == proc->is_local && | |
31381 | proc->state != PROC_STATE_DISABLED) { | |
31382 | /* only disable remote servers as we don't manage them*/ | |
31383 | - | |
31384 | - log_error_write(srv, __FILE__, __LINE__, "sbdb", "fcgi-server disabled:", | |
31385 | + | |
31386 | + log_error_write(srv, __FILE__, __LINE__, "sbdb", "fcgi-server disabled:", | |
31387 | host->host, | |
31388 | proc->port, | |
31389 | proc->socket); | |
31390 | - | |
31391 | + | |
31392 | /* disable this server */ | |
31393 | proc->disable_ts = srv->cur_ts; | |
31394 | proc->state = PROC_STATE_DISABLED; | |
31395 | host->active_procs--; | |
31396 | } | |
31397 | - | |
31398 | + | |
31399 | if (hctx->state == FCGI_STATE_INIT || | |
31400 | hctx->state == FCGI_STATE_CONNECT) { | |
31401 | - /* connect() or getsockopt() failed, | |
31402 | - * restart the request-handling | |
31403 | + /* connect() or getsockopt() failed, | |
31404 | + * restart the request-handling | |
31405 | */ | |
31406 | if (proc && proc->is_local) { | |
31407 | ||
31408 | if (p->conf.debug) { | |
31409 | - log_error_write(srv, __FILE__, __LINE__, "sbdb", "connect() to scgi failed, restarting the request-handling:", | |
31410 | + log_error_write(srv, __FILE__, __LINE__, "sbdb", "connect() to scgi failed, restarting the request-handling:", | |
31411 | host->host, | |
31412 | proc->port, | |
31413 | proc->socket); | |
31414 | } | |
31415 | ||
31416 | - /* | |
31417 | + /* | |
31418 | * several hctx might reference the same proc | |
31419 | - * | |
31420 | + * | |
31421 | * Only one of them should mark the proc as dead all the other | |
31422 | * ones should just take a new one. | |
31423 | - * | |
31424 | + * | |
31425 | * If a new proc was started with the old struct this might lead | |
31426 | * the mark a perfect proc as dead otherwise | |
31427 | - * | |
31428 | + * | |
31429 | */ | |
31430 | if (proc->state == PROC_STATE_RUNNING && | |
31431 | hctx->pid == proc->pid) { | |
31432 | @@ -2395,25 +2394,25 @@ | |
31433 | } | |
31434 | } | |
31435 | scgi_restart_dead_procs(srv, p, host); | |
31436 | - | |
31437 | + | |
31438 | scgi_connection_cleanup(srv, hctx); | |
31439 | - | |
31440 | + | |
31441 | buffer_reset(con->physical.path); | |
31442 | con->mode = DIRECT; | |
31443 | joblist_append(srv, con); | |
31444 | - | |
31445 | - /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop | |
31446 | - * and hope that the childs will be restarted | |
31447 | - * | |
31448 | + | |
31449 | + /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop | |
31450 | + * and hope that the childs will be restarted | |
31451 | + * | |
31452 | */ | |
31453 | return HANDLER_WAIT_FOR_FD; | |
31454 | } else { | |
31455 | scgi_connection_cleanup(srv, hctx); | |
31456 | - | |
31457 | + | |
31458 | buffer_reset(con->physical.path); | |
31459 | con->mode = DIRECT; | |
31460 | con->http_status = 503; | |
31461 | - | |
31462 | + | |
31463 | return HANDLER_FINISHED; | |
31464 | } | |
31465 | case HANDLER_WAIT_FOR_EVENT: | |
31466 | @@ -2433,23 +2432,23 @@ | |
31467 | static handler_t scgi_connection_close(server *srv, handler_ctx *hctx) { | |
31468 | plugin_data *p; | |
31469 | connection *con; | |
31470 | - | |
31471 | + | |
31472 | if (NULL == hctx) return HANDLER_GO_ON; | |
31473 | - | |
31474 | + | |
31475 | p = hctx->plugin_data; | |
31476 | con = hctx->remote_conn; | |
31477 | - | |
31478 | + | |
31479 | if (con->mode != p->id) return HANDLER_GO_ON; | |
31480 | - | |
31481 | - log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
31482 | - "emergency exit: scgi:", | |
31483 | + | |
31484 | + log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
31485 | + "emergency exit: scgi:", | |
31486 | "connection-fd:", con->fd, | |
31487 | "fcgi-fd:", hctx->fd); | |
31488 | - | |
31489 | - | |
31490 | - | |
31491 | + | |
31492 | + | |
31493 | + | |
31494 | scgi_connection_cleanup(srv, hctx); | |
31495 | - | |
31496 | + | |
31497 | return HANDLER_FINISHED; | |
31498 | } | |
31499 | ||
31500 | @@ -2459,7 +2458,7 @@ | |
31501 | handler_ctx *hctx = ctx; | |
31502 | connection *con = hctx->remote_conn; | |
31503 | plugin_data *p = hctx->plugin_data; | |
31504 | - | |
31505 | + | |
31506 | scgi_proc *proc = hctx->proc; | |
31507 | scgi_extension_host *host= hctx->host; | |
31508 | ||
31509 | @@ -2471,15 +2470,15 @@ | |
31510 | case 1: | |
31511 | /* we are done */ | |
31512 | scgi_connection_cleanup(srv, hctx); | |
31513 | - | |
31514 | + | |
31515 | joblist_append(srv, con); | |
31516 | return HANDLER_FINISHED; | |
31517 | case -1: | |
31518 | if (proc->pid && proc->state != PROC_STATE_DIED) { | |
31519 | int status; | |
31520 | - | |
31521 | + | |
31522 | /* only fetch the zombie if it is not already done */ | |
31523 | - | |
31524 | +#ifndef _WIN32 | |
31525 | switch(waitpid(proc->pid, &status, WNOHANG)) { | |
31526 | case 0: | |
31527 | /* child is still alive */ | |
31528 | @@ -2489,19 +2488,19 @@ | |
31529 | default: | |
31530 | /* the child should not terminate at all */ | |
31531 | if (WIFEXITED(status)) { | |
31532 | - log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
31533 | + log_error_write(srv, __FILE__, __LINE__, "sdsd", | |
31534 | "child exited, pid:", proc->pid, | |
31535 | "status:", WEXITSTATUS(status)); | |
31536 | } else if (WIFSIGNALED(status)) { | |
31537 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
31538 | - "child signaled:", | |
31539 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
31540 | + "child signaled:", | |
31541 | WTERMSIG(status)); | |
31542 | } else { | |
31543 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
31544 | - "child died somehow:", | |
31545 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
31546 | + "child died somehow:", | |
31547 | status); | |
31548 | } | |
31549 | - | |
31550 | + | |
31551 | if (p->conf.debug) { | |
31552 | log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd", | |
31553 | "--- scgi spawning", | |
31554 | @@ -2509,40 +2508,41 @@ | |
31555 | "\n\tsocket", host->unixsocket, | |
31556 | "\n\tcurrent:", 1, "/", host->min_procs); | |
31557 | } | |
31558 | - | |
31559 | + | |
31560 | if (scgi_spawn_connection(srv, p, host, proc)) { | |
31561 | /* child died */ | |
31562 | proc->state = PROC_STATE_DIED; | |
31563 | } else { | |
31564 | scgi_proclist_sort_down(srv, host, proc); | |
31565 | } | |
31566 | - | |
31567 | + | |
31568 | break; | |
31569 | } | |
31570 | +#endif | |
31571 | } | |
31572 | ||
31573 | if (con->file_started == 0) { | |
31574 | /* nothing has been send out yet, try to use another child */ | |
31575 | - | |
31576 | + | |
31577 | if (hctx->wb->bytes_out == 0 && | |
31578 | hctx->reconnects < 5) { | |
31579 | scgi_reconnect(srv, hctx); | |
31580 | - | |
31581 | - log_error_write(srv, __FILE__, __LINE__, "sdsdsd", | |
31582 | + | |
31583 | + log_error_write(srv, __FILE__, __LINE__, "sdsdsd", | |
31584 | "response not sent, request not sent, reconnection.", | |
31585 | "connection-fd:", con->fd, | |
31586 | "fcgi-fd:", hctx->fd); | |
31587 | - | |
31588 | + | |
31589 | return HANDLER_WAIT_FOR_FD; | |
31590 | } | |
31591 | - | |
31592 | - log_error_write(srv, __FILE__, __LINE__, "sdsdsd", | |
31593 | + | |
31594 | + log_error_write(srv, __FILE__, __LINE__, "sosdsd", | |
31595 | "response not sent, request sent:", hctx->wb->bytes_out, | |
31596 | "connection-fd:", con->fd, | |
31597 | "fcgi-fd:", hctx->fd); | |
31598 | - | |
31599 | + | |
31600 | scgi_connection_cleanup(srv, hctx); | |
31601 | - | |
31602 | + | |
31603 | connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); | |
31604 | buffer_reset(con->physical.path); | |
31605 | con->http_status = 500; | |
31606 | @@ -2550,76 +2550,76 @@ | |
31607 | } else { | |
31608 | /* response might have been already started, kill the connection */ | |
31609 | scgi_connection_cleanup(srv, hctx); | |
31610 | - | |
31611 | - log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
31612 | + | |
31613 | + log_error_write(srv, __FILE__, __LINE__, "ssdsd", | |
31614 | "response already sent out, termination connection", | |
31615 | "connection-fd:", con->fd, | |
31616 | "fcgi-fd:", hctx->fd); | |
31617 | - | |
31618 | + | |
31619 | connection_set_state(srv, con, CON_STATE_ERROR); | |
31620 | } | |
31621 | ||
31622 | /* */ | |
31623 | - | |
31624 | - | |
31625 | + | |
31626 | + | |
31627 | joblist_append(srv, con); | |
31628 | return HANDLER_FINISHED; | |
31629 | } | |
31630 | } | |
31631 | - | |
31632 | + | |
31633 | if (revents & FDEVENT_OUT) { | |
31634 | if (hctx->state == FCGI_STATE_CONNECT || | |
31635 | hctx->state == FCGI_STATE_WRITE) { | |
31636 | /* we are allowed to send something out | |
31637 | - * | |
31638 | + * | |
31639 | * 1. in a unfinished connect() call | |
31640 | * 2. in a unfinished write() call (long POST request) | |
31641 | */ | |
31642 | return mod_scgi_handle_subrequest(srv, con, p); | |
31643 | } else { | |
31644 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
31645 | - "got a FDEVENT_OUT and didn't know why:", | |
31646 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
31647 | + "got a FDEVENT_OUT and didn't know why:", | |
31648 | hctx->state); | |
31649 | } | |
31650 | } | |
31651 | - | |
31652 | + | |
31653 | /* perhaps this issue is already handled */ | |
31654 | if (revents & FDEVENT_HUP) { | |
31655 | if (hctx->state == FCGI_STATE_CONNECT) { | |
31656 | /* getoptsock will catch this one (right ?) | |
31657 | - * | |
31658 | - * if we are in connect we might get a EINPROGRESS | |
31659 | - * in the first call and a FDEVENT_HUP in the | |
31660 | + * | |
31661 | + * if we are in connect we might get a EINPROGRESS | |
31662 | + * in the first call and a FDEVENT_HUP in the | |
31663 | * second round | |
31664 | - * | |
31665 | + * | |
31666 | * FIXME: as it is a bit ugly. | |
31667 | - * | |
31668 | + * | |
31669 | */ | |
31670 | return mod_scgi_handle_subrequest(srv, con, p); | |
31671 | } else if (hctx->state == FCGI_STATE_READ && | |
31672 | hctx->proc->port == 0) { | |
31673 | /* FIXME: | |
31674 | - * | |
31675 | + * | |
31676 | * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket | |
31677 | * even if the FCGI_FIN packet is not received yet | |
31678 | */ | |
31679 | } else { | |
31680 | - log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", | |
31681 | - "error: unexpected close of scgi connection for", | |
31682 | + log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", | |
31683 | + "error: unexpected close of scgi connection for", | |
31684 | con->uri.path, | |
31685 | - "(no scgi process on host: ", | |
31686 | + "(no scgi process on host: ", | |
31687 | host->host, | |
31688 | - ", port: ", | |
31689 | + ", port: ", | |
31690 | host->port, | |
31691 | " ?)", | |
31692 | hctx->state); | |
31693 | - | |
31694 | + | |
31695 | connection_set_state(srv, con, CON_STATE_ERROR); | |
31696 | scgi_connection_close(srv, hctx); | |
31697 | joblist_append(srv, con); | |
31698 | } | |
31699 | } else if (revents & FDEVENT_ERR) { | |
31700 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
31701 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
31702 | "fcgi: got a FDEVENT_ERR. Don't know why."); | |
31703 | /* kill all connections to the scgi process */ | |
31704 | ||
31705 | @@ -2628,42 +2628,39 @@ | |
31706 | scgi_connection_close(srv, hctx); | |
31707 | joblist_append(srv, con); | |
31708 | } | |
31709 | - | |
31710 | + | |
31711 | return HANDLER_FINISHED; | |
31712 | } | |
31713 | -#define PATCH(x) \ | |
31714 | - p->conf.x = s->x; | |
31715 | + | |
31716 | static int scgi_patch_connection(server *srv, connection *con, plugin_data *p) { | |
31717 | size_t i, j; | |
31718 | plugin_config *s = p->config_storage[0]; | |
31719 | - | |
31720 | - PATCH(exts); | |
31721 | - PATCH(debug); | |
31722 | - | |
31723 | + | |
31724 | + PATCH_OPTION(exts); | |
31725 | + PATCH_OPTION(debug); | |
31726 | + | |
31727 | /* skip the first, the global context */ | |
31728 | for (i = 1; i < srv->config_context->used; i++) { | |
31729 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
31730 | s = p->config_storage[i]; | |
31731 | - | |
31732 | + | |
31733 | /* condition didn't match */ | |
31734 | if (!config_check_cond(srv, con, dc)) continue; | |
31735 | - | |
31736 | + | |
31737 | /* merge config */ | |
31738 | for (j = 0; j < dc->value->used; j++) { | |
31739 | data_unset *du = dc->value->data[j]; | |
31740 | - | |
31741 | + | |
31742 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.server"))) { | |
31743 | - PATCH(exts); | |
31744 | + PATCH_OPTION(exts); | |
31745 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.debug"))) { | |
31746 | - PATCH(debug); | |
31747 | + PATCH_OPTION(debug); | |
31748 | } | |
31749 | } | |
31750 | } | |
31751 | - | |
31752 | + | |
31753 | return 0; | |
31754 | } | |
31755 | -#undef PATCH | |
31756 | - | |
31757 | ||
31758 | static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) { | |
31759 | plugin_data *p = p_d; | |
31760 | @@ -2673,30 +2670,30 @@ | |
31761 | size_t k; | |
31762 | buffer *fn; | |
31763 | scgi_extension *extension = NULL; | |
31764 | - | |
31765 | + | |
31766 | /* Possibly, we processed already this request */ | |
31767 | if (con->file_started == 1) return HANDLER_GO_ON; | |
31768 | - | |
31769 | + | |
31770 | fn = uri_path_handler ? con->uri.path : con->physical.path; | |
31771 | ||
31772 | if (buffer_is_empty(fn)) return HANDLER_GO_ON; | |
31773 | ||
31774 | s_len = fn->used - 1; | |
31775 | - | |
31776 | + | |
31777 | scgi_patch_connection(srv, con, p); | |
31778 | ||
31779 | /* check if extension matches */ | |
31780 | for (k = 0; k < p->conf.exts->used; k++) { | |
31781 | size_t ct_len; | |
31782 | - | |
31783 | + | |
31784 | extension = p->conf.exts->exts[k]; | |
31785 | - | |
31786 | + | |
31787 | if (extension->key->used == 0) continue; | |
31788 | - | |
31789 | + | |
31790 | ct_len = extension->key->used - 1; | |
31791 | - | |
31792 | + | |
31793 | if (s_len < ct_len) continue; | |
31794 | - | |
31795 | + | |
31796 | /* check extension in the form "/scgi_pattern" */ | |
31797 | if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) { | |
31798 | break; | |
31799 | @@ -2710,17 +2707,17 @@ | |
31800 | if (k == p->conf.exts->used) { | |
31801 | return HANDLER_GO_ON; | |
31802 | } | |
31803 | - | |
31804 | + | |
31805 | /* get best server */ | |
31806 | for (k = 0, ndx = -1; k < extension->used; k++) { | |
31807 | scgi_extension_host *host = extension->hosts[k]; | |
31808 | - | |
31809 | + | |
31810 | /* we should have at least one proc that can do somthing */ | |
31811 | if (host->active_procs == 0) continue; | |
31812 | ||
31813 | if (used == -1 || host->load < used) { | |
31814 | used = host->load; | |
31815 | - | |
31816 | + | |
31817 | ndx = k; | |
31818 | } | |
31819 | } | |
31820 | @@ -2728,12 +2725,12 @@ | |
31821 | /* found a server */ | |
31822 | if (ndx != -1) { | |
31823 | scgi_extension_host *host = extension->hosts[ndx]; | |
31824 | - | |
31825 | - /* | |
31826 | - * if check-local is disabled, use the uri.path handler | |
31827 | - * | |
31828 | + | |
31829 | + /* | |
31830 | + * if check-local is disabled, use the uri.path handler | |
31831 | + * | |
31832 | */ | |
31833 | - | |
31834 | + | |
31835 | /* init handler-context */ | |
31836 | if (uri_path_handler) { | |
31837 | if (host->check_local == 0) { | |
31838 | @@ -2741,7 +2738,7 @@ | |
31839 | char *pathinfo; | |
31840 | ||
31841 | hctx = handler_ctx_init(); | |
31842 | - | |
31843 | + | |
31844 | hctx->remote_conn = con; | |
31845 | hctx->plugin_data = p; | |
31846 | hctx->host = host; | |
31847 | @@ -2749,45 +2746,45 @@ | |
31848 | ||
31849 | hctx->conf.exts = p->conf.exts; | |
31850 | hctx->conf.debug = p->conf.debug; | |
31851 | - | |
31852 | + | |
31853 | con->plugin_ctx[p->id] = hctx; | |
31854 | - | |
31855 | + | |
31856 | host->load++; | |
31857 | - | |
31858 | + | |
31859 | con->mode = p->id; | |
31860 | ||
31861 | if (con->conf.log_request_handling) { | |
31862 | log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_scgi"); | |
31863 | } | |
31864 | ||
31865 | - /* the prefix is the SCRIPT_NAME, | |
31866 | + /* the prefix is the SCRIPT_NAME, | |
31867 | * everthing from start to the next slash | |
31868 | * this is important for check-local = "disable" | |
31869 | - * | |
31870 | + * | |
31871 | * if prefix = /admin.fcgi | |
31872 | - * | |
31873 | + * | |
31874 | * /admin.fcgi/foo/bar | |
31875 | - * | |
31876 | + * | |
31877 | * SCRIPT_NAME = /admin.fcgi | |
31878 | * PATH_INFO = /foo/bar | |
31879 | - * | |
31880 | + * | |
31881 | * if prefix = /fcgi-bin/ | |
31882 | - * | |
31883 | + * | |
31884 | * /fcgi-bin/foo/bar | |
31885 | - * | |
31886 | + * | |
31887 | * SCRIPT_NAME = /fcgi-bin/foo | |
31888 | * PATH_INFO = /bar | |
31889 | - * | |
31890 | + * | |
31891 | */ | |
31892 | - | |
31893 | + | |
31894 | /* the rewrite is only done for /prefix/? matches */ | |
31895 | if (extension->key->ptr[0] == '/' && | |
31896 | con->uri.path->used > extension->key->used && | |
31897 | NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) { | |
31898 | - /* rewrite uri.path and pathinfo */ | |
31899 | - | |
31900 | + /* rewrite uri.path and pathinfo */ | |
31901 | + | |
31902 | buffer_copy_string(con->request.pathinfo, pathinfo); | |
31903 | - | |
31904 | + | |
31905 | con->uri.path->used -= con->request.pathinfo->used - 1; | |
31906 | con->uri.path->ptr[con->uri.path->used - 1] = '\0'; | |
31907 | } | |
31908 | @@ -2796,21 +2793,21 @@ | |
31909 | } else { | |
31910 | handler_ctx *hctx; | |
31911 | hctx = handler_ctx_init(); | |
31912 | - | |
31913 | + | |
31914 | hctx->remote_conn = con; | |
31915 | hctx->plugin_data = p; | |
31916 | hctx->host = host; | |
31917 | hctx->proc = NULL; | |
31918 | - | |
31919 | + | |
31920 | hctx->conf.exts = p->conf.exts; | |
31921 | hctx->conf.debug = p->conf.debug; | |
31922 | - | |
31923 | + | |
31924 | con->plugin_ctx[p->id] = hctx; | |
31925 | - | |
31926 | + | |
31927 | host->load++; | |
31928 | - | |
31929 | + | |
31930 | con->mode = p->id; | |
31931 | - | |
31932 | + | |
31933 | if (con->conf.log_request_handling) { | |
31934 | log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi"); | |
31935 | } | |
31936 | @@ -2821,11 +2818,11 @@ | |
31937 | /* no handler found */ | |
31938 | buffer_reset(con->physical.path); | |
31939 | con->http_status = 500; | |
31940 | - | |
31941 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
31942 | - "no fcgi-handler found for:", | |
31943 | + | |
31944 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
31945 | + "no fcgi-handler found for:", | |
31946 | fn); | |
31947 | - | |
31948 | + | |
31949 | return HANDLER_FINISHED; | |
31950 | } | |
31951 | return HANDLER_GO_ON; | |
31952 | @@ -2844,19 +2841,19 @@ | |
31953 | JOBLIST_FUNC(mod_scgi_handle_joblist) { | |
31954 | plugin_data *p = p_d; | |
31955 | handler_ctx *hctx = con->plugin_ctx[p->id]; | |
31956 | - | |
31957 | + | |
31958 | if (hctx == NULL) return HANDLER_GO_ON; | |
31959 | ||
31960 | if (hctx->fd != -1) { | |
31961 | switch (hctx->state) { | |
31962 | case FCGI_STATE_READ: | |
31963 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN); | |
31964 | - | |
31965 | + | |
31966 | break; | |
31967 | case FCGI_STATE_CONNECT: | |
31968 | case FCGI_STATE_WRITE: | |
31969 | fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); | |
31970 | - | |
31971 | + | |
31972 | break; | |
31973 | case FCGI_STATE_INIT: | |
31974 | /* at reconnect */ | |
31975 | @@ -2873,21 +2870,21 @@ | |
31976 | ||
31977 | static handler_t scgi_connection_close_callback(server *srv, connection *con, void *p_d) { | |
31978 | plugin_data *p = p_d; | |
31979 | - | |
31980 | + | |
31981 | return scgi_connection_close(srv, con->plugin_ctx[p->id]); | |
31982 | } | |
31983 | ||
31984 | TRIGGER_FUNC(mod_scgi_handle_trigger) { | |
31985 | plugin_data *p = p_d; | |
31986 | size_t i, j, n; | |
31987 | - | |
31988 | - | |
31989 | + | |
31990 | + | |
31991 | /* perhaps we should kill a connect attempt after 10-15 seconds | |
31992 | - * | |
31993 | + * | |
31994 | * currently we wait for the TCP timeout which is on Linux 180 seconds | |
31995 | - * | |
31996 | - * | |
31997 | - * | |
31998 | + * | |
31999 | + * | |
32000 | + * | |
32001 | */ | |
32002 | ||
32003 | /* check all childs if they are still up */ | |
32004 | @@ -2904,47 +2901,47 @@ | |
32005 | scgi_extension *ex; | |
32006 | ||
32007 | ex = exts->exts[j]; | |
32008 | - | |
32009 | + | |
32010 | for (n = 0; n < ex->used; n++) { | |
32011 | - | |
32012 | + | |
32013 | scgi_proc *proc; | |
32014 | unsigned long sum_load = 0; | |
32015 | scgi_extension_host *host; | |
32016 | - | |
32017 | + | |
32018 | host = ex->hosts[n]; | |
32019 | - | |
32020 | + | |
32021 | scgi_restart_dead_procs(srv, p, host); | |
32022 | - | |
32023 | + | |
32024 | for (proc = host->first; proc; proc = proc->next) { | |
32025 | sum_load += proc->load; | |
32026 | } | |
32027 | - | |
32028 | + | |
32029 | if (host->num_procs && | |
32030 | host->num_procs < host->max_procs && | |
32031 | (sum_load / host->num_procs) > host->max_load_per_proc) { | |
32032 | /* overload, spawn new child */ | |
32033 | scgi_proc *fp = NULL; | |
32034 | - | |
32035 | + | |
32036 | if (p->conf.debug) { | |
32037 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
32038 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
32039 | "overload detected, spawning a new child"); | |
32040 | } | |
32041 | - | |
32042 | + | |
32043 | for (fp = host->unused_procs; fp && fp->pid != 0; fp = fp->next); | |
32044 | - | |
32045 | + | |
32046 | if (fp) { | |
32047 | if (fp == host->unused_procs) host->unused_procs = fp->next; | |
32048 | - | |
32049 | + | |
32050 | if (fp->next) fp->next->prev = NULL; | |
32051 | - | |
32052 | + | |
32053 | host->max_id++; | |
32054 | } else { | |
32055 | fp = scgi_process_init(); | |
32056 | fp->id = host->max_id++; | |
32057 | } | |
32058 | - | |
32059 | + | |
32060 | host->num_procs++; | |
32061 | - | |
32062 | + | |
32063 | if (buffer_is_empty(host->unixsocket)) { | |
32064 | fp->port = host->port + fp->id; | |
32065 | } else { | |
32066 | @@ -2952,13 +2949,13 @@ | |
32067 | buffer_append_string(fp->socket, "-"); | |
32068 | buffer_append_long(fp->socket, fp->id); | |
32069 | } | |
32070 | - | |
32071 | + | |
32072 | if (scgi_spawn_connection(srv, p, host, fp)) { | |
32073 | log_error_write(srv, __FILE__, __LINE__, "s", | |
32074 | "ERROR: spawning fcgi failed."); | |
32075 | return HANDLER_ERROR; | |
32076 | } | |
32077 | - | |
32078 | + | |
32079 | fp->prev = NULL; | |
32080 | fp->next = host->first; | |
32081 | if (host->first) { | |
32082 | @@ -2966,56 +2963,57 @@ | |
32083 | } | |
32084 | host->first = fp; | |
32085 | } | |
32086 | - | |
32087 | + | |
32088 | for (proc = host->first; proc; proc = proc->next) { | |
32089 | if (proc->load != 0) break; | |
32090 | if (host->num_procs <= host->min_procs) break; | |
32091 | if (proc->pid == 0) continue; | |
32092 | - | |
32093 | +#ifndef _WIN32 | |
32094 | if (srv->cur_ts - proc->last_used > host->idle_timeout) { | |
32095 | /* a proc is idling for a long time now, | |
32096 | * terminated it */ | |
32097 | - | |
32098 | + | |
32099 | if (p->conf.debug) { | |
32100 | - log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
32101 | - "idle-timeout reached, terminating child:", | |
32102 | - "socket:", proc->socket, | |
32103 | + log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
32104 | + "idle-timeout reached, terminating child:", | |
32105 | + "socket:", proc->socket, | |
32106 | "pid", proc->pid); | |
32107 | } | |
32108 | - | |
32109 | - | |
32110 | + | |
32111 | + | |
32112 | if (proc->next) proc->next->prev = proc->prev; | |
32113 | if (proc->prev) proc->prev->next = proc->next; | |
32114 | - | |
32115 | + | |
32116 | if (proc->prev == NULL) host->first = proc->next; | |
32117 | - | |
32118 | + | |
32119 | proc->prev = NULL; | |
32120 | proc->next = host->unused_procs; | |
32121 | - | |
32122 | + | |
32123 | if (host->unused_procs) host->unused_procs->prev = proc; | |
32124 | host->unused_procs = proc; | |
32125 | - | |
32126 | + | |
32127 | kill(proc->pid, SIGTERM); | |
32128 | - | |
32129 | + | |
32130 | proc->state = PROC_STATE_KILLED; | |
32131 | - | |
32132 | - log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
32133 | - "killed:", | |
32134 | - "socket:", proc->socket, | |
32135 | + | |
32136 | + log_error_write(srv, __FILE__, __LINE__, "ssbsd", | |
32137 | + "killed:", | |
32138 | + "socket:", proc->socket, | |
32139 | "pid", proc->pid); | |
32140 | - | |
32141 | + | |
32142 | host->num_procs--; | |
32143 | - | |
32144 | + | |
32145 | /* proc is now in unused, let the next second handle the next process */ | |
32146 | break; | |
32147 | - } | |
32148 | + } | |
32149 | +#endif | |
32150 | } | |
32151 | - | |
32152 | + | |
32153 | for (proc = host->unused_procs; proc; proc = proc->next) { | |
32154 | int status; | |
32155 | - | |
32156 | + | |
32157 | if (proc->pid == 0) continue; | |
32158 | - | |
32159 | +#ifndef _WIN32 | |
32160 | switch (waitpid(proc->pid, &status, WNOHANG)) { | |
32161 | case 0: | |
32162 | /* child still running after timeout, good */ | |
32163 | @@ -3023,10 +3021,10 @@ | |
32164 | case -1: | |
32165 | if (errno != EINTR) { | |
32166 | /* no PID found ? should never happen */ | |
32167 | - log_error_write(srv, __FILE__, __LINE__, "sddss", | |
32168 | + log_error_write(srv, __FILE__, __LINE__, "sddss", | |
32169 | "pid ", proc->pid, proc->state, | |
32170 | "not found:", strerror(errno)); | |
32171 | - | |
32172 | + | |
32173 | #if 0 | |
32174 | if (errno == ECHILD) { | |
32175 | /* someone else has cleaned up for us */ | |
32176 | @@ -3040,25 +3038,26 @@ | |
32177 | /* the child should not terminate at all */ | |
32178 | if (WIFEXITED(status)) { | |
32179 | if (proc->state != PROC_STATE_KILLED) { | |
32180 | - log_error_write(srv, __FILE__, __LINE__, "sdb", | |
32181 | - "child exited:", | |
32182 | + log_error_write(srv, __FILE__, __LINE__, "sdb", | |
32183 | + "child exited:", | |
32184 | WEXITSTATUS(status), proc->socket); | |
32185 | } | |
32186 | } else if (WIFSIGNALED(status)) { | |
32187 | if (WTERMSIG(status) != SIGTERM) { | |
32188 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
32189 | - "child signaled:", | |
32190 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
32191 | + "child signaled:", | |
32192 | WTERMSIG(status)); | |
32193 | } | |
32194 | } else { | |
32195 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
32196 | - "child died somehow:", | |
32197 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
32198 | + "child died somehow:", | |
32199 | status); | |
32200 | } | |
32201 | proc->pid = 0; | |
32202 | proc->state = PROC_STATE_UNSET; | |
32203 | host->max_id--; | |
32204 | } | |
32205 | +#endif | |
32206 | } | |
32207 | } | |
32208 | } | |
32209 | @@ -3082,8 +3081,8 @@ | |
32210 | p->handle_subrequest = mod_scgi_handle_subrequest; | |
32211 | p->handle_joblist = mod_scgi_handle_joblist; | |
32212 | p->handle_trigger = mod_scgi_handle_trigger; | |
32213 | - | |
32214 | + | |
32215 | p->data = NULL; | |
32216 | - | |
32217 | + | |
32218 | return 0; | |
32219 | } | |
1175ccec | 32220 | --- ../lighttpd-1.4.11/src/mod_secure_download.c 2005-12-14 14:37:29.000000000 +0200 |
36e2a29e | 32221 | +++ lighttpd-1.4.12/src/mod_secure_download.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
32222 | @@ -25,7 +25,7 @@ |
32223 | #ifdef USE_OPENSSL | |
32224 | #define IN const | |
32225 | #else | |
32226 | -#define IN | |
32227 | +#define IN | |
32228 | #endif | |
32229 | #define OUT | |
32230 | ||
32231 | @@ -36,28 +36,28 @@ | |
32232 | buffer *doc_root; | |
32233 | buffer *secret; | |
32234 | buffer *uri_prefix; | |
32235 | - | |
32236 | + | |
32237 | unsigned short timeout; | |
32238 | } plugin_config; | |
32239 | ||
32240 | typedef struct { | |
32241 | PLUGIN_DATA; | |
32242 | - | |
32243 | + | |
32244 | buffer *md5; | |
32245 | - | |
32246 | + | |
32247 | plugin_config **config_storage; | |
32248 | - | |
32249 | - plugin_config conf; | |
32250 | + | |
32251 | + plugin_config conf; | |
32252 | } plugin_data; | |
32253 | ||
32254 | /* init the plugin data */ | |
32255 | INIT_FUNC(mod_secdownload_init) { | |
32256 | plugin_data *p; | |
32257 | - | |
32258 | + | |
32259 | p = calloc(1, sizeof(*p)); | |
32260 | - | |
32261 | + | |
32262 | p->md5 = buffer_init(); | |
32263 | - | |
32264 | + | |
32265 | return p; | |
32266 | } | |
32267 | ||
32268 | @@ -65,27 +65,27 @@ | |
32269 | FREE_FUNC(mod_secdownload_free) { | |
32270 | plugin_data *p = p_d; | |
32271 | UNUSED(srv); | |
32272 | - | |
32273 | + | |
32274 | if (!p) return HANDLER_GO_ON; | |
32275 | - | |
32276 | + | |
32277 | if (p->config_storage) { | |
32278 | size_t i; | |
32279 | for (i = 0; i < srv->config_context->used; i++) { | |
32280 | plugin_config *s = p->config_storage[i]; | |
32281 | - | |
32282 | + | |
32283 | buffer_free(s->secret); | |
32284 | buffer_free(s->doc_root); | |
32285 | buffer_free(s->uri_prefix); | |
32286 | - | |
32287 | + | |
32288 | free(s); | |
32289 | } | |
32290 | free(p->config_storage); | |
32291 | } | |
32292 | - | |
32293 | + | |
32294 | buffer_free(p->md5); | |
32295 | - | |
32296 | + | |
32297 | free(p); | |
32298 | - | |
32299 | + | |
32300 | return HANDLER_GO_ON; | |
32301 | } | |
32302 | ||
32303 | @@ -94,107 +94,103 @@ | |
32304 | SETDEFAULTS_FUNC(mod_secdownload_set_defaults) { | |
32305 | plugin_data *p = p_d; | |
32306 | size_t i = 0; | |
32307 | - | |
32308 | - config_values_t cv[] = { | |
32309 | + | |
32310 | + config_values_t cv[] = { | |
32311 | { "secdownload.secret", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
32312 | { "secdownload.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
32313 | { "secdownload.uri-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
32314 | { "secdownload.timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ | |
32315 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
32316 | }; | |
32317 | - | |
32318 | + | |
32319 | if (!p) return HANDLER_ERROR; | |
32320 | - | |
32321 | + | |
32322 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
32323 | - | |
32324 | + | |
32325 | for (i = 0; i < srv->config_context->used; i++) { | |
32326 | plugin_config *s; | |
32327 | - | |
32328 | + | |
32329 | s = calloc(1, sizeof(plugin_config)); | |
32330 | s->secret = buffer_init(); | |
32331 | s->doc_root = buffer_init(); | |
32332 | s->uri_prefix = buffer_init(); | |
32333 | s->timeout = 60; | |
32334 | - | |
32335 | + | |
32336 | cv[0].destination = s->secret; | |
32337 | cv[1].destination = s->doc_root; | |
32338 | cv[2].destination = s->uri_prefix; | |
32339 | cv[3].destination = &(s->timeout); | |
32340 | - | |
32341 | + | |
32342 | p->config_storage[i] = s; | |
32343 | - | |
32344 | + | |
32345 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
32346 | return HANDLER_ERROR; | |
32347 | } | |
32348 | } | |
32349 | - | |
32350 | + | |
32351 | return HANDLER_GO_ON; | |
32352 | } | |
32353 | ||
32354 | /** | |
32355 | * checks if the supplied string is a MD5 string | |
32356 | - * | |
32357 | + * | |
32358 | * @param str a possible MD5 string | |
32359 | * @return if the supplied string is a valid MD5 string 1 is returned otherwise 0 | |
32360 | */ | |
32361 | ||
32362 | int is_hex_len(const char *str, size_t len) { | |
32363 | size_t i; | |
32364 | - | |
32365 | + | |
32366 | if (NULL == str) return 0; | |
32367 | - | |
32368 | + | |
32369 | for (i = 0; i < len && *str; i++, str++) { | |
32370 | /* illegal characters */ | |
32371 | if (!((*str >= '0' && *str <= '9') || | |
32372 | (*str >= 'a' && *str <= 'f') || | |
32373 | - (*str >= 'A' && *str <= 'F')) | |
32374 | + (*str >= 'A' && *str <= 'F')) | |
32375 | ) { | |
32376 | return 0; | |
32377 | } | |
32378 | } | |
32379 | - | |
32380 | + | |
32381 | return i == len; | |
32382 | } | |
32383 | ||
32384 | -#define PATCH(x) \ | |
32385 | - p->conf.x = s->x; | |
32386 | static int mod_secdownload_patch_connection(server *srv, connection *con, plugin_data *p) { | |
32387 | size_t i, j; | |
32388 | plugin_config *s = p->config_storage[0]; | |
32389 | - | |
32390 | - PATCH(secret); | |
32391 | - PATCH(doc_root); | |
32392 | - PATCH(uri_prefix); | |
32393 | - PATCH(timeout); | |
32394 | - | |
32395 | + | |
32396 | + PATCH_OPTION(secret); | |
32397 | + PATCH_OPTION(doc_root); | |
32398 | + PATCH_OPTION(uri_prefix); | |
32399 | + PATCH_OPTION(timeout); | |
32400 | + | |
32401 | /* skip the first, the global context */ | |
32402 | for (i = 1; i < srv->config_context->used; i++) { | |
32403 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
32404 | s = p->config_storage[i]; | |
32405 | - | |
32406 | + | |
32407 | /* condition didn't match */ | |
32408 | if (!config_check_cond(srv, con, dc)) continue; | |
32409 | - | |
32410 | + | |
32411 | /* merge config */ | |
32412 | for (j = 0; j < dc->value->used; j++) { | |
32413 | data_unset *du = dc->value->data[j]; | |
32414 | - | |
32415 | + | |
32416 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.secret"))) { | |
32417 | - PATCH(secret); | |
32418 | + PATCH_OPTION(secret); | |
32419 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.document-root"))) { | |
32420 | - PATCH(doc_root); | |
32421 | + PATCH_OPTION(doc_root); | |
32422 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.uri-prefix"))) { | |
32423 | - PATCH(uri_prefix); | |
32424 | + PATCH_OPTION(uri_prefix); | |
32425 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.timeout"))) { | |
32426 | - PATCH(timeout); | |
32427 | + PATCH_OPTION(timeout); | |
32428 | } | |
32429 | } | |
32430 | } | |
32431 | - | |
32432 | + | |
32433 | return 0; | |
32434 | } | |
32435 | -#undef PATCH | |
32436 | - | |
32437 | ||
32438 | URIHANDLER_FUNC(mod_secdownload_uri_handler) { | |
32439 | plugin_data *p = p_d; | |
32440 | @@ -203,88 +199,88 @@ | |
32441 | const char *rel_uri, *ts_str, *md5_str; | |
32442 | time_t ts = 0; | |
32443 | size_t i; | |
32444 | - | |
32445 | + | |
32446 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
32447 | - | |
32448 | + | |
32449 | mod_secdownload_patch_connection(srv, con, p); | |
32450 | ||
32451 | if (buffer_is_empty(p->conf.uri_prefix)) return HANDLER_GO_ON; | |
32452 | - | |
32453 | + | |
32454 | if (buffer_is_empty(p->conf.secret)) { | |
32455 | log_error_write(srv, __FILE__, __LINE__, "s", | |
32456 | "secdownload.secret has to be set"); | |
32457 | return HANDLER_ERROR; | |
32458 | } | |
32459 | - | |
32460 | + | |
32461 | if (buffer_is_empty(p->conf.doc_root)) { | |
32462 | log_error_write(srv, __FILE__, __LINE__, "s", | |
32463 | "secdownload.document-root has to be set"); | |
32464 | return HANDLER_ERROR; | |
32465 | } | |
32466 | - | |
32467 | - /* | |
32468 | + | |
32469 | + /* | |
32470 | * /<uri-prefix>[a-f0-9]{32}/[a-f0-9]{8}/<rel-path> | |
32471 | */ | |
32472 | - | |
32473 | + | |
32474 | if (0 != strncmp(con->uri.path->ptr, p->conf.uri_prefix->ptr, p->conf.uri_prefix->used - 1)) return HANDLER_GO_ON; | |
32475 | - | |
32476 | + | |
32477 | md5_str = con->uri.path->ptr + p->conf.uri_prefix->used - 1; | |
32478 | - | |
32479 | + | |
32480 | if (!is_hex_len(md5_str, 32)) return HANDLER_GO_ON; | |
32481 | if (*(md5_str + 32) != '/') return HANDLER_GO_ON; | |
32482 | - | |
32483 | + | |
32484 | ts_str = md5_str + 32 + 1; | |
32485 | - | |
32486 | + | |
32487 | if (!is_hex_len(ts_str, 8)) return HANDLER_GO_ON; | |
32488 | if (*(ts_str + 8) != '/') return HANDLER_GO_ON; | |
32489 | - | |
32490 | + | |
32491 | for (i = 0; i < 8; i++) { | |
32492 | ts = (ts << 4) + hex2int(*(ts_str + i)); | |
32493 | } | |
32494 | - | |
32495 | + | |
32496 | /* timed-out */ | |
32497 | - if (srv->cur_ts - ts > p->conf.timeout || | |
32498 | + if (srv->cur_ts - ts > p->conf.timeout || | |
32499 | srv->cur_ts - ts < -p->conf.timeout) { | |
32500 | con->http_status = 408; | |
32501 | - | |
32502 | + | |
32503 | return HANDLER_FINISHED; | |
32504 | } | |
32505 | - | |
32506 | + | |
32507 | rel_uri = ts_str + 8; | |
32508 | - | |
32509 | - /* checking MD5 | |
32510 | - * | |
32511 | + | |
32512 | + /* checking MD5 | |
32513 | + * | |
32514 | * <secret><rel-path><timestamp-hex> | |
32515 | */ | |
32516 | - | |
32517 | + | |
32518 | buffer_copy_string_buffer(p->md5, p->conf.secret); | |
32519 | buffer_append_string(p->md5, rel_uri); | |
32520 | buffer_append_string_len(p->md5, ts_str, 8); | |
32521 | - | |
32522 | + | |
32523 | MD5_Init(&Md5Ctx); | |
32524 | MD5_Update(&Md5Ctx, (unsigned char *)p->md5->ptr, p->md5->used - 1); | |
32525 | MD5_Final(HA1, &Md5Ctx); | |
32526 | - | |
32527 | + | |
32528 | buffer_copy_string_hex(p->md5, (char *)HA1, 16); | |
32529 | - | |
32530 | + | |
32531 | if (0 != strncmp(md5_str, p->md5->ptr, 32)) { | |
32532 | con->http_status = 403; | |
32533 | - | |
32534 | - log_error_write(srv, __FILE__, __LINE__, "sss", | |
32535 | + | |
32536 | + log_error_write(srv, __FILE__, __LINE__, "sss", | |
32537 | "md5 invalid:", | |
32538 | md5_str, p->md5->ptr); | |
32539 | - | |
32540 | + | |
32541 | return HANDLER_FINISHED; | |
32542 | } | |
32543 | - | |
32544 | + | |
32545 | /* starting with the last / we should have relative-path to the docroot | |
32546 | */ | |
32547 | - | |
32548 | + | |
32549 | buffer_copy_string_buffer(con->physical.doc_root, p->conf.doc_root); | |
32550 | buffer_copy_string(con->physical.rel_path, rel_uri); | |
32551 | buffer_copy_string_buffer(con->physical.path, con->physical.doc_root); | |
32552 | buffer_append_string_buffer(con->physical.path, con->physical.rel_path); | |
32553 | - | |
32554 | + | |
32555 | return HANDLER_GO_ON; | |
32556 | } | |
32557 | ||
32558 | @@ -293,13 +289,13 @@ | |
32559 | int mod_secdownload_plugin_init(plugin *p) { | |
32560 | p->version = LIGHTTPD_VERSION_ID; | |
32561 | p->name = buffer_init_string("secdownload"); | |
32562 | - | |
32563 | + | |
32564 | p->init = mod_secdownload_init; | |
32565 | p->handle_physical = mod_secdownload_uri_handler; | |
32566 | p->set_defaults = mod_secdownload_set_defaults; | |
32567 | p->cleanup = mod_secdownload_free; | |
32568 | - | |
32569 | + | |
32570 | p->data = NULL; | |
32571 | - | |
32572 | + | |
32573 | return 0; | |
32574 | } | |
1175ccec | 32575 | --- ../lighttpd-1.4.11/src/mod_setenv.c 2006-01-14 20:33:12.000000000 +0200 |
36e2a29e | 32576 | +++ lighttpd-1.4.12/src/mod_setenv.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
32577 | @@ -18,25 +18,25 @@ |
32578 | typedef struct { | |
32579 | array *request_header; | |
32580 | array *response_header; | |
32581 | - | |
32582 | + | |
32583 | array *environment; | |
32584 | } plugin_config; | |
32585 | ||
32586 | typedef struct { | |
32587 | PLUGIN_DATA; | |
32588 | - | |
32589 | + | |
32590 | plugin_config **config_storage; | |
32591 | - | |
32592 | - plugin_config conf; | |
32593 | + | |
32594 | + plugin_config conf; | |
32595 | } plugin_data; | |
32596 | ||
32597 | static handler_ctx * handler_ctx_init() { | |
32598 | handler_ctx * hctx; | |
32599 | - | |
32600 | + | |
32601 | hctx = calloc(1, sizeof(*hctx)); | |
32602 | - | |
32603 | + | |
32604 | hctx->handled = 0; | |
32605 | - | |
32606 | + | |
32607 | return hctx; | |
32608 | } | |
32609 | ||
32610 | @@ -48,36 +48,36 @@ | |
32611 | /* init the plugin data */ | |
32612 | INIT_FUNC(mod_setenv_init) { | |
32613 | plugin_data *p; | |
32614 | - | |
32615 | + | |
32616 | p = calloc(1, sizeof(*p)); | |
32617 | - | |
32618 | + | |
32619 | return p; | |
32620 | } | |
32621 | ||
32622 | /* detroy the plugin data */ | |
32623 | FREE_FUNC(mod_setenv_free) { | |
32624 | plugin_data *p = p_d; | |
32625 | - | |
32626 | + | |
32627 | UNUSED(srv); | |
32628 | ||
32629 | if (!p) return HANDLER_GO_ON; | |
32630 | - | |
32631 | + | |
32632 | if (p->config_storage) { | |
32633 | size_t i; | |
32634 | for (i = 0; i < srv->config_context->used; i++) { | |
32635 | plugin_config *s = p->config_storage[i]; | |
32636 | - | |
32637 | + | |
32638 | array_free(s->request_header); | |
32639 | array_free(s->response_header); | |
32640 | array_free(s->environment); | |
32641 | - | |
32642 | + | |
32643 | free(s); | |
32644 | } | |
32645 | free(p->config_storage); | |
32646 | } | |
32647 | - | |
32648 | + | |
32649 | free(p); | |
32650 | - | |
32651 | + | |
32652 | return HANDLER_GO_ON; | |
32653 | } | |
32654 | ||
32655 | @@ -86,86 +86,83 @@ | |
32656 | SETDEFAULTS_FUNC(mod_setenv_set_defaults) { | |
32657 | plugin_data *p = p_d; | |
32658 | size_t i = 0; | |
32659 | - | |
32660 | - config_values_t cv[] = { | |
32661 | + | |
32662 | + config_values_t cv[] = { | |
32663 | { "setenv.add-request-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
32664 | { "setenv.add-response-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
32665 | { "setenv.add-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
32666 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
32667 | }; | |
32668 | - | |
32669 | + | |
32670 | if (!p) return HANDLER_ERROR; | |
32671 | - | |
32672 | + | |
32673 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
32674 | - | |
32675 | + | |
32676 | for (i = 0; i < srv->config_context->used; i++) { | |
32677 | plugin_config *s; | |
32678 | - | |
32679 | + | |
32680 | s = calloc(1, sizeof(plugin_config)); | |
32681 | s->request_header = array_init(); | |
32682 | s->response_header = array_init(); | |
32683 | s->environment = array_init(); | |
32684 | - | |
32685 | + | |
32686 | cv[0].destination = s->request_header; | |
32687 | cv[1].destination = s->response_header; | |
32688 | cv[2].destination = s->environment; | |
32689 | - | |
32690 | + | |
32691 | p->config_storage[i] = s; | |
32692 | - | |
32693 | + | |
32694 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
32695 | return HANDLER_ERROR; | |
32696 | } | |
32697 | } | |
32698 | - | |
32699 | + | |
32700 | return HANDLER_GO_ON; | |
32701 | } | |
32702 | ||
32703 | -#define PATCH(x) \ | |
32704 | - p->conf.x = s->x; | |
32705 | static int mod_setenv_patch_connection(server *srv, connection *con, plugin_data *p) { | |
32706 | size_t i, j; | |
32707 | plugin_config *s = p->config_storage[0]; | |
32708 | - | |
32709 | - PATCH(request_header); | |
32710 | - PATCH(response_header); | |
32711 | - PATCH(environment); | |
32712 | - | |
32713 | + | |
32714 | + PATCH_OPTION(request_header); | |
32715 | + PATCH_OPTION(response_header); | |
32716 | + PATCH_OPTION(environment); | |
32717 | + | |
32718 | /* skip the first, the global context */ | |
32719 | for (i = 1; i < srv->config_context->used; i++) { | |
32720 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
32721 | s = p->config_storage[i]; | |
32722 | - | |
32723 | + | |
32724 | /* condition didn't match */ | |
32725 | if (!config_check_cond(srv, con, dc)) continue; | |
32726 | - | |
32727 | + | |
32728 | /* merge config */ | |
32729 | for (j = 0; j < dc->value->used; j++) { | |
32730 | data_unset *du = dc->value->data[j]; | |
32731 | - | |
32732 | + | |
32733 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-request-header"))) { | |
32734 | - PATCH(request_header); | |
32735 | + PATCH_OPTION(request_header); | |
32736 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-response-header"))) { | |
32737 | - PATCH(response_header); | |
32738 | + PATCH_OPTION(response_header); | |
32739 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-environment"))) { | |
f26f9fd5 ER |
32740 | - PATCH(environment); |
32741 | + PATCH_OPTION(environment); | |
32742 | } | |
32743 | } | |
32744 | } | |
2519e6e5 ER |
32745 | - |
32746 | + | |
32747 | return 0; | |
32748 | } | |
32749 | -#undef PATCH | |
32750 | ||
32751 | URIHANDLER_FUNC(mod_setenv_uri_handler) { | |
32752 | plugin_data *p = p_d; | |
32753 | size_t k; | |
32754 | handler_ctx *hctx; | |
32755 | - | |
32756 | + | |
32757 | if (con->plugin_ctx[p->id]) { | |
32758 | hctx = con->plugin_ctx[p->id]; | |
32759 | } else { | |
32760 | hctx = handler_ctx_init(); | |
32761 | - | |
32762 | + | |
32763 | con->plugin_ctx[p->id] = hctx; | |
32764 | } | |
32765 | ||
32766 | @@ -180,52 +177,52 @@ | |
32767 | for (k = 0; k < p->conf.request_header->used; k++) { | |
32768 | data_string *ds = (data_string *)p->conf.request_header->data[k]; | |
32769 | data_string *ds_dst; | |
32770 | - | |
32771 | + | |
32772 | if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { | |
32773 | ds_dst = data_string_init(); | |
32774 | } | |
32775 | - | |
32776 | + | |
32777 | buffer_copy_string_buffer(ds_dst->key, ds->key); | |
32778 | buffer_copy_string_buffer(ds_dst->value, ds->value); | |
32779 | - | |
32780 | + | |
32781 | array_insert_unique(con->request.headers, (data_unset *)ds_dst); | |
32782 | } | |
32783 | - | |
32784 | + | |
32785 | for (k = 0; k < p->conf.environment->used; k++) { | |
32786 | data_string *ds = (data_string *)p->conf.environment->data[k]; | |
32787 | data_string *ds_dst; | |
32788 | - | |
32789 | + | |
32790 | if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) { | |
32791 | ds_dst = data_string_init(); | |
32792 | } | |
32793 | - | |
32794 | + | |
32795 | buffer_copy_string_buffer(ds_dst->key, ds->key); | |
32796 | buffer_copy_string_buffer(ds_dst->value, ds->value); | |
32797 | - | |
32798 | + | |
32799 | array_insert_unique(con->environment, (data_unset *)ds_dst); | |
32800 | } | |
32801 | - | |
32802 | + | |
32803 | for (k = 0; k < p->conf.response_header->used; k++) { | |
32804 | data_string *ds = (data_string *)p->conf.response_header->data[k]; | |
32805 | - | |
32806 | + | |
32807 | response_header_insert(srv, con, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value)); | |
32808 | } | |
32809 | - | |
32810 | + | |
32811 | /* not found */ | |
32812 | return HANDLER_GO_ON; | |
32813 | } | |
32814 | ||
32815 | REQUESTDONE_FUNC(mod_setenv_reset) { | |
32816 | plugin_data *p = p_d; | |
32817 | - | |
32818 | + | |
32819 | UNUSED(srv); | |
32820 | - | |
32821 | + | |
32822 | if (con->plugin_ctx[p->id]) { | |
32823 | handler_ctx_free(con->plugin_ctx[p->id]); | |
32824 | con->plugin_ctx[p->id] = NULL; | |
32825 | } | |
32826 | ||
32827 | - return HANDLER_GO_ON; | |
32828 | + return HANDLER_GO_ON; | |
32829 | } | |
32830 | ||
32831 | /* this function is called at dlopen() time and inits the callbacks */ | |
32832 | @@ -233,15 +230,15 @@ | |
32833 | int mod_setenv_plugin_init(plugin *p) { | |
32834 | p->version = LIGHTTPD_VERSION_ID; | |
32835 | p->name = buffer_init_string("setenv"); | |
32836 | - | |
32837 | + | |
32838 | p->init = mod_setenv_init; | |
32839 | p->handle_uri_clean = mod_setenv_uri_handler; | |
32840 | p->set_defaults = mod_setenv_set_defaults; | |
32841 | p->cleanup = mod_setenv_free; | |
32842 | - | |
32843 | + | |
32844 | p->handle_request_done = mod_setenv_reset; | |
32845 | ||
32846 | p->data = NULL; | |
32847 | - | |
32848 | + | |
32849 | return 0; | |
32850 | } | |
1175ccec | 32851 | --- ../lighttpd-1.4.11/src/mod_simple_vhost.c 2005-11-18 15:16:13.000000000 +0200 |
36e2a29e | 32852 | +++ lighttpd-1.4.12/src/mod_simple_vhost.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
32853 | @@ -10,6 +10,8 @@ |
32854 | ||
32855 | #include "plugin.h" | |
32856 | ||
32857 | +#include "sys-files.h" | |
32858 | + | |
32859 | #ifdef HAVE_CONFIG_H | |
32860 | #include "config.h" | |
32861 | #endif | |
32862 | @@ -18,7 +20,7 @@ | |
32863 | buffer *server_root; | |
32864 | buffer *default_host; | |
32865 | buffer *document_root; | |
32866 | - | |
32867 | + | |
32868 | buffer *docroot_cache_key; | |
32869 | buffer *docroot_cache_value; | |
32870 | buffer *docroot_cache_servername; | |
32871 | @@ -28,138 +30,138 @@ | |
32872 | ||
32873 | typedef struct { | |
32874 | PLUGIN_DATA; | |
32875 | - | |
32876 | + | |
32877 | buffer *doc_root; | |
32878 | - | |
32879 | + | |
32880 | plugin_config **config_storage; | |
32881 | - plugin_config conf; | |
32882 | + plugin_config conf; | |
32883 | } plugin_data; | |
32884 | ||
32885 | INIT_FUNC(mod_simple_vhost_init) { | |
32886 | plugin_data *p; | |
32887 | - | |
32888 | + | |
32889 | p = calloc(1, sizeof(*p)); | |
32890 | - | |
32891 | + | |
32892 | p->doc_root = buffer_init(); | |
32893 | - | |
32894 | + | |
32895 | return p; | |
32896 | } | |
32897 | ||
32898 | FREE_FUNC(mod_simple_vhost_free) { | |
32899 | plugin_data *p = p_d; | |
32900 | - | |
32901 | + | |
32902 | UNUSED(srv); | |
32903 | ||
32904 | if (!p) return HANDLER_GO_ON; | |
32905 | - | |
32906 | + | |
32907 | if (p->config_storage) { | |
32908 | size_t i; | |
32909 | for (i = 0; i < srv->config_context->used; i++) { | |
32910 | plugin_config *s = p->config_storage[i]; | |
32911 | - | |
32912 | + | |
32913 | buffer_free(s->document_root); | |
32914 | buffer_free(s->default_host); | |
32915 | buffer_free(s->server_root); | |
32916 | - | |
32917 | + | |
32918 | buffer_free(s->docroot_cache_key); | |
32919 | buffer_free(s->docroot_cache_value); | |
32920 | buffer_free(s->docroot_cache_servername); | |
32921 | - | |
32922 | + | |
32923 | free(s); | |
32924 | } | |
32925 | - | |
32926 | + | |
32927 | free(p->config_storage); | |
32928 | } | |
32929 | - | |
32930 | + | |
32931 | buffer_free(p->doc_root); | |
32932 | - | |
32933 | + | |
32934 | free(p); | |
32935 | - | |
32936 | + | |
32937 | return HANDLER_GO_ON; | |
32938 | } | |
32939 | ||
32940 | SETDEFAULTS_FUNC(mod_simple_vhost_set_defaults) { | |
32941 | plugin_data *p = p_d; | |
32942 | size_t i; | |
32943 | - | |
32944 | - config_values_t cv[] = { | |
32945 | + | |
32946 | + config_values_t cv[] = { | |
32947 | { "simple-vhost.server-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
32948 | { "simple-vhost.default-host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
32949 | { "simple-vhost.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
32950 | { "simple-vhost.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, | |
32951 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
32952 | }; | |
32953 | - | |
32954 | + | |
32955 | if (!p) return HANDLER_ERROR; | |
32956 | - | |
32957 | + | |
32958 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
32959 | - | |
32960 | + | |
32961 | for (i = 0; i < srv->config_context->used; i++) { | |
32962 | plugin_config *s; | |
32963 | - | |
32964 | + | |
32965 | s = calloc(1, sizeof(plugin_config)); | |
32966 | - | |
32967 | + | |
32968 | s->server_root = buffer_init(); | |
32969 | s->default_host = buffer_init(); | |
32970 | s->document_root = buffer_init(); | |
32971 | - | |
32972 | + | |
32973 | s->docroot_cache_key = buffer_init(); | |
32974 | s->docroot_cache_value = buffer_init(); | |
32975 | s->docroot_cache_servername = buffer_init(); | |
32976 | ||
32977 | s->debug = 0; | |
32978 | - | |
32979 | + | |
32980 | cv[0].destination = s->server_root; | |
32981 | cv[1].destination = s->default_host; | |
32982 | cv[2].destination = s->document_root; | |
32983 | cv[3].destination = &(s->debug); | |
32984 | - | |
32985 | - | |
32986 | + | |
32987 | + | |
32988 | p->config_storage[i] = s; | |
32989 | - | |
32990 | + | |
32991 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
32992 | return HANDLER_ERROR; | |
32993 | } | |
32994 | } | |
32995 | - | |
32996 | + | |
32997 | return HANDLER_GO_ON; | |
32998 | } | |
32999 | ||
33000 | static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *out, buffer *host) { | |
33001 | stat_cache_entry *sce = NULL; | |
33002 | - | |
33003 | + | |
33004 | buffer_prepare_copy(out, 128); | |
33005 | ||
33006 | if (p->conf.server_root->used) { | |
33007 | buffer_copy_string_buffer(out, p->conf.server_root); | |
33008 | - | |
33009 | + | |
33010 | if (host->used) { | |
33011 | /* a hostname has to start with a alpha-numerical character | |
33012 | * and must not contain a slash "/" | |
33013 | */ | |
33014 | char *dp; | |
33015 | - | |
33016 | - BUFFER_APPEND_SLASH(out); | |
33017 | - | |
33018 | + | |
33019 | + PATHNAME_APPEND_SLASH(out); | |
33020 | + | |
33021 | if (NULL == (dp = strchr(host->ptr, ':'))) { | |
33022 | buffer_append_string_buffer(out, host); | |
33023 | } else { | |
33024 | buffer_append_string_len(out, host->ptr, dp - host->ptr); | |
33025 | } | |
33026 | } | |
33027 | - BUFFER_APPEND_SLASH(out); | |
33028 | - | |
33029 | + PATHNAME_APPEND_SLASH(out); | |
33030 | + | |
33031 | if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') { | |
33032 | buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2); | |
33033 | } else { | |
33034 | buffer_append_string_buffer(out, p->conf.document_root); | |
33035 | - BUFFER_APPEND_SLASH(out); | |
33036 | + PATHNAME_APPEND_SLASH(out); | |
33037 | } | |
33038 | } else { | |
33039 | buffer_copy_string_buffer(out, con->conf.document_root); | |
33040 | - BUFFER_APPEND_SLASH(out); | |
33041 | + PATHNAME_APPEND_SLASH(out); | |
33042 | } | |
33043 | - | |
33044 | + | |
33045 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) { | |
33046 | if (p->conf.debug) { | |
33047 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
33048 | @@ -169,57 +171,53 @@ | |
33049 | } else if (!S_ISDIR(sce->st.st_mode)) { | |
33050 | return -1; | |
33051 | } | |
33052 | - | |
33053 | + | |
33054 | return 0; | |
33055 | } | |
33056 | ||
33057 | - | |
33058 | -#define PATCH(x) \ | |
33059 | - p->conf.x = s->x; | |
33060 | static int mod_simple_vhost_patch_connection(server *srv, connection *con, plugin_data *p) { | |
33061 | size_t i, j; | |
33062 | plugin_config *s = p->config_storage[0]; | |
33063 | - | |
33064 | - PATCH(server_root); | |
33065 | - PATCH(default_host); | |
33066 | - PATCH(document_root); | |
33067 | - | |
33068 | - PATCH(docroot_cache_key); | |
33069 | - PATCH(docroot_cache_value); | |
33070 | - PATCH(docroot_cache_servername); | |
33071 | ||
33072 | - PATCH(debug); | |
33073 | - | |
33074 | + PATCH_OPTION(server_root); | |
33075 | + PATCH_OPTION(default_host); | |
33076 | + PATCH_OPTION(document_root); | |
33077 | + | |
33078 | + PATCH_OPTION(docroot_cache_key); | |
33079 | + PATCH_OPTION(docroot_cache_value); | |
33080 | + PATCH_OPTION(docroot_cache_servername); | |
33081 | + | |
33082 | + PATCH_OPTION(debug); | |
33083 | + | |
33084 | /* skip the first, the global context */ | |
33085 | for (i = 1; i < srv->config_context->used; i++) { | |
33086 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
33087 | s = p->config_storage[i]; | |
33088 | - | |
33089 | + | |
33090 | /* condition didn't match */ | |
33091 | if (!config_check_cond(srv, con, dc)) continue; | |
33092 | - | |
33093 | + | |
33094 | /* merge config */ | |
33095 | for (j = 0; j < dc->value->used; j++) { | |
33096 | data_unset *du = dc->value->data[j]; | |
33097 | - | |
33098 | + | |
33099 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.server-root"))) { | |
33100 | - PATCH(server_root); | |
33101 | - PATCH(docroot_cache_key); | |
33102 | - PATCH(docroot_cache_value); | |
33103 | - PATCH(docroot_cache_servername); | |
33104 | + PATCH_OPTION(server_root); | |
33105 | + PATCH_OPTION(docroot_cache_key); | |
33106 | + PATCH_OPTION(docroot_cache_value); | |
33107 | + PATCH_OPTION(docroot_cache_servername); | |
33108 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.default-host"))) { | |
33109 | - PATCH(default_host); | |
33110 | + PATCH_OPTION(default_host); | |
33111 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.document-root"))) { | |
33112 | - PATCH(document_root); | |
33113 | + PATCH_OPTION(document_root); | |
33114 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.debug"))) { | |
33115 | - PATCH(debug); | |
33116 | + PATCH_OPTION(debug); | |
33117 | } | |
33118 | } | |
33119 | } | |
33120 | - | |
33121 | + | |
33122 | return 0; | |
33123 | } | |
33124 | -#undef PATCH | |
33125 | ||
33126 | static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_data) { | |
33127 | plugin_data *p = p_data; | |
33128 | @@ -227,12 +225,12 @@ | |
33129 | /* | |
33130 | * cache the last successfull translation from hostname (authority) to docroot | |
33131 | * - this saves us a stat() call | |
33132 | - * | |
33133 | + * | |
33134 | */ | |
33135 | - | |
33136 | + | |
33137 | mod_simple_vhost_patch_connection(srv, con, p); | |
33138 | - | |
33139 | - if (p->conf.docroot_cache_key->used && | |
33140 | + | |
33141 | + if (p->conf.docroot_cache_key->used && | |
33142 | con->uri.authority->used && | |
33143 | buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) { | |
33144 | /* cache hit */ | |
33145 | @@ -243,8 +241,8 @@ | |
33146 | if ((con->uri.authority->used == 0) || | |
33147 | build_doc_root(srv, con, p, p->doc_root, con->uri.authority)) { | |
33148 | /* not found, fallback the default-host */ | |
33149 | - if (build_doc_root(srv, con, p, | |
33150 | - p->doc_root, | |
33151 | + if (build_doc_root(srv, con, p, | |
33152 | + p->doc_root, | |
33153 | p->conf.default_host)) { | |
33154 | return HANDLER_GO_ON; | |
33155 | } else { | |
33156 | @@ -253,15 +251,15 @@ | |
33157 | } else { | |
33158 | buffer_copy_string_buffer(con->server_name, con->uri.authority); | |
33159 | } | |
33160 | - | |
33161 | + | |
33162 | /* copy to cache */ | |
33163 | buffer_copy_string_buffer(p->conf.docroot_cache_key, con->uri.authority); | |
33164 | buffer_copy_string_buffer(p->conf.docroot_cache_value, p->doc_root); | |
33165 | buffer_copy_string_buffer(p->conf.docroot_cache_servername, con->server_name); | |
33166 | - | |
33167 | + | |
33168 | buffer_copy_string_buffer(con->physical.doc_root, p->doc_root); | |
33169 | } | |
33170 | - | |
33171 | + | |
33172 | return HANDLER_GO_ON; | |
33173 | } | |
33174 | ||
33175 | @@ -269,13 +267,13 @@ | |
33176 | int mod_simple_vhost_plugin_init(plugin *p) { | |
33177 | p->version = LIGHTTPD_VERSION_ID; | |
33178 | p->name = buffer_init_string("simple_vhost"); | |
33179 | - | |
33180 | + | |
33181 | p->init = mod_simple_vhost_init; | |
33182 | p->set_defaults = mod_simple_vhost_set_defaults; | |
33183 | p->handle_docroot = mod_simple_vhost_docroot; | |
33184 | p->cleanup = mod_simple_vhost_free; | |
33185 | - | |
33186 | + | |
33187 | p->data = NULL; | |
33188 | - | |
33189 | + | |
33190 | return 0; | |
33191 | } | |
1175ccec | 33192 | --- ../lighttpd-1.4.11/src/mod_skeleton.c 2005-10-02 18:30:51.000000000 +0300 |
36e2a29e | 33193 | +++ lighttpd-1.4.12/src/mod_skeleton.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
33194 | @@ -14,13 +14,13 @@ |
33195 | ||
33196 | /** | |
33197 | * this is a skeleton for a lighttpd plugin | |
33198 | - * | |
33199 | + * | |
33200 | * just replaces every occurance of 'skeleton' by your plugin name | |
33201 | - * | |
33202 | + * | |
33203 | * e.g. in vim: | |
33204 | - * | |
33205 | + * | |
33206 | * :%s/skeleton/myhandler/ | |
33207 | - * | |
33208 | + * | |
33209 | */ | |
33210 | ||
33211 | ||
33212 | @@ -33,12 +33,12 @@ | |
33213 | ||
33214 | typedef struct { | |
33215 | PLUGIN_DATA; | |
33216 | - | |
33217 | + | |
33218 | buffer *match_buf; | |
33219 | - | |
33220 | + | |
33221 | plugin_config **config_storage; | |
33222 | - | |
33223 | - plugin_config conf; | |
33224 | + | |
33225 | + plugin_config conf; | |
33226 | } plugin_data; | |
33227 | ||
33228 | typedef struct { | |
33229 | @@ -47,36 +47,36 @@ | |
33230 | ||
33231 | static handler_ctx * handler_ctx_init() { | |
33232 | handler_ctx * hctx; | |
33233 | - | |
33234 | + | |
33235 | hctx = calloc(1, sizeof(*hctx)); | |
33236 | - | |
33237 | + | |
33238 | return hctx; | |
33239 | } | |
33240 | ||
33241 | static void handler_ctx_free(handler_ctx *hctx) { | |
33242 | - | |
33243 | + | |
33244 | free(hctx); | |
33245 | } | |
33246 | ||
33247 | /* init the plugin data */ | |
33248 | INIT_FUNC(mod_skeleton_init) { | |
33249 | plugin_data *p; | |
33250 | - | |
33251 | + | |
33252 | p = calloc(1, sizeof(*p)); | |
33253 | - | |
33254 | + | |
33255 | p->match_buf = buffer_init(); | |
33256 | - | |
33257 | + | |
33258 | return p; | |
33259 | } | |
33260 | ||
33261 | /* detroy the plugin data */ | |
33262 | FREE_FUNC(mod_skeleton_free) { | |
33263 | plugin_data *p = p_d; | |
33264 | - | |
33265 | + | |
33266 | UNUSED(srv); | |
33267 | ||
33268 | if (!p) return HANDLER_GO_ON; | |
33269 | - | |
33270 | + | |
33271 | if (p->config_storage) { | |
33272 | size_t i; | |
33273 | ||
33274 | @@ -84,18 +84,18 @@ | |
33275 | plugin_config *s = p->config_storage[i]; | |
33276 | ||
33277 | if (!s) continue; | |
33278 | - | |
33279 | + | |
33280 | array_free(s->match); | |
33281 | - | |
33282 | + | |
33283 | free(s); | |
33284 | } | |
33285 | free(p->config_storage); | |
33286 | } | |
33287 | - | |
33288 | + | |
33289 | buffer_free(p->match_buf); | |
33290 | - | |
33291 | + | |
33292 | free(p); | |
33293 | - | |
33294 | + | |
33295 | return HANDLER_GO_ON; | |
33296 | } | |
33297 | ||
33298 | @@ -104,91 +104,88 @@ | |
33299 | SETDEFAULTS_FUNC(mod_skeleton_set_defaults) { | |
33300 | plugin_data *p = p_d; | |
33301 | size_t i = 0; | |
33302 | - | |
33303 | - config_values_t cv[] = { | |
33304 | + | |
33305 | + config_values_t cv[] = { | |
33306 | { "skeleton.array", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
33307 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
33308 | }; | |
33309 | - | |
33310 | + | |
33311 | if (!p) return HANDLER_ERROR; | |
33312 | - | |
33313 | + | |
33314 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
33315 | - | |
33316 | + | |
33317 | for (i = 0; i < srv->config_context->used; i++) { | |
33318 | plugin_config *s; | |
33319 | - | |
33320 | + | |
33321 | s = calloc(1, sizeof(plugin_config)); | |
33322 | s->match = array_init(); | |
33323 | - | |
33324 | + | |
33325 | cv[0].destination = s->match; | |
33326 | - | |
33327 | + | |
33328 | p->config_storage[i] = s; | |
33329 | - | |
33330 | + | |
33331 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
33332 | return HANDLER_ERROR; | |
33333 | } | |
33334 | } | |
33335 | - | |
33336 | + | |
33337 | return HANDLER_GO_ON; | |
33338 | } | |
33339 | ||
33340 | -#define PATCH(x) \ | |
33341 | - p->conf.x = s->x; | |
33342 | static int mod_skeleton_patch_connection(server *srv, connection *con, plugin_data *p) { | |
33343 | size_t i, j; | |
33344 | plugin_config *s = p->config_storage[0]; | |
33345 | - | |
33346 | - PATCH(match); | |
33347 | - | |
33348 | + | |
33349 | + PATCH_OPTION(match); | |
33350 | + | |
33351 | /* skip the first, the global context */ | |
33352 | for (i = 1; i < srv->config_context->used; i++) { | |
33353 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
33354 | s = p->config_storage[i]; | |
33355 | - | |
33356 | + | |
33357 | /* condition didn't match */ | |
33358 | if (!config_check_cond(srv, con, dc)) continue; | |
33359 | - | |
33360 | + | |
33361 | /* merge config */ | |
33362 | for (j = 0; j < dc->value->used; j++) { | |
33363 | data_unset *du = dc->value->data[j]; | |
33364 | - | |
33365 | + | |
33366 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("skeleton.array"))) { | |
33367 | - PATCH(match); | |
33368 | + PATCH_OPTION(match); | |
33369 | } | |
33370 | } | |
33371 | } | |
33372 | - | |
33373 | + | |
33374 | return 0; | |
33375 | } | |
33376 | -#undef PATCH | |
33377 | ||
33378 | URIHANDLER_FUNC(mod_skeleton_uri_handler) { | |
33379 | plugin_data *p = p_d; | |
33380 | int s_len; | |
33381 | size_t k, i; | |
33382 | - | |
33383 | + | |
33384 | UNUSED(srv); | |
33385 | ||
33386 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
33387 | - | |
33388 | + | |
33389 | mod_skeleton_patch_connection(srv, con, p); | |
33390 | ||
33391 | s_len = con->uri.path->used - 1; | |
33392 | - | |
33393 | + | |
33394 | for (k = 0; k < p->conf.match->used; k++) { | |
33395 | data_string *ds = (data_string *)p->conf.match->data[k]; | |
33396 | int ct_len = ds->value->used - 1; | |
33397 | - | |
33398 | + | |
33399 | if (ct_len > s_len) continue; | |
33400 | if (ds->value->used == 0) continue; | |
33401 | - | |
33402 | + | |
33403 | if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { | |
33404 | con->http_status = 403; | |
33405 | - | |
33406 | + | |
33407 | return HANDLER_FINISHED; | |
33408 | } | |
33409 | } | |
33410 | - | |
33411 | + | |
33412 | /* not found */ | |
33413 | return HANDLER_GO_ON; | |
33414 | } | |
33415 | @@ -198,13 +195,13 @@ | |
33416 | int mod_skeleton_plugin_init(plugin *p) { | |
33417 | p->version = LIGHTTPD_VERSION_ID; | |
33418 | p->name = buffer_init_string("skeleton"); | |
33419 | - | |
33420 | + | |
33421 | p->init = mod_skeleton_init; | |
33422 | p->handle_uri_clean = mod_skeleton_uri_handler; | |
33423 | p->set_defaults = mod_skeleton_set_defaults; | |
33424 | p->cleanup = mod_skeleton_free; | |
33425 | - | |
33426 | + | |
33427 | p->data = NULL; | |
33428 | - | |
33429 | + | |
33430 | return 0; | |
33431 | } | |
1175ccec | 33432 | --- ../lighttpd-1.4.11/src/mod_sql_vhost_core.c 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 33433 | +++ lighttpd-1.4.12/src/mod_sql_vhost_core.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
33434 | @@ -0,0 +1,209 @@ |
33435 | +#include <stdio.h> | |
33436 | +#include <errno.h> | |
33437 | +#include <fcntl.h> | |
33438 | +#include <string.h> | |
33439 | + | |
33440 | +#ifdef HAVE_CONFIG_H | |
33441 | +#include "config.h" | |
33442 | +#endif | |
33443 | + | |
33444 | +#include "plugin.h" | |
33445 | +#include "log.h" | |
33446 | + | |
33447 | +#include "stat_cache.h" | |
33448 | + | |
33449 | +#include "mod_sql_vhost_core.h" | |
33450 | + | |
33451 | +#define plugin_data mod_sql_vhost_core_plugin_data | |
33452 | +#define plugin_config mod_sql_vhost_core_plugin_config | |
33453 | + | |
33454 | +/* init the plugin data */ | |
33455 | +INIT_FUNC(mod_sql_vhost_core_init) { | |
33456 | + plugin_data *p; | |
33457 | + | |
33458 | + p = calloc(1, sizeof(*p)); | |
33459 | + | |
33460 | + p->docroot = buffer_init(); | |
33461 | + p->host = buffer_init(); | |
33462 | + | |
33463 | + return p; | |
33464 | +} | |
33465 | + | |
33466 | +/* cleanup the plugin data */ | |
33467 | +SERVER_FUNC(mod_sql_vhost_core_cleanup) { | |
33468 | + plugin_data *p = p_d; | |
33469 | + | |
33470 | + UNUSED(srv); | |
33471 | + | |
33472 | + if (!p) return HANDLER_GO_ON; | |
33473 | + | |
33474 | + if (p->config_storage) { | |
33475 | + size_t i; | |
33476 | + for (i = 0; i < srv->config_context->used; i++) { | |
33477 | + plugin_config *s = p->config_storage[i]; | |
33478 | + | |
33479 | + if (!s) continue; | |
33480 | + | |
33481 | + buffer_free(s->db); | |
33482 | + buffer_free(s->user); | |
33483 | + buffer_free(s->pass); | |
33484 | + buffer_free(s->sock); | |
33485 | + buffer_free(s->backend); | |
33486 | + | |
33487 | + free(s); | |
33488 | + } | |
33489 | + free(p->config_storage); | |
33490 | + } | |
33491 | + buffer_free(p->docroot); | |
33492 | + buffer_free(p->host); | |
33493 | + | |
33494 | + free(p); | |
33495 | + | |
33496 | + return HANDLER_GO_ON; | |
33497 | +} | |
33498 | + | |
33499 | +/* set configuration values */ | |
33500 | +SERVER_FUNC(mod_sql_vhost_core_set_defaults) { | |
33501 | + plugin_data *p = p_d; | |
33502 | + | |
33503 | + size_t i = 0; | |
33504 | + | |
33505 | + config_values_t cv[] = { | |
33506 | + { "sql-vhost.db", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 * e.g. vhost */ | |
33507 | + { "sql-vhost.user", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 1 * lighty */ | |
33508 | + { "sql-vhost.pass", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 2 * secrect */ | |
33509 | + { "sql-vhost.sock", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 3 * /tmp/mysql.sock */ | |
33510 | + { "sql-vhost.select-vhost", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 4 * SELECT ... FROM hosts WHERE hostname = ? */ | |
33511 | + { "sql-vhost.hostname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 5 * 127.0.0.1 */ | |
33512 | + { "sql-vhost.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 6 * 3306 */ | |
33513 | + { "sql-vhost.backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 7 * mysql */ | |
33514 | + | |
33515 | + /* backward compat */ | |
33516 | + { "mysql-vhost.db", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 8 == 0 */ | |
33517 | + { "mysql-vhost.user", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 9 == 1 */ | |
33518 | + { "mysql-vhost.pass", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 == 2 */ | |
33519 | + { "mysql-vhost.sock", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 == 3 */ | |
33520 | + { "mysql-vhost.sql", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 12 == 4 */ | |
33521 | + { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER }, /* 13 == 5 */ | |
33522 | + { "mysql-vhost.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 14 == 6 */ | |
33523 | + | |
33524 | + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
33525 | + }; | |
33526 | + | |
33527 | + p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
33528 | + | |
33529 | + for (i = 0; i < srv->config_context->used; i++) { | |
33530 | + plugin_config *s; | |
33531 | + | |
33532 | + s = calloc(1, sizeof(plugin_config)); | |
33533 | + s->db = buffer_init(); | |
33534 | + s->user = buffer_init(); | |
33535 | + s->pass = buffer_init(); | |
33536 | + s->sock = buffer_init(); | |
33537 | + s->hostname = buffer_init(); | |
33538 | + s->backend = buffer_init(); | |
33539 | + s->port = 0; /* default port for mysql */ | |
33540 | + s->select_vhost = buffer_init(); | |
33541 | + s->backend_data = NULL; | |
33542 | + | |
33543 | + cv[0].destination = s->db; | |
33544 | + cv[1].destination = s->user; | |
33545 | + cv[2].destination = s->pass; | |
33546 | + cv[3].destination = s->sock; | |
33547 | + cv[4].destination = s->select_vhost; | |
33548 | + cv[5].destination = s->hostname; | |
33549 | + cv[6].destination = &(s->port); | |
33550 | + cv[7].destination = s->backend; | |
33551 | + | |
33552 | + /* backend compat */ | |
33553 | + cv[8].destination = cv[0].destination; | |
33554 | + cv[9].destination = cv[1].destination; | |
33555 | + cv[10].destination = cv[2].destination; | |
33556 | + cv[11].destination = cv[3].destination; | |
33557 | + cv[12].destination = cv[4].destination; | |
33558 | + cv[13].destination = cv[5].destination; | |
33559 | + cv[14].destination = cv[6].destination; | |
33560 | + | |
33561 | + p->config_storage[i] = s; | |
33562 | + | |
33563 | + if (config_insert_values_global(srv, | |
33564 | + ((data_config *)srv->config_context->data[i])->value, | |
33565 | + cv)) return HANDLER_ERROR; | |
33566 | + | |
33567 | + /* we only parse the config, the backend plugin will patch itself into the plugin-struct */ | |
33568 | + } | |
33569 | + | |
33570 | + return HANDLER_GO_ON; | |
33571 | +} | |
33572 | + | |
33573 | +static int mod_sql_vhost_core_patch_connection(server *srv, connection *con, plugin_data *p) { | |
33574 | + size_t i; | |
33575 | + plugin_config *s = p->config_storage[0]; | |
33576 | + | |
33577 | + PATCH_OPTION(backend_data); | |
33578 | + PATCH_OPTION(get_vhost); | |
33579 | + | |
33580 | + /* skip the first, the global context */ | |
33581 | + for (i = 1; i < srv->config_context->used; i++) { | |
33582 | + data_config *dc = (data_config *)srv->config_context->data[i]; | |
33583 | + s = p->config_storage[i]; | |
33584 | + | |
33585 | + /* condition didn't match */ | |
33586 | + if (!config_check_cond(srv, con, dc)) continue; | |
33587 | + | |
33588 | + if (s->backend_data) { | |
33589 | + PATCH_OPTION(backend_data); | |
33590 | + PATCH_OPTION(get_vhost); | |
33591 | + } | |
33592 | + } | |
33593 | + | |
33594 | + return 0; | |
33595 | +} | |
33596 | + | |
33597 | +/* handle document root request */ | |
33598 | +CONNECTION_FUNC(mod_sql_vhost_core_handle_docroot) { | |
33599 | + plugin_data *p = p_d; | |
33600 | + stat_cache_entry *sce; | |
33601 | + | |
33602 | + /* no host specified? */ | |
33603 | + if (!con->uri.authority->used) return HANDLER_GO_ON; | |
33604 | + | |
33605 | + mod_sql_vhost_core_patch_connection(srv, con, p); | |
33606 | + | |
33607 | + /* do we have backend ? */ | |
33608 | + if (!p->conf.get_vhost) return HANDLER_GO_ON; | |
33609 | + | |
33610 | + /* ask the backend for the data */ | |
33611 | + if (0 != p->conf.get_vhost(srv, con, p->conf.backend_data, p->docroot, p->host)) { | |
33612 | + return HANDLER_GO_ON; | |
33613 | + } | |
33614 | + | |
33615 | + if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->docroot, &sce)) { | |
33616 | + log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->docroot); | |
33617 | + return HANDLER_GO_ON; | |
33618 | + } | |
33619 | + if (!S_ISDIR(sce->st.st_mode)) { | |
33620 | + log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->docroot); | |
33621 | + return HANDLER_GO_ON; | |
33622 | + } | |
33623 | + | |
33624 | + buffer_copy_string_buffer(con->server_name, p->host); | |
33625 | + buffer_copy_string_buffer(con->physical.doc_root, p->docroot); | |
33626 | + | |
33627 | + return HANDLER_GO_ON; | |
33628 | +} | |
33629 | + | |
33630 | +/* this function is called at dlopen() time and inits the callbacks */ | |
33631 | +int mod_sql_vhost_core_plugin_init(plugin *p) { | |
33632 | + p->version = LIGHTTPD_VERSION_ID; | |
33633 | + p->name = buffer_init_string("mod_sql_vhost_core"); | |
33634 | + | |
33635 | + p->init = mod_sql_vhost_core_init; | |
33636 | + p->cleanup = mod_sql_vhost_core_cleanup; | |
33637 | + | |
33638 | + p->set_defaults = mod_sql_vhost_core_set_defaults; | |
33639 | + p->handle_docroot = mod_sql_vhost_core_handle_docroot; | |
33640 | + | |
33641 | + return 0; | |
33642 | +} | |
33643 | + | |
1175ccec | 33644 | --- ../lighttpd-1.4.11/src/mod_sql_vhost_core.h 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 33645 | +++ lighttpd-1.4.12/src/mod_sql_vhost_core.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
33646 | @@ -0,0 +1,49 @@ |
33647 | +#ifndef _MOD_SQL_VHOST_CORE_H_ | |
33648 | +#define _MOD_SQL_VHOST_CORE_H_ | |
33649 | + | |
33650 | +#include "buffer.h" | |
33651 | +#include "plugin.h" | |
33652 | + | |
33653 | +#define SQLVHOST_BACKEND_GETVHOST_PARAMS \ | |
33654 | + (server *srv, connection *con, void *p_d, buffer *docroot, buffer *host) | |
33655 | + | |
33656 | +#define SQLVHOST_BACKEND_GETVHOST_RETVAL handler_t | |
33657 | + | |
33658 | +#define SQLVHOST_BACKEND_GETVHOST(name) \ | |
33659 | + SQLVHOST_BACKEND_GETVHOST_RETVAL name SQLVHOST_BACKEND_GETVHOST_PARAMS | |
33660 | + | |
33661 | +#define SQLVHOST_BACKEND_GETVHOST_PTR(name) \ | |
33662 | + SQLVHOST_BACKEND_GETVHOST_RETVAL (* name)SQLVHOST_BACKEND_GETVHOST_PARAMS | |
33663 | + | |
33664 | +typedef struct { | |
33665 | + buffer *db; | |
33666 | + buffer *user; | |
33667 | + buffer *pass; | |
33668 | + buffer *sock; | |
33669 | + | |
33670 | + buffer *hostname; | |
33671 | + unsigned short port; | |
33672 | + | |
33673 | + buffer *backend; | |
33674 | + void *backend_data; | |
33675 | + | |
33676 | + buffer *select_vhost; | |
33677 | + | |
33678 | + SQLVHOST_BACKEND_GETVHOST_PTR(get_vhost); | |
33679 | +} mod_sql_vhost_core_plugin_config; | |
33680 | + | |
33681 | +/* global plugin data */ | |
33682 | +typedef struct { | |
33683 | + PLUGIN_DATA; | |
33684 | + | |
33685 | + buffer *docroot; | |
33686 | + buffer *host; | |
33687 | + | |
33688 | + mod_sql_vhost_core_plugin_config **config_storage; | |
33689 | + | |
33690 | + mod_sql_vhost_core_plugin_config conf; | |
33691 | +} mod_sql_vhost_core_plugin_data; | |
33692 | + | |
33693 | + | |
33694 | + | |
33695 | +#endif | |
1175ccec | 33696 | --- ../lighttpd-1.4.11/src/mod_ssi.c 2006-03-04 17:09:48.000000000 +0200 |
36e2a29e | 33697 | +++ lighttpd-1.4.12/src/mod_ssi.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
33698 | @@ -6,7 +6,6 @@ |
33699 | #include <string.h> | |
33700 | #include <errno.h> | |
33701 | #include <time.h> | |
33702 | -#include <unistd.h> | |
33703 | ||
33704 | #include "base.h" | |
33705 | #include "log.h" | |
33706 | @@ -23,6 +22,8 @@ | |
33707 | #include "inet_ntop_cache.h" | |
33708 | ||
33709 | #include "sys-socket.h" | |
33710 | +#include "sys-strings.h" | |
33711 | +#include "sys-files.h" | |
33712 | ||
33713 | #ifdef HAVE_PWD_H | |
33714 | #include <pwd.h> | |
33715 | @@ -39,15 +40,15 @@ | |
33716 | /* init the plugin data */ | |
33717 | INIT_FUNC(mod_ssi_init) { | |
33718 | plugin_data *p; | |
33719 | - | |
33720 | + | |
33721 | p = calloc(1, sizeof(*p)); | |
33722 | - | |
33723 | + | |
33724 | p->timefmt = buffer_init(); | |
33725 | p->stat_fn = buffer_init(); | |
33726 | - | |
33727 | + | |
33728 | p->ssi_vars = array_init(); | |
33729 | p->ssi_cgi_env = array_init(); | |
33730 | - | |
33731 | + | |
33732 | return p; | |
33733 | } | |
33734 | ||
33735 | @@ -55,21 +56,21 @@ | |
33736 | FREE_FUNC(mod_ssi_free) { | |
33737 | plugin_data *p = p_d; | |
33738 | UNUSED(srv); | |
33739 | - | |
33740 | + | |
33741 | if (!p) return HANDLER_GO_ON; | |
33742 | - | |
33743 | + | |
33744 | if (p->config_storage) { | |
33745 | size_t i; | |
33746 | for (i = 0; i < srv->config_context->used; i++) { | |
33747 | plugin_config *s = p->config_storage[i]; | |
33748 | - | |
33749 | + | |
33750 | array_free(s->ssi_extension); | |
33751 | - | |
33752 | + | |
33753 | free(s); | |
33754 | } | |
33755 | free(p->config_storage); | |
33756 | } | |
33757 | - | |
33758 | + | |
33759 | array_free(p->ssi_vars); | |
33760 | array_free(p->ssi_cgi_env); | |
33761 | #ifdef HAVE_PCRE_H | |
33762 | @@ -77,9 +78,9 @@ | |
33763 | #endif | |
33764 | buffer_free(p->timefmt); | |
33765 | buffer_free(p->stat_fn); | |
33766 | - | |
33767 | + | |
33768 | free(p); | |
33769 | - | |
33770 | + | |
33771 | return HANDLER_GO_ON; | |
33772 | } | |
33773 | ||
33774 | @@ -92,36 +93,36 @@ | |
33775 | const char *errptr; | |
33776 | int erroff; | |
33777 | #endif | |
33778 | - | |
33779 | - config_values_t cv[] = { | |
33780 | + | |
33781 | + config_values_t cv[] = { | |
33782 | { "ssi.extension", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
33783 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
33784 | }; | |
33785 | - | |
33786 | + | |
33787 | if (!p) return HANDLER_ERROR; | |
33788 | - | |
33789 | + | |
33790 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
33791 | - | |
33792 | + | |
33793 | for (i = 0; i < srv->config_context->used; i++) { | |
33794 | plugin_config *s; | |
33795 | - | |
33796 | + | |
33797 | s = calloc(1, sizeof(plugin_config)); | |
33798 | s->ssi_extension = array_init(); | |
33799 | - | |
33800 | + | |
33801 | cv[0].destination = s->ssi_extension; | |
33802 | - | |
33803 | + | |
33804 | p->config_storage[i] = s; | |
33805 | - | |
33806 | + | |
33807 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
33808 | return HANDLER_ERROR; | |
33809 | } | |
33810 | } | |
33811 | - | |
33812 | + | |
33813 | #ifdef HAVE_PCRE_H | |
33814 | /* allow 2 params */ | |
33815 | if (NULL == (p->ssi_regex = pcre_compile("<!--#([a-z]+)\\s+(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?-->", 0, &errptr, &erroff, NULL))) { | |
33816 | log_error_write(srv, __FILE__, __LINE__, "sds", | |
33817 | - "ssi: pcre ", | |
33818 | + "ssi: pcre ", | |
33819 | erroff, errptr); | |
33820 | return HANDLER_ERROR; | |
33821 | } | |
33822 | @@ -130,52 +131,52 @@ | |
33823 | "mod_ssi: pcre support is missing, please recompile with pcre support or remove mod_ssi from the list of modules"); | |
33824 | return HANDLER_ERROR; | |
33825 | #endif | |
33826 | - | |
33827 | + | |
33828 | return HANDLER_GO_ON; | |
33829 | } | |
33830 | ||
33831 | int ssi_env_add(array *env, const char *key, const char *val) { | |
33832 | data_string *ds; | |
33833 | - | |
33834 | + | |
33835 | if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) { | |
33836 | ds = data_string_init(); | |
33837 | } | |
33838 | buffer_copy_string(ds->key, key); | |
33839 | buffer_copy_string(ds->value, val); | |
33840 | - | |
33841 | + | |
33842 | array_insert_unique(env, (data_unset *)ds); | |
33843 | - | |
33844 | + | |
33845 | return 0; | |
33846 | } | |
33847 | ||
33848 | /** | |
33849 | * | |
33850 | * the next two functions are take from fcgi.c | |
33851 | - * | |
33852 | + * | |
33853 | */ | |
33854 | ||
33855 | static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data *p) { | |
33856 | size_t i; | |
33857 | - | |
33858 | + | |
33859 | for (i = 0; i < con->request.headers->used; i++) { | |
33860 | data_string *ds; | |
33861 | - | |
33862 | + | |
33863 | ds = (data_string *)con->request.headers->data[i]; | |
33864 | - | |
33865 | + | |
33866 | if (ds->value->used && ds->key->used) { | |
33867 | size_t j; | |
33868 | buffer_reset(srv->tmp_buf); | |
33869 | - | |
33870 | + | |
33871 | /* don't forward the Authorization: Header */ | |
33872 | if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) { | |
33873 | continue; | |
33874 | } | |
33875 | - | |
33876 | + | |
33877 | if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { | |
33878 | buffer_copy_string(srv->tmp_buf, "HTTP_"); | |
33879 | srv->tmp_buf->used--; | |
33880 | } | |
33881 | - | |
33882 | + | |
33883 | buffer_prepare_append(srv->tmp_buf, ds->key->used + 2); | |
33884 | for (j = 0; j < ds->key->used - 1; j++) { | |
33885 | char c = '_'; | |
33886 | @@ -189,33 +190,33 @@ | |
33887 | srv->tmp_buf->ptr[srv->tmp_buf->used++] = c; | |
33888 | } | |
33889 | srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0'; | |
33890 | - | |
33891 | + | |
33892 | ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr); | |
33893 | } | |
33894 | } | |
33895 | - | |
33896 | + | |
33897 | return 0; | |
33898 | } | |
33899 | ||
33900 | static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) { | |
33901 | char buf[32]; | |
33902 | - | |
33903 | + | |
33904 | server_socket *srv_sock = con->srv_socket; | |
33905 | - | |
33906 | + | |
33907 | #ifdef HAVE_IPV6 | |
33908 | char b2[INET6_ADDRSTRLEN + 1]; | |
33909 | #endif | |
33910 | ||
33911 | #define CONST_STRING(x) \ | |
33912 | x | |
33913 | - | |
33914 | + | |
33915 | array_reset(p->ssi_cgi_env); | |
33916 | - | |
33917 | + | |
33918 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION); | |
33919 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"), | |
33920 | #ifdef HAVE_IPV6 | |
33921 | - inet_ntop(srv_sock->addr.plain.sa_family, | |
33922 | - srv_sock->addr.plain.sa_family == AF_INET6 ? | |
33923 | + inet_ntop(srv_sock->addr.plain.sa_family, | |
33924 | + srv_sock->addr.plain.sa_family == AF_INET6 ? | |
33925 | (const void *) &(srv_sock->addr.ipv6.sin6_addr) : | |
33926 | (const void *) &(srv_sock->addr.ipv4.sin_addr), | |
33927 | b2, sizeof(b2)-1) | |
33928 | @@ -224,28 +225,28 @@ | |
33929 | #endif | |
33930 | ); | |
33931 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1"); | |
33932 | - | |
33933 | - ltostr(buf, | |
33934 | + | |
33935 | + ltostr(buf, | |
33936 | #ifdef HAVE_IPV6 | |
33937 | ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port) | |
33938 | #else | |
33939 | ntohs(srv_sock->addr.ipv4.sin_port) | |
33940 | #endif | |
33941 | ); | |
33942 | - | |
33943 | + | |
33944 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PORT"), buf); | |
33945 | - | |
33946 | + | |
33947 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_ADDR"), | |
33948 | inet_ntop_cache_get_ip(srv, &(con->dst_addr))); | |
33949 | - | |
33950 | + | |
33951 | if (con->authed_user->used) { | |
33952 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_USER"), | |
33953 | con->authed_user->ptr); | |
33954 | } | |
33955 | - | |
33956 | + | |
33957 | if (con->request.content_length > 0) { | |
33958 | /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */ | |
33959 | - | |
33960 | + | |
33961 | /* request.content_length < SSIZE_MAX, see request.c */ | |
33962 | ltostr(buf, con->request.content_length); | |
33963 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("CONTENT_LENGTH"), buf); | |
33964 | @@ -271,30 +272,30 @@ | |
33965 | if (con->request.pathinfo->used) { | |
33966 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("PATH_INFO"), con->request.pathinfo->ptr); | |
33967 | } | |
33968 | - | |
33969 | + | |
33970 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("SCRIPT_FILENAME"), con->physical.path->ptr); | |
33971 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("DOCUMENT_ROOT"), con->physical.doc_root->ptr); | |
33972 | - | |
33973 | + | |
33974 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_URI"), con->request.uri->ptr); | |
33975 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("QUERY_STRING"), con->uri.query->used ? con->uri.query->ptr : ""); | |
33976 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_METHOD"), get_http_method_name(con->request.http_method)); | |
33977 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("REDIRECT_STATUS"), "200"); | |
33978 | ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PROTOCOL"), get_http_version_name(con->request.http_version)); | |
33979 | - | |
33980 | + | |
33981 | ssi_env_add_request_headers(srv, con, p); | |
33982 | - | |
33983 | + | |
33984 | return 0; | |
33985 | } | |
33986 | ||
33987 | -static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, | |
33988 | +static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, | |
33989 | const char **l, size_t n) { | |
33990 | size_t i, ssicmd = 0; | |
33991 | char buf[255]; | |
33992 | buffer *b = NULL; | |
33993 | - | |
33994 | - struct { | |
33995 | + | |
33996 | + struct { | |
33997 | const char *var; | |
33998 | - enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD, | |
33999 | + enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD, | |
34000 | SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF, | |
34001 | SSI_ELSE, SSI_ENDIF, SSI_EXEC } type; | |
34002 | } ssicmds[] = { | |
34003 | @@ -310,27 +311,27 @@ | |
34004 | { "endif", SSI_ENDIF }, | |
34005 | { "else", SSI_ELSE }, | |
34006 | { "exec", SSI_EXEC }, | |
34007 | - | |
34008 | + | |
34009 | { NULL, SSI_UNSET } | |
34010 | }; | |
34011 | - | |
34012 | + | |
34013 | for (i = 0; ssicmds[i].var; i++) { | |
34014 | if (0 == strcmp(l[1], ssicmds[i].var)) { | |
34015 | ssicmd = ssicmds[i].type; | |
34016 | break; | |
34017 | } | |
34018 | } | |
34019 | - | |
34020 | + | |
34021 | switch(ssicmd) { | |
34022 | case SSI_ECHO: { | |
34023 | /* echo */ | |
34024 | int var = 0, enc = 0; | |
34025 | const char *var_val = NULL; | |
34026 | stat_cache_entry *sce = NULL; | |
34027 | - | |
34028 | - struct { | |
34029 | + | |
34030 | + struct { | |
34031 | const char *var; | |
34032 | - enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI, | |
34033 | + enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI, | |
34034 | SSI_ECHO_LAST_MODIFIED, SSI_ECHO_USER_NAME } type; | |
34035 | } echovars[] = { | |
34036 | { "DATE_GMT", SSI_ECHO_DATE_GMT }, | |
34037 | @@ -339,27 +340,27 @@ | |
34038 | { "DOCUMENT_URI", SSI_ECHO_DOCUMENT_URI }, | |
34039 | { "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED }, | |
34040 | { "USER_NAME", SSI_ECHO_USER_NAME }, | |
34041 | - | |
34042 | + | |
34043 | { NULL, SSI_ECHO_UNSET } | |
34044 | }; | |
34045 | - | |
34046 | - struct { | |
34047 | + | |
34048 | + struct { | |
34049 | const char *var; | |
34050 | enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type; | |
34051 | } encvars[] = { | |
34052 | { "url", SSI_ENC_URL }, | |
34053 | { "none", SSI_ENC_NONE }, | |
34054 | { "entity", SSI_ENC_ENTITY }, | |
34055 | - | |
34056 | + | |
34057 | { NULL, SSI_ENC_UNSET } | |
34058 | }; | |
34059 | - | |
34060 | + | |
34061 | for (i = 2; i < n; i += 2) { | |
34062 | if (0 == strcmp(l[i], "var")) { | |
34063 | int j; | |
34064 | - | |
34065 | + | |
34066 | var_val = l[i+1]; | |
34067 | - | |
34068 | + | |
34069 | for (j = 0; echovars[j].var; j++) { | |
34070 | if (0 == strcmp(l[i+1], echovars[j].var)) { | |
34071 | var = echovars[j].type; | |
34072 | @@ -368,7 +369,7 @@ | |
34073 | } | |
34074 | } else if (0 == strcmp(l[i], "encoding")) { | |
34075 | int j; | |
34076 | - | |
34077 | + | |
34078 | for (j = 0; encvars[j].var; j++) { | |
34079 | if (0 == strcmp(l[i+1], encvars[j].var)) { | |
34080 | enc = encvars[j].type; | |
34081 | @@ -377,26 +378,26 @@ | |
34082 | } | |
34083 | } else { | |
34084 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34085 | - "ssi: unknow attribute for ", | |
34086 | + "ssi: unknow attribute for ", | |
34087 | l[1], l[i]); | |
34088 | } | |
34089 | } | |
34090 | - | |
34091 | + | |
34092 | if (p->if_is_false) break; | |
34093 | - | |
34094 | + | |
34095 | if (!var_val) { | |
34096 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34097 | - "ssi: ", | |
34098 | + "ssi: ", | |
34099 | l[1], "var is missing"); | |
34100 | break; | |
34101 | } | |
34102 | ||
34103 | stat_cache_get_entry(srv, con, con->physical.path, &sce); | |
34104 | - | |
34105 | + | |
34106 | switch(var) { | |
34107 | case SSI_ECHO_USER_NAME: { | |
34108 | struct passwd *pw; | |
34109 | - | |
34110 | + | |
34111 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34112 | #ifdef HAVE_PWD_H | |
34113 | if (NULL == (pw = getpwuid(sce->st.st_uid))) { | |
34114 | @@ -411,7 +412,7 @@ | |
34115 | } | |
34116 | case SSI_ECHO_LAST_MODIFIED: { | |
34117 | time_t t = sce->st.st_mtime; | |
34118 | - | |
34119 | + | |
34120 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34121 | if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { | |
34122 | buffer_copy_string(b, "(none)"); | |
34123 | @@ -422,7 +423,7 @@ | |
34124 | } | |
34125 | case SSI_ECHO_DATE_LOCAL: { | |
34126 | time_t t = time(NULL); | |
34127 | - | |
34128 | + | |
34129 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34130 | if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { | |
34131 | buffer_copy_string(b, "(none)"); | |
34132 | @@ -433,7 +434,7 @@ | |
34133 | } | |
34134 | case SSI_ECHO_DATE_GMT: { | |
34135 | time_t t = time(NULL); | |
34136 | - | |
34137 | + | |
34138 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34139 | if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) { | |
34140 | buffer_copy_string(b, "(none)"); | |
34141 | @@ -444,7 +445,7 @@ | |
34142 | } | |
34143 | case SSI_ECHO_DOCUMENT_NAME: { | |
34144 | char *sl; | |
34145 | - | |
34146 | + | |
34147 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34148 | if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) { | |
34149 | buffer_copy_string_buffer(b, con->physical.path); | |
34150 | @@ -461,15 +462,15 @@ | |
34151 | default: { | |
34152 | data_string *ds; | |
34153 | /* check if it is a cgi-var */ | |
34154 | - | |
34155 | + | |
34156 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34157 | - | |
34158 | + | |
34159 | if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) { | |
34160 | buffer_copy_string_buffer(b, ds->value); | |
34161 | } else { | |
34162 | buffer_copy_string(b, "(none)"); | |
34163 | } | |
34164 | - | |
34165 | + | |
34166 | break; | |
34167 | } | |
34168 | } | |
34169 | @@ -481,7 +482,7 @@ | |
34170 | const char * file_path = NULL, *virt_path = NULL; | |
34171 | struct stat st; | |
34172 | char *sl; | |
34173 | - | |
34174 | + | |
34175 | for (i = 2; i < n; i += 2) { | |
34176 | if (0 == strcmp(l[i], "file")) { | |
34177 | file_path = l[i+1]; | |
34178 | @@ -489,28 +490,28 @@ | |
34179 | virt_path = l[i+1]; | |
34180 | } else { | |
34181 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34182 | - "ssi: unknow attribute for ", | |
34183 | + "ssi: unknow attribute for ", | |
34184 | l[1], l[i]); | |
34185 | } | |
34186 | } | |
34187 | - | |
34188 | + | |
34189 | if (!file_path && !virt_path) { | |
34190 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34191 | - "ssi: ", | |
34192 | + "ssi: ", | |
34193 | l[1], "file or virtual are missing"); | |
34194 | break; | |
34195 | } | |
34196 | - | |
34197 | + | |
34198 | if (file_path && virt_path) { | |
34199 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34200 | - "ssi: ", | |
34201 | + "ssi: ", | |
34202 | l[1], "only one of file and virtual is allowed here"); | |
34203 | break; | |
34204 | } | |
34205 | - | |
34206 | - | |
34207 | + | |
34208 | + | |
34209 | if (p->if_is_false) break; | |
34210 | - | |
34211 | + | |
34212 | if (file_path) { | |
34213 | /* current doc-root */ | |
34214 | if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) { | |
34215 | @@ -519,46 +520,46 @@ | |
34216 | buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, sl - con->physical.path->ptr + 1); | |
34217 | } | |
34218 | ||
34219 | - buffer_copy_string(srv->tmp_buf, file_path); | |
34220 | + buffer_copy_string(srv->tmp_buf, file_path); | |
34221 | buffer_urldecode_path(srv->tmp_buf); | |
34222 | - buffer_path_simplify(srv->tmp_buf, srv->tmp_buf); | |
34223 | - buffer_append_string_buffer(p->stat_fn, srv->tmp_buf); | |
34224 | + buffer_path_simplify(srv->tmp_buf, srv->tmp_buf); | |
34225 | + buffer_append_string_buffer(p->stat_fn, srv->tmp_buf); | |
34226 | } else { | |
34227 | /* virtual */ | |
34228 | - | |
34229 | + | |
34230 | if (virt_path[0] == '/') { | |
34231 | buffer_copy_string(p->stat_fn, virt_path); | |
34232 | } else { | |
34233 | /* there is always a / */ | |
34234 | sl = strrchr(con->uri.path->ptr, '/'); | |
34235 | - | |
34236 | + | |
34237 | buffer_copy_string_len(p->stat_fn, con->uri.path->ptr, sl - con->uri.path->ptr + 1); | |
34238 | buffer_append_string(p->stat_fn, virt_path); | |
34239 | } | |
34240 | - | |
34241 | + | |
34242 | buffer_urldecode_path(p->stat_fn); | |
34243 | buffer_path_simplify(srv->tmp_buf, p->stat_fn); | |
34244 | - | |
34245 | + | |
34246 | /* we have an uri */ | |
34247 | - | |
34248 | + | |
34249 | buffer_copy_string_buffer(p->stat_fn, con->physical.doc_root); | |
34250 | buffer_append_string_buffer(p->stat_fn, srv->tmp_buf); | |
34251 | } | |
34252 | - | |
34253 | + | |
34254 | if (0 == stat(p->stat_fn->ptr, &st)) { | |
34255 | time_t t = st.st_mtime; | |
34256 | - | |
34257 | + | |
34258 | switch (ssicmd) { | |
34259 | case SSI_FSIZE: | |
34260 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34261 | if (p->sizefmt) { | |
34262 | int j = 0; | |
34263 | const char *abr[] = { " B", " kB", " MB", " GB", " TB", NULL }; | |
34264 | - | |
34265 | + | |
34266 | off_t s = st.st_size; | |
34267 | - | |
34268 | + | |
34269 | for (j = 0; s > 1024 && abr[j+1]; s /= 1024, j++); | |
34270 | - | |
34271 | + | |
34272 | buffer_copy_off_t(b, s); | |
34273 | buffer_append_string(b, abr[j]); | |
34274 | } else { | |
34275 | @@ -579,7 +580,7 @@ | |
34276 | } | |
34277 | } else { | |
34278 | log_error_write(srv, __FILE__, __LINE__, "sbs", | |
34279 | - "ssi: stating failed ", | |
34280 | + "ssi: stating failed ", | |
34281 | p->stat_fn, strerror(errno)); | |
34282 | } | |
34283 | break; | |
34284 | @@ -593,33 +594,33 @@ | |
34285 | val = l[i+1]; | |
34286 | } else { | |
34287 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34288 | - "ssi: unknow attribute for ", | |
34289 | + "ssi: unknow attribute for ", | |
34290 | l[1], l[i]); | |
34291 | } | |
34292 | } | |
34293 | - | |
34294 | + | |
34295 | if (p->if_is_false) break; | |
34296 | - | |
34297 | + | |
34298 | if (key && val) { | |
34299 | data_string *ds; | |
34300 | - | |
34301 | + | |
34302 | if (NULL == (ds = (data_string *)array_get_unused_element(p->ssi_vars, TYPE_STRING))) { | |
34303 | ds = data_string_init(); | |
34304 | } | |
34305 | buffer_copy_string(ds->key, key); | |
34306 | buffer_copy_string(ds->value, val); | |
34307 | - | |
34308 | + | |
34309 | array_insert_unique(p->ssi_vars, (data_unset *)ds); | |
34310 | } else { | |
34311 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34312 | - "ssi: var and value have to be set in", | |
34313 | + "ssi: var and value have to be set in", | |
34314 | l[0], l[1]); | |
34315 | } | |
34316 | break; | |
34317 | } | |
34318 | - case SSI_CONFIG: | |
34319 | + case SSI_CONFIG: | |
34320 | if (p->if_is_false) break; | |
34321 | - | |
34322 | + | |
34323 | for (i = 2; i < n; i += 2) { | |
34324 | if (0 == strcmp(l[i], "timefmt")) { | |
34325 | buffer_copy_string(p->timefmt, l[i+1]); | |
34326 | @@ -632,63 +633,65 @@ | |
34327 | log_error_write(srv, __FILE__, __LINE__, "sssss", | |
34328 | "ssi: unknow value for attribute '", | |
34329 | l[i], | |
34330 | - "' for ", | |
34331 | + "' for ", | |
34332 | l[1], l[i+1]); | |
34333 | } | |
34334 | } else { | |
34335 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34336 | - "ssi: unknow attribute for ", | |
34337 | + "ssi: unknow attribute for ", | |
34338 | l[1], l[i]); | |
34339 | } | |
34340 | } | |
34341 | break; | |
34342 | case SSI_PRINTENV: | |
34343 | if (p->if_is_false) break; | |
34344 | - | |
34345 | + | |
34346 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34347 | buffer_copy_string(b, "<pre>"); | |
34348 | for (i = 0; i < p->ssi_vars->used; i++) { | |
34349 | data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]]; | |
34350 | - | |
34351 | + | |
34352 | buffer_append_string_buffer(b, ds->key); | |
34353 | buffer_append_string(b, ": "); | |
34354 | buffer_append_string_buffer(b, ds->value); | |
34355 | buffer_append_string(b, "<br />"); | |
34356 | - | |
34357 | + | |
34358 | } | |
34359 | buffer_append_string(b, "</pre>"); | |
34360 | - | |
34361 | + | |
34362 | break; | |
34363 | case SSI_EXEC: { | |
34364 | +#ifndef _WIN32 | |
34365 | + | |
34366 | const char *cmd = NULL; | |
34367 | pid_t pid; | |
34368 | int from_exec_fds[2]; | |
34369 | - | |
34370 | + | |
34371 | for (i = 2; i < n; i += 2) { | |
34372 | if (0 == strcmp(l[i], "cmd")) { | |
34373 | cmd = l[i+1]; | |
34374 | } else { | |
34375 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34376 | - "ssi: unknow attribute for ", | |
34377 | + "ssi: unknow attribute for ", | |
34378 | l[1], l[i]); | |
34379 | } | |
34380 | } | |
34381 | - | |
34382 | + | |
34383 | if (p->if_is_false) break; | |
34384 | - | |
34385 | + | |
34386 | /* create a return pipe and send output to the html-page | |
34387 | - * | |
34388 | - * as exec is assumed evil it is implemented synchronously | |
34389 | + * | |
34390 | + * as exec is assumed evil it is implemented synchronously | |
34391 | */ | |
34392 | - | |
34393 | + | |
34394 | if (!cmd) break; | |
34395 | -#ifdef HAVE_FORK | |
34396 | + | |
34397 | if (pipe(from_exec_fds)) { | |
34398 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
34399 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
34400 | "pipe failed: ", strerror(errno)); | |
34401 | return -1; | |
34402 | } | |
34403 | - | |
34404 | + | |
34405 | /* fork, execve */ | |
34406 | switch (pid = fork()) { | |
34407 | case 0: { | |
34408 | @@ -698,14 +701,14 @@ | |
34409 | close(from_exec_fds[1]); | |
34410 | /* not needed */ | |
34411 | close(from_exec_fds[0]); | |
34412 | - | |
34413 | + | |
34414 | /* close stdin */ | |
34415 | close(STDIN_FILENO); | |
34416 | - | |
34417 | + | |
34418 | execl("/bin/sh", "sh", "-c", cmd, NULL); | |
34419 | - | |
34420 | + | |
34421 | log_error_write(srv, __FILE__, __LINE__, "sss", "spawing exec failed:", strerror(errno), cmd); | |
34422 | - | |
34423 | + | |
34424 | /* */ | |
34425 | SEGFAULT(); | |
34426 | break; | |
34427 | @@ -718,9 +721,9 @@ | |
34428 | /* father */ | |
34429 | int status; | |
34430 | ssize_t r; | |
34431 | - | |
34432 | + | |
34433 | close(from_exec_fds[1]); | |
34434 | - | |
34435 | + | |
34436 | /* wait for the client to end */ | |
34437 | if (-1 == waitpid(pid, &status, 0)) { | |
34438 | log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno)); | |
34439 | @@ -730,7 +733,7 @@ | |
34440 | ||
34441 | while(1) { | |
34442 | if (ioctl(from_exec_fds[0], FIONREAD, &toread)) { | |
34443 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
34444 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
34445 | "unexpected end-of-file (perhaps the ssi-exec process died)"); | |
34446 | return -1; | |
34447 | } | |
34448 | @@ -738,10 +741,10 @@ | |
34449 | if (toread > 0) { | |
34450 | b = chunkqueue_get_append_buffer(con->write_queue); | |
34451 | ||
34452 | - buffer_prepare_copy(b, toread + 1); | |
34453 | + buffer_prepare_copy(b, toread + 1); | |
34454 | ||
34455 | if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) { | |
34456 | - /* read failed */ | |
34457 | + /* read failed */ | |
34458 | break; | |
34459 | } else { | |
34460 | b->used = r; | |
34461 | @@ -755,59 +758,58 @@ | |
34462 | log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally"); | |
34463 | } | |
34464 | close(from_exec_fds[0]); | |
34465 | - | |
34466 | + | |
34467 | break; | |
34468 | } | |
34469 | } | |
34470 | #else | |
34471 | - | |
34472 | return -1; | |
34473 | #endif | |
34474 | - | |
34475 | + | |
34476 | break; | |
34477 | } | |
34478 | case SSI_IF: { | |
34479 | const char *expr = NULL; | |
34480 | - | |
34481 | + | |
34482 | for (i = 2; i < n; i += 2) { | |
34483 | if (0 == strcmp(l[i], "expr")) { | |
34484 | expr = l[i+1]; | |
34485 | } else { | |
34486 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34487 | - "ssi: unknow attribute for ", | |
34488 | + "ssi: unknow attribute for ", | |
34489 | l[1], l[i]); | |
34490 | } | |
34491 | } | |
34492 | - | |
34493 | + | |
34494 | if (!expr) { | |
34495 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34496 | - "ssi: ", | |
34497 | + "ssi: ", | |
34498 | l[1], "expr missing"); | |
34499 | break; | |
34500 | } | |
34501 | - | |
34502 | + | |
34503 | if ((!p->if_is_false) && | |
34504 | - ((p->if_is_false_level == 0) || | |
34505 | + ((p->if_is_false_level == 0) || | |
34506 | (p->if_level < p->if_is_false_level))) { | |
34507 | switch (ssi_eval_expr(srv, con, p, expr)) { | |
34508 | case -1: | |
34509 | - case 0: | |
34510 | - p->if_is_false = 1; | |
34511 | + case 0: | |
34512 | + p->if_is_false = 1; | |
34513 | p->if_is_false_level = p->if_level; | |
34514 | break; | |
34515 | - case 1: | |
34516 | - p->if_is_false = 0; | |
34517 | + case 1: | |
34518 | + p->if_is_false = 0; | |
34519 | break; | |
34520 | } | |
34521 | } | |
34522 | - | |
34523 | + | |
34524 | p->if_level++; | |
34525 | - | |
34526 | + | |
34527 | break; | |
34528 | } | |
34529 | case SSI_ELSE: | |
34530 | p->if_level--; | |
34531 | - | |
34532 | + | |
34533 | if (p->if_is_false) { | |
34534 | if ((p->if_level == p->if_is_false_level) && | |
34535 | (p->if_is_false_endif == 0)) { | |
34536 | @@ -815,11 +817,11 @@ | |
34537 | } | |
34538 | } else { | |
34539 | p->if_is_false = 1; | |
34540 | - | |
34541 | + | |
34542 | p->if_is_false_level = p->if_level; | |
34543 | } | |
34544 | p->if_level++; | |
34545 | - | |
34546 | + | |
34547 | break; | |
34548 | case SSI_ELIF: { | |
34549 | const char *expr = NULL; | |
34550 | @@ -828,52 +830,52 @@ | |
34551 | expr = l[i+1]; | |
34552 | } else { | |
34553 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34554 | - "ssi: unknow attribute for ", | |
34555 | + "ssi: unknow attribute for ", | |
34556 | l[1], l[i]); | |
34557 | } | |
34558 | } | |
34559 | - | |
34560 | + | |
34561 | if (!expr) { | |
34562 | log_error_write(srv, __FILE__, __LINE__, "sss", | |
34563 | - "ssi: ", | |
34564 | + "ssi: ", | |
34565 | l[1], "expr missing"); | |
34566 | break; | |
34567 | } | |
34568 | - | |
34569 | + | |
34570 | p->if_level--; | |
34571 | - | |
34572 | + | |
34573 | if (p->if_level == p->if_is_false_level) { | |
34574 | if ((p->if_is_false) && | |
34575 | (p->if_is_false_endif == 0)) { | |
34576 | switch (ssi_eval_expr(srv, con, p, expr)) { | |
34577 | case -1: | |
34578 | - case 0: | |
34579 | - p->if_is_false = 1; | |
34580 | + case 0: | |
34581 | + p->if_is_false = 1; | |
34582 | p->if_is_false_level = p->if_level; | |
34583 | break; | |
34584 | - case 1: | |
34585 | - p->if_is_false = 0; | |
34586 | + case 1: | |
34587 | + p->if_is_false = 0; | |
34588 | break; | |
34589 | } | |
34590 | } else { | |
34591 | - p->if_is_false = 1; | |
34592 | + p->if_is_false = 1; | |
34593 | p->if_is_false_level = p->if_level; | |
34594 | p->if_is_false_endif = 1; | |
34595 | } | |
34596 | } | |
34597 | - | |
34598 | + | |
34599 | p->if_level++; | |
34600 | - | |
34601 | + | |
34602 | break; | |
34603 | } | |
34604 | case SSI_ENDIF: | |
34605 | p->if_level--; | |
34606 | - | |
34607 | + | |
34608 | if (p->if_level == p->if_is_false_level) { | |
34609 | p->if_is_false = 0; | |
34610 | p->if_is_false_endif = 0; | |
34611 | } | |
34612 | - | |
34613 | + | |
34614 | break; | |
34615 | default: | |
34616 | log_error_write(srv, __FILE__, __LINE__, "ss", | |
34617 | @@ -881,41 +883,41 @@ | |
34618 | l[1]); | |
34619 | break; | |
34620 | } | |
34621 | - | |
34622 | + | |
34623 | return 0; | |
34624 | - | |
34625 | + | |
34626 | } | |
34627 | ||
34628 | static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) { | |
34629 | stream s; | |
34630 | #ifdef HAVE_PCRE_H | |
34631 | int i, n; | |
34632 | - | |
34633 | + | |
34634 | #define N 10 | |
34635 | int ovec[N * 3]; | |
34636 | #endif | |
34637 | - | |
34638 | + | |
34639 | /* get a stream to the file */ | |
34640 | - | |
34641 | + | |
34642 | array_reset(p->ssi_vars); | |
34643 | array_reset(p->ssi_cgi_env); | |
34644 | buffer_copy_string(p->timefmt, "%a, %d %b %Y %H:%M:%S %Z"); | |
34645 | p->sizefmt = 0; | |
34646 | build_ssi_cgi_vars(srv, con, p); | |
34647 | p->if_is_false = 0; | |
34648 | - | |
34649 | + | |
34650 | if (-1 == stream_open(&s, con->physical.path)) { | |
34651 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
34652 | "stream-open: ", con->physical.path); | |
34653 | return -1; | |
34654 | } | |
34655 | - | |
34656 | - | |
34657 | + | |
34658 | + | |
34659 | /** | |
34660 | - * <!--#element attribute=value attribute=value ... --> | |
34661 | - * | |
34662 | + * <!--#element attribute=value attribute=value ... --> | |
34663 | + * | |
34664 | * config DONE | |
34665 | - * errmsg -- missing | |
34666 | + * errmsg -- missing | |
34667 | * sizefmt DONE | |
34668 | * timefmt DONE | |
34669 | * echo DONE | |
34670 | @@ -937,13 +939,13 @@ | |
34671 | * set DONE | |
34672 | * var DONE | |
34673 | * value DONE | |
34674 | - * | |
34675 | + * | |
34676 | * if DONE | |
34677 | * elif DONE | |
34678 | * else DONE | |
34679 | * endif DONE | |
34680 | - * | |
34681 | - * | |
34682 | + * | |
34683 | + * | |
34684 | * expressions | |
34685 | * AND, OR DONE | |
34686 | * comp DONE | |
34687 | @@ -951,118 +953,115 @@ | |
34688 | * $... DONE | |
34689 | * '...' DONE | |
34690 | * ( ... ) DONE | |
34691 | - * | |
34692 | - * | |
34693 | - * | |
34694 | + * | |
34695 | + * | |
34696 | + * | |
34697 | * ** all DONE ** | |
34698 | - * DATE_GMT | |
34699 | - * The current date in Greenwich Mean Time. | |
34700 | - * DATE_LOCAL | |
34701 | - * The current date in the local time zone. | |
34702 | - * DOCUMENT_NAME | |
34703 | - * The filename (excluding directories) of the document requested by the user. | |
34704 | - * DOCUMENT_URI | |
34705 | - * The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. | |
34706 | - * LAST_MODIFIED | |
34707 | - * The last modification date of the document requested by the user. | |
34708 | - * USER_NAME | |
34709 | + * DATE_GMT | |
34710 | + * The current date in Greenwich Mean Time. | |
34711 | + * DATE_LOCAL | |
34712 | + * The current date in the local time zone. | |
34713 | + * DOCUMENT_NAME | |
34714 | + * The filename (excluding directories) of the document requested by the user. | |
34715 | + * DOCUMENT_URI | |
34716 | + * The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. | |
34717 | + * LAST_MODIFIED | |
34718 | + * The last modification date of the document requested by the user. | |
34719 | + * USER_NAME | |
34720 | * Contains the owner of the file which included it. | |
34721 | - * | |
34722 | + * | |
34723 | */ | |
34724 | -#ifdef HAVE_PCRE_H | |
34725 | +#ifdef HAVE_PCRE_H | |
34726 | for (i = 0; (n = pcre_exec(p->ssi_regex, NULL, s.start, s.size, i, 0, ovec, N * 3)) > 0; i = ovec[1]) { | |
34727 | const char **l; | |
34728 | /* take everything from last offset to current match pos */ | |
34729 | - | |
34730 | + | |
34731 | if (!p->if_is_false) chunkqueue_append_file(con->write_queue, con->physical.path, i, ovec[0] - i); | |
34732 | - | |
34733 | + | |
34734 | pcre_get_substring_list(s.start, ovec, n, &l); | |
34735 | process_ssi_stmt(srv, con, p, l, n); | |
34736 | pcre_free_substring_list(l); | |
34737 | } | |
34738 | - | |
34739 | + | |
34740 | switch(n) { | |
34741 | case PCRE_ERROR_NOMATCH: | |
34742 | /* copy everything/the rest */ | |
34743 | chunkqueue_append_file(con->write_queue, con->physical.path, i, s.size - i); | |
34744 | - | |
34745 | + | |
34746 | break; | |
34747 | default: | |
34748 | log_error_write(srv, __FILE__, __LINE__, "sd", | |
34749 | "execution error while matching: ", n); | |
34750 | break; | |
34751 | } | |
34752 | -#endif | |
34753 | - | |
34754 | - | |
34755 | +#endif | |
34756 | + | |
34757 | + | |
34758 | stream_close(&s); | |
34759 | - | |
34760 | + | |
34761 | con->file_started = 1; | |
34762 | con->file_finished = 1; | |
34763 | - | |
34764 | + | |
34765 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); | |
34766 | - | |
34767 | + | |
34768 | /* reset physical.path */ | |
34769 | buffer_reset(con->physical.path); | |
34770 | - | |
34771 | + | |
34772 | return 0; | |
34773 | } | |
34774 | ||
34775 | -#define PATCH(x) \ | |
34776 | - p->conf.x = s->x; | |
34777 | static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p) { | |
34778 | size_t i, j; | |
34779 | plugin_config *s = p->config_storage[0]; | |
34780 | - | |
34781 | - PATCH(ssi_extension); | |
34782 | - | |
34783 | + | |
34784 | + PATCH_OPTION(ssi_extension); | |
34785 | + | |
34786 | /* skip the first, the global context */ | |
34787 | for (i = 1; i < srv->config_context->used; i++) { | |
34788 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
34789 | s = p->config_storage[i]; | |
34790 | - | |
34791 | + | |
34792 | /* condition didn't match */ | |
34793 | if (!config_check_cond(srv, con, dc)) continue; | |
34794 | - | |
34795 | + | |
34796 | /* merge config */ | |
34797 | for (j = 0; j < dc->value->used; j++) { | |
34798 | data_unset *du = dc->value->data[j]; | |
34799 | - | |
34800 | + | |
34801 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) { | |
34802 | - PATCH(ssi_extension); | |
34803 | + PATCH_OPTION(ssi_extension); | |
34804 | } | |
34805 | } | |
34806 | } | |
34807 | - | |
34808 | + | |
34809 | return 0; | |
34810 | } | |
34811 | -#undef PATCH | |
34812 | ||
34813 | URIHANDLER_FUNC(mod_ssi_physical_path) { | |
34814 | plugin_data *p = p_d; | |
34815 | size_t k; | |
34816 | - | |
34817 | + | |
34818 | if (con->physical.path->used == 0) return HANDLER_GO_ON; | |
34819 | - | |
34820 | + | |
34821 | mod_ssi_patch_connection(srv, con, p); | |
34822 | - | |
34823 | + | |
34824 | for (k = 0; k < p->conf.ssi_extension->used; k++) { | |
34825 | data_string *ds = (data_string *)p->conf.ssi_extension->data[k]; | |
34826 | - | |
34827 | + | |
34828 | if (ds->value->used == 0) continue; | |
34829 | - | |
34830 | + | |
34831 | if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) { | |
34832 | /* handle ssi-request */ | |
34833 | - | |
34834 | + | |
34835 | if (mod_ssi_handle_request(srv, con, p)) { | |
34836 | /* on error */ | |
34837 | con->http_status = 500; | |
34838 | } | |
34839 | - | |
34840 | + | |
34841 | return HANDLER_FINISHED; | |
34842 | } | |
34843 | } | |
34844 | - | |
34845 | + | |
34846 | /* not found */ | |
34847 | return HANDLER_GO_ON; | |
34848 | } | |
34849 | @@ -1072,13 +1071,13 @@ | |
34850 | int mod_ssi_plugin_init(plugin *p) { | |
34851 | p->version = LIGHTTPD_VERSION_ID; | |
34852 | p->name = buffer_init_string("ssi"); | |
34853 | - | |
34854 | + | |
34855 | p->init = mod_ssi_init; | |
34856 | p->handle_subrequest_start = mod_ssi_physical_path; | |
34857 | p->set_defaults = mod_ssi_set_defaults; | |
34858 | p->cleanup = mod_ssi_free; | |
34859 | - | |
34860 | + | |
34861 | p->data = NULL; | |
34862 | - | |
34863 | + | |
34864 | return 0; | |
34865 | } | |
1175ccec | 34866 | --- ../lighttpd-1.4.11/src/mod_ssi.h 2005-08-11 01:26:39.000000000 +0300 |
36e2a29e | 34867 | +++ lighttpd-1.4.12/src/mod_ssi.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
34868 | @@ -19,23 +19,23 @@ |
34869 | ||
34870 | typedef struct { | |
34871 | PLUGIN_DATA; | |
34872 | - | |
34873 | -#ifdef HAVE_PCRE_H | |
34874 | + | |
34875 | +#ifdef HAVE_PCRE_H | |
34876 | pcre *ssi_regex; | |
34877 | -#endif | |
34878 | +#endif | |
34879 | buffer *timefmt; | |
34880 | int sizefmt; | |
34881 | - | |
34882 | + | |
34883 | buffer *stat_fn; | |
34884 | - | |
34885 | + | |
34886 | array *ssi_vars; | |
34887 | array *ssi_cgi_env; | |
34888 | - | |
34889 | + | |
34890 | int if_level, if_is_false_level, if_is_false, if_is_false_endif; | |
34891 | - | |
34892 | + | |
34893 | plugin_config **config_storage; | |
34894 | - | |
34895 | - plugin_config conf; | |
34896 | + | |
34897 | + plugin_config conf; | |
34898 | } plugin_data; | |
34899 | ||
34900 | int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr); | |
1175ccec | 34901 | --- ../lighttpd-1.4.11/src/mod_ssi_expr.c 2005-08-11 01:26:48.000000000 +0300 |
36e2a29e | 34902 | +++ lighttpd-1.4.12/src/mod_ssi_expr.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
34903 | @@ -11,9 +11,9 @@ |
34904 | const char *input; | |
34905 | size_t offset; | |
34906 | size_t size; | |
34907 | - | |
34908 | + | |
34909 | int line_pos; | |
34910 | - | |
34911 | + | |
34912 | int in_key; | |
34913 | int in_brace; | |
34914 | int in_cond; | |
34915 | @@ -21,15 +21,15 @@ | |
34916 | ||
34917 | ssi_val_t *ssi_val_init() { | |
34918 | ssi_val_t *s; | |
34919 | - | |
34920 | + | |
34921 | s = calloc(1, sizeof(*s)); | |
34922 | - | |
34923 | + | |
34924 | return s; | |
34925 | } | |
34926 | ||
34927 | void ssi_val_free(ssi_val_t *s) { | |
34928 | if (s->str) buffer_free(s->str); | |
34929 | - | |
34930 | + | |
34931 | free(s); | |
34932 | } | |
34933 | ||
34934 | @@ -45,175 +45,175 @@ | |
34935 | ssi_tokenizer_t *t, int *token_id, buffer *token) { | |
34936 | int tid = 0; | |
34937 | size_t i; | |
34938 | - | |
34939 | + | |
34940 | UNUSED(con); | |
34941 | ||
34942 | for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) { | |
34943 | char c = t->input[t->offset]; | |
34944 | data_string *ds; | |
34945 | - | |
34946 | + | |
34947 | switch (c) { | |
34948 | - case '=': | |
34949 | + case '=': | |
34950 | tid = TK_EQ; | |
34951 | - | |
34952 | + | |
34953 | t->offset++; | |
34954 | t->line_pos++; | |
34955 | - | |
34956 | + | |
34957 | buffer_copy_string(token, "(=)"); | |
34958 | - | |
34959 | + | |
34960 | break; | |
34961 | case '>': | |
34962 | if (t->input[t->offset + 1] == '=') { | |
34963 | t->offset += 2; | |
34964 | t->line_pos += 2; | |
34965 | - | |
34966 | + | |
34967 | tid = TK_GE; | |
34968 | - | |
34969 | + | |
34970 | buffer_copy_string(token, "(>=)"); | |
34971 | } else { | |
34972 | t->offset += 1; | |
34973 | t->line_pos += 1; | |
34974 | - | |
34975 | + | |
34976 | tid = TK_GT; | |
34977 | - | |
34978 | + | |
34979 | buffer_copy_string(token, "(>)"); | |
34980 | } | |
34981 | - | |
34982 | + | |
34983 | break; | |
34984 | case '<': | |
34985 | if (t->input[t->offset + 1] == '=') { | |
34986 | t->offset += 2; | |
34987 | t->line_pos += 2; | |
34988 | - | |
34989 | + | |
34990 | tid = TK_LE; | |
34991 | - | |
34992 | + | |
34993 | buffer_copy_string(token, "(<=)"); | |
34994 | } else { | |
34995 | t->offset += 1; | |
34996 | t->line_pos += 1; | |
34997 | - | |
34998 | + | |
34999 | tid = TK_LT; | |
35000 | - | |
35001 | + | |
35002 | buffer_copy_string(token, "(<)"); | |
35003 | } | |
35004 | - | |
35005 | + | |
35006 | break; | |
35007 | - | |
35008 | + | |
35009 | case '!': | |
35010 | if (t->input[t->offset + 1] == '=') { | |
35011 | t->offset += 2; | |
35012 | t->line_pos += 2; | |
35013 | - | |
35014 | + | |
35015 | tid = TK_NE; | |
35016 | - | |
35017 | + | |
35018 | buffer_copy_string(token, "(!=)"); | |
35019 | } else { | |
35020 | t->offset += 1; | |
35021 | t->line_pos += 1; | |
35022 | - | |
35023 | + | |
35024 | tid = TK_NOT; | |
35025 | - | |
35026 | + | |
35027 | buffer_copy_string(token, "(!)"); | |
35028 | } | |
35029 | - | |
35030 | + | |
35031 | break; | |
35032 | case '&': | |
35033 | if (t->input[t->offset + 1] == '&') { | |
35034 | t->offset += 2; | |
35035 | t->line_pos += 2; | |
35036 | - | |
35037 | + | |
35038 | tid = TK_AND; | |
35039 | - | |
35040 | + | |
35041 | buffer_copy_string(token, "(&&)"); | |
35042 | } else { | |
35043 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
35044 | - "pos:", t->line_pos, | |
35045 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
35046 | + "pos:", t->line_pos, | |
35047 | "missing second &"); | |
35048 | return -1; | |
35049 | } | |
35050 | - | |
35051 | + | |
35052 | break; | |
35053 | case '|': | |
35054 | if (t->input[t->offset + 1] == '|') { | |
35055 | t->offset += 2; | |
35056 | t->line_pos += 2; | |
35057 | - | |
35058 | + | |
35059 | tid = TK_OR; | |
35060 | - | |
35061 | + | |
35062 | buffer_copy_string(token, "(||)"); | |
35063 | } else { | |
35064 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
35065 | - "pos:", t->line_pos, | |
35066 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
35067 | + "pos:", t->line_pos, | |
35068 | "missing second |"); | |
35069 | return -1; | |
35070 | } | |
35071 | - | |
35072 | + | |
35073 | break; | |
35074 | case '\t': | |
35075 | case ' ': | |
35076 | t->offset++; | |
35077 | t->line_pos++; | |
35078 | break; | |
35079 | - | |
35080 | + | |
35081 | case '\'': | |
35082 | /* search for the terminating " */ | |
35083 | for (i = 1; t->input[t->offset + i] && t->input[t->offset + i] != '\''; i++); | |
35084 | - | |
35085 | + | |
35086 | if (t->input[t->offset + i]) { | |
35087 | tid = TK_VALUE; | |
35088 | - | |
35089 | + | |
35090 | buffer_copy_string_len(token, t->input + t->offset + 1, i-1); | |
35091 | - | |
35092 | + | |
35093 | t->offset += i + 1; | |
35094 | t->line_pos += i + 1; | |
35095 | } else { | |
35096 | /* ERROR */ | |
35097 | - | |
35098 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
35099 | - "pos:", t->line_pos, | |
35100 | + | |
35101 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
35102 | + "pos:", t->line_pos, | |
35103 | "missing closing quote"); | |
35104 | - | |
35105 | + | |
35106 | return -1; | |
35107 | } | |
35108 | - | |
35109 | + | |
35110 | break; | |
35111 | case '(': | |
35112 | t->offset++; | |
35113 | t->in_brace++; | |
35114 | - | |
35115 | + | |
35116 | tid = TK_LPARAN; | |
35117 | - | |
35118 | + | |
35119 | buffer_copy_string(token, "("); | |
35120 | break; | |
35121 | case ')': | |
35122 | t->offset++; | |
35123 | t->in_brace--; | |
35124 | - | |
35125 | + | |
35126 | tid = TK_RPARAN; | |
35127 | - | |
35128 | + | |
35129 | buffer_copy_string(token, ")"); | |
35130 | break; | |
35131 | case '$': | |
35132 | if (t->input[t->offset + 1] == '{') { | |
35133 | for (i = 2; t->input[t->offset + i] && t->input[t->offset + i] != '}'; i++); | |
35134 | - | |
35135 | + | |
35136 | if (t->input[t->offset + i] != '}') { | |
35137 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
35138 | - "pos:", t->line_pos, | |
35139 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
35140 | + "pos:", t->line_pos, | |
35141 | "missing closing quote"); | |
35142 | - | |
35143 | + | |
35144 | return -1; | |
35145 | } | |
35146 | - | |
35147 | + | |
35148 | buffer_copy_string_len(token, t->input + t->offset + 2, i-3); | |
35149 | } else { | |
35150 | for (i = 1; isalpha(t->input[t->offset + i]) || t->input[t->offset + i] == '_'; i++); | |
35151 | - | |
35152 | + | |
35153 | buffer_copy_string_len(token, t->input + t->offset + 1, i-1); | |
35154 | } | |
35155 | - | |
35156 | + | |
35157 | tid = TK_VALUE; | |
35158 | - | |
35159 | + | |
35160 | if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) { | |
35161 | buffer_copy_string_buffer(token, ds->value); | |
35162 | } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) { | |
35163 | @@ -221,16 +221,16 @@ | |
35164 | } else { | |
35165 | buffer_copy_string(token, ""); | |
35166 | } | |
35167 | - | |
35168 | + | |
35169 | t->offset += i; | |
35170 | t->line_pos += i; | |
35171 | - | |
35172 | + | |
35173 | break; | |
35174 | default: | |
35175 | for (i = 0; isgraph(t->input[t->offset + i]); i++) { | |
35176 | char d = t->input[t->offset + i]; | |
35177 | switch(d) { | |
35178 | - case ' ': | |
35179 | + case ' ': | |
35180 | case '\t': | |
35181 | case ')': | |
35182 | case '(': | |
35183 | @@ -244,25 +244,25 @@ | |
35184 | break; | |
35185 | } | |
35186 | } | |
35187 | - | |
35188 | + | |
35189 | tid = TK_VALUE; | |
35190 | - | |
35191 | + | |
35192 | buffer_copy_string_len(token, t->input + t->offset, i); | |
35193 | - | |
35194 | + | |
35195 | t->offset += i; | |
35196 | t->line_pos += i; | |
35197 | - | |
35198 | + | |
35199 | break; | |
35200 | } | |
35201 | } | |
35202 | - | |
35203 | + | |
35204 | if (tid) { | |
35205 | *token_id = tid; | |
35206 | - | |
35207 | + | |
35208 | return 1; | |
35209 | } else if (t->offset < t->size) { | |
35210 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
35211 | - "pos:", t->line_pos, | |
35212 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
35213 | + "pos:", t->line_pos, | |
35214 | "foobar"); | |
35215 | } | |
35216 | return 0; | |
35217 | @@ -275,50 +275,50 @@ | |
35218 | buffer *token; | |
35219 | ssi_ctx_t context; | |
35220 | int ret; | |
35221 | - | |
35222 | + | |
35223 | t.input = expr; | |
35224 | t.offset = 0; | |
35225 | t.size = strlen(expr); | |
35226 | t.line_pos = 1; | |
35227 | - | |
35228 | + | |
35229 | t.in_key = 1; | |
35230 | t.in_brace = 0; | |
35231 | t.in_cond = 0; | |
35232 | - | |
35233 | + | |
35234 | context.ok = 1; | |
35235 | context.srv = srv; | |
35236 | - | |
35237 | + | |
35238 | /* default context */ | |
35239 | - | |
35240 | + | |
35241 | pParser = ssiexprparserAlloc( malloc ); | |
35242 | token = buffer_init(); | |
35243 | while((1 == (ret = ssi_expr_tokenizer(srv, con, p, &t, &token_id, token))) && context.ok) { | |
35244 | ssiexprparser(pParser, token_id, token, &context); | |
35245 | - | |
35246 | + | |
35247 | token = buffer_init(); | |
35248 | } | |
35249 | ssiexprparser(pParser, 0, token, &context); | |
35250 | ssiexprparserFree(pParser, free ); | |
35251 | - | |
35252 | + | |
35253 | buffer_free(token); | |
35254 | - | |
35255 | + | |
35256 | if (ret == -1) { | |
35257 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
35258 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
35259 | "expr parser failed"); | |
35260 | return -1; | |
35261 | } | |
35262 | - | |
35263 | + | |
35264 | if (context.ok == 0) { | |
35265 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
35266 | - "pos:", t.line_pos, | |
35267 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
35268 | + "pos:", t.line_pos, | |
35269 | "parser failed somehow near here"); | |
35270 | return -1; | |
35271 | } | |
35272 | #if 0 | |
35273 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
35274 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
35275 | "expr: ", | |
35276 | expr, | |
35277 | context.val.bo); | |
35278 | -#endif | |
35279 | +#endif | |
35280 | return context.val.bo; | |
35281 | } | |
1175ccec | 35282 | --- ../lighttpd-1.4.11/src/mod_ssi_expr.h 2005-08-11 01:26:48.000000000 +0300 |
36e2a29e | 35283 | +++ lighttpd-1.4.12/src/mod_ssi_expr.h 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
35284 | @@ -5,16 +5,16 @@ |
35285 | ||
35286 | typedef struct { | |
35287 | enum { SSI_TYPE_UNSET, SSI_TYPE_BOOL, SSI_TYPE_STRING } type; | |
35288 | - | |
35289 | + | |
35290 | buffer *str; | |
35291 | int bo; | |
35292 | } ssi_val_t; | |
35293 | ||
35294 | typedef struct { | |
35295 | int ok; | |
35296 | - | |
35297 | + | |
35298 | ssi_val_t val; | |
35299 | - | |
35300 | + | |
35301 | void *srv; | |
35302 | } ssi_ctx_t; | |
35303 | ||
1175ccec | 35304 | --- ../lighttpd-1.4.11/src/mod_ssi_exprparser.c 2005-10-03 00:40:25.000000000 +0300 |
36e2a29e | 35305 | +++ lighttpd-1.4.12/src/mod_ssi_exprparser.c 2006-07-11 22:08:02.000000000 +0300 |
2519e6e5 ER |
35306 | @@ -18,10 +18,10 @@ |
35307 | /* Next is all token values, in a form suitable for use by makeheaders. | |
35308 | ** This section will be null unless lemon is run with the -m switch. | |
35309 | */ | |
35310 | -/* | |
35311 | +/* | |
35312 | ** These constants (all generated automatically by the parser generator) | |
35313 | ** specify the various kinds of tokens (terminals) that the parser | |
35314 | -** understands. | |
35315 | +** understands. | |
35316 | ** | |
35317 | ** Each symbol here is a terminal symbol in the grammar. | |
35318 | */ | |
35319 | @@ -38,7 +38,7 @@ | |
35320 | ** and nonterminals. "int" is used otherwise. | |
35321 | ** YYNOCODE is a number of type YYCODETYPE which corresponds | |
35322 | ** to no legal terminal or nonterminal number. This | |
35323 | -** number is used to fill in empty slots of the hash | |
35324 | +** number is used to fill in empty slots of the hash | |
35325 | ** table. | |
35326 | ** YYFALLBACK If defined, this indicates that one or more tokens | |
35327 | ** have fall-back values which should be used if the | |
35328 | @@ -47,7 +47,7 @@ | |
35329 | ** and nonterminal numbers. "unsigned char" is | |
35330 | ** used if there are fewer than 250 rules and | |
35331 | ** states combined. "int" is used otherwise. | |
35332 | -** ssiexprparserTOKENTYPE is the data type used for minor tokens given | |
35333 | +** ssiexprparserTOKENTYPE is the data type used for minor tokens given | |
35334 | ** directly to the parser from the tokenizer. | |
35335 | ** YYMINORTYPE is the data type used for all minor tokens. | |
35336 | ** This is typically a union of many types, one of | |
35337 | @@ -91,7 +91,7 @@ | |
35338 | /* Next are that tables used to determine what action to take based on the | |
35339 | ** current state and lookahead token. These tables are used to implement | |
35340 | ** functions that take a state number and lookahead value and return an | |
35341 | -** action integer. | |
35342 | +** action integer. | |
35343 | ** | |
35344 | ** Suppose the action integer is N. Then the action is determined as | |
35345 | ** follows | |
35346 | @@ -116,7 +116,7 @@ | |
35347 | ** If the index value yy_shift_ofst[S]+X is out of range or if the value | |
35348 | ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] | |
35349 | ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table | |
35350 | -** and that yy_default[S] should be used instead. | |
35351 | +** and that yy_default[S] should be used instead. | |
35352 | ** | |
35353 | ** The formula above is for computing the action when the lookahead is | |
35354 | ** a terminal symbol. If the lookahead is a non-terminal (as occurs after | |
35355 | @@ -168,7 +168,7 @@ | |
35356 | ||
35357 | /* The next table maps tokens into fallback tokens. If a construct | |
35358 | ** like the following: | |
35359 | -** | |
35360 | +** | |
35361 | ** %fallback ID X Y Z. | |
35362 | ** | |
35363 | ** appears in the grammer, then ID becomes a fallback token for X, Y, | |
35364 | @@ -219,10 +219,10 @@ | |
35365 | #endif /* NDEBUG */ | |
35366 | ||
35367 | #ifndef NDEBUG | |
35368 | -/* | |
35369 | +/* | |
35370 | ** Turn parser tracing on by giving a stream to which to write the trace | |
35371 | ** and a prompt to preface each trace message. Tracing is turned off | |
35372 | -** by making either argument NULL | |
35373 | +** by making either argument NULL | |
35374 | ** | |
35375 | ** Inputs: | |
35376 | ** <ul> | |
35377 | @@ -247,7 +247,7 @@ | |
35378 | #ifndef NDEBUG | |
35379 | /* For tracing shifts, the names of all terminals and nonterminals | |
35380 | ** are required. The following table supplies these names */ | |
35381 | -static const char *yyTokenName[] = { | |
35382 | +static const char *yyTokenName[] = { | |
35383 | "$", "AND", "OR", "EQ", | |
35384 | "NE", "GT", "GE", "LT", | |
35385 | "LE", "NOT", "LPARAN", "RPARAN", | |
35386 | @@ -295,7 +295,7 @@ | |
35387 | #endif | |
35388 | } | |
35389 | ||
35390 | -/* | |
35391 | +/* | |
35392 | ** This function allocates a new parser. | |
35393 | ** The only argument is a pointer to a function which works like | |
35394 | ** malloc. | |
35395 | @@ -326,7 +326,7 @@ | |
35396 | /* Here is inserted the actions which take place when a | |
35397 | ** terminal or non-terminal is destroyed. This can happen | |
35398 | ** when the symbol is popped from the stack during a | |
35399 | - ** reduce or during error processing or when a parser is | |
35400 | + ** reduce or during error processing or when a parser is | |
35401 | ** being destroyed before it is finished parsing. | |
35402 | ** | |
35403 | ** Note: during a reduce, the only symbols destroyed are those | |
35404 | @@ -379,7 +379,7 @@ | |
35405 | return yymajor; | |
35406 | } | |
35407 | ||
35408 | -/* | |
35409 | +/* | |
35410 | ** Deallocate and destroy a parser. Destructors are all called for | |
35411 | ** all stack elements before shutting the parser down. | |
35412 | ** | |
35413 | @@ -415,7 +415,7 @@ | |
35414 | ){ | |
35415 | int i; | |
35416 | int stateno = pParser->yystack[pParser->yyidx].stateno; | |
35417 | - | |
35418 | + | |
35419 | /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */ | |
35420 | i = yy_shift_ofst[stateno]; | |
35421 | if( i==YY_SHIFT_USE_DFLT ){ | |
35422 | @@ -459,7 +459,7 @@ | |
35423 | ){ | |
35424 | int i; | |
35425 | int stateno = pParser->yystack[pParser->yyidx].stateno; | |
35426 | - | |
35427 | + | |
35428 | i = yy_reduce_ofst[stateno]; | |
35429 | if( i==YY_REDUCE_USE_DFLT ){ | |
35430 | return yy_default[stateno]; | |
35431 | @@ -559,7 +559,7 @@ | |
35432 | ssiexprparserARG_FETCH; | |
35433 | yymsp = &yypParser->yystack[yypParser->yyidx]; | |
35434 | #ifndef NDEBUG | |
35435 | - if( yyTraceFILE && yyruleno>=0 | |
35436 | + if( yyTraceFILE && yyruleno>=0 | |
35437 | && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){ | |
35438 | fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, | |
35439 | yyRuleName[yyruleno]); | |
35440 | @@ -872,7 +872,7 @@ | |
35441 | #ifdef YYERRORSYMBOL | |
35442 | /* A syntax error has occurred. | |
35443 | ** The response to an error depends upon whether or not the | |
35444 | - ** grammar defines an error token "ERROR". | |
35445 | + ** grammar defines an error token "ERROR". | |
35446 | ** | |
35447 | ** This is what we do if the grammar does define ERROR: | |
35448 | ** | |
1175ccec | 35449 | --- ../lighttpd-1.4.11/src/mod_staticfile.c 2006-02-15 14:31:14.000000000 +0200 |
36e2a29e | 35450 | +++ lighttpd-1.4.12/src/mod_staticfile.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
35451 | @@ -14,9 +14,11 @@ |
35452 | #include "http_chunk.h" | |
35453 | #include "response.h" | |
35454 | ||
35455 | +#include "sys-files.h" | |
35456 | +#include "sys-strings.h" | |
35457 | /** | |
35458 | * this is a staticfile for a lighttpd plugin | |
35459 | - * | |
35460 | + * | |
35461 | */ | |
35462 | ||
35463 | ||
35464 | @@ -29,48 +31,48 @@ | |
35465 | ||
35466 | typedef struct { | |
35467 | PLUGIN_DATA; | |
35468 | - | |
35469 | + | |
35470 | buffer *range_buf; | |
35471 | - | |
35472 | + | |
35473 | plugin_config **config_storage; | |
35474 | - | |
35475 | - plugin_config conf; | |
35476 | + | |
35477 | + plugin_config conf; | |
35478 | } plugin_data; | |
35479 | ||
35480 | /* init the plugin data */ | |
35481 | INIT_FUNC(mod_staticfile_init) { | |
35482 | plugin_data *p; | |
35483 | - | |
35484 | + | |
35485 | p = calloc(1, sizeof(*p)); | |
35486 | - | |
35487 | + | |
35488 | p->range_buf = buffer_init(); | |
35489 | - | |
35490 | + | |
35491 | return p; | |
35492 | } | |
35493 | ||
35494 | -/* detroy the plugin data */ | |
35495 | +/* destroy the plugin data */ | |
35496 | FREE_FUNC(mod_staticfile_free) { | |
35497 | plugin_data *p = p_d; | |
35498 | - | |
35499 | + | |
35500 | UNUSED(srv); | |
35501 | ||
35502 | if (!p) return HANDLER_GO_ON; | |
35503 | - | |
35504 | + | |
35505 | if (p->config_storage) { | |
35506 | size_t i; | |
35507 | for (i = 0; i < srv->config_context->used; i++) { | |
35508 | plugin_config *s = p->config_storage[i]; | |
35509 | - | |
35510 | + | |
35511 | array_free(s->exclude_ext); | |
35512 | - | |
35513 | + | |
35514 | free(s); | |
35515 | } | |
35516 | free(p->config_storage); | |
35517 | } | |
35518 | buffer_free(p->range_buf); | |
35519 | - | |
35520 | + | |
35521 | free(p); | |
35522 | - | |
35523 | + | |
35524 | return HANDLER_GO_ON; | |
35525 | } | |
35526 | ||
35527 | @@ -79,63 +81,60 @@ | |
35528 | SETDEFAULTS_FUNC(mod_staticfile_set_defaults) { | |
35529 | plugin_data *p = p_d; | |
35530 | size_t i = 0; | |
35531 | - | |
35532 | - config_values_t cv[] = { | |
35533 | + | |
35534 | + config_values_t cv[] = { | |
35535 | { "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
35536 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
35537 | }; | |
35538 | - | |
35539 | + | |
35540 | if (!p) return HANDLER_ERROR; | |
35541 | - | |
35542 | + | |
35543 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
35544 | - | |
35545 | + | |
35546 | for (i = 0; i < srv->config_context->used; i++) { | |
35547 | plugin_config *s; | |
35548 | - | |
35549 | + | |
35550 | s = calloc(1, sizeof(plugin_config)); | |
35551 | s->exclude_ext = array_init(); | |
35552 | - | |
35553 | + | |
35554 | cv[0].destination = s->exclude_ext; | |
35555 | - | |
35556 | + | |
35557 | p->config_storage[i] = s; | |
35558 | - | |
35559 | + | |
35560 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
35561 | return HANDLER_ERROR; | |
35562 | } | |
35563 | } | |
35564 | - | |
35565 | + | |
35566 | return HANDLER_GO_ON; | |
35567 | } | |
35568 | ||
35569 | -#define PATCH(x) \ | |
35570 | - p->conf.x = s->x; | |
35571 | static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_data *p) { | |
35572 | size_t i, j; | |
35573 | plugin_config *s = p->config_storage[0]; | |
35574 | - | |
35575 | - PATCH(exclude_ext); | |
35576 | - | |
35577 | + | |
35578 | + PATCH_OPTION(exclude_ext); | |
35579 | + | |
35580 | /* skip the first, the global context */ | |
35581 | for (i = 1; i < srv->config_context->used; i++) { | |
35582 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
35583 | s = p->config_storage[i]; | |
35584 | - | |
35585 | + | |
35586 | /* condition didn't match */ | |
35587 | if (!config_check_cond(srv, con, dc)) continue; | |
35588 | - | |
35589 | + | |
35590 | /* merge config */ | |
35591 | for (j = 0; j < dc->value->used; j++) { | |
35592 | data_unset *du = dc->value->data[j]; | |
35593 | - | |
35594 | + | |
35595 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) { | |
35596 | - PATCH(exclude_ext); | |
35597 | + PATCH_OPTION(exclude_ext); | |
35598 | } | |
35599 | } | |
35600 | } | |
35601 | - | |
35602 | + | |
35603 | return 0; | |
35604 | } | |
35605 | -#undef PATCH | |
35606 | ||
35607 | static int http_response_parse_range(server *srv, connection *con, plugin_data *p) { | |
35608 | int multipart = 0; | |
35609 | @@ -146,69 +145,69 @@ | |
35610 | data_string *ds; | |
35611 | stat_cache_entry *sce = NULL; | |
35612 | buffer *content_type = NULL; | |
35613 | - | |
35614 | + | |
35615 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) { | |
35616 | SEGFAULT(); | |
35617 | } | |
35618 | - | |
35619 | + | |
35620 | start = 0; | |
35621 | end = sce->st.st_size - 1; | |
35622 | - | |
35623 | + | |
35624 | con->response.content_length = 0; | |
35625 | - | |
35626 | + | |
35627 | if (NULL != (ds = (data_string *)array_get_element(con->response.headers, "Content-Type"))) { | |
35628 | content_type = ds->value; | |
35629 | } | |
35630 | - | |
35631 | + | |
35632 | for (s = con->request.http_range, error = 0; | |
35633 | !error && *s && NULL != (minus = strchr(s, '-')); ) { | |
35634 | char *err; | |
35635 | off_t la, le; | |
35636 | - | |
35637 | + | |
35638 | if (s == minus) { | |
35639 | /* -<stop> */ | |
35640 | - | |
35641 | + | |
35642 | le = strtoll(s, &err, 10); | |
35643 | - | |
35644 | + | |
35645 | if (le == 0) { | |
35646 | /* RFC 2616 - 14.35.1 */ | |
35647 | - | |
35648 | + | |
35649 | con->http_status = 416; | |
35650 | error = 1; | |
35651 | } else if (*err == '\0') { | |
35652 | /* end */ | |
35653 | s = err; | |
35654 | - | |
35655 | + | |
35656 | end = sce->st.st_size - 1; | |
35657 | start = sce->st.st_size + le; | |
35658 | } else if (*err == ',') { | |
35659 | multipart = 1; | |
35660 | s = err + 1; | |
35661 | - | |
35662 | + | |
35663 | end = sce->st.st_size - 1; | |
35664 | start = sce->st.st_size + le; | |
35665 | } else { | |
35666 | error = 1; | |
35667 | } | |
35668 | - | |
35669 | + | |
35670 | } else if (*(minus+1) == '\0' || *(minus+1) == ',') { | |
35671 | /* <start>- */ | |
35672 | - | |
35673 | + | |
35674 | la = strtoll(s, &err, 10); | |
35675 | - | |
35676 | + | |
35677 | if (err == minus) { | |
35678 | /* ok */ | |
35679 | - | |
35680 | + | |
35681 | if (*(err + 1) == '\0') { | |
35682 | s = err + 1; | |
35683 | - | |
35684 | + | |
35685 | end = sce->st.st_size - 1; | |
35686 | start = la; | |
35687 | - | |
35688 | + | |
35689 | } else if (*(err + 1) == ',') { | |
35690 | multipart = 1; | |
35691 | s = err + 2; | |
35692 | - | |
35693 | + | |
35694 | end = sce->st.st_size - 1; | |
35695 | start = la; | |
35696 | } else { | |
35697 | @@ -220,64 +219,64 @@ | |
35698 | } | |
35699 | } else { | |
35700 | /* <start>-<stop> */ | |
35701 | - | |
35702 | + | |
35703 | la = strtoll(s, &err, 10); | |
35704 | - | |
35705 | + | |
35706 | if (err == minus) { | |
35707 | le = strtoll(minus+1, &err, 10); | |
35708 | - | |
35709 | + | |
35710 | /* RFC 2616 - 14.35.1 */ | |
35711 | if (la > le) { | |
35712 | error = 1; | |
35713 | } | |
35714 | - | |
35715 | + | |
35716 | if (*err == '\0') { | |
35717 | /* ok, end*/ | |
35718 | s = err; | |
35719 | - | |
35720 | + | |
35721 | end = le; | |
35722 | start = la; | |
35723 | } else if (*err == ',') { | |
35724 | multipart = 1; | |
35725 | s = err + 1; | |
35726 | - | |
35727 | + | |
35728 | end = le; | |
35729 | start = la; | |
35730 | } else { | |
35731 | /* error */ | |
35732 | - | |
35733 | + | |
35734 | error = 1; | |
35735 | } | |
35736 | } else { | |
35737 | /* error */ | |
35738 | - | |
35739 | + | |
35740 | error = 1; | |
35741 | } | |
35742 | } | |
35743 | - | |
35744 | + | |
35745 | if (!error) { | |
35746 | if (start < 0) start = 0; | |
35747 | - | |
35748 | + | |
35749 | /* RFC 2616 - 14.35.1 */ | |
35750 | if (end > sce->st.st_size - 1) end = sce->st.st_size - 1; | |
35751 | - | |
35752 | + | |
35753 | if (start > sce->st.st_size - 1) { | |
35754 | error = 1; | |
35755 | - | |
35756 | + | |
35757 | con->http_status = 416; | |
35758 | } | |
35759 | } | |
35760 | - | |
35761 | + | |
35762 | if (!error) { | |
35763 | if (multipart) { | |
35764 | /* write boundary-header */ | |
35765 | buffer *b; | |
35766 | - | |
35767 | + | |
35768 | b = chunkqueue_get_append_buffer(con->write_queue); | |
35769 | - | |
35770 | + | |
35771 | buffer_copy_string(b, "\r\n--"); | |
35772 | buffer_append_string(b, boundary); | |
35773 | - | |
35774 | + | |
35775 | /* write Content-Range */ | |
35776 | buffer_append_string(b, "\r\nContent-Range: bytes "); | |
35777 | buffer_append_off_t(b, start); | |
35778 | @@ -285,54 +284,54 @@ | |
35779 | buffer_append_off_t(b, end); | |
35780 | buffer_append_string(b, "/"); | |
35781 | buffer_append_off_t(b, sce->st.st_size); | |
35782 | - | |
35783 | + | |
35784 | buffer_append_string(b, "\r\nContent-Type: "); | |
35785 | buffer_append_string_buffer(b, content_type); | |
35786 | - | |
35787 | + | |
35788 | /* write END-OF-HEADER */ | |
35789 | buffer_append_string(b, "\r\n\r\n"); | |
35790 | - | |
35791 | + | |
35792 | con->response.content_length += b->used - 1; | |
35793 | - | |
35794 | + | |
35795 | } | |
35796 | - | |
35797 | + | |
35798 | chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1); | |
35799 | con->response.content_length += end - start + 1; | |
35800 | } | |
35801 | } | |
35802 | - | |
35803 | + | |
35804 | /* something went wrong */ | |
35805 | if (error) return -1; | |
35806 | - | |
35807 | + | |
35808 | if (multipart) { | |
35809 | /* add boundary end */ | |
35810 | buffer *b; | |
35811 | - | |
35812 | + | |
35813 | b = chunkqueue_get_append_buffer(con->write_queue); | |
35814 | - | |
35815 | + | |
35816 | buffer_copy_string_len(b, "\r\n--", 4); | |
35817 | buffer_append_string(b, boundary); | |
35818 | buffer_append_string_len(b, "--\r\n", 4); | |
35819 | - | |
35820 | + | |
35821 | con->response.content_length += b->used - 1; | |
35822 | - | |
35823 | + | |
35824 | /* set header-fields */ | |
35825 | - | |
35826 | + | |
35827 | buffer_copy_string(p->range_buf, "multipart/byteranges; boundary="); | |
35828 | buffer_append_string(p->range_buf, boundary); | |
35829 | - | |
35830 | + | |
35831 | /* overwrite content-type */ | |
35832 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->range_buf)); | |
35833 | } else { | |
35834 | /* add Content-Range-header */ | |
35835 | - | |
35836 | + | |
35837 | buffer_copy_string(p->range_buf, "bytes "); | |
35838 | buffer_append_off_t(p->range_buf, start); | |
35839 | buffer_append_string(p->range_buf, "-"); | |
35840 | buffer_append_off_t(p->range_buf, end); | |
35841 | buffer_append_string(p->range_buf, "/"); | |
35842 | buffer_append_off_t(p->range_buf, sce->st.st_size); | |
35843 | - | |
35844 | + | |
35845 | response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf)); | |
35846 | } | |
35847 | ||
35848 | @@ -347,12 +346,12 @@ | |
35849 | stat_cache_entry *sce = NULL; | |
35850 | buffer *mtime; | |
35851 | data_string *ds; | |
35852 | - | |
35853 | + | |
35854 | /* someone else has done a decision for us */ | |
35855 | if (con->http_status != 0) return HANDLER_GO_ON; | |
35856 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
35857 | if (con->physical.path->used == 0) return HANDLER_GO_ON; | |
35858 | - | |
35859 | + | |
35860 | /* someone else has handled this request */ | |
35861 | if (con->mode != DIRECT) return HANDLER_GO_ON; | |
35862 | ||
35863 | @@ -365,52 +364,52 @@ | |
35864 | default: | |
35865 | return HANDLER_GO_ON; | |
35866 | } | |
35867 | - | |
35868 | + | |
35869 | mod_staticfile_patch_connection(srv, con, p); | |
35870 | - | |
35871 | + | |
35872 | s_len = con->uri.path->used - 1; | |
35873 | - | |
35874 | + | |
35875 | /* ignore certain extensions */ | |
35876 | for (k = 0; k < p->conf.exclude_ext->used; k++) { | |
35877 | - ds = (data_string *)p->conf.exclude_ext->data[k]; | |
35878 | - | |
35879 | + ds = (data_string *)p->conf.exclude_ext->data[k]; | |
35880 | + | |
35881 | if (ds->value->used == 0) continue; | |
35882 | ||
35883 | if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) { | |
35884 | return HANDLER_GO_ON; | |
35885 | } | |
35886 | } | |
35887 | - | |
35888 | + | |
35889 | ||
35890 | if (con->conf.log_request_handling) { | |
35891 | log_error_write(srv, __FILE__, __LINE__, "s", "-- handling file as static file"); | |
35892 | } | |
35893 | - | |
35894 | + | |
35895 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) { | |
35896 | con->http_status = 403; | |
35897 | - | |
35898 | + | |
35899 | log_error_write(srv, __FILE__, __LINE__, "sbsb", | |
35900 | "not a regular file:", con->uri.path, | |
35901 | "->", con->physical.path); | |
35902 | - | |
35903 | + | |
35904 | return HANDLER_FINISHED; | |
35905 | } | |
35906 | - | |
35907 | - /* we only handline regular files */ | |
35908 | + | |
35909 | + /* we only handle regular files */ | |
35910 | if (!S_ISREG(sce->st.st_mode)) { | |
35911 | con->http_status = 404; | |
35912 | - | |
35913 | + | |
35914 | if (con->conf.log_file_not_found) { | |
35915 | log_error_write(srv, __FILE__, __LINE__, "sbsb", | |
35916 | "not a regular file:", con->uri.path, | |
35917 | "->", sce->name); | |
35918 | } | |
35919 | - | |
35920 | + | |
35921 | return HANDLER_FINISHED; | |
35922 | } | |
35923 | ||
35924 | - /* mod_compress might set several data directly, don't overwrite them */ | |
35925 | - | |
35926 | + /* mod_compress might set several parameters directly; don't overwrite them */ | |
35927 | + | |
35928 | /* set response content-type, if not set already */ | |
35929 | ||
35930 | if (NULL == array_get_element(con->response.headers, "Content-Type")) { | |
35931 | @@ -420,15 +419,15 @@ | |
35932 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); | |
35933 | } | |
35934 | } | |
35935 | - | |
35936 | + | |
35937 | if (NULL == array_get_element(con->response.headers, "ETag")) { | |
35938 | /* generate e-tag */ | |
35939 | etag_mutate(con->physical.etag, sce->etag); | |
35940 | - | |
35941 | + | |
35942 | response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); | |
35943 | } | |
35944 | response_header_overwrite(srv, con, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes")); | |
35945 | - | |
35946 | + | |
35947 | /* prepare header */ | |
35948 | if (NULL == (ds = (data_string *)array_get_element(con->response.headers, "Last-Modified"))) { | |
35949 | mtime = strftime_cache_get(srv, sce->st.st_mtime); | |
35950 | @@ -444,34 +443,34 @@ | |
35951 | /* check if we have a conditional GET */ | |
35952 | ||
35953 | if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If-Range"))) { | |
35954 | - /* if the value is the same as our ETag, we do a Range-request, | |
35955 | + /* if the value is the same as our ETag, we do a Range-request, | |
35956 | * otherwise a full 200 */ | |
35957 | ||
35958 | if (!buffer_is_equal(ds->value, con->physical.etag)) { | |
35959 | do_range_request = 0; | |
35960 | } | |
35961 | } | |
35962 | - | |
35963 | + | |
35964 | if (do_range_request) { | |
35965 | /* content prepared, I'm done */ | |
35966 | con->file_finished = 1; | |
35967 | - | |
35968 | + | |
35969 | if (0 == http_response_parse_range(srv, con, p)) { | |
35970 | con->http_status = 206; | |
35971 | } | |
35972 | return HANDLER_FINISHED; | |
35973 | } | |
35974 | } | |
35975 | - | |
35976 | + | |
35977 | /* if we are still here, prepare body */ | |
35978 | - | |
35979 | - /* we add it here for all requests | |
35980 | - * the HEAD request will drop it afterwards again | |
35981 | + | |
35982 | + /* we add it here for all requests | |
35983 | + * the HEAD request will drop it afterwards again | |
35984 | */ | |
35985 | http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size); | |
35986 | - | |
35987 | + | |
35988 | con->file_finished = 1; | |
35989 | - | |
35990 | + | |
35991 | return HANDLER_FINISHED; | |
35992 | } | |
35993 | ||
35994 | @@ -480,13 +479,13 @@ | |
35995 | int mod_staticfile_plugin_init(plugin *p) { | |
35996 | p->version = LIGHTTPD_VERSION_ID; | |
35997 | p->name = buffer_init_string("staticfile"); | |
35998 | - | |
35999 | + | |
36000 | p->init = mod_staticfile_init; | |
36001 | p->handle_subrequest_start = mod_staticfile_subrequest; | |
36002 | p->set_defaults = mod_staticfile_set_defaults; | |
36003 | p->cleanup = mod_staticfile_free; | |
36004 | - | |
36005 | + | |
36006 | p->data = NULL; | |
36007 | - | |
36008 | + | |
36009 | return 0; | |
36010 | } | |
1175ccec | 36011 | --- ../lighttpd-1.4.11/src/mod_status.c 2006-01-10 21:45:32.000000000 +0200 |
36e2a29e | 36012 | +++ lighttpd-1.4.12/src/mod_status.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
36013 | @@ -4,7 +4,6 @@ |
36014 | #include <fcntl.h> | |
36015 | #include <stdlib.h> | |
36016 | #include <string.h> | |
36017 | -#include <unistd.h> | |
36018 | #include <errno.h> | |
36019 | #include <time.h> | |
36020 | #include <stdio.h> | |
36021 | @@ -29,114 +28,114 @@ | |
36022 | ||
36023 | typedef struct { | |
36024 | PLUGIN_DATA; | |
36025 | - | |
36026 | + | |
36027 | double traffic_out; | |
36028 | double requests; | |
36029 | - | |
36030 | + | |
36031 | double mod_5s_traffic_out[5]; | |
36032 | double mod_5s_requests[5]; | |
36033 | size_t mod_5s_ndx; | |
36034 | - | |
36035 | + | |
36036 | double rel_traffic_out; | |
36037 | double rel_requests; | |
36038 | - | |
36039 | + | |
36040 | double abs_traffic_out; | |
36041 | double abs_requests; | |
36042 | - | |
36043 | + | |
36044 | double bytes_written; | |
36045 | - | |
36046 | + | |
36047 | buffer *module_list; | |
36048 | - | |
36049 | + | |
36050 | plugin_config **config_storage; | |
36051 | - | |
36052 | - plugin_config conf; | |
36053 | + | |
36054 | + plugin_config conf; | |
36055 | } plugin_data; | |
36056 | ||
36057 | INIT_FUNC(mod_status_init) { | |
36058 | plugin_data *p; | |
36059 | size_t i; | |
36060 | - | |
36061 | + | |
36062 | p = calloc(1, sizeof(*p)); | |
36063 | - | |
36064 | + | |
36065 | p->traffic_out = p->requests = 0; | |
36066 | p->rel_traffic_out = p->rel_requests = 0; | |
36067 | p->abs_traffic_out = p->abs_requests = 0; | |
36068 | p->bytes_written = 0; | |
36069 | p->module_list = buffer_init(); | |
36070 | - | |
36071 | + | |
36072 | for (i = 0; i < 5; i++) { | |
36073 | p->mod_5s_traffic_out[i] = p->mod_5s_requests[i] = 0; | |
36074 | } | |
36075 | - | |
36076 | + | |
36077 | return p; | |
36078 | } | |
36079 | ||
36080 | FREE_FUNC(mod_status_free) { | |
36081 | plugin_data *p = p_d; | |
36082 | - | |
36083 | + | |
36084 | UNUSED(srv); | |
36085 | ||
36086 | if (!p) return HANDLER_GO_ON; | |
36087 | - | |
36088 | + | |
36089 | buffer_free(p->module_list); | |
36090 | - | |
36091 | + | |
36092 | if (p->config_storage) { | |
36093 | size_t i; | |
36094 | for (i = 0; i < srv->config_context->used; i++) { | |
36095 | plugin_config *s = p->config_storage[i]; | |
36096 | - | |
36097 | + | |
36098 | buffer_free(s->status_url); | |
36099 | buffer_free(s->statistics_url); | |
36100 | buffer_free(s->config_url); | |
36101 | - | |
36102 | + | |
36103 | free(s); | |
36104 | } | |
36105 | free(p->config_storage); | |
36106 | } | |
36107 | - | |
36108 | - | |
36109 | + | |
36110 | + | |
36111 | free(p); | |
36112 | - | |
36113 | + | |
36114 | return HANDLER_GO_ON; | |
36115 | } | |
36116 | ||
36117 | SETDEFAULTS_FUNC(mod_status_set_defaults) { | |
36118 | plugin_data *p = p_d; | |
36119 | size_t i; | |
36120 | - | |
36121 | - config_values_t cv[] = { | |
36122 | + | |
36123 | + config_values_t cv[] = { | |
36124 | { "status.status-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
36125 | { "status.config-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
36126 | { "status.enable-sort", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, | |
36127 | { "status.statistics-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, | |
36128 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
36129 | }; | |
36130 | - | |
36131 | + | |
36132 | if (!p) return HANDLER_ERROR; | |
36133 | - | |
36134 | + | |
36135 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
36136 | - | |
36137 | + | |
36138 | for (i = 0; i < srv->config_context->used; i++) { | |
36139 | plugin_config *s; | |
36140 | - | |
36141 | + | |
36142 | s = calloc(1, sizeof(plugin_config)); | |
36143 | s->config_url = buffer_init(); | |
36144 | s->status_url = buffer_init(); | |
36145 | s->sort = 1; | |
36146 | s->statistics_url = buffer_init(); | |
36147 | - | |
36148 | + | |
36149 | cv[0].destination = s->status_url; | |
36150 | cv[1].destination = s->config_url; | |
36151 | cv[2].destination = &(s->sort); | |
36152 | cv[3].destination = s->statistics_url; | |
36153 | - | |
36154 | + | |
36155 | p->config_storage[i] = s; | |
36156 | - | |
36157 | + | |
36158 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
36159 | return HANDLER_ERROR; | |
36160 | } | |
36161 | } | |
36162 | - | |
36163 | + | |
36164 | return HANDLER_GO_ON; | |
36165 | } | |
36166 | ||
36167 | @@ -151,7 +150,7 @@ | |
36168 | buffer_append_string(b, value); | |
36169 | BUFFER_APPEND_STRING_CONST(b, "</td>\n"); | |
36170 | BUFFER_APPEND_STRING_CONST(b, " </tr>\n"); | |
36171 | - | |
36172 | + | |
36173 | return 0; | |
36174 | } | |
36175 | ||
36176 | @@ -161,13 +160,13 @@ | |
36177 | buffer_append_string(b, key); | |
36178 | BUFFER_APPEND_STRING_CONST(b, "</th>\n"); | |
36179 | BUFFER_APPEND_STRING_CONST(b, " </tr>\n"); | |
36180 | - | |
36181 | + | |
36182 | return 0; | |
36183 | } | |
36184 | ||
36185 | static int mod_status_header_append_sort(buffer *b, void *p_d, const char* key) { | |
36186 | plugin_data *p = p_d; | |
36187 | - | |
36188 | + | |
36189 | if (p->conf.sort) { | |
36190 | BUFFER_APPEND_STRING_CONST(b, "<th class=\"status\"><a href=\"#\" class=\"sortheader\" onclick=\"resort(this);return false;\">"); | |
36191 | buffer_append_string(b, key); | |
36192 | @@ -177,13 +176,13 @@ | |
36193 | buffer_append_string(b, key); | |
36194 | BUFFER_APPEND_STRING_CONST(b, "</th>\n"); | |
36195 | } | |
36196 | - | |
36197 | + | |
36198 | return 0; | |
36199 | } | |
36200 | ||
36201 | static int mod_status_get_multiplier(double *avg, char *multiplier, int size) { | |
36202 | *multiplier = ' '; | |
36203 | - | |
36204 | + | |
36205 | if (*avg > size) { *avg /= size; *multiplier = 'k'; } | |
36206 | if (*avg > size) { *avg /= size; *multiplier = 'M'; } | |
36207 | if (*avg > size) { *avg /= size; *multiplier = 'G'; } | |
36208 | @@ -202,21 +201,21 @@ | |
36209 | size_t j; | |
36210 | double avg; | |
36211 | char multiplier = '\0'; | |
36212 | - char buf[32]; | |
36213 | + char buf[128]; | |
36214 | time_t ts; | |
36215 | - | |
36216 | + | |
36217 | int days, hours, mins, seconds; | |
36218 | - | |
36219 | + | |
36220 | b = chunkqueue_get_append_buffer(con->write_queue); | |
36221 | ||
36222 | - BUFFER_COPY_STRING_CONST(b, | |
36223 | + BUFFER_COPY_STRING_CONST(b, | |
36224 | "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" | |
36225 | "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" | |
36226 | " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" | |
36227 | "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" | |
36228 | " <head>\n" | |
36229 | " <title>Status</title>\n"); | |
36230 | - | |
36231 | + | |
36232 | BUFFER_APPEND_STRING_CONST(b, | |
36233 | " <style type=\"text/css\">\n" | |
36234 | " table.status { border: black solid thin; }\n" | |
36235 | @@ -226,14 +225,14 @@ | |
36236 | " a.sortheader { background-color: black; color: white; font-weight: bold; text-decoration: none; display: block; }\n" | |
36237 | " span.sortarrow { color: white; text-decoration: none; }\n" | |
36238 | " </style>\n"); | |
36239 | - | |
36240 | + | |
36241 | if (p->conf.sort) { | |
36242 | BUFFER_APPEND_STRING_CONST(b, | |
36243 | "<script type=\"text/javascript\">\n" | |
36244 | "// <!--\n" | |
36245 | "var sort_column;\n" | |
36246 | "var prev_span = null;\n"); | |
36247 | - | |
36248 | + | |
36249 | BUFFER_APPEND_STRING_CONST(b, | |
36250 | "function get_inner_text(el) {\n" | |
36251 | " if((typeof el == 'string')||(typeof el == 'undefined'))\n" | |
36252 | @@ -251,7 +250,7 @@ | |
36253 | " }\n" | |
36254 | " return str;\n" | |
36255 | "}\n"); | |
36256 | - | |
36257 | + | |
36258 | BUFFER_APPEND_STRING_CONST(b, | |
36259 | "function sortfn(a,b) {\n" | |
36260 | " var at = get_inner_text(a.cells[sort_column]);\n" | |
36261 | @@ -266,7 +265,7 @@ | |
36262 | " else return 1;\n" | |
36263 | " }\n" | |
36264 | "}\n"); | |
36265 | - | |
36266 | + | |
36267 | BUFFER_APPEND_STRING_CONST(b, | |
36268 | "function resort(lnk) {\n" | |
36269 | " var span = lnk.childNodes[1];\n" | |
36270 | @@ -276,7 +275,7 @@ | |
36271 | " rows[j-1] = table.rows[j];\n" | |
36272 | " sort_column = lnk.parentNode.cellIndex;\n" | |
36273 | " rows.sort(sortfn);\n"); | |
36274 | - | |
36275 | + | |
36276 | BUFFER_APPEND_STRING_CONST(b, | |
36277 | " if (prev_span != null) prev_span.innerHTML = '';\n" | |
36278 | " if (span.getAttribute('sortdir')=='down') {\n" | |
36279 | @@ -294,175 +293,175 @@ | |
36280 | "// -->\n" | |
36281 | "</script>\n"); | |
36282 | } | |
36283 | - | |
36284 | - BUFFER_APPEND_STRING_CONST(b, | |
36285 | + | |
36286 | + BUFFER_APPEND_STRING_CONST(b, | |
36287 | " </head>\n" | |
36288 | " <body>\n"); | |
36289 | - | |
36290 | - | |
36291 | - | |
36292 | + | |
36293 | + | |
36294 | + | |
36295 | /* connection listing */ | |
36296 | BUFFER_APPEND_STRING_CONST(b, "<h1>Server-Status</h1>"); | |
36297 | - | |
36298 | - BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">"); | |
36299 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\">"); | |
36300 | + | |
36301 | + BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" id=\"status\" summary=\"Server Status\">"); | |
36302 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\"><span id=\"host_addr\">"); | |
36303 | buffer_append_string_buffer(b, con->uri.authority); | |
36304 | - BUFFER_APPEND_STRING_CONST(b, " ("); | |
36305 | + BUFFER_APPEND_STRING_CONST(b, "</span> (<span id=\"host_name\">"); | |
36306 | buffer_append_string_buffer(b, con->server_name); | |
36307 | - BUFFER_APPEND_STRING_CONST(b, ")</td></tr>\n"); | |
36308 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\">"); | |
36309 | - | |
36310 | + BUFFER_APPEND_STRING_CONST(b, "</span>)</td></tr>\n"); | |
36311 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\" id=\"uptime\">"); | |
36312 | + | |
36313 | ts = srv->cur_ts - srv->startup_ts; | |
36314 | - | |
36315 | + | |
36316 | days = ts / (60 * 60 * 24); | |
36317 | ts %= (60 * 60 * 24); | |
36318 | - | |
36319 | + | |
36320 | hours = ts / (60 * 60); | |
36321 | ts %= (60 * 60); | |
36322 | - | |
36323 | + | |
36324 | mins = ts / (60); | |
36325 | ts %= (60); | |
36326 | - | |
36327 | + | |
36328 | seconds = ts; | |
36329 | - | |
36330 | + | |
36331 | if (days) { | |
36332 | buffer_append_long(b, days); | |
36333 | BUFFER_APPEND_STRING_CONST(b, " days "); | |
36334 | } | |
36335 | - | |
36336 | + | |
36337 | if (hours) { | |
36338 | buffer_append_long(b, hours); | |
36339 | BUFFER_APPEND_STRING_CONST(b, " hours "); | |
36340 | } | |
36341 | - | |
36342 | + | |
36343 | if (mins) { | |
36344 | buffer_append_long(b, mins); | |
36345 | BUFFER_APPEND_STRING_CONST(b, " min "); | |
36346 | } | |
36347 | - | |
36348 | + | |
36349 | buffer_append_long(b, seconds); | |
36350 | BUFFER_APPEND_STRING_CONST(b, " s"); | |
36351 | - | |
36352 | + | |
36353 | BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n"); | |
36354 | BUFFER_APPEND_STRING_CONST(b, "<tr><td>Started at</td><td class=\"string\">"); | |
36355 | - | |
36356 | + | |
36357 | ts = srv->startup_ts; | |
36358 | - | |
36359 | - strftime(buf, sizeof(buf) - 1, "%Y-%m-%d %H:%M:%S", localtime(&ts)); | |
36360 | + | |
36361 | + strftime(buf, sizeof(buf) - 1, "<span id=\"start_date\">%Y-%m-%d</span> <span id=\"start_time\">%H:%M:%S</span>", localtime(&ts)); | |
36362 | buffer_append_string(b, buf); | |
36363 | BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n"); | |
36364 | - | |
36365 | - | |
36366 | + | |
36367 | + | |
36368 | BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">absolute (since start)</th></tr>\n"); | |
36369 | - | |
36370 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">"); | |
36371 | + | |
36372 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\" ><span id=\"requests\">"); | |
36373 | avg = p->abs_requests; | |
36374 | ||
36375 | mod_status_get_multiplier(&avg, &multiplier, 1000); | |
36376 | - | |
36377 | + | |
36378 | buffer_append_long(b, avg); | |
36379 | - BUFFER_APPEND_STRING_CONST(b, " "); | |
36380 | + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_mult\">"); | |
36381 | if (multiplier) buffer_append_string_len(b, &multiplier, 1); | |
36382 | - BUFFER_APPEND_STRING_CONST(b, "req</td></tr>\n"); | |
36383 | - | |
36384 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">"); | |
36385 | + BUFFER_APPEND_STRING_CONST(b, "</span>req</td></tr>\n"); | |
36386 | + | |
36387 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic\">"); | |
36388 | avg = p->abs_traffic_out; | |
36389 | ||
36390 | mod_status_get_multiplier(&avg, &multiplier, 1024); | |
36391 | ||
36392 | sprintf(buf, "%.2f", avg); | |
36393 | buffer_append_string(b, buf); | |
36394 | - BUFFER_APPEND_STRING_CONST(b, " "); | |
36395 | + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"traffic_mult\">"); | |
36396 | if (multiplier) buffer_append_string_len(b, &multiplier, 1); | |
36397 | - BUFFER_APPEND_STRING_CONST(b, "byte</td></tr>\n"); | |
36398 | + BUFFER_APPEND_STRING_CONST(b, "</span>byte</td></tr>\n"); | |
36399 | ||
36400 | ||
36401 | ||
36402 | BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (since start)</th></tr>\n"); | |
36403 | - | |
36404 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">"); | |
36405 | + | |
36406 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_avg\">"); | |
36407 | avg = p->abs_requests / (srv->cur_ts - srv->startup_ts); | |
36408 | ||
36409 | mod_status_get_multiplier(&avg, &multiplier, 1000); | |
36410 | ||
36411 | buffer_append_long(b, avg); | |
36412 | - BUFFER_APPEND_STRING_CONST(b, " "); | |
36413 | + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_avg_mult\">"); | |
36414 | if (multiplier) buffer_append_string_len(b, &multiplier, 1); | |
36415 | - BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n"); | |
36416 | - | |
36417 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">"); | |
36418 | + BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n"); | |
36419 | + | |
36420 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic_avg\">"); | |
36421 | avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts); | |
36422 | ||
36423 | mod_status_get_multiplier(&avg, &multiplier, 1024); | |
36424 | ||
36425 | sprintf(buf, "%.2f", avg); | |
36426 | buffer_append_string(b, buf); | |
36427 | - BUFFER_APPEND_STRING_CONST(b, " "); | |
36428 | + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"traffic_avg_mult\">"); | |
36429 | if (multiplier) buffer_append_string_len(b, &multiplier, 1); | |
36430 | - BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n"); | |
36431 | + BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n"); | |
36432 | + | |
36433 | + | |
36434 | ||
36435 | - | |
36436 | - | |
36437 | BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (5s sliding average)</th></tr>\n"); | |
36438 | for (j = 0, avg = 0; j < 5; j++) { | |
36439 | avg += p->mod_5s_requests[j]; | |
36440 | } | |
36441 | - | |
36442 | + | |
36443 | avg /= 5; | |
36444 | - | |
36445 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">"); | |
36446 | + | |
36447 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_sliding_avg\">"); | |
36448 | ||
36449 | mod_status_get_multiplier(&avg, &multiplier, 1000); | |
36450 | ||
36451 | buffer_append_long(b, avg); | |
36452 | - BUFFER_APPEND_STRING_CONST(b, " "); | |
36453 | + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_avg_mult\">"); | |
36454 | if (multiplier) buffer_append_string_len(b, &multiplier, 1); | |
36455 | - | |
36456 | - BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n"); | |
36457 | - | |
36458 | + | |
36459 | + BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n"); | |
36460 | + | |
36461 | for (j = 0, avg = 0; j < 5; j++) { | |
36462 | avg += p->mod_5s_traffic_out[j]; | |
36463 | } | |
36464 | - | |
36465 | + | |
36466 | avg /= 5; | |
36467 | - | |
36468 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">"); | |
36469 | + | |
36470 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"requests_sliding_traffic\">"); | |
36471 | ||
36472 | mod_status_get_multiplier(&avg, &multiplier, 1024); | |
36473 | ||
36474 | sprintf(buf, "%.2f", avg); | |
36475 | buffer_append_string(b, buf); | |
36476 | - BUFFER_APPEND_STRING_CONST(b, " "); | |
36477 | + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_traffic_mult\">"); | |
36478 | if (multiplier) buffer_append_string_len(b, &multiplier, 1); | |
36479 | - BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n"); | |
36480 | - | |
36481 | + BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n"); | |
36482 | + | |
36483 | BUFFER_APPEND_STRING_CONST(b, "</table>\n"); | |
36484 | - | |
36485 | - | |
36486 | + | |
36487 | + | |
36488 | BUFFER_APPEND_STRING_CONST(b, "<hr />\n<pre><b>legend</b>\n"); | |
36489 | BUFFER_APPEND_STRING_CONST(b, ". = connect, C = close, E = hard error\n"); | |
36490 | BUFFER_APPEND_STRING_CONST(b, "r = read, R = read-POST, W = write, h = handle-request\n"); | |
36491 | BUFFER_APPEND_STRING_CONST(b, "q = request-start, Q = request-end\n"); | |
36492 | BUFFER_APPEND_STRING_CONST(b, "s = response-start, S = response-end\n"); | |
36493 | - | |
36494 | - BUFFER_APPEND_STRING_CONST(b, "<b>"); | |
36495 | + | |
36496 | + BUFFER_APPEND_STRING_CONST(b, "<strong><span id=\"connections\">"); | |
36497 | buffer_append_long(b, srv->conns->used); | |
36498 | - BUFFER_APPEND_STRING_CONST(b, " connections</b>\n"); | |
36499 | - | |
36500 | + BUFFER_APPEND_STRING_CONST(b, "</span> connections</strong>\n"); | |
36501 | + | |
36502 | for (j = 0; j < srv->conns->used; j++) { | |
36503 | connection *c = srv->conns->ptr[j]; | |
36504 | const char *state = connection_get_short_state(c->state); | |
36505 | - | |
36506 | + | |
36507 | buffer_append_string_len(b, state, 1); | |
36508 | - | |
36509 | + | |
36510 | if (((j + 1) % 50) == 0) { | |
36511 | BUFFER_APPEND_STRING_CONST(b, "\n"); | |
36512 | } | |
36513 | } | |
36514 | - | |
36515 | + | |
36516 | BUFFER_APPEND_STRING_CONST(b, "\n</pre><hr />\n<h2>Connections</h2>\n"); | |
36517 | - | |
36518 | - BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">\n"); | |
36519 | + | |
36520 | + BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" summary=\"Current connections\" id=\"clients\">\n"); | |
36521 | BUFFER_APPEND_STRING_CONST(b, "<tr>"); | |
36522 | mod_status_header_append_sort(b, p_d, "Client IP"); | |
36523 | mod_status_header_append_sort(b, p_d, "Read"); | |
36524 | @@ -473,16 +472,16 @@ | |
36525 | mod_status_header_append_sort(b, p_d, "URI"); | |
36526 | mod_status_header_append_sort(b, p_d, "File"); | |
36527 | BUFFER_APPEND_STRING_CONST(b, "</tr>\n"); | |
36528 | - | |
36529 | + | |
36530 | for (j = 0; j < srv->conns->used; j++) { | |
36531 | connection *c = srv->conns->ptr[j]; | |
36532 | - | |
36533 | - BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string\">"); | |
36534 | - | |
36535 | + | |
36536 | + BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string ip\">"); | |
36537 | + | |
36538 | buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(c->dst_addr))); | |
36539 | - | |
36540 | - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">"); | |
36541 | - | |
36542 | + | |
36543 | + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_read\">"); | |
36544 | + | |
36545 | if (con->request.content_length) { | |
36546 | buffer_append_long(b, c->request_content_queue->bytes_in); | |
36547 | BUFFER_APPEND_STRING_CONST(b, "/"); | |
36548 | @@ -490,55 +489,55 @@ | |
36549 | } else { | |
36550 | BUFFER_APPEND_STRING_CONST(b, "0/0"); | |
36551 | } | |
36552 | - | |
36553 | - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">"); | |
36554 | - | |
36555 | + | |
36556 | + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_written\">"); | |
36557 | + | |
36558 | buffer_append_off_t(b, chunkqueue_written(c->write_queue)); | |
36559 | BUFFER_APPEND_STRING_CONST(b, "/"); | |
36560 | buffer_append_off_t(b, chunkqueue_length(c->write_queue)); | |
36561 | - | |
36562 | - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">"); | |
36563 | - | |
36564 | + | |
36565 | + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string state\">"); | |
36566 | + | |
36567 | buffer_append_string(b, connection_get_state(c->state)); | |
36568 | - | |
36569 | - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">"); | |
36570 | - | |
36571 | + | |
36572 | + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int time\">"); | |
36573 | + | |
36574 | buffer_append_long(b, srv->cur_ts - c->request_start); | |
36575 | - | |
36576 | - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">"); | |
36577 | - | |
36578 | + | |
36579 | + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string host\">"); | |
36580 | + | |
36581 | if (buffer_is_empty(c->server_name)) { | |
36582 | buffer_append_string_buffer(b, c->uri.authority); | |
36583 | } | |
36584 | else { | |
36585 | buffer_append_string_buffer(b, c->server_name); | |
36586 | } | |
36587 | - | |
36588 | - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">"); | |
36589 | - | |
36590 | + | |
36591 | + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string uri\">"); | |
36592 | + | |
36593 | if (!buffer_is_empty(c->uri.path)) { | |
36594 | buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML); | |
36595 | } | |
36596 | - | |
36597 | - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">"); | |
36598 | - | |
36599 | + | |
36600 | + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string file\">"); | |
36601 | + | |
36602 | buffer_append_string_buffer(b, c->physical.path); | |
36603 | - | |
36604 | + | |
36605 | BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n"); | |
36606 | } | |
36607 | - | |
36608 | - | |
36609 | - BUFFER_APPEND_STRING_CONST(b, | |
36610 | + | |
36611 | + | |
36612 | + BUFFER_APPEND_STRING_CONST(b, | |
36613 | "</table>\n"); | |
36614 | - | |
36615 | - | |
36616 | - BUFFER_APPEND_STRING_CONST(b, | |
36617 | + | |
36618 | + | |
36619 | + BUFFER_APPEND_STRING_CONST(b, | |
36620 | " </body>\n" | |
36621 | "</html>\n" | |
36622 | ); | |
36623 | - | |
36624 | + | |
36625 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); | |
36626 | - | |
36627 | + | |
36628 | return 0; | |
36629 | } | |
36630 | ||
36631 | @@ -548,7 +547,7 @@ | |
36632 | buffer *b; | |
36633 | double avg; | |
36634 | time_t ts; | |
36635 | - | |
36636 | + | |
36637 | b = chunkqueue_get_append_buffer(con->write_queue); | |
36638 | ||
36639 | /* output total number of requests */ | |
36640 | @@ -556,19 +555,19 @@ | |
36641 | avg = p->abs_requests; | |
36642 | buffer_append_long(b, avg); | |
36643 | BUFFER_APPEND_STRING_CONST(b, "\n"); | |
36644 | - | |
36645 | + | |
36646 | /* output total traffic out in kbytes */ | |
36647 | BUFFER_APPEND_STRING_CONST(b, "Total kBytes: "); | |
36648 | avg = p->abs_traffic_out / 1024; | |
36649 | buffer_append_long(b, avg); | |
36650 | BUFFER_APPEND_STRING_CONST(b, "\n"); | |
36651 | - | |
36652 | + | |
36653 | /* output uptime */ | |
36654 | BUFFER_APPEND_STRING_CONST(b, "Uptime: "); | |
36655 | ts = srv->cur_ts - srv->startup_ts; | |
36656 | buffer_append_long(b, ts); | |
36657 | BUFFER_APPEND_STRING_CONST(b, "\n"); | |
36658 | - | |
36659 | + | |
36660 | /* output busy servers */ | |
36661 | BUFFER_APPEND_STRING_CONST(b, "BusyServers: "); | |
36662 | buffer_append_long(b, srv->conns->used); | |
36663 | @@ -577,7 +576,7 @@ | |
36664 | /* set text/plain output */ | |
36665 | ||
36666 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); | |
36667 | - | |
36668 | + | |
36669 | return 0; | |
36670 | } | |
36671 | ||
36672 | @@ -591,10 +590,10 @@ | |
36673 | /* we have nothing to send */ | |
36674 | con->http_status = 204; | |
36675 | con->file_finished = 1; | |
36676 | - | |
36677 | + | |
36678 | return HANDLER_FINISHED; | |
36679 | } | |
36680 | - | |
36681 | + | |
36682 | b = chunkqueue_get_append_buffer(con->write_queue); | |
36683 | ||
36684 | for (i = 0; i < st->used; i++) { | |
36685 | @@ -605,27 +604,27 @@ | |
36686 | buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value); | |
36687 | buffer_append_string(b, "\n"); | |
36688 | } | |
36689 | - | |
36690 | + | |
36691 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); | |
36692 | - | |
36693 | + | |
36694 | con->http_status = 200; | |
36695 | con->file_finished = 1; | |
36696 | - | |
36697 | + | |
36698 | return HANDLER_FINISHED; | |
36699 | } | |
36700 | ||
36701 | ||
36702 | static handler_t mod_status_handle_server_status(server *srv, connection *con, void *p_d) { | |
36703 | - | |
36704 | + | |
36705 | if (buffer_is_equal_string(con->uri.query, CONST_STR_LEN("auto"))) { | |
36706 | mod_status_handle_server_status_text(srv, con, p_d); | |
36707 | } else { | |
36708 | mod_status_handle_server_status_html(srv, con, p_d); | |
36709 | } | |
36710 | - | |
36711 | + | |
36712 | con->http_status = 200; | |
36713 | con->file_finished = 1; | |
36714 | - | |
36715 | + | |
36716 | return HANDLER_FINISHED; | |
36717 | } | |
36718 | ||
36719 | @@ -634,9 +633,9 @@ | |
36720 | plugin_data *p = p_d; | |
36721 | buffer *b, *m = p->module_list; | |
36722 | size_t i; | |
36723 | - | |
36724 | - struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = | |
36725 | - { | |
36726 | + | |
36727 | + struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = | |
36728 | + { | |
36729 | /* - poll is most reliable | |
36730 | * - select works everywhere | |
36731 | * - linux-* are experimental | |
36732 | @@ -661,10 +660,10 @@ | |
36733 | #endif | |
36734 | { FDEVENT_HANDLER_UNSET, NULL } | |
36735 | }; | |
36736 | - | |
36737 | + | |
36738 | b = chunkqueue_get_append_buffer(con->write_queue); | |
36739 | - | |
36740 | - BUFFER_COPY_STRING_CONST(b, | |
36741 | + | |
36742 | + BUFFER_COPY_STRING_CONST(b, | |
36743 | "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" | |
36744 | "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" | |
36745 | " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" | |
36746 | @@ -675,7 +674,7 @@ | |
36747 | " <body>\n" | |
36748 | " <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n" | |
36749 | " <table border=\"1\">\n"); | |
36750 | - | |
36751 | + | |
36752 | mod_status_header_append(b, "Server-Features"); | |
36753 | #ifdef HAVE_PCRE_H | |
36754 | mod_status_row_append(b, "RegEx Conditionals", "enabled"); | |
36755 | @@ -683,21 +682,21 @@ | |
36756 | mod_status_row_append(b, "RegEx Conditionals", "disabled - pcre missing"); | |
36757 | #endif | |
36758 | mod_status_header_append(b, "Network Engine"); | |
36759 | - | |
36760 | + | |
36761 | for (i = 0; event_handlers[i].name; i++) { | |
36762 | if (event_handlers[i].et == srv->event_handler) { | |
36763 | mod_status_row_append(b, "fd-Event-Handler", event_handlers[i].name); | |
36764 | break; | |
36765 | } | |
36766 | } | |
36767 | - | |
36768 | + | |
36769 | mod_status_header_append(b, "Config-File-Settings"); | |
36770 | - | |
36771 | + | |
36772 | for (i = 0; i < srv->plugins.used; i++) { | |
36773 | plugin **ps = srv->plugins.ptr; | |
36774 | - | |
36775 | + | |
36776 | plugin *pl = ps[i]; | |
36777 | - | |
36778 | + | |
36779 | if (i == 0) { | |
36780 | buffer_copy_string_buffer(m, pl->name); | |
36781 | } else { | |
36782 | @@ -705,137 +704,135 @@ | |
36783 | buffer_append_string_buffer(m, pl->name); | |
36784 | } | |
36785 | } | |
36786 | - | |
36787 | + | |
36788 | mod_status_row_append(b, "Loaded Modules", m->ptr); | |
36789 | - | |
36790 | + | |
36791 | BUFFER_APPEND_STRING_CONST(b, " </table>\n"); | |
36792 | - | |
36793 | - BUFFER_APPEND_STRING_CONST(b, | |
36794 | + | |
36795 | + BUFFER_APPEND_STRING_CONST(b, | |
36796 | " </body>\n" | |
36797 | "</html>\n" | |
36798 | ); | |
36799 | - | |
36800 | + | |
36801 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); | |
36802 | - | |
36803 | + | |
36804 | con->http_status = 200; | |
36805 | con->file_finished = 1; | |
36806 | - | |
36807 | + | |
36808 | return HANDLER_FINISHED; | |
36809 | } | |
36810 | ||
36811 | -#define PATCH(x) \ | |
36812 | - p->conf.x = s->x; | |
36813 | static int mod_status_patch_connection(server *srv, connection *con, plugin_data *p) { | |
36814 | size_t i, j; | |
36815 | plugin_config *s = p->config_storage[0]; | |
36816 | - | |
36817 | - PATCH(status_url); | |
36818 | - PATCH(config_url); | |
36819 | - PATCH(sort); | |
36820 | - PATCH(statistics_url); | |
36821 | - | |
36822 | + | |
36823 | + PATCH_OPTION(status_url); | |
36824 | + PATCH_OPTION(config_url); | |
36825 | + PATCH_OPTION(sort); | |
36826 | + PATCH_OPTION(statistics_url); | |
36827 | + | |
36828 | /* skip the first, the global context */ | |
36829 | for (i = 1; i < srv->config_context->used; i++) { | |
36830 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
36831 | s = p->config_storage[i]; | |
36832 | - | |
36833 | + | |
36834 | /* condition didn't match */ | |
36835 | if (!config_check_cond(srv, con, dc)) continue; | |
36836 | - | |
36837 | + | |
36838 | /* merge config */ | |
36839 | for (j = 0; j < dc->value->used; j++) { | |
36840 | data_unset *du = dc->value->data[j]; | |
36841 | - | |
36842 | + | |
36843 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.status-url"))) { | |
36844 | - PATCH(status_url); | |
36845 | + PATCH_OPTION(status_url); | |
36846 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.config-url"))) { | |
36847 | - PATCH(config_url); | |
36848 | + PATCH_OPTION(config_url); | |
36849 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.enable-sort"))) { | |
36850 | - PATCH(sort); | |
36851 | + PATCH_OPTION(sort); | |
36852 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.statistics-url"))) { | |
36853 | - PATCH(statistics_url); | |
36854 | - } | |
36855 | + PATCH_OPTION(statistics_url); | |
36856 | + } | |
36857 | } | |
36858 | } | |
36859 | - | |
36860 | + | |
36861 | return 0; | |
36862 | } | |
36863 | ||
36864 | static handler_t mod_status_handler(server *srv, connection *con, void *p_d) { | |
36865 | plugin_data *p = p_d; | |
36866 | - | |
36867 | + | |
36868 | mod_status_patch_connection(srv, con, p); | |
36869 | - | |
36870 | - if (!buffer_is_empty(p->conf.status_url) && | |
36871 | + | |
36872 | + if (!buffer_is_empty(p->conf.status_url) && | |
36873 | buffer_is_equal(p->conf.status_url, con->uri.path)) { | |
36874 | return mod_status_handle_server_status(srv, con, p_d); | |
36875 | - } else if (!buffer_is_empty(p->conf.config_url) && | |
36876 | + } else if (!buffer_is_empty(p->conf.config_url) && | |
36877 | buffer_is_equal(p->conf.config_url, con->uri.path)) { | |
36878 | return mod_status_handle_server_config(srv, con, p_d); | |
36879 | - } else if (!buffer_is_empty(p->conf.statistics_url) && | |
36880 | + } else if (!buffer_is_empty(p->conf.statistics_url) && | |
36881 | buffer_is_equal(p->conf.statistics_url, con->uri.path)) { | |
36882 | return mod_status_handle_server_statistics(srv, con, p_d); | |
36883 | } | |
36884 | - | |
36885 | + | |
36886 | return HANDLER_GO_ON; | |
36887 | } | |
36888 | ||
36889 | TRIGGER_FUNC(mod_status_trigger) { | |
36890 | plugin_data *p = p_d; | |
36891 | size_t i; | |
36892 | - | |
36893 | + | |
36894 | /* check all connections */ | |
36895 | for (i = 0; i < srv->conns->used; i++) { | |
36896 | connection *c = srv->conns->ptr[i]; | |
36897 | - | |
36898 | + | |
36899 | p->bytes_written += c->bytes_written_cur_second; | |
36900 | } | |
36901 | - | |
36902 | + | |
36903 | /* a sliding average */ | |
36904 | p->mod_5s_traffic_out[p->mod_5s_ndx] = p->bytes_written; | |
36905 | p->mod_5s_requests [p->mod_5s_ndx] = p->requests; | |
36906 | - | |
36907 | + | |
36908 | p->mod_5s_ndx = (p->mod_5s_ndx+1) % 5; | |
36909 | - | |
36910 | + | |
36911 | p->abs_traffic_out += p->bytes_written; | |
36912 | p->rel_traffic_out += p->bytes_written; | |
36913 | - | |
36914 | + | |
36915 | p->bytes_written = 0; | |
36916 | - | |
36917 | + | |
36918 | /* reset storage - second */ | |
36919 | p->traffic_out = 0; | |
36920 | p->requests = 0; | |
36921 | - | |
36922 | + | |
36923 | return HANDLER_GO_ON; | |
36924 | } | |
36925 | ||
36926 | REQUESTDONE_FUNC(mod_status_account) { | |
36927 | plugin_data *p = p_d; | |
36928 | - | |
36929 | + | |
36930 | UNUSED(srv); | |
36931 | ||
36932 | p->requests++; | |
36933 | p->rel_requests++; | |
36934 | p->abs_requests++; | |
36935 | - | |
36936 | + | |
36937 | p->bytes_written += con->bytes_written_cur_second; | |
36938 | - | |
36939 | + | |
36940 | return HANDLER_GO_ON; | |
36941 | } | |
36942 | ||
36943 | int mod_status_plugin_init(plugin *p) { | |
36944 | p->version = LIGHTTPD_VERSION_ID; | |
36945 | p->name = buffer_init_string("status"); | |
36946 | - | |
36947 | + | |
36948 | p->init = mod_status_init; | |
36949 | p->cleanup = mod_status_free; | |
36950 | p->set_defaults= mod_status_set_defaults; | |
36951 | - | |
36952 | + | |
36953 | p->handle_uri_clean = mod_status_handler; | |
36954 | p->handle_trigger = mod_status_trigger; | |
36955 | p->handle_request_done = mod_status_account; | |
36956 | - | |
36957 | + | |
36958 | p->data = NULL; | |
36959 | - | |
36960 | + | |
36961 | return 0; | |
36962 | } | |
1175ccec | 36963 | --- ../lighttpd-1.4.11/src/mod_trigger_b4_dl.c 2005-09-23 22:53:55.000000000 +0300 |
36e2a29e | 36964 | +++ lighttpd-1.4.12/src/mod_trigger_b4_dl.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
36965 | @@ -24,18 +24,18 @@ |
36966 | ||
36967 | /** | |
36968 | * this is a trigger_b4_dl for a lighttpd plugin | |
36969 | - * | |
36970 | + * | |
36971 | */ | |
36972 | ||
36973 | /* plugin config for all request/connections */ | |
36974 | ||
36975 | typedef struct { | |
36976 | buffer *db_filename; | |
36977 | - | |
36978 | + | |
36979 | buffer *trigger_url; | |
36980 | buffer *download_url; | |
36981 | buffer *deny_url; | |
36982 | - | |
36983 | + | |
36984 | array *mc_hosts; | |
36985 | buffer *mc_namespace; | |
36986 | #if defined(HAVE_PCRE_H) | |
36987 | @@ -46,58 +46,58 @@ | |
36988 | GDBM_FILE db; | |
36989 | #endif | |
36990 | ||
36991 | -#if defined(HAVE_MEMCACHE_H) | |
36992 | +#if defined(HAVE_MEMCACHE_H) | |
36993 | struct memcache *mc; | |
36994 | #endif | |
36995 | - | |
36996 | + | |
36997 | unsigned short trigger_timeout; | |
36998 | unsigned short debug; | |
36999 | } plugin_config; | |
37000 | ||
37001 | typedef struct { | |
37002 | PLUGIN_DATA; | |
37003 | - | |
37004 | + | |
37005 | buffer *tmp_buf; | |
37006 | - | |
37007 | + | |
37008 | plugin_config **config_storage; | |
37009 | - | |
37010 | - plugin_config conf; | |
37011 | + | |
37012 | + plugin_config conf; | |
37013 | } plugin_data; | |
37014 | ||
37015 | /* init the plugin data */ | |
37016 | INIT_FUNC(mod_trigger_b4_dl_init) { | |
37017 | plugin_data *p; | |
37018 | - | |
37019 | + | |
37020 | p = calloc(1, sizeof(*p)); | |
37021 | - | |
37022 | + | |
37023 | p->tmp_buf = buffer_init(); | |
37024 | - | |
37025 | + | |
37026 | return p; | |
37027 | } | |
37028 | ||
37029 | /* detroy the plugin data */ | |
37030 | FREE_FUNC(mod_trigger_b4_dl_free) { | |
37031 | plugin_data *p = p_d; | |
37032 | - | |
37033 | + | |
37034 | UNUSED(srv); | |
37035 | ||
37036 | if (!p) return HANDLER_GO_ON; | |
37037 | - | |
37038 | + | |
37039 | if (p->config_storage) { | |
37040 | size_t i; | |
37041 | for (i = 0; i < srv->config_context->used; i++) { | |
37042 | plugin_config *s = p->config_storage[i]; | |
37043 | ||
37044 | if (!s) continue; | |
37045 | - | |
37046 | + | |
37047 | buffer_free(s->db_filename); | |
37048 | buffer_free(s->download_url); | |
37049 | buffer_free(s->trigger_url); | |
37050 | buffer_free(s->deny_url); | |
37051 | - | |
37052 | + | |
37053 | buffer_free(s->mc_namespace); | |
37054 | array_free(s->mc_hosts); | |
37055 | - | |
37056 | + | |
37057 | #if defined(HAVE_PCRE_H) | |
37058 | if (s->trigger_regex) pcre_free(s->trigger_regex); | |
37059 | if (s->download_regex) pcre_free(s->download_regex); | |
37060 | @@ -108,16 +108,16 @@ | |
37061 | #if defined(HAVE_MEMCACHE_H) | |
37062 | if (s->mc) mc_free(s->mc); | |
37063 | #endif | |
37064 | - | |
37065 | + | |
37066 | free(s); | |
37067 | } | |
37068 | free(p->config_storage); | |
37069 | } | |
37070 | - | |
37071 | + | |
37072 | buffer_free(p->tmp_buf); | |
37073 | - | |
37074 | + | |
37075 | free(p); | |
37076 | - | |
37077 | + | |
37078 | return HANDLER_GO_ON; | |
37079 | } | |
37080 | ||
37081 | @@ -126,9 +126,9 @@ | |
37082 | SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) { | |
37083 | plugin_data *p = p_d; | |
37084 | size_t i = 0; | |
37085 | - | |
37086 | - | |
37087 | - config_values_t cv[] = { | |
37088 | + | |
37089 | + | |
37090 | + config_values_t cv[] = { | |
37091 | { "trigger-before-download.gdbm-filename", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
37092 | { "trigger-before-download.trigger-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
37093 | { "trigger-before-download.download-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
37094 | @@ -139,18 +139,18 @@ | |
37095 | { "trigger-before-download.debug", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */ | |
37096 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
37097 | }; | |
37098 | - | |
37099 | + | |
37100 | if (!p) return HANDLER_ERROR; | |
37101 | - | |
37102 | + | |
37103 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
37104 | - | |
37105 | + | |
37106 | for (i = 0; i < srv->config_context->used; i++) { | |
37107 | plugin_config *s; | |
37108 | #if defined(HAVE_PCRE_H) | |
37109 | const char *errptr; | |
37110 | int erroff; | |
37111 | #endif | |
37112 | - | |
37113 | + | |
37114 | s = calloc(1, sizeof(plugin_config)); | |
37115 | s->db_filename = buffer_init(); | |
37116 | s->download_url = buffer_init(); | |
37117 | @@ -158,7 +158,7 @@ | |
37118 | s->deny_url = buffer_init(); | |
37119 | s->mc_hosts = array_init(); | |
37120 | s->mc_namespace = buffer_init(); | |
37121 | - | |
37122 | + | |
37123 | cv[0].destination = s->db_filename; | |
37124 | cv[1].destination = s->trigger_url; | |
37125 | cv[2].destination = s->download_url; | |
37126 | @@ -167,41 +167,41 @@ | |
37127 | cv[5].destination = s->mc_hosts; | |
37128 | cv[6].destination = s->mc_namespace; | |
37129 | cv[7].destination = &(s->debug); | |
37130 | - | |
37131 | + | |
37132 | p->config_storage[i] = s; | |
37133 | - | |
37134 | + | |
37135 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
37136 | return HANDLER_ERROR; | |
37137 | } | |
37138 | #if defined(HAVE_GDBM_H) | |
37139 | if (!buffer_is_empty(s->db_filename)) { | |
37140 | if (NULL == (s->db = gdbm_open(s->db_filename->ptr, 4096, GDBM_WRCREAT | GDBM_NOLOCK, S_IRUSR | S_IWUSR, 0))) { | |
37141 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
37142 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
37143 | "gdbm-open failed"); | |
37144 | return HANDLER_ERROR; | |
37145 | } | |
37146 | } | |
37147 | #endif | |
37148 | -#if defined(HAVE_PCRE_H) | |
37149 | +#if defined(HAVE_PCRE_H) | |
37150 | if (!buffer_is_empty(s->download_url)) { | |
37151 | if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr, | |
37152 | 0, &errptr, &erroff, NULL))) { | |
37153 | - | |
37154 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
37155 | - "compiling regex for download-url failed:", | |
37156 | + | |
37157 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
37158 | + "compiling regex for download-url failed:", | |
37159 | s->download_url, "pos:", erroff); | |
37160 | return HANDLER_ERROR; | |
37161 | } | |
37162 | } | |
37163 | - | |
37164 | + | |
37165 | if (!buffer_is_empty(s->trigger_url)) { | |
37166 | if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr, | |
37167 | 0, &errptr, &erroff, NULL))) { | |
37168 | - | |
37169 | - log_error_write(srv, __FILE__, __LINE__, "sbss", | |
37170 | - "compiling regex for trigger-url failed:", | |
37171 | + | |
37172 | + log_error_write(srv, __FILE__, __LINE__, "sbss", | |
37173 | + "compiling regex for trigger-url failed:", | |
37174 | s->trigger_url, "pos:", erroff); | |
37175 | - | |
37176 | + | |
37177 | return HANDLER_ERROR; | |
37178 | } | |
37179 | } | |
37180 | @@ -211,100 +211,97 @@ | |
37181 | #if defined(HAVE_MEMCACHE_H) | |
37182 | size_t k; | |
37183 | s->mc = mc_new(); | |
37184 | - | |
37185 | + | |
37186 | for (k = 0; k < s->mc_hosts->used; k++) { | |
37187 | data_string *ds = (data_string *)s->mc_hosts->data[k]; | |
37188 | - | |
37189 | + | |
37190 | if (0 != mc_server_add4(s->mc, ds->value->ptr)) { | |
37191 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
37192 | - "connection to host failed:", | |
37193 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
37194 | + "connection to host failed:", | |
37195 | ds->value); | |
37196 | - | |
37197 | + | |
37198 | return HANDLER_ERROR; | |
37199 | } | |
37200 | } | |
37201 | #else | |
37202 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
37203 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
37204 | "memcache support is not compiled in but trigger-before-download.memcache-hosts is set, aborting"); | |
37205 | return HANDLER_ERROR; | |
37206 | #endif | |
37207 | } | |
37208 | - | |
37209 | + | |
37210 | ||
37211 | #if (!defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)) || !defined(HAVE_PCRE_H) | |
37212 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
37213 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
37214 | "(either gdbm or libmemcache) and pcre are require, but were not found, aborting"); | |
37215 | return HANDLER_ERROR; | |
37216 | #endif | |
37217 | } | |
37218 | - | |
37219 | + | |
37220 | return HANDLER_GO_ON; | |
37221 | } | |
37222 | ||
37223 | -#define PATCH(x) \ | |
37224 | - p->conf.x = s->x; | |
37225 | static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plugin_data *p) { | |
37226 | size_t i, j; | |
37227 | plugin_config *s = p->config_storage[0]; | |
37228 | - | |
37229 | + | |
37230 | #if defined(HAVE_GDBM) | |
37231 | - PATCH(db); | |
37232 | -#endif | |
37233 | + PATCH_OPTION(db); | |
37234 | +#endif | |
37235 | #if defined(HAVE_PCRE_H) | |
37236 | - PATCH(download_regex); | |
37237 | - PATCH(trigger_regex); | |
37238 | -#endif | |
37239 | - PATCH(trigger_timeout); | |
37240 | - PATCH(deny_url); | |
37241 | - PATCH(mc_namespace); | |
37242 | - PATCH(debug); | |
37243 | + PATCH_OPTION(download_regex); | |
37244 | + PATCH_OPTION(trigger_regex); | |
37245 | +#endif | |
37246 | + PATCH_OPTION(trigger_timeout); | |
37247 | + PATCH_OPTION(deny_url); | |
37248 | + PATCH_OPTION(mc_namespace); | |
37249 | + PATCH_OPTION(debug); | |
37250 | #if defined(HAVE_MEMCACHE_H) | |
37251 | - PATCH(mc); | |
37252 | + PATCH_OPTION(mc); | |
37253 | #endif | |
37254 | - | |
37255 | + | |
37256 | /* skip the first, the global context */ | |
37257 | for (i = 1; i < srv->config_context->used; i++) { | |
37258 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
37259 | s = p->config_storage[i]; | |
37260 | - | |
37261 | + | |
37262 | /* condition didn't match */ | |
37263 | if (!config_check_cond(srv, con, dc)) continue; | |
37264 | - | |
37265 | + | |
37266 | /* merge config */ | |
37267 | for (j = 0; j < dc->value->used; j++) { | |
37268 | data_unset *du = dc->value->data[j]; | |
37269 | ||
37270 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.download-url"))) { | |
37271 | #if defined(HAVE_PCRE_H) | |
37272 | - PATCH(download_regex); | |
37273 | + PATCH_OPTION(download_regex); | |
37274 | #endif | |
37275 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-url"))) { | |
37276 | # if defined(HAVE_PCRE_H) | |
37277 | - PATCH(trigger_regex); | |
37278 | + PATCH_OPTION(trigger_regex); | |
37279 | # endif | |
37280 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.gdbm-filename"))) { | |
37281 | #if defined(HAVE_GDBM_H) | |
37282 | - PATCH(db); | |
37283 | + PATCH_OPTION(db); | |
37284 | #endif | |
37285 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-timeout"))) { | |
37286 | - PATCH(trigger_timeout); | |
37287 | + PATCH_OPTION(trigger_timeout); | |
37288 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.debug"))) { | |
37289 | - PATCH(debug); | |
37290 | + PATCH_OPTION(debug); | |
37291 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.deny-url"))) { | |
37292 | - PATCH(deny_url); | |
37293 | + PATCH_OPTION(deny_url); | |
37294 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-namespace"))) { | |
37295 | - PATCH(mc_namespace); | |
37296 | + PATCH_OPTION(mc_namespace); | |
37297 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-hosts"))) { | |
37298 | #if defined(HAVE_MEMCACHE_H) | |
37299 | - PATCH(mc); | |
37300 | + PATCH_OPTION(mc); | |
37301 | #endif | |
37302 | } | |
37303 | } | |
37304 | } | |
37305 | - | |
37306 | + | |
37307 | return 0; | |
37308 | } | |
37309 | -#undef PATCH | |
37310 | ||
37311 | URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { | |
37312 | plugin_data *p = p_d; | |
37313 | @@ -315,20 +312,20 @@ | |
37314 | int n; | |
37315 | # define N 10 | |
37316 | int ovec[N * 3]; | |
37317 | - | |
37318 | + | |
37319 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
37320 | - | |
37321 | + | |
37322 | mod_trigger_b4_dl_patch_connection(srv, con, p); | |
37323 | - | |
37324 | + | |
37325 | if (!p->conf.trigger_regex || !p->conf.download_regex) return HANDLER_GO_ON; | |
37326 | - | |
37327 | + | |
37328 | # if !defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H) | |
37329 | return HANDLER_GO_ON; | |
37330 | # elif defined(HAVE_GDBM_H) && defined(HAVE_MEMCACHE_H) | |
37331 | if (!p->conf.db && !p->conf.mc) return HANDLER_GO_ON; | |
37332 | if (p->conf.db && p->conf.mc) { | |
37333 | /* can't decide which one */ | |
37334 | - | |
37335 | + | |
37336 | return HANDLER_GO_ON; | |
37337 | } | |
37338 | # elif defined(HAVE_GDBM_H) | |
37339 | @@ -336,12 +333,12 @@ | |
37340 | # else | |
37341 | if (!p->conf.mc) return HANDLER_GO_ON; | |
37342 | # endif | |
37343 | - | |
37344 | + | |
37345 | if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "X-Forwarded-For"))) { | |
37346 | /* X-Forwarded-For contains the ip behind the proxy */ | |
37347 | - | |
37348 | + | |
37349 | remote_ip = ds->value->ptr; | |
37350 | - | |
37351 | + | |
37352 | /* memcache can't handle spaces */ | |
37353 | } else { | |
37354 | remote_ip = inet_ntop_cache_get_ip(srv, &(con->dst_addr)); | |
37355 | @@ -350,13 +347,13 @@ | |
37356 | if (p->conf.debug) { | |
37357 | log_error_write(srv, __FILE__, __LINE__, "ss", "(debug) remote-ip:", remote_ip); | |
37358 | } | |
37359 | - | |
37360 | + | |
37361 | /* check if URL is a trigger -> insert IP into DB */ | |
37362 | if ((n = pcre_exec(p->conf.trigger_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) { | |
37363 | if (n != PCRE_ERROR_NOMATCH) { | |
37364 | log_error_write(srv, __FILE__, __LINE__, "sd", | |
37365 | "execution error while matching:", n); | |
37366 | - | |
37367 | + | |
37368 | return HANDLER_ERROR; | |
37369 | } | |
37370 | } else { | |
37371 | @@ -364,34 +361,34 @@ | |
37372 | if (p->conf.db) { | |
37373 | /* the trigger matched */ | |
37374 | datum key, val; | |
37375 | - | |
37376 | + | |
37377 | key.dptr = (char *)remote_ip; | |
37378 | key.dsize = strlen(remote_ip); | |
37379 | - | |
37380 | + | |
37381 | val.dptr = (char *)&(srv->cur_ts); | |
37382 | val.dsize = sizeof(srv->cur_ts); | |
37383 | - | |
37384 | + | |
37385 | if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) { | |
37386 | log_error_write(srv, __FILE__, __LINE__, "s", | |
37387 | "insert failed"); | |
37388 | } | |
37389 | } | |
37390 | # endif | |
37391 | -# if defined(HAVE_MEMCACHE_H) | |
37392 | +# if defined(HAVE_MEMCACHE_H) | |
37393 | if (p->conf.mc) { | |
37394 | size_t i; | |
37395 | buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace); | |
37396 | buffer_append_string(p->tmp_buf, remote_ip); | |
37397 | - | |
37398 | + | |
37399 | for (i = 0; i < p->tmp_buf->used - 1; i++) { | |
37400 | if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; | |
37401 | } | |
37402 | - | |
37403 | + | |
37404 | if (p->conf.debug) { | |
37405 | log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) triggered IP:", p->tmp_buf); | |
37406 | } | |
37407 | ||
37408 | - if (0 != mc_set(p->conf.mc, | |
37409 | + if (0 != mc_set(p->conf.mc, | |
37410 | CONST_BUF_LEN(p->tmp_buf), | |
37411 | (char *)&(srv->cur_ts), sizeof(srv->cur_ts), | |
37412 | p->conf.trigger_timeout, 0)) { | |
37413 | @@ -401,7 +398,7 @@ | |
37414 | } | |
37415 | # endif | |
37416 | } | |
37417 | - | |
37418 | + | |
37419 | /* check if URL is a download -> check IP in DB, update timestamp */ | |
37420 | if ((n = pcre_exec(p->conf.download_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) { | |
37421 | if (n != PCRE_ERROR_NOMATCH) { | |
37422 | @@ -411,93 +408,93 @@ | |
37423 | } | |
37424 | } else { | |
37425 | /* the download uri matched */ | |
37426 | -# if defined(HAVE_GDBM_H) | |
37427 | +# if defined(HAVE_GDBM_H) | |
37428 | if (p->conf.db) { | |
37429 | datum key, val; | |
37430 | time_t last_hit; | |
37431 | - | |
37432 | + | |
37433 | key.dptr = (char *)remote_ip; | |
37434 | key.dsize = strlen(remote_ip); | |
37435 | - | |
37436 | + | |
37437 | val = gdbm_fetch(p->conf.db, key); | |
37438 | - | |
37439 | + | |
37440 | if (val.dptr == NULL) { | |
37441 | /* not found, redirect */ | |
37442 | - | |
37443 | + | |
37444 | response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); | |
37445 | - | |
37446 | + | |
37447 | con->http_status = 307; | |
37448 | - | |
37449 | + | |
37450 | return HANDLER_FINISHED; | |
37451 | } | |
37452 | - | |
37453 | + | |
37454 | last_hit = *(time_t *)(val.dptr); | |
37455 | - | |
37456 | + | |
37457 | free(val.dptr); | |
37458 | - | |
37459 | + | |
37460 | if (srv->cur_ts - last_hit > p->conf.trigger_timeout) { | |
37461 | /* found, but timeout, redirect */ | |
37462 | - | |
37463 | + | |
37464 | response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); | |
37465 | con->http_status = 307; | |
37466 | - | |
37467 | + | |
37468 | if (p->conf.db) { | |
37469 | if (0 != gdbm_delete(p->conf.db, key)) { | |
37470 | log_error_write(srv, __FILE__, __LINE__, "s", | |
37471 | "delete failed"); | |
37472 | } | |
37473 | } | |
37474 | - | |
37475 | + | |
37476 | return HANDLER_FINISHED; | |
37477 | } | |
37478 | - | |
37479 | + | |
37480 | val.dptr = (char *)&(srv->cur_ts); | |
37481 | val.dsize = sizeof(srv->cur_ts); | |
37482 | - | |
37483 | + | |
37484 | if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) { | |
37485 | log_error_write(srv, __FILE__, __LINE__, "s", | |
37486 | "insert failed"); | |
37487 | } | |
37488 | } | |
37489 | # endif | |
37490 | - | |
37491 | -# if defined(HAVE_MEMCACHE_H) | |
37492 | + | |
37493 | +# if defined(HAVE_MEMCACHE_H) | |
37494 | if (p->conf.mc) { | |
37495 | void *r; | |
37496 | size_t i; | |
37497 | - | |
37498 | + | |
37499 | buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace); | |
37500 | buffer_append_string(p->tmp_buf, remote_ip); | |
37501 | - | |
37502 | + | |
37503 | for (i = 0; i < p->tmp_buf->used - 1; i++) { | |
37504 | if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; | |
37505 | } | |
37506 | - | |
37507 | + | |
37508 | if (p->conf.debug) { | |
37509 | log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) checking IP:", p->tmp_buf); | |
37510 | } | |
37511 | ||
37512 | /** | |
37513 | - * | |
37514 | + * | |
37515 | * memcached is do expiration for us, as long as we can fetch it every thing is ok | |
37516 | - * and the timestamp is updated | |
37517 | - * | |
37518 | + * and the timestamp is updated | |
37519 | + * | |
37520 | */ | |
37521 | - if (NULL == (r = mc_aget(p->conf.mc, | |
37522 | + if (NULL == (r = mc_aget(p->conf.mc, | |
37523 | CONST_BUF_LEN(p->tmp_buf) | |
37524 | ))) { | |
37525 | - | |
37526 | + | |
37527 | response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); | |
37528 | - | |
37529 | + | |
37530 | con->http_status = 307; | |
37531 | - | |
37532 | + | |
37533 | return HANDLER_FINISHED; | |
37534 | } | |
37535 | - | |
37536 | + | |
37537 | free(r); | |
37538 | - | |
37539 | + | |
37540 | /* set a new timeout */ | |
37541 | - if (0 != mc_set(p->conf.mc, | |
37542 | + if (0 != mc_set(p->conf.mc, | |
37543 | CONST_BUF_LEN(p->tmp_buf), | |
37544 | (char *)&(srv->cur_ts), sizeof(srv->cur_ts), | |
37545 | p->conf.trigger_timeout, 0)) { | |
37546 | @@ -507,13 +504,13 @@ | |
37547 | } | |
37548 | # endif | |
37549 | } | |
37550 | - | |
37551 | + | |
37552 | #else | |
37553 | UNUSED(srv); | |
37554 | UNUSED(con); | |
37555 | UNUSED(p_d); | |
37556 | #endif | |
37557 | - | |
37558 | + | |
37559 | return HANDLER_GO_ON; | |
37560 | } | |
37561 | ||
37562 | @@ -521,21 +518,21 @@ | |
37563 | TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) { | |
37564 | plugin_data *p = p_d; | |
37565 | size_t i; | |
37566 | - | |
37567 | + | |
37568 | /* check DB each minute */ | |
37569 | if (srv->cur_ts % 60 != 0) return HANDLER_GO_ON; | |
37570 | - | |
37571 | + | |
37572 | /* cleanup */ | |
37573 | for (i = 0; i < srv->config_context->used; i++) { | |
37574 | plugin_config *s = p->config_storage[i]; | |
37575 | datum key, val, okey; | |
37576 | - | |
37577 | + | |
37578 | if (!s->db) continue; | |
37579 | - | |
37580 | + | |
37581 | okey.dptr = NULL; | |
37582 | - | |
37583 | - /* according to the manual this loop + delete does delete all entries on its way | |
37584 | - * | |
37585 | + | |
37586 | + /* according to the manual this loop + delete does delete all entries on its way | |
37587 | + * | |
37588 | * we don't care as the next round will remove them. We don't have to perfect here. | |
37589 | */ | |
37590 | for (key = gdbm_firstkey(s->db); key.dptr; key = gdbm_nextkey(s->db, okey)) { | |
37591 | @@ -544,21 +541,21 @@ | |
37592 | free(okey.dptr); | |
37593 | okey.dptr = NULL; | |
37594 | } | |
37595 | - | |
37596 | + | |
37597 | val = gdbm_fetch(s->db, key); | |
37598 | - | |
37599 | + | |
37600 | last_hit = *(time_t *)(val.dptr); | |
37601 | - | |
37602 | + | |
37603 | free(val.dptr); | |
37604 | - | |
37605 | + | |
37606 | if (srv->cur_ts - last_hit > s->trigger_timeout) { | |
37607 | gdbm_delete(s->db, key); | |
37608 | } | |
37609 | - | |
37610 | + | |
37611 | okey = key; | |
37612 | } | |
37613 | if (okey.dptr) free(okey.dptr); | |
37614 | - | |
37615 | + | |
37616 | /* reorg once a day */ | |
37617 | if ((srv->cur_ts % (60 * 60 * 24) != 0)) gdbm_reorganize(s->db); | |
37618 | } | |
37619 | @@ -571,7 +568,7 @@ | |
37620 | int mod_trigger_b4_dl_plugin_init(plugin *p) { | |
37621 | p->version = LIGHTTPD_VERSION_ID; | |
37622 | p->name = buffer_init_string("trigger_b4_dl"); | |
37623 | - | |
37624 | + | |
37625 | p->init = mod_trigger_b4_dl_init; | |
37626 | p->handle_uri_clean = mod_trigger_b4_dl_uri_handler; | |
37627 | p->set_defaults = mod_trigger_b4_dl_set_defaults; | |
37628 | @@ -579,8 +576,8 @@ | |
37629 | p->handle_trigger = mod_trigger_b4_dl_handle_trigger; | |
37630 | #endif | |
37631 | p->cleanup = mod_trigger_b4_dl_free; | |
37632 | - | |
37633 | + | |
37634 | p->data = NULL; | |
37635 | - | |
37636 | + | |
37637 | return 0; | |
37638 | } | |
1175ccec | 37639 | --- ../lighttpd-1.4.11/src/mod_userdir.c 2005-10-28 16:48:28.000000000 +0300 |
36e2a29e | 37640 | +++ lighttpd-1.4.12/src/mod_userdir.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
37641 | @@ -10,6 +10,7 @@ |
37642 | #include "response.h" | |
37643 | ||
37644 | #include "plugin.h" | |
37645 | +#include "sys-files.h" | |
37646 | ||
37647 | #ifdef HAVE_PWD_H | |
37648 | #include <pwd.h> | |
37649 | @@ -25,54 +26,54 @@ | |
37650 | ||
37651 | typedef struct { | |
37652 | PLUGIN_DATA; | |
37653 | - | |
37654 | + | |
37655 | buffer *username; | |
37656 | buffer *temp_path; | |
37657 | - | |
37658 | + | |
37659 | plugin_config **config_storage; | |
37660 | - | |
37661 | - plugin_config conf; | |
37662 | + | |
37663 | + plugin_config conf; | |
37664 | } plugin_data; | |
37665 | ||
37666 | /* init the plugin data */ | |
37667 | INIT_FUNC(mod_userdir_init) { | |
37668 | plugin_data *p; | |
37669 | - | |
37670 | + | |
37671 | p = calloc(1, sizeof(*p)); | |
37672 | - | |
37673 | + | |
37674 | p->username = buffer_init(); | |
37675 | p->temp_path = buffer_init(); | |
37676 | - | |
37677 | + | |
37678 | return p; | |
37679 | } | |
37680 | ||
37681 | /* detroy the plugin data */ | |
37682 | FREE_FUNC(mod_userdir_free) { | |
37683 | plugin_data *p = p_d; | |
37684 | - | |
37685 | + | |
37686 | if (!p) return HANDLER_GO_ON; | |
37687 | - | |
37688 | + | |
37689 | if (p->config_storage) { | |
37690 | size_t i; | |
37691 | - | |
37692 | + | |
37693 | for (i = 0; i < srv->config_context->used; i++) { | |
37694 | plugin_config *s = p->config_storage[i]; | |
37695 | - | |
37696 | + | |
37697 | array_free(s->include_user); | |
37698 | array_free(s->exclude_user); | |
37699 | buffer_free(s->path); | |
37700 | buffer_free(s->basepath); | |
37701 | - | |
37702 | + | |
37703 | free(s); | |
37704 | } | |
37705 | free(p->config_storage); | |
37706 | } | |
37707 | - | |
37708 | + | |
37709 | buffer_free(p->username); | |
37710 | buffer_free(p->temp_path); | |
37711 | - | |
37712 | + | |
37713 | free(p); | |
37714 | - | |
37715 | + | |
37716 | return HANDLER_GO_ON; | |
37717 | } | |
37718 | ||
37719 | @@ -81,81 +82,78 @@ | |
37720 | SETDEFAULTS_FUNC(mod_userdir_set_defaults) { | |
37721 | plugin_data *p = p_d; | |
37722 | size_t i; | |
37723 | - | |
37724 | - config_values_t cv[] = { | |
37725 | + | |
37726 | + config_values_t cv[] = { | |
37727 | { "userdir.path", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
37728 | { "userdir.exclude-user", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
37729 | { "userdir.include-user", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
37730 | { "userdir.basepath", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ | |
37731 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
37732 | }; | |
37733 | - | |
37734 | + | |
37735 | if (!p) return HANDLER_ERROR; | |
37736 | - | |
37737 | + | |
37738 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
37739 | - | |
37740 | + | |
37741 | for (i = 0; i < srv->config_context->used; i++) { | |
37742 | plugin_config *s; | |
37743 | - | |
37744 | + | |
37745 | s = calloc(1, sizeof(plugin_config)); | |
37746 | s->exclude_user = array_init(); | |
37747 | s->include_user = array_init(); | |
37748 | s->path = buffer_init(); | |
37749 | s->basepath = buffer_init(); | |
37750 | - | |
37751 | + | |
37752 | cv[0].destination = s->path; | |
37753 | cv[1].destination = s->exclude_user; | |
37754 | cv[2].destination = s->include_user; | |
37755 | cv[3].destination = s->basepath; | |
37756 | - | |
37757 | + | |
37758 | p->config_storage[i] = s; | |
37759 | - | |
37760 | + | |
37761 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
37762 | return HANDLER_ERROR; | |
37763 | } | |
37764 | } | |
37765 | - | |
37766 | + | |
37767 | return HANDLER_GO_ON; | |
37768 | } | |
37769 | ||
37770 | -#define PATCH(x) \ | |
37771 | - p->conf.x = s->x; | |
37772 | static int mod_userdir_patch_connection(server *srv, connection *con, plugin_data *p) { | |
37773 | size_t i, j; | |
37774 | plugin_config *s = p->config_storage[0]; | |
37775 | - | |
37776 | - PATCH(path); | |
37777 | - PATCH(exclude_user); | |
37778 | - PATCH(include_user); | |
37779 | - PATCH(basepath); | |
37780 | - | |
37781 | + | |
37782 | + PATCH_OPTION(path); | |
37783 | + PATCH_OPTION(exclude_user); | |
37784 | + PATCH_OPTION(include_user); | |
37785 | + PATCH_OPTION(basepath); | |
37786 | + | |
37787 | /* skip the first, the global context */ | |
37788 | for (i = 1; i < srv->config_context->used; i++) { | |
37789 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
37790 | s = p->config_storage[i]; | |
37791 | - | |
37792 | + | |
37793 | /* condition didn't match */ | |
37794 | if (!config_check_cond(srv, con, dc)) continue; | |
37795 | - | |
37796 | + | |
37797 | /* merge config */ | |
37798 | for (j = 0; j < dc->value->used; j++) { | |
37799 | data_unset *du = dc->value->data[j]; | |
37800 | - | |
37801 | + | |
37802 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.path"))) { | |
37803 | - PATCH(path); | |
37804 | + PATCH_OPTION(path); | |
37805 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.exclude-user"))) { | |
37806 | - PATCH(exclude_user); | |
37807 | + PATCH_OPTION(exclude_user); | |
37808 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.include-user"))) { | |
37809 | - PATCH(include_user); | |
37810 | + PATCH_OPTION(include_user); | |
37811 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.basepath"))) { | |
37812 | - PATCH(basepath); | |
37813 | + PATCH_OPTION(basepath); | |
37814 | } | |
37815 | } | |
37816 | } | |
37817 | - | |
37818 | + | |
37819 | return 0; | |
37820 | } | |
37821 | -#undef PATCH | |
37822 | ||
37823 | URIHANDLER_FUNC(mod_userdir_docroot_handler) { | |
37824 | plugin_data *p = p_d; | |
37825 | @@ -169,18 +167,18 @@ | |
37826 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
37827 | ||
37828 | mod_userdir_patch_connection(srv, con, p); | |
37829 | - | |
37830 | + | |
37831 | uri_len = con->uri.path->used - 1; | |
37832 | - | |
37833 | + | |
37834 | /* /~user/foo.html -> /home/user/public_html/foo.html */ | |
37835 | - | |
37836 | + | |
37837 | if (con->uri.path->ptr[0] != '/' || | |
37838 | con->uri.path->ptr[1] != '~') return HANDLER_GO_ON; | |
37839 | - | |
37840 | + | |
37841 | if (NULL == (rel_url = strchr(con->uri.path->ptr + 2, '/'))) { | |
37842 | /* / is missing -> redirect to .../ as we are a user - DIRECTORY ! :) */ | |
37843 | http_response_redirect_to_directory(srv, con); | |
37844 | - | |
37845 | + | |
37846 | return HANDLER_FINISHED; | |
37847 | } | |
37848 | ||
37849 | @@ -188,10 +186,10 @@ | |
37850 | if (0 == rel_url - (con->uri.path->ptr + 2)) { | |
37851 | return HANDLER_GO_ON; | |
37852 | } | |
37853 | - | |
37854 | + | |
37855 | buffer_copy_string_len(p->username, con->uri.path->ptr + 2, rel_url - (con->uri.path->ptr + 2)); | |
37856 | - | |
37857 | - if (buffer_is_empty(p->conf.basepath) | |
37858 | + | |
37859 | + if (buffer_is_empty(p->conf.basepath) | |
37860 | #ifdef HAVE_PWD_H | |
37861 | && NULL == (pwd = getpwnam(p->username->ptr)) | |
37862 | #endif | |
37863 | @@ -200,31 +198,31 @@ | |
37864 | return HANDLER_GO_ON; | |
37865 | } | |
37866 | ||
37867 | - | |
37868 | + | |
37869 | for (k = 0; k < p->conf.exclude_user->used; k++) { | |
37870 | data_string *ds = (data_string *)p->conf.exclude_user->data[k]; | |
37871 | - | |
37872 | + | |
37873 | if (buffer_is_equal(ds->value, p->username)) { | |
37874 | /* user in exclude list */ | |
37875 | return HANDLER_GO_ON; | |
37876 | } | |
37877 | } | |
37878 | - | |
37879 | + | |
37880 | if (p->conf.include_user->used) { | |
37881 | int found_user = 0; | |
37882 | for (k = 0; k < p->conf.include_user->used; k++) { | |
37883 | data_string *ds = (data_string *)p->conf.include_user->data[k]; | |
37884 | - | |
37885 | + | |
37886 | if (buffer_is_equal(ds->value, p->username)) { | |
37887 | /* user in include list */ | |
37888 | found_user = 1; | |
37889 | break; | |
37890 | } | |
37891 | } | |
37892 | - | |
37893 | + | |
37894 | if (!found_user) return HANDLER_GO_ON; | |
37895 | } | |
37896 | - | |
37897 | + | |
37898 | /* we build the physical path */ | |
37899 | ||
37900 | if (buffer_is_empty(p->conf.basepath)) { | |
37901 | @@ -252,23 +250,23 @@ | |
37902 | } | |
37903 | ||
37904 | buffer_copy_string_buffer(p->temp_path, p->conf.basepath); | |
37905 | - BUFFER_APPEND_SLASH(p->temp_path); | |
37906 | + PATHNAME_APPEND_SLASH(p->temp_path); | |
37907 | buffer_append_string_buffer(p->temp_path, p->username); | |
37908 | } | |
37909 | - BUFFER_APPEND_SLASH(p->temp_path); | |
37910 | - buffer_append_string_buffer(p->temp_path, p->conf.path); | |
37911 | + PATHNAME_APPEND_SLASH(p->temp_path); | |
37912 | + buffer_append_string_buffer(p->temp_path, p->conf.path); | |
37913 | ||
37914 | if (buffer_is_empty(p->conf.basepath)) { | |
37915 | struct stat st; | |
37916 | int ret; | |
37917 | - | |
37918 | + | |
37919 | ret = stat(p->temp_path->ptr, &st); | |
37920 | if (ret < 0 || S_ISDIR(st.st_mode) != 1) { | |
37921 | return HANDLER_GO_ON; | |
37922 | - } | |
37923 | + } | |
37924 | } | |
37925 | ||
37926 | - BUFFER_APPEND_SLASH(p->temp_path); | |
37927 | + PATHNAME_APPEND_SLASH(p->temp_path); | |
37928 | buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */ | |
37929 | buffer_copy_string_buffer(con->physical.path, p->temp_path); | |
37930 | ||
37931 | @@ -282,13 +280,13 @@ | |
37932 | int mod_userdir_plugin_init(plugin *p) { | |
37933 | p->version = LIGHTTPD_VERSION_ID; | |
37934 | p->name = buffer_init_string("userdir"); | |
37935 | - | |
37936 | + | |
37937 | p->init = mod_userdir_init; | |
37938 | p->handle_physical = mod_userdir_docroot_handler; | |
37939 | p->set_defaults = mod_userdir_set_defaults; | |
37940 | p->cleanup = mod_userdir_free; | |
37941 | - | |
37942 | + | |
37943 | p->data = NULL; | |
37944 | - | |
37945 | + | |
37946 | return 0; | |
37947 | } | |
1175ccec | 37948 | --- ../lighttpd-1.4.11/src/mod_usertrack.c 2006-01-31 15:01:20.000000000 +0200 |
36e2a29e | 37949 | +++ lighttpd-1.4.12/src/mod_usertrack.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
37950 | @@ -24,44 +24,44 @@ |
37951 | ||
37952 | typedef struct { | |
37953 | PLUGIN_DATA; | |
37954 | - | |
37955 | + | |
37956 | plugin_config **config_storage; | |
37957 | - | |
37958 | - plugin_config conf; | |
37959 | + | |
37960 | + plugin_config conf; | |
37961 | } plugin_data; | |
37962 | ||
37963 | /* init the plugin data */ | |
37964 | INIT_FUNC(mod_usertrack_init) { | |
37965 | plugin_data *p; | |
37966 | - | |
37967 | + | |
37968 | p = calloc(1, sizeof(*p)); | |
37969 | - | |
37970 | + | |
37971 | return p; | |
37972 | } | |
37973 | ||
37974 | /* detroy the plugin data */ | |
37975 | FREE_FUNC(mod_usertrack_free) { | |
37976 | plugin_data *p = p_d; | |
37977 | - | |
37978 | + | |
37979 | UNUSED(srv); | |
37980 | - | |
37981 | + | |
37982 | if (!p) return HANDLER_GO_ON; | |
37983 | - | |
37984 | + | |
37985 | if (p->config_storage) { | |
37986 | size_t i; | |
37987 | for (i = 0; i < srv->config_context->used; i++) { | |
37988 | plugin_config *s = p->config_storage[i]; | |
37989 | - | |
37990 | + | |
37991 | buffer_free(s->cookie_name); | |
37992 | buffer_free(s->cookie_domain); | |
37993 | - | |
37994 | + | |
37995 | free(s); | |
37996 | } | |
37997 | free(p->config_storage); | |
37998 | } | |
37999 | - | |
38000 | + | |
38001 | free(p); | |
38002 | - | |
38003 | + | |
38004 | return HANDLER_GO_ON; | |
38005 | } | |
38006 | ||
38007 | @@ -70,38 +70,38 @@ | |
38008 | SETDEFAULTS_FUNC(mod_usertrack_set_defaults) { | |
38009 | plugin_data *p = p_d; | |
38010 | size_t i = 0; | |
38011 | - | |
38012 | - config_values_t cv[] = { | |
38013 | + | |
38014 | + config_values_t cv[] = { | |
38015 | { "usertrack.cookie-name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
38016 | { "usertrack.cookie-max-age", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
38017 | { "usertrack.cookie-domain", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
38018 | - | |
38019 | - { "usertrack.cookiename", NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION }, | |
38020 | + | |
38021 | + { "usertrack.cookiename", NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION }, | |
38022 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
38023 | }; | |
38024 | - | |
38025 | + | |
38026 | if (!p) return HANDLER_ERROR; | |
38027 | - | |
38028 | + | |
38029 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
38030 | - | |
38031 | + | |
38032 | for (i = 0; i < srv->config_context->used; i++) { | |
38033 | plugin_config *s; | |
38034 | - | |
38035 | + | |
38036 | s = calloc(1, sizeof(plugin_config)); | |
38037 | s->cookie_name = buffer_init(); | |
38038 | s->cookie_domain = buffer_init(); | |
38039 | s->cookie_max_age = 0; | |
38040 | - | |
38041 | + | |
38042 | cv[0].destination = s->cookie_name; | |
38043 | cv[1].destination = &(s->cookie_max_age); | |
38044 | cv[2].destination = s->cookie_domain; | |
38045 | - | |
38046 | + | |
38047 | p->config_storage[i] = s; | |
38048 | - | |
38049 | + | |
38050 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
38051 | return HANDLER_ERROR; | |
38052 | } | |
38053 | - | |
38054 | + | |
38055 | if (buffer_is_empty(s->cookie_name)) { | |
38056 | buffer_copy_string(s->cookie_name, "TRACKID"); | |
38057 | } else { | |
38058 | @@ -109,68 +109,65 @@ | |
38059 | for (j = 0; j < s->cookie_name->used - 1; j++) { | |
38060 | char c = s->cookie_name->ptr[j] | 32; | |
38061 | if (c < 'a' || c > 'z') { | |
38062 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
38063 | - "invalid character in usertrack.cookie-name:", | |
38064 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
38065 | + "invalid character in usertrack.cookie-name:", | |
38066 | s->cookie_name); | |
38067 | - | |
38068 | + | |
38069 | return HANDLER_ERROR; | |
38070 | } | |
38071 | } | |
38072 | } | |
38073 | - | |
38074 | + | |
38075 | if (!buffer_is_empty(s->cookie_domain)) { | |
38076 | size_t j; | |
38077 | for (j = 0; j < s->cookie_domain->used - 1; j++) { | |
38078 | char c = s->cookie_domain->ptr[j]; | |
38079 | if (c <= 32 || c >= 127 || c == '"' || c == '\\') { | |
38080 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
38081 | - "invalid character in usertrack.cookie-domain:", | |
38082 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
38083 | + "invalid character in usertrack.cookie-domain:", | |
38084 | s->cookie_domain); | |
38085 | - | |
38086 | + | |
38087 | return HANDLER_ERROR; | |
38088 | } | |
38089 | } | |
38090 | } | |
38091 | } | |
38092 | - | |
38093 | + | |
38094 | return HANDLER_GO_ON; | |
38095 | } | |
38096 | ||
38097 | -#define PATCH(x) \ | |
38098 | - p->conf.x = s->x; | |
38099 | static int mod_usertrack_patch_connection(server *srv, connection *con, plugin_data *p) { | |
38100 | size_t i, j; | |
38101 | plugin_config *s = p->config_storage[0]; | |
38102 | - | |
38103 | - PATCH(cookie_name); | |
38104 | - PATCH(cookie_domain); | |
38105 | - PATCH(cookie_max_age); | |
38106 | - | |
38107 | + | |
38108 | + PATCH_OPTION(cookie_name); | |
38109 | + PATCH_OPTION(cookie_domain); | |
38110 | + PATCH_OPTION(cookie_max_age); | |
38111 | + | |
38112 | /* skip the first, the global context */ | |
38113 | for (i = 1; i < srv->config_context->used; i++) { | |
38114 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
38115 | s = p->config_storage[i]; | |
38116 | - | |
38117 | + | |
38118 | /* condition didn't match */ | |
38119 | if (!config_check_cond(srv, con, dc)) continue; | |
38120 | - | |
38121 | + | |
38122 | /* merge config */ | |
38123 | for (j = 0; j < dc->value->used; j++) { | |
38124 | data_unset *du = dc->value->data[j]; | |
38125 | - | |
38126 | + | |
38127 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-name"))) { | |
38128 | - PATCH(cookie_name); | |
38129 | + PATCH_OPTION(cookie_name); | |
38130 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-max-age"))) { | |
38131 | - PATCH(cookie_max_age); | |
38132 | + PATCH_OPTION(cookie_max_age); | |
38133 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-domain"))) { | |
38134 | - PATCH(cookie_domain); | |
38135 | + PATCH_OPTION(cookie_domain); | |
38136 | } | |
38137 | } | |
38138 | } | |
38139 | - | |
38140 | + | |
38141 | return 0; | |
38142 | } | |
38143 | -#undef PATCH | |
38144 | ||
38145 | URIHANDLER_FUNC(mod_usertrack_uri_handler) { | |
38146 | plugin_data *p = p_d; | |
38147 | @@ -178,38 +175,38 @@ | |
38148 | unsigned char h[16]; | |
38149 | MD5_CTX Md5Ctx; | |
38150 | char hh[32]; | |
38151 | - | |
38152 | + | |
38153 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
38154 | - | |
38155 | + | |
38156 | mod_usertrack_patch_connection(srv, con, p); | |
38157 | - | |
38158 | + | |
38159 | if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) { | |
38160 | char *g; | |
38161 | /* we have a cookie, does it contain a valid name ? */ | |
38162 | - | |
38163 | - /* parse the cookie | |
38164 | - * | |
38165 | + | |
38166 | + /* parse the cookie | |
38167 | + * | |
38168 | * check for cookiename + (WS | '=') | |
38169 | - * | |
38170 | + * | |
38171 | */ | |
38172 | - | |
38173 | + | |
38174 | if (NULL != (g = strstr(ds->value->ptr, p->conf.cookie_name->ptr))) { | |
38175 | char *nc; | |
38176 | - | |
38177 | + | |
38178 | /* skip WS */ | |
38179 | for (nc = g + p->conf.cookie_name->used-1; *nc == ' ' || *nc == '\t'; nc++); | |
38180 | - | |
38181 | + | |
38182 | if (*nc == '=') { | |
38183 | /* ok, found the key of our own cookie */ | |
38184 | - | |
38185 | + | |
38186 | if (strlen(nc) > 32) { | |
38187 | /* i'm lazy */ | |
38188 | return HANDLER_GO_ON; | |
38189 | } | |
38190 | } | |
38191 | } | |
38192 | - } | |
38193 | - | |
38194 | + } | |
38195 | + | |
38196 | /* set a cookie */ | |
38197 | if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { | |
38198 | ds = data_response_init(); | |
38199 | @@ -217,39 +214,39 @@ | |
38200 | buffer_copy_string(ds->key, "Set-Cookie"); | |
38201 | buffer_copy_string_buffer(ds->value, p->conf.cookie_name); | |
38202 | buffer_append_string(ds->value, "="); | |
38203 | - | |
38204 | + | |
38205 | ||
38206 | /* taken from mod_auth.c */ | |
38207 | - | |
38208 | + | |
38209 | /* generate shared-secret */ | |
38210 | MD5_Init(&Md5Ctx); | |
38211 | MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1); | |
38212 | MD5_Update(&Md5Ctx, (unsigned char *)"+", 1); | |
38213 | - | |
38214 | + | |
38215 | /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */ | |
38216 | ltostr(hh, srv->cur_ts); | |
38217 | MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); | |
38218 | ltostr(hh, rand()); | |
38219 | MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); | |
38220 | - | |
38221 | + | |
38222 | MD5_Final(h, &Md5Ctx); | |
38223 | - | |
38224 | + | |
38225 | buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX); | |
38226 | buffer_append_string(ds->value, "; Path=/"); | |
38227 | buffer_append_string(ds->value, "; Version=1"); | |
38228 | - | |
38229 | + | |
38230 | if (!buffer_is_empty(p->conf.cookie_domain)) { | |
38231 | buffer_append_string(ds->value, "; Domain="); | |
38232 | buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI); | |
38233 | } | |
38234 | - | |
38235 | + | |
38236 | if (p->conf.cookie_max_age) { | |
38237 | buffer_append_string(ds->value, "; max-age="); | |
38238 | buffer_append_long(ds->value, p->conf.cookie_max_age); | |
38239 | } | |
38240 | - | |
38241 | + | |
38242 | array_insert_unique(con->response.headers, (data_unset *)ds); | |
38243 | - | |
38244 | + | |
38245 | return HANDLER_GO_ON; | |
38246 | } | |
38247 | ||
38248 | @@ -258,13 +255,13 @@ | |
38249 | int mod_usertrack_plugin_init(plugin *p) { | |
38250 | p->version = LIGHTTPD_VERSION_ID; | |
38251 | p->name = buffer_init_string("usertrack"); | |
38252 | - | |
38253 | + | |
38254 | p->init = mod_usertrack_init; | |
38255 | p->handle_uri_clean = mod_usertrack_uri_handler; | |
38256 | p->set_defaults = mod_usertrack_set_defaults; | |
38257 | p->cleanup = mod_usertrack_free; | |
38258 | - | |
38259 | + | |
38260 | p->data = NULL; | |
38261 | - | |
38262 | + | |
38263 | return 0; | |
38264 | } | |
1175ccec | 38265 | --- ../lighttpd-1.4.11/src/mod_webdav.c 2006-03-03 01:28:58.000000000 +0200 |
36e2a29e | 38266 | +++ lighttpd-1.4.12/src/mod_webdav.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
38267 | @@ -3,13 +3,10 @@ |
38268 | #include <ctype.h> | |
38269 | #include <stdlib.h> | |
38270 | #include <string.h> | |
38271 | -#include <dirent.h> | |
38272 | #include <errno.h> | |
38273 | -#include <unistd.h> | |
38274 | #include <fcntl.h> | |
38275 | #include <stdio.h> | |
38276 | #include <assert.h> | |
38277 | -#include <sys/mman.h> | |
38278 | ||
38279 | #ifdef HAVE_CONFIG_H | |
38280 | #include "config.h" | |
38281 | @@ -23,6 +20,11 @@ | |
38282 | #include <sqlite3.h> | |
38283 | #endif | |
38284 | ||
38285 | +#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H) && defined(HAVE_UUID_H) | |
38286 | +#define USE_LOCKS | |
38287 | +#include <uuid/uuid.h> | |
38288 | +#endif | |
38289 | + | |
38290 | #include "base.h" | |
38291 | #include "log.h" | |
38292 | #include "buffer.h" | |
38293 | @@ -33,13 +35,16 @@ | |
38294 | #include "stream.h" | |
38295 | #include "stat_cache.h" | |
38296 | ||
38297 | +#include "sys-files.h" | |
38298 | +#include "sys-mmap.h" | |
38299 | +#include "sys-strings.h" | |
38300 | ||
38301 | /** | |
38302 | * this is a webdav for a lighttpd plugin | |
38303 | * | |
38304 | - * at least a very basic one. | |
38305 | + * at least a very basic one. | |
38306 | * - for now it is read-only and we only support PROPFIND | |
38307 | - * | |
38308 | + * | |
38309 | */ | |
38310 | ||
38311 | ||
38312 | @@ -58,64 +63,70 @@ | |
38313 | sqlite3_stmt *stmt_delete_prop; | |
38314 | sqlite3_stmt *stmt_select_prop; | |
38315 | sqlite3_stmt *stmt_select_propnames; | |
38316 | - | |
38317 | + | |
38318 | sqlite3_stmt *stmt_delete_uri; | |
38319 | sqlite3_stmt *stmt_move_uri; | |
38320 | sqlite3_stmt *stmt_copy_uri; | |
38321 | + | |
38322 | + sqlite3_stmt *stmt_remove_lock; | |
38323 | + sqlite3_stmt *stmt_create_lock; | |
38324 | + sqlite3_stmt *stmt_read_lock; | |
38325 | + sqlite3_stmt *stmt_read_lock_by_uri; | |
38326 | + sqlite3_stmt *stmt_refresh_lock; | |
38327 | #endif | |
38328 | } plugin_config; | |
38329 | ||
38330 | typedef struct { | |
38331 | PLUGIN_DATA; | |
38332 | - | |
38333 | + | |
38334 | buffer *tmp_buf; | |
38335 | request_uri uri; | |
38336 | physical physical; | |
38337 | ||
38338 | plugin_config **config_storage; | |
38339 | - | |
38340 | - plugin_config conf; | |
38341 | + | |
38342 | + plugin_config conf; | |
38343 | } plugin_data; | |
38344 | ||
38345 | /* init the plugin data */ | |
38346 | INIT_FUNC(mod_webdav_init) { | |
38347 | plugin_data *p; | |
38348 | - | |
38349 | + | |
38350 | p = calloc(1, sizeof(*p)); | |
38351 | - | |
38352 | + | |
38353 | p->tmp_buf = buffer_init(); | |
38354 | ||
38355 | p->uri.scheme = buffer_init(); | |
38356 | p->uri.path_raw = buffer_init(); | |
38357 | p->uri.path = buffer_init(); | |
38358 | p->uri.authority = buffer_init(); | |
38359 | - | |
38360 | + | |
38361 | p->physical.path = buffer_init(); | |
38362 | p->physical.rel_path = buffer_init(); | |
38363 | p->physical.doc_root = buffer_init(); | |
38364 | p->physical.basedir = buffer_init(); | |
38365 | - | |
38366 | + | |
38367 | return p; | |
38368 | } | |
38369 | ||
38370 | /* detroy the plugin data */ | |
38371 | FREE_FUNC(mod_webdav_free) { | |
38372 | plugin_data *p = p_d; | |
38373 | - | |
38374 | + | |
38375 | UNUSED(srv); | |
38376 | ||
38377 | if (!p) return HANDLER_GO_ON; | |
38378 | - | |
38379 | + | |
38380 | if (p->config_storage) { | |
38381 | size_t i; | |
38382 | for (i = 0; i < srv->config_context->used; i++) { | |
38383 | plugin_config *s = p->config_storage[i]; | |
38384 | ||
38385 | if (!s) continue; | |
38386 | - | |
38387 | + | |
38388 | buffer_free(s->sqlite_db_name); | |
38389 | #ifdef USE_PROPPATCH | |
38390 | - if (s->sql) { | |
38391 | + if (s->sql) { | |
38392 | sqlite3_finalize(s->stmt_delete_prop); | |
38393 | sqlite3_finalize(s->stmt_delete_uri); | |
38394 | sqlite3_finalize(s->stmt_copy_uri); | |
38395 | @@ -123,9 +134,15 @@ | |
38396 | sqlite3_finalize(s->stmt_update_prop); | |
38397 | sqlite3_finalize(s->stmt_select_prop); | |
38398 | sqlite3_finalize(s->stmt_select_propnames); | |
38399 | + | |
38400 | + sqlite3_finalize(s->stmt_read_lock); | |
38401 | + sqlite3_finalize(s->stmt_read_lock_by_uri); | |
38402 | + sqlite3_finalize(s->stmt_create_lock); | |
38403 | + sqlite3_finalize(s->stmt_remove_lock); | |
38404 | + sqlite3_finalize(s->stmt_refresh_lock); | |
38405 | sqlite3_close(s->sql); | |
38406 | } | |
38407 | -#endif | |
38408 | +#endif | |
38409 | free(s); | |
38410 | } | |
38411 | free(p->config_storage); | |
38412 | @@ -135,16 +152,16 @@ | |
38413 | buffer_free(p->uri.path_raw); | |
38414 | buffer_free(p->uri.path); | |
38415 | buffer_free(p->uri.authority); | |
38416 | - | |
38417 | + | |
38418 | buffer_free(p->physical.path); | |
38419 | buffer_free(p->physical.rel_path); | |
38420 | buffer_free(p->physical.doc_root); | |
38421 | buffer_free(p->physical.basedir); | |
38422 | - | |
38423 | + | |
38424 | buffer_free(p->tmp_buf); | |
38425 | - | |
38426 | + | |
38427 | free(p); | |
38428 | - | |
38429 | + | |
38430 | return HANDLER_GO_ON; | |
38431 | } | |
38432 | ||
38433 | @@ -153,32 +170,32 @@ | |
38434 | SETDEFAULTS_FUNC(mod_webdav_set_defaults) { | |
38435 | plugin_data *p = p_d; | |
38436 | size_t i = 0; | |
38437 | - | |
38438 | - config_values_t cv[] = { | |
38439 | + | |
38440 | + config_values_t cv[] = { | |
38441 | { "webdav.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ | |
38442 | { "webdav.is-readonly", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ | |
38443 | { "webdav.sqlite-db-name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ | |
38444 | { "webdav.log-xml", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ | |
38445 | { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } | |
38446 | }; | |
38447 | - | |
38448 | + | |
38449 | if (!p) return HANDLER_ERROR; | |
38450 | - | |
38451 | + | |
38452 | p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); | |
38453 | - | |
38454 | + | |
38455 | for (i = 0; i < srv->config_context->used; i++) { | |
38456 | plugin_config *s; | |
38457 | - | |
38458 | + | |
38459 | s = calloc(1, sizeof(plugin_config)); | |
38460 | s->sqlite_db_name = buffer_init(); | |
38461 | - | |
38462 | + | |
38463 | cv[0].destination = &(s->enabled); | |
38464 | cv[1].destination = &(s->is_readonly); | |
38465 | cv[2].destination = s->sqlite_db_name; | |
38466 | cv[3].destination = &(s->log_xml); | |
38467 | - | |
38468 | + | |
38469 | p->config_storage[i] = s; | |
38470 | - | |
38471 | + | |
38472 | if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | |
38473 | return HANDLER_ERROR; | |
38474 | } | |
38475 | @@ -193,8 +210,26 @@ | |
38476 | return HANDLER_ERROR; | |
38477 | } | |
38478 | ||
38479 | - if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38480 | - CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), | |
38481 | + if (SQLITE_OK != sqlite3_exec(s->sql, | |
38482 | + "CREATE TABLE properties (" | |
38483 | + " resource TEXT NOT NULL," | |
38484 | + " prop TEXT NOT NULL," | |
38485 | + " ns TEXT NOT NULL," | |
38486 | + " value TEXT NOT NULL," | |
38487 | + " PRIMARY KEY(resource, prop, ns))", | |
38488 | + NULL, NULL, &err)) { | |
38489 | + | |
38490 | + if (0 != strcmp(err, "table properties already exists")) { | |
38491 | + log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err); | |
38492 | + sqlite3_free(err); | |
38493 | + | |
38494 | + return HANDLER_ERROR; | |
38495 | + } | |
38496 | + sqlite3_free(err); | |
38497 | + } | |
38498 | + | |
38499 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38500 | + CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), | |
38501 | &(s->stmt_select_prop), &next_stmt)) { | |
38502 | /* prepare failed */ | |
38503 | ||
38504 | @@ -202,8 +237,8 @@ | |
38505 | return HANDLER_ERROR; | |
38506 | } | |
38507 | ||
38508 | - if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38509 | - CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"), | |
38510 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38511 | + CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"), | |
38512 | &(s->stmt_select_propnames), &next_stmt)) { | |
38513 | /* prepare failed */ | |
38514 | ||
38515 | @@ -211,16 +246,67 @@ | |
38516 | return HANDLER_ERROR; | |
38517 | } | |
38518 | ||
38519 | - if (SQLITE_OK != sqlite3_exec(s->sql, | |
38520 | - "CREATE TABLE properties (" | |
38521 | + | |
38522 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38523 | + CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"), | |
38524 | + &(s->stmt_update_prop), &next_stmt)) { | |
38525 | + /* prepare failed */ | |
38526 | + | |
38527 | + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql)); | |
38528 | + return HANDLER_ERROR; | |
38529 | + } | |
38530 | + | |
38531 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38532 | + CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), | |
38533 | + &(s->stmt_delete_prop), &next_stmt)) { | |
38534 | + /* prepare failed */ | |
38535 | + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38536 | + | |
38537 | + return HANDLER_ERROR; | |
38538 | + } | |
38539 | + | |
38540 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38541 | + CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"), | |
38542 | + &(s->stmt_delete_uri), &next_stmt)) { | |
38543 | + /* prepare failed */ | |
38544 | + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38545 | + | |
38546 | + return HANDLER_ERROR; | |
38547 | + } | |
38548 | + | |
38549 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38550 | + CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"), | |
38551 | + &(s->stmt_copy_uri), &next_stmt)) { | |
38552 | + /* prepare failed */ | |
38553 | + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38554 | + | |
38555 | + return HANDLER_ERROR; | |
38556 | + } | |
38557 | + | |
38558 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38559 | + CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"), | |
38560 | + &(s->stmt_move_uri), &next_stmt)) { | |
38561 | + /* prepare failed */ | |
38562 | + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38563 | + | |
38564 | + return HANDLER_ERROR; | |
38565 | + } | |
38566 | + | |
38567 | + /* LOCKS */ | |
38568 | + | |
38569 | + if (SQLITE_OK != sqlite3_exec(s->sql, | |
38570 | + "CREATE TABLE locks (" | |
38571 | + " locktoken TEXT NOT NULL," | |
38572 | " resource TEXT NOT NULL," | |
38573 | - " prop TEXT NOT NULL," | |
38574 | - " ns TEXT NOT NULL," | |
38575 | - " value TEXT NOT NULL," | |
38576 | - " PRIMARY KEY(resource, prop, ns))", | |
38577 | + " lockscope TEXT NOT NULL," | |
38578 | + " locktype TEXT NOT NULL," | |
38579 | + " owner TEXT NOT NULL," | |
38580 | + " depth INT NOT NULL," | |
38581 | + " timeout TIMESTAMP NOT NULL," | |
38582 | + " PRIMARY KEY(locktoken))", | |
38583 | NULL, NULL, &err)) { | |
38584 | ||
38585 | - if (0 != strcmp(err, "table properties already exists")) { | |
38586 | + if (0 != strcmp(err, "table locks already exists")) { | |
38587 | log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err); | |
38588 | sqlite3_free(err); | |
38589 | ||
38590 | @@ -228,127 +314,138 @@ | |
38591 | } | |
38592 | sqlite3_free(err); | |
38593 | } | |
38594 | - | |
38595 | - if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38596 | - CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"), | |
38597 | - &(s->stmt_update_prop), &next_stmt)) { | |
38598 | + | |
38599 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38600 | + CONST_STR_LEN("INSERT INTO locks (locktoken, resource, lockscope, locktype, owner, depth, timeout) VALUES (?,?,?,?,?,?, CURRENT_TIME + 600)"), | |
38601 | + &(s->stmt_create_lock), &next_stmt)) { | |
38602 | /* prepare failed */ | |
38603 | + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38604 | ||
38605 | - log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql)); | |
38606 | return HANDLER_ERROR; | |
38607 | } | |
38608 | ||
38609 | - if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38610 | - CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), | |
38611 | - &(s->stmt_delete_prop), &next_stmt)) { | |
38612 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38613 | + CONST_STR_LEN("DELETE FROM locks WHERE locktoken = ?"), | |
38614 | + &(s->stmt_remove_lock), &next_stmt)) { | |
38615 | /* prepare failed */ | |
38616 | log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38617 | ||
38618 | return HANDLER_ERROR; | |
38619 | } | |
38620 | ||
38621 | - if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38622 | - CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"), | |
38623 | - &(s->stmt_delete_uri), &next_stmt)) { | |
38624 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38625 | + CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE locktoken = ?"), | |
38626 | + &(s->stmt_read_lock), &next_stmt)) { | |
38627 | /* prepare failed */ | |
38628 | log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38629 | ||
38630 | return HANDLER_ERROR; | |
38631 | } | |
38632 | ||
38633 | - if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38634 | - CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"), | |
38635 | - &(s->stmt_copy_uri), &next_stmt)) { | |
38636 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38637 | + CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE resource = ?"), | |
38638 | + &(s->stmt_read_lock_by_uri), &next_stmt)) { | |
38639 | /* prepare failed */ | |
38640 | log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38641 | ||
38642 | return HANDLER_ERROR; | |
38643 | } | |
38644 | ||
38645 | - if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38646 | - CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"), | |
38647 | - &(s->stmt_move_uri), &next_stmt)) { | |
38648 | + if (SQLITE_OK != sqlite3_prepare(s->sql, | |
38649 | + CONST_STR_LEN("UPDATE locks SET timeout = CURRENT_TIME + 600 WHERE locktoken = ?"), | |
38650 | + &(s->stmt_refresh_lock), &next_stmt)) { | |
38651 | /* prepare failed */ | |
38652 | log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql)); | |
38653 | ||
38654 | return HANDLER_ERROR; | |
38655 | } | |
38656 | + | |
38657 | + | |
38658 | #else | |
38659 | log_error_write(srv, __FILE__, __LINE__, "s", "Sorry, no sqlite3 and libxml2 support include, compile with --with-webdav-props"); | |
38660 | return HANDLER_ERROR; | |
38661 | #endif | |
38662 | } | |
38663 | } | |
38664 | - | |
38665 | + | |
38666 | return HANDLER_GO_ON; | |
38667 | } | |
38668 | ||
38669 | -#define PATCH(x) \ | |
38670 | - p->conf.x = s->x; | |
38671 | static int mod_webdav_patch_connection(server *srv, connection *con, plugin_data *p) { | |
38672 | size_t i, j; | |
38673 | plugin_config *s = p->config_storage[0]; | |
38674 | - | |
38675 | - PATCH(enabled); | |
38676 | - PATCH(is_readonly); | |
38677 | - PATCH(log_xml); | |
38678 | - | |
38679 | + | |
38680 | + PATCH_OPTION(enabled); | |
38681 | + PATCH_OPTION(is_readonly); | |
38682 | + PATCH_OPTION(log_xml); | |
38683 | + | |
38684 | #ifdef USE_PROPPATCH | |
38685 | - PATCH(sql); | |
38686 | - PATCH(stmt_update_prop); | |
38687 | - PATCH(stmt_delete_prop); | |
38688 | - PATCH(stmt_select_prop); | |
38689 | - PATCH(stmt_select_propnames); | |
38690 | - | |
38691 | - PATCH(stmt_delete_uri); | |
38692 | - PATCH(stmt_move_uri); | |
38693 | - PATCH(stmt_copy_uri); | |
38694 | + PATCH_OPTION(sql); | |
38695 | + PATCH_OPTION(stmt_update_prop); | |
38696 | + PATCH_OPTION(stmt_delete_prop); | |
38697 | + PATCH_OPTION(stmt_select_prop); | |
38698 | + PATCH_OPTION(stmt_select_propnames); | |
38699 | + | |
38700 | + PATCH_OPTION(stmt_delete_uri); | |
38701 | + PATCH_OPTION(stmt_move_uri); | |
38702 | + PATCH_OPTION(stmt_copy_uri); | |
38703 | + | |
38704 | + PATCH_OPTION(stmt_remove_lock); | |
38705 | + PATCH_OPTION(stmt_refresh_lock); | |
38706 | + PATCH_OPTION(stmt_create_lock); | |
38707 | + PATCH_OPTION(stmt_read_lock); | |
38708 | + PATCH_OPTION(stmt_read_lock_by_uri); | |
38709 | #endif | |
38710 | /* skip the first, the global context */ | |
38711 | for (i = 1; i < srv->config_context->used; i++) { | |
38712 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
38713 | s = p->config_storage[i]; | |
38714 | - | |
38715 | + | |
38716 | /* condition didn't match */ | |
38717 | if (!config_check_cond(srv, con, dc)) continue; | |
38718 | - | |
38719 | + | |
38720 | /* merge config */ | |
38721 | for (j = 0; j < dc->value->used; j++) { | |
38722 | data_unset *du = dc->value->data[j]; | |
38723 | - | |
38724 | + | |
38725 | if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.activate"))) { | |
38726 | - PATCH(enabled); | |
38727 | + PATCH_OPTION(enabled); | |
38728 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.is-readonly"))) { | |
38729 | - PATCH(is_readonly); | |
38730 | + PATCH_OPTION(is_readonly); | |
38731 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.log-xml"))) { | |
38732 | - PATCH(log_xml); | |
38733 | + PATCH_OPTION(log_xml); | |
38734 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.sqlite-db-name"))) { | |
38735 | #ifdef USE_PROPPATCH | |
38736 | - PATCH(sql); | |
38737 | - PATCH(stmt_update_prop); | |
38738 | - PATCH(stmt_delete_prop); | |
38739 | - PATCH(stmt_select_prop); | |
38740 | - PATCH(stmt_select_propnames); | |
38741 | - | |
38742 | - PATCH(stmt_delete_uri); | |
38743 | - PATCH(stmt_move_uri); | |
38744 | - PATCH(stmt_copy_uri); | |
38745 | + PATCH_OPTION(sql); | |
38746 | + PATCH_OPTION(stmt_update_prop); | |
38747 | + PATCH_OPTION(stmt_delete_prop); | |
38748 | + PATCH_OPTION(stmt_select_prop); | |
38749 | + PATCH_OPTION(stmt_select_propnames); | |
38750 | + | |
38751 | + PATCH_OPTION(stmt_delete_uri); | |
38752 | + PATCH_OPTION(stmt_move_uri); | |
38753 | + PATCH_OPTION(stmt_copy_uri); | |
38754 | + | |
38755 | + PATCH_OPTION(stmt_remove_lock); | |
38756 | + PATCH_OPTION(stmt_refresh_lock); | |
38757 | + PATCH_OPTION(stmt_create_lock); | |
38758 | + PATCH_OPTION(stmt_read_lock); | |
38759 | + PATCH_OPTION(stmt_read_lock_by_uri); | |
38760 | #endif | |
38761 | } | |
38762 | } | |
38763 | } | |
38764 | - | |
38765 | + | |
38766 | return 0; | |
38767 | } | |
38768 | -#undef PATCH | |
38769 | ||
38770 | URIHANDLER_FUNC(mod_webdav_uri_handler) { | |
38771 | plugin_data *p = p_d; | |
38772 | - | |
38773 | + | |
38774 | UNUSED(srv); | |
38775 | ||
38776 | if (con->uri.path->used == 0) return HANDLER_GO_ON; | |
38777 | - | |
38778 | + | |
38779 | mod_webdav_patch_connection(srv, con, p); | |
38780 | ||
38781 | if (!p->conf.enabled) return HANDLER_GO_ON; | |
38782 | @@ -362,20 +459,20 @@ | |
38783 | if (p->conf.is_readonly) { | |
38784 | response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND")); | |
38785 | } else { | |
38786 | - response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH")); | |
38787 | + response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK")); | |
38788 | } | |
38789 | break; | |
38790 | default: | |
38791 | break; | |
38792 | } | |
38793 | - | |
38794 | + | |
38795 | /* not found */ | |
38796 | return HANDLER_GO_ON; | |
38797 | } | |
38798 | -static int webdav_gen_prop_tag(server *srv, connection *con, | |
38799 | - char *prop_name, | |
38800 | - char *prop_ns, | |
38801 | - char *value, | |
38802 | +static int webdav_gen_prop_tag(server *srv, connection *con, | |
38803 | + char *prop_name, | |
38804 | + char *prop_ns, | |
38805 | + char *value, | |
38806 | buffer *b) { | |
38807 | ||
38808 | UNUSED(srv); | |
38809 | @@ -414,7 +511,7 @@ | |
38810 | buffer_append_string_buffer(b, dst->rel_path); | |
38811 | buffer_append_string(b,"</D:href>\n"); | |
38812 | buffer_append_string(b,"<D:status>\n"); | |
38813 | - | |
38814 | + | |
38815 | if (con->request.http_version == HTTP_VERSION_1_1) { | |
38816 | BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 "); | |
38817 | } else { | |
38818 | @@ -458,11 +555,11 @@ | |
38819 | ||
38820 | /* bind the values to the insert */ | |
38821 | ||
38822 | - sqlite3_bind_text(stmt, 1, | |
38823 | - dst->rel_path->ptr, | |
38824 | + sqlite3_bind_text(stmt, 1, | |
38825 | + dst->rel_path->ptr, | |
38826 | dst->rel_path->used - 1, | |
38827 | SQLITE_TRANSIENT); | |
38828 | - | |
38829 | + | |
38830 | if (SQLITE_DONE != sqlite3_step(stmt)) { | |
38831 | /* */ | |
38832 | WP(); | |
38833 | @@ -493,14 +590,14 @@ | |
38834 | (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) { | |
38835 | continue; | |
38836 | /* ignore the parent dir */ | |
38837 | - } | |
38838 | + } | |
38839 | ||
38840 | buffer_copy_string_buffer(d.path, dst->path); | |
38841 | - BUFFER_APPEND_SLASH(d.path); | |
38842 | + PATHNAME_APPEND_SLASH(d.path); | |
38843 | buffer_append_string(d.path, de->d_name); | |
38844 | - | |
38845 | + | |
38846 | buffer_copy_string_buffer(d.rel_path, dst->rel_path); | |
38847 | - BUFFER_APPEND_SLASH(d.rel_path); | |
38848 | + PATHNAME_APPEND_SLASH(d.rel_path); | |
38849 | buffer_append_string(d.rel_path, de->d_name); | |
38850 | ||
38851 | /* stat and unlink afterwards */ | |
38852 | @@ -508,7 +605,7 @@ | |
38853 | /* don't about it yet, rmdir will fail too */ | |
38854 | } else if (S_ISDIR(st.st_mode)) { | |
38855 | have_multi_status = webdav_delete_dir(srv, con, p, &d, b); | |
38856 | - | |
38857 | + | |
38858 | /* try to unlink it */ | |
38859 | if (-1 == rmdir(d.path->ptr)) { | |
38860 | switch(errno) { | |
38861 | @@ -535,11 +632,11 @@ | |
38862 | ||
38863 | /* bind the values to the insert */ | |
38864 | ||
38865 | - sqlite3_bind_text(stmt, 1, | |
38866 | - d.rel_path->ptr, | |
38867 | + sqlite3_bind_text(stmt, 1, | |
38868 | + d.rel_path->ptr, | |
38869 | d.rel_path->used - 1, | |
38870 | SQLITE_TRANSIENT); | |
38871 | - | |
38872 | + | |
38873 | if (SQLITE_DONE != sqlite3_step(stmt)) { | |
38874 | /* */ | |
38875 | WP(); | |
38876 | @@ -569,7 +666,7 @@ | |
38877 | if (stream_open(&s, src->path)) { | |
38878 | return 403; | |
38879 | } | |
38880 | - | |
38881 | + | |
38882 | if (-1 == (ofd = open(dst->path->ptr, O_WRONLY|O_TRUNC|O_CREAT|(overwrite ? 0 : O_EXCL), 0600))) { | |
38883 | /* opening the destination failed for some reason */ | |
38884 | switch(errno) { | |
38885 | @@ -601,7 +698,7 @@ | |
38886 | break; | |
38887 | } | |
38888 | } | |
38889 | - | |
38890 | + | |
38891 | stream_close(&s); | |
38892 | close(ofd); | |
38893 | ||
38894 | @@ -614,16 +711,16 @@ | |
38895 | sqlite3_reset(stmt); | |
38896 | ||
38897 | /* bind the values to the insert */ | |
38898 | - sqlite3_bind_text(stmt, 1, | |
38899 | - dst->rel_path->ptr, | |
38900 | + sqlite3_bind_text(stmt, 1, | |
38901 | + dst->rel_path->ptr, | |
38902 | dst->rel_path->used - 1, | |
38903 | SQLITE_TRANSIENT); | |
38904 | ||
38905 | - sqlite3_bind_text(stmt, 2, | |
38906 | - src->rel_path->ptr, | |
38907 | + sqlite3_bind_text(stmt, 2, | |
38908 | + src->rel_path->ptr, | |
38909 | src->rel_path->used - 1, | |
38910 | SQLITE_TRANSIENT); | |
38911 | - | |
38912 | + | |
38913 | if (SQLITE_DONE != sqlite3_step(stmt)) { | |
38914 | /* */ | |
38915 | WP(); | |
38916 | @@ -655,21 +752,21 @@ | |
38917 | (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) { | |
38918 | continue; | |
38919 | } | |
38920 | - | |
38921 | + | |
38922 | buffer_copy_string_buffer(s.path, src->path); | |
38923 | - BUFFER_APPEND_SLASH(s.path); | |
38924 | + PATHNAME_APPEND_SLASH(s.path); | |
38925 | buffer_append_string(s.path, de->d_name); | |
38926 | ||
38927 | buffer_copy_string_buffer(d.path, dst->path); | |
38928 | - BUFFER_APPEND_SLASH(d.path); | |
38929 | + PATHNAME_APPEND_SLASH(d.path); | |
38930 | buffer_append_string(d.path, de->d_name); | |
38931 | ||
38932 | buffer_copy_string_buffer(s.rel_path, src->rel_path); | |
38933 | - BUFFER_APPEND_SLASH(s.rel_path); | |
38934 | + PATHNAME_APPEND_SLASH(s.rel_path); | |
38935 | buffer_append_string(s.rel_path, de->d_name); | |
38936 | ||
38937 | buffer_copy_string_buffer(d.rel_path, dst->rel_path); | |
38938 | - BUFFER_APPEND_SLASH(d.rel_path); | |
38939 | + PATHNAME_APPEND_SLASH(d.rel_path); | |
38940 | buffer_append_string(d.rel_path, de->d_name); | |
38941 | ||
38942 | if (-1 == stat(s.path->ptr, &st)) { | |
38943 | @@ -692,16 +789,16 @@ | |
38944 | sqlite3_reset(stmt); | |
38945 | ||
38946 | /* bind the values to the insert */ | |
38947 | - sqlite3_bind_text(stmt, 1, | |
38948 | - dst->rel_path->ptr, | |
38949 | + sqlite3_bind_text(stmt, 1, | |
38950 | + dst->rel_path->ptr, | |
38951 | dst->rel_path->used - 1, | |
38952 | SQLITE_TRANSIENT); | |
38953 | ||
38954 | - sqlite3_bind_text(stmt, 2, | |
38955 | - src->rel_path->ptr, | |
38956 | + sqlite3_bind_text(stmt, 2, | |
38957 | + src->rel_path->ptr, | |
38958 | src->rel_path->used - 1, | |
38959 | SQLITE_TRANSIENT); | |
38960 | - | |
38961 | + | |
38962 | if (SQLITE_DONE != sqlite3_step(stmt)) { | |
38963 | /* */ | |
38964 | WP(); | |
38965 | @@ -721,7 +818,7 @@ | |
38966 | buffer_free(s.rel_path); | |
38967 | buffer_free(d.path); | |
38968 | buffer_free(d.rel_path); | |
38969 | - | |
38970 | + | |
38971 | closedir(srcdir); | |
38972 | } | |
38973 | ||
38974 | @@ -748,12 +845,12 @@ | |
38975 | if (S_ISDIR(sce->st.st_mode)) { | |
38976 | buffer_append_string(b, "<D:getcontenttype>httpd/unix-directory</D:getcontenttype>"); | |
38977 | found = 1; | |
38978 | - } else if(S_ISREG(sce->st.st_mode)) { | |
38979 | + } else if(S_ISREG(sce->st.st_mode)) { | |
38980 | for (k = 0; k < con->conf.mimetypes->used; k++) { | |
38981 | data_string *ds = (data_string *)con->conf.mimetypes->data[k]; | |
38982 | - | |
38983 | + | |
38984 | if (ds->key->used == 0) continue; | |
38985 | - | |
38986 | + | |
38987 | if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) { | |
38988 | buffer_append_string(b,"<D:getcontenttype>"); | |
38989 | buffer_append_string_buffer(b, ds->value); | |
38990 | @@ -807,23 +904,23 @@ | |
38991 | ||
38992 | /* bind the values to the insert */ | |
38993 | ||
38994 | - sqlite3_bind_text(stmt, 1, | |
38995 | - dst->rel_path->ptr, | |
38996 | + sqlite3_bind_text(stmt, 1, | |
38997 | + dst->rel_path->ptr, | |
38998 | dst->rel_path->used - 1, | |
38999 | SQLITE_TRANSIENT); | |
39000 | - sqlite3_bind_text(stmt, 2, | |
39001 | + sqlite3_bind_text(stmt, 2, | |
39002 | prop_name, | |
39003 | strlen(prop_name), | |
39004 | SQLITE_TRANSIENT); | |
39005 | - sqlite3_bind_text(stmt, 3, | |
39006 | + sqlite3_bind_text(stmt, 3, | |
39007 | prop_ns, | |
39008 | strlen(prop_ns), | |
39009 | SQLITE_TRANSIENT); | |
39010 | ||
39011 | /* it is the PK */ | |
39012 | - while (SQLITE_ROW == sqlite3_step(p->conf.stmt_select_prop)) { | |
39013 | + while (SQLITE_ROW == sqlite3_step(stmt)) { | |
39014 | /* there is a row for us, we only expect a single col 'value' */ | |
39015 | - webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(p->conf.stmt_select_prop, 0), b); | |
39016 | + webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(stmt, 0), b); | |
39017 | found = 1; | |
39018 | } | |
39019 | } | |
39020 | @@ -840,7 +937,7 @@ | |
39021 | char *prop; | |
39022 | } webdav_property; | |
39023 | ||
39024 | -webdav_property live_properties[] = { | |
39025 | +webdav_property live_properties[] = { | |
39026 | { "DAV:", "creationdate" }, | |
39027 | { "DAV:", "displayname" }, | |
39028 | { "DAV:", "getcontentlanguage" }, | |
39029 | @@ -871,8 +968,8 @@ | |
39030 | webdav_property *prop; | |
39031 | ||
39032 | prop = props->ptr[i]; | |
39033 | - | |
39034 | - if (0 != webdav_get_property(srv, con, p, | |
39035 | + | |
39036 | + if (0 != webdav_get_property(srv, con, p, | |
39037 | dst, prop->prop, prop->ns, b_200)) { | |
39038 | webdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_404); | |
39039 | } | |
39040 | @@ -916,12 +1013,12 @@ | |
39041 | if (-1 == c->file.fd && /* open the file if not already open */ | |
39042 | -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { | |
39043 | log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
39044 | - | |
39045 | + | |
39046 | return -1; | |
39047 | } | |
39048 | - | |
39049 | + | |
39050 | if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) { | |
39051 | - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", | |
39052 | + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", | |
39053 | strerror(errno), c->file.name, c->file.fd); | |
39054 | ||
39055 | return -1; | |
39056 | @@ -938,7 +1035,7 @@ | |
39057 | if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->file.mmap.start + c->offset, weHave, 0))) { | |
39058 | log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err); | |
39059 | } | |
39060 | - | |
39061 | + | |
39062 | c->offset += weHave; | |
39063 | cq->bytes_out += weHave; | |
39064 | ||
39065 | @@ -956,7 +1053,7 @@ | |
39066 | if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->mem->ptr + c->offset, weHave, 0))) { | |
39067 | log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err); | |
39068 | } | |
39069 | - | |
39070 | + | |
39071 | c->offset += weHave; | |
39072 | cq->bytes_out += weHave; | |
39073 | ||
39074 | @@ -991,6 +1088,113 @@ | |
39075 | } | |
39076 | #endif | |
39077 | ||
39078 | +int webdav_lockdiscovery(server *srv, connection *con, | |
39079 | + buffer *locktoken, const char *lockscope, const char *locktype, int depth) { | |
39080 | + | |
39081 | + buffer *b; | |
39082 | + | |
39083 | + response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken)); | |
39084 | + | |
39085 | + response_header_overwrite(srv, con, | |
39086 | + CONST_STR_LEN("Content-Type"), | |
39087 | + CONST_STR_LEN("text/xml; charset=\"utf-8\"")); | |
39088 | + | |
39089 | + b = chunkqueue_get_append_buffer(con->write_queue); | |
39090 | + | |
39091 | + buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); | |
39092 | + | |
39093 | + buffer_append_string(b,"<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"); | |
39094 | + buffer_append_string(b,"<D:lockdiscovery>\n"); | |
39095 | + buffer_append_string(b,"<D:activelock>\n"); | |
39096 | + | |
39097 | + buffer_append_string(b,"<D:lockscope>"); | |
39098 | + buffer_append_string(b,"<D:"); | |
39099 | + buffer_append_string(b, lockscope); | |
39100 | + buffer_append_string(b, "/>"); | |
39101 | + buffer_append_string(b,"</D:lockscope>\n"); | |
39102 | + | |
39103 | + buffer_append_string(b,"<D:locktype>"); | |
39104 | + buffer_append_string(b,"<D:"); | |
39105 | + buffer_append_string(b, locktype); | |
39106 | + buffer_append_string(b, "/>"); | |
39107 | + buffer_append_string(b,"</D:locktype>\n"); | |
39108 | + | |
39109 | + buffer_append_string(b,"<D:depth>"); | |
39110 | + buffer_append_string(b, depth == 0 ? "0" : "infinity"); | |
39111 | + buffer_append_string(b,"</D:depth>\n"); | |
39112 | + | |
39113 | + buffer_append_string(b,"<D:timeout>"); | |
39114 | + buffer_append_string(b, "Second-600"); | |
39115 | + buffer_append_string(b,"</D:timeout>\n"); | |
39116 | + | |
39117 | + buffer_append_string(b,"<D:owner>"); | |
39118 | + buffer_append_string(b,"</D:owner>\n"); | |
39119 | + | |
39120 | + buffer_append_string(b,"<D:locktoken>"); | |
39121 | + buffer_append_string(b, "<D:href>"); | |
39122 | + buffer_append_string_buffer(b, locktoken); | |
39123 | + buffer_append_string(b, "</D:href>"); | |
39124 | + buffer_append_string(b,"</D:locktoken>\n"); | |
39125 | + | |
39126 | + buffer_append_string(b,"</D:activelock>\n"); | |
39127 | + buffer_append_string(b,"</D:lockdiscovery>\n"); | |
39128 | + buffer_append_string(b,"</D:prop>\n"); | |
39129 | + | |
39130 | + return 0; | |
39131 | +} | |
39132 | +/** | |
39133 | + * check if resource is having the right locks to access to resource | |
39134 | + * | |
39135 | + * | |
39136 | + * | |
39137 | + */ | |
39138 | +int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) { | |
39139 | + int has_lock = 1; | |
39140 | + | |
39141 | +#ifdef USE_LOCKS | |
39142 | + data_string *ds; | |
39143 | + | |
39144 | + /** | |
39145 | + * If can have | |
39146 | + * - <lock-token> | |
39147 | + * - [etag] | |
39148 | + * | |
39149 | + * there is NOT, AND and OR | |
39150 | + * and a list can be tagged | |
39151 | + * | |
39152 | + * (<lock-token>) is untagged | |
39153 | + * <tag> (<lock-token>) is tagged | |
39154 | + * | |
39155 | + * as long as we don't handle collections it is simple. :) | |
39156 | + * | |
39157 | + * X-Litmus: locks: 11 (owner_modify) | |
39158 | + * If: <http://127.0.0.1:1025/dav/litmus/lockme> (<opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1>) | |
39159 | + * | |
39160 | + * X-Litmus: locks: 16 (fail_cond_put) | |
39161 | + * If: (<DAV:no-lock> ["-1622396671"]) | |
39162 | + */ | |
39163 | + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) { | |
39164 | + } else { | |
39165 | + /* we didn't provided a lock-token -> */ | |
39166 | + /* if the resource is locked -> 423 */ | |
39167 | + | |
39168 | + sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri; | |
39169 | + | |
39170 | + sqlite3_reset(stmt); | |
39171 | + | |
39172 | + sqlite3_bind_text(stmt, 1, | |
39173 | + CONST_BUF_LEN(uri), | |
39174 | + SQLITE_TRANSIENT); | |
39175 | + | |
39176 | + while (SQLITE_ROW == sqlite3_step(stmt)) { | |
39177 | + has_lock = 0; | |
39178 | + } | |
39179 | + } | |
39180 | +#endif | |
39181 | + | |
39182 | + return has_lock; | |
39183 | +} | |
39184 | + | |
39185 | URIHANDLER_FUNC(mod_webdav_subrequest_handler) { | |
39186 | plugin_data *p = p_d; | |
39187 | buffer *b; | |
39188 | @@ -1001,7 +1205,8 @@ | |
39189 | buffer *prop_200; | |
39190 | buffer *prop_404; | |
39191 | webdav_properties *req_props; | |
39192 | - | |
39193 | + stat_cache_entry *sce = NULL; | |
39194 | + | |
39195 | UNUSED(srv); | |
39196 | ||
39197 | if (!p->conf.enabled) return HANDLER_GO_ON; | |
39198 | @@ -1019,7 +1224,19 @@ | |
39199 | req_props = NULL; | |
39200 | ||
39201 | /* is there a content-body ? */ | |
39202 | - | |
39203 | + | |
39204 | + switch (stat_cache_get_entry(srv, con, con->physical.path, &sce)) { | |
39205 | + case HANDLER_ERROR: | |
39206 | + if (errno == ENOENT) { | |
39207 | + con->http_status = 404; | |
39208 | + return HANDLER_FINISHED; | |
39209 | + } | |
39210 | + break; | |
39211 | + default: | |
39212 | + break; | |
39213 | + } | |
39214 | + | |
39215 | + | |
39216 | #ifdef USE_PROPPATCH | |
39217 | /* any special requests or just allprop ? */ | |
39218 | if (con->request.content_length) { | |
39219 | @@ -1087,12 +1304,12 @@ | |
39220 | /* get all property names (EMPTY) */ | |
39221 | sqlite3_reset(stmt); | |
39222 | /* bind the values to the insert */ | |
39223 | - | |
39224 | - sqlite3_bind_text(stmt, 1, | |
39225 | - con->uri.path->ptr, | |
39226 | + | |
39227 | + sqlite3_bind_text(stmt, 1, | |
39228 | + con->uri.path->ptr, | |
39229 | con->uri.path->used - 1, | |
39230 | SQLITE_TRANSIENT); | |
39231 | - | |
39232 | + | |
39233 | if (SQLITE_DONE != sqlite3_step(stmt)) { | |
39234 | WP(); | |
39235 | } | |
39236 | @@ -1115,13 +1332,13 @@ | |
39237 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\"")); | |
39238 | ||
39239 | b = chunkqueue_get_append_buffer(con->write_queue); | |
39240 | - | |
39241 | + | |
39242 | buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); | |
39243 | ||
39244 | buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"); | |
39245 | ||
39246 | /* allprop */ | |
39247 | - | |
39248 | + | |
39249 | prop_200 = buffer_init(); | |
39250 | prop_404 = buffer_init(); | |
39251 | ||
39252 | @@ -1129,7 +1346,7 @@ | |
39253 | case 0: | |
39254 | /* Depth: 0 */ | |
39255 | webdav_get_props(srv, con, p, &(con->physical), req_props, prop_200, prop_404); | |
39256 | - | |
39257 | + | |
39258 | buffer_append_string(b,"<D:response>\n"); | |
39259 | buffer_append_string(b,"<D:href>"); | |
39260 | buffer_append_string_buffer(b, con->uri.scheme); | |
39261 | @@ -1145,9 +1362,9 @@ | |
39262 | buffer_append_string_buffer(b, prop_200); | |
39263 | ||
39264 | buffer_append_string(b,"</D:prop>\n"); | |
39265 | - | |
39266 | + | |
39267 | buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n"); | |
39268 | - | |
39269 | + | |
39270 | buffer_append_string(b,"</D:propstat>\n"); | |
39271 | } | |
39272 | if (!buffer_is_empty(prop_404)) { | |
39273 | @@ -1157,16 +1374,16 @@ | |
39274 | buffer_append_string_buffer(b, prop_404); | |
39275 | ||
39276 | buffer_append_string(b,"</D:prop>\n"); | |
39277 | - | |
39278 | + | |
39279 | buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n"); | |
39280 | - | |
39281 | + | |
39282 | buffer_append_string(b,"</D:propstat>\n"); | |
39283 | } | |
39284 | ||
39285 | buffer_append_string(b,"</D:response>\n"); | |
39286 | ||
39287 | break; | |
39288 | - case 1: | |
39289 | + case 1: | |
39290 | if (NULL != (dir = opendir(con->physical.path->ptr))) { | |
39291 | struct dirent *de; | |
39292 | physical d; | |
39293 | @@ -1179,16 +1396,16 @@ | |
39294 | if (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0') { | |
39295 | continue; | |
39296 | /* ignore the parent dir */ | |
39297 | - } | |
39298 | + } | |
39299 | ||
39300 | buffer_copy_string_buffer(d.path, dst->path); | |
39301 | - BUFFER_APPEND_SLASH(d.path); | |
39302 | + PATHNAME_APPEND_SLASH(d.path); | |
39303 | ||
39304 | buffer_copy_string_buffer(d.rel_path, dst->rel_path); | |
39305 | - BUFFER_APPEND_SLASH(d.rel_path); | |
39306 | + PATHNAME_APPEND_SLASH(d.rel_path); | |
39307 | ||
39308 | if (de->d_name[0] == '.' && de->d_name[1] == '\0') { | |
39309 | - /* don't append the . */ | |
39310 | + /* don't append the . */ | |
39311 | } else { | |
39312 | buffer_append_string(d.path, de->d_name); | |
39313 | buffer_append_string(d.rel_path, de->d_name); | |
39314 | @@ -1198,7 +1415,7 @@ | |
39315 | buffer_reset(prop_404); | |
39316 | ||
39317 | webdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404); | |
39318 | - | |
39319 | + | |
39320 | buffer_append_string(b,"<D:response>\n"); | |
39321 | buffer_append_string(b,"<D:href>"); | |
39322 | buffer_append_string_buffer(b, con->uri.scheme); | |
39323 | @@ -1214,9 +1431,9 @@ | |
39324 | buffer_append_string_buffer(b, prop_200); | |
39325 | ||
39326 | buffer_append_string(b,"</D:prop>\n"); | |
39327 | - | |
39328 | + | |
39329 | buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n"); | |
39330 | - | |
39331 | + | |
39332 | buffer_append_string(b,"</D:propstat>\n"); | |
39333 | } | |
39334 | if (!buffer_is_empty(prop_404)) { | |
39335 | @@ -1226,9 +1443,9 @@ | |
39336 | buffer_append_string_buffer(b, prop_404); | |
39337 | ||
39338 | buffer_append_string(b,"</D:prop>\n"); | |
39339 | - | |
39340 | + | |
39341 | buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n"); | |
39342 | - | |
39343 | + | |
39344 | buffer_append_string(b,"</D:propstat>\n"); | |
39345 | } | |
39346 | ||
39347 | @@ -1275,7 +1492,7 @@ | |
39348 | ||
39349 | return HANDLER_FINISHED; | |
39350 | } | |
39351 | - | |
39352 | + | |
39353 | /* let's create the directory */ | |
39354 | ||
39355 | if (-1 == mkdir(con->physical.path->ptr, 0700)) { | |
39356 | @@ -1303,7 +1520,13 @@ | |
39357 | con->http_status = 403; | |
39358 | return HANDLER_FINISHED; | |
39359 | } | |
39360 | - | |
39361 | + | |
39362 | + /* does the client have a lock for this connection ? */ | |
39363 | + if (!webdav_has_lock(srv, con, p, con->uri.path)) { | |
39364 | + con->http_status = 423; | |
39365 | + return HANDLER_FINISHED; | |
39366 | + } | |
39367 | + | |
39368 | /* stat and unlink afterwards */ | |
39369 | if (-1 == stat(con->physical.path->ptr, &st)) { | |
39370 | /* don't about it yet, unlink will fail too */ | |
39371 | @@ -1323,7 +1546,7 @@ | |
39372 | response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\"")); | |
39373 | ||
39374 | b = chunkqueue_get_append_buffer(con->write_queue); | |
39375 | - | |
39376 | + | |
39377 | buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); | |
39378 | ||
39379 | buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\">\n"); | |
39380 | @@ -1331,7 +1554,7 @@ | |
39381 | buffer_append_string_buffer(b, multi_status_resp); | |
39382 | ||
39383 | buffer_append_string(b,"</D:multistatus>\n"); | |
39384 | - | |
39385 | + | |
39386 | if (p->conf.log_xml) { | |
39387 | log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b); | |
39388 | } | |
39389 | @@ -1340,7 +1563,7 @@ | |
39390 | con->file_finished = 1; | |
39391 | } else { | |
39392 | /* everything went fine, remove the directory */ | |
39393 | - | |
39394 | + | |
39395 | if (-1 == rmdir(con->physical.path->ptr)) { | |
39396 | switch(errno) { | |
39397 | case ENOENT: | |
39398 | @@ -1375,97 +1598,174 @@ | |
39399 | case HTTP_METHOD_PUT: { | |
39400 | int fd; | |
39401 | chunkqueue *cq = con->request_content_queue; | |
39402 | + chunk *c; | |
39403 | + data_string *ds_range; | |
39404 | ||
39405 | if (p->conf.is_readonly) { | |
39406 | con->http_status = 403; | |
39407 | return HANDLER_FINISHED; | |
39408 | } | |
39409 | ||
39410 | + /* is a exclusive lock set on the source */ | |
39411 | + if (!webdav_has_lock(srv, con, p, con->uri.path)) { | |
39412 | + con->http_status = 423; | |
39413 | + return HANDLER_FINISHED; | |
39414 | + } | |
39415 | + | |
39416 | + | |
39417 | assert(chunkqueue_length(cq) == (off_t)con->request.content_length); | |
39418 | ||
39419 | - /* taken what we have in the request-body and write it to a file */ | |
39420 | - if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC, 0600))) { | |
39421 | - /* we can't open the file */ | |
39422 | - con->http_status = 403; | |
39423 | - } else { | |
39424 | - chunk *c; | |
39425 | + /* RFC2616 Section 9.6 PUT requires us to send 501 on all Content-* we don't support | |
39426 | + * - most important Content-Range | |
39427 | + * | |
39428 | + * | |
39429 | + * Example: Content-Range: bytes 100-1037/1038 */ | |
39430 | ||
39431 | - con->http_status = 201; /* created */ | |
39432 | - con->file_finished = 1; | |
39433 | + if (NULL != (ds_range = (data_string *)array_get_element(con->request.headers, "Content-Range"))) { | |
39434 | + const char *num = ds_range->value->ptr; | |
39435 | + off_t offset; | |
39436 | + char *err = NULL; | |
39437 | ||
39438 | - for (c = cq->first; c; c = cq->first) { | |
39439 | - int r = 0; | |
39440 | + if (0 != strncmp(num, "bytes ", 6)) { | |
39441 | + con->http_status = 501; /* not implemented */ | |
39442 | ||
39443 | - /* copy all chunks */ | |
39444 | - switch(c->type) { | |
39445 | - case FILE_CHUNK: | |
39446 | - | |
39447 | - if (c->file.mmap.start == MAP_FAILED) { | |
39448 | - if (-1 == c->file.fd && /* open the file if not already open */ | |
39449 | - -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { | |
39450 | - log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
39451 | - | |
39452 | - return -1; | |
39453 | - } | |
39454 | - | |
39455 | - if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) { | |
39456 | - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", | |
39457 | - strerror(errno), c->file.name, c->file.fd); | |
39458 | + return HANDLER_FINISHED; | |
39459 | + } | |
39460 | ||
39461 | - return -1; | |
39462 | - } | |
39463 | + /* we only support <num>- ... */ | |
39464 | ||
39465 | - c->file.mmap.length = c->file.length; | |
39466 | + num += 6; | |
39467 | ||
39468 | - close(c->file.fd); | |
39469 | - c->file.fd = -1; | |
39470 | - | |
39471 | - /* chunk_reset() or chunk_free() will cleanup for us */ | |
39472 | - } | |
39473 | - | |
39474 | - if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) { | |
39475 | - switch(errno) { | |
39476 | - case ENOSPC: | |
39477 | - con->http_status = 507; | |
39478 | - | |
39479 | - break; | |
39480 | - default: | |
39481 | - con->http_status = 403; | |
39482 | - break; | |
39483 | - } | |
39484 | - } | |
39485 | - break; | |
39486 | - case MEM_CHUNK: | |
39487 | - if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) { | |
39488 | - switch(errno) { | |
39489 | - case ENOSPC: | |
39490 | - con->http_status = 507; | |
39491 | - | |
39492 | - break; | |
39493 | - default: | |
39494 | - con->http_status = 403; | |
39495 | - break; | |
39496 | - } | |
39497 | - } | |
39498 | + /* skip WS */ | |
39499 | + while (*num == ' ' || *num == '\t') num++; | |
39500 | + | |
39501 | + if (*num == '\0') { | |
39502 | + con->http_status = 501; /* not implemented */ | |
39503 | + | |
39504 | + return HANDLER_FINISHED; | |
39505 | + } | |
39506 | + | |
39507 | + offset = strtoll(num, &err, 10); | |
39508 | + | |
39509 | + if (*err != '-' || offset < 0) { | |
39510 | + con->http_status = 501; /* not implemented */ | |
39511 | + | |
39512 | + return HANDLER_FINISHED; | |
39513 | + } | |
39514 | + | |
39515 | + if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY, 0600))) { | |
39516 | + switch (errno) { | |
39517 | + case ENOENT: | |
39518 | + con->http_status = 404; /* not found */ | |
39519 | break; | |
39520 | - case UNUSED_CHUNK: | |
39521 | + default: | |
39522 | + con->http_status = 403; /* not found */ | |
39523 | break; | |
39524 | } | |
39525 | + return HANDLER_FINISHED; | |
39526 | + } | |
39527 | + | |
39528 | + if (-1 == lseek(fd, offset, SEEK_SET)) { | |
39529 | + con->http_status = 501; /* not implemented */ | |
39530 | + | |
39531 | + close(fd); | |
39532 | + | |
39533 | + return HANDLER_FINISHED; | |
39534 | + } | |
39535 | + con->http_status = 200; /* modified */ | |
39536 | + } else { | |
39537 | + /* take what we have in the request-body and write it to a file */ | |
39538 | + | |
39539 | + /* if the file doesn't exist, create it */ | |
39540 | + if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_TRUNC, 0600))) { | |
39541 | + if (errno == ENOENT && | |
39542 | + -1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0600))) { | |
39543 | + /* we can't open the file */ | |
39544 | + con->http_status = 403; | |
39545 | ||
39546 | - if (r > 0) { | |
39547 | - c->offset += r; | |
39548 | - cq->bytes_out += r; | |
39549 | + return HANDLER_FINISHED; | |
39550 | } else { | |
39551 | - break; | |
39552 | + con->http_status = 201; /* created */ | |
39553 | + } | |
39554 | + } else { | |
39555 | + con->http_status = 200; /* modified */ | |
39556 | + } | |
39557 | + } | |
39558 | + | |
39559 | + con->file_finished = 1; | |
39560 | + | |
39561 | + for (c = cq->first; c; c = cq->first) { | |
39562 | + int r = 0; | |
39563 | + | |
39564 | + /* copy all chunks */ | |
39565 | + switch(c->type) { | |
39566 | + case FILE_CHUNK: | |
39567 | + | |
39568 | + if (c->file.mmap.start == MAP_FAILED) { | |
39569 | + if (-1 == c->file.fd && /* open the file if not already open */ | |
39570 | + -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { | |
39571 | + log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
39572 | + | |
39573 | + return -1; | |
39574 | + } | |
39575 | + | |
39576 | + if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) { | |
39577 | + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", | |
39578 | + strerror(errno), c->file.name, c->file.fd); | |
39579 | + | |
39580 | + return -1; | |
39581 | + } | |
39582 | + | |
39583 | + c->file.mmap.length = c->file.length; | |
39584 | + | |
39585 | + close(c->file.fd); | |
39586 | + c->file.fd = -1; | |
39587 | + | |
39588 | + /* chunk_reset() or chunk_free() will cleanup for us */ | |
39589 | + } | |
39590 | + | |
39591 | + if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) { | |
39592 | + switch(errno) { | |
39593 | + case ENOSPC: | |
39594 | + con->http_status = 507; | |
39595 | + | |
39596 | + break; | |
39597 | + default: | |
39598 | + con->http_status = 403; | |
39599 | + break; | |
39600 | + } | |
39601 | } | |
39602 | - chunkqueue_remove_finished_chunks(cq); | |
39603 | + break; | |
39604 | + case MEM_CHUNK: | |
39605 | + if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) { | |
39606 | + switch(errno) { | |
39607 | + case ENOSPC: | |
39608 | + con->http_status = 507; | |
39609 | + | |
39610 | + break; | |
39611 | + default: | |
39612 | + con->http_status = 403; | |
39613 | + break; | |
39614 | + } | |
39615 | + } | |
39616 | + break; | |
39617 | + case UNUSED_CHUNK: | |
39618 | + break; | |
39619 | } | |
39620 | - close(fd); | |
39621 | ||
39622 | + if (r > 0) { | |
39623 | + c->offset += r; | |
39624 | + cq->bytes_out += r; | |
39625 | + } else { | |
39626 | + break; | |
39627 | + } | |
39628 | + chunkqueue_remove_finished_chunks(cq); | |
39629 | } | |
39630 | + close(fd); | |
39631 | + | |
39632 | return HANDLER_FINISHED; | |
39633 | } | |
39634 | - case HTTP_METHOD_MOVE: | |
39635 | + case HTTP_METHOD_MOVE: | |
39636 | case HTTP_METHOD_COPY: { | |
39637 | buffer *destination = NULL; | |
39638 | char *sep, *start; | |
39639 | @@ -1475,7 +1775,15 @@ | |
39640 | con->http_status = 403; | |
39641 | return HANDLER_FINISHED; | |
39642 | } | |
39643 | - | |
39644 | + | |
39645 | + /* is a exclusive lock set on the source */ | |
39646 | + if (con->request.http_method == HTTP_METHOD_MOVE) { | |
39647 | + if (!webdav_has_lock(srv, con, p, con->uri.path)) { | |
39648 | + con->http_status = 423; | |
39649 | + return HANDLER_FINISHED; | |
39650 | + } | |
39651 | + } | |
39652 | + | |
39653 | if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Destination"))) { | |
39654 | destination = ds->value; | |
39655 | } else { | |
39656 | @@ -1549,10 +1857,10 @@ | |
39657 | } | |
39658 | ||
39659 | buffer_copy_string_buffer(p->physical.path, p->physical.doc_root); | |
39660 | - BUFFER_APPEND_SLASH(p->physical.path); | |
39661 | + PATHNAME_APPEND_SLASH(p->physical.path); | |
39662 | buffer_copy_string_buffer(p->physical.basedir, p->physical.path); | |
39663 | ||
39664 | - /* don't add a second / */ | |
39665 | + /* don't add a second / */ | |
39666 | if (p->physical.rel_path->ptr[0] == '/') { | |
39667 | buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, p->physical.rel_path->used - 2); | |
39668 | } else { | |
39669 | @@ -1613,6 +1921,12 @@ | |
39670 | /* it is just a file, good */ | |
39671 | int r; | |
39672 | ||
39673 | + /* does the client have a lock for this connection ? */ | |
39674 | + if (!webdav_has_lock(srv, con, p, p->uri.path)) { | |
39675 | + con->http_status = 423; | |
39676 | + return HANDLER_FINISHED; | |
39677 | + } | |
39678 | + | |
39679 | /* destination exists */ | |
39680 | if (0 == (r = stat(p->physical.path->ptr, &st))) { | |
39681 | if (S_ISDIR(st.st_mode)) { | |
39682 | @@ -1636,7 +1950,7 @@ | |
39683 | return HANDLER_FINISHED; | |
39684 | } | |
39685 | } else if (overwrite == 0) { | |
39686 | - /* destination exists, but overwrite is not set */ | |
39687 | + /* destination exists, but overwrite is not set */ | |
39688 | con->http_status = 412; | |
39689 | return HANDLER_FINISHED; | |
39690 | } else { | |
39691 | @@ -1655,16 +1969,16 @@ | |
39692 | sqlite3_reset(stmt); | |
39693 | ||
39694 | /* bind the values to the insert */ | |
39695 | - sqlite3_bind_text(stmt, 1, | |
39696 | - p->uri.path->ptr, | |
39697 | + sqlite3_bind_text(stmt, 1, | |
39698 | + p->uri.path->ptr, | |
39699 | p->uri.path->used - 1, | |
39700 | SQLITE_TRANSIENT); | |
39701 | ||
39702 | - sqlite3_bind_text(stmt, 2, | |
39703 | - con->uri.path->ptr, | |
39704 | + sqlite3_bind_text(stmt, 2, | |
39705 | + con->uri.path->ptr, | |
39706 | con->uri.path->used - 1, | |
39707 | SQLITE_TRANSIENT); | |
39708 | - | |
39709 | + | |
39710 | if (SQLITE_DONE != sqlite3_step(stmt)) { | |
39711 | log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move failed:", sqlite3_errmsg(p->conf.sql)); | |
39712 | } | |
39713 | @@ -1691,12 +2005,17 @@ | |
39714 | ||
39715 | return HANDLER_FINISHED; | |
39716 | } | |
39717 | - case HTTP_METHOD_PROPPATCH: { | |
39718 | + case HTTP_METHOD_PROPPATCH: | |
39719 | if (p->conf.is_readonly) { | |
39720 | con->http_status = 403; | |
39721 | return HANDLER_FINISHED; | |
39722 | } | |
39723 | ||
39724 | + if (!webdav_has_lock(srv, con, p, con->uri.path)) { | |
39725 | + con->http_status = 423; | |
39726 | + return HANDLER_FINISHED; | |
39727 | + } | |
39728 | + | |
39729 | /* check if destination exists */ | |
39730 | if (-1 == stat(con->physical.path->ptr, &st)) { | |
39731 | switch(errno) { | |
39732 | @@ -1737,7 +2056,7 @@ | |
39733 | ||
39734 | sqlite3_stmt *stmt; | |
39735 | ||
39736 | - stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ? | |
39737 | + stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ? | |
39738 | p->conf.stmt_delete_prop : p->conf.stmt_update_prop; | |
39739 | ||
39740 | for (props = cmd->children; props; props = props->next) { | |
39741 | @@ -1762,34 +2081,35 @@ | |
39742 | ||
39743 | /* bind the values to the insert */ | |
39744 | ||
39745 | - sqlite3_bind_text(stmt, 1, | |
39746 | - con->uri.path->ptr, | |
39747 | + sqlite3_bind_text(stmt, 1, | |
39748 | + con->uri.path->ptr, | |
39749 | con->uri.path->used - 1, | |
39750 | SQLITE_TRANSIENT); | |
39751 | - sqlite3_bind_text(stmt, 2, | |
39752 | + sqlite3_bind_text(stmt, 2, | |
39753 | (char *)prop->name, | |
39754 | strlen((char *)prop->name), | |
39755 | SQLITE_TRANSIENT); | |
39756 | if (prop->ns) { | |
39757 | - sqlite3_bind_text(stmt, 3, | |
39758 | + sqlite3_bind_text(stmt, 3, | |
39759 | (char *)prop->ns->href, | |
39760 | strlen((char *)prop->ns->href), | |
39761 | SQLITE_TRANSIENT); | |
39762 | } else { | |
39763 | - sqlite3_bind_text(stmt, 3, | |
39764 | + sqlite3_bind_text(stmt, 3, | |
39765 | "", | |
39766 | 0, | |
39767 | SQLITE_TRANSIENT); | |
39768 | } | |
39769 | if (stmt == p->conf.stmt_update_prop) { | |
39770 | - sqlite3_bind_text(stmt, 4, | |
39771 | + sqlite3_bind_text(stmt, 4, | |
39772 | (char *)xmlNodeGetContent(prop), | |
39773 | strlen((char *)xmlNodeGetContent(prop)), | |
39774 | SQLITE_TRANSIENT); | |
39775 | } | |
39776 | - | |
39777 | + | |
39778 | if (SQLITE_DONE != (r = sqlite3_step(stmt))) { | |
39779 | - log_error_write(srv, __FILE__, __LINE__, "ss", "sql-set failed:", sqlite3_errmsg(p->conf.sql)); | |
39780 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
39781 | + "sql-set failed:", sqlite3_errmsg(p->conf.sql)); | |
39782 | } | |
39783 | } | |
39784 | } | |
39785 | @@ -1804,7 +2124,7 @@ | |
39786 | ||
39787 | goto propmatch_cleanup; | |
39788 | } | |
39789 | - | |
39790 | + | |
39791 | con->http_status = 400; | |
39792 | } else { | |
39793 | if (SQLITE_OK != sqlite3_exec(p->conf.sql, "COMMIT", NULL, NULL, &err)) { | |
39794 | @@ -1821,6 +2141,7 @@ | |
39795 | } | |
39796 | ||
39797 | propmatch_cleanup: | |
39798 | + | |
39799 | xmlFreeDoc(xml); | |
39800 | } else { | |
39801 | con->http_status = 400; | |
39802 | @@ -1830,11 +2151,307 @@ | |
39803 | #endif | |
39804 | con->http_status = 501; | |
39805 | return HANDLER_FINISHED; | |
39806 | - } | |
39807 | + case HTTP_METHOD_LOCK: | |
39808 | + /** | |
39809 | + * a mac wants to write | |
39810 | + * | |
39811 | + * LOCK /dav/expire.txt HTTP/1.1\r\n | |
39812 | + * User-Agent: WebDAVFS/1.3 (01308000) Darwin/8.1.0 (Power Macintosh)\r\n | |
39813 | + * Accept: * / *\r\n | |
39814 | + * Depth: 0\r\n | |
39815 | + * Timeout: Second-600\r\n | |
39816 | + * Content-Type: text/xml; charset=\"utf-8\"\r\n | |
39817 | + * Content-Length: 229\r\n | |
39818 | + * Connection: keep-alive\r\n | |
39819 | + * Host: 192.168.178.23:1025\r\n | |
39820 | + * \r\n | |
39821 | + * <?xml version=\"1.0\" encoding=\"utf-8\"?>\n | |
39822 | + * <D:lockinfo xmlns:D=\"DAV:\">\n | |
39823 | + * <D:lockscope><D:exclusive/></D:lockscope>\n | |
39824 | + * <D:locktype><D:write/></D:locktype>\n | |
39825 | + * <D:owner>\n | |
39826 | + * <D:href>http://www.apple.com/webdav_fs/</D:href>\n | |
39827 | + * </D:owner>\n | |
39828 | + * </D:lockinfo>\n | |
39829 | + */ | |
39830 | + | |
39831 | + if (depth != 0 && depth != -1) { | |
39832 | + con->http_status = 400; | |
39833 | + | |
39834 | + return HANDLER_FINISHED; | |
39835 | + } | |
39836 | + | |
39837 | +#ifdef USE_LOCKS | |
39838 | + if (con->request.content_length) { | |
39839 | + xmlDocPtr xml; | |
39840 | + buffer *hdr_if = NULL; | |
39841 | + | |
39842 | + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) { | |
39843 | + hdr_if = ds->value; | |
39844 | + } | |
39845 | + | |
39846 | + /* we don't support Depth: Infinity on locks */ | |
39847 | + if (hdr_if == NULL && depth == -1) { | |
39848 | + con->http_status = 409; /* Conflict */ | |
39849 | + | |
39850 | + return HANDLER_FINISHED; | |
39851 | + } | |
39852 | + | |
39853 | + if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) { | |
39854 | + xmlNode *rootnode = xmlDocGetRootElement(xml); | |
39855 | + | |
39856 | + assert(rootnode); | |
39857 | + | |
39858 | + if (0 == xmlStrcmp(rootnode->name, BAD_CAST "lockinfo")) { | |
39859 | + xmlNode *lockinfo; | |
39860 | + const xmlChar *lockscope = NULL, *locktype = NULL, *owner = NULL; | |
39861 | + | |
39862 | + for (lockinfo = rootnode->children; lockinfo; lockinfo = lockinfo->next) { | |
39863 | + if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "lockscope")) { | |
39864 | + xmlNode *value; | |
39865 | + for (value = lockinfo->children; value; value = value->next) { | |
39866 | + if ((0 == xmlStrcmp(value->name, BAD_CAST "exclusive")) || | |
39867 | + (0 == xmlStrcmp(value->name, BAD_CAST "shared"))) { | |
39868 | + lockscope = value->name; | |
39869 | + } else { | |
39870 | + con->http_status = 400; | |
39871 | + | |
39872 | + xmlFreeDoc(xml); | |
39873 | + return HANDLER_FINISHED; | |
39874 | + } | |
39875 | + } | |
39876 | + } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "locktype")) { | |
39877 | + xmlNode *value; | |
39878 | + for (value = lockinfo->children; value; value = value->next) { | |
39879 | + if ((0 == xmlStrcmp(value->name, BAD_CAST "write"))) { | |
39880 | + locktype = value->name; | |
39881 | + } else { | |
39882 | + con->http_status = 400; | |
39883 | + | |
39884 | + xmlFreeDoc(xml); | |
39885 | + return HANDLER_FINISHED; | |
39886 | + } | |
39887 | + } | |
39888 | + | |
39889 | + } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "owner")) { | |
39890 | + } | |
39891 | + } | |
39892 | + | |
39893 | + if (lockscope && locktype) { | |
39894 | + sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri; | |
39895 | + | |
39896 | + /* is this resourse already locked ? */ | |
39897 | + | |
39898 | + /* SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout | |
39899 | + * FROM locks | |
39900 | + * WHERE resource = ? */ | |
39901 | + | |
39902 | + if (stmt) { | |
39903 | + | |
39904 | + sqlite3_reset(stmt); | |
39905 | + | |
39906 | + sqlite3_bind_text(stmt, 1, | |
39907 | + p->uri.path->ptr, | |
39908 | + p->uri.path->used - 1, | |
39909 | + SQLITE_TRANSIENT); | |
39910 | + | |
39911 | + /* it is the PK */ | |
39912 | + while (SQLITE_ROW == sqlite3_step(stmt)) { | |
39913 | + /* we found a lock | |
39914 | + * 1. is it compatible ? | |
39915 | + * 2. is it ours */ | |
39916 | + char *sql_lockscope = (char *)sqlite3_column_text(stmt, 2); | |
39917 | + | |
39918 | + if (strcmp(sql_lockscope, "exclusive")) { | |
39919 | + con->http_status = 423; | |
39920 | + } else if (0 == xmlStrcmp(lockscope, BAD_CAST "exclusive")) { | |
39921 | + /* resourse is locked with a shared lock | |
39922 | + * client wants exclusive */ | |
39923 | + con->http_status = 423; | |
39924 | + } | |
39925 | + } | |
39926 | + if (con->http_status == 423) { | |
39927 | + xmlFreeDoc(xml); | |
39928 | + return HANDLER_FINISHED; | |
39929 | + } | |
39930 | + } | |
39931 | + | |
39932 | + stmt = p->conf.stmt_create_lock; | |
39933 | + if (stmt) { | |
39934 | + /* create a lock-token */ | |
39935 | + uuid_t id; | |
39936 | + char uuid[37] /* 36 + \0 */; | |
39937 | + | |
39938 | + uuid_generate(id); | |
39939 | + uuid_unparse(id, uuid); | |
39940 | + | |
39941 | + buffer_copy_string(p->tmp_buf, "opaquelocktoken:"); | |
39942 | + buffer_append_string(p->tmp_buf, uuid); | |
39943 | + | |
39944 | + /* "CREATE TABLE locks (" | |
39945 | + * " locktoken TEXT NOT NULL," | |
39946 | + * " resource TEXT NOT NULL," | |
39947 | + * " lockscope TEXT NOT NULL," | |
39948 | + * " locktype TEXT NOT NULL," | |
39949 | + * " owner TEXT NOT NULL," | |
39950 | + * " depth INT NOT NULL," | |
39951 | + */ | |
39952 | + | |
39953 | + sqlite3_reset(stmt); | |
39954 | + | |
39955 | + sqlite3_bind_text(stmt, 1, | |
39956 | + CONST_BUF_LEN(p->tmp_buf), | |
39957 | + SQLITE_TRANSIENT); | |
39958 | + | |
39959 | + sqlite3_bind_text(stmt, 2, | |
39960 | + CONST_BUF_LEN(con->uri.path), | |
39961 | + SQLITE_TRANSIENT); | |
39962 | + | |
39963 | + sqlite3_bind_text(stmt, 3, | |
39964 | + lockscope, | |
39965 | + xmlStrlen(lockscope), | |
39966 | + SQLITE_TRANSIENT); | |
39967 | + | |
39968 | + sqlite3_bind_text(stmt, 4, | |
39969 | + locktype, | |
39970 | + xmlStrlen(locktype), | |
39971 | + SQLITE_TRANSIENT); | |
39972 | + | |
39973 | + /* owner */ | |
39974 | + sqlite3_bind_text(stmt, 5, | |
39975 | + "", | |
39976 | + 0, | |
39977 | + SQLITE_TRANSIENT); | |
39978 | + | |
39979 | + /* depth */ | |
39980 | + sqlite3_bind_int(stmt, 6, | |
39981 | + depth); | |
39982 | + | |
39983 | + | |
39984 | + if (SQLITE_DONE != sqlite3_step(stmt)) { | |
39985 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
39986 | + "create lock:", sqlite3_errmsg(p->conf.sql)); | |
39987 | + } | |
39988 | + | |
39989 | + /* looks like we survived */ | |
39990 | + webdav_lockdiscovery(srv, con, p->tmp_buf, lockscope, locktype, depth); | |
39991 | + | |
39992 | + con->http_status = 201; | |
39993 | + con->file_finished = 1; | |
39994 | + } | |
39995 | + } | |
39996 | + } | |
39997 | + | |
39998 | + xmlFreeDoc(xml); | |
39999 | + return HANDLER_FINISHED; | |
40000 | + } else { | |
40001 | + con->http_status = 400; | |
40002 | + return HANDLER_FINISHED; | |
40003 | + } | |
40004 | + } else { | |
40005 | + | |
40006 | + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) { | |
40007 | + buffer *locktoken = ds->value; | |
40008 | + sqlite3_stmt *stmt = p->conf.stmt_refresh_lock; | |
40009 | + | |
40010 | + /* remove the < > around the token */ | |
40011 | + if (locktoken->used < 6) { | |
40012 | + con->http_status = 400; | |
40013 | + | |
40014 | + return HANDLER_FINISHED; | |
40015 | + } | |
40016 | + | |
40017 | + buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5); | |
40018 | + | |
40019 | + sqlite3_reset(stmt); | |
40020 | + | |
40021 | + sqlite3_bind_text(stmt, 1, | |
40022 | + CONST_BUF_LEN(p->tmp_buf), | |
40023 | + SQLITE_TRANSIENT); | |
40024 | + | |
40025 | + if (SQLITE_DONE != sqlite3_step(stmt)) { | |
40026 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
40027 | + "refresh lock:", sqlite3_errmsg(p->conf.sql)); | |
40028 | + } | |
40029 | + | |
40030 | + webdav_lockdiscovery(srv, con, p->tmp_buf, "exclusive", "write", 0); | |
40031 | + | |
40032 | + con->http_status = 200; | |
40033 | + con->file_finished = 1; | |
40034 | + return HANDLER_FINISHED; | |
40035 | + } else { | |
40036 | + /* we need a lock-token to refresh */ | |
40037 | + con->http_status = 400; | |
40038 | + | |
40039 | + return HANDLER_FINISHED; | |
40040 | + } | |
40041 | + } | |
40042 | + break; | |
40043 | +#else | |
40044 | + con->http_status = 501; | |
40045 | + return HANDLER_FINISHED; | |
40046 | +#endif | |
40047 | + case HTTP_METHOD_UNLOCK: | |
40048 | +#ifdef USE_LOCKS | |
40049 | + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Lock-Token"))) { | |
40050 | + buffer *locktoken = ds->value; | |
40051 | + sqlite3_stmt *stmt = p->conf.stmt_remove_lock; | |
40052 | + | |
40053 | + /* remove the < > around the token */ | |
40054 | + if (locktoken->used < 4) { | |
40055 | + con->http_status = 400; | |
40056 | + | |
40057 | + return HANDLER_FINISHED; | |
40058 | + } | |
40059 | + | |
40060 | + /** | |
40061 | + * FIXME: | |
40062 | + * | |
40063 | + * if the resourse is locked: | |
40064 | + * - by us: unlock | |
40065 | + * - by someone else: 401 | |
40066 | + * if the resource is not locked: | |
40067 | + * - 412 | |
40068 | + * */ | |
40069 | + | |
40070 | + buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3); | |
40071 | + | |
40072 | + sqlite3_reset(stmt); | |
40073 | + | |
40074 | + sqlite3_bind_text(stmt, 1, | |
40075 | + CONST_BUF_LEN(p->tmp_buf), | |
40076 | + SQLITE_TRANSIENT); | |
40077 | + | |
40078 | + sqlite3_bind_text(stmt, 2, | |
40079 | + CONST_BUF_LEN(con->uri.path), | |
40080 | + SQLITE_TRANSIENT); | |
40081 | + | |
40082 | + if (SQLITE_DONE != sqlite3_step(stmt)) { | |
40083 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
40084 | + "remove lock:", sqlite3_errmsg(p->conf.sql)); | |
40085 | + } | |
40086 | + | |
40087 | + if (0 == sqlite3_changes(p->conf.sql)) { | |
40088 | + con->http_status = 401; | |
40089 | + } else { | |
40090 | + con->http_status = 204; | |
40091 | + } | |
40092 | + return HANDLER_FINISHED; | |
40093 | + } else { | |
40094 | + /* we need a lock-token to unlock */ | |
40095 | + con->http_status = 400; | |
40096 | + | |
40097 | + return HANDLER_FINISHED; | |
40098 | + } | |
40099 | + break; | |
40100 | +#else | |
40101 | + con->http_status = 501; | |
40102 | + return HANDLER_FINISHED; | |
40103 | +#endif | |
40104 | default: | |
40105 | break; | |
40106 | } | |
40107 | - | |
40108 | + | |
40109 | /* not found */ | |
40110 | return HANDLER_GO_ON; | |
40111 | } | |
40112 | @@ -1845,14 +2462,14 @@ | |
40113 | int mod_webdav_plugin_init(plugin *p) { | |
40114 | p->version = LIGHTTPD_VERSION_ID; | |
40115 | p->name = buffer_init_string("webdav"); | |
40116 | - | |
40117 | + | |
40118 | p->init = mod_webdav_init; | |
40119 | p->handle_uri_clean = mod_webdav_uri_handler; | |
40120 | p->handle_physical = mod_webdav_subrequest_handler; | |
40121 | p->set_defaults = mod_webdav_set_defaults; | |
40122 | p->cleanup = mod_webdav_free; | |
40123 | - | |
40124 | + | |
40125 | p->data = NULL; | |
40126 | - | |
40127 | + | |
40128 | return 0; | |
40129 | } | |
1175ccec | 40130 | --- ../lighttpd-1.4.11/src/network.c 2006-03-04 16:45:46.000000000 +0200 |
36e2a29e | 40131 | +++ lighttpd-1.4.12/src/network.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
40132 | @@ -1,14 +1,14 @@ |
40133 | #include <sys/types.h> | |
40134 | #include <sys/stat.h> | |
40135 | -#include <sys/time.h> | |
40136 | ||
40137 | #include <errno.h> | |
40138 | #include <fcntl.h> | |
40139 | -#include <unistd.h> | |
40140 | #include <string.h> | |
40141 | #include <stdlib.h> | |
40142 | #include <assert.h> | |
40143 | ||
40144 | +#include <stdio.h> | |
40145 | + | |
40146 | #include "network.h" | |
40147 | #include "fdevent.h" | |
40148 | #include "log.h" | |
40149 | @@ -19,11 +19,12 @@ | |
40150 | #include "network_backends.h" | |
40151 | #include "sys-mmap.h" | |
40152 | #include "sys-socket.h" | |
40153 | +#include "sys-files.h" | |
40154 | ||
40155 | #ifdef USE_OPENSSL | |
40156 | -# include <openssl/ssl.h> | |
40157 | -# include <openssl/err.h> | |
40158 | -# include <openssl/rand.h> | |
40159 | +# include <openssl/ssl.h> | |
40160 | +# include <openssl/err.h> | |
40161 | +# include <openssl/rand.h> | |
40162 | #endif | |
40163 | ||
40164 | handler_t network_server_handle_fdevent(void *s, void *context, int revents) { | |
40165 | @@ -31,11 +32,11 @@ | |
40166 | server_socket *srv_socket = (server_socket *)context; | |
40167 | connection *con; | |
40168 | int loops = 0; | |
40169 | - | |
40170 | + | |
40171 | UNUSED(context); | |
40172 | - | |
40173 | + | |
40174 | if (revents != FDEVENT_IN) { | |
40175 | - log_error_write(srv, __FILE__, __LINE__, "sdd", | |
40176 | + log_error_write(srv, __FILE__, __LINE__, "sdd", | |
40177 | "strange event for server socket", | |
40178 | srv_socket->fd, | |
40179 | revents); | |
40180 | @@ -44,12 +45,12 @@ | |
40181 | ||
40182 | /* accept()s at most 100 connections directly | |
40183 | * | |
40184 | - * we jump out after 100 to give the waiting connections a chance */ | |
40185 | + * we jump out after 100 to give the waiting connections a chance */ | |
40186 | for (loops = 0; loops < 100 && NULL != (con = connection_accept(srv, srv_socket)); loops++) { | |
40187 | handler_t r; | |
40188 | - | |
40189 | + | |
40190 | connection_state_machine(srv, con); | |
40191 | - | |
40192 | + | |
40193 | switch(r = plugins_call_handle_joblist(srv, con)) { | |
40194 | case HANDLER_FINISHED: | |
40195 | case HANDLER_GO_ON: | |
40196 | @@ -72,18 +73,18 @@ | |
40197 | buffer *b; | |
40198 | int is_unix_domain_socket = 0; | |
40199 | int fd; | |
40200 | - | |
40201 | + | |
40202 | #ifdef SO_ACCEPTFILTER | |
40203 | struct accept_filter_arg afa; | |
40204 | #endif | |
40205 | ||
40206 | -#ifdef __WIN32 | |
40207 | +#ifdef _WIN32 | |
40208 | WORD wVersionRequested; | |
40209 | WSADATA wsaData; | |
40210 | int err; | |
40211 | - | |
40212 | + | |
40213 | wVersionRequested = MAKEWORD( 2, 2 ); | |
40214 | - | |
40215 | + | |
40216 | err = WSAStartup( wVersionRequested, &wsaData ); | |
40217 | if ( err != 0 ) { | |
40218 | /* Tell the user that we could not find a usable */ | |
40219 | @@ -91,37 +92,37 @@ | |
40220 | return -1; | |
40221 | } | |
40222 | #endif | |
40223 | - | |
40224 | + | |
40225 | srv_socket = calloc(1, sizeof(*srv_socket)); | |
40226 | srv_socket->fd = -1; | |
40227 | - | |
40228 | + | |
40229 | srv_socket->srv_token = buffer_init(); | |
40230 | buffer_copy_string_buffer(srv_socket->srv_token, host_token); | |
40231 | - | |
40232 | + | |
40233 | b = buffer_init(); | |
40234 | buffer_copy_string_buffer(b, host_token); | |
40235 | - | |
40236 | - /* ipv4:port | |
40237 | + | |
40238 | + /* ipv4:port | |
40239 | * [ipv6]:port | |
40240 | */ | |
40241 | if (NULL == (sp = strrchr(b->ptr, ':'))) { | |
40242 | log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b); | |
40243 | - | |
40244 | + | |
40245 | return -1; | |
40246 | } | |
40247 | - | |
40248 | + | |
40249 | host = b->ptr; | |
40250 | - | |
40251 | + | |
40252 | /* check for [ and ] */ | |
40253 | if (b->ptr[0] == '[' && *(sp-1) == ']') { | |
40254 | *(sp-1) = '\0'; | |
40255 | host++; | |
40256 | - | |
40257 | + | |
40258 | s->use_ipv6 = 1; | |
40259 | } | |
40260 | - | |
40261 | + | |
40262 | *(sp++) = '\0'; | |
40263 | - | |
40264 | + | |
40265 | port = strtol(sp, NULL, 10); | |
40266 | ||
40267 | if (host[0] == '/') { | |
40268 | @@ -129,17 +130,17 @@ | |
40269 | is_unix_domain_socket = 1; | |
40270 | } else if (port == 0 || port > 65535) { | |
40271 | log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port); | |
40272 | - | |
40273 | + | |
40274 | return -1; | |
40275 | } | |
40276 | - | |
40277 | + | |
40278 | if (*host == '\0') host = NULL; | |
40279 | ||
40280 | if (is_unix_domain_socket) { | |
40281 | #ifdef HAVE_SYS_UN_H | |
40282 | ||
40283 | srv_socket->addr.plain.sa_family = AF_UNIX; | |
40284 | - | |
40285 | + | |
40286 | if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) { | |
40287 | log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); | |
40288 | return -1; | |
40289 | @@ -154,7 +155,7 @@ | |
40290 | #ifdef HAVE_IPV6 | |
40291 | if (s->use_ipv6) { | |
40292 | srv_socket->addr.plain.sa_family = AF_INET6; | |
40293 | - | |
40294 | + | |
40295 | if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { | |
40296 | log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); | |
40297 | return -1; | |
40298 | @@ -162,7 +163,7 @@ | |
40299 | srv_socket->use_ipv6 = 1; | |
40300 | } | |
40301 | #endif | |
40302 | - | |
40303 | + | |
40304 | if (srv_socket->fd == -1) { | |
40305 | srv_socket->addr.plain.sa_family = AF_INET; | |
40306 | if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { | |
40307 | @@ -170,16 +171,16 @@ | |
40308 | return -1; | |
40309 | } | |
40310 | } | |
40311 | - | |
40312 | + | |
40313 | /* */ | |
40314 | srv->cur_fds = srv_socket->fd; | |
40315 | - | |
40316 | + | |
40317 | val = 1; | |
40318 | if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { | |
40319 | log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno)); | |
40320 | return -1; | |
40321 | } | |
40322 | - | |
40323 | + | |
40324 | switch(srv_socket->addr.plain.sa_family) { | |
40325 | #ifdef HAVE_IPV6 | |
40326 | case AF_INET6: | |
40327 | @@ -190,23 +191,23 @@ | |
40328 | } else { | |
40329 | struct addrinfo hints, *res; | |
40330 | int r; | |
40331 | - | |
40332 | + | |
40333 | memset(&hints, 0, sizeof(hints)); | |
40334 | - | |
40335 | + | |
40336 | hints.ai_family = AF_INET6; | |
40337 | hints.ai_socktype = SOCK_STREAM; | |
40338 | hints.ai_protocol = IPPROTO_TCP; | |
40339 | - | |
40340 | + | |
40341 | if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) { | |
40342 | - log_error_write(srv, __FILE__, __LINE__, | |
40343 | - "sssss", "getaddrinfo failed: ", | |
40344 | + log_error_write(srv, __FILE__, __LINE__, | |
40345 | + "sssss", "getaddrinfo failed: ", | |
40346 | gai_strerror(r), "'", host, "'"); | |
40347 | - | |
40348 | + | |
40349 | return -1; | |
40350 | } | |
40351 | - | |
40352 | + | |
40353 | memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen); | |
40354 | - | |
40355 | + | |
40356 | freeaddrinfo(res); | |
40357 | } | |
40358 | srv_socket->addr.ipv6.sin6_port = htons(port); | |
40359 | @@ -221,33 +222,34 @@ | |
40360 | } else { | |
40361 | struct hostent *he; | |
40362 | if (NULL == (he = gethostbyname(host))) { | |
40363 | - log_error_write(srv, __FILE__, __LINE__, | |
40364 | - "sds", "gethostbyname failed: ", | |
40365 | + log_error_write(srv, __FILE__, __LINE__, | |
40366 | + "sds", "gethostbyname failed: ", | |
40367 | h_errno, host); | |
40368 | return -1; | |
40369 | } | |
40370 | - | |
40371 | + | |
40372 | if (he->h_addrtype != AF_INET) { | |
40373 | log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype); | |
40374 | return -1; | |
40375 | } | |
40376 | - | |
40377 | + | |
40378 | if (he->h_length != sizeof(struct in_addr)) { | |
40379 | log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length); | |
40380 | return -1; | |
40381 | } | |
40382 | - | |
40383 | + | |
40384 | memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length); | |
40385 | } | |
40386 | srv_socket->addr.ipv4.sin_port = htons(port); | |
40387 | - | |
40388 | + | |
40389 | addr_len = sizeof(struct sockaddr_in); | |
40390 | - | |
40391 | + | |
40392 | break; | |
40393 | +#ifndef _WIN32 | |
40394 | case AF_UNIX: | |
40395 | srv_socket->addr.un.sun_family = AF_UNIX; | |
40396 | strcpy(srv_socket->addr.un.sun_path, host); | |
40397 | - | |
40398 | + | |
40399 | #ifdef SUN_LEN | |
40400 | addr_len = SUN_LEN(&srv_socket->addr.un); | |
40401 | #else | |
40402 | @@ -259,8 +261,8 @@ | |
40403 | if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) { | |
40404 | close(fd); | |
40405 | ||
40406 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
40407 | - "server socket is still in use:", | |
40408 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
40409 | + "server socket is still in use:", | |
40410 | host); | |
40411 | ||
40412 | ||
40413 | @@ -275,88 +277,89 @@ | |
40414 | case ENOENT: | |
40415 | break; | |
40416 | default: | |
40417 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
40418 | - "testing socket failed:", | |
40419 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
40420 | + "testing socket failed:", | |
40421 | host, strerror(errno)); | |
40422 | ||
40423 | return -1; | |
40424 | } | |
40425 | ||
40426 | break; | |
40427 | +#endif | |
40428 | default: | |
40429 | addr_len = 0; | |
40430 | - | |
40431 | + | |
40432 | return -1; | |
40433 | } | |
40434 | - | |
40435 | + | |
40436 | if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { | |
40437 | switch(srv_socket->addr.plain.sa_family) { | |
40438 | case AF_UNIX: | |
40439 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
40440 | - "can't bind to socket:", | |
40441 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
40442 | + "can't bind to socket:", | |
40443 | host, strerror(errno)); | |
40444 | break; | |
40445 | default: | |
40446 | - log_error_write(srv, __FILE__, __LINE__, "ssds", | |
40447 | - "can't bind to port:", | |
40448 | + log_error_write(srv, __FILE__, __LINE__, "ssds", | |
40449 | + "can't bind to port:", | |
40450 | host, port, strerror(errno)); | |
40451 | break; | |
40452 | } | |
40453 | return -1; | |
40454 | } | |
40455 | - | |
40456 | + | |
40457 | if (-1 == listen(srv_socket->fd, 128 * 8)) { | |
40458 | log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno)); | |
40459 | return -1; | |
40460 | } | |
40461 | - | |
40462 | + | |
40463 | if (s->is_ssl) { | |
40464 | #ifdef USE_OPENSSL | |
40465 | if (srv->ssl_is_init == 0) { | |
40466 | SSL_load_error_strings(); | |
40467 | SSL_library_init(); | |
40468 | srv->ssl_is_init = 1; | |
40469 | - | |
40470 | + | |
40471 | if (0 == RAND_status()) { | |
40472 | - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
40473 | + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
40474 | "not enough entropy in the pool"); | |
40475 | return -1; | |
40476 | } | |
40477 | } | |
40478 | - | |
40479 | + | |
40480 | if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { | |
40481 | - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
40482 | + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
40483 | ERR_error_string(ERR_get_error(), NULL)); | |
40484 | return -1; | |
40485 | } | |
40486 | - | |
40487 | + | |
40488 | if (buffer_is_empty(s->ssl_pemfile)) { | |
40489 | log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set"); | |
40490 | return -1; | |
40491 | } | |
40492 | - | |
40493 | + | |
40494 | if (!buffer_is_empty(s->ssl_ca_file)) { | |
40495 | if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { | |
40496 | - log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", | |
40497 | + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", | |
40498 | ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); | |
40499 | return -1; | |
40500 | } | |
40501 | } | |
40502 | - | |
40503 | + | |
40504 | if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { | |
40505 | - log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", | |
40506 | + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", | |
40507 | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); | |
40508 | return -1; | |
40509 | } | |
40510 | - | |
40511 | + | |
40512 | if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { | |
40513 | - log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", | |
40514 | + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", | |
40515 | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); | |
40516 | return -1; | |
40517 | } | |
40518 | - | |
40519 | + | |
40520 | if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { | |
40521 | - log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", | |
40522 | + log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", | |
40523 | "Private key does not match the certificate public key, reason:", | |
40524 | ERR_error_string(ERR_get_error(), NULL), | |
40525 | s->ssl_pemfile); | |
40526 | @@ -364,15 +367,15 @@ | |
40527 | } | |
40528 | srv_socket->ssl_ctx = s->ssl_ctx; | |
40529 | #else | |
40530 | - | |
40531 | + | |
40532 | buffer_free(srv_socket->srv_token); | |
40533 | free(srv_socket); | |
40534 | - | |
40535 | + | |
40536 | buffer_free(b); | |
40537 | - | |
40538 | - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
40539 | + | |
40540 | + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", | |
40541 | "ssl requested but openssl support is not compiled in"); | |
40542 | - | |
40543 | + | |
40544 | return -1; | |
40545 | #endif | |
40546 | } else { | |
40547 | @@ -390,10 +393,10 @@ | |
40548 | } | |
40549 | #endif | |
40550 | } | |
40551 | - | |
40552 | + | |
40553 | srv_socket->is_ssl = s->is_ssl; | |
40554 | srv_socket->fde_ndx = -1; | |
40555 | - | |
40556 | + | |
40557 | if (srv->srv_sockets.size == 0) { | |
40558 | srv->srv_sockets.size = 4; | |
40559 | srv->srv_sockets.used = 0; | |
40560 | @@ -402,11 +405,10 @@ | |
40561 | srv->srv_sockets.size += 4; | |
40562 | srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket)); | |
40563 | } | |
40564 | - | |
40565 | + | |
40566 | srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket; | |
40567 | - | |
40568 | buffer_free(b); | |
40569 | - | |
40570 | + | |
40571 | return 0; | |
40572 | } | |
40573 | ||
40574 | @@ -414,45 +416,58 @@ | |
40575 | size_t i; | |
40576 | for (i = 0; i < srv->srv_sockets.used; i++) { | |
40577 | server_socket *srv_socket = srv->srv_sockets.ptr[i]; | |
40578 | - | |
40579 | + | |
40580 | if (srv_socket->fd != -1) { | |
40581 | /* check if server fd are already registered */ | |
40582 | if (srv_socket->fde_ndx != -1) { | |
40583 | fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd); | |
40584 | fdevent_unregister(srv->ev, srv_socket->fd); | |
40585 | } | |
40586 | - | |
40587 | + | |
40588 | close(srv_socket->fd); | |
40589 | } | |
40590 | - | |
40591 | + | |
40592 | + if (srv_socket->is_ssl) { | |
40593 | +#ifdef USE_OPENSSL | |
40594 | + SSL_CTX_free(srv_socket->ssl_ctx); | |
40595 | +#endif | |
40596 | + } | |
40597 | + | |
40598 | buffer_free(srv_socket->srv_token); | |
40599 | - | |
40600 | + | |
40601 | free(srv_socket); | |
40602 | } | |
40603 | - | |
40604 | + | |
40605 | +#ifdef USE_OPENSSL | |
40606 | + ERR_free_strings(); | |
40607 | +#endif | |
40608 | free(srv->srv_sockets.ptr); | |
40609 | - | |
40610 | + | |
f26f9fd5 ER |
40611 | return 0; |
40612 | } | |
f26f9fd5 | 40613 | |
2519e6e5 ER |
40614 | typedef enum { |
40615 | NETWORK_BACKEND_UNSET, | |
40616 | + | |
40617 | NETWORK_BACKEND_WRITE, | |
40618 | NETWORK_BACKEND_WRITEV, | |
40619 | NETWORK_BACKEND_LINUX_SENDFILE, | |
40620 | NETWORK_BACKEND_FREEBSD_SENDFILE, | |
40621 | - NETWORK_BACKEND_SOLARIS_SENDFILEV | |
40622 | + NETWORK_BACKEND_SOLARIS_SENDFILEV, | |
40623 | + | |
40624 | + NETWORK_BACKEND_WIN32_SEND, | |
40625 | + NETWORK_BACKEND_WIN32_TRANSMITFILE, | |
40626 | } network_backend_t; | |
40627 | ||
40628 | int network_init(server *srv) { | |
40629 | buffer *b; | |
40630 | size_t i; | |
40631 | network_backend_t backend; | |
40632 | - | |
40633 | - struct nb_map { | |
40634 | - network_backend_t nb; | |
40635 | - const char *name; | |
40636 | - } network_backends[] = { | |
40637 | + | |
40638 | + struct nb_map { | |
40639 | + network_backend_t nb; | |
40640 | + const char *name; | |
40641 | + } network_backends[] = { | |
40642 | /* lowest id wins */ | |
40643 | #if defined USE_LINUX_SENDFILE | |
40644 | { NETWORK_BACKEND_LINUX_SENDFILE, "linux-sendfile" }, | |
40645 | @@ -466,21 +481,30 @@ | |
40646 | #if defined USE_WRITEV | |
40647 | { NETWORK_BACKEND_WRITEV, "writev" }, | |
40648 | #endif | |
40649 | +#if defined USE_WRITE | |
40650 | { NETWORK_BACKEND_WRITE, "write" }, | |
40651 | +#endif | |
40652 | +#if defined USE_WIN32_TRANSMITFILE | |
40653 | + { NETWORK_BACKEND_WIN32_TRANSMITFILE, "win32-transmitfile" }, | |
40654 | +#endif | |
40655 | +#if defined USE_WIN32_SEND | |
40656 | + { NETWORK_BACKEND_WIN32_SEND, "win32-send" }, | |
40657 | +#endif | |
40658 | + | |
40659 | { NETWORK_BACKEND_UNSET, NULL } | |
40660 | }; | |
40661 | - | |
40662 | + | |
40663 | b = buffer_init(); | |
40664 | - | |
40665 | + | |
40666 | buffer_copy_string_buffer(b, srv->srvconf.bindhost); | |
40667 | buffer_append_string(b, ":"); | |
40668 | buffer_append_long(b, srv->srvconf.port); | |
40669 | - | |
40670 | + | |
40671 | if (0 != network_server_init(srv, b, srv->config_storage[0])) { | |
40672 | return -1; | |
40673 | } | |
40674 | buffer_free(b); | |
40675 | - | |
40676 | + | |
40677 | #ifdef USE_OPENSSL | |
40678 | srv->network_ssl_backend_write = network_write_chunkqueue_openssl; | |
40679 | #endif | |
40680 | @@ -500,54 +524,80 @@ | |
40681 | if (NULL == network_backends[i].name) { | |
40682 | /* we don't know it */ | |
40683 | ||
40684 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
40685 | - "server.network-backend has a unknown value:", | |
40686 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
40687 | + "server.network-backend has a unknown value:", | |
40688 | srv->srvconf.network_backend); | |
40689 | ||
40690 | return -1; | |
40691 | } | |
40692 | } | |
40693 | ||
40694 | +#define SET_NETWORK_BACKEND(read, write) \ | |
40695 | + srv->network_backend_write = network_write_chunkqueue_##write;\ | |
40696 | + srv->network_backend_read = network_read_chunkqueue_##read | |
40697 | + | |
40698 | +#define SET_NETWORK_BACKEND_SSL(read, write) \ | |
40699 | + srv->network_ssl_backend_write = network_write_chunkqueue_##write;\ | |
40700 | + srv->network_ssl_backend_read = network_read_chunkqueue_##read | |
40701 | + | |
40702 | switch(backend) { | |
40703 | + | |
40704 | +#ifdef USE_WIN32_SEND | |
40705 | + case NETWORK_BACKEND_WIN32_SEND: | |
40706 | + SET_NETWORK_BACKEND(win32recv, win32send); | |
40707 | + break; | |
40708 | +#ifdef USE_WIN32_TRANSMITFILE | |
40709 | + case NETWORK_BACKEND_WIN32_TRANSMITFILE: | |
40710 | + SET_NETWORK_BACKEND(win32recv, win32transmitfile); | |
40711 | + break; | |
40712 | +#endif | |
40713 | +#endif | |
40714 | + | |
40715 | +#ifdef USE_WRITE | |
40716 | case NETWORK_BACKEND_WRITE: | |
40717 | - srv->network_backend_write = network_write_chunkqueue_write; | |
40718 | + SET_NETWORK_BACKEND(read, write); | |
40719 | break; | |
40720 | + | |
40721 | #ifdef USE_WRITEV | |
40722 | case NETWORK_BACKEND_WRITEV: | |
40723 | - srv->network_backend_write = network_write_chunkqueue_writev; | |
40724 | + SET_NETWORK_BACKEND(read, writev); | |
40725 | break; | |
40726 | #endif | |
40727 | #ifdef USE_LINUX_SENDFILE | |
40728 | case NETWORK_BACKEND_LINUX_SENDFILE: | |
40729 | - srv->network_backend_write = network_write_chunkqueue_linuxsendfile; | |
40730 | + SET_NETWORK_BACKEND(read, linuxsendfile); | |
40731 | break; | |
40732 | #endif | |
40733 | #ifdef USE_FREEBSD_SENDFILE | |
40734 | case NETWORK_BACKEND_FREEBSD_SENDFILE: | |
40735 | - srv->network_backend_write = network_write_chunkqueue_freebsdsendfile; | |
40736 | + SET_NETWORK_BACKEND(read, freebsdsendfile); | |
40737 | break; | |
40738 | #endif | |
40739 | #ifdef USE_SOLARIS_SENDFILEV | |
40740 | case NETWORK_BACKEND_SOLARIS_SENDFILEV: | |
40741 | - srv->network_backend_write = network_write_chunkqueue_solarissendfilev; | |
40742 | + SET_NETWORK_BACKEND(read, solarissendfilev); | |
40743 | break; | |
40744 | #endif | |
40745 | +#endif | |
40746 | default: | |
40747 | return -1; | |
40748 | } | |
40749 | +#ifdef USE_OPENSSL | |
40750 | + SET_NETWORK_BACKEND_SSL(openssl, openssl); | |
40751 | +#endif | |
40752 | ||
40753 | /* check for $SERVER["socket"] */ | |
40754 | for (i = 1; i < srv->config_context->used; i++) { | |
40755 | data_config *dc = (data_config *)srv->config_context->data[i]; | |
40756 | specific_config *s = srv->config_storage[i]; | |
40757 | size_t j; | |
40758 | - | |
40759 | + | |
40760 | /* not our stage */ | |
40761 | if (COMP_SERVER_SOCKET != dc->comp) continue; | |
40762 | - | |
40763 | + | |
40764 | if (dc->cond != CONFIG_COND_EQ) { | |
40765 | log_error_write(srv, __FILE__, __LINE__, "s", "only == is allowed for $SERVER[\"socket\"]."); | |
40766 | - | |
40767 | + | |
40768 | return -1; | |
40769 | } | |
40770 | ||
40771 | @@ -558,36 +608,47 @@ | |
40772 | break; | |
40773 | } | |
40774 | } | |
40775 | - | |
40776 | + | |
40777 | if (j == srv->srv_sockets.used) { | |
40778 | if (0 != network_server_init(srv, dc->string, s)) return -1; | |
40779 | } | |
40780 | } | |
40781 | - | |
40782 | + | |
40783 | return 0; | |
40784 | } | |
40785 | ||
40786 | int network_register_fdevents(server *srv) { | |
40787 | size_t i; | |
40788 | - | |
40789 | if (-1 == fdevent_reset(srv->ev)) { | |
40790 | return -1; | |
40791 | } | |
40792 | - | |
40793 | /* register fdevents after reset */ | |
40794 | for (i = 0; i < srv->srv_sockets.used; i++) { | |
40795 | server_socket *srv_socket = srv->srv_sockets.ptr[i]; | |
40796 | - | |
40797 | fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket); | |
40798 | fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN); | |
40799 | } | |
40800 | return 0; | |
40801 | } | |
40802 | ||
40803 | -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) { | |
40804 | - int ret = -1; | |
40805 | +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *cq) { | |
40806 | + server_socket *srv_socket = con->srv_socket; | |
40807 | + | |
40808 | + if (srv_socket->is_ssl) { | |
40809 | +#ifdef USE_OPENSSL | |
40810 | + return srv->network_ssl_backend_read(srv, con, con->ssl, cq); | |
40811 | +#else | |
40812 | + return NETWORK_STATUS_FATAL_ERROR; | |
40813 | +#endif | |
40814 | + } else { | |
40815 | + return srv->network_backend_read(srv, con, con->fd, cq); | |
40816 | + } | |
40817 | +} | |
40818 | + | |
40819 | +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) { | |
40820 | + network_status_t ret = NETWORK_STATUS_UNSET; | |
40821 | off_t written = 0; | |
40822 | -#ifdef TCP_CORK | |
40823 | +#ifdef TCP_CORK | |
40824 | int corked = 0; | |
40825 | #endif | |
40826 | server_socket *srv_socket = con->srv_socket; | |
40827 | @@ -600,11 +661,11 @@ | |
40828 | joblist_append(srv, con); | |
40829 | ||
40830 | return 1; | |
40831 | - } | |
40832 | + } | |
40833 | ||
40834 | written = cq->bytes_out; | |
40835 | ||
40836 | -#ifdef TCP_CORK | |
40837 | +#ifdef TCP_CORK | |
40838 | /* Linux: put a cork into the socket as we want to combine the write() calls | |
40839 | * but only if we really have multiple chunks | |
40840 | */ | |
40841 | @@ -613,7 +674,7 @@ | |
40842 | setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked)); | |
40843 | } | |
40844 | #endif | |
40845 | - | |
40846 | + | |
40847 | if (srv_socket->is_ssl) { | |
40848 | #ifdef USE_OPENSSL | |
40849 | ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq); | |
40850 | @@ -621,12 +682,17 @@ | |
40851 | } else { | |
40852 | ret = srv->network_backend_write(srv, con, con->fd, cq); | |
40853 | } | |
40854 | - | |
40855 | - if (ret >= 0) { | |
40856 | + | |
40857 | + switch (ret) { | |
40858 | + case NETWORK_STATUS_WAIT_FOR_EVENT: | |
40859 | + case NETWORK_STATUS_SUCCESS: | |
40860 | chunkqueue_remove_finished_chunks(cq); | |
40861 | - ret = chunkqueue_is_empty(cq) ? 0 : 1; | |
40862 | + | |
40863 | + break; | |
40864 | + default: | |
40865 | + break; | |
40866 | } | |
40867 | - | |
40868 | + | |
40869 | #ifdef TCP_CORK | |
40870 | if (corked) { | |
40871 | corked = 0; | |
40872 | @@ -639,13 +705,13 @@ | |
40873 | con->bytes_written_cur_second += written; | |
40874 | ||
40875 | *(con->conf.global_bytes_per_second_cnt_ptr) += written; | |
40876 | - | |
40877 | + | |
40878 | if (con->conf.kbytes_per_second && | |
40879 | (con->bytes_written_cur_second > con->conf.kbytes_per_second * 1024)) { | |
40880 | /* we reached the traffic limit */ | |
40881 | ||
40882 | con->traffic_limit_reached = 1; | |
40883 | joblist_append(srv, con); | |
40884 | - } | |
40885 | + } | |
40886 | return ret; | |
40887 | } | |
1175ccec | 40888 | --- ../lighttpd-1.4.11/src/network.h 2005-08-11 01:26:42.000000000 +0300 |
36e2a29e | 40889 | +++ lighttpd-1.4.12/src/network.h 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
40890 | @@ -3,7 +3,8 @@ |
40891 | ||
40892 | #include "server.h" | |
40893 | ||
40894 | -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c); | |
40895 | +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *c); | |
40896 | +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *c); | |
40897 | ||
40898 | int network_init(server *srv); | |
40899 | int network_close(server *srv); | |
1175ccec | 40900 | --- ../lighttpd-1.4.11/src/network_backends.h 2005-10-24 15:13:51.000000000 +0300 |
36e2a29e | 40901 | +++ lighttpd-1.4.12/src/network_backends.h 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
40902 | @@ -43,16 +43,52 @@ |
40903 | # define USE_AIX_SENDFILE | |
40904 | #endif | |
40905 | ||
40906 | +/** | |
40907 | +* unix can use read/write or recv/send on sockets | |
40908 | +* win32 only recv/send | |
40909 | +*/ | |
40910 | +#ifdef _WIN32 | |
40911 | +# define USE_WIN32_SEND | |
40912 | +/* wait for async-io support | |
40913 | +# define USE_WIN32_TRANSMITFILE | |
40914 | +*/ | |
40915 | +#else | |
40916 | +# define USE_WRITE | |
40917 | +#endif | |
40918 | + | |
40919 | #include "base.h" | |
40920 | +#include "network.h" | |
40921 | + | |
40922 | +#define NETWORK_BACKEND_WRITE_CHUNK(x) \ | |
40923 | + network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq, chunk *c) | |
40924 | + | |
40925 | +#define NETWORK_BACKEND_WRITE(x) \ | |
40926 | + network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq) | |
40927 | +#define NETWORK_BACKEND_READ(x) \ | |
40928 | + network_status_t network_read_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq) | |
f26f9fd5 | 40929 | |
2519e6e5 ER |
40930 | +NETWORK_BACKEND_WRITE_CHUNK(writev_mem); |
40931 | + | |
40932 | +NETWORK_BACKEND_WRITE(write); | |
40933 | +NETWORK_BACKEND_WRITE(writev); | |
40934 | +NETWORK_BACKEND_WRITE(linuxsendfile); | |
40935 | +NETWORK_BACKEND_WRITE(freebsdsendfile); | |
40936 | +NETWORK_BACKEND_WRITE(solarissendfilev); | |
40937 | + | |
40938 | +NETWORK_BACKEND_WRITE(win32transmitfile); | |
40939 | +NETWORK_BACKEND_WRITE(win32send); | |
40940 | + | |
40941 | +NETWORK_BACKEND_READ(read); | |
40942 | +NETWORK_BACKEND_READ(win32recv); | |
f26f9fd5 | 40943 | |
2519e6e5 ER |
40944 | -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq); |
40945 | -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq); | |
40946 | -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq); | |
40947 | -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq); | |
40948 | -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq); | |
40949 | #ifdef USE_OPENSSL | |
40950 | -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq); | |
40951 | +#define NETWORK_BACKEND_WRITE_SSL(x) \ | |
40952 | + network_status_t network_write_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq) | |
40953 | +#define NETWORK_BACKEND_READ_SSL(x) \ | |
40954 | + network_status_t network_read_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq) | |
f673a614 | 40955 | + |
2519e6e5 ER |
40956 | +NETWORK_BACKEND_WRITE_SSL(openssl); |
40957 | +NETWORK_BACKEND_READ_SSL(openssl); | |
f26f9fd5 | 40958 | #endif |
f26f9fd5 | 40959 | |
2519e6e5 | 40960 | #endif |
1175ccec | 40961 | --- ../lighttpd-1.4.11/src/network_freebsd_sendfile.c 2005-10-22 12:28:18.000000000 +0300 |
36e2a29e | 40962 | +++ lighttpd-1.4.12/src/network_freebsd_sendfile.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
40963 | @@ -26,142 +26,61 @@ |
40964 | ||
40965 | #ifndef UIO_MAXIOV | |
40966 | # ifdef __FreeBSD__ | |
40967 | -/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */ | |
40968 | +/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */ | |
40969 | # define UIO_MAXIOV 1024 | |
40970 | # endif | |
40971 | #endif | |
40972 | ||
40973 | -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq) { | |
40974 | +NETWORK_BACKEND_WRITE(freebsdsendfile) { | |
40975 | chunk *c; | |
40976 | size_t chunks_written = 0; | |
f26f9fd5 | 40977 | - |
f673a614 | 40978 | + |
2519e6e5 ER |
40979 | for(c = cq->first; c; c = c->next, chunks_written++) { |
40980 | int chunk_finished = 0; | |
40981 | - | |
40982 | + network_status_t ret; | |
40983 | + | |
40984 | switch(c->type) { | |
40985 | - case MEM_CHUNK: { | |
40986 | - char * offset; | |
40987 | - size_t toSend; | |
40988 | - ssize_t r; | |
40989 | - | |
40990 | - size_t num_chunks, i; | |
40991 | - struct iovec chunks[UIO_MAXIOV]; | |
40992 | - chunk *tc; | |
40993 | - size_t num_bytes = 0; | |
40994 | - | |
40995 | - /* we can't send more then SSIZE_MAX bytes in one chunk */ | |
40996 | - | |
40997 | - /* build writev list | |
40998 | - * | |
40999 | - * 1. limit: num_chunks < UIO_MAXIOV | |
41000 | - * 2. limit: num_bytes < SSIZE_MAX | |
41001 | - */ | |
41002 | - for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next); | |
41003 | - | |
41004 | - for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) { | |
41005 | - if (tc->mem->used == 0) { | |
41006 | - chunks[i].iov_base = tc->mem->ptr; | |
41007 | - chunks[i].iov_len = 0; | |
41008 | - } else { | |
41009 | - offset = tc->mem->ptr + tc->offset; | |
41010 | - toSend = tc->mem->used - 1 - tc->offset; | |
41011 | - | |
41012 | - chunks[i].iov_base = offset; | |
41013 | - | |
41014 | - /* protect the return value of writev() */ | |
41015 | - if (toSend > SSIZE_MAX || | |
41016 | - num_bytes + toSend > SSIZE_MAX) { | |
41017 | - chunks[i].iov_len = SSIZE_MAX - num_bytes; | |
41018 | - | |
41019 | - num_chunks = i + 1; | |
41020 | - break; | |
41021 | - } else { | |
41022 | - chunks[i].iov_len = toSend; | |
41023 | - } | |
41024 | - | |
41025 | - num_bytes += toSend; | |
41026 | - } | |
41027 | - } | |
41028 | - | |
41029 | - if ((r = writev(fd, chunks, num_chunks)) < 0) { | |
41030 | - switch (errno) { | |
41031 | - case EAGAIN: | |
41032 | - case EINTR: | |
41033 | - r = 0; | |
41034 | - break; | |
41035 | - case EPIPE: | |
41036 | - case ECONNRESET: | |
41037 | - return -2; | |
41038 | - default: | |
41039 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41040 | - "writev failed:", strerror(errno), fd); | |
41041 | - | |
41042 | - return -1; | |
41043 | - } | |
41044 | + case MEM_CHUNK: | |
41045 | + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c); | |
41046 | ||
41047 | - r = 0; | |
41048 | - } | |
41049 | - | |
41050 | - /* check which chunks have been written */ | |
41051 | - cq->bytes_out += r; | |
41052 | - | |
41053 | - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) { | |
41054 | - if (r >= (ssize_t)chunks[i].iov_len) { | |
41055 | - /* written */ | |
41056 | - r -= chunks[i].iov_len; | |
41057 | - tc->offset += chunks[i].iov_len; | |
41058 | - | |
41059 | - if (chunk_finished) { | |
41060 | - /* skip the chunks from further touches */ | |
41061 | - chunks_written++; | |
41062 | - c = c->next; | |
41063 | - } else { | |
41064 | - /* chunks_written + c = c->next is done in the for()*/ | |
41065 | - chunk_finished++; | |
41066 | - } | |
41067 | - } else { | |
41068 | - /* partially written */ | |
41069 | - | |
41070 | - tc->offset += r; | |
41071 | - chunk_finished = 0; | |
41072 | - | |
41073 | - break; | |
41074 | - } | |
41075 | + if (ret != NETWORK_STATUS_SUCCESS) { | |
41076 | + return ret; | |
41077 | } | |
41078 | - | |
41079 | + | |
41080 | + chunk_finished = 1; | |
41081 | + | |
41082 | break; | |
41083 | - } | |
41084 | case FILE_CHUNK: { | |
41085 | off_t offset, r; | |
41086 | size_t toSend; | |
41087 | stat_cache_entry *sce = NULL; | |
41088 | int ifd; | |
41089 | - | |
41090 | + | |
41091 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { | |
41092 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
41093 | strerror(errno), c->file.name); | |
41094 | - return -1; | |
41095 | + return NETWORK_STATUS_FATAL_ERROR; | |
41096 | } | |
41097 | - | |
41098 | + | |
41099 | offset = c->file.start + c->offset; | |
41100 | /* limit the toSend to 2^31-1 bytes in a chunk */ | |
41101 | - toSend = c->file.length - c->offset > ((1 << 30) - 1) ? | |
41102 | + toSend = c->file.length - c->offset > ((1 << 30) - 1) ? | |
41103 | ((1 << 30) - 1) : c->file.length - c->offset; | |
41104 | - | |
41105 | + | |
41106 | if (offset > sce->st.st_size) { | |
41107 | log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name); | |
41108 | - | |
41109 | - return -1; | |
41110 | + | |
41111 | + return NETWORK_STATUS_FATAL_ERROR; | |
41112 | } | |
41113 | - | |
41114 | + | |
41115 | if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) { | |
41116 | log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
41117 | - | |
41118 | - return -1; | |
41119 | + | |
41120 | + return NETWORK_STATUS_FATAL_ERROR; | |
41121 | } | |
41122 | - | |
41123 | + | |
41124 | r = 0; | |
41125 | - | |
41126 | + | |
41127 | /* FreeBSD sendfile() */ | |
41128 | if (-1 == sendfile(ifd, fd, offset, toSend, NULL, &r, 0)) { | |
41129 | switch(errno) { | |
41130 | @@ -169,39 +88,39 @@ | |
41131 | break; | |
41132 | case ENOTCONN: | |
41133 | close(ifd); | |
41134 | - return -2; | |
41135 | + return NETWORK_STATUS_CONNECTION_CLOSE; | |
41136 | default: | |
41137 | log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno); | |
41138 | close(ifd); | |
41139 | - return -1; | |
41140 | + return NETWORK_STATUS_FATAL_ERROR; | |
41141 | } | |
f26f9fd5 | 41142 | } |
2519e6e5 ER |
41143 | close(ifd); |
41144 | - | |
41145 | + | |
41146 | c->offset += r; | |
41147 | cq->bytes_out += r; | |
41148 | - | |
41149 | + | |
41150 | if (c->offset == c->file.length) { | |
41151 | chunk_finished = 1; | |
f26f9fd5 | 41152 | } |
2519e6e5 ER |
41153 | - |
41154 | + | |
41155 | break; | |
41156 | } | |
41157 | default: | |
41158 | - | |
41159 | + | |
41160 | log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known"); | |
41161 | - | |
41162 | + | |
41163 | return -1; | |
41164 | } | |
41165 | - | |
41166 | + | |
41167 | if (!chunk_finished) { | |
41168 | /* not finished yet */ | |
41169 | - | |
41170 | + | |
41171 | break; | |
f26f9fd5 ER |
41172 | } |
41173 | } | |
f673a614 | 41174 | |
2519e6e5 ER |
41175 | - return chunks_written; |
41176 | + return NETWORK_STATUS_SUCCESS; | |
41177 | } | |
f673a614 | 41178 | |
2519e6e5 | 41179 | #endif |
1175ccec ER |
41180 | --- ../lighttpd-1.4.11/src/network_linux_sendfile.c 2006-02-15 20:02:36.000000000 +0200 |
41181 | +++ lighttpd-1.4.12/src/network_linux_sendfile.c 2006-07-15 22:43:21.000000000 +0300 | |
2519e6e5 ER |
41182 | @@ -26,122 +26,54 @@ |
41183 | /* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */ | |
41184 | #undef HAVE_POSIX_FADVISE | |
f673a614 | 41185 | |
2519e6e5 ER |
41186 | -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq) { |
41187 | - chunk *c; | |
41188 | +NETWORK_BACKEND_WRITE(linuxsendfile) { | |
41189 | + chunk *c, *tc; | |
41190 | size_t chunks_written = 0; | |
41191 | - | |
41192 | + | |
41193 | for(c = cq->first; c; c = c->next, chunks_written++) { | |
41194 | int chunk_finished = 0; | |
41195 | - | |
41196 | + network_status_t ret; | |
41197 | + | |
41198 | switch(c->type) { | |
41199 | - case MEM_CHUNK: { | |
41200 | - char * offset; | |
41201 | - size_t toSend; | |
41202 | - ssize_t r; | |
41203 | - | |
41204 | - size_t num_chunks, i; | |
41205 | - struct iovec chunks[UIO_MAXIOV]; | |
41206 | - chunk *tc; | |
41207 | - size_t num_bytes = 0; | |
41208 | - | |
41209 | - /* we can't send more then SSIZE_MAX bytes in one chunk */ | |
41210 | - | |
41211 | - /* build writev list | |
41212 | - * | |
41213 | - * 1. limit: num_chunks < UIO_MAXIOV | |
41214 | - * 2. limit: num_bytes < SSIZE_MAX | |
41215 | - */ | |
41216 | - for (num_chunks = 0, tc = c; | |
41217 | - tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; | |
41218 | - tc = tc->next, num_chunks++); | |
41219 | - | |
41220 | - for (tc = c, i = 0; i < num_chunks; tc = tc->next, i++) { | |
41221 | - if (tc->mem->used == 0) { | |
41222 | - chunks[i].iov_base = tc->mem->ptr; | |
41223 | - chunks[i].iov_len = 0; | |
41224 | - } else { | |
41225 | - offset = tc->mem->ptr + tc->offset; | |
41226 | - toSend = tc->mem->used - 1 - tc->offset; | |
41227 | - | |
41228 | - chunks[i].iov_base = offset; | |
41229 | - | |
41230 | - /* protect the return value of writev() */ | |
41231 | - if (toSend > SSIZE_MAX || | |
41232 | - num_bytes + toSend > SSIZE_MAX) { | |
41233 | - chunks[i].iov_len = SSIZE_MAX - num_bytes; | |
41234 | - | |
41235 | - num_chunks = i + 1; | |
41236 | - break; | |
41237 | - } else { | |
41238 | - chunks[i].iov_len = toSend; | |
41239 | - } | |
41240 | - | |
41241 | - num_bytes += toSend; | |
41242 | - } | |
41243 | - } | |
41244 | - | |
41245 | - if ((r = writev(fd, chunks, num_chunks)) < 0) { | |
41246 | - switch (errno) { | |
41247 | - case EAGAIN: | |
41248 | - case EINTR: | |
41249 | - r = 0; | |
41250 | - break; | |
41251 | - case EPIPE: | |
41252 | - case ECONNRESET: | |
41253 | - return -2; | |
41254 | - default: | |
41255 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41256 | - "writev failed:", strerror(errno), fd); | |
41257 | - | |
41258 | - return -1; | |
41259 | - } | |
41260 | - } | |
41261 | - | |
41262 | - /* check which chunks have been written */ | |
41263 | - cq->bytes_out += r; | |
41264 | + case MEM_CHUNK: | |
41265 | + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c); | |
f673a614 | 41266 | |
2519e6e5 ER |
41267 | - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) { |
41268 | - if (r >= (ssize_t)chunks[i].iov_len) { | |
41269 | - /* written */ | |
41270 | - r -= chunks[i].iov_len; | |
41271 | - tc->offset += chunks[i].iov_len; | |
41272 | - | |
41273 | + /* check which chunks are finished now */ | |
41274 | + for (tc = c; tc; tc = tc->next) { | |
41275 | + /* finished the chunk */ | |
41276 | + if (tc->offset == tc->mem->used - 1) { | |
41277 | + /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */ | |
41278 | if (chunk_finished) { | |
41279 | - /* skip the chunks from further touches */ | |
41280 | - chunks_written++; | |
41281 | c = c->next; | |
41282 | } else { | |
41283 | - /* chunks_written + c = c->next is done in the for()*/ | |
41284 | - chunk_finished++; | |
41285 | + chunk_finished = 1; | |
41286 | } | |
41287 | } else { | |
41288 | - /* partially written */ | |
41289 | - | |
41290 | - tc->offset += r; | |
41291 | - chunk_finished = 0; | |
41292 | - | |
41293 | break; | |
41294 | } | |
41295 | } | |
41296 | - | |
f673a614 | 41297 | + |
2519e6e5 ER |
41298 | + if (ret != NETWORK_STATUS_SUCCESS) { |
41299 | + return ret; | |
41300 | + } | |
41301 | + | |
41302 | break; | |
41303 | - } | |
41304 | case FILE_CHUNK: { | |
41305 | ssize_t r; | |
41306 | off_t offset; | |
41307 | size_t toSend; | |
41308 | stat_cache_entry *sce = NULL; | |
41309 | - | |
41310 | + | |
41311 | offset = c->file.start + c->offset; | |
41312 | /* limit the toSend to 2^31-1 bytes in a chunk */ | |
41313 | - toSend = c->file.length - c->offset > ((1 << 30) - 1) ? | |
41314 | + toSend = c->file.length - c->offset > ((1 << 30) - 1) ? | |
41315 | ((1 << 30) - 1) : c->file.length - c->offset; | |
41316 | - | |
41317 | - /* open file if not already opened */ | |
f673a614 | 41318 | + |
2519e6e5 ER |
41319 | + /* open file if not already opened */ |
41320 | if (-1 == c->file.fd) { | |
41321 | if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { | |
41322 | log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
41323 | - | |
41324 | + | |
41325 | return -1; | |
41326 | } | |
41327 | #ifdef FD_CLOEXEC | |
41328 | @@ -151,7 +83,7 @@ | |
41329 | /* tell the kernel that we want to stream the file */ | |
41330 | if (-1 == posix_fadvise(c->file.fd, 0, 0, POSIX_FADV_SEQUENTIAL)) { | |
41331 | if (ENOSYS != errno) { | |
41332 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41333 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41334 | "posix_fadvise failed:", strerror(errno), c->file.fd); | |
41335 | } | |
41336 | } | |
41337 | @@ -168,7 +100,7 @@ | |
41338 | case ECONNRESET: | |
41339 | return -2; | |
41340 | default: | |
41341 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41342 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41343 | "sendfile failed:", strerror(errno), fd); | |
41344 | return -1; | |
41345 | } | |
41346 | @@ -179,7 +111,7 @@ | |
41347 | * | |
41348 | * - the file shrinked -> error | |
41349 | * - the remote side closed inbetween -> remote-close */ | |
41350 | - | |
41351 | + | |
41352 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { | |
41353 | /* file is gone ? */ | |
41354 | return -1; | |
41355 | @@ -196,22 +128,22 @@ | |
41356 | #ifdef HAVE_POSIX_FADVISE | |
41357 | #if 0 | |
41358 | #define K * 1024 | |
41359 | -#define M * 1024 K | |
41360 | +#define M * 1024 K | |
41361 | #define READ_AHEAD 4 M | |
41362 | /* check if we need a new chunk */ | |
41363 | if ((c->offset & ~(READ_AHEAD - 1)) != ((c->offset + r) & ~(READ_AHEAD - 1))) { | |
41364 | /* tell the kernel that we want to stream the file */ | |
41365 | if (-1 == posix_fadvise(c->file.fd, (c->offset + r) & ~(READ_AHEAD - 1), READ_AHEAD, POSIX_FADV_NOREUSE)) { | |
41366 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41367 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41368 | "posix_fadvise failed:", strerror(errno), c->file.fd); | |
41369 | } | |
41370 | } | |
f26f9fd5 | 41371 | #endif |
2519e6e5 ER |
41372 | #endif |
41373 | - | |
41374 | + | |
41375 | c->offset += r; | |
41376 | cq->bytes_out += r; | |
41377 | - | |
41378 | + | |
41379 | if (c->offset == c->file.length) { | |
41380 | chunk_finished = 1; | |
f673a614 | 41381 | |
1175ccec | 41382 | @@ -222,24 +154,24 @@ |
2519e6e5 ER |
41383 | c->file.fd = -1; |
41384 | } | |
f26f9fd5 | 41385 | } |
2519e6e5 ER |
41386 | - |
41387 | + | |
41388 | break; | |
41389 | } | |
41390 | default: | |
41391 | - | |
41392 | + | |
41393 | log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known"); | |
41394 | - | |
41395 | + | |
41396 | return -1; | |
41397 | } | |
41398 | - | |
41399 | + | |
41400 | if (!chunk_finished) { | |
41401 | /* not finished yet */ | |
41402 | - | |
41403 | + | |
41404 | break; | |
f26f9fd5 | 41405 | } |
f673a614 | 41406 | } |
1175ccec ER |
41407 | |
41408 | - return chunks_written; | |
41409 | + return NETWORK_STATUS_SUCCESS; | |
41410 | } | |
41411 | ||
41412 | #endif | |
41413 | --- ../lighttpd-1.4.11/src/network_openssl.c 2005-11-17 14:53:29.000000000 +0200 | |
36e2a29e | 41414 | +++ lighttpd-1.4.12/src/network_openssl.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
41415 | @@ -23,17 +23,87 @@ |
41416 | #include "log.h" | |
41417 | #include "stat_cache.h" | |
f673a614 | 41418 | |
2519e6e5 ER |
41419 | -# include <openssl/ssl.h> |
41420 | -# include <openssl/err.h> | |
41421 | +# include <openssl/ssl.h> | |
41422 | +# include <openssl/err.h> | |
f673a614 | 41423 | |
2519e6e5 ER |
41424 | -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) { |
41425 | +NETWORK_BACKEND_READ_SSL(openssl) { | |
41426 | + buffer *b; | |
41427 | + off_t len; | |
41428 | + | |
41429 | + b = chunkqueue_get_append_buffer(cq); | |
41430 | + buffer_prepare_copy(b, 8192); | |
41431 | + len = SSL_read(ssl, b->ptr, b->size - 1); | |
41432 | + | |
41433 | + log_error_write(srv, __FILE__, __LINE__, "so", "SSL:", len); | |
41434 | + | |
41435 | + if (len < 0) { | |
41436 | + int r, ssl_err; | |
41437 | + | |
41438 | + switch ((r = SSL_get_error(con->ssl, len))) { | |
41439 | + case SSL_ERROR_WANT_READ: | |
41440 | + return NETWORK_STATUS_WAIT_FOR_EVENT; | |
41441 | + case SSL_ERROR_SYSCALL: | |
41442 | + /** | |
41443 | + * man SSL_get_error() | |
41444 | + * | |
41445 | + * SSL_ERROR_SYSCALL | |
41446 | + * Some I/O error occurred. The OpenSSL error queue may contain more | |
41447 | + * information on the error. If the error queue is empty (i.e. | |
41448 | + * ERR_get_error() returns 0), ret can be used to find out more about | |
41449 | + * the error: If ret == 0, an EOF was observed that violates the | |
41450 | + * protocol. If ret == -1, the underlying BIO reported an I/O error | |
41451 | + * (for socket I/O on Unix systems, consult errno for details). | |
41452 | + * | |
41453 | + */ | |
41454 | + while((ssl_err = ERR_get_error())) { | |
41455 | + /* get all errors from the error-queue */ | |
41456 | + log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", | |
41457 | + r, ERR_error_string(ssl_err, NULL)); | |
41458 | + } | |
41459 | + | |
41460 | + switch(errno) { | |
41461 | + default: | |
41462 | + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", | |
41463 | + len, r, errno, | |
41464 | + strerror(errno)); | |
41465 | + break; | |
41466 | + } | |
41467 | + | |
41468 | + break; | |
41469 | + case SSL_ERROR_ZERO_RETURN: | |
41470 | + /* clean shutdown on the remote side */ | |
41471 | + | |
41472 | + if (r == 0) { | |
41473 | + /* FIXME: later */ | |
41474 | + } | |
41475 | + | |
41476 | + /* fall thourgh */ | |
41477 | + default: | |
41478 | + while((ssl_err = ERR_get_error())) { | |
41479 | + /* get all errors from the error-queue */ | |
41480 | + log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", | |
41481 | + r, ERR_error_string(ssl_err, NULL)); | |
41482 | + } | |
41483 | + break; | |
41484 | + } | |
41485 | + } | |
41486 | + | |
41487 | + assert(len > 0); | |
41488 | + b->used += len; | |
41489 | + b->ptr[b->used - 1] = '\0'; | |
41490 | + | |
41491 | + return NETWORK_STATUS_SUCCESS; | |
41492 | +} | |
41493 | + | |
41494 | + | |
41495 | +NETWORK_BACKEND_WRITE_SSL(openssl) { | |
41496 | int ssl_r; | |
41497 | chunk *c; | |
41498 | size_t chunks_written = 0; | |
f673a614 | 41499 | |
2519e6e5 ER |
41500 | /* this is a 64k sendbuffer |
41501 | * | |
41502 | - * it has to stay at the same location all the time to satisfy the needs | |
41503 | + * it has to stay at the same location all the time to satisfy the needs | |
41504 | * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE | |
41505 | * | |
41506 | * the buffer is allocated once, is NOT realloced and is NOT freed at shutdown | |
41507 | @@ -43,14 +113,14 @@ | |
41508 | * In reality we would like to use mmap() but we don't have a guarantee that | |
41509 | * we get the same mmap() address for each call. On openbsd the mmap() address | |
41510 | * even randomized. | |
41511 | - * That means either we keep the mmap() open or we do a read() into a | |
41512 | - * constant buffer | |
41513 | + * That means either we keep the mmap() open or we do a read() into a | |
41514 | + * constant buffer | |
41515 | * */ | |
41516 | #define LOCAL_SEND_BUFSIZE (64 * 1024) | |
41517 | static char *local_send_buffer = NULL; | |
41518 | ||
41519 | /* the remote side closed the connection before without shutdown request | |
41520 | - * - IE | |
41521 | + * - IE | |
41522 | * - wget | |
41523 | * if keep-alive is disabled */ | |
41524 | ||
41525 | @@ -60,32 +130,34 @@ | |
41526 | ||
41527 | for(c = cq->first; c; c = c->next) { | |
41528 | int chunk_finished = 0; | |
41529 | - | |
41530 | + | |
41531 | switch(c->type) { | |
41532 | case MEM_CHUNK: { | |
41533 | char * offset; | |
41534 | size_t toSend; | |
41535 | - ssize_t r; | |
41536 | - | |
41537 | + ssize_t r = 0; | |
41538 | + | |
41539 | if (c->mem->used == 0) { | |
41540 | chunk_finished = 1; | |
41541 | break; | |
41542 | } | |
41543 | - | |
41544 | + | |
41545 | offset = c->mem->ptr + c->offset; | |
41546 | toSend = c->mem->used - 1 - c->offset; | |
41547 | - | |
41548 | + | |
41549 | /** | |
41550 | * SSL_write man-page | |
41551 | - * | |
41552 | + * | |
41553 | * WARNING | |
41554 | * When an SSL_write() operation has to be repeated because of | |
41555 | * SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be | |
41556 | * repeated with the same arguments. | |
41557 | - * | |
41558 | + * | |
41559 | + * SSL_write(..., 0) return 0 which is handle as an error (Success) | |
41560 | + * checking toSend and not calling SSL_write() is simpler | |
41561 | */ | |
41562 | - | |
41563 | - if ((r = SSL_write(ssl, offset, toSend)) <= 0) { | |
41564 | + | |
41565 | + if (toSend != 0 && (r = SSL_write(ssl, offset, toSend)) <= 0) { | |
41566 | unsigned long err; | |
f26f9fd5 | 41567 | |
2519e6e5 ER |
41568 | switch ((ssl_r = SSL_get_error(ssl, r))) { |
41569 | @@ -95,7 +167,7 @@ | |
41570 | /* perhaps we have error waiting in our error-queue */ | |
41571 | if (0 != (err = ERR_get_error())) { | |
41572 | do { | |
41573 | - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41574 | + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41575 | ssl_r, r, | |
41576 | ERR_error_string(err, NULL)); | |
41577 | } while((err = ERR_get_error())); | |
41578 | @@ -105,43 +177,43 @@ | |
41579 | case EPIPE: | |
41580 | return -2; | |
41581 | default: | |
41582 | - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", | |
41583 | + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", | |
41584 | ssl_r, r, errno, | |
41585 | strerror(errno)); | |
41586 | break; | |
41587 | } | |
41588 | } else { | |
41589 | /* neither error-queue nor errno ? */ | |
41590 | - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", | |
41591 | + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", | |
41592 | ssl_r, r, errno, | |
41593 | strerror(errno)); | |
41594 | } | |
41595 | - | |
41596 | + | |
41597 | return -1; | |
41598 | case SSL_ERROR_ZERO_RETURN: | |
41599 | /* clean shutdown on the remote side */ | |
41600 | - | |
41601 | + | |
41602 | if (r == 0) return -2; | |
41603 | - | |
41604 | + | |
41605 | /* fall through */ | |
41606 | default: | |
41607 | while((err = ERR_get_error())) { | |
41608 | - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41609 | + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41610 | ssl_r, r, | |
41611 | ERR_error_string(err, NULL)); | |
41612 | } | |
41613 | - | |
41614 | + | |
41615 | return -1; | |
41616 | } | |
41617 | } else { | |
41618 | c->offset += r; | |
41619 | cq->bytes_out += r; | |
41620 | } | |
41621 | - | |
41622 | + | |
41623 | if (c->offset == (off_t)c->mem->used - 1) { | |
41624 | chunk_finished = 1; | |
f26f9fd5 | 41625 | } |
2519e6e5 ER |
41626 | - |
41627 | + | |
41628 | break; | |
f26f9fd5 | 41629 | } |
2519e6e5 ER |
41630 | case FILE_CHUNK: { |
41631 | @@ -150,7 +222,7 @@ | |
41632 | stat_cache_entry *sce = NULL; | |
41633 | int ifd; | |
41634 | int write_wait = 0; | |
41635 | - | |
41636 | + | |
41637 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { | |
41638 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
41639 | strerror(errno), c->file.name); | |
41640 | @@ -164,13 +236,13 @@ | |
41641 | ||
41642 | do { | |
41643 | off_t offset = c->file.start + c->offset; | |
41644 | - off_t toSend = c->file.length - c->offset; | |
41645 | + off_t toSend = c->file.length - c->offset; | |
f673a614 | 41646 | |
2519e6e5 ER |
41647 | if (toSend > LOCAL_SEND_BUFSIZE) toSend = LOCAL_SEND_BUFSIZE; |
41648 | - | |
41649 | + | |
41650 | if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) { | |
41651 | log_error_write(srv, __FILE__, __LINE__, "ss", "open failed:", strerror(errno)); | |
41652 | - | |
41653 | + | |
41654 | return -1; | |
41655 | } | |
f673a614 | 41656 | |
2519e6e5 ER |
41657 | @@ -183,9 +255,9 @@ |
41658 | } | |
f26f9fd5 | 41659 | |
2519e6e5 ER |
41660 | s = local_send_buffer; |
41661 | - | |
41662 | + | |
41663 | close(ifd); | |
41664 | - | |
41665 | + | |
41666 | if ((r = SSL_write(ssl, s, toSend)) <= 0) { | |
41667 | unsigned long err; | |
41668 | ||
41669 | @@ -197,7 +269,7 @@ | |
41670 | /* perhaps we have error waiting in our error-queue */ | |
41671 | if (0 != (err = ERR_get_error())) { | |
41672 | do { | |
41673 | - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41674 | + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41675 | ssl_r, r, | |
41676 | ERR_error_string(err, NULL)); | |
41677 | } while((err = ERR_get_error())); | |
41678 | @@ -207,58 +279,58 @@ | |
41679 | case EPIPE: | |
41680 | return -2; | |
41681 | default: | |
41682 | - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", | |
41683 | + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", | |
41684 | ssl_r, r, errno, | |
41685 | strerror(errno)); | |
41686 | break; | |
41687 | } | |
41688 | } else { | |
41689 | /* neither error-queue nor errno ? */ | |
41690 | - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", | |
41691 | + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", | |
41692 | ssl_r, r, errno, | |
41693 | strerror(errno)); | |
41694 | } | |
41695 | - | |
41696 | + | |
41697 | return -1; | |
41698 | case SSL_ERROR_ZERO_RETURN: | |
41699 | /* clean shutdown on the remote side */ | |
41700 | - | |
41701 | + | |
41702 | if (r == 0) return -2; | |
41703 | - | |
41704 | + | |
41705 | /* fall thourgh */ | |
41706 | default: | |
41707 | while((err = ERR_get_error())) { | |
41708 | - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41709 | + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", | |
41710 | ssl_r, r, | |
41711 | ERR_error_string(err, NULL)); | |
41712 | } | |
41713 | - | |
41714 | + | |
41715 | return -1; | |
41716 | } | |
41717 | } else { | |
41718 | c->offset += r; | |
41719 | cq->bytes_out += r; | |
41720 | } | |
41721 | - | |
41722 | + | |
41723 | if (c->offset == c->file.length) { | |
41724 | chunk_finished = 1; | |
41725 | } | |
41726 | } while(!chunk_finished && !write_wait); | |
41727 | - | |
41728 | + | |
41729 | break; | |
41730 | } | |
41731 | default: | |
41732 | log_error_write(srv, __FILE__, __LINE__, "s", "type not known"); | |
41733 | - | |
41734 | + | |
41735 | return -1; | |
41736 | } | |
41737 | - | |
41738 | + | |
41739 | if (!chunk_finished) { | |
41740 | /* not finished yet */ | |
41741 | - | |
41742 | + | |
41743 | break; | |
41744 | } | |
41745 | - | |
41746 | + | |
41747 | chunks_written++; | |
41748 | } | |
f673a614 | 41749 | |
1175ccec | 41750 | --- ../lighttpd-1.4.11/src/network_solaris_sendfilev.c 2005-10-22 12:28:27.000000000 +0300 |
36e2a29e | 41751 | +++ lighttpd-1.4.12/src/network_solaris_sendfilev.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
41752 | @@ -29,114 +29,34 @@ |
41753 | #endif | |
f673a614 | 41754 | |
2519e6e5 ER |
41755 | /** |
41756 | - * a very simple sendfilev() interface for solaris which can be optimised a lot more | |
41757 | + * a very simple sendfilev() interface for solaris which can be optimised a lot more | |
41758 | * as solaris sendfilev() supports 'sending everythin in one syscall()' | |
41759 | - * | |
41760 | - * If you want such an interface and need the performance, just give me an account on | |
41761 | - * a solaris box. | |
41762 | + * | |
41763 | + * If you want such an interface and need the performance, just give me an account on | |
41764 | + * a solaris box. | |
41765 | * - jan@kneschke.de | |
41766 | */ | |
f673a614 | 41767 | |
f673a614 | 41768 | |
2519e6e5 ER |
41769 | -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq) { |
41770 | +NETWORK_BACKEND_WRITE(solarissendfilev) { | |
41771 | chunk *c; | |
41772 | size_t chunks_written = 0; | |
41773 | - | |
41774 | + | |
41775 | for(c = cq->first; c; c = c->next, chunks_written++) { | |
41776 | int chunk_finished = 0; | |
41777 | - | |
41778 | + network_status_t ret; | |
41779 | + | |
41780 | switch(c->type) { | |
41781 | - case MEM_CHUNK: { | |
41782 | - char * offset; | |
41783 | - size_t toSend; | |
41784 | - ssize_t r; | |
41785 | - | |
41786 | - size_t num_chunks, i; | |
41787 | - struct iovec chunks[UIO_MAXIOV]; | |
41788 | - chunk *tc; | |
41789 | - | |
41790 | - size_t num_bytes = 0; | |
41791 | - | |
41792 | - /* we can't send more then SSIZE_MAX bytes in one chunk */ | |
41793 | - | |
41794 | - /* build writev list | |
41795 | - * | |
41796 | - * 1. limit: num_chunks < UIO_MAXIOV | |
41797 | - * 2. limit: num_bytes < SSIZE_MAX | |
41798 | - */ | |
41799 | - for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next); | |
41800 | - | |
41801 | - for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) { | |
41802 | - if (tc->mem->used == 0) { | |
41803 | - chunks[i].iov_base = tc->mem->ptr; | |
41804 | - chunks[i].iov_len = 0; | |
41805 | - } else { | |
41806 | - offset = tc->mem->ptr + tc->offset; | |
41807 | - toSend = tc->mem->used - 1 - tc->offset; | |
41808 | - | |
41809 | - chunks[i].iov_base = offset; | |
41810 | - | |
41811 | - /* protect the return value of writev() */ | |
41812 | - if (toSend > SSIZE_MAX || | |
41813 | - num_bytes + toSend > SSIZE_MAX) { | |
41814 | - chunks[i].iov_len = SSIZE_MAX - num_bytes; | |
41815 | - | |
41816 | - num_chunks = i + 1; | |
41817 | - break; | |
41818 | - } else { | |
41819 | - chunks[i].iov_len = toSend; | |
41820 | - } | |
41821 | - | |
41822 | - num_bytes += toSend; | |
41823 | - } | |
41824 | - } | |
41825 | - | |
41826 | - if ((r = writev(fd, chunks, num_chunks)) < 0) { | |
41827 | - switch (errno) { | |
41828 | - case EAGAIN: | |
41829 | - case EINTR: | |
41830 | - r = 0; | |
41831 | - break; | |
41832 | - case EPIPE: | |
41833 | - case ECONNRESET: | |
41834 | - return -2; | |
41835 | - default: | |
41836 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
41837 | - "writev failed:", strerror(errno), fd); | |
41838 | - | |
41839 | - return -1; | |
41840 | - } | |
41841 | - } | |
41842 | - | |
41843 | - /* check which chunks have been written */ | |
41844 | - cq->bytes_out += r; | |
41845 | - | |
41846 | - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) { | |
41847 | - if (r >= (ssize_t)chunks[i].iov_len) { | |
41848 | - /* written */ | |
41849 | - r -= chunks[i].iov_len; | |
41850 | - tc->offset += chunks[i].iov_len; | |
41851 | - | |
41852 | - if (chunk_finished) { | |
41853 | - /* skip the chunks from further touches */ | |
41854 | - chunks_written++; | |
41855 | - c = c->next; | |
41856 | - } else { | |
41857 | - /* chunks_written + c = c->next is done in the for()*/ | |
41858 | - chunk_finished++; | |
41859 | - } | |
41860 | - } else { | |
41861 | - /* partially written */ | |
41862 | - | |
41863 | - tc->offset += r; | |
41864 | - chunk_finished = 0; | |
41865 | - | |
41866 | - break; | |
41867 | - } | |
41868 | + case MEM_CHUNK: | |
41869 | + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c); | |
41870 | + | |
41871 | + if (ret != NETWORK_STATUS_SUCCESS) { | |
41872 | + return ret; | |
41873 | } | |
41874 | - | |
41875 | + | |
41876 | + chunk_finished = 1; | |
41877 | + | |
41878 | break; | |
41879 | - } | |
41880 | case FILE_CHUNK: { | |
41881 | ssize_t r; | |
41882 | off_t offset; | |
41883 | @@ -144,25 +64,25 @@ | |
41884 | sendfilevec_t fvec; | |
41885 | stat_cache_entry *sce = NULL; | |
41886 | int ifd; | |
41887 | - | |
41888 | + | |
41889 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { | |
41890 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
41891 | strerror(errno), c->file.name); | |
41892 | return -1; | |
41893 | } | |
41894 | - | |
41895 | + | |
41896 | offset = c->file.start + c->offset; | |
41897 | toSend = c->file.length - c->offset; | |
41898 | - | |
41899 | + | |
41900 | if (offset > sce->st.st_size) { | |
41901 | log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name); | |
41902 | - | |
41903 | + | |
41904 | return -1; | |
41905 | } | |
f673a614 | 41906 | |
2519e6e5 ER |
41907 | if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) { |
41908 | log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
41909 | - | |
41910 | + | |
41911 | return -1; | |
41912 | } | |
f673a614 | 41913 | |
2519e6e5 ER |
41914 | @@ -170,44 +90,43 @@ |
41915 | fvec.sfv_flag = 0; | |
41916 | fvec.sfv_off = offset; | |
41917 | fvec.sfv_len = toSend; | |
41918 | - | |
41919 | + | |
41920 | /* Solaris sendfilev() */ | |
41921 | if (-1 == (r = sendfilev(fd, &fvec, 1, &written))) { | |
41922 | if (errno != EAGAIN) { | |
41923 | log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno); | |
41924 | - | |
41925 | + | |
41926 | close(ifd); | |
41927 | - return -1; | |
41928 | + return NETWORK_STATUS_FATAL_ERROR; | |
41929 | } | |
41930 | - | |
41931 | + | |
41932 | r = 0; | |
41933 | } | |
41934 | - | |
41935 | + | |
41936 | close(ifd); | |
41937 | c->offset += written; | |
41938 | cq->bytes_out += written; | |
41939 | - | |
41940 | + | |
41941 | if (c->offset == c->file.length) { | |
41942 | chunk_finished = 1; | |
41943 | } | |
41944 | - | |
41945 | + | |
41946 | break; | |
41947 | } | |
41948 | default: | |
41949 | - | |
41950 | log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known"); | |
41951 | - | |
41952 | - return -1; | |
41953 | + | |
41954 | + return NETWORK_STATUS_FATAL_ERROR; | |
41955 | } | |
41956 | - | |
41957 | + | |
41958 | if (!chunk_finished) { | |
41959 | /* not finished yet */ | |
41960 | - | |
41961 | + | |
41962 | break; | |
41963 | } | |
41964 | } | |
f673a614 | 41965 | |
2519e6e5 ER |
41966 | - return chunks_written; |
41967 | + return NETWORK_STATUS_SUCCESS; | |
41968 | } | |
f673a614 | 41969 | |
2519e6e5 | 41970 | #endif |
1175ccec ER |
41971 | --- ../lighttpd-1.4.11/src/network_write.c 2005-10-22 12:27:56.000000000 +0300 |
41972 | +++ lighttpd-1.4.12/src/network_write.c 2006-07-15 22:43:21.000000000 +0300 | |
2519e6e5 ER |
41973 | @@ -1,11 +1,11 @@ |
41974 | #include <sys/types.h> | |
41975 | #include <sys/stat.h> | |
41976 | -#include <sys/time.h> | |
41977 | + | |
41978 | #include <errno.h> | |
41979 | #include <fcntl.h> | |
41980 | -#include <unistd.h> | |
41981 | #include <string.h> | |
41982 | #include <stdlib.h> | |
41983 | +#include <assert.h> | |
f673a614 | 41984 | |
2519e6e5 ER |
41985 | #include "network.h" |
41986 | #include "fdevent.h" | |
41987 | @@ -13,9 +13,12 @@ | |
41988 | #include "stat_cache.h" | |
f673a614 | 41989 | |
2519e6e5 ER |
41990 | #include "sys-socket.h" |
41991 | +#include "sys-files.h" | |
f673a614 | 41992 | |
2519e6e5 | 41993 | #include "network_backends.h" |
f673a614 | 41994 | |
2519e6e5 ER |
41995 | +#ifdef USE_WRITE |
41996 | + | |
41997 | #ifdef HAVE_SYS_FILIO_H | |
41998 | # include <sys/filio.h> | |
41999 | #endif | |
1175ccec | 42000 | @@ -24,47 +27,84 @@ |
2519e6e5 ER |
42001 | #include <sys/resource.h> |
42002 | #endif | |
f673a614 | 42003 | |
2519e6e5 ER |
42004 | -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq) { |
42005 | +/** | |
42006 | +* fill the chunkqueue will all the data that we can get | |
42007 | +* | |
42008 | +* this might be optimized into a readv() which uses the chunks | |
42009 | +* as vectors | |
42010 | +*/ | |
42011 | +NETWORK_BACKEND_READ(read) { | |
1175ccec ER |
42012 | + int toread; |
42013 | + buffer *b; | |
42014 | + off_t r; | |
2519e6e5 | 42015 | + |
1175ccec ER |
42016 | + /* use a chunk-size of 8k */ |
42017 | + do { | |
42018 | + toread = 8192; | |
2519e6e5 | 42019 | + |
1175ccec | 42020 | + b = chunkqueue_get_append_buffer(cq); |
2519e6e5 | 42021 | + |
1175ccec | 42022 | + buffer_prepare_copy(b, toread); |
2519e6e5 | 42023 | + |
1175ccec ER |
42024 | + if (-1 == (r = read(fd, b->ptr, toread))) { |
42025 | + switch (errno) { | |
42026 | + case EAGAIN: | |
42027 | + return NETWORK_STATUS_WAIT_FOR_EVENT; | |
42028 | + default: | |
42029 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
42030 | + "unexpected end-of-file (perhaps the proxy process died):", | |
42031 | + fd, strerror(errno)); | |
42032 | + return NETWORK_STATUS_FATAL_ERROR; | |
42033 | + } | |
42034 | + } | |
2519e6e5 | 42035 | + |
1175ccec ER |
42036 | + if (r == 0) { |
42037 | + return NETWORK_STATUS_CONNECTION_CLOSE; | |
42038 | + } | |
2519e6e5 | 42039 | + |
1175ccec ER |
42040 | + /* this should be catched by the b > 0 above */ |
42041 | + assert(r); | |
42042 | + b->used += r + 1; | |
42043 | + b->ptr[b->used - 1] = '\0'; | |
42044 | + } while (r == toread); | |
2519e6e5 | 42045 | + |
1175ccec | 42046 | + return NETWORK_STATUS_SUCCESS; |
2519e6e5 ER |
42047 | +} |
42048 | + | |
42049 | +NETWORK_BACKEND_WRITE(write) { | |
42050 | chunk *c; | |
42051 | size_t chunks_written = 0; | |
42052 | - | |
42053 | + | |
42054 | for(c = cq->first; c; c = c->next) { | |
42055 | int chunk_finished = 0; | |
42056 | - | |
42057 | + | |
42058 | switch(c->type) { | |
42059 | case MEM_CHUNK: { | |
42060 | char * offset; | |
42061 | size_t toSend; | |
42062 | ssize_t r; | |
42063 | - | |
42064 | + | |
42065 | if (c->mem->used == 0) { | |
42066 | chunk_finished = 1; | |
42067 | break; | |
42068 | } | |
42069 | - | |
42070 | + | |
42071 | offset = c->mem->ptr + c->offset; | |
42072 | toSend = c->mem->used - 1 - c->offset; | |
42073 | -#ifdef __WIN32 | |
42074 | - if ((r = send(fd, offset, toSend, 0)) < 0) { | |
42075 | - log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd); | |
42076 | - | |
42077 | - return -1; | |
42078 | - } | |
42079 | -#else | |
42080 | + | |
42081 | if ((r = write(fd, offset, toSend)) < 0) { | |
42082 | log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd); | |
42083 | - | |
42084 | - return -1; | |
42085 | + | |
42086 | + return NETWORK_STATUS_FATAL_ERROR; | |
42087 | } | |
42088 | -#endif | |
42089 | - | |
42090 | + | |
42091 | c->offset += r; | |
42092 | cq->bytes_out += r; | |
42093 | - | |
42094 | + | |
42095 | if (c->offset == (off_t)c->mem->used - 1) { | |
42096 | chunk_finished = 1; | |
42097 | } | |
42098 | - | |
42099 | + | |
42100 | break; | |
42101 | } | |
42102 | case FILE_CHUNK: { | |
1175ccec | 42103 | @@ -76,93 +116,89 @@ |
2519e6e5 ER |
42104 | size_t toSend; |
42105 | stat_cache_entry *sce = NULL; | |
42106 | int ifd; | |
42107 | - | |
42108 | + | |
42109 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { | |
42110 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
42111 | strerror(errno), c->file.name); | |
42112 | - return -1; | |
42113 | + return NETWORK_STATUS_FATAL_ERROR; | |
42114 | } | |
42115 | - | |
42116 | + | |
42117 | offset = c->file.start + c->offset; | |
42118 | toSend = c->file.length - c->offset; | |
42119 | - | |
42120 | + | |
42121 | if (offset > sce->st.st_size) { | |
42122 | log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name); | |
42123 | - | |
42124 | - return -1; | |
42125 | + | |
42126 | + return NETWORK_STATUS_FATAL_ERROR; | |
42127 | } | |
f673a614 | 42128 | |
2519e6e5 ER |
42129 | if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) { |
42130 | log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); | |
42131 | - | |
42132 | - return -1; | |
42133 | + | |
42134 | + return NETWORK_STATUS_FATAL_ERROR; | |
42135 | } | |
42136 | - | |
42137 | + | |
42138 | #if defined USE_MMAP | |
42139 | if (MAP_FAILED == (p = mmap(0, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { | |
42140 | log_error_write(srv, __FILE__, __LINE__, "ss", "mmap failed: ", strerror(errno)); | |
f673a614 | 42141 | |
2519e6e5 ER |
42142 | close(ifd); |
42143 | - | |
42144 | - return -1; | |
42145 | + | |
42146 | + return NETWORK_STATUS_FATAL_ERROR; | |
42147 | } | |
42148 | close(ifd); | |
42149 | ||
42150 | if ((r = write(fd, p + offset, toSend)) <= 0) { | |
42151 | log_error_write(srv, __FILE__, __LINE__, "ss", "write failed: ", strerror(errno)); | |
42152 | munmap(p, sce->st.st_size); | |
42153 | - return -1; | |
42154 | + return NETWORK_STATUS_FATAL_ERROR; | |
42155 | } | |
42156 | - | |
42157 | + | |
42158 | munmap(p, sce->st.st_size); | |
42159 | #else | |
42160 | buffer_prepare_copy(srv->tmp_buf, toSend); | |
42161 | - | |
42162 | + | |
42163 | lseek(ifd, offset, SEEK_SET); | |
42164 | if (-1 == (toSend = read(ifd, srv->tmp_buf->ptr, toSend))) { | |
42165 | log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno)); | |
42166 | close(ifd); | |
42167 | - | |
42168 | - return -1; | |
42169 | + | |
42170 | + return NETWORK_STATUS_FATAL_ERROR; | |
42171 | } | |
42172 | close(ifd); | |
42173 | ||
42174 | if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) { | |
42175 | log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno)); | |
42176 | - | |
42177 | - return -1; | |
42178 | + | |
42179 | + return NETWORK_STATUS_FATAL_ERROR; | |
42180 | } | |
42181 | #endif | |
42182 | c->offset += r; | |
42183 | cq->bytes_out += r; | |
42184 | - | |
42185 | + | |
42186 | if (c->offset == c->file.length) { | |
42187 | chunk_finished = 1; | |
42188 | } | |
42189 | - | |
42190 | + | |
42191 | break; | |
f673a614 | 42192 | } |
2519e6e5 ER |
42193 | default: |
42194 | - | |
42195 | + | |
42196 | log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known"); | |
42197 | - | |
42198 | - return -1; | |
42199 | + | |
42200 | + return NETWORK_STATUS_FATAL_ERROR; | |
f673a614 | 42201 | } |
2519e6e5 ER |
42202 | - |
42203 | + | |
42204 | if (!chunk_finished) { | |
42205 | /* not finished yet */ | |
42206 | - | |
42207 | + | |
42208 | break; | |
f26f9fd5 | 42209 | } |
2519e6e5 ER |
42210 | - |
42211 | + | |
42212 | chunks_written++; | |
42213 | } | |
42214 | ||
42215 | - return chunks_written; | |
42216 | + return NETWORK_STATUS_SUCCESS; | |
f673a614 ER |
42217 | } |
42218 | ||
2519e6e5 ER |
42219 | -#if 0 |
42220 | -network_write_init(void) { | |
42221 | - p->write = network_write_write_chunkset; | |
42222 | -} | |
42223 | #endif | |
1175ccec ER |
42224 | --- ../lighttpd-1.4.11/src/network_writev.c 2006-02-15 01:02:36.000000000 +0200 |
42225 | +++ lighttpd-1.4.12/src/network_writev.c 2006-07-15 22:43:21.000000000 +0300 | |
2519e6e5 ER |
42226 | @@ -28,10 +28,10 @@ |
42227 | ||
42228 | #ifndef UIO_MAXIOV | |
42229 | # if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__) | |
42230 | -/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */ | |
42231 | +/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */ | |
42232 | # define UIO_MAXIOV 1024 | |
42233 | # elif defined(__sgi) | |
42234 | -/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */ | |
42235 | +/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */ | |
42236 | # define UIO_MAXIOV 512 | |
42237 | # elif defined(__sun) | |
42238 | /* Solaris (and SunOS?) defines IOV_MAX instead */ | |
1175ccec | 42239 | @@ -51,105 +51,121 @@ |
2519e6e5 ER |
42240 | #define LOCAL_BUFFERING 1 |
42241 | #endif | |
42242 | ||
42243 | -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq) { | |
42244 | - chunk *c; | |
42245 | +NETWORK_BACKEND_WRITE_CHUNK(writev_mem) { | |
42246 | + char * offset; | |
42247 | + size_t toSend; | |
42248 | + ssize_t r; | |
42249 | + | |
42250 | + size_t num_chunks, i; | |
42251 | + struct iovec chunks[UIO_MAXIOV]; | |
42252 | + chunk *tc; /* transfer chunks */ | |
42253 | + size_t num_bytes = 0; | |
42254 | + | |
42255 | + /* we can't send more then SSIZE_MAX bytes in one chunk */ | |
42256 | + | |
42257 | + /* build writev list | |
42258 | + * | |
42259 | + * 1. limit: num_chunks < UIO_MAXIOV | |
42260 | + * 2. limit: num_bytes < SSIZE_MAX | |
42261 | + */ | |
42262 | + for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next); | |
42263 | + | |
42264 | + for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) { | |
42265 | + if (tc->mem->used == 0) { | |
42266 | + chunks[i].iov_base = tc->mem->ptr; | |
42267 | + chunks[i].iov_len = 0; | |
42268 | + } else { | |
42269 | + offset = tc->mem->ptr + tc->offset; | |
42270 | + toSend = tc->mem->used - 1 - tc->offset; | |
42271 | + | |
42272 | + chunks[i].iov_base = offset; | |
42273 | + | |
42274 | + /* protect the return value of writev() */ | |
42275 | + if (toSend > SSIZE_MAX || | |
42276 | + num_bytes + toSend > SSIZE_MAX) { | |
42277 | + chunks[i].iov_len = SSIZE_MAX - num_bytes; | |
42278 | + | |
42279 | + num_chunks = i + 1; | |
42280 | + break; | |
42281 | + } else { | |
42282 | + chunks[i].iov_len = toSend; | |
42283 | + } | |
42284 | + | |
42285 | + num_bytes += toSend; | |
42286 | + } | |
42287 | + } | |
42288 | + | |
42289 | + if ((r = writev(fd, chunks, num_chunks)) < 0) { | |
42290 | + switch (errno) { | |
42291 | + case EAGAIN: | |
1175ccec | 42292 | + return NETWORK_STATUS_WAIT_FOR_EVENT; |
2519e6e5 | 42293 | + case EINTR: |
1175ccec | 42294 | + return NETWORK_STATUS_INTERRUPTED; |
2519e6e5 ER |
42295 | + case EPIPE: |
42296 | + case ECONNRESET: | |
42297 | + return NETWORK_STATUS_CONNECTION_CLOSE; | |
42298 | + default: | |
42299 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
42300 | + "writev failed:", strerror(errno), fd); | |
42301 | + | |
42302 | + return NETWORK_STATUS_FATAL_ERROR; | |
42303 | + } | |
42304 | + } | |
42305 | + | |
42306 | + cq->bytes_out += r; | |
42307 | + | |
42308 | + /* check which chunks have been written */ | |
42309 | + | |
42310 | + for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) { | |
42311 | + if (r >= (ssize_t)chunks[i].iov_len) { | |
42312 | + /* written */ | |
42313 | + r -= chunks[i].iov_len; | |
42314 | + tc->offset += chunks[i].iov_len; | |
42315 | + } else { | |
42316 | + /* partially written */ | |
42317 | + | |
42318 | + tc->offset += r; | |
1175ccec ER |
42319 | + |
42320 | + return NETWORK_STATUS_WAIT_FOR_EVENT; | |
2519e6e5 ER |
42321 | + } |
42322 | + } | |
42323 | + | |
1175ccec | 42324 | + /* all chunks have been pushed out */ |
2519e6e5 ER |
42325 | + return NETWORK_STATUS_SUCCESS; |
42326 | +} | |
42327 | + | |
42328 | +NETWORK_BACKEND_WRITE(writev) { | |
42329 | + chunk *c, *tc; | |
42330 | size_t chunks_written = 0; | |
42331 | - | |
42332 | + | |
42333 | for(c = cq->first; c; c = c->next) { | |
42334 | int chunk_finished = 0; | |
42335 | - | |
42336 | + network_status_t ret; | |
42337 | + | |
42338 | switch(c->type) { | |
42339 | - case MEM_CHUNK: { | |
42340 | - char * offset; | |
42341 | - size_t toSend; | |
42342 | - ssize_t r; | |
42343 | - | |
42344 | - size_t num_chunks, i; | |
42345 | - struct iovec chunks[UIO_MAXIOV]; | |
42346 | - chunk *tc; | |
42347 | - size_t num_bytes = 0; | |
42348 | - | |
42349 | - /* we can't send more then SSIZE_MAX bytes in one chunk */ | |
42350 | - | |
42351 | - /* build writev list | |
42352 | - * | |
42353 | - * 1. limit: num_chunks < UIO_MAXIOV | |
42354 | - * 2. limit: num_bytes < SSIZE_MAX | |
42355 | - */ | |
42356 | - for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next); | |
42357 | - | |
42358 | - for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) { | |
42359 | - if (tc->mem->used == 0) { | |
42360 | - chunks[i].iov_base = tc->mem->ptr; | |
42361 | - chunks[i].iov_len = 0; | |
42362 | - } else { | |
42363 | - offset = tc->mem->ptr + tc->offset; | |
42364 | - toSend = tc->mem->used - 1 - tc->offset; | |
42365 | - | |
42366 | - chunks[i].iov_base = offset; | |
42367 | - | |
42368 | - /* protect the return value of writev() */ | |
42369 | - if (toSend > SSIZE_MAX || | |
42370 | - num_bytes + toSend > SSIZE_MAX) { | |
42371 | - chunks[i].iov_len = SSIZE_MAX - num_bytes; | |
42372 | - | |
42373 | - num_chunks = i + 1; | |
42374 | - break; | |
42375 | - } else { | |
42376 | - chunks[i].iov_len = toSend; | |
42377 | - } | |
42378 | - | |
42379 | - num_bytes += toSend; | |
42380 | - } | |
42381 | - } | |
42382 | - | |
42383 | - if ((r = writev(fd, chunks, num_chunks)) < 0) { | |
42384 | - switch (errno) { | |
42385 | - case EAGAIN: | |
42386 | - case EINTR: | |
42387 | - r = 0; | |
42388 | - break; | |
42389 | - case EPIPE: | |
42390 | - case ECONNRESET: | |
42391 | - return -2; | |
42392 | - default: | |
42393 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
42394 | - "writev failed:", strerror(errno), fd); | |
42395 | - | |
42396 | - return -1; | |
42397 | - } | |
42398 | - } | |
42399 | - | |
42400 | - cq->bytes_out += r; | |
42401 | + case MEM_CHUNK: | |
42402 | + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c); | |
42403 | ||
42404 | - /* check which chunks have been written */ | |
42405 | - | |
42406 | - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) { | |
42407 | - if (r >= (ssize_t)chunks[i].iov_len) { | |
42408 | - /* written */ | |
42409 | - r -= chunks[i].iov_len; | |
42410 | - tc->offset += chunks[i].iov_len; | |
42411 | - | |
42412 | + /* check which chunks are finished now */ | |
42413 | + for (tc = c; tc; tc = tc->next) { | |
42414 | + /* finished the chunk */ | |
42415 | + if (tc->offset == tc->mem->used - 1) { | |
42416 | + /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */ | |
42417 | if (chunk_finished) { | |
42418 | - /* skip the chunks from further touches */ | |
42419 | - chunks_written++; | |
42420 | c = c->next; | |
42421 | } else { | |
42422 | - /* chunks_written + c = c->next is done in the for()*/ | |
42423 | - chunk_finished++; | |
42424 | + chunk_finished = 1; | |
42425 | } | |
42426 | } else { | |
42427 | - /* partially written */ | |
42428 | - | |
42429 | - tc->offset += r; | |
42430 | - chunk_finished = 0; | |
42431 | - | |
42432 | break; | |
42433 | } | |
42434 | } | |
42435 | - | |
42436 | + | |
42437 | + if (ret != NETWORK_STATUS_SUCCESS) { | |
42438 | + return ret; | |
42439 | + } | |
42440 | + | |
42441 | break; | |
42442 | - } | |
42443 | case FILE_CHUNK: { | |
42444 | ssize_t r; | |
42445 | off_t abs_offset; | |
1175ccec | 42446 | @@ -159,26 +175,26 @@ |
2519e6e5 ER |
42447 | #define KByte * 1024 |
42448 | #define MByte * 1024 KByte | |
42449 | #define GByte * 1024 MByte | |
42450 | - const off_t we_want_to_mmap = 512 KByte; | |
42451 | + const off_t we_want_to_mmap = 512 KByte; | |
42452 | char *start = NULL; | |
f673a614 | 42453 | |
2519e6e5 ER |
42454 | if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { |
42455 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
42456 | strerror(errno), c->file.name); | |
42457 | - return -1; | |
42458 | + return NETWORK_STATUS_FATAL_ERROR; | |
42459 | } | |
f673a614 | 42460 | |
2519e6e5 ER |
42461 | abs_offset = c->file.start + c->offset; |
42462 | - | |
42463 | + | |
42464 | if (abs_offset > sce->st.st_size) { | |
42465 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
42466 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
42467 | "file was shrinked:", c->file.name); | |
42468 | - | |
42469 | - return -1; | |
42470 | + | |
42471 | + return NETWORK_STATUS_FATAL_ERROR; | |
f26f9fd5 | 42472 | } |
f673a614 | 42473 | |
2519e6e5 ER |
42474 | - /* mmap the buffer |
42475 | - * - first mmap | |
42476 | + /* mmap the buffer | |
42477 | + * - first mmap | |
42478 | * - new mmap as the we are at the end of the last one */ | |
42479 | if (c->file.mmap.start == MAP_FAILED || | |
42480 | abs_offset == (off_t)(c->file.mmap.offset + c->file.mmap.length)) { | |
1175ccec | 42481 | @@ -188,7 +204,7 @@ |
2519e6e5 ER |
42482 | * adaptive mem-mapping |
42483 | * the problem: | |
42484 | * we mmap() the whole file. If someone has alot large files and 32bit | |
42485 | - * machine the virtual address area will be unrun and we will have a failing | |
42486 | + * machine the virtual address area will be unrun and we will have a failing | |
42487 | * mmap() call. | |
42488 | * solution: | |
42489 | * only mmap 16M in one chunk and move the window as soon as we have finished | |
1175ccec | 42490 | @@ -234,8 +250,8 @@ |
2519e6e5 ER |
42491 | if (-1 == c->file.fd) { /* open the file if not already open */ |
42492 | if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { | |
42493 | log_error_write(srv, __FILE__, __LINE__, "sbs", "open failed for:", c->file.name, strerror(errno)); | |
42494 | - | |
42495 | - return -1; | |
42496 | + | |
42497 | + return NETWORK_STATUS_FATAL_ERROR; | |
42498 | } | |
42499 | #ifdef FD_CLOEXEC | |
42500 | fcntl(c->file.fd, F_SETFD, FD_CLOEXEC); | |
1175ccec | 42501 | @@ -245,10 +261,10 @@ |
2519e6e5 ER |
42502 | if (MAP_FAILED == (c->file.mmap.start = mmap(0, to_mmap, PROT_READ, MAP_SHARED, c->file.fd, c->file.mmap.offset))) { |
42503 | /* close it here, otherwise we'd have to set FD_CLOEXEC */ | |
f673a614 | 42504 | |
2519e6e5 ER |
42505 | - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:", |
42506 | + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:", | |
42507 | strerror(errno), c->file.name, c->file.fd); | |
f673a614 | 42508 | |
2519e6e5 ER |
42509 | - return -1; |
42510 | + return NETWORK_STATUS_FATAL_ERROR; | |
42511 | } | |
f673a614 | 42512 | |
2519e6e5 | 42513 | c->file.mmap.length = to_mmap; |
1175ccec | 42514 | @@ -258,7 +274,7 @@ |
2519e6e5 ER |
42515 | #ifdef HAVE_MADVISE |
42516 | /* don't advise files < 64Kb */ | |
42517 | if (c->file.mmap.length > (64 KByte)) { | |
42518 | - /* darwin 7 is returning EINVAL all the time and I don't know how to | |
42519 | + /* darwin 7 is returning EINVAL all the time and I don't know how to | |
42520 | * detect this at runtime.i | |
42521 | * | |
42522 | * ignore the return value for now */ | |
1175ccec | 42523 | @@ -274,12 +290,12 @@ |
2519e6e5 ER |
42524 | toSend = (c->file.mmap.offset + c->file.mmap.length) - (abs_offset); |
42525 | ||
42526 | if (toSend < 0) { | |
42527 | - log_error_write(srv, __FILE__, __LINE__, "soooo", | |
42528 | + log_error_write(srv, __FILE__, __LINE__, "soooo", | |
42529 | "toSend is negative:", | |
42530 | toSend, | |
42531 | c->file.mmap.length, | |
42532 | abs_offset, | |
42533 | - c->file.mmap.offset); | |
42534 | + c->file.mmap.offset); | |
42535 | assert(toSend < 0); | |
42536 | } | |
42537 | ||
1175ccec | 42538 | @@ -297,18 +313,18 @@ |
2519e6e5 ER |
42539 | break; |
42540 | case EPIPE: | |
42541 | case ECONNRESET: | |
42542 | - return -2; | |
42543 | + return NETWORK_STATUS_CONNECTION_CLOSE; | |
42544 | default: | |
42545 | - log_error_write(srv, __FILE__, __LINE__, "ssd", | |
42546 | + log_error_write(srv, __FILE__, __LINE__, "ssd", | |
42547 | "write failed:", strerror(errno), fd); | |
42548 | - | |
42549 | - return -1; | |
42550 | + | |
42551 | + return NETWORK_STATUS_FATAL_ERROR; | |
42552 | } | |
f673a614 | 42553 | } |
2519e6e5 ER |
42554 | - |
42555 | + | |
42556 | c->offset += r; | |
42557 | cq->bytes_out += r; | |
42558 | - | |
42559 | + | |
42560 | if (c->offset == c->file.length) { | |
42561 | chunk_finished = 1; | |
42562 | ||
1175ccec | 42563 | @@ -318,26 +334,26 @@ |
2519e6e5 ER |
42564 | c->file.mmap.start = MAP_FAILED; |
42565 | } | |
42566 | } | |
42567 | - | |
42568 | + | |
42569 | break; | |
42570 | } | |
42571 | default: | |
42572 | - | |
42573 | + | |
42574 | log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known"); | |
42575 | - | |
42576 | - return -1; | |
42577 | + | |
42578 | + return NETWORK_STATUS_FATAL_ERROR; | |
42579 | } | |
42580 | - | |
42581 | + | |
42582 | if (!chunk_finished) { | |
42583 | /* not finished yet */ | |
42584 | - | |
42585 | + | |
42586 | break; | |
f673a614 | 42587 | } |
2519e6e5 ER |
42588 | - |
42589 | + | |
42590 | chunks_written++; | |
f673a614 | 42591 | } |
2519e6e5 ER |
42592 | |
42593 | - return chunks_written; | |
42594 | + return NETWORK_STATUS_SUCCESS; | |
f673a614 ER |
42595 | } |
42596 | ||
2519e6e5 | 42597 | #endif |
1175ccec | 42598 | --- ../lighttpd-1.4.11/src/plugin.c 2006-02-08 14:00:54.000000000 +0200 |
36e2a29e | 42599 | +++ lighttpd-1.4.12/src/plugin.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
42600 | @@ -13,27 +13,27 @@ |
42601 | #include <valgrind/valgrind.h> | |
42602 | #endif | |
f673a614 | 42603 | |
2519e6e5 ER |
42604 | -#ifndef __WIN32 |
42605 | +#ifndef _WIN32 | |
42606 | #include <dlfcn.h> | |
42607 | #endif | |
42608 | /* | |
42609 | - * | |
42610 | + * | |
42611 | * if you change this enum to add a new callback, be sure | |
42612 | * - that PLUGIN_FUNC_SIZEOF is the last entry | |
42613 | * - that you add PLUGIN_TO_SLOT twice: | |
42614 | - * 1. as callback-dispatcher | |
42615 | + * 1. as callback-dispatcher | |
42616 | * 2. in plugins_call_init() | |
42617 | - * | |
42618 | + * | |
42619 | */ | |
f26f9fd5 | 42620 | |
2519e6e5 ER |
42621 | typedef struct { |
42622 | PLUGIN_DATA; | |
42623 | } plugin_data; | |
f26f9fd5 | 42624 | |
2519e6e5 ER |
42625 | -typedef enum { |
42626 | +typedef enum { | |
42627 | PLUGIN_FUNC_UNSET, | |
42628 | - PLUGIN_FUNC_HANDLE_URI_CLEAN, | |
42629 | - PLUGIN_FUNC_HANDLE_URI_RAW, | |
42630 | + PLUGIN_FUNC_HANDLE_URI_CLEAN, | |
42631 | + PLUGIN_FUNC_HANDLE_URI_RAW, | |
42632 | PLUGIN_FUNC_HANDLE_REQUEST_DONE, | |
42633 | PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, | |
42634 | PLUGIN_FUNC_HANDLE_TRIGGER, | |
42635 | @@ -44,38 +44,42 @@ | |
42636 | PLUGIN_FUNC_HANDLE_DOCROOT, | |
42637 | PLUGIN_FUNC_HANDLE_PHYSICAL, | |
42638 | PLUGIN_FUNC_CONNECTION_RESET, | |
42639 | - PLUGIN_FUNC_INIT, | |
42640 | + PLUGIN_FUNC_INIT, | |
42641 | PLUGIN_FUNC_CLEANUP, | |
42642 | PLUGIN_FUNC_SET_DEFAULTS, | |
42643 | - | |
42644 | + | |
42645 | PLUGIN_FUNC_SIZEOF | |
42646 | } plugin_t; | |
f26f9fd5 | 42647 | |
2519e6e5 ER |
42648 | static plugin *plugin_init(void) { |
42649 | plugin *p; | |
42650 | - | |
42651 | + | |
42652 | p = calloc(1, sizeof(*p)); | |
42653 | - | |
42654 | + | |
42655 | + p->required_plugins = array_init(); | |
42656 | + | |
42657 | return p; | |
f26f9fd5 ER |
42658 | } |
42659 | ||
2519e6e5 ER |
42660 | static void plugin_free(plugin *p) { |
42661 | int use_dlclose = 1; | |
42662 | if (p->name) buffer_free(p->name); | |
42663 | + | |
42664 | + array_free(p->required_plugins); | |
42665 | #ifdef HAVE_VALGRIND_VALGRIND_H | |
42666 | /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/ | |
42667 | #endif | |
42668 | ||
42669 | #ifndef LIGHTTPD_STATIC | |
42670 | - if (use_dlclose && p->lib) { | |
42671 | -#ifdef __WIN32 | |
42672 | + if (use_dlclose && p->lib) { | |
42673 | +#ifdef _WIN32 | |
42674 | FreeLibrary(p->lib); | |
42675 | #else | |
42676 | dlclose(p->lib); | |
42677 | #endif | |
f673a614 | 42678 | } |
2519e6e5 ER |
42679 | #endif |
42680 | - | |
42681 | + | |
42682 | free(p); | |
42683 | } | |
42684 | ||
42685 | @@ -89,17 +93,17 @@ | |
42686 | srv->plugins.size += 4; | |
42687 | srv->plugins.ptr = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps)); | |
42688 | } | |
42689 | - | |
42690 | + | |
42691 | ps = srv->plugins.ptr; | |
42692 | ps[srv->plugins.used++] = p; | |
42693 | - | |
42694 | + | |
f26f9fd5 | 42695 | return 0; |
f673a614 ER |
42696 | } |
42697 | ||
2519e6e5 ER |
42698 | /** |
42699 | - * | |
42700 | - * | |
42701 | - * | |
42702 | + * | |
42703 | + * | |
42704 | + * | |
42705 | */ | |
f673a614 | 42706 | |
2519e6e5 ER |
42707 | #ifdef LIGHTTPD_STATIC |
42708 | @@ -121,30 +125,35 @@ | |
42709 | #else | |
42710 | int plugins_load(server *srv) { | |
42711 | plugin *p; | |
42712 | +#ifdef _WIN32 | |
42713 | + FARPROC init; | |
42714 | +#else | |
42715 | int (*init)(plugin *pl); | |
42716 | +#endif | |
42717 | + | |
42718 | const char *error; | |
42719 | - size_t i; | |
42720 | - | |
42721 | + size_t i, j, k; | |
42722 | + | |
42723 | for (i = 0; i < srv->srvconf.modules->used; i++) { | |
42724 | data_string *d = (data_string *)srv->srvconf.modules->data[i]; | |
42725 | char *modules = d->value->ptr; | |
42726 | - | |
42727 | + | |
42728 | buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir); | |
42729 | ||
42730 | buffer_append_string(srv->tmp_buf, "/"); | |
42731 | buffer_append_string(srv->tmp_buf, modules); | |
42732 | -#if defined(__WIN32) || defined(__CYGWIN__) | |
42733 | +#if defined(_WIN32) || defined(__CYGWIN__) | |
42734 | buffer_append_string(srv->tmp_buf, ".dll"); | |
42735 | #else | |
42736 | buffer_append_string(srv->tmp_buf, ".so"); | |
42737 | #endif | |
42738 | - | |
42739 | + | |
42740 | p = plugin_init(); | |
42741 | -#ifdef __WIN32 | |
42742 | +#ifdef _WIN32 | |
42743 | if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) { | |
42744 | LPVOID lpMsgBuf; | |
42745 | FormatMessage( | |
42746 | - FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
42747 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
42748 | FORMAT_MESSAGE_FROM_SYSTEM, | |
42749 | NULL, | |
42750 | GetLastError(), | |
42751 | @@ -152,36 +161,36 @@ | |
42752 | (LPTSTR) &lpMsgBuf, | |
42753 | 0, NULL ); | |
42754 | ||
42755 | - log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", | |
42756 | + log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", | |
42757 | lpMsgBuf, srv->tmp_buf); | |
42758 | - | |
42759 | + | |
42760 | plugin_free(p); | |
42761 | - | |
42762 | + | |
42763 | return -1; | |
42764 | ||
42765 | } | |
42766 | -#else | |
42767 | +#else | |
42768 | if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_LAZY))) { | |
42769 | - log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", | |
42770 | + log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", | |
42771 | srv->tmp_buf, dlerror()); | |
42772 | - | |
42773 | + | |
42774 | plugin_free(p); | |
42775 | - | |
42776 | + | |
42777 | return -1; | |
42778 | } | |
42779 | - | |
42780 | + | |
42781 | #endif | |
42782 | buffer_reset(srv->tmp_buf); | |
42783 | buffer_copy_string(srv->tmp_buf, modules); | |
42784 | buffer_append_string(srv->tmp_buf, "_plugin_init"); | |
42785 | ||
42786 | -#ifdef __WIN32 | |
42787 | +#ifdef _WIN32 | |
42788 | init = GetProcAddress(p->lib, srv->tmp_buf->ptr); | |
42789 | ||
42790 | if (init == NULL) { | |
42791 | LPVOID lpMsgBuf; | |
42792 | FormatMessage( | |
42793 | - FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
42794 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
42795 | FORMAT_MESSAGE_FROM_SYSTEM, | |
42796 | NULL, | |
42797 | GetLastError(), | |
42798 | @@ -190,7 +199,7 @@ | |
42799 | 0, NULL ); | |
42800 | ||
42801 | log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf); | |
42802 | - | |
42803 | + | |
42804 | plugin_free(p); | |
42805 | return -1; | |
42806 | } | |
42807 | @@ -203,24 +212,43 @@ | |
42808 | #endif | |
42809 | if ((error = dlerror()) != NULL) { | |
42810 | log_error_write(srv, __FILE__, __LINE__, "s", error); | |
42811 | - | |
42812 | + | |
42813 | plugin_free(p); | |
42814 | return -1; | |
42815 | } | |
42816 | - | |
42817 | + | |
42818 | #endif | |
42819 | if ((*init)(p)) { | |
42820 | log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin init failed" ); | |
42821 | - | |
42822 | + | |
42823 | plugin_free(p); | |
42824 | return -1; | |
42825 | } | |
42826 | #if 0 | |
42827 | log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" ); | |
42828 | #endif | |
42829 | + /* check if the required plugin is loaded */ | |
42830 | + for (k = 0; k < p->required_plugins->used; k++) { | |
42831 | + data_string *req = (data_string *)p->required_plugins->data[k]; | |
42832 | + | |
42833 | + for (j = 0; j < i; j++) { | |
42834 | + data_string *mod = (data_string *)srv->srvconf.modules->data[j]; | |
42835 | + | |
42836 | + if (buffer_is_equal(req->value, mod->value)) break; | |
42837 | + } | |
42838 | + | |
42839 | + if (j == i) { | |
42840 | + /* not found */ | |
42841 | + log_error_write(srv, __FILE__, __LINE__, "ssbs", modules, "failed to load. required plugin", req->value, "was not loaded" ); | |
42842 | + | |
42843 | + plugin_free(p); | |
42844 | + | |
42845 | + return -1; | |
42846 | + } | |
42847 | + } | |
42848 | plugins_register(srv, p); | |
42849 | } | |
42850 | - | |
42851 | + | |
42852 | return 0; | |
42853 | } | |
f673a614 | 42854 | #endif |
2519e6e5 ER |
42855 | @@ -253,8 +281,8 @@ |
42856 | } | |
f26f9fd5 | 42857 | |
2519e6e5 ER |
42858 | /** |
42859 | - * plugins that use | |
42860 | - * | |
42861 | + * plugins that use | |
42862 | + * | |
42863 | * - server *srv | |
42864 | * - connection *con | |
42865 | * - void *p_d (plugin_data *) | |
42866 | @@ -301,12 +329,12 @@ | |
42867 | } | |
42868 | ||
42869 | /** | |
42870 | - * plugins that use | |
42871 | - * | |
42872 | + * plugins that use | |
42873 | + * | |
42874 | * - server *srv | |
42875 | * - void *p_d (plugin_data *) | |
42876 | */ | |
42877 | - | |
f673a614 | 42878 | + |
2519e6e5 ER |
42879 | PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger) |
42880 | PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup) | |
42881 | PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup) | |
42882 | @@ -314,18 +342,18 @@ | |
f26f9fd5 | 42883 | |
2519e6e5 | 42884 | #undef PLUGIN_TO_SLOT |
f26f9fd5 | 42885 | |
2519e6e5 ER |
42886 | -#if 0 |
42887 | +#if 0 | |
f26f9fd5 | 42888 | /** |
2519e6e5 ER |
42889 | - * |
42890 | + * | |
42891 | * special handler | |
42892 | - * | |
42893 | + * | |
42894 | */ | |
42895 | handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) { | |
42896 | size_t i; | |
42897 | plugin **ps; | |
42898 | - | |
f673a614 | 42899 | + |
2519e6e5 ER |
42900 | ps = srv->plugins.ptr; |
42901 | - | |
f673a614 | 42902 | + |
2519e6e5 ER |
42903 | for (i = 0; i < srv->plugins.used; i++) { |
42904 | plugin *p = ps[i]; | |
42905 | if (p->handle_fdevent) { | |
42906 | @@ -344,34 +372,34 @@ | |
f673a614 | 42907 | } |
2519e6e5 ER |
42908 | } |
42909 | } | |
42910 | - | |
42911 | + | |
42912 | return HANDLER_GO_ON; | |
42913 | } | |
42914 | #endif | |
42915 | /** | |
42916 | - * | |
42917 | + * | |
42918 | * - call init function of all plugins to init the plugin-internals | |
42919 | * - added each plugin that supports has callback to the corresponding slot | |
42920 | - * | |
42921 | + * | |
42922 | * - is only called once. | |
42923 | */ | |
f26f9fd5 | 42924 | |
2519e6e5 ER |
42925 | handler_t plugins_call_init(server *srv) { |
42926 | size_t i; | |
42927 | plugin **ps; | |
42928 | - | |
f673a614 | 42929 | + |
2519e6e5 ER |
42930 | ps = srv->plugins.ptr; |
42931 | - | |
f673a614 | 42932 | + |
2519e6e5 ER |
42933 | /* fill slots */ |
42934 | - | |
f673a614 | 42935 | + |
2519e6e5 ER |
42936 | srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps)); |
42937 | - | |
f673a614 | 42938 | + |
2519e6e5 ER |
42939 | for (i = 0; i < srv->plugins.used; i++) { |
42940 | size_t j; | |
42941 | /* check which calls are supported */ | |
42942 | - | |
f673a614 | 42943 | + |
2519e6e5 ER |
42944 | plugin *p = ps[i]; |
42945 | - | |
f673a614 | 42946 | + |
2519e6e5 ER |
42947 | #define PLUGIN_TO_SLOT(x, y) \ |
42948 | if (p->y) { \ | |
42949 | plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \ | |
42950 | @@ -384,11 +412,11 @@ | |
42951 | slot[j] = p;\ | |
42952 | break;\ | |
42953 | }\ | |
42954 | - } | |
42955 | - | |
42956 | - | |
42957 | - PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); | |
42958 | - PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); | |
42959 | + } | |
f673a614 | 42960 | + |
f673a614 | 42961 | + |
2519e6e5 ER |
42962 | + PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); |
42963 | + PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); | |
42964 | PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done); | |
42965 | PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close); | |
42966 | PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger); | |
42967 | @@ -402,19 +430,19 @@ | |
42968 | PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup); | |
42969 | PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults); | |
42970 | #undef PLUGIN_TO_SLOT | |
42971 | - | |
f673a614 | 42972 | + |
2519e6e5 ER |
42973 | if (p->init) { |
42974 | if (NULL == (p->data = p->init())) { | |
42975 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
42976 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
42977 | "plugin-init failed for module", p->name); | |
42978 | return HANDLER_ERROR; | |
42979 | } | |
42980 | - | |
f673a614 | 42981 | + |
2519e6e5 ER |
42982 | /* used for con->mode, DIRECT == 0, plugins above that */ |
42983 | ((plugin_data *)(p->data))->id = i + 1; | |
42984 | - | |
f673a614 | 42985 | + |
2519e6e5 ER |
42986 | if (p->version != LIGHTTPD_VERSION_ID) { |
42987 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
42988 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
42989 | "plugin-version doesn't match lighttpd-version for", p->name); | |
42990 | return HANDLER_ERROR; | |
42991 | } | |
42992 | @@ -422,29 +450,46 @@ | |
42993 | p->data = NULL; | |
42994 | } | |
42995 | } | |
42996 | - | |
f673a614 | 42997 | + |
2519e6e5 ER |
42998 | return HANDLER_GO_ON; |
42999 | } | |
43000 | ||
43001 | +/** | |
43002 | + * get the config-storage of the named plugin | |
43003 | + */ | |
43004 | +void *plugin_get_config(server *srv, const char *name) { | |
43005 | + size_t i; | |
f673a614 | 43006 | + |
2519e6e5 ER |
43007 | + for (i = 0; i < srv->plugins.used; i++) { |
43008 | + plugin *p = ((plugin **)srv->plugins.ptr)[i]; | |
f673a614 | 43009 | + |
2519e6e5 ER |
43010 | + if (buffer_is_equal_string(p->name, name, strlen(name))) { |
43011 | + return p->data; | |
43012 | + } | |
43013 | + } | |
f673a614 | 43014 | + |
2519e6e5 ER |
43015 | + return NULL; |
43016 | +} | |
f673a614 | 43017 | + |
2519e6e5 ER |
43018 | void plugins_free(server *srv) { |
43019 | size_t i; | |
43020 | plugins_call_cleanup(srv); | |
43021 | - | |
f673a614 | 43022 | + |
2519e6e5 ER |
43023 | for (i = 0; i < srv->plugins.used; i++) { |
43024 | plugin *p = ((plugin **)srv->plugins.ptr)[i]; | |
43025 | - | |
f673a614 | 43026 | + |
2519e6e5 ER |
43027 | plugin_free(p); |
43028 | } | |
43029 | - | |
f673a614 | 43030 | + |
2519e6e5 ER |
43031 | for (i = 0; srv->plugin_slots && i < PLUGIN_FUNC_SIZEOF; i++) { |
43032 | plugin **slot = ((plugin ***)(srv->plugin_slots))[i]; | |
43033 | - | |
43034 | + | |
43035 | if (slot) free(slot); | |
43036 | } | |
43037 | - | |
43038 | + | |
43039 | free(srv->plugin_slots); | |
43040 | srv->plugin_slots = NULL; | |
43041 | - | |
43042 | + | |
43043 | free(srv->plugins.ptr); | |
43044 | srv->plugins.ptr = NULL; | |
43045 | srv->plugins.used = 0; | |
1175ccec | 43046 | --- ../lighttpd-1.4.11/src/plugin.h 2005-08-15 12:28:56.000000000 +0300 |
36e2a29e | 43047 | +++ lighttpd-1.4.12/src/plugin.h 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 | 43048 | @@ -12,6 +12,12 @@ |
f673a614 | 43049 | |
2519e6e5 ER |
43050 | #define INIT_FUNC(x) \ |
43051 | static void *x() | |
43052 | +/* | |
43053 | + * The PATCH_OPTION() macro is used in the patch_connection() functions | |
43054 | + * of the modules to update the config object for the current request. | |
43055 | + */ | |
43056 | +#define PATCH_OPTION(x) \ | |
43057 | + p->conf.x = s->x | |
43058 | ||
43059 | #define FREE_FUNC SERVER_FUNC | |
43060 | #define TRIGGER_FUNC SERVER_FUNC | |
43061 | @@ -25,19 +31,19 @@ | |
43062 | #define URIHANDLER_FUNC CONNECTION_FUNC | |
43063 | ||
43064 | #define PLUGIN_DATA size_t id | |
43065 | - | |
f673a614 | 43066 | + |
2519e6e5 ER |
43067 | typedef struct { |
43068 | size_t version; | |
43069 | - | |
f673a614 | 43070 | + |
2519e6e5 ER |
43071 | buffer *name; /* name of the plugin */ |
43072 | - | |
f673a614 | 43073 | + |
2519e6e5 ER |
43074 | void *(* init) (); |
43075 | handler_t (* set_defaults) (server *srv, void *p_d); | |
43076 | handler_t (* cleanup) (server *srv, void *p_d); | |
43077 | /* is called ... */ | |
43078 | handler_t (* handle_trigger) (server *srv, void *p_d); /* once a second */ | |
43079 | handler_t (* handle_sighup) (server *srv, void *p_d); /* at a signup */ | |
43080 | - | |
f26f9fd5 | 43081 | + |
2519e6e5 ER |
43082 | handler_t (* handle_uri_raw) (server *srv, connection *con, void *p_d); /* after uri_raw is set */ |
43083 | handler_t (* handle_uri_clean) (server *srv, connection *con, void *p_d); /* after uri is set */ | |
43084 | handler_t (* handle_docroot) (server *srv, connection *con, void *p_d); /* getting the document-root */ | |
43085 | @@ -45,20 +51,22 @@ | |
43086 | handler_t (* handle_request_done) (server *srv, connection *con, void *p_d); /* at the end of a request */ | |
43087 | handler_t (* handle_connection_close)(server *srv, connection *con, void *p_d); /* at the end of a connection */ | |
43088 | handler_t (* handle_joblist) (server *srv, connection *con, void *p_d); /* after all events are handled */ | |
43089 | - | |
43090 | - | |
43091 | - | |
43092 | - handler_t (* handle_subrequest_start)(server *srv, connection *con, void *p_d); | |
43093 | - | |
43094 | - /* when a handler for the request | |
43095 | + | |
43096 | + | |
43097 | + | |
43098 | + handler_t (* handle_subrequest_start)(server *srv, connection *con, void *p_d); | |
43099 | + | |
43100 | + /* when a handler for the request | |
43101 | * has to be found | |
43102 | */ | |
43103 | handler_t (* handle_subrequest) (server *srv, connection *con, void *p_d); /* */ | |
43104 | handler_t (* connection_reset) (server *srv, connection *con, void *p_d); /* */ | |
43105 | void *data; | |
43106 | - | |
43107 | + | |
43108 | /* dlopen handle */ | |
43109 | void *lib; | |
43110 | + | |
43111 | + array *required_plugins; | |
43112 | } plugin; | |
43113 | ||
43114 | int plugins_load(server *srv); | |
43115 | @@ -88,5 +96,8 @@ | |
43116 | int config_patch_connection(server *srv, connection *con, comp_key_t comp); | |
43117 | int config_check_cond(server *srv, connection *con, data_config *dc); | |
43118 | int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n); | |
43119 | +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result); | |
43120 | + | |
43121 | +void *plugin_get_config(server *srv, const char *name); | |
43122 | ||
43123 | #endif | |
1175ccec | 43124 | --- ../lighttpd-1.4.11/src/proc_open.c 2005-08-11 01:26:39.000000000 +0300 |
36e2a29e | 43125 | +++ lighttpd-1.4.12/src/proc_open.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 | 43126 | @@ -13,13 +13,13 @@ |
f26f9fd5 | 43127 | #endif |
f673a614 | 43128 | |
f26f9fd5 | 43129 | |
2519e6e5 ER |
43130 | -#ifdef WIN32 |
43131 | +#ifdef _WIN32 | |
43132 | /* {{{ win32 stuff */ | |
43133 | # define SHELLENV "ComSpec" | |
43134 | # define SECURITY_DC , SECURITY_ATTRIBUTES *security | |
43135 | # define SECURITY_CC , security | |
43136 | # define pipe(pair) (CreatePipe(&pair[0], &pair[1], security, 2048L) ? 0 : -1) | |
43137 | -static inline HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig) | |
43138 | +static HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig) | |
43139 | { | |
43140 | HANDLE copy, self = GetCurrentProcess(); | |
f26f9fd5 | 43141 | |
2519e6e5 ER |
43142 | @@ -148,11 +148,14 @@ |
43143 | STARTUPINFO si; | |
43144 | BOOL procok; | |
43145 | SECURITY_ATTRIBUTES security; | |
43146 | - const char *shell; | |
43147 | + const char *shell = NULL; | |
43148 | + const char *windir = NULL; | |
43149 | buffer *cmdline; | |
f26f9fd5 | 43150 | |
2519e6e5 ER |
43151 | - if (NULL == (shell = getenv(SHELLENV))) { |
43152 | - fprintf(stderr, "env %s is required", SHELLENV); | |
43153 | + if (NULL == (shell = getenv(SHELLENV)) && | |
43154 | + NULL == (windir = getenv("SystemRoot")) && | |
43155 | + NULL == (windir = getenv("windir"))) { | |
43156 | + fprintf(stderr, "One of %s,%%SystemRoot,%%windir is required", SHELLENV); | |
43157 | return -1; | |
43158 | } | |
f26f9fd5 | 43159 | |
2519e6e5 ER |
43160 | @@ -177,17 +180,23 @@ |
43161 | memset(&pi, 0, sizeof(pi)); | |
f26f9fd5 | 43162 | |
2519e6e5 ER |
43163 | cmdline = buffer_init(); |
43164 | - buffer_append_string(cmdline, shell); | |
43165 | + if (shell) { | |
43166 | + buffer_append_string(cmdline, shell); | |
43167 | + } else { | |
43168 | + buffer_append_string(cmdline, windir); | |
43169 | + buffer_append_string(cmdline, "\\system32\\cmd.exe"); | |
43170 | + } | |
43171 | buffer_append_string_len(cmdline, CONST_STR_LEN(" /c ")); | |
43172 | buffer_append_string(cmdline, command); | |
43173 | procok = CreateProcess(NULL, cmdline->ptr, &security, &security, TRUE, | |
43174 | NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); | |
43175 | - buffer_free(cmdline); | |
f26f9fd5 | 43176 | |
2519e6e5 ER |
43177 | if (FALSE == procok) { |
43178 | - fprintf(stderr, "failed to CreateProcess"); | |
43179 | + fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr); | |
43180 | + buffer_free(cmdline); | |
43181 | return -1; | |
43182 | } | |
43183 | + buffer_free(cmdline); | |
f26f9fd5 | 43184 | |
2519e6e5 ER |
43185 | proc->child = pi.hProcess; |
43186 | CloseHandle(pi.hThread); | |
43187 | @@ -226,8 +235,7 @@ | |
43188 | const char *shell; | |
43189 | ||
43190 | if (NULL == (shell = getenv(SHELLENV))) { | |
43191 | - fprintf(stderr, "env %s is required", SHELLENV); | |
43192 | - return -1; | |
43193 | + shell = "/bin/sh"; | |
43194 | } | |
43195 | ||
43196 | if (proc_open_pipes(proc) != 0) { | |
43197 | @@ -262,11 +270,11 @@ | |
43198 | } | |
f26f9fd5 | 43199 | } |
2519e6e5 ER |
43200 | /* }}} */ |
43201 | -#endif /* WIN32 */ | |
43202 | +#endif /* _WIN32 */ | |
f26f9fd5 | 43203 | |
2519e6e5 ER |
43204 | /* {{{ proc_read_fd_to_buffer */ |
43205 | static void proc_read_fd_to_buffer(int fd, buffer *b) { | |
43206 | - ssize_t s; | |
43207 | + int s; /* win32 has not ssize_t */ | |
43208 | ||
43209 | for (;;) { | |
43210 | buffer_prepare_append(b, 512); | |
1175ccec | 43211 | --- ../lighttpd-1.4.11/src/proc_open.h 2005-08-11 01:26:39.000000000 +0300 |
36e2a29e | 43212 | +++ lighttpd-1.4.12/src/proc_open.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
43213 | @@ -1,7 +1,7 @@ |
43214 | ||
43215 | #include "buffer.h" | |
43216 | ||
43217 | -#ifdef WIN32 | |
43218 | +#ifdef _WIN32 | |
43219 | #include <windows.h> | |
43220 | typedef HANDLE descriptor_t; | |
43221 | typedef HANDLE proc_pid_t; | |
1175ccec | 43222 | --- ../lighttpd-1.4.11/src/request.c 2006-03-05 11:58:09.000000000 +0200 |
36e2a29e | 43223 | +++ lighttpd-1.4.12/src/request.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 ER |
43224 | @@ -10,15 +10,17 @@ |
43225 | #include "keyvalue.h" | |
43226 | #include "log.h" | |
43227 | ||
43228 | +#include "sys-strings.h" | |
f673a614 | 43229 | + |
2519e6e5 ER |
43230 | static int request_check_hostname(server *srv, connection *con, buffer *host) { |
43231 | enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL; | |
43232 | size_t i; | |
43233 | int label_len = 0; | |
43234 | size_t host_len; | |
43235 | char *colon; | |
43236 | - int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */ | |
43237 | + int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */ | |
43238 | int level = 0; | |
43239 | - | |
f673a614 | 43240 | + |
2519e6e5 ER |
43241 | UNUSED(srv); |
43242 | UNUSED(con); | |
43243 | ||
43244 | @@ -32,17 +34,17 @@ | |
43245 | * IPv6address = "[" ... "]" | |
43246 | * port = *digit | |
43247 | */ | |
43248 | - | |
43249 | + | |
43250 | /* no Host: */ | |
43251 | if (!host || host->used == 0) return 0; | |
43252 | - | |
43253 | + | |
43254 | host_len = host->used - 1; | |
43255 | - | |
43256 | + | |
43257 | /* IPv6 adress */ | |
43258 | if (host->ptr[0] == '[') { | |
43259 | char *c = host->ptr + 1; | |
43260 | int colon_cnt = 0; | |
43261 | - | |
43262 | + | |
43263 | /* check portnumber */ | |
43264 | for (; *c && *c != ']'; c++) { | |
43265 | if (*c == ':') { | |
43266 | @@ -53,12 +55,12 @@ | |
43267 | return -1; | |
43268 | } | |
43269 | } | |
43270 | - | |
43271 | + | |
43272 | /* missing ] */ | |
43273 | if (!*c) { | |
43274 | return -1; | |
43275 | } | |
43276 | - | |
43277 | + | |
43278 | /* check port */ | |
43279 | if (*(c+1) == ':') { | |
43280 | for (c += 2; *c; c++) { | |
43281 | @@ -69,39 +71,39 @@ | |
43282 | } | |
43283 | return 0; | |
43284 | } | |
43285 | - | |
43286 | + | |
43287 | if (NULL != (colon = memchr(host->ptr, ':', host_len))) { | |
43288 | char *c = colon + 1; | |
43289 | - | |
43290 | + | |
43291 | /* check portnumber */ | |
43292 | for (; *c; c++) { | |
43293 | if (!light_isdigit(*c)) return -1; | |
43294 | } | |
43295 | - | |
f673a614 | 43296 | + |
2519e6e5 ER |
43297 | /* remove the port from the host-len */ |
43298 | host_len = colon - host->ptr; | |
43299 | } | |
43300 | - | |
f673a614 | 43301 | + |
2519e6e5 ER |
43302 | /* Host is empty */ |
43303 | if (host_len == 0) return -1; | |
43304 | - | |
f673a614 | 43305 | + |
2519e6e5 ER |
43306 | /* scan from the right and skip the \0 */ |
43307 | for (i = host_len - 1; i + 1 > 0; i--) { | |
43308 | const char c = host->ptr[i]; | |
43309 | ||
43310 | switch (stage) { | |
43311 | - case TOPLABEL: | |
43312 | + case TOPLABEL: | |
43313 | if (c == '.') { | |
43314 | /* only switch stage, if this is not the last character */ | |
43315 | if (i != host_len - 1) { | |
43316 | if (label_len == 0) { | |
43317 | return -1; | |
43318 | } | |
43319 | - | |
f673a614 | 43320 | + |
2519e6e5 ER |
43321 | /* check the first character at right of the dot */ |
43322 | if (is_ip == 0) { | |
43323 | if (!light_isalpha(host->ptr[i+1])) { | |
43324 | - return -1; | |
43325 | + return -1; | |
43326 | } | |
43327 | } else if (!light_isdigit(host->ptr[i+1])) { | |
43328 | is_ip = 0; | |
43329 | @@ -111,9 +113,9 @@ | |
43330 | /* just digits */ | |
43331 | is_ip = 1; | |
43332 | } | |
43333 | - | |
f26f9fd5 | 43334 | + |
2519e6e5 ER |
43335 | stage = DOMAINLABEL; |
43336 | - | |
f26f9fd5 | 43337 | + |
2519e6e5 ER |
43338 | label_len = 0; |
43339 | level++; | |
43340 | } else if (i == 0) { | |
43341 | @@ -135,7 +137,7 @@ | |
43342 | } | |
43343 | label_len++; | |
43344 | } | |
43345 | - | |
f26f9fd5 | 43346 | + |
2519e6e5 ER |
43347 | break; |
43348 | case DOMAINLABEL: | |
43349 | if (is_ip == 1) { | |
43350 | @@ -143,7 +145,7 @@ | |
43351 | if (label_len == 0) { | |
43352 | return -1; | |
43353 | } | |
43354 | - | |
f26f9fd5 | 43355 | + |
2519e6e5 ER |
43356 | label_len = 0; |
43357 | level++; | |
43358 | } else if (!light_isdigit(c)) { | |
43359 | @@ -156,12 +158,12 @@ | |
43360 | if (label_len == 0) { | |
43361 | return -1; | |
43362 | } | |
43363 | - | |
f26f9fd5 | 43364 | + |
2519e6e5 ER |
43365 | /* c is either - or alphanum here */ |
43366 | if ('-' == host->ptr[i+1]) { | |
43367 | return -1; | |
43368 | } | |
43369 | - | |
f26f9fd5 | 43370 | + |
2519e6e5 ER |
43371 | label_len = 0; |
43372 | level++; | |
43373 | } else if (i == 0) { | |
43374 | @@ -176,20 +178,20 @@ | |
43375 | label_len++; | |
43376 | } | |
43377 | } | |
43378 | - | |
f673a614 | 43379 | + |
2519e6e5 ER |
43380 | break; |
43381 | } | |
43382 | } | |
43383 | - | |
f673a614 | 43384 | + |
2519e6e5 ER |
43385 | /* a IP has to consist of 4 parts */ |
43386 | if (is_ip == 1 && level != 3) { | |
43387 | return -1; | |
43388 | } | |
43389 | - | |
f673a614 | 43390 | + |
2519e6e5 ER |
43391 | if (label_len == 0) { |
43392 | return -1; | |
43393 | } | |
43394 | - | |
f673a614 | 43395 | + |
2519e6e5 ER |
43396 | return 0; |
43397 | } | |
43398 | ||
43399 | @@ -201,53 +203,53 @@ | |
43400 | char *s; | |
43401 | size_t i; | |
43402 | int state = 0; | |
43403 | - /* | |
43404 | - * parse | |
43405 | - * | |
43406 | + /* | |
43407 | + * parse | |
f26f9fd5 | 43408 | + * |
2519e6e5 ER |
43409 | * val1, val2, val3, val4 |
43410 | - * | |
f26f9fd5 | 43411 | + * |
2519e6e5 ER |
43412 | * into a array (more or less a explode() incl. striping of whitespaces |
43413 | */ | |
43414 | - | |
f673a614 | 43415 | + |
2519e6e5 ER |
43416 | if (b->used == 0) return 0; |
43417 | - | |
f673a614 | 43418 | + |
2519e6e5 ER |
43419 | s = b->ptr; |
43420 | - | |
f673a614 | 43421 | + |
2519e6e5 ER |
43422 | for (i =0; i < b->used - 1; ) { |
43423 | char *start = NULL, *end = NULL; | |
43424 | data_string *ds; | |
43425 | - | |
f673a614 | 43426 | + |
2519e6e5 ER |
43427 | switch (state) { |
43428 | case 0: /* ws */ | |
43429 | - | |
f673a614 | 43430 | + |
2519e6e5 ER |
43431 | /* skip ws */ |
43432 | for (; (*s == ' ' || *s == '\t') && i < b->used - 1; i++, s++); | |
43433 | - | |
43434 | - | |
f673a614 | 43435 | + |
f673a614 | 43436 | + |
2519e6e5 ER |
43437 | state = 1; |
43438 | break; | |
43439 | case 1: /* value */ | |
43440 | start = s; | |
43441 | - | |
f673a614 | 43442 | + |
2519e6e5 ER |
43443 | for (; *s != ',' && i < b->used - 1; i++, s++); |
43444 | end = s - 1; | |
43445 | - | |
43446 | + | |
43447 | for (; (*end == ' ' || *end == '\t') && end > start; end--); | |
43448 | - | |
43449 | + | |
43450 | if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) { | |
43451 | ds = data_string_init(); | |
43452 | } | |
f26f9fd5 | 43453 | |
2519e6e5 ER |
43454 | buffer_copy_string_len(ds->value, start, end-start+1); |
43455 | array_insert_unique(vals, (data_unset *)ds); | |
43456 | - | |
43457 | + | |
43458 | if (*s == ',') { | |
43459 | state = 0; | |
43460 | i++; | |
43461 | s++; | |
43462 | } else { | |
43463 | /* end of string */ | |
43464 | - | |
43465 | + | |
43466 | state = 2; | |
43467 | } | |
43468 | break; | |
43469 | @@ -263,7 +265,7 @@ | |
43470 | if (c <= 32) return 0; | |
43471 | if (c == 127) return 0; | |
43472 | if (c == 255) return 0; | |
43473 | - | |
43474 | + | |
43475 | return 1; | |
43476 | } | |
f26f9fd5 | 43477 | |
2519e6e5 ER |
43478 | @@ -271,28 +273,28 @@ |
43479 | char *uri = NULL, *proto = NULL, *method = NULL, con_length_set; | |
43480 | int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding; | |
43481 | char *value = NULL, *key = NULL; | |
43482 | - | |
f673a614 | 43483 | + |
2519e6e5 ER |
43484 | enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_KEEPALIVE, HTTP_CONNECTION_CLOSE } keep_alive_set = HTTP_CONNECTION_UNSET; |
43485 | - | |
43486 | + | |
43487 | int line = 0; | |
43488 | - | |
43489 | + | |
43490 | int request_line_stage = 0; | |
43491 | size_t i, first; | |
43492 | - | |
43493 | + | |
43494 | int done = 0; | |
43495 | - | |
43496 | + | |
43497 | data_string *ds = NULL; | |
43498 | - | |
43499 | - /* | |
43500 | - * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$" | |
43501 | - * Option : "^([-a-zA-Z]+): (.+)$" | |
43502 | + | |
43503 | + /* | |
43504 | + * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$" | |
43505 | + * Option : "^([-a-zA-Z]+): (.+)$" | |
43506 | * End : "^$" | |
43507 | */ | |
f673a614 | 43508 | |
2519e6e5 ER |
43509 | if (con->conf.log_request_header) { |
43510 | - log_error_write(srv, __FILE__, __LINE__, "sdsdSb", | |
43511 | - "fd:", con->fd, | |
43512 | - "request-len:", con->request.request->used, | |
43513 | + log_error_write(srv, __FILE__, __LINE__, "sdsdSb", | |
43514 | + "fd:", con->fd, | |
43515 | + "request-len:", con->request.request->used, | |
43516 | "\n", con->request.request); | |
43517 | } | |
f673a614 | 43518 | |
2519e6e5 ER |
43519 | @@ -300,13 +302,13 @@ |
43520 | con->request.request->ptr[0] == '\r' && | |
43521 | con->request.request->ptr[1] == '\n') { | |
43522 | /* we are in keep-alive and might get \r\n after a previous POST request.*/ | |
43523 | - | |
f673a614 | 43524 | + |
2519e6e5 ER |
43525 | buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, con->request.request->used - 1 - 2); |
43526 | } else { | |
43527 | /* fill the local request buffer */ | |
43528 | buffer_copy_string_buffer(con->parse_request, con->request.request); | |
43529 | } | |
43530 | - | |
f673a614 | 43531 | + |
2519e6e5 ER |
43532 | keep_alive_set = 0; |
43533 | con_length_set = 0; | |
f673a614 | 43534 | |
2519e6e5 ER |
43535 | @@ -318,25 +320,25 @@ |
43536 | * */ | |
43537 | for (i = 0, first = 0; i < con->parse_request->used && line == 0; i++) { | |
43538 | char *cur = con->parse_request->ptr + i; | |
43539 | - | |
f673a614 | 43540 | + |
2519e6e5 ER |
43541 | switch(*cur) { |
43542 | - case '\r': | |
43543 | + case '\r': | |
43544 | if (con->parse_request->ptr[i+1] == '\n') { | |
43545 | http_method_t r; | |
43546 | char *nuri = NULL; | |
43547 | size_t j; | |
43548 | - | |
f673a614 | 43549 | + |
2519e6e5 ER |
43550 | /* \r\n -> \0\0 */ |
43551 | con->parse_request->ptr[i] = '\0'; | |
43552 | con->parse_request->ptr[i+1] = '\0'; | |
43553 | - | |
f673a614 | 43554 | + |
2519e6e5 ER |
43555 | buffer_copy_string_len(con->request.request_line, con->parse_request->ptr, i); |
43556 | - | |
f673a614 | 43557 | + |
2519e6e5 ER |
43558 | if (request_line_stage != 2) { |
43559 | con->http_status = 400; | |
43560 | con->response.keep_alive = 0; | |
43561 | con->keep_alive = 0; | |
43562 | - | |
f673a614 | 43563 | + |
2519e6e5 ER |
43564 | if (srv->srvconf.log_request_header_on_error) { |
43565 | log_error_write(srv, __FILE__, __LINE__, "s", "incomplete request line -> 400"); | |
43566 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
43567 | @@ -345,36 +347,36 @@ | |
43568 | } | |
43569 | return 0; | |
43570 | } | |
43571 | - | |
43572 | + | |
43573 | proto = con->parse_request->ptr + first; | |
43574 | - | |
43575 | + | |
43576 | *(uri - 1) = '\0'; | |
43577 | *(proto - 1) = '\0'; | |
43578 | - | |
43579 | + | |
43580 | /* we got the first one :) */ | |
43581 | if (-1 == (r = get_http_method_key(method))) { | |
43582 | con->http_status = 501; | |
43583 | con->response.keep_alive = 0; | |
43584 | con->keep_alive = 0; | |
43585 | - | |
43586 | + | |
43587 | if (srv->srvconf.log_request_header_on_error) { | |
43588 | log_error_write(srv, __FILE__, __LINE__, "s", "unknown http-method -> 501"); | |
43589 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
43590 | "request-header:\n", | |
43591 | con->request.request); | |
43592 | } | |
43593 | - | |
43594 | + | |
43595 | return 0; | |
43596 | } | |
43597 | - | |
f673a614 | 43598 | + |
2519e6e5 ER |
43599 | con->request.http_method = r; |
43600 | - | |
43601 | - /* | |
43602 | + | |
43603 | + /* | |
43604 | * RFC2616 says: | |
43605 | * | |
43606 | * HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT | |
43607 | * | |
43608 | - * */ | |
43609 | + * */ | |
43610 | if (0 == strncmp(proto, "HTTP/", sizeof("HTTP/") - 1)) { | |
43611 | char * major = proto + sizeof("HTTP/") - 1; | |
43612 | char * minor = strchr(major, '.'); | |
43613 | @@ -413,10 +415,10 @@ | |
43614 | } | |
43615 | ||
43616 | if (major_num == 1 && minor_num == 1) { | |
43617 | - con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0; | |
43618 | + con->request.http_version = HTTP_VERSION_1_1; | |
43619 | } else if (major_num == 1 && minor_num == 0) { | |
43620 | con->request.http_version = HTTP_VERSION_1_0; | |
43621 | - } else { | |
43622 | + } else { | |
43623 | con->http_status = 505; | |
43624 | ||
43625 | if (srv->srvconf.log_request_header_on_error) { | |
43626 | @@ -439,30 +441,30 @@ | |
43627 | } | |
43628 | return 0; | |
43629 | } | |
43630 | - | |
f673a614 | 43631 | + |
2519e6e5 ER |
43632 | if (0 == strncmp(uri, "http://", 7) && |
43633 | NULL != (nuri = strchr(uri + 7, '/'))) { | |
43634 | /* ignore the host-part */ | |
43635 | - | |
f673a614 | 43636 | + |
2519e6e5 ER |
43637 | buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1); |
43638 | } else { | |
43639 | /* everything looks good so far */ | |
43640 | buffer_copy_string_len(con->request.uri, uri, proto - uri - 1); | |
43641 | } | |
43642 | - | |
f673a614 | 43643 | + |
2519e6e5 ER |
43644 | /* check uri for invalid characters */ |
43645 | for (j = 0; j < con->request.uri->used - 1; j++) { | |
43646 | if (!request_uri_is_valid_char(con->request.uri->ptr[j])) { | |
43647 | unsigned char buf[2]; | |
43648 | con->http_status = 400; | |
43649 | con->keep_alive = 0; | |
43650 | - | |
f673a614 | 43651 | + |
2519e6e5 ER |
43652 | if (srv->srvconf.log_request_header_on_error) { |
43653 | buf[0] = con->request.uri->ptr[j]; | |
43654 | buf[1] = '\0'; | |
43655 | - | |
f673a614 | 43656 | + |
2519e6e5 ER |
43657 | if (con->request.uri->ptr[j] > 32 && |
43658 | - con->request.uri->ptr[j] != 127) { | |
43659 | + con->request.uri->ptr[j] != 127) { | |
43660 | /* the character is printable -> print it */ | |
43661 | log_error_write(srv, __FILE__, __LINE__, "ss", | |
43662 | "invalid character in URI -> 400", | |
43663 | @@ -473,20 +475,20 @@ | |
43664 | "invalid character in URI -> 400", | |
43665 | con->request.uri->ptr[j]); | |
43666 | } | |
43667 | - | |
f673a614 | 43668 | + |
2519e6e5 ER |
43669 | log_error_write(srv, __FILE__, __LINE__, "Sb", |
43670 | "request-header:\n", | |
43671 | con->request.request); | |
43672 | } | |
43673 | - | |
f673a614 | 43674 | + |
2519e6e5 ER |
43675 | return 0; |
43676 | } | |
43677 | } | |
43678 | - | |
f673a614 | 43679 | + |
2519e6e5 ER |
43680 | buffer_copy_string_buffer(con->request.orig_uri, con->request.uri); |
43681 | - | |
f673a614 | 43682 | + |
2519e6e5 ER |
43683 | con->http_status = 0; |
43684 | - | |
f673a614 | 43685 | + |
2519e6e5 ER |
43686 | i++; |
43687 | line++; | |
43688 | first = i+1; | |
43689 | @@ -494,14 +496,14 @@ | |
43690 | break; | |
43691 | case ' ': | |
43692 | switch(request_line_stage) { | |
43693 | - case 0: | |
43694 | + case 0: | |
43695 | /* GET|POST|... */ | |
43696 | - method = con->parse_request->ptr + first; | |
43697 | + method = con->parse_request->ptr + first; | |
43698 | first = i + 1; | |
43699 | break; | |
43700 | case 1: | |
43701 | /* /foobar/... */ | |
43702 | - uri = con->parse_request->ptr + first; | |
43703 | + uri = con->parse_request->ptr + first; | |
43704 | first = i + 1; | |
43705 | break; | |
43706 | default: | |
43707 | @@ -509,7 +511,7 @@ | |
43708 | con->http_status = 400; | |
43709 | con->response.keep_alive = 0; | |
43710 | con->keep_alive = 0; | |
43711 | - | |
f673a614 | 43712 | + |
2519e6e5 ER |
43713 | if (srv->srvconf.log_request_header_on_error) { |
43714 | log_error_write(srv, __FILE__, __LINE__, "s", "overlong request line -> 400"); | |
43715 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
43716 | @@ -518,12 +520,12 @@ | |
43717 | } | |
43718 | return 0; | |
f26f9fd5 | 43719 | } |
2519e6e5 | 43720 | - |
f673a614 | 43721 | + |
2519e6e5 ER |
43722 | request_line_stage++; |
43723 | break; | |
f26f9fd5 | 43724 | } |
2519e6e5 ER |
43725 | } |
43726 | - | |
f673a614 | 43727 | + |
2519e6e5 | 43728 | in_folding = 0; |
f673a614 | 43729 | |
2519e6e5 ER |
43730 | if (con->request.uri->used == 1) { |
43731 | @@ -540,30 +542,30 @@ | |
43732 | return 0; | |
f26f9fd5 | 43733 | } |
f673a614 | 43734 | |
2519e6e5 | 43735 | - |
f673a614 | 43736 | + |
2519e6e5 ER |
43737 | for (; i < con->parse_request->used && !done; i++) { |
43738 | char *cur = con->parse_request->ptr + i; | |
43739 | - | |
43740 | + | |
43741 | if (is_key) { | |
43742 | size_t j; | |
43743 | int got_colon = 0; | |
43744 | - | |
43745 | + | |
43746 | /** | |
43747 | * 1*<any CHAR except CTLs or separators> | |
43748 | * CTLs == 0-31 + 127 | |
43749 | - * | |
43750 | + * | |
43751 | */ | |
43752 | switch(*cur) { | |
43753 | case ':': | |
43754 | is_key = 0; | |
43755 | - | |
43756 | + | |
43757 | value = cur + 1; | |
43758 | - | |
43759 | + | |
43760 | if (is_ws_after_key == 0) { | |
43761 | key_len = i - first; | |
f26f9fd5 | 43762 | } |
2519e6e5 ER |
43763 | is_ws_after_key = 0; |
43764 | - | |
f673a614 | 43765 | + |
2519e6e5 ER |
43766 | break; |
43767 | case '(': | |
43768 | case ')': | |
43769 | @@ -584,8 +586,8 @@ | |
f26f9fd5 | 43770 | con->http_status = 400; |
2519e6e5 ER |
43771 | con->keep_alive = 0; |
43772 | con->response.keep_alive = 0; | |
43773 | - | |
43774 | - log_error_write(srv, __FILE__, __LINE__, "sbsds", | |
43775 | + | |
43776 | + log_error_write(srv, __FILE__, __LINE__, "sbsds", | |
43777 | "invalid character in key", con->request.request, cur, *cur, "-> 400"); | |
43778 | return 0; | |
43779 | case ' ': | |
43780 | @@ -594,13 +596,13 @@ | |
43781 | is_key = 0; | |
43782 | in_folding = 1; | |
43783 | value = cur; | |
43784 | - | |
f673a614 | 43785 | + |
2519e6e5 ER |
43786 | break; |
43787 | } | |
43788 | - | |
43789 | - | |
f673a614 | 43790 | + |
f673a614 | 43791 | + |
2519e6e5 ER |
43792 | key_len = i - first; |
43793 | - | |
f673a614 | 43794 | + |
2519e6e5 ER |
43795 | /* skip every thing up to the : */ |
43796 | for (j = 1; !got_colon; j++) { | |
43797 | switch(con->parse_request->ptr[j + i]) { | |
43798 | @@ -610,40 +612,40 @@ | |
43799 | continue; | |
43800 | case ':': | |
43801 | /* ok, done */ | |
43802 | - | |
f673a614 | 43803 | + |
2519e6e5 ER |
43804 | i += j - 1; |
43805 | got_colon = 1; | |
43806 | - | |
f673a614 | 43807 | + |
2519e6e5 ER |
43808 | break; |
43809 | default: | |
43810 | /* error */ | |
43811 | - | |
f673a614 | 43812 | + |
2519e6e5 ER |
43813 | if (srv->srvconf.log_request_header_on_error) { |
43814 | log_error_write(srv, __FILE__, __LINE__, "s", "WS character in key -> 400"); | |
43815 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
43816 | "request-header:\n", | |
43817 | con->request.request); | |
43818 | } | |
43819 | - | |
f673a614 | 43820 | + |
2519e6e5 ER |
43821 | con->http_status = 400; |
43822 | con->response.keep_alive = 0; | |
43823 | con->keep_alive = 0; | |
43824 | - | |
f673a614 | 43825 | + |
2519e6e5 ER |
43826 | return 0; |
43827 | } | |
43828 | } | |
43829 | - | |
f673a614 | 43830 | + |
2519e6e5 ER |
43831 | break; |
43832 | case '\r': | |
43833 | if (con->parse_request->ptr[i+1] == '\n' && i == first) { | |
43834 | /* End of Header */ | |
43835 | con->parse_request->ptr[i] = '\0'; | |
43836 | con->parse_request->ptr[i+1] = '\0'; | |
43837 | - | |
f673a614 | 43838 | + |
2519e6e5 ER |
43839 | i++; |
43840 | - | |
43841 | + | |
43842 | done = 1; | |
43843 | - | |
43844 | + | |
43845 | break; | |
43846 | } else { | |
43847 | if (srv->srvconf.log_request_header_on_error) { | |
43848 | @@ -652,7 +654,7 @@ | |
43849 | "request-header:\n", | |
43850 | con->request.request); | |
43851 | } | |
43852 | - | |
f673a614 | 43853 | + |
2519e6e5 ER |
43854 | con->http_status = 400; |
43855 | con->keep_alive = 0; | |
43856 | con->response.keep_alive = 0; | |
43857 | @@ -693,16 +695,16 @@ | |
43858 | con->http_status = 400; | |
43859 | con->keep_alive = 0; | |
43860 | con->response.keep_alive = 0; | |
43861 | - | |
f673a614 | 43862 | + |
2519e6e5 ER |
43863 | if (srv->srvconf.log_request_header_on_error) { |
43864 | - log_error_write(srv, __FILE__, __LINE__, "sbsds", | |
43865 | + log_error_write(srv, __FILE__, __LINE__, "sbsds", | |
43866 | "CTL character in key", con->request.request, cur, *cur, "-> 400"); | |
43867 | ||
43868 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
43869 | "request-header:\n", | |
43870 | con->request.request); | |
43871 | } | |
43872 | - | |
f673a614 | 43873 | + |
2519e6e5 ER |
43874 | return 0; |
43875 | default: | |
43876 | /* ok */ | |
43877 | @@ -710,25 +712,25 @@ | |
43878 | } | |
43879 | } else { | |
43880 | switch(*cur) { | |
43881 | - case '\r': | |
43882 | + case '\r': | |
43883 | if (con->parse_request->ptr[i+1] == '\n') { | |
43884 | /* End of Headerline */ | |
43885 | con->parse_request->ptr[i] = '\0'; | |
43886 | con->parse_request->ptr[i+1] = '\0'; | |
43887 | - | |
f673a614 | 43888 | + |
2519e6e5 ER |
43889 | if (in_folding) { |
43890 | if (!ds) { | |
43891 | /* 400 */ | |
43892 | - | |
f673a614 | 43893 | + |
2519e6e5 ER |
43894 | if (srv->srvconf.log_request_header_on_error) { |
43895 | log_error_write(srv, __FILE__, __LINE__, "s", "WS at the start of first line -> 400"); | |
43896 | - | |
f673a614 | 43897 | + |
2519e6e5 ER |
43898 | log_error_write(srv, __FILE__, __LINE__, "Sb", |
43899 | "request-header:\n", | |
43900 | con->request.request); | |
43901 | } | |
43902 | ||
43903 | - | |
f673a614 | 43904 | + |
2519e6e5 ER |
43905 | con->http_status = 400; |
43906 | con->keep_alive = 0; | |
43907 | con->response.keep_alive = 0; | |
43908 | @@ -738,9 +740,9 @@ | |
43909 | } else { | |
43910 | int s_len; | |
43911 | key = con->parse_request->ptr + first; | |
43912 | - | |
f673a614 | 43913 | + |
2519e6e5 ER |
43914 | s_len = cur - value; |
43915 | - | |
f673a614 | 43916 | + |
2519e6e5 ER |
43917 | if (s_len > 0) { |
43918 | int cmp = 0; | |
43919 | if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { | |
43920 | @@ -748,86 +750,87 @@ | |
43921 | } | |
43922 | buffer_copy_string_len(ds->key, key, key_len); | |
43923 | buffer_copy_string_len(ds->value, value, s_len); | |
43924 | - | |
43925 | - /* retreive values | |
43926 | - * | |
43927 | - * | |
43928 | + | |
43929 | + /* retreive values | |
43930 | + * | |
43931 | + * | |
43932 | * the list of options is sorted to simplify the search | |
43933 | */ | |
43934 | - | |
f673a614 | 43935 | + |
2519e6e5 ER |
43936 | if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) { |
43937 | array *vals; | |
43938 | size_t vi; | |
43939 | - | |
f673a614 | 43940 | + |
2519e6e5 ER |
43941 | /* split on , */ |
43942 | - | |
f673a614 | 43943 | + |
2519e6e5 ER |
43944 | vals = srv->split_vals; |
43945 | ||
43946 | array_reset(vals); | |
43947 | - | |
f673a614 | 43948 | + |
2519e6e5 ER |
43949 | http_request_split_value(vals, ds->value); |
43950 | - | |
f673a614 | 43951 | + |
2519e6e5 ER |
43952 | for (vi = 0; vi < vals->used; vi++) { |
43953 | data_string *dsv = (data_string *)vals->data[vi]; | |
43954 | - | |
f673a614 | 43955 | + |
2519e6e5 ER |
43956 | if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) { |
43957 | keep_alive_set = HTTP_CONNECTION_KEEPALIVE; | |
43958 | - | |
f673a614 | 43959 | + |
2519e6e5 ER |
43960 | break; |
43961 | } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) { | |
43962 | keep_alive_set = HTTP_CONNECTION_CLOSE; | |
43963 | - | |
f673a614 | 43964 | + |
2519e6e5 ER |
43965 | break; |
43966 | } | |
43967 | } | |
43968 | - | |
43969 | + | |
43970 | } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) { | |
43971 | char *err; | |
43972 | unsigned long int r; | |
43973 | size_t j; | |
43974 | - | |
43975 | + | |
43976 | if (con_length_set) { | |
43977 | con->http_status = 400; | |
43978 | con->keep_alive = 0; | |
43979 | - | |
43980 | + | |
43981 | if (srv->srvconf.log_request_header_on_error) { | |
43982 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
43983 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
43984 | "duplicate Content-Length-header -> 400"); | |
43985 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
43986 | "request-header:\n", | |
43987 | con->request.request); | |
43988 | } | |
43989 | + ds->free((data_unset *) ds); | |
43990 | return 0; | |
43991 | } | |
43992 | - | |
f673a614 | 43993 | + |
2519e6e5 ER |
43994 | if (ds->value->used == 0) SEGFAULT(); |
43995 | - | |
f673a614 | 43996 | + |
2519e6e5 ER |
43997 | for (j = 0; j < ds->value->used - 1; j++) { |
43998 | char c = ds->value->ptr[j]; | |
43999 | if (!isdigit((unsigned char)c)) { | |
44000 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
44001 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
44002 | "content-length broken:", ds->value, "-> 400"); | |
44003 | - | |
f673a614 | 44004 | + |
2519e6e5 ER |
44005 | con->http_status = 400; |
44006 | con->keep_alive = 0; | |
44007 | - | |
f673a614 | 44008 | + |
2519e6e5 ER |
44009 | array_insert_unique(con->request.headers, (data_unset *)ds); |
44010 | return 0; | |
44011 | } | |
44012 | } | |
44013 | - | |
f673a614 | 44014 | + |
2519e6e5 ER |
44015 | r = strtoul(ds->value->ptr, &err, 10); |
44016 | - | |
f673a614 | 44017 | + |
2519e6e5 ER |
44018 | if (*err == '\0') { |
44019 | con_length_set = 1; | |
44020 | con->request.content_length = r; | |
44021 | } else { | |
44022 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
44023 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
44024 | "content-length broken:", ds->value, "-> 400"); | |
44025 | - | |
f673a614 | 44026 | + |
2519e6e5 ER |
44027 | con->http_status = 400; |
44028 | con->keep_alive = 0; | |
44029 | - | |
f673a614 | 44030 | + |
2519e6e5 ER |
44031 | array_insert_unique(con->request.headers, (data_unset *)ds); |
44032 | return 0; | |
44033 | } | |
44034 | @@ -838,23 +841,24 @@ | |
44035 | } else { | |
44036 | con->http_status = 400; | |
44037 | con->keep_alive = 0; | |
44038 | - | |
44039 | + | |
44040 | if (srv->srvconf.log_request_header_on_error) { | |
44041 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
44042 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
44043 | "duplicate Content-Type-header -> 400"); | |
44044 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
44045 | "request-header:\n", | |
44046 | con->request.request); | |
44047 | } | |
44048 | + ds->free((data_unset *) ds); | |
44049 | return 0; | |
44050 | } | |
44051 | } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) { | |
44052 | - /* HTTP 2616 8.2.3 | |
44053 | + /* HTTP 2616 8.2.3 | |
44054 | * Expect: 100-continue | |
44055 | - * | |
44056 | + * | |
44057 | * -> (10.1.1) 100 (read content, process request, send final status-code) | |
44058 | * -> (10.4.18) 417 (close) | |
44059 | - * | |
44060 | + * | |
44061 | * (not handled at all yet, we always send 417 here) | |
44062 | * | |
44063 | * What has to be added ? | |
44064 | @@ -863,10 +867,10 @@ | |
44065 | * header | |
44066 | * | |
44067 | */ | |
44068 | - | |
44069 | + | |
44070 | con->http_status = 417; | |
44071 | con->keep_alive = 0; | |
44072 | - | |
44073 | + | |
44074 | array_insert_unique(con->request.headers, (data_unset *)ds); | |
44075 | return 0; | |
44076 | } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) { | |
44077 | @@ -875,14 +879,15 @@ | |
44078 | } else { | |
44079 | con->http_status = 400; | |
44080 | con->keep_alive = 0; | |
44081 | - | |
44082 | + | |
44083 | if (srv->srvconf.log_request_header_on_error) { | |
44084 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
44085 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
44086 | "duplicate Host-header -> 400"); | |
44087 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
44088 | "request-header:\n", | |
44089 | con->request.request); | |
44090 | } | |
44091 | + ds->free((data_unset *) ds); | |
44092 | return 0; | |
44093 | } | |
44094 | } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) { | |
44095 | @@ -897,14 +902,15 @@ | |
44096 | } else { | |
44097 | con->http_status = 400; | |
44098 | con->keep_alive = 0; | |
44099 | - | |
44100 | + | |
44101 | if (srv->srvconf.log_request_header_on_error) { | |
44102 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
44103 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
44104 | "duplicate If-Modified-Since header -> 400"); | |
44105 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
44106 | "request-header:\n", | |
44107 | con->request.request); | |
44108 | } | |
44109 | + ds->free((data_unset *) ds); | |
44110 | return 0; | |
44111 | } | |
44112 | } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) { | |
44113 | @@ -914,47 +920,49 @@ | |
44114 | } else { | |
44115 | con->http_status = 400; | |
44116 | con->keep_alive = 0; | |
44117 | - | |
44118 | + | |
44119 | if (srv->srvconf.log_request_header_on_error) { | |
44120 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
44121 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
44122 | "duplicate If-None-Match-header -> 400"); | |
44123 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
44124 | "request-header:\n", | |
44125 | con->request.request); | |
44126 | } | |
44127 | + ds->free((data_unset *) ds); | |
44128 | return 0; | |
44129 | } | |
44130 | } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) { | |
44131 | if (!con->request.http_range) { | |
44132 | /* bytes=.*-.* */ | |
44133 | - | |
f673a614 | 44134 | + |
2519e6e5 ER |
44135 | if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) && |
44136 | NULL != strchr(ds->value->ptr+6, '-')) { | |
44137 | - | |
f673a614 | 44138 | + |
2519e6e5 ER |
44139 | /* if dup, only the first one will survive */ |
44140 | con->request.http_range = ds->value->ptr + 6; | |
44141 | } | |
44142 | } else { | |
44143 | con->http_status = 400; | |
44144 | con->keep_alive = 0; | |
44145 | - | |
44146 | + | |
44147 | if (srv->srvconf.log_request_header_on_error) { | |
44148 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
44149 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
44150 | "duplicate Range-header -> 400"); | |
44151 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
44152 | "request-header:\n", | |
44153 | con->request.request); | |
44154 | } | |
44155 | + ds->free((data_unset *) ds); | |
44156 | return 0; | |
44157 | } | |
44158 | } | |
44159 | - | |
f673a614 | 44160 | + |
2519e6e5 ER |
44161 | array_insert_unique(con->request.headers, (data_unset *)ds); |
44162 | } else { | |
44163 | /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */ | |
44164 | } | |
44165 | } | |
44166 | - | |
f673a614 | 44167 | + |
2519e6e5 ER |
44168 | i++; |
44169 | first = i+1; | |
44170 | is_key = 1; | |
44171 | @@ -963,10 +971,10 @@ | |
44172 | in_folding = 0; | |
44173 | } else { | |
44174 | if (srv->srvconf.log_request_header_on_error) { | |
44175 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
44176 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
44177 | "CR without LF", con->request.request, "-> 400"); | |
44178 | } | |
44179 | - | |
f673a614 | 44180 | + |
2519e6e5 ER |
44181 | con->http_status = 400; |
44182 | con->keep_alive = 0; | |
44183 | con->response.keep_alive = 0; | |
44184 | @@ -982,28 +990,28 @@ | |
44185 | } | |
44186 | } | |
44187 | } | |
44188 | - | |
f673a614 | 44189 | + |
2519e6e5 ER |
44190 | con->header_len = i; |
44191 | - | |
f673a614 | 44192 | + |
2519e6e5 ER |
44193 | /* do some post-processing */ |
44194 | ||
44195 | if (con->request.http_version == HTTP_VERSION_1_1) { | |
44196 | if (keep_alive_set != HTTP_CONNECTION_CLOSE) { | |
44197 | /* no Connection-Header sent */ | |
44198 | - | |
f673a614 | 44199 | + |
2519e6e5 ER |
44200 | /* HTTP/1.1 -> keep-alive default TRUE */ |
44201 | con->keep_alive = 1; | |
44202 | } else { | |
44203 | con->keep_alive = 0; | |
44204 | } | |
44205 | - | |
f673a614 | 44206 | + |
2519e6e5 ER |
44207 | /* RFC 2616, 14.23 */ |
44208 | if (con->request.http_host == NULL || | |
44209 | buffer_is_empty(con->request.http_host)) { | |
44210 | con->http_status = 400; | |
44211 | con->response.keep_alive = 0; | |
44212 | con->keep_alive = 0; | |
44213 | - | |
f673a614 | 44214 | + |
2519e6e5 ER |
44215 | if (srv->srvconf.log_request_header_on_error) { |
44216 | log_error_write(srv, __FILE__, __LINE__, "s", "HTTP/1.1 but Host missing -> 400"); | |
44217 | log_error_write(srv, __FILE__, __LINE__, "Sb", | |
44218 | @@ -1015,18 +1023,18 @@ | |
44219 | } else { | |
44220 | if (keep_alive_set == HTTP_CONNECTION_KEEPALIVE) { | |
44221 | /* no Connection-Header sent */ | |
44222 | - | |
f673a614 | 44223 | + |
2519e6e5 ER |
44224 | /* HTTP/1.0 -> keep-alive default FALSE */ |
44225 | con->keep_alive = 1; | |
44226 | } else { | |
44227 | con->keep_alive = 0; | |
44228 | } | |
44229 | } | |
44230 | - | |
f673a614 | 44231 | + |
2519e6e5 ER |
44232 | /* check hostname field if it is set */ |
44233 | if (NULL != con->request.http_host && | |
44234 | 0 != request_check_hostname(srv, con, con->request.http_host)) { | |
44235 | - | |
f673a614 | 44236 | + |
2519e6e5 ER |
44237 | if (srv->srvconf.log_request_header_on_error) { |
44238 | log_error_write(srv, __FILE__, __LINE__, "s", | |
44239 | "Invalid Hostname -> 400"); | |
44240 | @@ -1038,7 +1046,7 @@ | |
44241 | con->http_status = 400; | |
44242 | con->response.keep_alive = 0; | |
44243 | con->keep_alive = 0; | |
44244 | - | |
f673a614 | 44245 | + |
2519e6e5 ER |
44246 | return 0; |
44247 | } | |
44248 | ||
44249 | @@ -1048,7 +1056,7 @@ | |
44250 | /* content-length is forbidden for those */ | |
44251 | if (con_length_set && con->request.content_length != 0) { | |
44252 | /* content-length is missing */ | |
44253 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
44254 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
44255 | "GET/HEAD with content-length -> 400"); | |
44256 | ||
44257 | con->keep_alive = 0; | |
44258 | @@ -1060,7 +1068,7 @@ | |
44259 | /* content-length is required for them */ | |
44260 | if (!con_length_set) { | |
44261 | /* content-length is missing */ | |
44262 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
44263 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
44264 | "POST-request, but content-length missing -> 411"); | |
44265 | ||
44266 | con->keep_alive = 0; | |
44267 | @@ -1073,16 +1081,16 @@ | |
44268 | /* the may have a content-length */ | |
44269 | break; | |
44270 | } | |
44271 | - | |
44272 | - | |
44273 | + | |
44274 | + | |
44275 | /* check if we have read post data */ | |
44276 | if (con_length_set) { | |
44277 | /* don't handle more the SSIZE_MAX bytes in content-length */ | |
44278 | if (con->request.content_length > SSIZE_MAX) { | |
44279 | - con->http_status = 413; | |
44280 | + con->http_status = 413; | |
44281 | con->keep_alive = 0; | |
44282 | ||
44283 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
44284 | + log_error_write(srv, __FILE__, __LINE__, "sds", | |
44285 | "request-size too long:", con->request.content_length, "-> 413"); | |
44286 | return 0; | |
44287 | } | |
44288 | @@ -1090,25 +1098,25 @@ | |
44289 | /* divide by 1024 as srvconf.max_request_size is in kBytes */ | |
44290 | if (srv->srvconf.max_request_size != 0 && | |
44291 | (con->request.content_length >> 10) > srv->srvconf.max_request_size) { | |
44292 | - /* the request body itself is larger then | |
44293 | + /* the request body itself is larger then | |
44294 | * our our max_request_size | |
44295 | */ | |
44296 | - | |
f673a614 | 44297 | + |
2519e6e5 ER |
44298 | con->http_status = 413; |
44299 | con->keep_alive = 0; | |
44300 | - | |
44301 | - log_error_write(srv, __FILE__, __LINE__, "sds", | |
f673a614 | 44302 | + |
2519e6e5 ER |
44303 | + log_error_write(srv, __FILE__, __LINE__, "sds", |
44304 | "request-size too long:", con->request.content_length, "-> 413"); | |
44305 | return 0; | |
44306 | } | |
44307 | - | |
44308 | - | |
f673a614 | 44309 | + |
f673a614 | 44310 | + |
2519e6e5 ER |
44311 | /* we have content */ |
44312 | if (con->request.content_length != 0) { | |
44313 | return 1; | |
44314 | } | |
44315 | } | |
44316 | - | |
f673a614 | 44317 | + |
2519e6e5 ER |
44318 | return 0; |
44319 | } | |
44320 | ||
44321 | @@ -1116,9 +1124,9 @@ | |
44322 | UNUSED(srv); | |
44323 | ||
44324 | if (con->request.request->used < 5) return 0; | |
44325 | - | |
f673a614 | 44326 | + |
2519e6e5 ER |
44327 | if (0 == memcmp(con->request.request->ptr + con->request.request->used - 5, "\r\n\r\n", 4)) return 1; |
44328 | if (NULL != strstr(con->request.request->ptr, "\r\n\r\n")) return 1; | |
44329 | - | |
f673a614 | 44330 | + |
2519e6e5 ER |
44331 | return 0; |
44332 | } | |
1175ccec | 44333 | --- ../lighttpd-1.4.11/src/response.c 2006-03-04 16:41:39.000000000 +0200 |
36e2a29e | 44334 | +++ lighttpd-1.4.12/src/response.c 2006-07-11 22:07:52.000000000 +0300 |
2519e6e5 | 44335 | @@ -7,7 +7,6 @@ |
f26f9fd5 | 44336 | #include <stdlib.h> |
2519e6e5 ER |
44337 | #include <string.h> |
44338 | #include <time.h> | |
44339 | -#include <unistd.h> | |
44340 | #include <ctype.h> | |
f26f9fd5 ER |
44341 | #include <assert.h> |
44342 | ||
2519e6e5 ER |
44343 | @@ -24,15 +23,17 @@ |
44344 | #include "plugin.h" | |
44345 | ||
f26f9fd5 ER |
44346 | #include "sys-socket.h" |
44347 | +#include "sys-files.h" | |
2519e6e5 | 44348 | +#include "sys-strings.h" |
f26f9fd5 | 44349 | |
2519e6e5 ER |
44350 | int http_response_write_header(server *srv, connection *con) { |
44351 | buffer *b; | |
44352 | size_t i; | |
44353 | int have_date = 0; | |
44354 | int have_server = 0; | |
f26f9fd5 | 44355 | - |
f673a614 | 44356 | + |
2519e6e5 ER |
44357 | b = chunkqueue_get_prepend_buffer(con->write_queue); |
44358 | - | |
f673a614 | 44359 | + |
2519e6e5 ER |
44360 | if (con->request.http_version == HTTP_VERSION_1_1) { |
44361 | BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 "); | |
44362 | } else { | |
44363 | @@ -41,25 +42,26 @@ | |
44364 | buffer_append_long(b, con->http_status); | |
44365 | BUFFER_APPEND_STRING_CONST(b, " "); | |
44366 | buffer_append_string(b, get_http_status_name(con->http_status)); | |
44367 | - | |
f26f9fd5 | 44368 | + |
2519e6e5 ER |
44369 | if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) { |
44370 | BUFFER_APPEND_STRING_CONST(b, "\r\nConnection: "); | |
44371 | buffer_append_string(b, con->keep_alive ? "keep-alive" : "close"); | |
f26f9fd5 | 44372 | } |
2519e6e5 | 44373 | - |
f673a614 | 44374 | + |
2519e6e5 ER |
44375 | if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { |
44376 | BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked"); | |
44377 | } | |
44378 | - | |
44379 | - | |
f673a614 | 44380 | + |
f673a614 | 44381 | + |
2519e6e5 ER |
44382 | /* add all headers */ |
44383 | for (i = 0; i < con->response.headers->used; i++) { | |
44384 | data_string *ds; | |
44385 | - | |
f26f9fd5 | 44386 | + |
2519e6e5 ER |
44387 | ds = (data_string *)con->response.headers->data[i]; |
44388 | - | |
f26f9fd5 | 44389 | + |
2519e6e5 ER |
44390 | if (ds->value->used && ds->key->used && |
44391 | - 0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1)) { | |
44392 | + 0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1) && | |
44393 | + 0 != strcasecmp(ds->key->ptr, "X-Sendfile")) { | |
44394 | if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1; | |
44395 | if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1; | |
44396 | ||
44397 | @@ -68,28 +70,28 @@ | |
44398 | BUFFER_APPEND_STRING_CONST(b, ": "); | |
44399 | buffer_append_string_buffer(b, ds->value); | |
44400 | #if 0 | |
44401 | - log_error_write(srv, __FILE__, __LINE__, "bb", | |
44402 | + log_error_write(srv, __FILE__, __LINE__, "bb", | |
44403 | ds->key, ds->value); | |
f26f9fd5 | 44404 | #endif |
2519e6e5 | 44405 | } |
f26f9fd5 | 44406 | } |
f26f9fd5 | 44407 | - |
2519e6e5 ER |
44408 | + |
44409 | if (!have_date) { | |
44410 | /* HTTP/1.1 requires a Date: header */ | |
44411 | BUFFER_APPEND_STRING_CONST(b, "\r\nDate: "); | |
f673a614 | 44412 | - |
2519e6e5 ER |
44413 | + |
44414 | /* cache the generated timestamp */ | |
44415 | if (srv->cur_ts != srv->last_generated_date_ts) { | |
44416 | buffer_prepare_copy(srv->ts_date_str, 255); | |
44417 | - | |
44418 | - strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1, | |
44419 | + | |
44420 | + strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1, | |
44421 | "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts))); | |
44422 | - | |
44423 | + | |
44424 | srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1; | |
f673a614 ER |
44425 | - |
44426 | + | |
2519e6e5 ER |
44427 | srv->last_generated_date_ts = srv->cur_ts; |
44428 | } | |
44429 | - | |
f673a614 | 44430 | + |
2519e6e5 | 44431 | buffer_append_string_buffer(b, srv->ts_date_str); |
f26f9fd5 | 44432 | } |
2519e6e5 ER |
44433 | |
44434 | @@ -101,16 +103,16 @@ | |
44435 | buffer_append_string_buffer(b, con->conf.server_tag); | |
44436 | } | |
44437 | } | |
44438 | - | |
f26f9fd5 | 44439 | + |
2519e6e5 ER |
44440 | BUFFER_APPEND_STRING_CONST(b, "\r\n\r\n"); |
44441 | - | |
44442 | - | |
44443 | + | |
44444 | + | |
44445 | con->bytes_header = b->used - 1; | |
44446 | - | |
44447 | + | |
44448 | if (con->conf.log_response_header) { | |
44449 | log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b); | |
f673a614 | 44450 | } |
2519e6e5 ER |
44451 | - |
44452 | + | |
44453 | return 0; | |
44454 | } | |
f26f9fd5 | 44455 | |
2519e6e5 | 44456 | @@ -118,71 +120,71 @@ |
f673a614 | 44457 | |
2519e6e5 ER |
44458 | handler_t http_response_prepare(server *srv, connection *con) { |
44459 | handler_t r; | |
44460 | - | |
44461 | - /* looks like someone has already done a decision */ | |
44462 | - if (con->mode == DIRECT && | |
f673a614 | 44463 | + |
2519e6e5 ER |
44464 | + /* looks like someone has already made a decision */ |
44465 | + if (con->mode == DIRECT && | |
44466 | (con->http_status != 0 && con->http_status != 200)) { | |
44467 | /* remove a packets in the queue */ | |
44468 | if (con->file_finished == 0) { | |
44469 | chunkqueue_reset(con->write_queue); | |
44470 | } | |
44471 | - | |
f673a614 | 44472 | + |
2519e6e5 ER |
44473 | return HANDLER_FINISHED; |
44474 | } | |
44475 | - | |
f673a614 | 44476 | + |
2519e6e5 ER |
44477 | /* no decision yet, build conf->filename */ |
44478 | if (con->mode == DIRECT && con->physical.path->used == 0) { | |
44479 | char *qstr; | |
f26f9fd5 | 44480 | |
2519e6e5 ER |
44481 | - /* we only come here when we have the parse the full request again |
44482 | - * | |
44483 | - * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a | |
44484 | + /* we only come here when we have to parse the full request again | |
44485 | + * | |
44486 | + * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a | |
44487 | * problem here as mod_setenv might get called multiple times | |
44488 | * | |
44489 | * fastcgi-auth might lead to a COMEBACK too | |
44490 | * fastcgi again dead server too | |
44491 | * | |
44492 | * mod_compress might add headers twice too | |
44493 | - * | |
44494 | + * | |
44495 | * */ | |
44496 | - | |
f673a614 | 44497 | + |
2519e6e5 ER |
44498 | if (con->conf.log_condition_handling) { |
44499 | log_error_write(srv, __FILE__, __LINE__, "s", "run condition"); | |
44500 | } | |
44501 | config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */ | |
44502 | - | |
f673a614 | 44503 | + |
2519e6e5 ER |
44504 | /** |
44505 | * prepare strings | |
44506 | - * | |
44507 | - * - uri.path_raw | |
44508 | + * | |
44509 | + * - uri.path_raw | |
44510 | * - uri.path (secure) | |
44511 | * - uri.query | |
44512 | - * | |
44513 | + * | |
44514 | */ | |
44515 | - | |
44516 | - /** | |
f26f9fd5 | 44517 | + |
2519e6e5 ER |
44518 | + /** |
44519 | * Name according to RFC 2396 | |
44520 | - * | |
44521 | + * | |
44522 | * - scheme | |
44523 | * - authority | |
44524 | * - path | |
44525 | * - query | |
44526 | - * | |
44527 | + * | |
44528 | * (scheme)://(authority)(path)?(query) | |
44529 | - * | |
44530 | - * | |
44531 | + * | |
44532 | + * | |
44533 | */ | |
44534 | - | |
f673a614 | 44535 | + |
2519e6e5 ER |
44536 | buffer_copy_string(con->uri.scheme, con->conf.is_ssl ? "https" : "http"); |
44537 | buffer_copy_string_buffer(con->uri.authority, con->request.http_host); | |
44538 | buffer_to_lower(con->uri.authority); | |
44539 | - | |
44540 | + | |
44541 | config_patch_connection(srv, con, COMP_HTTP_HOST); /* Host: */ | |
44542 | config_patch_connection(srv, con, COMP_HTTP_REMOTEIP); /* Client-IP */ | |
44543 | config_patch_connection(srv, con, COMP_HTTP_REFERER); /* Referer: */ | |
44544 | config_patch_connection(srv, con, COMP_HTTP_USERAGENT); /* User-Agent: */ | |
44545 | config_patch_connection(srv, con, COMP_HTTP_COOKIE); /* Cookie: */ | |
44546 | - | |
44547 | + | |
44548 | /** extract query string from request.uri */ | |
44549 | if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) { | |
44550 | buffer_copy_string (con->uri.query, qstr + 1); | |
44551 | @@ -200,22 +202,22 @@ | |
44552 | log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path_raw); | |
44553 | log_error_write(srv, __FILE__, __LINE__, "sb", "URI-query : ", con->uri.query); | |
44554 | } | |
44555 | - | |
44556 | + | |
44557 | /* disable keep-alive if requested */ | |
44558 | - | |
44559 | + | |
44560 | if (con->request_count > con->conf.max_keep_alive_requests) { | |
44561 | con->keep_alive = 0; | |
44562 | } | |
44563 | - | |
44564 | - | |
44565 | + | |
44566 | + | |
44567 | /** | |
44568 | - * | |
44569 | - * call plugins | |
44570 | - * | |
44571 | + * | |
44572 | + * call plugins | |
44573 | + * | |
44574 | * - based on the raw URL | |
44575 | - * | |
44576 | + * | |
44577 | */ | |
44578 | - | |
44579 | + | |
44580 | switch(r = plugins_call_handle_uri_raw(srv, con)) { | |
44581 | case HANDLER_GO_ON: | |
44582 | break; | |
44583 | @@ -229,14 +231,14 @@ | |
f26f9fd5 | 44584 | break; |
f673a614 | 44585 | } |
f673a614 | 44586 | |
2519e6e5 ER |
44587 | - /* build filename |
44588 | + /* build filename | |
44589 | * | |
44590 | * - decode url-encodings (e.g. %20 -> ' ') | |
44591 | * - remove path-modifiers (e.g. /../) | |
44592 | */ | |
44593 | - | |
44594 | - | |
44595 | - | |
f673a614 | 44596 | + |
2519e6e5 ER |
44597 | + |
44598 | + | |
44599 | if (con->request.http_method == HTTP_METHOD_OPTIONS && | |
44600 | con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') { | |
44601 | /* OPTIONS * ... */ | |
44602 | @@ -253,15 +255,20 @@ | |
44603 | } | |
f26f9fd5 | 44604 | |
2519e6e5 ER |
44605 | /** |
44606 | - * | |
44607 | - * call plugins | |
44608 | - * | |
44609 | + * | |
44610 | + * call plugins | |
44611 | + * | |
44612 | * - based on the clean URL | |
44613 | - * | |
44614 | + * | |
44615 | */ | |
44616 | - | |
f673a614 | 44617 | + |
2519e6e5 ER |
44618 | config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */ |
44619 | - | |
f673a614 | 44620 | + |
2519e6e5 ER |
44621 | + /* do we have to downgrade to 1.0 ? */ |
44622 | + if (!con->conf.allow_http11) { | |
44623 | + con->request.http_version = HTTP_VERSION_1_0; | |
44624 | + } | |
f673a614 | 44625 | + |
2519e6e5 ER |
44626 | switch(r = plugins_call_handle_uri_clean(srv, con)) { |
44627 | case HANDLER_GO_ON: | |
44628 | break; | |
44629 | @@ -274,11 +281,11 @@ | |
44630 | log_error_write(srv, __FILE__, __LINE__, ""); | |
44631 | break; | |
44632 | } | |
44633 | - | |
f673a614 | 44634 | + |
2519e6e5 ER |
44635 | if (con->request.http_method == HTTP_METHOD_OPTIONS && |
44636 | con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') { | |
44637 | - /* option requests are handled directly without checking of the path */ | |
44638 | - | |
44639 | + /* option requests are handled directly without checking the path */ | |
44640 | + | |
44641 | response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST")); | |
44642 | ||
44643 | con->http_status = 200; | |
44644 | @@ -288,46 +295,47 @@ | |
44645 | } | |
44646 | ||
44647 | /*** | |
44648 | - * | |
44649 | - * border | |
44650 | - * | |
44651 | + * | |
44652 | + * border | |
44653 | + * | |
44654 | * logical filename (URI) becomes a physical filename here | |
44655 | - * | |
44656 | - * | |
44657 | - * | |
44658 | + * | |
44659 | + * | |
44660 | + * | |
44661 | */ | |
44662 | - | |
44663 | - | |
44664 | - | |
44665 | - | |
f673a614 | 44666 | + |
f673a614 | 44667 | + |
f673a614 | 44668 | + |
f673a614 | 44669 | + |
2519e6e5 ER |
44670 | /* 1. stat() |
44671 | * ... ISREG() -> ok, go on | |
44672 | * ... ISDIR() -> index-file -> redirect | |
44673 | - * | |
44674 | - * 2. pathinfo() | |
44675 | + * | |
44676 | + * 2. pathinfo() | |
44677 | * ... ISREG() | |
44678 | - * | |
44679 | + * | |
44680 | * 3. -> 404 | |
44681 | - * | |
44682 | + * | |
44683 | */ | |
44684 | - | |
f673a614 | 44685 | + |
2519e6e5 ER |
44686 | /* |
44687 | * SEARCH DOCUMENT ROOT | |
44688 | */ | |
44689 | - | |
f673a614 | 44690 | + |
2519e6e5 ER |
44691 | /* set a default */ |
44692 | - | |
f673a614 | 44693 | + |
2519e6e5 ER |
44694 | buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root); |
44695 | buffer_copy_string_buffer(con->physical.rel_path, con->uri.path); | |
44696 | - | |
44697 | -#if defined(__WIN32) || defined(__CYGWIN__) | |
44698 | - /* strip dots from the end and spaces | |
f26f9fd5 | 44699 | + |
2519e6e5 ER |
44700 | + filename_unix2local(con->physical.rel_path); |
44701 | +#if defined(_WIN32) || defined(__CYGWIN__) | |
44702 | + /* strip dots and spaces from the end | |
44703 | * | |
44704 | * windows/dos handle those filenames as the same file | |
44705 | * | |
44706 | * foo == foo. == foo..... == "foo... " == "foo.. ./" | |
44707 | * | |
44708 | - * This will affect in some cases PATHINFO | |
44709 | + * This will affect PATHINFO in some cases | |
44710 | * | |
44711 | * on native windows we could prepend the filename with \\?\ to circumvent | |
44712 | * this behaviour. I have no idea how to push this through cygwin | |
44713 | @@ -377,36 +385,41 @@ | |
44714 | log_error_write(srv, __FILE__, __LINE__, ""); | |
f26f9fd5 | 44715 | break; |
f673a614 | 44716 | } |
2519e6e5 ER |
44717 | - |
44718 | - /* MacOS X and Windows can't distiguish between upper and lower-case | |
44719 | - * | |
44720 | - * convert to lower-case | |
44721 | + | |
44722 | + /* The default Mac OS X and Windows filesystems can't distiguish between | |
44723 | + * upper- and lowercase, so convert to lowercase | |
44724 | */ | |
44725 | if (con->conf.force_lowercase_filenames) { | |
44726 | buffer_to_lower(con->physical.rel_path); | |
44727 | } | |
44728 | ||
44729 | - /* the docroot plugins might set the servername, if they don't we take http-host */ | |
44730 | + /* the docroot plugins might set the servername; if they don't we take http-host */ | |
44731 | if (buffer_is_empty(con->server_name)) { | |
44732 | buffer_copy_string_buffer(con->server_name, con->uri.authority); | |
44733 | } | |
44734 | - | |
44735 | - /** | |
44736 | - * create physical filename | |
44737 | + | |
44738 | + /** | |
44739 | + * create physical filename | |
44740 | * -> physical.path = docroot + rel_path | |
44741 | - * | |
44742 | + * | |
44743 | */ | |
44744 | - | |
44745 | + | |
44746 | buffer_copy_string_buffer(con->physical.path, con->physical.doc_root); | |
44747 | - BUFFER_APPEND_SLASH(con->physical.path); | |
44748 | + PATHNAME_APPEND_SLASH(con->physical.path); | |
44749 | buffer_copy_string_buffer(con->physical.basedir, con->physical.path); | |
44750 | if (con->physical.rel_path->used && | |
44751 | - con->physical.rel_path->ptr[0] == '/') { | |
44752 | + con->physical.rel_path->ptr[0] == DIR_SEPERATOR) { | |
44753 | buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2); | |
44754 | } else { | |
44755 | buffer_append_string_buffer(con->physical.path, con->physical.rel_path); | |
44756 | } | |
44757 | ||
44758 | + /* win32: directories can't have a trailing slash */ | |
44759 | + if (con->physical.path->ptr[con->physical.path->used - 2] == DIR_SEPERATOR) { | |
44760 | + con->physical.path->ptr[con->physical.path->used - 2] = '\0'; | |
44761 | + con->physical.path->used--; | |
44762 | + } | |
44763 | + | |
44764 | if (con->conf.log_request_handling) { | |
44765 | log_error_write(srv, __FILE__, __LINE__, "s", "-- after doc_root"); | |
44766 | log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root); | |
44767 | @@ -426,7 +439,7 @@ | |
44768 | log_error_write(srv, __FILE__, __LINE__, ""); | |
44769 | break; | |
f673a614 | 44770 | } |
2519e6e5 ER |
44771 | - |
44772 | + | |
44773 | if (con->conf.log_request_handling) { | |
44774 | log_error_write(srv, __FILE__, __LINE__, "s", "-- logical -> physical"); | |
44775 | log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root); | |
44776 | @@ -434,38 +447,38 @@ | |
44777 | log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); | |
f673a614 ER |
44778 | } |
44779 | } | |
2519e6e5 ER |
44780 | - |
44781 | - /* | |
44782 | - * Noone catched away the file from normal path of execution yet (like mod_access) | |
44783 | - * | |
f673a614 | 44784 | + |
2519e6e5 ER |
44785 | + /* |
44786 | + * No one took the file away from the normal path of execution yet (like mod_access) | |
44787 | + * | |
44788 | * Go on and check of the file exists at all | |
44789 | */ | |
44790 | - | |
f673a614 | 44791 | + |
2519e6e5 ER |
44792 | if (con->mode == DIRECT) { |
44793 | char *slash = NULL; | |
44794 | char *pathinfo = NULL; | |
44795 | int found = 0; | |
44796 | stat_cache_entry *sce = NULL; | |
44797 | - | |
f673a614 | 44798 | + |
2519e6e5 ER |
44799 | if (con->conf.log_request_handling) { |
44800 | log_error_write(srv, __FILE__, __LINE__, "s", "-- handling physical path"); | |
44801 | log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); | |
44802 | } | |
44803 | - | |
f673a614 | 44804 | + |
2519e6e5 ER |
44805 | if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { |
44806 | /* file exists */ | |
44807 | - | |
f673a614 | 44808 | + |
2519e6e5 ER |
44809 | if (con->conf.log_request_handling) { |
44810 | log_error_write(srv, __FILE__, __LINE__, "s", "-- file found"); | |
44811 | log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); | |
44812 | } | |
44813 | - | |
f673a614 | 44814 | + |
2519e6e5 ER |
44815 | if (S_ISDIR(sce->st.st_mode)) { |
44816 | - if (con->physical.path->ptr[con->physical.path->used - 2] != '/') { | |
44817 | + if (con->uri.path->ptr[con->uri.path->used - 2] != '/') { | |
44818 | /* redirect to .../ */ | |
44819 | - | |
f673a614 | 44820 | + |
2519e6e5 ER |
44821 | http_response_redirect_to_directory(srv, con); |
44822 | - | |
f673a614 | 44823 | + |
2519e6e5 ER |
44824 | return HANDLER_FINISHED; |
44825 | } | |
44826 | } else if (!S_ISREG(sce->st.st_mode)) { | |
44827 | @@ -477,12 +490,12 @@ | |
44828 | switch (errno) { | |
44829 | case EACCES: | |
44830 | con->http_status = 403; | |
44831 | - | |
f673a614 | 44832 | + |
2519e6e5 ER |
44833 | if (con->conf.log_request_handling) { |
44834 | log_error_write(srv, __FILE__, __LINE__, "s", "-- access denied"); | |
44835 | log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); | |
44836 | } | |
44837 | - | |
f673a614 | 44838 | + |
2519e6e5 ER |
44839 | buffer_reset(con->physical.path); |
44840 | return HANDLER_FINISHED; | |
44841 | case ENOENT: | |
44842 | @@ -499,77 +512,77 @@ | |
44843 | /* PATH_INFO ! :) */ | |
44844 | break; | |
44845 | default: | |
44846 | - /* we have no idea what happend. let's tell the user so. */ | |
44847 | + /* we have no idea what happened, so tell the user. */ | |
44848 | con->http_status = 500; | |
44849 | buffer_reset(con->physical.path); | |
44850 | - | |
f673a614 | 44851 | + |
2519e6e5 ER |
44852 | log_error_write(srv, __FILE__, __LINE__, "ssbsb", |
44853 | "file not found ... or so: ", strerror(errno), | |
44854 | con->uri.path, | |
44855 | "->", con->physical.path); | |
44856 | - | |
44857 | + | |
44858 | return HANDLER_FINISHED; | |
f26f9fd5 | 44859 | } |
2519e6e5 ER |
44860 | - |
44861 | + | |
44862 | /* not found, perhaps PATHINFO */ | |
44863 | - | |
44864 | + | |
44865 | buffer_copy_string_buffer(srv->tmp_buf, con->physical.path); | |
44866 | - | |
44867 | + | |
44868 | do { | |
44869 | struct stat st; | |
44870 | - | |
44871 | + | |
44872 | if (slash) { | |
44873 | buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr); | |
44874 | } else { | |
44875 | buffer_copy_string_buffer(con->physical.path, srv->tmp_buf); | |
44876 | } | |
44877 | - | |
44878 | + | |
44879 | if (0 == stat(con->physical.path->ptr, &(st)) && | |
44880 | S_ISREG(st.st_mode)) { | |
44881 | found = 1; | |
44882 | break; | |
44883 | } | |
44884 | - | |
44885 | + | |
44886 | if (pathinfo != NULL) { | |
44887 | *pathinfo = '\0'; | |
44888 | } | |
44889 | slash = strrchr(srv->tmp_buf->ptr, '/'); | |
44890 | - | |
44891 | + | |
44892 | if (pathinfo != NULL) { | |
44893 | /* restore '/' */ | |
44894 | *pathinfo = '/'; | |
44895 | } | |
44896 | - | |
44897 | + | |
44898 | if (slash) pathinfo = slash; | |
44899 | } while ((found == 0) && (slash != NULL) && (slash - srv->tmp_buf->ptr > con->physical.basedir->used - 2)); | |
44900 | - | |
44901 | + | |
44902 | if (found == 0) { | |
44903 | - /* no it really doesn't exists */ | |
44904 | + /* no, it really doesn't exists */ | |
44905 | con->http_status = 404; | |
44906 | - | |
44907 | + | |
44908 | if (con->conf.log_file_not_found) { | |
44909 | log_error_write(srv, __FILE__, __LINE__, "sbsb", | |
44910 | "file not found:", con->uri.path, | |
44911 | "->", con->physical.path); | |
44912 | } | |
44913 | - | |
44914 | + | |
44915 | buffer_reset(con->physical.path); | |
44916 | - | |
44917 | + | |
44918 | return HANDLER_FINISHED; | |
f26f9fd5 | 44919 | } |
2519e6e5 ER |
44920 | - |
44921 | + | |
44922 | /* we have a PATHINFO */ | |
44923 | if (pathinfo) { | |
44924 | buffer_copy_string(con->request.pathinfo, pathinfo); | |
44925 | - | |
44926 | + | |
44927 | /* | |
44928 | * shorten uri.path | |
44929 | */ | |
44930 | - | |
44931 | + | |
44932 | con->uri.path->used -= strlen(pathinfo); | |
44933 | con->uri.path->ptr[con->uri.path->used - 1] = '\0'; | |
f26f9fd5 | 44934 | } |
2519e6e5 ER |
44935 | - |
44936 | + | |
44937 | if (con->conf.log_request_handling) { | |
44938 | log_error_write(srv, __FILE__, __LINE__, "s", "-- after pathinfo check"); | |
44939 | log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); | |
44940 | @@ -577,12 +590,12 @@ | |
44941 | log_error_write(srv, __FILE__, __LINE__, "sb", "Pathinfo :", con->request.pathinfo); | |
f673a614 | 44942 | } |
2519e6e5 ER |
44943 | } |
44944 | - | |
44945 | + | |
44946 | if (con->conf.log_request_handling) { | |
44947 | log_error_write(srv, __FILE__, __LINE__, "s", "-- handling subrequest"); | |
44948 | log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); | |
44949 | } | |
44950 | - | |
44951 | + | |
44952 | /* call the handlers */ | |
44953 | switch(r = plugins_call_handle_subrequest_start(srv, con)) { | |
44954 | case HANDLER_GO_ON: | |
44955 | @@ -593,32 +606,32 @@ | |
44956 | if (con->conf.log_request_handling) { | |
44957 | log_error_write(srv, __FILE__, __LINE__, "s", "-- subrequest finished"); | |
f26f9fd5 | 44958 | } |
2519e6e5 ER |
44959 | - |
44960 | - /* something strange happend */ | |
44961 | + | |
44962 | + /* something strange happened */ | |
44963 | return r; | |
44964 | } | |
44965 | - | |
44966 | - /* if we are still here, no one wanted the file, status 403 is ok I think */ | |
44967 | - | |
44968 | + | |
44969 | + /* if we are still here, no one wanted the file; status 403 is ok I think */ | |
44970 | + | |
44971 | if (con->mode == DIRECT) { | |
44972 | con->http_status = 403; | |
44973 | - | |
44974 | + | |
44975 | return HANDLER_FINISHED; | |
44976 | } | |
44977 | - | |
44978 | + | |
44979 | } | |
44980 | - | |
44981 | + | |
44982 | switch(r = plugins_call_handle_subrequest(srv, con)) { | |
44983 | case HANDLER_GO_ON: | |
44984 | - /* request was not handled, looks like we are done */ | |
44985 | + /* request was not handled; looks like we are done */ | |
44986 | return HANDLER_FINISHED; | |
44987 | case HANDLER_FINISHED: | |
44988 | /* request is finished */ | |
44989 | default: | |
44990 | - /* something strange happend */ | |
44991 | + /* something strange happened */ | |
44992 | return r; | |
44993 | } | |
44994 | - | |
44995 | + | |
44996 | /* can't happen */ | |
44997 | return HANDLER_COMEBACK; | |
44998 | } | |
1175ccec | 44999 | --- ../lighttpd-1.4.11/src/server.c 2006-03-04 19:12:17.000000000 +0200 |
36e2a29e | 45000 | +++ lighttpd-1.4.12/src/server.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
45001 | @@ -1,11 +1,9 @@ |
45002 | #include <sys/types.h> | |
45003 | -#include <sys/time.h> | |
45004 | #include <sys/stat.h> | |
f26f9fd5 | 45005 | |
2519e6e5 ER |
45006 | #include <string.h> |
45007 | #include <errno.h> | |
45008 | #include <fcntl.h> | |
45009 | -#include <unistd.h> | |
45010 | #include <stdlib.h> | |
45011 | #include <time.h> | |
45012 | #include <signal.h> | |
45013 | @@ -29,9 +27,14 @@ | |
45014 | #include "plugin.h" | |
45015 | #include "joblist.h" | |
45016 | #include "network_backends.h" | |
45017 | - | |
45018 | +#ifdef _WIN32 | |
45019 | +/* use local getopt implementation */ | |
45020 | +# undef HAVE_GETOPT_H | |
45021 | +#endif | |
45022 | #ifdef HAVE_GETOPT_H | |
45023 | #include <getopt.h> | |
45024 | +#else | |
45025 | +#include "getopt.h" | |
45026 | #endif | |
f673a614 | 45027 | |
2519e6e5 ER |
45028 | #ifdef HAVE_VALGRIND_VALGRIND_H |
45029 | @@ -60,8 +63,16 @@ | |
45030 | /* #define USE_ALARM */ | |
f26f9fd5 | 45031 | #endif |
f26f9fd5 | 45032 | |
2519e6e5 ER |
45033 | +#ifdef _WIN32 |
45034 | +#undef HAVE_SIGNAL | |
45035 | +#endif | |
45036 | + | |
45037 | +#include "sys-files.h" | |
45038 | +#include "sys-process.h" | |
45039 | + | |
45040 | static volatile sig_atomic_t srv_shutdown = 0; | |
45041 | static volatile sig_atomic_t graceful_shutdown = 0; | |
45042 | +static volatile sig_atomic_t graceful_restart = 0; | |
45043 | static volatile sig_atomic_t handle_sig_alarm = 1; | |
45044 | static volatile sig_atomic_t handle_sig_hup = 0; | |
f673a614 | 45045 | |
2519e6e5 ER |
45046 | @@ -72,9 +83,9 @@ |
45047 | ||
45048 | switch (sig) { | |
45049 | case SIGTERM: srv_shutdown = 1; break; | |
45050 | - case SIGINT: | |
45051 | + case SIGINT: | |
45052 | if (graceful_shutdown) srv_shutdown = 1; | |
45053 | - else graceful_shutdown = 1; | |
45054 | + else graceful_shutdown = 1; | |
45055 | ||
45056 | break; | |
45057 | case SIGALRM: handle_sig_alarm = 1; break; | |
45058 | @@ -86,9 +97,9 @@ | |
45059 | static void signal_handler(int sig) { | |
45060 | switch (sig) { | |
45061 | case SIGTERM: srv_shutdown = 1; break; | |
45062 | - case SIGINT: | |
45063 | + case SIGINT: | |
45064 | if (graceful_shutdown) srv_shutdown = 1; | |
45065 | - else graceful_shutdown = 1; | |
45066 | + else graceful_shutdown = 1; | |
45067 | ||
45068 | break; | |
45069 | case SIGALRM: handle_sig_alarm = 1; break; | |
45070 | @@ -110,25 +121,26 @@ | |
45071 | signal(SIGTSTP, SIG_IGN); | |
f26f9fd5 | 45072 | #endif |
2519e6e5 ER |
45073 | if (0 != fork()) exit(0); |
45074 | - | |
45075 | + | |
45076 | if (-1 == setsid()) exit(0); | |
45077 | ||
45078 | signal(SIGHUP, SIG_IGN); | |
45079 | ||
45080 | if (0 != fork()) exit(0); | |
45081 | - | |
45082 | + | |
45083 | if (0 != chdir("/")) exit(0); | |
45084 | } | |
f26f9fd5 | 45085 | #endif |
f673a614 | 45086 | |
2519e6e5 ER |
45087 | static server *server_init(void) { |
45088 | int i; | |
f673a614 | 45089 | - |
f673a614 | 45090 | + |
2519e6e5 ER |
45091 | server *srv = calloc(1, sizeof(*srv)); |
45092 | assert(srv); | |
45093 | + srv->max_fds = 1024; | |
45094 | #define CLEAN(x) \ | |
45095 | srv->x = buffer_init(); | |
45096 | - | |
f673a614 | 45097 | + |
2519e6e5 ER |
45098 | CLEAN(response_header); |
45099 | CLEAN(parse_full_path); | |
45100 | CLEAN(ts_debug_str); | |
45101 | @@ -138,7 +150,7 @@ | |
45102 | CLEAN(tmp_buf); | |
45103 | srv->empty_string = buffer_init_string(""); | |
45104 | CLEAN(cond_check_buf); | |
45105 | - | |
f673a614 | 45106 | + |
2519e6e5 ER |
45107 | CLEAN(srvconf.errorlog_file); |
45108 | CLEAN(srvconf.groupname); | |
45109 | CLEAN(srvconf.username); | |
45110 | @@ -146,58 +158,58 @@ | |
45111 | CLEAN(srvconf.bindhost); | |
45112 | CLEAN(srvconf.event_handler); | |
45113 | CLEAN(srvconf.pid_file); | |
45114 | - | |
f673a614 | 45115 | + |
2519e6e5 ER |
45116 | CLEAN(tmp_chunk_len); |
45117 | #undef CLEAN | |
45118 | - | |
f673a614 | 45119 | + |
2519e6e5 ER |
45120 | #define CLEAN(x) \ |
45121 | srv->x = array_init(); | |
45122 | - | |
f673a614 | 45123 | + |
2519e6e5 ER |
45124 | CLEAN(config_context); |
45125 | CLEAN(config_touched); | |
45126 | CLEAN(status); | |
45127 | #undef CLEAN | |
45128 | - | |
45129 | + | |
45130 | for (i = 0; i < FILE_CACHE_MAX; i++) { | |
45131 | srv->mtime_cache[i].str = buffer_init(); | |
45132 | } | |
45133 | - | |
45134 | + | |
45135 | srv->cur_ts = time(NULL); | |
45136 | srv->startup_ts = srv->cur_ts; | |
45137 | - | |
45138 | + | |
45139 | srv->conns = calloc(1, sizeof(*srv->conns)); | |
45140 | assert(srv->conns); | |
45141 | - | |
45142 | + | |
45143 | srv->joblist = calloc(1, sizeof(*srv->joblist)); | |
45144 | assert(srv->joblist); | |
45145 | - | |
45146 | + | |
45147 | srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue)); | |
45148 | assert(srv->fdwaitqueue); | |
45149 | - | |
45150 | + | |
45151 | srv->srvconf.modules = array_init(); | |
45152 | srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR); | |
45153 | srv->srvconf.network_backend = buffer_init(); | |
45154 | srv->srvconf.upload_tempdirs = array_init(); | |
45155 | - | |
45156 | + | |
45157 | /* use syslog */ | |
45158 | srv->errorlog_fd = -1; | |
45159 | srv->errorlog_mode = ERRORLOG_STDERR; | |
f26f9fd5 | 45160 | |
2519e6e5 ER |
45161 | srv->split_vals = array_init(); |
45162 | - | |
45163 | + | |
45164 | return srv; | |
45165 | } | |
f26f9fd5 | 45166 | |
2519e6e5 ER |
45167 | static void server_free(server *srv) { |
45168 | size_t i; | |
45169 | - | |
45170 | + | |
45171 | for (i = 0; i < FILE_CACHE_MAX; i++) { | |
45172 | buffer_free(srv->mtime_cache[i].str); | |
45173 | } | |
45174 | - | |
45175 | + | |
45176 | #define CLEAN(x) \ | |
45177 | buffer_free(srv->x); | |
45178 | - | |
45179 | + | |
45180 | CLEAN(response_header); | |
45181 | CLEAN(parse_full_path); | |
45182 | CLEAN(ts_debug_str); | |
45183 | @@ -207,7 +219,7 @@ | |
45184 | CLEAN(tmp_buf); | |
45185 | CLEAN(empty_string); | |
45186 | CLEAN(cond_check_buf); | |
45187 | - | |
45188 | + | |
45189 | CLEAN(srvconf.errorlog_file); | |
45190 | CLEAN(srvconf.groupname); | |
45191 | CLEAN(srvconf.username); | |
45192 | @@ -217,7 +229,7 @@ | |
45193 | CLEAN(srvconf.pid_file); | |
45194 | CLEAN(srvconf.modules_dir); | |
45195 | CLEAN(srvconf.network_backend); | |
45196 | - | |
45197 | + | |
45198 | CLEAN(tmp_chunk_len); | |
45199 | #undef CLEAN | |
f26f9fd5 | 45200 | |
2519e6e5 ER |
45201 | @@ -225,15 +237,15 @@ |
45202 | fdevent_unregister(srv->ev, srv->fd); | |
45203 | #endif | |
45204 | fdevent_free(srv->ev); | |
45205 | - | |
45206 | + | |
45207 | free(srv->conns); | |
45208 | - | |
45209 | + | |
45210 | if (srv->config_storage) { | |
45211 | for (i = 0; i < srv->config_context->used; i++) { | |
45212 | specific_config *s = srv->config_storage[i]; | |
f26f9fd5 | 45213 | |
2519e6e5 ER |
45214 | if (!s) continue; |
45215 | - | |
45216 | + | |
45217 | buffer_free(s->document_root); | |
45218 | buffer_free(s->server_name); | |
45219 | buffer_free(s->server_tag); | |
45220 | @@ -242,32 +254,32 @@ | |
45221 | buffer_free(s->error_handler); | |
45222 | buffer_free(s->errorfile_prefix); | |
45223 | array_free(s->mimetypes); | |
45224 | - | |
45225 | + | |
45226 | free(s); | |
f673a614 | 45227 | } |
2519e6e5 ER |
45228 | free(srv->config_storage); |
45229 | srv->config_storage = NULL; | |
45230 | } | |
45231 | - | |
45232 | + | |
45233 | #define CLEAN(x) \ | |
45234 | array_free(srv->x); | |
45235 | - | |
45236 | + | |
45237 | CLEAN(config_context); | |
45238 | CLEAN(config_touched); | |
45239 | CLEAN(status); | |
45240 | CLEAN(srvconf.upload_tempdirs); | |
45241 | #undef CLEAN | |
45242 | - | |
45243 | + | |
45244 | joblist_free(srv, srv->joblist); | |
45245 | fdwaitqueue_free(srv, srv->fdwaitqueue); | |
45246 | - | |
45247 | + | |
45248 | if (srv->stat_cache) { | |
45249 | stat_cache_free(srv->stat_cache); | |
f673a614 | 45250 | } |
f673a614 | 45251 | |
2519e6e5 ER |
45252 | array_free(srv->srvconf.modules); |
45253 | array_free(srv->split_vals); | |
45254 | - | |
45255 | + | |
45256 | free(srv); | |
45257 | } | |
45258 | ||
45259 | @@ -281,14 +293,12 @@ | |
45260 | " - a light and fast webserver\n" \ | |
45261 | "Build-Date: " __DATE__ " " __TIME__ "\n"; | |
45262 | ; | |
45263 | -#undef TEXT_SSL | |
45264 | +#undef TEXT_SSL | |
45265 | write(STDOUT_FILENO, b, strlen(b)); | |
f26f9fd5 | 45266 | } |
f673a614 | 45267 | |
2519e6e5 ER |
45268 | static void show_features (void) { |
45269 | - show_version(); | |
45270 | - printf("\nEvent Handlers:\n\n%s", | |
45271 | - | |
45272 | + const char *s = "" | |
45273 | #ifdef USE_SELECT | |
45274 | "\t+ select (generic)\n" | |
45275 | #else | |
45276 | @@ -355,11 +365,6 @@ | |
45277 | #else | |
45278 | "\t- crypt support\n" | |
f673a614 | 45279 | #endif |
2519e6e5 ER |
45280 | -#ifdef USE_PAM |
45281 | - "\t+ PAM support\n" | |
45282 | -#else | |
45283 | - "\t- PAM support\n" | |
45284 | -#endif | |
45285 | #ifdef USE_OPENSSL | |
45286 | "\t+ SSL Support\n" | |
45287 | #else | |
45288 | @@ -371,9 +376,9 @@ | |
45289 | "\t- PCRE support\n" | |
f26f9fd5 | 45290 | #endif |
2519e6e5 ER |
45291 | #ifdef HAVE_MYSQL |
45292 | - "\t+ mySQL support\n" | |
45293 | + "\t+ MySQL support\n" | |
45294 | #else | |
45295 | - "\t- mySQL support\n" | |
45296 | + "\t- MySQL support\n" | |
f673a614 | 45297 | #endif |
2519e6e5 ER |
45298 | #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER) |
45299 | "\t+ LDAP support\n" | |
45300 | @@ -410,8 +415,11 @@ | |
45301 | #else | |
45302 | "\t- GDBM support\n" | |
45303 | #endif | |
45304 | - "\n" | |
45305 | - ); | |
45306 | + "\n"; | |
f673a614 | 45307 | + |
2519e6e5 ER |
45308 | + show_version(); |
45309 | + | |
45310 | + printf("\nEvent Handlers:\n\n%s", s); | |
f26f9fd5 | 45311 | } |
f673a614 | 45312 | |
2519e6e5 ER |
45313 | static void show_help (void) { |
45314 | @@ -433,12 +441,12 @@ | |
45315 | " -h show this help\n" \ | |
45316 | "\n" | |
45317 | ; | |
45318 | -#undef TEXT_SSL | |
45319 | +#undef TEXT_SSL | |
45320 | #undef TEXT_IPV6 | |
45321 | write(STDOUT_FILENO, b, strlen(b)); | |
45322 | } | |
f673a614 | 45323 | |
2519e6e5 ER |
45324 | -int main (int argc, char **argv) { |
45325 | +int main (int argc, char **argv, char **envp) { | |
45326 | server *srv = NULL; | |
45327 | int print_config = 0; | |
45328 | int test_config = 0; | |
45329 | @@ -447,33 +455,37 @@ | |
45330 | int num_childs = 0; | |
45331 | int pid_fd = -1, fd; | |
45332 | size_t i; | |
f26f9fd5 | 45333 | +#ifdef _WIN32 |
2519e6e5 | 45334 | + char *optarg = NULL; |
f26f9fd5 | 45335 | +#endif |
f673a614 | 45336 | + |
2519e6e5 ER |
45337 | #ifdef HAVE_SIGACTION |
45338 | struct sigaction act; | |
f673a614 | 45339 | #endif |
2519e6e5 ER |
45340 | #ifdef HAVE_GETRLIMIT |
45341 | struct rlimit rlim; | |
f673a614 | 45342 | #endif |
2519e6e5 | 45343 | - |
f673a614 | 45344 | + |
2519e6e5 ER |
45345 | #ifdef USE_ALARM |
45346 | struct itimerval interval; | |
45347 | - | |
f673a614 | 45348 | + |
2519e6e5 ER |
45349 | interval.it_interval.tv_sec = 1; |
45350 | interval.it_interval.tv_usec = 0; | |
45351 | interval.it_value.tv_sec = 1; | |
45352 | interval.it_value.tv_usec = 0; | |
45353 | #endif | |
45354 | - | |
45355 | - | |
f673a614 | 45356 | + |
f673a614 | 45357 | + |
2519e6e5 ER |
45358 | /* for nice %b handling in strfime() */ |
45359 | setlocale(LC_TIME, "C"); | |
45360 | - | |
45361 | + | |
45362 | if (NULL == (srv = server_init())) { | |
45363 | fprintf(stderr, "did this really happen?\n"); | |
45364 | return -1; | |
f673a614 | 45365 | } |
2519e6e5 | 45366 | - |
f673a614 | 45367 | + |
2519e6e5 ER |
45368 | /* init structs done */ |
45369 | - | |
f673a614 | 45370 | + |
2519e6e5 ER |
45371 | srv->srvconf.port = 0; |
45372 | #ifdef HAVE_GETUID | |
45373 | i_am_root = (getuid() == 0); | |
45374 | @@ -481,14 +493,19 @@ | |
45375 | i_am_root = 0; | |
45376 | #endif | |
45377 | srv->srvconf.dont_daemonize = 0; | |
45378 | - | |
f673a614 | 45379 | + |
2519e6e5 ER |
45380 | while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) { |
45381 | switch(o) { | |
45382 | - case 'f': | |
45383 | - if (config_read(srv, optarg)) { | |
45384 | + case 'f': | |
45385 | +#ifdef _WIN32 | |
45386 | + /* evil HACK for windows, optarg is not set */ | |
45387 | + optarg = argv[optind-1]; | |
45388 | +#endif | |
45389 | + if (config_read(srv, optarg)) { | |
45390 | server_free(srv); | |
45391 | return -1; | |
45392 | } | |
f673a614 | 45393 | + |
2519e6e5 ER |
45394 | break; |
45395 | case 'm': | |
45396 | buffer_copy_string(srv->srvconf.modules_dir, optarg); | |
45397 | @@ -497,23 +514,23 @@ | |
45398 | case 't': test_config = 1; break; | |
45399 | case 'D': srv->srvconf.dont_daemonize = 1; break; | |
45400 | case 'v': show_version(); return 0; | |
45401 | - case 'V': show_features(); return 0; | |
45402 | + case 'V': show_features(); return 0; | |
45403 | case 'h': show_help(); return 0; | |
45404 | - default: | |
45405 | + default: | |
45406 | show_help(); | |
45407 | server_free(srv); | |
45408 | return -1; | |
45409 | } | |
45410 | } | |
45411 | - | |
f673a614 | 45412 | + |
2519e6e5 ER |
45413 | if (!srv->config_storage) { |
45414 | log_error_write(srv, __FILE__, __LINE__, "s", | |
45415 | "No configuration available. Try using -f option."); | |
45416 | - | |
f673a614 | 45417 | + |
2519e6e5 ER |
45418 | server_free(srv); |
45419 | return -1; | |
45420 | } | |
45421 | - | |
45422 | + | |
45423 | if (print_config) { | |
45424 | data_unset *dc = srv->config_context->data[0]; | |
45425 | if (dc) { | |
45426 | @@ -533,7 +550,7 @@ | |
45427 | server_free(srv); | |
45428 | return 0; | |
45429 | } | |
45430 | - | |
45431 | + | |
45432 | /* close stdin and stdout, as they are not needed */ | |
45433 | /* move stdin to /dev/null */ | |
45434 | if (-1 != (fd = open("/dev/null", O_RDONLY))) { | |
45435 | @@ -541,54 +558,55 @@ | |
45436 | dup2(fd, STDIN_FILENO); | |
45437 | close(fd); | |
45438 | } | |
45439 | - | |
45440 | + | |
45441 | /* move stdout to /dev/null */ | |
45442 | if (-1 != (fd = open("/dev/null", O_WRONLY))) { | |
45443 | close(STDOUT_FILENO); | |
45444 | dup2(fd, STDOUT_FILENO); | |
45445 | close(fd); | |
45446 | } | |
45447 | - | |
45448 | + | |
45449 | if (0 != config_set_defaults(srv)) { | |
45450 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
45451 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
45452 | "setting default values failed"); | |
45453 | server_free(srv); | |
f26f9fd5 ER |
45454 | return -1; |
45455 | } | |
2519e6e5 ER |
45456 | - |
45457 | + | |
45458 | /* UID handling */ | |
45459 | #ifdef HAVE_GETUID | |
45460 | if (!i_am_root && (geteuid() == 0 || getegid() == 0)) { | |
45461 | /* we are setuid-root */ | |
45462 | - | |
45463 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
45464 | + | |
45465 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
45466 | "Are you nuts ? Don't apply a SUID bit to this binary"); | |
45467 | - | |
45468 | + | |
45469 | server_free(srv); | |
f26f9fd5 | 45470 | return -1; |
f673a614 | 45471 | } |
2519e6e5 ER |
45472 | #endif |
45473 | - | |
45474 | + | |
45475 | /* check document-root */ | |
45476 | if (srv->config_storage[0]->document_root->used <= 1) { | |
45477 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
45478 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
45479 | "document-root is not set\n"); | |
45480 | - | |
45481 | + | |
45482 | server_free(srv); | |
45483 | - | |
45484 | + | |
45485 | return -1; | |
f673a614 | 45486 | } |
2519e6e5 ER |
45487 | - |
45488 | + | |
45489 | if (plugins_load(srv)) { | |
45490 | log_error_write(srv, __FILE__, __LINE__, "s", | |
45491 | "loading plugins finally failed"); | |
45492 | - | |
45493 | + | |
45494 | plugins_free(srv); | |
45495 | server_free(srv); | |
45496 | - | |
45497 | + | |
45498 | return -1; | |
f673a614 | 45499 | } |
2519e6e5 ER |
45500 | - |
45501 | + | |
45502 | +#ifndef _WIN32 | |
45503 | /* open pid file BEFORE chroot */ | |
45504 | if (srv->srvconf.pid_file->used) { | |
45505 | if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { | |
45506 | @@ -598,18 +616,18 @@ | |
45507 | "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno)); | |
45508 | return -1; | |
45509 | } | |
45510 | - | |
45511 | + | |
45512 | if (0 != stat(srv->srvconf.pid_file->ptr, &st)) { | |
45513 | log_error_write(srv, __FILE__, __LINE__, "sbs", | |
45514 | "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno)); | |
45515 | } | |
45516 | - | |
45517 | + | |
45518 | if (!S_ISREG(st.st_mode)) { | |
45519 | log_error_write(srv, __FILE__, __LINE__, "sb", | |
45520 | "pid-file exists and isn't regular file:", srv->srvconf.pid_file); | |
45521 | return -1; | |
45522 | } | |
45523 | - | |
45524 | + | |
45525 | if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { | |
45526 | log_error_write(srv, __FILE__, __LINE__, "sbs", | |
45527 | "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno)); | |
45528 | @@ -617,13 +635,14 @@ | |
45529 | } | |
45530 | } | |
45531 | } | |
45532 | - | |
45533 | +#endif | |
45534 | if (srv->event_handler == FDEVENT_HANDLER_SELECT) { | |
45535 | /* select limits itself | |
45536 | * | |
45537 | * as it is a hard limit and will lead to a segfault we add some safety | |
45538 | * */ | |
45539 | - srv->max_fds = FD_SETSIZE - 200; | |
45540 | + fprintf(stderr, "%s.%d: max parallel connections: %d\r\n", __FILE__, __LINE__, FD_SETSIZE); | |
45541 | + srv->max_fds = FD_SETSIZE - 4; | |
45542 | } else { | |
45543 | srv->max_fds = 4096; | |
45544 | } | |
45545 | @@ -636,7 +655,7 @@ | |
45546 | #ifdef HAVE_VALGRIND_VALGRIND_H | |
45547 | if (RUNNING_ON_VALGRIND) use_rlimit = 0; | |
45548 | #endif | |
45549 | - | |
45550 | + | |
45551 | #ifdef HAVE_GETRLIMIT | |
45552 | if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) { | |
45553 | log_error_write(srv, __FILE__, __LINE__, | |
45554 | @@ -644,13 +663,13 @@ | |
45555 | strerror(errno)); | |
45556 | return -1; | |
45557 | } | |
45558 | - | |
45559 | + | |
45560 | if (use_rlimit && srv->srvconf.max_fds) { | |
45561 | /* set rlimits */ | |
45562 | - | |
45563 | + | |
45564 | rlim.rlim_cur = srv->srvconf.max_fds; | |
45565 | rlim.rlim_max = srv->srvconf.max_fds; | |
45566 | - | |
45567 | + | |
45568 | if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) { | |
45569 | log_error_write(srv, __FILE__, __LINE__, | |
45570 | "ss", "couldn't set 'max filedescriptors'", | |
45571 | @@ -659,7 +678,7 @@ | |
45572 | } | |
45573 | } | |
f673a614 | 45574 | |
2519e6e5 ER |
45575 | - /* #372: solaris need some fds extra for devpoll */ |
45576 | + /* #372: solaris need some fds extra for devpoll */ | |
45577 | if (rlim.rlim_cur > 10) rlim.rlim_cur -= 10; | |
f673a614 | 45578 | |
2519e6e5 ER |
45579 | if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
45580 | @@ -677,33 +696,33 @@ | |
45581 | if (srv->event_handler == FDEVENT_HANDLER_SELECT) { | |
45582 | /* don't raise the limit above FD_SET_SIZE */ | |
45583 | if (srv->max_fds > FD_SETSIZE - 200) { | |
45584 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
45585 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
45586 | "can't raise max filedescriptors above", FD_SETSIZE - 200, | |
45587 | "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds."); | |
45588 | return -1; | |
45589 | } | |
45590 | } | |
f673a614 | 45591 | |
2519e6e5 ER |
45592 | - |
45593 | + | |
45594 | #ifdef HAVE_PWD_H | |
45595 | /* set user and group */ | |
45596 | if (srv->srvconf.username->used) { | |
45597 | if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) { | |
45598 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
45599 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
45600 | "can't find username", srv->srvconf.username); | |
45601 | return -1; | |
45602 | } | |
45603 | - | |
45604 | + | |
45605 | if (pwd->pw_uid == 0) { | |
45606 | log_error_write(srv, __FILE__, __LINE__, "s", | |
45607 | "I will not set uid to 0\n"); | |
45608 | return -1; | |
45609 | } | |
45610 | } | |
45611 | - | |
45612 | + | |
45613 | if (srv->srvconf.groupname->used) { | |
45614 | if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) { | |
45615 | - log_error_write(srv, __FILE__, __LINE__, "sb", | |
45616 | + log_error_write(srv, __FILE__, __LINE__, "sb", | |
45617 | "can't find groupname", srv->srvconf.groupname); | |
45618 | return -1; | |
45619 | } | |
45620 | @@ -713,15 +732,15 @@ | |
45621 | return -1; | |
45622 | } | |
45623 | } | |
45624 | -#endif | |
45625 | +#endif | |
45626 | /* we need root-perms for port < 1024 */ | |
45627 | if (0 != network_init(srv)) { | |
45628 | plugins_free(srv); | |
45629 | server_free(srv); | |
45630 | - | |
45631 | + | |
45632 | return -1; | |
45633 | } | |
45634 | -#ifdef HAVE_CHROOT | |
45635 | +#ifdef HAVE_CHROOT | |
45636 | if (srv->srvconf.changeroot->used) { | |
45637 | tzset(); | |
f673a614 | 45638 | |
2519e6e5 ER |
45639 | @@ -761,7 +780,7 @@ |
45640 | } | |
f26f9fd5 | 45641 | |
2519e6e5 ER |
45642 | if (srv->event_handler == FDEVENT_HANDLER_SELECT) { |
45643 | - srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200; | |
45644 | + srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 4 ? rlim.rlim_cur : FD_SETSIZE - 4; | |
45645 | } else { | |
45646 | srv->max_fds = rlim.rlim_cur; | |
45647 | } | |
45648 | @@ -775,18 +794,18 @@ | |
45649 | #endif | |
45650 | if (srv->event_handler == FDEVENT_HANDLER_SELECT) { | |
45651 | /* don't raise the limit above FD_SET_SIZE */ | |
45652 | - if (srv->max_fds > FD_SETSIZE - 200) { | |
45653 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
45654 | - "can't raise max filedescriptors above", FD_SETSIZE - 200, | |
45655 | + if (srv->max_fds > FD_SETSIZE - 4) { | |
45656 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
45657 | + "can't raise max filedescriptors above", FD_SETSIZE - 4, | |
45658 | "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds."); | |
45659 | return -1; | |
45660 | } | |
45661 | } | |
45662 | - | |
f673a614 | 45663 | + |
2519e6e5 ER |
45664 | if (0 != network_init(srv)) { |
45665 | plugins_free(srv); | |
45666 | server_free(srv); | |
45667 | - | |
45668 | + | |
45669 | return -1; | |
45670 | } | |
45671 | } | |
45672 | @@ -802,25 +821,27 @@ | |
45673 | /* or use the default */ | |
45674 | srv->max_conns = srv->max_fds; | |
45675 | } | |
45676 | - | |
45677 | + | |
45678 | if (HANDLER_GO_ON != plugins_call_init(srv)) { | |
45679 | log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down."); | |
45680 | - | |
45681 | + | |
45682 | plugins_free(srv); | |
45683 | network_close(srv); | |
45684 | server_free(srv); | |
45685 | - | |
45686 | + | |
45687 | return -1; | |
45688 | } | |
f673a614 | 45689 | |
2519e6e5 ER |
45690 | -#ifdef HAVE_FORK |
45691 | +#ifdef HAVE_FORK | |
45692 | /* network is up, let's deamonize ourself */ | |
45693 | if (srv->srvconf.dont_daemonize == 0) daemonize(); | |
45694 | #endif | |
f673a614 | 45695 | |
2519e6e5 ER |
45696 | +#ifdef HAVE_PWD_H |
45697 | srv->gid = getgid(); | |
45698 | srv->uid = getuid(); | |
45699 | - | |
45700 | +#endif | |
45701 | + | |
45702 | /* write pid file */ | |
45703 | if (pid_fd != -1) { | |
45704 | buffer_copy_long(srv->tmp_buf, getpid()); | |
45705 | @@ -829,17 +850,17 @@ | |
45706 | close(pid_fd); | |
45707 | pid_fd = -1; | |
45708 | } | |
45709 | - | |
45710 | + | |
45711 | if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) { | |
45712 | log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down."); | |
45713 | - | |
45714 | + | |
45715 | plugins_free(srv); | |
45716 | network_close(srv); | |
45717 | server_free(srv); | |
45718 | - | |
45719 | + | |
45720 | return -1; | |
45721 | } | |
45722 | - | |
45723 | + | |
45724 | /* dump unused config-keys */ | |
45725 | for (i = 0; i < srv->config_context->used; i++) { | |
45726 | array *config = ((data_config *)srv->config_context->data[i])->value; | |
45727 | @@ -847,43 +868,42 @@ | |
f673a614 | 45728 | |
2519e6e5 ER |
45729 | for (j = 0; config && j < config->used; j++) { |
45730 | data_unset *du = config->data[j]; | |
45731 | - | |
45732 | + | |
45733 | /* all var.* is known as user defined variable */ | |
45734 | if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) { | |
45735 | continue; | |
45736 | } | |
f673a614 | 45737 | |
2519e6e5 ER |
45738 | if (NULL == array_get_element(srv->config_touched, du->key->ptr)) { |
45739 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
45740 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
45741 | "WARNING: unknown config-key:", | |
45742 | du->key, | |
45743 | "(ignored)"); | |
45744 | } | |
45745 | } | |
45746 | } | |
45747 | - | |
45748 | + | |
45749 | if (srv->config_deprecated) { | |
45750 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
45751 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
45752 | "Configuration contains deprecated keys. Going down."); | |
45753 | - | |
45754 | + | |
45755 | plugins_free(srv); | |
45756 | network_close(srv); | |
45757 | server_free(srv); | |
45758 | - | |
45759 | + | |
45760 | return -1; | |
45761 | } | |
45762 | - | |
45763 | + | |
45764 | if (-1 == log_error_open(srv)) { | |
45765 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
45766 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
45767 | "opening errorlog failed, dying"); | |
45768 | - | |
45769 | + | |
45770 | plugins_free(srv); | |
45771 | network_close(srv); | |
45772 | server_free(srv); | |
45773 | return -1; | |
45774 | } | |
45775 | - | |
45776 | - | |
45777 | + | |
45778 | #ifdef HAVE_SIGACTION | |
45779 | memset(&act, 0, sizeof(act)); | |
45780 | act.sa_handler = SIG_IGN; | |
45781 | @@ -903,7 +923,7 @@ | |
45782 | sigaction(SIGHUP, &act, NULL); | |
45783 | sigaction(SIGALRM, &act, NULL); | |
45784 | sigaction(SIGCHLD, &act, NULL); | |
45785 | - | |
45786 | + | |
45787 | #elif defined(HAVE_SIGNAL) | |
45788 | /* ignore the SIGPIPE from sendfile() */ | |
45789 | signal(SIGPIPE, SIG_IGN); | |
45790 | @@ -914,20 +934,20 @@ | |
45791 | signal(SIGCHLD, signal_handler); | |
45792 | signal(SIGINT, signal_handler); | |
45793 | #endif | |
45794 | - | |
45795 | + | |
45796 | #ifdef USE_ALARM | |
45797 | signal(SIGALRM, signal_handler); | |
45798 | - | |
45799 | + | |
45800 | /* setup periodic timer (1 second) */ | |
45801 | if (setitimer(ITIMER_REAL, &interval, NULL)) { | |
45802 | log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed"); | |
45803 | return -1; | |
45804 | } | |
45805 | - | |
45806 | + | |
45807 | getitimer(ITIMER_REAL, &interval); | |
45808 | #endif | |
f673a614 | 45809 | |
2519e6e5 ER |
45810 | -#ifdef HAVE_FORK |
45811 | +#ifdef HAVE_FORK | |
45812 | /* start watcher and workers */ | |
45813 | num_childs = srv->srvconf.max_worker; | |
45814 | if (num_childs > 0) { | |
45815 | @@ -957,13 +977,13 @@ | |
45816 | } | |
45817 | #endif | |
f26f9fd5 | 45818 | |
2519e6e5 ER |
45819 | - if (NULL == (srv->ev = fdevent_init(srv->max_fds + 1, srv->event_handler))) { |
45820 | + if (NULL == (srv->ev = fdevent_init(/*srv->max_fds + 1*/ 4096, srv->event_handler))) { | |
45821 | log_error_write(srv, __FILE__, __LINE__, | |
45822 | "s", "fdevent_init failed"); | |
45823 | return -1; | |
45824 | } | |
45825 | - /* | |
45826 | - * kqueue() is called here, select resets its internals, | |
45827 | + /* | |
45828 | + * kqueue() is called here, select resets its internals, | |
45829 | * all server sockets get their handlers | |
45830 | * | |
45831 | * */ | |
45832 | @@ -971,7 +991,7 @@ | |
45833 | plugins_free(srv); | |
45834 | network_close(srv); | |
45835 | server_free(srv); | |
45836 | - | |
f673a614 | 45837 | + |
2519e6e5 ER |
45838 | return -1; |
45839 | } | |
f673a614 | 45840 | |
2519e6e5 ER |
45841 | @@ -986,7 +1006,7 @@ |
45842 | /* setup FAM */ | |
45843 | if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) { | |
45844 | if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) { | |
45845 | - log_error_write(srv, __FILE__, __LINE__, "s", | |
45846 | + log_error_write(srv, __FILE__, __LINE__, "s", | |
45847 | "could not open a fam connection, dieing."); | |
45848 | return -1; | |
f26f9fd5 | 45849 | } |
2519e6e5 ER |
45850 | @@ -1018,16 +1038,40 @@ |
45851 | int n; | |
45852 | size_t ndx; | |
45853 | time_t min_ts; | |
45854 | - | |
45855 | + | |
45856 | if (handle_sig_hup) { | |
45857 | handler_t r; | |
45858 | - | |
45859 | + | |
45860 | /* reset notification */ | |
45861 | handle_sig_hup = 0; | |
45862 | - | |
45863 | - | |
45864 | + | |
45865 | +#if 0 | |
45866 | + pid_t pid; | |
45867 | + | |
45868 | + /* send the old process into a graceful-shutdown and start a | |
45869 | + * new process right away | |
45870 | + * | |
45871 | + * BUGS: | |
45872 | + * - if webserver is running on port < 1024 (e.g. 80, 433) | |
45873 | + * we don't have the permissions to bind to that port anymore | |
45874 | + * | |
45875 | + * | |
45876 | + * */ | |
45877 | + if (0 == (pid = fork())) { | |
45878 | + execve(argv[0], argv, envp); | |
45879 | + | |
45880 | + exit(-1); | |
45881 | + } else if (pid == -1) { | |
45882 | + | |
45883 | + } else { | |
45884 | + /* parent */ | |
45885 | + | |
45886 | + graceful_shutdown = 1; /* shutdown without killing running connections */ | |
45887 | + graceful_restart = 1; /* don't delete pid file */ | |
45888 | + } | |
45889 | +#else | |
45890 | /* cycle logfiles */ | |
45891 | - | |
45892 | + | |
45893 | switch(r = plugins_call_handle_sighup(srv)) { | |
45894 | case HANDLER_GO_ON: | |
45895 | break; | |
45896 | @@ -1035,30 +1079,31 @@ | |
45897 | log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r); | |
45898 | break; | |
45899 | } | |
45900 | - | |
45901 | + | |
45902 | if (-1 == log_error_cycle(srv)) { | |
45903 | log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying"); | |
45904 | - | |
45905 | + | |
45906 | return -1; | |
45907 | } | |
45908 | +#endif | |
45909 | } | |
45910 | - | |
45911 | + | |
45912 | if (handle_sig_alarm) { | |
45913 | /* a new second */ | |
45914 | - | |
45915 | + | |
45916 | #ifdef USE_ALARM | |
45917 | /* reset notification */ | |
45918 | handle_sig_alarm = 0; | |
45919 | #endif | |
45920 | - | |
45921 | + | |
45922 | /* get current time */ | |
45923 | min_ts = time(NULL); | |
45924 | - | |
45925 | + | |
45926 | if (min_ts != srv->cur_ts) { | |
45927 | int cs = 0; | |
45928 | connections *conns = srv->conns; | |
45929 | handler_t r; | |
45930 | - | |
45931 | + | |
45932 | switch(r = plugins_call_handle_trigger(srv)) { | |
45933 | case HANDLER_GO_ON: | |
45934 | break; | |
45935 | @@ -1069,21 +1114,21 @@ | |
45936 | log_error_write(srv, __FILE__, __LINE__, "d", r); | |
45937 | break; | |
45938 | } | |
45939 | - | |
45940 | + | |
45941 | /* trigger waitpid */ | |
45942 | srv->cur_ts = min_ts; | |
45943 | - | |
45944 | - /* cleanup stat-cache */ | |
45945 | + | |
45946 | + /* cleanup stat-cache */ | |
45947 | stat_cache_trigger_cleanup(srv); | |
45948 | /** | |
45949 | - * check all connections for timeouts | |
45950 | - * | |
45951 | + * check all connections for timeouts | |
45952 | + * | |
45953 | */ | |
45954 | for (ndx = 0; ndx < conns->used; ndx++) { | |
45955 | int changed = 0; | |
45956 | connection *con; | |
45957 | int t_diff; | |
45958 | - | |
45959 | + | |
45960 | con = conns->ptr[ndx]; | |
45961 | ||
45962 | if (con->state == CON_STATE_READ || | |
45963 | @@ -1092,7 +1137,7 @@ | |
45964 | if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) { | |
45965 | /* time - out */ | |
45966 | #if 0 | |
45967 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
45968 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
45969 | "connection closed - read-timeout:", con->fd); | |
45970 | #endif | |
45971 | connection_set_state(srv, con, CON_STATE_ERROR); | |
45972 | @@ -1102,7 +1147,7 @@ | |
45973 | if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) { | |
45974 | /* time - out */ | |
45975 | #if 0 | |
45976 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
45977 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
45978 | "connection closed - read-timeout:", con->fd); | |
45979 | #endif | |
45980 | connection_set_state(srv, con, CON_STATE_ERROR); | |
45981 | @@ -1110,20 +1155,20 @@ | |
45982 | } | |
45983 | } | |
45984 | } | |
45985 | - | |
45986 | + | |
45987 | if ((con->state == CON_STATE_WRITE) && | |
45988 | - (con->write_request_ts != 0)) { | |
45989 | + (con->write_request_ts != 0)) { | |
45990 | #if 0 | |
45991 | if (srv->cur_ts - con->write_request_ts > 60) { | |
45992 | - log_error_write(srv, __FILE__, __LINE__, "sdd", | |
45993 | + log_error_write(srv, __FILE__, __LINE__, "sdd", | |
45994 | "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts); | |
45995 | } | |
45996 | #endif | |
45997 | - | |
45998 | + | |
45999 | if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) { | |
46000 | /* time - out */ | |
46001 | #if 1 | |
46002 | - log_error_write(srv, __FILE__, __LINE__, "sbsosds", | |
46003 | + log_error_write(srv, __FILE__, __LINE__, "sbsosds", | |
46004 | "NOTE: a request for", | |
46005 | con->request.uri, | |
46006 | "timed out after writing", | |
46007 | @@ -1138,35 +1183,35 @@ | |
46008 | } | |
46009 | /* we don't like div by zero */ | |
46010 | if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1; | |
46011 | - | |
46012 | - if (con->traffic_limit_reached && | |
46013 | - (con->conf.kbytes_per_second == 0 || | |
46014 | + | |
46015 | + if (con->traffic_limit_reached && | |
46016 | + (con->conf.kbytes_per_second == 0 || | |
46017 | ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) { | |
46018 | /* enable connection again */ | |
46019 | con->traffic_limit_reached = 0; | |
46020 | - | |
46021 | + | |
46022 | changed = 1; | |
46023 | } | |
46024 | - | |
46025 | + | |
46026 | if (changed) { | |
46027 | connection_state_machine(srv, con); | |
46028 | } | |
46029 | con->bytes_written_cur_second = 0; | |
46030 | *(con->conf.global_bytes_per_second_cnt_ptr) = 0; | |
46031 | - | |
46032 | + | |
46033 | #if 0 | |
46034 | if (cs == 0) { | |
46035 | fprintf(stderr, "connection-state: "); | |
46036 | cs = 1; | |
46037 | } | |
46038 | - | |
46039 | + | |
46040 | fprintf(stderr, "c[%d,%d]: %s ", | |
46041 | con->fd, | |
46042 | con->fcgi.fd, | |
46043 | connection_get_state(con->state)); | |
46044 | #endif | |
46045 | } | |
46046 | - | |
46047 | + | |
46048 | if (cs == 1) fprintf(stderr, "\n"); | |
46049 | } | |
f26f9fd5 | 46050 | } |
2519e6e5 ER |
46051 | @@ -1181,18 +1226,18 @@ |
46052 | server_socket *srv_socket = srv->srv_sockets.ptr[i]; | |
46053 | fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN); | |
46054 | } | |
46055 | - | |
46056 | + | |
46057 | log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again"); | |
46058 | - | |
46059 | + | |
46060 | srv->sockets_disabled = 0; | |
46061 | } | |
46062 | } else { | |
46063 | if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */ | |
46064 | (srv->conns->used > srv->max_conns) || /* out of connections */ | |
46065 | - (graceful_shutdown)) { /* graceful_shutdown */ | |
46066 | + (graceful_shutdown)) { /* graceful_shutdown */ | |
f673a614 | 46067 | |
2519e6e5 ER |
46068 | /* disable server-fds */ |
46069 | - | |
46070 | + | |
46071 | for (i = 0; i < srv->srv_sockets.used; i++) { | |
46072 | server_socket *srv_socket = srv->srv_sockets.ptr[i]; | |
46073 | fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd); | |
46074 | @@ -1211,7 +1256,7 @@ | |
46075 | /* network_close() will cleanup after us */ | |
46076 | } | |
46077 | } | |
46078 | - | |
46079 | + | |
46080 | if (graceful_shutdown) { | |
46081 | log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started"); | |
46082 | } else if (srv->conns->used > srv->max_conns) { | |
46083 | @@ -1219,7 +1264,7 @@ | |
46084 | } else { | |
46085 | log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds"); | |
46086 | } | |
46087 | - | |
46088 | + | |
46089 | srv->sockets_disabled = 1; | |
46090 | } | |
f26f9fd5 | 46091 | } |
2519e6e5 ER |
46092 | @@ -1229,16 +1274,16 @@ |
46093 | * we are ready to terminate without harming anyone */ | |
46094 | srv_shutdown = 1; | |
f673a614 | 46095 | } |
2519e6e5 | 46096 | - |
f673a614 | 46097 | + |
2519e6e5 ER |
46098 | /* we still have some fds to share */ |
46099 | - if (srv->want_fds) { | |
46100 | + if (srv->want_fds) { | |
46101 | /* check the fdwaitqueue for waiting fds */ | |
46102 | int free_fds = srv->max_fds - srv->cur_fds - 16; | |
46103 | connection *con; | |
46104 | - | |
46105 | + | |
46106 | for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) { | |
46107 | connection_state_machine(srv, con); | |
46108 | - | |
46109 | + | |
46110 | srv->want_fds--; | |
f26f9fd5 | 46111 | } |
2519e6e5 ER |
46112 | } |
46113 | @@ -1249,27 +1294,27 @@ | |
46114 | int fd_ndx; | |
46115 | #if 0 | |
46116 | if (n > 0) { | |
46117 | - log_error_write(srv, __FILE__, __LINE__, "sd", | |
46118 | + log_error_write(srv, __FILE__, __LINE__, "sd", | |
46119 | "polls:", n); | |
46120 | } | |
46121 | -#endif | |
46122 | +#endif | |
46123 | fd_ndx = -1; | |
46124 | do { | |
46125 | fdevent_handler handler; | |
46126 | void *context; | |
46127 | handler_t r; | |
46128 | - | |
46129 | + | |
46130 | fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx); | |
46131 | revents = fdevent_event_get_revent (srv->ev, fd_ndx); | |
46132 | fd = fdevent_event_get_fd (srv->ev, fd_ndx); | |
46133 | handler = fdevent_get_handler(srv->ev, fd); | |
46134 | context = fdevent_get_context(srv->ev, fd); | |
46135 | - | |
46136 | + | |
46137 | /* connection_handle_fdevent needs a joblist_append */ | |
46138 | #if 0 | |
46139 | - log_error_write(srv, __FILE__, __LINE__, "sdd", | |
46140 | + log_error_write(srv, __FILE__, __LINE__, "sdd", | |
46141 | "event for", fd, revents); | |
46142 | -#endif | |
46143 | +#endif | |
46144 | switch (r = (*handler)(srv, context, revents)) { | |
46145 | case HANDLER_FINISHED: | |
46146 | case HANDLER_GO_ON: | |
46147 | @@ -1286,17 +1331,17 @@ | |
46148 | } | |
46149 | } while (--n > 0); | |
46150 | } else if (n < 0 && errno != EINTR) { | |
46151 | - log_error_write(srv, __FILE__, __LINE__, "ss", | |
46152 | - "fdevent_poll failed:", | |
46153 | + log_error_write(srv, __FILE__, __LINE__, "ss", | |
46154 | + "fdevent_poll failed:", | |
46155 | strerror(errno)); | |
46156 | } | |
46157 | - | |
46158 | + | |
46159 | for (ndx = 0; ndx < srv->joblist->used; ndx++) { | |
46160 | connection *con = srv->joblist->ptr[ndx]; | |
46161 | handler_t r; | |
46162 | - | |
46163 | + | |
46164 | connection_state_machine(srv, con); | |
46165 | - | |
46166 | + | |
46167 | switch(r = plugins_call_handle_joblist(srv, con)) { | |
46168 | case HANDLER_FINISHED: | |
46169 | case HANDLER_GO_ON: | |
46170 | @@ -1305,32 +1350,33 @@ | |
46171 | log_error_write(srv, __FILE__, __LINE__, "d", r); | |
f26f9fd5 | 46172 | break; |
f26f9fd5 | 46173 | } |
2519e6e5 ER |
46174 | - |
46175 | + | |
46176 | con->in_joblist = 0; | |
f673a614 | 46177 | } |
2519e6e5 ER |
46178 | - |
46179 | + | |
46180 | srv->joblist->used = 0; | |
f673a614 | 46181 | } |
2519e6e5 ER |
46182 | - |
46183 | - if (srv->srvconf.pid_file->used && | |
46184 | + | |
46185 | + if (0 == graceful_restart && | |
46186 | + srv->srvconf.pid_file->used && | |
46187 | srv->srvconf.changeroot->used == 0) { | |
46188 | if (0 != unlink(srv->srvconf.pid_file->ptr)) { | |
46189 | if (errno != EACCES && errno != EPERM) { | |
46190 | - log_error_write(srv, __FILE__, __LINE__, "sbds", | |
46191 | - "unlink failed for:", | |
46192 | + log_error_write(srv, __FILE__, __LINE__, "sbds", | |
46193 | + "unlink failed for:", | |
46194 | srv->srvconf.pid_file, | |
46195 | errno, | |
46196 | strerror(errno)); | |
46197 | } | |
46198 | } | |
46199 | } | |
46200 | - | |
46201 | + | |
46202 | /* clean-up */ | |
46203 | log_error_close(srv); | |
46204 | network_close(srv); | |
46205 | connections_free(srv); | |
46206 | plugins_free(srv); | |
46207 | server_free(srv); | |
46208 | - | |
46209 | + | |
46210 | return 0; | |
46211 | } | |
1175ccec | 46212 | --- ../lighttpd-1.4.11/src/settings.h 2005-08-11 01:26:41.000000000 +0300 |
36e2a29e | 46213 | +++ lighttpd-1.4.12/src/settings.h 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
46214 | @@ -9,24 +9,24 @@ |
46215 | /** | |
46216 | * max size of a buffer which will just be reset | |
46217 | * to ->used = 0 instead of really freeing the buffer | |
46218 | - * | |
46219 | + * | |
46220 | * 64kB (no real reason, just a guess) | |
46221 | */ | |
46222 | #define BUFFER_MAX_REUSE_SIZE (4 * 1024) | |
46223 | ||
46224 | /** | |
46225 | * max size of the HTTP request header | |
46226 | - * | |
46227 | + * | |
46228 | * 32k should be enough for everything (just a guess) | |
46229 | - * | |
46230 | + * | |
46231 | */ | |
46232 | #define MAX_HTTP_REQUEST_HEADER (32 * 1024) | |
46233 | ||
46234 | -typedef enum { HANDLER_UNSET, | |
46235 | - HANDLER_GO_ON, | |
46236 | +typedef enum { HANDLER_UNSET, | |
46237 | + HANDLER_GO_ON, | |
46238 | HANDLER_FINISHED, | |
46239 | - HANDLER_COMEBACK, | |
46240 | - HANDLER_WAIT_FOR_EVENT, | |
46241 | + HANDLER_COMEBACK, | |
46242 | + HANDLER_WAIT_FOR_EVENT, | |
46243 | HANDLER_ERROR, | |
46244 | HANDLER_WAIT_FOR_FD | |
46245 | } handler_t; | |
1175ccec | 46246 | --- ../lighttpd-1.4.11/src/spawn-fcgi.c 2006-03-07 14:18:10.000000000 +0200 |
36e2a29e | 46247 | +++ lighttpd-1.4.12/src/spawn-fcgi.c 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 | 46248 | @@ -1,19 +1,16 @@ |
f26f9fd5 ER |
46249 | #include <sys/types.h> |
46250 | -#include <sys/time.h> | |
46251 | #include <sys/stat.h> | |
f673a614 | 46252 | |
2519e6e5 | 46253 | #include <stdlib.h> |
f26f9fd5 ER |
46254 | #include <string.h> |
46255 | #include <errno.h> | |
2519e6e5 | 46256 | #include <stdio.h> |
f26f9fd5 | 46257 | -#include <unistd.h> |
2519e6e5 | 46258 | #include <fcntl.h> |
f26f9fd5 | 46259 | - |
2519e6e5 ER |
46260 | +#include <time.h> |
46261 | #ifdef HAVE_CONFIG_H | |
46262 | #include "config.h" | |
f673a614 ER |
46263 | #endif |
46264 | ||
2519e6e5 ER |
46265 | - |
46266 | #ifdef HAVE_PWD_H | |
46267 | #include <grp.h> | |
46268 | #include <pwd.h> | |
46269 | @@ -30,6 +27,7 @@ | |
f673a614 | 46270 | #endif |
f673a614 | 46271 | |
2519e6e5 | 46272 | #include "sys-socket.h" |
f26f9fd5 | 46273 | +#include "sys-files.h" |
f673a614 | 46274 | |
2519e6e5 ER |
46275 | #ifdef HAVE_SYS_WAIT_H |
46276 | #include <sys/wait.h> | |
46277 | @@ -45,28 +43,28 @@ | |
46278 | int fcgi_fd; | |
46279 | int socket_type, status; | |
46280 | struct timeval tv = { 0, 100 * 1000 }; | |
46281 | - | |
46282 | + | |
46283 | struct sockaddr_un fcgi_addr_un; | |
46284 | struct sockaddr_in fcgi_addr_in; | |
46285 | struct sockaddr *fcgi_addr; | |
46286 | - | |
46287 | + | |
46288 | socklen_t servlen; | |
46289 | - | |
46290 | + | |
46291 | if (child_count < 2) { | |
46292 | child_count = 5; | |
46293 | } | |
46294 | - | |
46295 | + | |
46296 | if (child_count > 256) { | |
46297 | child_count = 256; | |
46298 | } | |
46299 | - | |
46300 | - | |
46301 | + | |
46302 | + | |
46303 | if (unixsocket) { | |
46304 | memset(&fcgi_addr, 0, sizeof(fcgi_addr)); | |
46305 | - | |
46306 | + | |
46307 | fcgi_addr_un.sun_family = AF_UNIX; | |
46308 | strcpy(fcgi_addr_un.sun_path, unixsocket); | |
46309 | - | |
46310 | + | |
46311 | #ifdef SUN_LEN | |
46312 | servlen = SUN_LEN(&fcgi_addr_un); | |
f26f9fd5 | 46313 | #else |
2519e6e5 ER |
46314 | @@ -84,50 +82,50 @@ |
46315 | } | |
46316 | fcgi_addr_in.sin_port = htons(port); | |
46317 | servlen = sizeof(fcgi_addr_in); | |
46318 | - | |
46319 | + | |
46320 | socket_type = AF_INET; | |
46321 | fcgi_addr = (struct sockaddr *) &fcgi_addr_in; | |
46322 | } | |
46323 | - | |
f673a614 | 46324 | + |
2519e6e5 ER |
46325 | if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { |
46326 | - fprintf(stderr, "%s.%d\n", | |
46327 | + fprintf(stderr, "%s.%d\n", | |
46328 | __FILE__, __LINE__); | |
46329 | return -1; | |
46330 | } | |
46331 | - | |
f26f9fd5 | 46332 | + |
2519e6e5 ER |
46333 | if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) { |
46334 | /* server is not up, spawn in */ | |
46335 | pid_t child; | |
46336 | int val; | |
46337 | - | |
46338 | + | |
46339 | if (unixsocket) unlink(unixsocket); | |
46340 | - | |
46341 | + | |
46342 | close(fcgi_fd); | |
46343 | - | |
46344 | + | |
46345 | /* reopen socket */ | |
46346 | if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { | |
46347 | - fprintf(stderr, "%s.%d\n", | |
46348 | + fprintf(stderr, "%s.%d\n", | |
46349 | __FILE__, __LINE__); | |
46350 | return -1; | |
46351 | } | |
f673a614 | 46352 | |
2519e6e5 ER |
46353 | val = 1; |
46354 | if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { | |
46355 | - fprintf(stderr, "%s.%d\n", | |
46356 | + fprintf(stderr, "%s.%d\n", | |
46357 | __FILE__, __LINE__); | |
46358 | return -1; | |
46359 | } | |
f673a614 | 46360 | |
2519e6e5 ER |
46361 | /* create socket */ |
46362 | if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) { | |
46363 | - fprintf(stderr, "%s.%d: bind failed: %s\n", | |
46364 | + fprintf(stderr, "%s.%d: bind failed: %s\n", | |
46365 | __FILE__, __LINE__, | |
46366 | strerror(errno)); | |
46367 | return -1; | |
46368 | } | |
46369 | - | |
f673a614 | 46370 | + |
2519e6e5 ER |
46371 | if (-1 == listen(fcgi_fd, 1024)) { |
46372 | - fprintf(stderr, "%s.%d: fd = -1\n", | |
46373 | + fprintf(stderr, "%s.%d: fd = -1\n", | |
46374 | __FILE__, __LINE__); | |
46375 | return -1; | |
46376 | } | |
46377 | @@ -137,42 +135,45 @@ | |
46378 | } else { | |
46379 | child = 0; | |
46380 | } | |
46381 | - | |
46382 | + | |
46383 | switch (child) { | |
46384 | case 0: { | |
46385 | char cgi_childs[64]; | |
46386 | char *b; | |
46387 | - | |
46388 | + | |
46389 | int i = 0; | |
46390 | - | |
46391 | + | |
46392 | + /* loose control terminal */ | |
46393 | + setsid(); | |
46394 | + | |
46395 | /* is save as we limit to 256 childs */ | |
46396 | sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count); | |
46397 | - | |
46398 | + | |
46399 | if(fcgi_fd != FCGI_LISTENSOCK_FILENO) { | |
46400 | close(FCGI_LISTENSOCK_FILENO); | |
46401 | dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO); | |
46402 | close(fcgi_fd); | |
46403 | } | |
46404 | - | |
46405 | + | |
46406 | /* we don't need the client socket */ | |
46407 | for (i = 3; i < 256; i++) { | |
46408 | close(i); | |
f26f9fd5 | 46409 | } |
2519e6e5 ER |
46410 | - |
46411 | + | |
46412 | /* create environment */ | |
46413 | - | |
46414 | + | |
46415 | putenv(cgi_childs); | |
46416 | - | |
46417 | + | |
46418 | /* fork and replace shell */ | |
46419 | b = malloc(strlen("exec ") + strlen(appPath) + 1); | |
46420 | strcpy(b, "exec "); | |
46421 | strcat(b, appPath); | |
46422 | - | |
46423 | + | |
46424 | /* exec the cgi */ | |
46425 | execl("/bin/sh", "sh", "-c", b, NULL); | |
46426 | - | |
46427 | + | |
46428 | exit(errno); | |
46429 | - | |
f673a614 | 46430 | + |
f26f9fd5 | 46431 | break; |
2519e6e5 ER |
46432 | } |
46433 | case -1: | |
46434 | @@ -180,47 +181,47 @@ | |
46435 | break; | |
46436 | default: | |
46437 | /* father */ | |
46438 | - | |
46439 | + | |
46440 | /* wait */ | |
46441 | select(0, NULL, NULL, NULL, &tv); | |
46442 | - | |
46443 | + | |
46444 | switch (waitpid(child, &status, WNOHANG)) { | |
46445 | case 0: | |
46446 | - fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n", | |
46447 | + fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n", | |
46448 | __FILE__, __LINE__, | |
46449 | child); | |
46450 | - | |
46451 | + | |
46452 | /* write pid file */ | |
46453 | if (pid_fd != -1) { | |
46454 | /* assume a 32bit pid_t */ | |
46455 | char pidbuf[12]; | |
46456 | - | |
46457 | + | |
46458 | snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child); | |
46459 | - | |
46460 | + | |
46461 | write(pid_fd, pidbuf, strlen(pidbuf)); | |
46462 | close(pid_fd); | |
46463 | pid_fd = -1; | |
46464 | } | |
46465 | - | |
46466 | + | |
46467 | break; | |
46468 | case -1: | |
46469 | break; | |
46470 | default: | |
46471 | if (WIFEXITED(status)) { | |
46472 | - fprintf(stderr, "%s.%d: child exited with: %d, %s\n", | |
46473 | + fprintf(stderr, "%s.%d: child exited with: %d, %s\n", | |
46474 | __FILE__, __LINE__, | |
46475 | WEXITSTATUS(status), strerror(WEXITSTATUS(status))); | |
46476 | } else if (WIFSIGNALED(status)) { | |
46477 | - fprintf(stderr, "%s.%d: child signaled: %d\n", | |
46478 | + fprintf(stderr, "%s.%d: child signaled: %d\n", | |
46479 | __FILE__, __LINE__, | |
46480 | WTERMSIG(status)); | |
46481 | } else { | |
46482 | - fprintf(stderr, "%s.%d: child died somehow: %d\n", | |
46483 | + fprintf(stderr, "%s.%d: child died somehow: %d\n", | |
46484 | __FILE__, __LINE__, | |
46485 | status); | |
46486 | } | |
f26f9fd5 | 46487 | } |
2519e6e5 ER |
46488 | - |
46489 | + | |
46490 | break; | |
f26f9fd5 | 46491 | } |
f26f9fd5 | 46492 | } else { |
2519e6e5 ER |
46493 | @@ -228,16 +229,16 @@ |
46494 | __FILE__, __LINE__); | |
46495 | return -1; | |
f26f9fd5 | 46496 | } |
2519e6e5 ER |
46497 | - |
46498 | + | |
46499 | close(fcgi_fd); | |
46500 | - | |
46501 | + | |
46502 | return 0; | |
46503 | } | |
f673a614 | 46504 | |
f673a614 | 46505 | |
2519e6e5 ER |
46506 | void show_version () { |
46507 | char *b = "spawn-fcgi" "-" PACKAGE_VERSION \ | |
46508 | -" - spawns fastcgi processes\n" | |
46509 | +" - spawns fastcgi processes\n" | |
46510 | ; | |
46511 | write(1, b, strlen(b)); | |
46512 | } | |
46513 | @@ -265,7 +266,7 @@ | |
46514 | ||
46515 | ||
46516 | int main(int argc, char **argv) { | |
46517 | - char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, | |
46518 | + char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, | |
46519 | *groupname = NULL, *unixsocket = NULL, *pid_file = NULL, | |
46520 | *addr = NULL; | |
46521 | unsigned short port = 0; | |
46522 | @@ -273,9 +274,9 @@ | |
46523 | int i_am_root, o; | |
46524 | int pid_fd = -1; | |
46525 | int nofork = 0; | |
46526 | - | |
46527 | + | |
46528 | i_am_root = (getuid() == 0); | |
46529 | - | |
46530 | + | |
46531 | while(-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:s:P:"))) { | |
46532 | switch(o) { | |
46533 | case 'f': fcgi_app = optarg; break; | |
46534 | @@ -290,137 +291,137 @@ | |
46535 | case 'P': pid_file = optarg; /* PID file */ break; | |
46536 | case 'v': show_version(); return 0; | |
46537 | case 'h': show_help(); return 0; | |
46538 | - default: | |
46539 | + default: | |
46540 | show_help(); | |
46541 | return -1; | |
46542 | } | |
46543 | } | |
46544 | - | |
46545 | + | |
46546 | if (fcgi_app == NULL || (port == 0 && unixsocket == NULL)) { | |
46547 | show_help(); | |
46548 | return -1; | |
46549 | } | |
46550 | - | |
46551 | + | |
46552 | if (unixsocket && port) { | |
46553 | - fprintf(stderr, "%s.%d: %s\n", | |
46554 | + fprintf(stderr, "%s.%d: %s\n", | |
46555 | __FILE__, __LINE__, | |
46556 | "either a unix domain socket or a tcp-port, but not both\n"); | |
46557 | - | |
46558 | + | |
f26f9fd5 ER |
46559 | return -1; |
46560 | } | |
f673a614 | 46561 | - |
2519e6e5 ER |
46562 | + |
46563 | if (unixsocket && strlen(unixsocket) > UNIX_PATH_MAX - 1) { | |
46564 | - fprintf(stderr, "%s.%d: %s\n", | |
46565 | + fprintf(stderr, "%s.%d: %s\n", | |
46566 | __FILE__, __LINE__, | |
46567 | "path of the unix socket is too long\n"); | |
46568 | - | |
46569 | + | |
46570 | return -1; | |
f26f9fd5 | 46571 | } |
f26f9fd5 | 46572 | |
2519e6e5 ER |
46573 | /* UID handling */ |
46574 | if (!i_am_root && (geteuid() == 0 || getegid() == 0)) { | |
46575 | /* we are setuid-root */ | |
46576 | - | |
46577 | - fprintf(stderr, "%s.%d: %s\n", | |
46578 | + | |
46579 | + fprintf(stderr, "%s.%d: %s\n", | |
46580 | __FILE__, __LINE__, | |
46581 | "Are you nuts ? Don't apply a SUID bit to this binary\n"); | |
46582 | - | |
46583 | + | |
f26f9fd5 | 46584 | return -1; |
2519e6e5 ER |
46585 | } |
46586 | - | |
46587 | - if (pid_file && | |
46588 | + | |
46589 | + if (pid_file && | |
46590 | (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) { | |
46591 | struct stat st; | |
46592 | if (errno != EEXIST) { | |
46593 | - fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", | |
46594 | + fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", | |
46595 | __FILE__, __LINE__, | |
46596 | pid_file, strerror(errno)); | |
46597 | - | |
f673a614 | 46598 | + |
2519e6e5 ER |
46599 | return -1; |
46600 | } | |
46601 | - | |
f673a614 | 46602 | + |
2519e6e5 ER |
46603 | /* ok, file exists */ |
46604 | - | |
46605 | + | |
46606 | if (0 != stat(pid_file, &st)) { | |
46607 | - fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n", | |
46608 | + fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n", | |
46609 | __FILE__, __LINE__, | |
46610 | pid_file, strerror(errno)); | |
46611 | - | |
46612 | + | |
46613 | return -1; | |
46614 | } | |
46615 | - | |
46616 | + | |
46617 | /* is it a regular file ? */ | |
46618 | - | |
46619 | + | |
46620 | if (!S_ISREG(st.st_mode)) { | |
46621 | - fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n", | |
46622 | + fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n", | |
46623 | __FILE__, __LINE__, | |
46624 | pid_file); | |
46625 | - | |
46626 | + | |
46627 | return -1; | |
46628 | } | |
46629 | - | |
46630 | + | |
46631 | if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { | |
46632 | - fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", | |
46633 | + fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", | |
46634 | __FILE__, __LINE__, | |
46635 | pid_file, strerror(errno)); | |
46636 | - | |
46637 | + | |
46638 | return -1; | |
46639 | } | |
46640 | } | |
46641 | - | |
46642 | + | |
46643 | if (i_am_root) { | |
46644 | struct group *grp = NULL; | |
46645 | struct passwd *pwd = NULL; | |
46646 | - | |
46647 | + | |
46648 | /* set user and group */ | |
46649 | - | |
46650 | + | |
46651 | if (username) { | |
46652 | if (NULL == (pwd = getpwnam(username))) { | |
46653 | - fprintf(stderr, "%s.%d: %s, %s\n", | |
46654 | + fprintf(stderr, "%s.%d: %s, %s\n", | |
46655 | __FILE__, __LINE__, | |
46656 | "can't find username", username); | |
46657 | return -1; | |
46658 | } | |
46659 | - | |
46660 | + | |
46661 | if (pwd->pw_uid == 0) { | |
46662 | - fprintf(stderr, "%s.%d: %s\n", | |
46663 | + fprintf(stderr, "%s.%d: %s\n", | |
46664 | __FILE__, __LINE__, | |
46665 | "I will not set uid to 0\n"); | |
46666 | return -1; | |
46667 | } | |
46668 | } | |
46669 | - | |
46670 | + | |
46671 | if (groupname) { | |
46672 | if (NULL == (grp = getgrnam(groupname))) { | |
46673 | - fprintf(stderr, "%s.%d: %s %s\n", | |
46674 | + fprintf(stderr, "%s.%d: %s %s\n", | |
46675 | __FILE__, __LINE__, | |
46676 | - "can't find groupname", | |
46677 | + "can't find groupname", | |
46678 | groupname); | |
46679 | return -1; | |
46680 | } | |
46681 | if (grp->gr_gid == 0) { | |
46682 | - fprintf(stderr, "%s.%d: %s\n", | |
46683 | + fprintf(stderr, "%s.%d: %s\n", | |
46684 | __FILE__, __LINE__, | |
46685 | "I will not set gid to 0\n"); | |
46686 | return -1; | |
46687 | } | |
46688 | } | |
46689 | - | |
f673a614 | 46690 | + |
2519e6e5 ER |
46691 | if (changeroot) { |
46692 | if (-1 == chroot(changeroot)) { | |
46693 | - fprintf(stderr, "%s.%d: %s %s\n", | |
46694 | + fprintf(stderr, "%s.%d: %s %s\n", | |
46695 | __FILE__, __LINE__, | |
46696 | "chroot failed: ", strerror(errno)); | |
46697 | return -1; | |
46698 | } | |
46699 | if (-1 == chdir("/")) { | |
46700 | - fprintf(stderr, "%s.%d: %s %s\n", | |
46701 | + fprintf(stderr, "%s.%d: %s %s\n", | |
46702 | __FILE__, __LINE__, | |
46703 | "chdir failed: ", strerror(errno)); | |
f26f9fd5 ER |
46704 | return -1; |
46705 | } | |
f26f9fd5 | 46706 | } |
2519e6e5 ER |
46707 | - |
46708 | + | |
46709 | /* drop root privs */ | |
46710 | if (groupname) { | |
46711 | setgid(grp->gr_gid); | |
46712 | @@ -428,7 +429,7 @@ | |
46713 | } | |
46714 | if (username) setuid(pwd->pw_uid); | |
f26f9fd5 | 46715 | } |
2519e6e5 ER |
46716 | - |
46717 | + | |
46718 | return fcgi_spawn_connection(fcgi_app, addr, port, unixsocket, child_count, pid_fd, nofork); | |
46719 | } | |
46720 | #else | |
1175ccec | 46721 | --- ../lighttpd-1.4.11/src/splaytree.c 2005-09-12 21:51:28.000000000 +0300 |
36e2a29e | 46722 | +++ lighttpd-1.4.12/src/splaytree.c 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
46723 | @@ -56,19 +56,19 @@ |
46724 | ||
46725 | #define node_size splaytree_size | |
46726 | ||
46727 | -/* Splay using the key i (which may or may not be in the tree.) | |
46728 | - * The starting root is t, and the tree used is defined by rat | |
46729 | +/* Splay using the key i (which may or may not be in the tree.) | |
46730 | + * The starting root is t, and the tree used is defined by rat | |
46731 | * size fields are maintained */ | |
46732 | splay_tree * splaytree_splay (splay_tree *t, int i) { | |
46733 | splay_tree N, *l, *r, *y; | |
46734 | int comp, root_size, l_size, r_size; | |
46735 | - | |
46736 | + | |
46737 | if (t == NULL) return t; | |
46738 | N.left = N.right = NULL; | |
46739 | l = r = &N; | |
46740 | root_size = node_size(t); | |
46741 | l_size = r_size = 0; | |
46742 | - | |
46743 | + | |
46744 | for (;;) { | |
46745 | comp = compare(i, t->key); | |
46746 | if (comp < 0) { | |
46747 | @@ -120,7 +120,7 @@ | |
46748 | y->size = r_size; | |
46749 | r_size -= 1+node_size(y->right); | |
46750 | } | |
46751 | - | |
46752 | + | |
46753 | l->right = t->left; /* assemble */ | |
46754 | r->left = t->right; | |
46755 | t->left = N.right; | |
1175ccec | 46756 | --- ../lighttpd-1.4.11/src/splaytree.h 2005-09-12 21:51:13.000000000 +0300 |
36e2a29e | 46757 | +++ lighttpd-1.4.12/src/splaytree.h 2006-07-11 22:07:51.000000000 +0300 |
2519e6e5 ER |
46758 | @@ -19,6 +19,6 @@ |
46759 | /* This macro returns the size of a node. Unlike "x->size", */ | |
46760 | /* it works even if x=NULL. The test could be avoided by using */ | |
46761 | /* a special version of NULL which was a real node with size 0. */ | |
46762 | - | |
46763 | + | |
f673a614 | 46764 | |
f26f9fd5 | 46765 | #endif |
1175ccec ER |
46766 | --- ../lighttpd-1.4.11/src/stat_cache.c 2005-11-22 15:23:51.000000000 +0200 |
46767 | +++ lighttpd-1.4.12/src/stat_cache.c 2006-07-15 22:43:21.000000000 +0300 | |
f26f9fd5 ER |
46768 | @@ -6,7 +6,6 @@ |
46769 | #include <stdlib.h> | |
46770 | #include <string.h> | |
46771 | #include <errno.h> | |
46772 | -#include <unistd.h> | |
46773 | #include <stdio.h> | |
46774 | #include <fcntl.h> | |
46775 | #include <assert.h> | |
46776 | @@ -25,19 +24,8 @@ | |
46777 | #endif | |
f673a614 | 46778 | |
f26f9fd5 ER |
46779 | #include "sys-mmap.h" |
46780 | - | |
46781 | -/* NetBSD 1.3.x needs it */ | |
46782 | -#ifndef MAP_FAILED | |
46783 | -# define MAP_FAILED -1 | |
46784 | -#endif | |
46785 | - | |
46786 | -#ifndef O_LARGEFILE | |
46787 | -# define O_LARGEFILE 0 | |
46788 | -#endif | |
46789 | - | |
46790 | -#ifndef HAVE_LSTAT | |
46791 | -#define lstat stat | |
46792 | -#endif | |
46793 | +#include "sys-files.h" | |
46794 | +#include "sys-strings.h" | |
f673a614 | 46795 | |
2519e6e5 ER |
46796 | #if 0 |
46797 | /* enables debug code for testing if all nodes in the stat-cache as accessable */ | |
46798 | @@ -52,8 +40,8 @@ | |
46799 | * | |
46800 | * if we get a change-event from FAM, we increment the version in the FAM->dir mapping | |
46801 | * | |
46802 | - * if the stat()-cache is queried we check if the version id for the directory is the | |
46803 | - * same and return immediatly. | |
46804 | + * if the stat()-cache is queried we check if the version id for the directory is the | |
46805 | + * same and return immediatly. | |
46806 | * | |
46807 | * | |
46808 | * What we need: | |
46809 | @@ -62,17 +50,17 @@ | |
46810 | * - for each FAMRequest we have to find the version in the directory cache (index as userdata) | |
46811 | * | |
46812 | * stat <<-> directory <-> FAMRequest | |
46813 | - * | |
46814 | - * if file is deleted, directory is dirty, file is rechecked ... | |
46815 | + * | |
46816 | + * if file is deleted, directory is dirty, file is rechecked ... | |
46817 | * if directory is deleted, directory mapping is removed | |
46818 | - * | |
46819 | + * | |
46820 | * */ | |
46821 | ||
46822 | #ifdef HAVE_FAM_H | |
46823 | typedef struct { | |
46824 | FAMRequest *req; | |
46825 | FAMConnection *fc; | |
46826 | - | |
46827 | + | |
46828 | buffer *name; | |
46829 | ||
46830 | int version; | |
46831 | @@ -83,16 +71,16 @@ | |
46832 | * - we need a hash | |
46833 | * - the hash-key is used as sorting criteria for a tree | |
46834 | * - a splay-tree is used as we can use the caching effect of it | |
46835 | - */ | |
46836 | + */ | |
46837 | ||
46838 | /* we want to cleanup the stat-cache every few seconds, let's say 10 | |
46839 | * | |
46840 | * - remove entries which are outdated since 30s | |
46841 | * - remove entries which are fresh but havn't been used since 60s | |
46842 | * - if we don't have a stat-cache entry for a directory, release it from the monitor | |
46843 | - */ | |
46844 | + */ | |
46845 | ||
46846 | -#ifdef DEBUG_STAT_CACHE | |
46847 | +#ifdef DEBUG_STAT_CACHE | |
46848 | typedef struct { | |
46849 | int *ptr; | |
46850 | ||
46851 | @@ -105,15 +93,15 @@ | |
46852 | ||
46853 | stat_cache *stat_cache_init(void) { | |
46854 | stat_cache *fc = NULL; | |
46855 | - | |
46856 | + | |
46857 | fc = calloc(1, sizeof(*fc)); | |
46858 | - | |
46859 | + | |
46860 | fc->dir_name = buffer_init(); | |
46861 | #ifdef HAVE_FAM_H | |
46862 | fc->fam = calloc(1, sizeof(*fc->fam)); | |
46863 | #endif | |
46864 | ||
46865 | -#ifdef DEBUG_STAT_CACHE | |
46866 | +#ifdef DEBUG_STAT_CACHE | |
46867 | ctrl.size = 0; | |
46868 | #endif | |
46869 | ||
46870 | @@ -122,24 +110,24 @@ | |
46871 | ||
46872 | static stat_cache_entry * stat_cache_entry_init(void) { | |
46873 | stat_cache_entry *sce = NULL; | |
46874 | - | |
46875 | + | |
46876 | sce = calloc(1, sizeof(*sce)); | |
46877 | - | |
46878 | + | |
46879 | sce->name = buffer_init(); | |
46880 | sce->etag = buffer_init(); | |
46881 | sce->content_type = buffer_init(); | |
46882 | - | |
46883 | + | |
46884 | return sce; | |
46885 | } | |
46886 | ||
46887 | static void stat_cache_entry_free(void *data) { | |
46888 | stat_cache_entry *sce = data; | |
46889 | if (!sce) return; | |
46890 | - | |
46891 | + | |
46892 | buffer_free(sce->etag); | |
46893 | buffer_free(sce->name); | |
46894 | buffer_free(sce->content_type); | |
46895 | - | |
46896 | + | |
46897 | free(sce); | |
46898 | } | |
46899 | ||
46900 | @@ -148,22 +136,22 @@ | |
46901 | fam_dir_entry *fam_dir = NULL; | |
46902 | ||
46903 | fam_dir = calloc(1, sizeof(*fam_dir)); | |
46904 | - | |
46905 | + | |
46906 | fam_dir->name = buffer_init(); | |
46907 | - | |
46908 | + | |
46909 | return fam_dir; | |
46910 | } | |
46911 | ||
46912 | static void fam_dir_entry_free(void *data) { | |
46913 | fam_dir_entry *fam_dir = data; | |
46914 | - | |
46915 | + | |
46916 | if (!fam_dir) return; | |
46917 | - | |
46918 | + | |
46919 | FAMCancelMonitor(fam_dir->fc, fam_dir->req); | |
46920 | - | |
46921 | + | |
46922 | buffer_free(fam_dir->name); | |
46923 | free(fam_dir->req); | |
46924 | - | |
46925 | + | |
46926 | free(fam_dir); | |
46927 | } | |
46928 | #endif | |
46929 | @@ -174,7 +162,7 @@ | |
46930 | splay_tree *node = sc->files; | |
46931 | ||
46932 | osize = sc->files->size; | |
46933 | - | |
46934 | + | |
46935 | stat_cache_entry_free(node->data); | |
46936 | sc->files = splaytree_delete(sc->files, node->key); | |
46937 | ||
46938 | @@ -187,12 +175,12 @@ | |
46939 | while (sc->dirs) { | |
46940 | int osize; | |
46941 | splay_tree *node = sc->dirs; | |
46942 | - | |
46943 | + | |
46944 | osize = sc->dirs->size; | |
46945 | ||
46946 | fam_dir_entry_free(node->data); | |
46947 | sc->dirs = splaytree_delete(sc->dirs, node->key); | |
46948 | - | |
46949 | + | |
46950 | if (osize == 1) { | |
46951 | assert(NULL == sc->dirs); | |
46952 | } else { | |
46953 | @@ -212,7 +200,7 @@ | |
46954 | static int stat_cache_attr_get(buffer *buf, char *name) { | |
46955 | int attrlen; | |
46956 | int ret; | |
46957 | - | |
46958 | + | |
46959 | attrlen = 1024; | |
46960 | buffer_prepare_copy(buf, attrlen); | |
46961 | attrlen--; | |
46962 | @@ -251,15 +239,15 @@ | |
46963 | sc->fam) { | |
46964 | ||
46965 | events = FAMPending(sc->fam); | |
46966 | - | |
46967 | + | |
46968 | for (i = 0; i < events; i++) { | |
46969 | FAMEvent fe; | |
46970 | fam_dir_entry *fam_dir; | |
46971 | splay_tree *node; | |
46972 | int ndx; | |
46973 | - | |
46974 | + | |
46975 | FAMNextEvent(sc->fam, &fe); | |
46976 | - | |
46977 | + | |
46978 | /* handle event */ | |
46979 | ||
46980 | switch(fe.code) { | |
46981 | @@ -280,7 +268,7 @@ | |
46982 | ||
46983 | sc->dirs = splaytree_splay(sc->dirs, ndx); | |
46984 | node = sc->dirs; | |
46985 | - | |
46986 | + | |
46987 | if (node && (node->key == ndx)) { | |
46988 | int osize = splaytree_size(sc->dirs); | |
46989 | ||
46990 | @@ -308,7 +296,7 @@ | |
46991 | ||
46992 | sc->fam = NULL; | |
46993 | } | |
46994 | - | |
46995 | + | |
46996 | return HANDLER_GO_ON; | |
46997 | } | |
46998 | ||
46999 | @@ -332,7 +320,7 @@ | |
47000 | * | |
47001 | * | |
47002 | * | |
47003 | - * returns: | |
47004 | + * returns: | |
47005 | * - HANDLER_FINISHED on cache-miss (don't forget to reopen the file) | |
47006 | * - HANDLER_ERROR on stat() failed -> see errno for problem | |
47007 | */ | |
47008 | @@ -348,16 +336,16 @@ | |
47009 | struct stat st; | |
47010 | size_t k; | |
47011 | int fd; | |
47012 | -#ifdef DEBUG_STAT_CACHE | |
47013 | +#ifdef DEBUG_STAT_CACHE | |
47014 | size_t i; | |
47015 | #endif | |
47016 | ||
47017 | int file_ndx; | |
47018 | splay_tree *file_node = NULL; | |
47019 | ||
47020 | - *ret_sce = NULL; | |
47021 | + *ret_sce = NULL; | |
47022 | ||
47023 | - /* | |
47024 | + /* | |
47025 | * check if the directory for this file has changed | |
47026 | */ | |
47027 | ||
47028 | @@ -366,23 +354,23 @@ | |
47029 | file_ndx = hashme(name); | |
47030 | sc->files = splaytree_splay(sc->files, file_ndx); | |
47031 | ||
47032 | -#ifdef DEBUG_STAT_CACHE | |
47033 | +#ifdef DEBUG_STAT_CACHE | |
47034 | for (i = 0; i < ctrl.used; i++) { | |
47035 | if (ctrl.ptr[i] == file_ndx) break; | |
47036 | } | |
47037 | #endif | |
47038 | ||
47039 | if (sc->files && (sc->files->key == file_ndx)) { | |
47040 | -#ifdef DEBUG_STAT_CACHE | |
47041 | +#ifdef DEBUG_STAT_CACHE | |
47042 | /* it was in the cache */ | |
47043 | assert(i < ctrl.used); | |
47044 | #endif | |
47045 | - | |
47046 | - /* we have seen this file already and | |
47047 | + | |
47048 | + /* we have seen this file already and | |
47049 | * don't stat() it again in the same second */ | |
47050 | ||
47051 | file_node = sc->files; | |
47052 | - | |
47053 | + | |
47054 | sce = file_node->data; | |
47055 | ||
47056 | /* check if the name is the same, we might have a collision */ | |
47057 | @@ -390,7 +378,7 @@ | |
47058 | if (buffer_is_equal(name, sce->name)) { | |
47059 | if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_SIMPLE) { | |
47060 | if (sce->stat_ts == srv->cur_ts) { | |
47061 | - *ret_sce = sce; | |
47062 | + *ret_sce = sce; | |
47063 | return HANDLER_GO_ON; | |
47064 | } | |
47065 | } | |
47066 | @@ -400,15 +388,15 @@ | |
47067 | * file_node is used by the FAM check below to see if we know this file | |
47068 | * and if we can save a stat(). | |
47069 | * | |
47070 | - * BUT, the sce is not reset here as the entry into the cache is ok, we | |
47071 | + * BUT, the sce is not reset here as the entry into the cache is ok, we | |
47072 | * it is just not pointing to our requested file. | |
47073 | - * | |
47074 | + * | |
47075 | * */ | |
47076 | ||
47077 | file_node = NULL; | |
47078 | } | |
47079 | } else { | |
47080 | -#ifdef DEBUG_STAT_CACHE | |
47081 | +#ifdef DEBUG_STAT_CACHE | |
47082 | if (i != ctrl.used) { | |
47083 | fprintf(stderr, "%s.%d: %08x was already inserted but not found in cache, %s\n", __FILE__, __LINE__, file_ndx, name->ptr); | |
47084 | } | |
47085 | @@ -424,23 +412,23 @@ | |
47086 | } | |
47087 | ||
47088 | dir_ndx = hashme(sc->dir_name); | |
47089 | - | |
47090 | + | |
47091 | sc->dirs = splaytree_splay(sc->dirs, dir_ndx); | |
47092 | - | |
47093 | + | |
47094 | if (sc->dirs && (sc->dirs->key == dir_ndx)) { | |
47095 | dir_node = sc->dirs; | |
47096 | } | |
47097 | - | |
47098 | + | |
47099 | if (dir_node && file_node) { | |
47100 | /* we found a file */ | |
47101 | - | |
47102 | + | |
47103 | sce = file_node->data; | |
47104 | fam_dir = dir_node->data; | |
47105 | - | |
47106 | + | |
47107 | if (fam_dir->version == sce->dir_version) { | |
47108 | /* the stat()-cache entry is still ok */ | |
47109 | - | |
47110 | - *ret_sce = sce; | |
47111 | + | |
47112 | + *ret_sce = sce; | |
47113 | return HANDLER_GO_ON; | |
47114 | } | |
47115 | } | |
47116 | @@ -448,7 +436,7 @@ | |
47117 | #endif | |
47118 | ||
47119 | /* | |
47120 | - * *lol* | |
47121 | + * *lol* | |
47122 | * - open() + fstat() on a named-pipe results in a (intended) hang. | |
47123 | * - stat() if regualar file + open() to see if we can read from it is better | |
47124 | * | |
47125 | @@ -469,16 +457,16 @@ | |
47126 | ||
47127 | if (NULL == sce) { | |
47128 | int osize = 0; | |
47129 | - | |
47130 | + | |
47131 | if (sc->files) { | |
47132 | osize = sc->files->size; | |
47133 | } | |
47134 | ||
47135 | sce = stat_cache_entry_init(); | |
47136 | buffer_copy_string_buffer(sce->name, name); | |
47137 | - | |
47138 | - sc->files = splaytree_insert(sc->files, file_ndx, sce); | |
47139 | -#ifdef DEBUG_STAT_CACHE | |
47140 | + | |
47141 | + sc->files = splaytree_insert(sc->files, file_ndx, sce); | |
47142 | +#ifdef DEBUG_STAT_CACHE | |
47143 | if (ctrl.size == 0) { | |
47144 | ctrl.size = 16; | |
47145 | ctrl.used = 0; | |
47146 | @@ -499,29 +487,29 @@ | |
47147 | sce->st = st; | |
47148 | sce->stat_ts = srv->cur_ts; | |
47149 | ||
47150 | - /* catch the obvious symlinks | |
47151 | + /* catch the obvious symlinks | |
47152 | * | |
47153 | * this is not a secure check as we still have a race-condition between | |
47154 | - * the stat() and the open. We can only solve this by | |
47155 | + * the stat() and the open. We can only solve this by | |
47156 | * 1. open() the file | |
47157 | * 2. fstat() the fd | |
47158 | * | |
47159 | * and keeping the file open for the rest of the time. But this can | |
47160 | * only be done at network level. | |
47161 | - * | |
47162 | + * | |
47163 | * */ | |
47164 | if (S_ISLNK(st.st_mode) && !con->conf.follow_symlink) { | |
47165 | return HANDLER_ERROR; | |
47166 | } | |
47167 | ||
47168 | - if (S_ISREG(st.st_mode)) { | |
47169 | + if (S_ISREG(st.st_mode)) { | |
47170 | /* determine mimetype */ | |
47171 | buffer_reset(sce->content_type); | |
47172 | - | |
47173 | + | |
47174 | for (k = 0; k < con->conf.mimetypes->used; k++) { | |
47175 | data_string *ds = (data_string *)con->conf.mimetypes->data[k]; | |
47176 | buffer *type = ds->key; | |
47177 | - | |
47178 | + | |
47179 | if (type->used == 0) continue; | |
47180 | ||
47181 | /* check if the right side is the same */ | |
1175ccec ER |
47182 | @@ -538,8 +526,10 @@ |
47183 | stat_cache_attr_get(sce->content_type, name->ptr); | |
2519e6e5 ER |
47184 | } |
47185 | #endif | |
1175ccec ER |
47186 | + } else if (S_ISDIR(st.st_mode)) { |
47187 | + etag_create(sce->etag, &(sce->st)); | |
2519e6e5 ER |
47188 | } |
47189 | - | |
47190 | + | |
47191 | #ifdef HAVE_FAM_H | |
47192 | if (sc->fam && | |
47193 | (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) { | |
1175ccec | 47194 | @@ -549,19 +539,19 @@ |
2519e6e5 ER |
47195 | fam_dir->fc = sc->fam; |
47196 | ||
47197 | buffer_copy_string_buffer(fam_dir->name, sc->dir_name); | |
47198 | - | |
47199 | + | |
47200 | fam_dir->version = 1; | |
47201 | - | |
47202 | + | |
47203 | fam_dir->req = calloc(1, sizeof(FAMRequest)); | |
47204 | - | |
47205 | - if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr, | |
47206 | + | |
47207 | + if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr, | |
47208 | fam_dir->req, fam_dir)) { | |
47209 | - | |
47210 | - log_error_write(srv, __FILE__, __LINE__, "sbs", | |
47211 | - "monitoring dir failed:", | |
47212 | - fam_dir->name, | |
47213 | + | |
47214 | + log_error_write(srv, __FILE__, __LINE__, "sbs", | |
47215 | + "monitoring dir failed:", | |
47216 | + fam_dir->name, | |
47217 | FamErrlist[FAMErrno]); | |
47218 | - | |
47219 | + | |
47220 | fam_dir_entry_free(fam_dir); | |
47221 | } else { | |
47222 | int osize = 0; | |
1175ccec | 47223 | @@ -570,7 +560,7 @@ |
2519e6e5 ER |
47224 | osize = sc->dirs->size; |
47225 | } | |
47226 | ||
47227 | - sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir); | |
47228 | + sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir); | |
47229 | assert(sc->dirs); | |
47230 | assert(sc->dirs->data == fam_dir); | |
47231 | assert(osize == (sc->dirs->size - 1)); | |
1175ccec | 47232 | @@ -578,9 +568,9 @@ |
2519e6e5 ER |
47233 | } else { |
47234 | fam_dir = dir_node->data; | |
47235 | } | |
47236 | - | |
47237 | + | |
47238 | /* bind the fam_fc to the stat() cache entry */ | |
47239 | - | |
47240 | + | |
47241 | if (fam_dir) { | |
47242 | sce->dir_version = fam_dir->version; | |
47243 | sce->dir_ndx = dir_ndx; | |
1175ccec | 47244 | @@ -594,11 +584,11 @@ |
2519e6e5 ER |
47245 | } |
47246 | ||
47247 | /** | |
47248 | - * remove stat() from cache which havn't been stat()ed for | |
47249 | + * remove stat() from cache which havn't been stat()ed for | |
47250 | * more than 10 seconds | |
47251 | - * | |
47252 | * | |
47253 | - * walk though the stat-cache, collect the ids which are too old | |
47254 | + * | |
47255 | + * walk though the stat-cache, collect the ids which are too old | |
47256 | * and remove them in a second loop | |
47257 | */ | |
47258 | ||
1175ccec | 47259 | @@ -639,9 +629,9 @@ |
2519e6e5 ER |
47260 | sc->files = splaytree_splay(sc->files, ndx); |
47261 | ||
47262 | node = sc->files; | |
47263 | - | |
47264 | + | |
47265 | if (node && (node->key == ndx)) { | |
47266 | -#ifdef DEBUG_STAT_CACHE | |
47267 | +#ifdef DEBUG_STAT_CACHE | |
47268 | size_t j; | |
47269 | int osize = splaytree_size(sc->files); | |
47270 | stat_cache_entry *sce = node->data; | |
1175ccec | 47271 | @@ -649,7 +639,7 @@ |
2519e6e5 ER |
47272 | stat_cache_entry_free(node->data); |
47273 | sc->files = splaytree_delete(sc->files, ndx); | |
47274 | ||
47275 | -#ifdef DEBUG_STAT_CACHE | |
47276 | +#ifdef DEBUG_STAT_CACHE | |
47277 | for (j = 0; j < ctrl.used; j++) { | |
47278 | if (ctrl.ptr[j] == ndx) { | |
47279 | ctrl.ptr[j] = ctrl.ptr[--ctrl.used]; | |
1175ccec | 47280 | --- ../lighttpd-1.4.11/src/stream.c 2005-09-23 21:50:15.000000000 +0300 |
36e2a29e | 47281 | +++ lighttpd-1.4.12/src/stream.c 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 ER |
47282 | @@ -1,7 +1,6 @@ |
47283 | #include <sys/types.h> | |
47284 | #include <sys/stat.h> | |
f673a614 | 47285 | |
f26f9fd5 ER |
47286 | -#include <unistd.h> |
47287 | #include <fcntl.h> | |
47288 | ||
47289 | #include "stream.h" | |
47290 | @@ -10,6 +9,7 @@ | |
f673a614 | 47291 | #endif |
f26f9fd5 ER |
47292 | |
47293 | #include "sys-mmap.h" | |
47294 | +#include "sys-files.h" | |
47295 | ||
47296 | #ifndef O_BINARY | |
47297 | # define O_BINARY 0 | |
2519e6e5 | 47298 | @@ -19,39 +19,39 @@ |
f26f9fd5 ER |
47299 | struct stat st; |
47300 | #ifdef HAVE_MMAP | |
47301 | int fd; | |
47302 | -#elif defined __WIN32 | |
f673a614 | 47303 | +#elif defined _WIN32 |
f26f9fd5 ER |
47304 | HANDLE *fh, *mh; |
47305 | void *p; | |
f673a614 | 47306 | #endif |
2519e6e5 ER |
47307 | |
47308 | f->start = NULL; | |
47309 | - | |
47310 | + | |
47311 | if (-1 == stat(fn->ptr, &st)) { | |
47312 | return -1; | |
47313 | } | |
47314 | - | |
47315 | + | |
47316 | f->size = st.st_size; | |
47317 | ||
47318 | #ifdef HAVE_MMAP | |
47319 | if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY))) { | |
47320 | return -1; | |
47321 | } | |
47322 | - | |
47323 | + | |
47324 | f->start = mmap(0, f->size, PROT_READ, MAP_SHARED, fd, 0); | |
47325 | - | |
47326 | + | |
47327 | close(fd); | |
47328 | - | |
47329 | + | |
47330 | if (MAP_FAILED == f->start) { | |
f26f9fd5 ER |
47331 | return -1; |
47332 | } | |
f673a614 | 47333 | |
f26f9fd5 | 47334 | -#elif defined __WIN32 |
2519e6e5 ER |
47335 | - fh = CreateFile(fn->ptr, |
47336 | - GENERIC_READ, | |
47337 | - FILE_SHARE_READ, | |
47338 | - NULL, | |
47339 | - OPEN_EXISTING, | |
47340 | - FILE_ATTRIBUTE_READONLY, | |
f26f9fd5 | 47341 | +#elif defined _WIN32 |
2519e6e5 ER |
47342 | + fh = CreateFile(fn->ptr, |
47343 | + GENERIC_READ, | |
47344 | + FILE_SHARE_READ, | |
47345 | + NULL, | |
47346 | + OPEN_EXISTING, | |
47347 | + FILE_ATTRIBUTE_READONLY, | |
47348 | NULL); | |
47349 | ||
47350 | if (!fh) return -1; | |
47351 | @@ -66,7 +66,7 @@ | |
47352 | if (!mh) { | |
47353 | LPVOID lpMsgBuf; | |
47354 | FormatMessage( | |
47355 | - FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
47356 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
47357 | FORMAT_MESSAGE_FROM_SYSTEM, | |
47358 | NULL, | |
47359 | GetLastError(), | |
47360 | @@ -76,7 +76,7 @@ | |
47361 | ||
47362 | return -1; | |
47363 | } | |
47364 | - | |
47365 | + | |
47366 | p = MapViewOfFile(mh, | |
47367 | FILE_MAP_READ, | |
47368 | 0, | |
47369 | @@ -87,9 +87,9 @@ | |
47370 | ||
47371 | f->start = p; | |
47372 | #else | |
47373 | -# error no mmap found | |
47374 | +# error no mmap found | |
47375 | #endif | |
47376 | - | |
47377 | + | |
47378 | return 0; | |
47379 | } | |
47380 | ||
1175ccec | 47381 | --- ../lighttpd-1.4.11/src/sys-files.h 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e ER |
47382 | +++ lighttpd-1.4.12/src/sys-files.h 2006-07-11 22:07:53.000000000 +0300 |
47383 | @@ -0,0 +1,67 @@ | |
47384 | +#ifndef _SYS_FILES_H_ | |
47385 | +#define _SYS_FILES_H_ | |
47386 | + | |
47387 | +#define DIR_SEPERATOR_UNIX '/' | |
47388 | +#define DIR_SEPERATOR_WIN '\\' | |
47389 | + | |
47390 | +#ifdef _WIN32 | |
47391 | +#include <windows.h> | |
47392 | +#include <io.h> /* open */ | |
47393 | +#include <direct.h> /* chdir */ | |
47394 | + | |
47395 | +#include "buffer.h" | |
47396 | + | |
47397 | +#define DIR_SEPERATOR DIR_SEPERATOR_WIN | |
47398 | + | |
47399 | +#define __S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask)) | |
47400 | + | |
47401 | +#define S_ISDIR(mode) __S_ISTYPE((mode), _S_IFDIR) | |
47402 | +#define S_ISCHR(mode) __S_ISTYPE((mode), _S_IFCHR) | |
47403 | +#define S_ISBLK(mode) __S_ISTYPE((mode), _S_IFBLK) | |
47404 | +#define S_ISREG(mode) __S_ISTYPE((mode), _S_IFREG) | |
47405 | +/* we don't support symlinks */ | |
47406 | +#define S_ISLNK(mode) 0 | |
47407 | + | |
47408 | +#define lstat stat | |
47409 | +#define mkstemp mktemp | |
47410 | +#define mkdir(x, y) mkdir(x) | |
47411 | + | |
47412 | +struct dirent { | |
47413 | + const char *d_name; | |
47414 | +}; | |
47415 | + | |
47416 | +typedef struct { | |
47417 | + HANDLE h; | |
47418 | + WIN32_FIND_DATA finddata; | |
47419 | + struct dirent dent; | |
47420 | +} DIR; | |
47421 | + | |
47422 | +DIR *opendir(const char *dn); | |
47423 | +struct dirent *readdir(DIR *d); | |
47424 | +void closedir(DIR *d); | |
47425 | + | |
47426 | +buffer *filename_unix2local(buffer *b); | |
47427 | +buffer *pathname_unix2local(buffer *b); | |
47428 | + | |
47429 | +#else | |
47430 | +#include <unistd.h> | |
47431 | +#include <dirent.h> | |
47432 | + | |
47433 | +#define DIR_SEPERATOR DIR_SEPERATOR_UNIX | |
47434 | + | |
47435 | +#define filename_unix2local(x) (x) | |
47436 | +#define pathname_unix2local(x) (x) | |
47437 | +#endif | |
47438 | + | |
47439 | +#define PATHNAME_APPEND_SLASH(x) \ | |
47440 | + if (x->used > 1 && x->ptr[x->used - 2] != DIR_SEPERATOR) { \ | |
47441 | + char sl[2] = { DIR_SEPERATOR, 0 }; \ | |
47442 | + BUFFER_APPEND_STRING_CONST(x, sl); \ | |
47443 | + } | |
47444 | + | |
47445 | +#ifndef O_LARGEFILE | |
47446 | +# define O_LARGEFILE 0 | |
47447 | +#endif | |
47448 | + | |
47449 | +#endif | |
47450 | + | |
1175ccec | 47451 | --- ../lighttpd-1.4.11/src/sys-mmap.h 2005-08-11 01:26:34.000000000 +0300 |
36e2a29e | 47452 | +++ lighttpd-1.4.12/src/sys-mmap.h 2006-07-11 22:07:52.000000000 +0300 |
f26f9fd5 ER |
47453 | @@ -1,7 +1,7 @@ |
47454 | #ifndef WIN32_MMAP_H | |
47455 | #define WIN32_MMAP_H | |
f673a614 | 47456 | |
f26f9fd5 ER |
47457 | -#ifdef __WIN32 |
47458 | +#ifdef _WIN32 | |
f673a614 | 47459 | |
f26f9fd5 ER |
47460 | #define MAP_FAILED -1 |
47461 | #define PROT_SHARED 0 | |
1175ccec ER |
47462 | --- ../lighttpd-1.4.11/src/sys-process.h 1970-01-01 03:00:00.000000000 +0300 |
47463 | +++ lighttpd-1.4.12/src/sys-process.h 2006-07-15 22:43:21.000000000 +0300 | |
47464 | @@ -0,0 +1,17 @@ | |
36e2a29e ER |
47465 | +#ifndef _SYS_PROCESS_H_ |
47466 | +#define _SYS_PROCESS_H_ | |
47467 | + | |
47468 | +#ifdef _WIN32 | |
47469 | +#include <process.h> | |
47470 | +#define pid_t int | |
47471 | +/* win32 has no fork() */ | |
47472 | +#define kill(x, y) | |
1175ccec | 47473 | +#define getpid() 0 |
36e2a29e ER |
47474 | + |
47475 | +#else | |
47476 | +#include <sys/wait.h> | |
47477 | +#include <unistd.h> | |
47478 | +#endif | |
47479 | + | |
47480 | +#endif | |
47481 | + | |
1175ccec ER |
47482 | --- ../lighttpd-1.4.11/src/sys-socket.h 2005-08-11 01:26:39.000000000 +0300 |
47483 | +++ lighttpd-1.4.12/src/sys-socket.h 2006-07-15 22:43:21.000000000 +0300 | |
f26f9fd5 ER |
47484 | @@ -1,15 +1,26 @@ |
47485 | #ifndef WIN32_SOCKET_H | |
47486 | #define WIN32_SOCKET_H | |
f673a614 | 47487 | |
f26f9fd5 ER |
47488 | -#ifdef __WIN32 |
47489 | +#ifdef _WIN32 | |
f673a614 | 47490 | |
f26f9fd5 | 47491 | #include <winsock2.h> |
f673a614 | 47492 | |
f26f9fd5 ER |
47493 | #define ECONNRESET WSAECONNRESET |
47494 | #define EINPROGRESS WSAEINPROGRESS | |
47495 | #define EALREADY WSAEALREADY | |
47496 | +#define ENOTCONN WSAENOTCONN | |
47497 | +#define EWOULDBLOCK WSAEWOULDBLOCK | |
47498 | #define ioctl ioctlsocket | |
47499 | #define hstrerror(x) "" | |
47500 | +#define STDIN_FILENO 0 | |
47501 | +#define STDOUT_FILENO 1 | |
47502 | +#define STDERR_FILENO 2 | |
47503 | +#define ssize_t int | |
47504 | + | |
47505 | +int inet_aton(const char *cp, struct in_addr *inp); | |
47506 | +#define HAVE_INET_ADDR | |
47507 | +#undef HAVE_INET_ATON | |
47508 | + | |
47509 | #else | |
47510 | #include <sys/socket.h> | |
47511 | #include <sys/ioctl.h> | |
1175ccec | 47512 | @@ -18,7 +29,23 @@ |
f26f9fd5 ER |
47513 | #include <sys/un.h> |
47514 | #include <arpa/inet.h> | |
f673a614 | 47515 | |
f26f9fd5 ER |
47516 | +#ifndef SUN_LEN |
47517 | +#define SUN_LEN(su) \ | |
47518 | + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) | |
47519 | +#endif | |
47520 | + | |
47521 | #include <netdb.h> | |
47522 | #endif | |
f673a614 | 47523 | |
1175ccec ER |
47524 | +typedef union { |
47525 | +#ifdef HAVE_IPV6 | |
47526 | + struct sockaddr_in6 ipv6; | |
47527 | +#endif | |
47528 | + struct sockaddr_in ipv4; | |
47529 | +#ifdef HAVE_SYS_UN_H | |
47530 | + struct sockaddr_un un; | |
47531 | +#endif | |
47532 | + struct sockaddr plain; | |
47533 | +} sock_addr; | |
47534 | + | |
47535 | #endif | |
47536 | --- ../lighttpd-1.4.11/src/sys-strings.h 1970-01-01 03:00:00.000000000 +0300 | |
36e2a29e ER |
47537 | +++ lighttpd-1.4.12/src/sys-strings.h 2006-07-11 22:07:51.000000000 +0300 |
47538 | @@ -0,0 +1,11 @@ | |
47539 | +#ifndef _SYS_STRINGS_H_ | |
47540 | +#define _SYS_STRINGS_H_ | |
47541 | + | |
47542 | +#ifdef _WIN32 | |
47543 | +#define strcasecmp stricmp | |
47544 | +#define strncasecmp strnicmp | |
47545 | +#define strtoll(p, e, b) _strtoi64(p, e, b) | |
47546 | +#endif | |
47547 | + | |
47548 | +#endif | |
47549 | + | |
1175ccec | 47550 | --- ../lighttpd-1.4.11/tests/LightyTest.pm 2006-01-14 20:32:31.000000000 +0200 |
36e2a29e | 47551 | +++ lighttpd-1.4.12/tests/LightyTest.pm 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 ER |
47552 | @@ -87,14 +87,14 @@ |
47553 | # pre-process configfile if necessary | |
47554 | # | |
f673a614 | 47555 | |
f26f9fd5 ER |
47556 | - unlink($self->{TESTDIR}."/tmp/cfg.file"); |
47557 | - system("cat ".$self->{SRCDIR}."/".$self->{CONFIGFILE}.' | perl -pe "s#\@SRCDIR\@#'.$self->{BASEDIR}.'/tests/#" > '.$self->{TESTDIR}.'/tmp/cfg.file'); | |
47558 | + $ENV{'SRCDIR'} = $self->{BASEDIR}.'/tests'; | |
47559 | + $ENV{'PORT'} = $self->{PORT}; | |
f673a614 | 47560 | |
f26f9fd5 ER |
47561 | unlink($self->{LIGHTTPD_PIDFILE}); |
47562 | if (1) { | |
47563 | - system($self->{LIGHTTPD_PATH}." -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH}); | |
47564 | + system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}); | |
47565 | } else { | |
47566 | - system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=foo ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH}." &"); | |
47567 | + system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=foo ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &"); | |
47568 | } | |
f673a614 | 47569 | |
f26f9fd5 ER |
47570 | select(undef, undef, undef, 0.1); |
47571 | @@ -184,7 +184,7 @@ | |
47572 | (my $h = $1) =~ tr/[A-Z]/[a-z]/; | |
f673a614 | 47573 | |
f26f9fd5 ER |
47574 | if (defined $resp_hdr{$h}) { |
47575 | - diag(sprintf("header %s is duplicated: %s and %s\n", | |
47576 | + diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n", | |
47577 | $h, $resp_hdr{$h}, $2)); | |
47578 | } else { | |
47579 | $resp_hdr{$h} = $2; | |
47580 | @@ -196,6 +196,9 @@ | |
47581 | } | |
47582 | } | |
f673a614 | 47583 | |
f26f9fd5 ER |
47584 | + $t->{etag} = $resp_hdr{'etag'}; |
47585 | + $t->{date} = $resp_hdr{'date'}; | |
47586 | + | |
47587 | # check length | |
47588 | if (defined $resp_hdr{"content-length"}) { | |
47589 | $resp_body = substr($lines, 0, $resp_hdr{"content-length"}); | |
1175ccec ER |
47590 | --- ../lighttpd-1.4.11/tests/Makefile.am 2005-09-16 15:48:40.000000000 +0300 |
47591 | +++ lighttpd-1.4.12/tests/Makefile.am 2006-07-15 22:43:22.000000000 +0300 | |
47592 | @@ -39,10 +39,18 @@ | |
f26f9fd5 ER |
47593 | mod-redirect.t \ |
47594 | mod-userdir.t \ | |
47595 | mod-rewrite.t \ | |
47596 | + mod-proxy.t \ | |
47597 | request.t \ | |
47598 | mod-ssi.t \ | |
47599 | LightyTest.pm \ | |
47600 | - mod-setenv.t | |
47601 | + mod-setenv.t \ | |
47602 | + lowercase.t \ | |
47603 | + lowercase.conf \ | |
47604 | + proxy.conf \ | |
1175ccec ER |
47605 | + cachable.t \ |
47606 | + default.conf \ | |
47607 | + proxy-backend-1.conf \ | |
47608 | + proxy-backend-2.conf | |
f673a614 | 47609 | |
f673a614 | 47610 | |
f26f9fd5 | 47611 | TESTS_ENVIRONMENT=$(srcdir)/wrapper.sh $(srcdir) $(top_builddir) |
1175ccec | 47612 | --- ../lighttpd-1.4.11/tests/bug-06.conf 2005-08-27 17:44:19.000000000 +0300 |
36e2a29e | 47613 | +++ lighttpd-1.4.12/tests/bug-06.conf 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 | 47614 | @@ -1,5 +1,5 @@ |
f673a614 ER |
47615 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" |
47616 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
47617 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47618 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
47619 | ||
47620 | ## bind to port (default: 80) | |
47621 | server.port = 2048 | |
f26f9fd5 | 47622 | @@ -8,7 +8,7 @@ |
f673a614 ER |
47623 | |
47624 | ## bind to localhost (default: all interfaces) | |
47625 | server.bind = "localhost" | |
47626 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
47627 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
47628 | server.name = "www.example.org" | |
47629 | server.tag = "Apache 1.3.29" | |
47630 | ||
f26f9fd5 | 47631 | @@ -59,7 +59,7 @@ |
f673a614 ER |
47632 | ######################## MODULE CONFIG ############################ |
47633 | ||
47634 | ||
47635 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" | |
47636 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" | |
47637 | ||
47638 | mimetype.assign = ( ".png" => "image/png", | |
47639 | ".jpg" => "image/jpeg", | |
f26f9fd5 | 47640 | @@ -77,7 +77,7 @@ |
f673a614 ER |
47641 | ".c" => "text/plain", |
47642 | ".conf" => "text/plain" ) | |
47643 | ||
47644 | -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/" | |
47645 | +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" | |
47646 | compress.filetype = ("text/plain", "text/html") | |
47647 | ||
f26f9fd5 ER |
47648 | setenv.add-environment = ( "TRAC_ENV" => "foo") |
47649 | @@ -90,7 +90,7 @@ | |
47650 | "host" => "127.0.0.1", | |
47651 | "port" => 1026, | |
47652 | # "mode" => "authorizer", | |
47653 | -# "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/", | |
47654 | +# "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/", | |
47655 | ) | |
47656 | ) | |
47657 | ) | |
47658 | @@ -106,7 +106,7 @@ | |
f673a614 ER |
47659 | ssl.pemfile = "server.pem" |
47660 | ||
47661 | auth.backend = "plain" | |
47662 | -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user" | |
47663 | +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" | |
47664 | auth.backend.plain.groupfile = "lighttpd.group" | |
47665 | ||
47666 | auth.backend.ldap.hostname = "localhost" | |
f26f9fd5 | 47667 | @@ -149,15 +149,15 @@ |
f673a614 ER |
47668 | status.config-url = "/server-config" |
47669 | ||
f26f9fd5 ER |
47670 | simple-vhost.document-root = "pages" |
47671 | -simple-vhost.server-root = "@SRCDIR@/tmp/lighttpd/servers/" | |
47672 | +simple-vhost.server-root = env.SRCDIR + "/tmp/lighttpd/servers/" | |
47673 | simple-vhost.default-host = "www.example.org" | |
47674 | ||
f673a614 ER |
47675 | $HTTP["host"] == "vvv.example.org" { |
47676 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47677 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47678 | } | |
47679 | ||
47680 | $HTTP["host"] == "zzz.example.org" { | |
47681 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47682 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47683 | server.name = "zzz.example.org" | |
47684 | } | |
47685 | ||
1175ccec | 47686 | --- ../lighttpd-1.4.11/tests/bug-12.conf 2005-08-27 17:44:19.000000000 +0300 |
36e2a29e | 47687 | +++ lighttpd-1.4.12/tests/bug-12.conf 2006-07-11 22:07:53.000000000 +0300 |
f673a614 ER |
47688 | @@ -1,5 +1,5 @@ |
47689 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47690 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
47691 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47692 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
47693 | ||
47694 | ## bind to port (default: 80) | |
47695 | server.port = 2048 | |
47696 | @@ -8,7 +8,7 @@ | |
47697 | ||
47698 | ## bind to localhost (default: all interfaces) | |
47699 | server.bind = "localhost" | |
47700 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
47701 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
47702 | server.name = "www.example.org" | |
47703 | server.tag = "Apache 1.3.29" | |
47704 | ||
f26f9fd5 | 47705 | @@ -61,7 +61,7 @@ |
f673a614 ER |
47706 | ######################## MODULE CONFIG ############################ |
47707 | ||
47708 | ||
47709 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" | |
47710 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" | |
47711 | ||
47712 | mimetype.assign = ( ".png" => "image/png", | |
47713 | ".jpg" => "image/jpeg", | |
f26f9fd5 | 47714 | @@ -79,7 +79,7 @@ |
f673a614 ER |
47715 | ".c" => "text/plain", |
47716 | ".conf" => "text/plain" ) | |
47717 | ||
47718 | -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/" | |
47719 | +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" | |
47720 | compress.filetype = ("text/plain", "text/html") | |
47721 | ||
47722 | setenv.add-environment = ( "TRAC_ENV" => "foo") | |
f26f9fd5 | 47723 | @@ -92,7 +92,7 @@ |
f673a614 ER |
47724 | "host" => "127.0.0.1", |
47725 | "port" => 1026, | |
47726 | # "mode" => "authorizer", | |
47727 | -# "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/", | |
47728 | +# "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/", | |
47729 | ) | |
47730 | ) | |
47731 | ) | |
f26f9fd5 | 47732 | @@ -108,7 +108,7 @@ |
f673a614 ER |
47733 | ssl.pemfile = "server.pem" |
47734 | ||
47735 | auth.backend = "plain" | |
47736 | -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user" | |
47737 | +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" | |
47738 | auth.backend.plain.groupfile = "lighttpd.group" | |
47739 | ||
47740 | auth.backend.ldap.hostname = "localhost" | |
f26f9fd5 | 47741 | @@ -151,15 +151,15 @@ |
f673a614 ER |
47742 | status.config-url = "/server-config" |
47743 | ||
47744 | simple-vhost.document-root = "pages" | |
47745 | -simple-vhost.server-root = "@SRCDIR@/tmp/lighttpd/servers/" | |
47746 | +simple-vhost.server-root = env.SRCDIR + "/tmp/lighttpd/servers/" | |
47747 | simple-vhost.default-host = "www.example.org" | |
47748 | ||
47749 | $HTTP["host"] == "vvv.example.org" { | |
47750 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47751 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47752 | } | |
47753 | ||
47754 | $HTTP["host"] == "zzz.example.org" { | |
47755 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47756 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47757 | server.name = "zzz.example.org" | |
47758 | } | |
47759 | ||
1175ccec | 47760 | --- ../lighttpd-1.4.11/tests/cachable.t 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 47761 | +++ lighttpd-1.4.12/tests/cachable.t 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
47762 | @@ -0,0 +1,112 @@ |
47763 | +#!/usr/bin/env perl | |
47764 | +BEGIN { | |
47765 | + # add current source dir to the include-path | |
47766 | + # we need this for make distcheck | |
47767 | + (my $srcdir = $0) =~ s#/[^/]+$#/#; | |
47768 | + unshift @INC, $srcdir; | |
47769 | +} | |
47770 | + | |
47771 | +use strict; | |
47772 | +use IO::Socket; | |
47773 | +use Test::More tests => 12; | |
47774 | +use LightyTest; | |
47775 | + | |
47776 | +my $tf = LightyTest->new(); | |
47777 | +my $t; | |
47778 | + | |
47779 | +$tf->{CONFIGFILE} = 'lighttpd.conf'; | |
47780 | + | |
47781 | +ok($tf->start_proc == 0, "Starting lighttpd") or die(); | |
47782 | + | |
47783 | +## check if If-Modified-Since, If-None-Match works | |
47784 | + | |
47785 | +$t->{REQUEST} = ( <<EOF | |
47786 | +GET / HTTP/1.0 | |
47787 | +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT | |
47788 | +EOF | |
47789 | + ); | |
47790 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
47791 | +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since'); | |
47792 | + | |
47793 | +$t->{REQUEST} = ( <<EOF | |
47794 | +GET / HTTP/1.0 | |
47795 | +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo | |
47796 | +EOF | |
47797 | + ); | |
47798 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
47799 | +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since, comment'); | |
47800 | + | |
47801 | +my $now = $t->{date}; | |
47802 | + | |
47803 | +$t->{REQUEST} = ( <<EOF | |
47804 | +GET / HTTP/1.0 | |
47805 | +If-Modified-Since: $now | |
47806 | +EOF | |
47807 | + ); | |
47808 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; | |
47809 | +ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since'); | |
47810 | + | |
47811 | +$t->{REQUEST} = ( <<EOF | |
47812 | +GET / HTTP/1.0 | |
47813 | +If-Modified-Since: $now; foo | |
47814 | +EOF | |
47815 | + ); | |
47816 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; | |
47817 | +ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since, comment'); | |
47818 | + | |
47819 | +$t->{REQUEST} = ( <<EOF | |
47820 | +GET / HTTP/1.0 | |
47821 | +If-None-Match: foo | |
47822 | +EOF | |
47823 | + ); | |
47824 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
47825 | +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match'); | |
47826 | + | |
47827 | +my $etag = $t->{etag}; | |
47828 | + | |
47829 | +$t->{REQUEST} = ( <<EOF | |
47830 | +GET / HTTP/1.0 | |
47831 | +If-None-Match: $etag | |
47832 | +EOF | |
47833 | + ); | |
47834 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; | |
47835 | +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match'); | |
47836 | + | |
47837 | +$t->{REQUEST} = ( <<EOF | |
47838 | +GET / HTTP/1.0 | |
47839 | +If-None-Match: $etag | |
47840 | +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo | |
47841 | +EOF | |
47842 | + ); | |
47843 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
47844 | +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + old Last-Modified'); | |
47845 | + | |
47846 | +$t->{REQUEST} = ( <<EOF | |
47847 | +GET / HTTP/1.0 | |
47848 | +If-None-Match: $etag | |
47849 | +If-Modified-Since: $now; foo | |
47850 | +EOF | |
47851 | + ); | |
47852 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; | |
47853 | +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag, Last-Modified + comment'); | |
47854 | + | |
47855 | +$t->{REQUEST} = ( <<EOF | |
47856 | +GET / HTTP/1.0 | |
47857 | +If-None-Match: Foo | |
47858 | +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo | |
47859 | +EOF | |
47860 | + ); | |
47861 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
47862 | +ok($tf->handle_http($t) == 0, 'Conditional GET - old ETAG + old Last-Modified'); | |
47863 | + | |
47864 | +$t->{REQUEST} = ( <<EOF | |
47865 | +GET / HTTP/1.0 | |
47866 | +If-None-Match: $etag | |
47867 | +If-Modified-Since: $now foo | |
47868 | +EOF | |
47869 | + ); | |
47870 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 412 } ]; | |
47871 | +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + Last-Modified + overlong timestamp'); | |
47872 | + | |
47873 | +ok($tf->stop_proc == 0, "Stopping lighttpd"); | |
47874 | + | |
1175ccec | 47875 | --- ../lighttpd-1.4.11/tests/condition.conf 2005-08-27 17:44:19.000000000 +0300 |
36e2a29e | 47876 | +++ lighttpd-1.4.12/tests/condition.conf 2006-07-11 22:07:53.000000000 +0300 |
f673a614 ER |
47877 | @@ -2,15 +2,15 @@ |
47878 | debug.log-request-handling = "enable" | |
47879 | debug.log-condition-handling = "enable" | |
47880 | ||
47881 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47882 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
47883 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47884 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
47885 | ||
47886 | ## bind to port (default: 80) | |
47887 | server.port = 2048 | |
47888 | ||
47889 | ## bind to localhost (default: all interfaces) | |
47890 | server.bind = "localhost" | |
47891 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
47892 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
47893 | server.name = "www.example.org" | |
47894 | server.tag = "Apache 1.3.29" | |
47895 | ||
47896 | @@ -22,25 +22,25 @@ | |
47897 | ######################## MODULE CONFIG ############################ | |
47898 | ||
47899 | ||
47900 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" | |
47901 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" | |
47902 | ||
47903 | mimetype.assign = ( ".html" => "text/html" ) | |
47904 | ||
47905 | url.redirect = ("^" => "/default") | |
47906 | ||
47907 | $HTTP["host"] == "www.example.org" { | |
47908 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47909 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47910 | server.name = "www.example.org" | |
47911 | url.redirect = ("^" => "/match_1") | |
47912 | } | |
47913 | else $HTTP["host"] == "test1.example.org" { | |
47914 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47915 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47916 | server.name = "test1.example.org" | |
47917 | url.redirect = ("^" => "/match_2") | |
47918 | } | |
47919 | # comments | |
47920 | else $HTTP["host"] == "test2.example.org" { | |
47921 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47922 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47923 | server.name = "test2.example.org" | |
47924 | url.redirect = ("^" => "/match_3") | |
47925 | } | |
47926 | @@ -48,7 +48,7 @@ | |
47927 | # comments | |
47928 | ||
47929 | else $HTTP["host"] == "test3.example.org" { | |
47930 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
47931 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47932 | server.name = "test3.example.org" | |
47933 | url.redirect = ("^" => "/match_4") | |
47934 | ||
1175ccec | 47935 | --- ../lighttpd-1.4.11/tests/core-keepalive.t 2005-11-17 15:54:19.000000000 +0200 |
36e2a29e | 47936 | +++ lighttpd-1.4.12/tests/core-keepalive.t 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 ER |
47937 | @@ -40,7 +40,7 @@ |
47938 | ||
47939 | GET /12345.txt HTTP/1.0 | |
47940 | Host: 123.example.org | |
47941 | -Connection: keep-alive | |
47942 | +Connection: close | |
47943 | EOF | |
47944 | ); | |
47945 | $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
1175ccec ER |
47946 | --- ../lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries 2006-03-09 19:21:49.000000000 +0200 |
47947 | +++ lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries 2006-07-15 22:43:22.000000000 +0300 | |
f26f9fd5 ER |
47948 | @@ -9,5 +9,6 @@ |
47949 | last-author="jan" | |
47950 | kind="dir" | |
47951 | uuid="152afb58-edef-0310-8abb-c4023f1b3aa9" | |
47952 | - revision="1040"/> | |
47953 | + repos="svn://svn.lighttpd.net/lighttpd" | |
1175ccec | 47954 | + revision="1173"/> |
f26f9fd5 | 47955 | </wc-entries> |
1175ccec | 47956 | --- ../lighttpd-1.4.11/tests/fastcgi-10.conf 2005-08-31 23:36:34.000000000 +0300 |
36e2a29e | 47957 | +++ lighttpd-1.4.12/tests/fastcgi-10.conf 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 | 47958 | @@ -1,12 +1,12 @@ |
f673a614 ER |
47959 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" |
47960 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
47961 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
47962 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
47963 | ||
f26f9fd5 ER |
47964 | ## bind to port (default: 80) |
47965 | server.port = 2048 | |
f673a614 ER |
47966 | |
47967 | ## bind to localhost (default: all interfaces) | |
47968 | server.bind = "localhost" | |
47969 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
47970 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
47971 | server.name = "www.example.org" | |
47972 | server.tag = "Apache 1.3.29" | |
47973 | ||
f26f9fd5 | 47974 | @@ -44,7 +44,7 @@ |
f673a614 ER |
47975 | ######################## MODULE CONFIG ############################ |
47976 | ||
47977 | ||
47978 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" | |
47979 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" | |
47980 | ||
47981 | mimetype.assign = ( ".png" => "image/png", | |
47982 | ".jpg" => "image/jpeg", | |
f26f9fd5 | 47983 | @@ -62,7 +62,7 @@ |
f673a614 ER |
47984 | ".c" => "text/plain", |
47985 | ".conf" => "text/plain" ) | |
47986 | ||
47987 | -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/" | |
47988 | +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" | |
47989 | compress.filetype = ("text/plain", "text/html") | |
47990 | ||
47991 | fastcgi.debug = 0 | |
f26f9fd5 | 47992 | @@ -85,7 +85,7 @@ |
f673a614 ER |
47993 | ssl.pemfile = "server.pem" |
47994 | ||
47995 | auth.backend = "plain" | |
47996 | -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user" | |
47997 | +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" | |
47998 | auth.backend.plain.groupfile = "lighttpd.group" | |
47999 | ||
48000 | auth.backend.ldap.hostname = "localhost" | |
f26f9fd5 | 48001 | @@ -128,11 +128,11 @@ |
f673a614 ER |
48002 | status.config-url = "/server-config" |
48003 | ||
48004 | $HTTP["host"] == "vvv.example.org" { | |
48005 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48006 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48007 | } | |
48008 | ||
48009 | $HTTP["host"] == "zzz.example.org" { | |
48010 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48011 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48012 | server.name = "zzz.example.org" | |
48013 | } | |
48014 | ||
1175ccec | 48015 | --- ../lighttpd-1.4.11/tests/fastcgi-13.conf 2006-01-03 12:38:17.000000000 +0200 |
36e2a29e | 48016 | +++ lighttpd-1.4.12/tests/fastcgi-13.conf 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 | 48017 | @@ -1,5 +1,5 @@ |
f673a614 ER |
48018 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" |
48019 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
48020 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48021 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
f673a614 | 48022 | |
f26f9fd5 ER |
48023 | debug.log-request-header = "enable" |
48024 | debug.log-response-header = "enable" | |
48025 | @@ -10,7 +10,7 @@ | |
f673a614 | 48026 | |
f26f9fd5 ER |
48027 | ## bind to localhost (default: all interfaces) |
48028 | server.bind = "localhost" | |
f673a614 | 48029 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" |
f26f9fd5 ER |
48030 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" |
48031 | server.name = "www.example.org" | |
48032 | server.tag = "Apache 1.3.29" | |
48033 | ||
48034 | @@ -59,7 +59,7 @@ | |
48035 | ######################## MODULE CONFIG ############################ | |
48036 | ||
f673a614 | 48037 | |
f673a614 | 48038 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" |
f26f9fd5 | 48039 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" |
f673a614 | 48040 | |
f26f9fd5 ER |
48041 | mimetype.assign = ( ".png" => "image/png", |
48042 | ".jpg" => "image/jpeg", | |
48043 | @@ -77,7 +77,7 @@ | |
48044 | ".c" => "text/plain", | |
48045 | ".conf" => "text/plain" ) | |
48046 | ||
48047 | -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/" | |
48048 | +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" | |
48049 | compress.filetype = ("text/plain", "text/html") | |
48050 | ||
48051 | fastcgi.debug = 0 | |
48052 | @@ -102,7 +102,7 @@ | |
48053 | ssl.pemfile = "server.pem" | |
48054 | ||
48055 | auth.backend = "plain" | |
48056 | -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user" | |
48057 | +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" | |
48058 | auth.backend.plain.groupfile = "lighttpd.group" | |
48059 | ||
48060 | auth.backend.ldap.hostname = "localhost" | |
48061 | @@ -145,11 +145,11 @@ | |
48062 | status.config-url = "/server-config" | |
f673a614 | 48063 | |
f673a614 ER |
48064 | $HTTP["host"] == "vvv.example.org" { |
48065 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48066 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
f673a614 ER |
48067 | } |
48068 | ||
48069 | $HTTP["host"] == "zzz.example.org" { | |
48070 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48071 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48072 | server.name = "zzz.example.org" | |
48073 | } | |
48074 | ||
1175ccec | 48075 | --- ../lighttpd-1.4.11/tests/fastcgi-auth.conf 2005-08-27 17:44:19.000000000 +0300 |
36e2a29e | 48076 | +++ lighttpd-1.4.12/tests/fastcgi-auth.conf 2006-07-11 22:07:53.000000000 +0300 |
f673a614 ER |
48077 | @@ -1,5 +1,5 @@ |
48078 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48079 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
48080 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48081 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
48082 | ||
f26f9fd5 ER |
48083 | debug.log-request-header = "enable" |
48084 | debug.log-response-header = "enable" | |
48085 | @@ -12,7 +12,7 @@ | |
f673a614 ER |
48086 | |
48087 | ## bind to localhost (default: all interfaces) | |
48088 | server.bind = "localhost" | |
48089 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
48090 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
48091 | server.name = "www.example.org" | |
48092 | server.tag = "Apache 1.3.29" | |
48093 | ||
f26f9fd5 | 48094 | @@ -61,7 +61,7 @@ |
f673a614 ER |
48095 | ######################## MODULE CONFIG ############################ |
48096 | ||
48097 | ||
48098 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" | |
48099 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" | |
48100 | ||
48101 | mimetype.assign = ( ".png" => "image/png", | |
48102 | ".jpg" => "image/jpeg", | |
f26f9fd5 | 48103 | @@ -79,7 +79,7 @@ |
f673a614 ER |
48104 | ".c" => "text/plain", |
48105 | ".conf" => "text/plain" ) | |
48106 | ||
48107 | -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/" | |
48108 | +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" | |
48109 | compress.filetype = ("text/plain", "text/html") | |
48110 | ||
48111 | fastcgi.debug = 0 | |
f26f9fd5 | 48112 | @@ -87,9 +87,9 @@ |
f673a614 ER |
48113 | "grisu" => ( |
48114 | "host" => "127.0.0.1", | |
f26f9fd5 ER |
48115 | "port" => 20000, |
48116 | - "bin-path" => "@SRCDIR@/fcgi-auth", | |
48117 | + "bin-path" => env.SRCDIR + "/fcgi-auth", | |
48118 | "mode" => "authorizer", | |
48119 | - "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/", | |
48120 | + "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/", | |
48121 | ||
f673a614 ER |
48122 | ) |
48123 | ) | |
f26f9fd5 | 48124 | @@ -106,7 +106,7 @@ |
f673a614 ER |
48125 | ssl.pemfile = "server.pem" |
48126 | ||
48127 | auth.backend = "plain" | |
48128 | -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user" | |
48129 | +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" | |
48130 | auth.backend.plain.groupfile = "lighttpd.group" | |
48131 | ||
48132 | auth.backend.ldap.hostname = "localhost" | |
f26f9fd5 | 48133 | @@ -149,11 +149,11 @@ |
f673a614 ER |
48134 | status.config-url = "/server-config" |
48135 | ||
48136 | $HTTP["host"] == "vvv.example.org" { | |
48137 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48138 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48139 | } | |
48140 | ||
48141 | $HTTP["host"] == "zzz.example.org" { | |
48142 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48143 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48144 | server.name = "zzz.example.org" | |
48145 | } | |
48146 | ||
1175ccec | 48147 | --- ../lighttpd-1.4.11/tests/fastcgi-responder.conf 2005-08-27 17:44:19.000000000 +0300 |
36e2a29e | 48148 | +++ lighttpd-1.4.12/tests/fastcgi-responder.conf 2006-07-11 22:07:53.000000000 +0300 |
f673a614 ER |
48149 | @@ -1,5 +1,5 @@ |
48150 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48151 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
48152 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48153 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
48154 | ||
f26f9fd5 ER |
48155 | #debug.log-request-header = "enable" |
48156 | #debug.log-response-header = "enable" | |
48157 | @@ -15,7 +15,7 @@ | |
f673a614 ER |
48158 | |
48159 | ## bind to localhost (default: all interfaces) | |
48160 | server.bind = "localhost" | |
48161 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
48162 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
48163 | server.name = "www.example.org" | |
48164 | server.tag = "Apache 1.3.29" | |
48165 | ||
f26f9fd5 | 48166 | @@ -64,7 +64,7 @@ |
f673a614 ER |
48167 | ######################## MODULE CONFIG ############################ |
48168 | ||
48169 | ||
48170 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" | |
48171 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" | |
48172 | ||
48173 | mimetype.assign = ( ".png" => "image/png", | |
48174 | ".jpg" => "image/jpeg", | |
f26f9fd5 | 48175 | @@ -82,7 +82,7 @@ |
f673a614 ER |
48176 | ".c" => "text/plain", |
48177 | ".conf" => "text/plain" ) | |
48178 | ||
48179 | -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/" | |
48180 | +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" | |
48181 | compress.filetype = ("text/plain", "text/html") | |
48182 | ||
48183 | fastcgi.debug = 0 | |
f26f9fd5 | 48184 | @@ -90,10 +90,11 @@ |
f673a614 ER |
48185 | "grisu" => ( |
48186 | "host" => "127.0.0.1", | |
f26f9fd5 ER |
48187 | "port" => 10000, |
48188 | - "bin-path" => "@SRCDIR@/fcgi-responder", | |
48189 | + "bin-path" => env.SRCDIR + "/fcgi-responder", | |
48190 | "check-local" => "disable", | |
48191 | "max-procs" => 1, | |
48192 | - "min-procs" => 1 | |
48193 | + "min-procs" => 1, | |
48194 | + "allow-x-send-file" => "enable", | |
f673a614 ER |
48195 | ) |
48196 | ) | |
f26f9fd5 ER |
48197 | ) |
48198 | @@ -109,7 +110,7 @@ | |
f673a614 ER |
48199 | ssl.pemfile = "server.pem" |
48200 | ||
48201 | auth.backend = "plain" | |
48202 | -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user" | |
48203 | +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" | |
48204 | auth.backend.plain.groupfile = "lighttpd.group" | |
48205 | ||
48206 | auth.backend.ldap.hostname = "localhost" | |
f26f9fd5 | 48207 | @@ -152,11 +153,11 @@ |
f673a614 ER |
48208 | status.config-url = "/server-config" |
48209 | ||
48210 | $HTTP["host"] == "vvv.example.org" { | |
48211 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48212 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48213 | } | |
48214 | ||
48215 | $HTTP["host"] == "zzz.example.org" { | |
48216 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48217 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48218 | server.name = "zzz.example.org" | |
48219 | } | |
48220 | ||
1175ccec | 48221 | --- ../lighttpd-1.4.11/tests/fcgi-responder.c 2005-08-11 01:26:55.000000000 +0300 |
36e2a29e | 48222 | +++ lighttpd-1.4.12/tests/fcgi-responder.c 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 ER |
48223 | @@ -6,11 +6,17 @@ |
48224 | int main () { | |
48225 | int num_requests = 2; | |
48226 | ||
48227 | - while (num_requests > 0 && | |
48228 | - FCGI_Accept() >= 0) { | |
48229 | - char* p; | |
2519e6e5 ER |
48230 | - |
48231 | - if (NULL != (p = getenv("QUERY_STRING"))) { | |
f26f9fd5 ER |
48232 | + while (num_requests > 0 && FCGI_Accept() >= 0) { |
48233 | + char* p = NULL; | |
48234 | + char* doc_root = NULL; | |
48235 | + char fname[4096]; | |
48236 | + char* pfname = (char *)fname; | |
2519e6e5 | 48237 | + |
f26f9fd5 ER |
48238 | + doc_root = getenv("DOCUMENT_ROOT"); |
48239 | + p = getenv("QUERY_STRING"); | |
48240 | + | |
48241 | + if (NULL != p && NULL != doc_root) { | |
48242 | + snprintf(pfname, sizeof(fname), "%s/phpinfo.php", doc_root); | |
48243 | if (0 == strcmp(p, "lf")) { | |
48244 | printf("Status: 200 OK\n\n"); | |
48245 | } else if (0 == strcmp(p, "crlf")) { | |
48246 | @@ -23,6 +29,18 @@ | |
48247 | printf("Status: 200 OK\r\n"); | |
48248 | fflush(stdout); | |
48249 | printf("\r\n"); | |
48250 | + } else if (0 == strcmp(p,"x-lighttpd-send-file")) { | |
48251 | + printf("Status: 200 OK\r\n"); | |
48252 | + printf("X-LIGHTTPD-send-file: %s\r\n", pfname); | |
48253 | + printf("\r\n"); | |
48254 | + } else if (0 == strcmp(p,"xsendfile")) { | |
48255 | + printf("Status: 200 OK\r\n"); | |
48256 | + printf("X-Sendfile: %s\r\n", pfname); | |
48257 | + printf("\r\n"); | |
48258 | + } else if (0 == strcmp(p,"xsendfile-mixed-case")) { | |
48259 | + printf("Status: 200 OK\r\n"); | |
48260 | + printf("X-SeNdFiLe: %s\r\n", pfname); | |
48261 | + printf("\r\n"); | |
48262 | } else if (0 == strcmp(p, "die-at-end")) { | |
48263 | printf("Status: 200 OK\r\n\r\n"); | |
48264 | num_requests--; | |
1175ccec | 48265 | --- ../lighttpd-1.4.11/tests/lighttpd.conf 2006-03-09 15:26:58.000000000 +0200 |
36e2a29e | 48266 | +++ lighttpd-1.4.12/tests/lighttpd.conf 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 ER |
48267 | @@ -1,80 +1,18 @@ |
48268 | -debug.log-request-handling = "enable" | |
48269 | -debug.log-condition-handling = "enable" | |
f673a614 | 48270 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" |
f26f9fd5 | 48271 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" |
f673a614 | 48272 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" |
f26f9fd5 ER |
48273 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" |
48274 | +server.tag = "Apache 1.3.29" | |
f673a614 | 48275 | |
f26f9fd5 ER |
48276 | ## 64 Mbyte ... nice limit |
48277 | server.max-request-size = 65000 | |
f673a614 | 48278 | |
f26f9fd5 ER |
48279 | -## bind to port (default: 80) |
48280 | -server.port = 2048 | |
2519e6e5 ER |
48281 | +include "default.conf" |
48282 | ||
f673a614 ER |
48283 | -## bind to localhost (default: all interfaces) |
48284 | -server.bind = "localhost" | |
48285 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
48286 | -server.name = "www.example.org" | |
f26f9fd5 | 48287 | -server.tag = "Apache 1.3.29" |
f673a614 ER |
48288 | - |
48289 | -server.dir-listing = "enable" | |
2519e6e5 | 48290 | - |
f673a614 ER |
48291 | -#server.event-handler = "linux-sysepoll" |
48292 | -#server.event-handler = "linux-rtsig" | |
48293 | - | |
48294 | -#server.modules.path = "" | |
48295 | -server.modules = ( | |
48296 | - "mod_rewrite", | |
48297 | - "mod_setenv", | |
f26f9fd5 | 48298 | - "mod_secdownload", |
f673a614 ER |
48299 | - "mod_access", |
48300 | - "mod_auth", | |
48301 | -# "mod_httptls", | |
48302 | - "mod_status", | |
48303 | - "mod_expire", | |
48304 | - "mod_simple_vhost", | |
48305 | - "mod_redirect", | |
48306 | -# "mod_evhost", | |
48307 | -# "mod_localizer", | |
48308 | - "mod_fastcgi", | |
f673a614 ER |
48309 | - "mod_cgi", |
48310 | - "mod_compress", | |
48311 | - "mod_userdir", | |
f26f9fd5 | 48312 | - "mod_ssi", |
f673a614 ER |
48313 | - "mod_accesslog" ) |
48314 | - | |
48315 | -server.indexfiles = ( "index.php", "index.html", | |
48316 | - "index.htm", "default.htm" ) | |
48317 | - | |
48318 | - | |
48319 | -######################## MODULE CONFIG ############################ | |
48320 | - | |
f26f9fd5 | 48321 | -ssi.extension = ( ".shtml" ) |
f673a614 ER |
48322 | - |
48323 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" | |
48324 | - | |
48325 | -mimetype.assign = ( ".png" => "image/png", | |
48326 | - ".jpg" => "image/jpeg", | |
48327 | - ".jpeg" => "image/jpeg", | |
48328 | - ".gif" => "image/gif", | |
48329 | - ".html" => "text/html", | |
48330 | - ".htm" => "text/html", | |
48331 | - ".pdf" => "application/pdf", | |
48332 | - ".swf" => "application/x-shockwave-flash", | |
48333 | - ".spl" => "application/futuresplash", | |
48334 | - ".txt" => "text/plain", | |
48335 | - ".tar.gz" => "application/x-tgz", | |
48336 | - ".tgz" => "application/x-tgz", | |
48337 | - ".gz" => "application/x-gzip", | |
48338 | - ".c" => "text/plain", | |
48339 | - ".conf" => "text/plain" ) | |
f26f9fd5 ER |
48340 | +setenv.add-request-header = ( "FOO" => "foo") |
48341 | +setenv.add-response-header = ( "BAR" => "foo") | |
48342 | ||
48343 | $HTTP["host"] == "cache.example.org" { | |
48344 | - compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/" | |
48345 | + compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/" | |
48346 | } | |
f673a614 ER |
48347 | -compress.filetype = ("text/plain", "text/html") |
48348 | - | |
f26f9fd5 | 48349 | -setenv.add-environment = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv") |
f673a614 ER |
48350 | -setenv.add-request-header = ( "FOO" => "foo") |
48351 | -setenv.add-response-header = ( "BAR" => "foo") | |
f26f9fd5 ER |
48352 | |
48353 | $HTTP["url"] =~ "\.pdf$" { | |
48354 | server.range-requests = "disable" | |
48355 | @@ -85,76 +23,31 @@ | |
48356 | "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) ) | |
48357 | ) | |
f673a614 ER |
48358 | |
48359 | - | |
48360 | -cgi.assign = ( ".pl" => "/usr/bin/perl", | |
48361 | - ".cgi" => "/usr/bin/perl", | |
48362 | - ".py" => "/usr/bin/python" ) | |
48363 | - | |
48364 | -userdir.include-user = ( "jan" ) | |
48365 | -userdir.path = "/" | |
48366 | - | |
48367 | -ssl.engine = "disable" | |
48368 | -ssl.pemfile = "server.pem" | |
48369 | - | |
f26f9fd5 ER |
48370 | $HTTP["host"] == "auth-htpasswd.example.org" { |
48371 | auth.backend = "htpasswd" | |
48372 | } | |
48373 | ||
f673a614 ER |
48374 | -auth.backend = "plain" |
48375 | -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user" | |
f673a614 | 48376 | - |
f26f9fd5 ER |
48377 | -auth.backend.htpasswd.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.htpasswd" |
48378 | - | |
f673a614 ER |
48379 | - |
48380 | -auth.require = ( "/server-status" => | |
48381 | - ( | |
48382 | - "method" => "digest", | |
48383 | - "realm" => "download archiv", | |
f673a614 ER |
48384 | - "require" => "group=www|user=jan|host=192.168.2.10" |
48385 | - ), | |
f673a614 ER |
48386 | - "/server-config" => |
48387 | - ( | |
48388 | - "method" => "basic", | |
48389 | - "realm" => "download archiv", | |
f26f9fd5 | 48390 | - "require" => "valid-user" |
f673a614 ER |
48391 | - ) |
48392 | - ) | |
48393 | - | |
48394 | -url.access-deny = ( "~", ".inc") | |
48395 | - | |
f673a614 | 48396 | -url.rewrite = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1", |
f26f9fd5 ER |
48397 | - "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" ) |
48398 | - | |
48399 | -expire.url = ( "/expire/access" => "access 2 hours", | |
48400 | - "/expire/modification" => "access plus 1 seconds 2 minutes") | |
48401 | - | |
48402 | -#cache.cache-dir = "/home/weigon/wwwroot/cache/" | |
48403 | - | |
48404 | -#### status module | |
48405 | -status.status-url = "/server-status" | |
48406 | -status.config-url = "/server-config" | |
48407 | - | |
48408 | $HTTP["host"] == "vvv.example.org" { | |
48409 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48410 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48411 | secdownload.secret = "verysecret" | |
48412 | - secdownload.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48413 | + secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48414 | secdownload.uri-prefix = "/sec/" | |
48415 | secdownload.timeout = 120 | |
48416 | } | |
f673a614 | 48417 | |
f26f9fd5 ER |
48418 | $HTTP["host"] == "zzz.example.org" { |
48419 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48420 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48421 | server.name = "zzz.example.org" | |
48422 | } | |
f673a614 | 48423 | |
f26f9fd5 ER |
48424 | $HTTP["host"] == "no-simple.example.org" { |
48425 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/123.example.org/pages/" | |
48426 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/123.example.org/pages/" | |
48427 | server.name = "zzz.example.org" | |
48428 | } | |
f673a614 | 48429 | |
f26f9fd5 ER |
48430 | $HTTP["host"] !~ "(no-simple\.example\.org)" { |
48431 | simple-vhost.document-root = "pages" | |
48432 | - simple-vhost.server-root = "@SRCDIR@/tmp/lighttpd/servers/" | |
48433 | + simple-vhost.server-root = env.SRCDIR + "/tmp/lighttpd/servers/" | |
48434 | simple-vhost.default-host = "www.example.org" | |
48435 | } | |
f673a614 | 48436 | |
1175ccec | 48437 | --- ../lighttpd-1.4.11/tests/lowercase.conf 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 48438 | +++ lighttpd-1.4.12/tests/lowercase.conf 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
48439 | @@ -0,0 +1,80 @@ |
48440 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48441 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
48442 | + | |
48443 | +## bind to port (default: 80) | |
48444 | +server.port = 2048 | |
48445 | + | |
48446 | +## bind to localhost (default: all interfaces) | |
48447 | +server.bind = "localhost" | |
48448 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
48449 | + | |
48450 | +server.force-lowercase-filenames = "enable" | |
48451 | + | |
48452 | +server.dir-listing = "enable" | |
48453 | + | |
48454 | +server.modules = ( | |
48455 | + "mod_rewrite", | |
48456 | + "mod_setenv", | |
48457 | + "mod_secdownload", | |
48458 | + "mod_access", | |
48459 | + "mod_auth", | |
48460 | + "mod_status", | |
48461 | + "mod_expire", | |
48462 | + "mod_redirect", | |
48463 | + "mod_fastcgi", | |
48464 | + "mod_cgi" ) | |
48465 | + | |
48466 | +server.indexfiles = ( "index.php", "index.html", | |
48467 | + "index.htm", "default.htm" ) | |
48468 | + | |
48469 | + | |
48470 | +######################## MODULE CONFIG ############################ | |
48471 | + | |
48472 | +mimetype.assign = ( ".png" => "image/png", | |
48473 | + ".jpg" => "image/jpeg", | |
48474 | + ".jpeg" => "image/jpeg", | |
48475 | + ".gif" => "image/gif", | |
48476 | + ".html" => "text/html", | |
48477 | + ".htm" => "text/html", | |
48478 | + ".pdf" => "application/pdf", | |
48479 | + ".swf" => "application/x-shockwave-flash", | |
48480 | + ".spl" => "application/futuresplash", | |
48481 | + ".txt" => "text/plain", | |
48482 | + ".tar.gz" => "application/x-tgz", | |
48483 | + ".tgz" => "application/x-tgz", | |
48484 | + ".gz" => "application/x-gzip", | |
48485 | + ".c" => "text/plain", | |
48486 | + ".conf" => "text/plain" ) | |
48487 | + | |
48488 | +fastcgi.debug = 0 | |
48489 | +fastcgi.server = ( ".php" => ( ( "host" => "127.0.0.1", "port" => 1026, "broken-scriptfilename" => "enable" ) ), | |
48490 | + "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) ) | |
48491 | + ) | |
48492 | + | |
48493 | + | |
48494 | +cgi.assign = ( ".pl" => "/usr/bin/perl", | |
48495 | + ".cgi" => "/usr/bin/perl", | |
48496 | + ".py" => "/usr/bin/python" ) | |
48497 | + | |
48498 | +auth.backend = "plain" | |
48499 | +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user" | |
48500 | + | |
48501 | +auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd" | |
48502 | + | |
48503 | +$HTTP["host"] == "lowercase-auth" { | |
48504 | + auth.require = ( "/image.jpg" => | |
48505 | + ( | |
48506 | + "method" => "digest", | |
48507 | + "realm" => "download archiv", | |
48508 | + "require" => "valid-user" | |
48509 | + ) | |
48510 | + ) | |
48511 | +} | |
48512 | + | |
48513 | +$HTTP["host"] == "lowercase-deny" { | |
48514 | + url.access-deny = ( ".jpg") | |
48515 | +} | |
48516 | + | |
48517 | +$HTTP["host"] == "lowercase-exclude" { | |
48518 | + static-file.exclude-extensions = ( ".jpg" ) | |
48519 | +} | |
1175ccec | 48520 | --- ../lighttpd-1.4.11/tests/lowercase.t 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 48521 | +++ lighttpd-1.4.12/tests/lowercase.t 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
48522 | @@ -0,0 +1,94 @@ |
48523 | +#!/usr/bin/env perl | |
48524 | +BEGIN { | |
48525 | + # add current source dir to the include-path | |
48526 | + # we need this for make distcheck | |
48527 | + (my $srcdir = $0) =~ s#/[^/]+$#/#; | |
48528 | + unshift @INC, $srcdir; | |
48529 | +} | |
48530 | + | |
48531 | +use strict; | |
48532 | +use IO::Socket; | |
48533 | +use Test::More tests => 10; | |
48534 | +use LightyTest; | |
48535 | + | |
48536 | +my $tf = LightyTest->new(); | |
48537 | +my $t; | |
48538 | + | |
48539 | +$tf->{CONFIGFILE} = 'lowercase.conf'; | |
48540 | + | |
48541 | +ok($tf->start_proc == 0, "Starting lighttpd") or die(); | |
48542 | + | |
48543 | +## check if lower-casing works | |
48544 | + | |
48545 | +$t->{REQUEST} = ( <<EOF | |
48546 | +GET /image.JPG HTTP/1.0 | |
48547 | +EOF | |
48548 | + ); | |
48549 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
48550 | +ok($tf->handle_http($t) == 0, 'uppercase access'); | |
48551 | + | |
48552 | +$t->{REQUEST} = ( <<EOF | |
48553 | +GET /image.jpg HTTP/1.0 | |
48554 | +EOF | |
48555 | + ); | |
48556 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
48557 | +ok($tf->handle_http($t) == 0, 'lowercase access'); | |
48558 | + | |
48559 | +## check that mod-auth works | |
48560 | + | |
48561 | +$t->{REQUEST} = ( <<EOF | |
48562 | +GET /image.JPG HTTP/1.0 | |
48563 | +Host: lowercase-auth | |
48564 | +EOF | |
48565 | + ); | |
48566 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; | |
48567 | +ok($tf->handle_http($t) == 0, 'uppercase access'); | |
48568 | + | |
48569 | +$t->{REQUEST} = ( <<EOF | |
48570 | +GET /image.jpg HTTP/1.0 | |
48571 | +Host: lowercase-auth | |
48572 | +EOF | |
48573 | + ); | |
48574 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; | |
48575 | +ok($tf->handle_http($t) == 0, 'lowercase access'); | |
48576 | + | |
48577 | + | |
48578 | +## check that mod-staticfile exclude works | |
48579 | +$t->{REQUEST} = ( <<EOF | |
48580 | +GET /image.JPG HTTP/1.0 | |
48581 | +Host: lowercase-exclude | |
48582 | +EOF | |
48583 | + ); | |
48584 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; | |
48585 | +ok($tf->handle_http($t) == 0, 'upper case access to staticfile.exclude-extension'); | |
48586 | + | |
48587 | +$t->{REQUEST} = ( <<EOF | |
48588 | +GET /image.jpg HTTP/1.0 | |
48589 | +Host: lowercase-exclude | |
48590 | +EOF | |
48591 | + ); | |
48592 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; | |
48593 | +ok($tf->handle_http($t) == 0, 'lowercase access'); | |
48594 | + | |
48595 | + | |
48596 | +## check that mod-access exclude works | |
48597 | +$t->{REQUEST} = ( <<EOF | |
48598 | +GET /image.JPG HTTP/1.0 | |
48599 | +Host: lowercase-deny | |
48600 | +EOF | |
48601 | + ); | |
48602 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; | |
48603 | +ok($tf->handle_http($t) == 0, 'uppercase access to url.access-deny protected location'); | |
48604 | + | |
48605 | +$t->{REQUEST} = ( <<EOF | |
48606 | +GET /image.jpg HTTP/1.0 | |
48607 | +Host: lowercase-deny | |
48608 | +EOF | |
48609 | + ); | |
48610 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; | |
48611 | +ok($tf->handle_http($t) == 0, 'lowercase access'); | |
48612 | + | |
48613 | + | |
48614 | + | |
48615 | +ok($tf->stop_proc == 0, "Stopping lighttpd"); | |
48616 | + | |
1175ccec | 48617 | --- ../lighttpd-1.4.11/tests/mod-fastcgi.t 2006-03-09 15:30:45.000000000 +0200 |
36e2a29e | 48618 | +++ lighttpd-1.4.12/tests/mod-fastcgi.t 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 ER |
48619 | @@ -7,7 +7,7 @@ |
48620 | } | |
f673a614 | 48621 | |
f26f9fd5 ER |
48622 | use strict; |
48623 | -use Test::More tests => 47; | |
48624 | +use Test::More tests => 49; | |
48625 | use LightyTest; | |
f673a614 | 48626 | |
f26f9fd5 ER |
48627 | my $tf = LightyTest->new(); |
48628 | @@ -15,7 +15,7 @@ | |
48629 | my $t; | |
f673a614 | 48630 | |
f26f9fd5 ER |
48631 | SKIP: { |
48632 | - skip "no PHP running on port 1026", 30 unless $tf->listening_on(1026); | |
48633 | + skip "no PHP running on port 1026", 29 unless $tf->listening_on(1026); | |
f673a614 | 48634 | |
f26f9fd5 | 48635 | ok($tf->start_proc == 0, "Starting lighttpd") or die(); |
f673a614 | 48636 | |
2519e6e5 ER |
48637 | @@ -223,7 +223,7 @@ |
48638 | } | |
48639 | ||
48640 | SKIP: { | |
48641 | - skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php"; | |
48642 | + skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php"; | |
48643 | $tf->{CONFIGFILE} = 'fastcgi-13.conf'; | |
48644 | ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die(); | |
48645 | $t->{REQUEST} = ( <<EOF | |
f26f9fd5 ER |
48646 | @@ -285,6 +285,34 @@ |
48647 | $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'test123' } ]; | |
48648 | ok($tf->handle_http($t) == 0, 'line-ending \r\n + \r\n'); | |
f673a614 | 48649 | |
f26f9fd5 ER |
48650 | + # X-LIGHTTPD-send-file |
48651 | + $t->{REQUEST} = ( <<EOF | |
48652 | +GET /index.fcgi?x-lighttpd-send-file HTTP/1.0 | |
48653 | +Host: www.example.org | |
48654 | +EOF | |
48655 | + ); | |
48656 | + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?> | |
48657 | +' } ]; | |
48658 | + ok($tf->handle_http($t) == 0, 'X-LIGHTTPD-send-file'); | |
48659 | + # X-Sendfile | |
48660 | + $t->{REQUEST} = ( <<EOF | |
48661 | +GET /index.fcgi?xsendfile HTTP/1.0 | |
48662 | +Host: www.example.org | |
48663 | +EOF | |
48664 | + ); | |
48665 | + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?> | |
48666 | +' } ]; | |
48667 | + ok($tf->handle_http($t) == 0, 'X-Sendfile'); | |
f673a614 | 48668 | + |
f26f9fd5 ER |
48669 | + $t->{REQUEST} = ( <<EOF |
48670 | +GET /index.fcgi?xsendfile-mixed-case HTTP/1.0 | |
48671 | +Host: www.example.org | |
48672 | +EOF | |
48673 | + ); | |
48674 | + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?> | |
48675 | +' } ]; | |
48676 | + ok($tf->handle_http($t) == 0, 'X-SeNdFiLe in mixed case'); | |
f673a614 | 48677 | + |
f26f9fd5 ER |
48678 | $t->{REQUEST} = ( <<EOF |
48679 | GET /index.fcgi?die-at-end HTTP/1.0 | |
48680 | Host: www.example.org | |
1175ccec | 48681 | --- ../lighttpd-1.4.11/tests/mod-proxy.t 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 48682 | +++ lighttpd-1.4.12/tests/mod-proxy.t 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
48683 | @@ -0,0 +1,173 @@ |
48684 | +#!/usr/bin/env perl | |
48685 | +BEGIN { | |
48686 | + # add current source dir to the include-path | |
48687 | + # we need this for make distcheck | |
48688 | + (my $srcdir = $0) =~ s#/[^/]+$#/#; | |
48689 | + unshift @INC, $srcdir; | |
48690 | +} | |
48691 | + | |
48692 | +use strict; | |
48693 | +use IO::Socket; | |
48694 | +use Test::More tests => 21; | |
48695 | +use LightyTest; | |
48696 | + | |
48697 | +my $tf_proxy = LightyTest->new(); | |
48698 | +my $tf_backend1 = LightyTest->new(); | |
48699 | +my $tf_backend2 = LightyTest->new(); | |
48700 | + | |
48701 | +my $t; | |
48702 | + | |
48703 | +## we need two procs | |
48704 | +## 1. the real webserver | |
48705 | +## 2. the proxy server | |
48706 | + | |
48707 | +$tf_proxy->{PORT} = 2048; | |
48708 | +$tf_proxy->{CONFIGFILE} = 'proxy.conf'; | |
48709 | +$tf_proxy->{LIGHTTPD_PIDFILE} = $tf_proxy->{SRCDIR}.'/tmp/lighttpd/lighttpd-proxy.pid'; | |
48710 | + | |
48711 | +$tf_backend1->{PORT} = 2050; | |
48712 | +$tf_backend1->{CONFIGFILE} = 'proxy-backend-1.conf'; | |
48713 | +$tf_backend1->{LIGHTTPD_PIDFILE} = $tf_backend1->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-1.pid'; | |
48714 | + | |
48715 | +$tf_backend2->{PORT} = 2051; | |
48716 | +$tf_backend2->{CONFIGFILE} = 'proxy-backend-2.conf'; | |
48717 | +$tf_backend2->{LIGHTTPD_PIDFILE} = $tf_backend2->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-2.pid'; | |
48718 | + | |
48719 | + | |
48720 | +ok($tf_backend1->start_proc == 0, "Starting lighttpd") or die(); | |
48721 | + | |
48722 | +ok($tf_proxy->start_proc == 0, "Starting lighttpd as proxy") or die(); | |
48723 | + | |
48724 | +sleep(1); | |
48725 | + | |
48726 | +$t->{REQUEST} = ( <<EOF | |
48727 | +GET /index.html HTTP/1.0 | |
48728 | +Host: www.example.org | |
48729 | +EOF | |
48730 | + ); | |
48731 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; | |
48732 | +ok($tf_proxy->handle_http($t) == 0, 'valid request'); | |
48733 | + | |
48734 | +$t->{REQUEST} = ( <<EOF | |
48735 | +GET /index.html HTTP/1.0 | |
48736 | +Host: www.example.org | |
48737 | +EOF | |
48738 | + ); | |
48739 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Server' => 'proxy-backend-1' } ]; | |
48740 | +ok($tf_proxy->handle_http($t) == 0, 'drop Server from real server'); | |
48741 | + | |
48742 | +$t->{REQUEST} = ( <<EOF | |
48743 | +GET /balance-rr/foo HTTP/1.0 | |
48744 | +Host: www.example.org | |
48745 | +EOF | |
48746 | + ); | |
48747 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ]; | |
48748 | +ok($tf_proxy->handle_http($t) == 0, 'balance rr - one backend'); | |
48749 | + | |
48750 | +$t->{REQUEST} = ( <<EOF | |
48751 | +GET /balance-rr/foo HTTP/1.0 | |
48752 | +Host: www.example.org | |
48753 | +EOF | |
48754 | + ); | |
48755 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ]; | |
48756 | +ok($tf_proxy->handle_http($t) == 0, 'balance rr - one host down, failover'); | |
48757 | + | |
48758 | +$t->{REQUEST} = ( <<EOF | |
48759 | +GET /balance-fair/foo HTTP/1.0 | |
48760 | +Host: www.example.org | |
48761 | +EOF | |
48762 | + ); | |
48763 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ]; | |
48764 | +ok($tf_proxy->handle_http($t) == 0, 'balance fair - one backend'); | |
48765 | + | |
48766 | +## backend 2 starting | |
48767 | +ok($tf_backend2->start_proc == 0, "Starting second proxy backend") or die(); | |
48768 | + | |
48769 | +$t->{REQUEST} = ( <<EOF | |
48770 | +GET /balance-rr/foo HTTP/1.0 | |
48771 | +Host: www.example.org | |
48772 | +EOF | |
48773 | + ); | |
48774 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ]; | |
48775 | +ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 1'); | |
48776 | + | |
48777 | +$t->{REQUEST} = ( <<EOF | |
48778 | +GET /balance-rr/foo HTTP/1.0 | |
48779 | +Host: www.example.org | |
48780 | +EOF | |
48781 | + ); | |
48782 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ]; | |
48783 | +ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 2'); | |
48784 | + | |
48785 | +$t->{REQUEST} = ( <<EOF | |
48786 | +GET /balance-hash/foo HTTP/1.0 | |
48787 | +Host: www.example.org | |
48788 | +EOF | |
48789 | + ); | |
48790 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ]; | |
48791 | +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1'); | |
48792 | + | |
48793 | +$t->{REQUEST} = ( <<EOF | |
48794 | +GET /balance-hash/foo HTTP/1.0 | |
48795 | +Host: www.example.org | |
48796 | +EOF | |
48797 | + ); | |
48798 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ]; | |
48799 | +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1 - same URL'); | |
48800 | + | |
48801 | +$t->{REQUEST} = ( <<EOF | |
48802 | +GET /balance-hash/bar HTTP/1.0 | |
48803 | +Host: www.example.org | |
48804 | +EOF | |
48805 | + ); | |
48806 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ]; | |
48807 | +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2'); | |
48808 | + | |
48809 | +$t->{REQUEST} = ( <<EOF | |
48810 | +GET /balance-hash/bar HTTP/1.0 | |
48811 | +Host: www.example.org | |
48812 | +EOF | |
48813 | + ); | |
48814 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ]; | |
48815 | +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2 - same URL'); | |
48816 | + | |
48817 | +## backend 1 stopping, failover | |
48818 | +ok($tf_backend1->stop_proc == 0, "Stopping backend 1"); | |
48819 | + | |
48820 | +$t->{REQUEST} = ( <<EOF | |
48821 | +GET /balance-hash/foo HTTP/1.0 | |
48822 | +Host: www.example.org | |
48823 | +EOF | |
48824 | + ); | |
48825 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ]; | |
48826 | +ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2'); | |
48827 | + | |
48828 | +$t->{REQUEST} = ( <<EOF | |
48829 | +GET /balance-hash/bar HTTP/1.0 | |
48830 | +Host: www.example.org | |
48831 | +EOF | |
48832 | + ); | |
48833 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ]; | |
48834 | +ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2 - same URL'); | |
48835 | + | |
48836 | +$t->{REQUEST} = ( <<EOF | |
48837 | +GET /balance-rr/foo HTTP/1.0 | |
48838 | +Host: www.example.org | |
48839 | +EOF | |
48840 | + ); | |
48841 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ]; | |
48842 | +ok($tf_proxy->handle_http($t) == 0, 'balance rr - failover to backend 2'); | |
48843 | + | |
48844 | +$t->{REQUEST} = ( <<EOF | |
48845 | +GET /balance-fair/foo HTTP/1.0 | |
48846 | +Host: www.example.org | |
48847 | +EOF | |
48848 | + ); | |
48849 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ]; | |
48850 | +ok($tf_proxy->handle_http($t) == 0, 'balance fair - failover to backend 2'); | |
48851 | + | |
48852 | + | |
48853 | +ok($tf_backend2->stop_proc == 0, "Stopping lighttpd"); | |
48854 | + | |
48855 | +ok($tf_proxy->stop_proc == 0, "Stopping lighttpd proxy"); | |
48856 | + | |
1175ccec | 48857 | --- ../lighttpd-1.4.11/tests/proxy.conf 1970-01-01 03:00:00.000000000 +0300 |
36e2a29e | 48858 | +++ lighttpd-1.4.12/tests/proxy.conf 2006-07-11 22:07:53.000000000 +0300 |
2519e6e5 ER |
48859 | @@ -0,0 +1,26 @@ |
48860 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48861 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd-proxy.pid" | |
48862 | +server.tag = "proxy" | |
48863 | + | |
48864 | +include "default.conf" | |
48865 | + | |
48866 | +## 127.0.0.1 and 127.0.0.2 are the same host | |
48867 | +proxy.server = ( | |
48868 | + "" => (( "host" => "127.0.0.1", | |
48869 | + "port" => 2050 ), | |
48870 | + ( "host" => "127.0.0.2", | |
48871 | + "port" => 2051 ) | |
48872 | + )) | |
48873 | + | |
48874 | +$HTTP["url"] =~ "^/balance-rr/" { | |
48875 | + proxy.balance = "round-robin" | |
48876 | +} | |
48877 | + | |
48878 | +$HTTP["url"] =~ "^/balance-hash/" { | |
48879 | + proxy.balance = "hash" | |
48880 | +} | |
48881 | + | |
48882 | +$HTTP["url"] =~ "^/balance-fair/" { | |
48883 | + proxy.balance = "fair" | |
48884 | +} | |
48885 | + | |
1175ccec | 48886 | --- ../lighttpd-1.4.11/tests/var-include.conf 2005-08-27 17:44:19.000000000 +0300 |
36e2a29e | 48887 | +++ lighttpd-1.4.12/tests/var-include.conf 2006-07-11 22:07:53.000000000 +0300 |
f26f9fd5 ER |
48888 | @@ -2,15 +2,15 @@ |
48889 | debug.log-request-handling = "enable" | |
48890 | debug.log-condition-handling = "enable" | |
f673a614 | 48891 | |
f26f9fd5 ER |
48892 | -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" |
48893 | -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid" | |
48894 | +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48895 | +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" | |
f673a614 | 48896 | |
f26f9fd5 ER |
48897 | ## bind to port (default: 80) |
48898 | server.port = 2048 | |
f673a614 | 48899 | |
f26f9fd5 ER |
48900 | ## bind to localhost (default: all interfaces) |
48901 | server.bind = "localhost" | |
48902 | -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log" | |
48903 | +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log" | |
48904 | server.name = "www.example.org" | |
48905 | server.tag = "Apache 1.3.29" | |
f673a614 | 48906 | |
f26f9fd5 ER |
48907 | @@ -21,19 +21,19 @@ |
48908 | ######################## MODULE CONFIG ############################ | |
f673a614 | 48909 | |
f673a614 | 48910 | |
f26f9fd5 ER |
48911 | -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log" |
48912 | +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log" | |
f673a614 | 48913 | |
f26f9fd5 | 48914 | mimetype.assign = ( ".html" => "text/html" ) |
f673a614 | 48915 | |
f26f9fd5 | 48916 | url.redirect = ("^" => "/default") |
f673a614 | 48917 | |
f26f9fd5 ER |
48918 | $HTTP["host"] == "www.example.org" { |
48919 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48920 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48921 | server.name = "www.example.org" | |
48922 | url.redirect = ("^" => "/redirect") | |
48923 | } | |
48924 | $HTTP["host"] == "test.example.org" { | |
48925 | - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/" | |
48926 | + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" | |
48927 | server.name = "test.example.org" | |
48928 | var.myvar = "good" | |
48929 | var.one = 1 |