]>
Commit | Line | Data |
---|---|---|
1530c5cf ER |
1 | # Revision 2711 |
2 | Index: src/mod_cgi.c | |
3 | =================================================================== | |
4 | --- src/mod_cgi.c (.../tags/lighttpd-1.4.25) | |
5 | +++ src/mod_cgi.c (.../branches/lighttpd-1.4.x) | |
6 | @@ -747,6 +747,8 @@ | |
7 | } | |
8 | ||
9 | if (pipe(from_cgi_fds)) { | |
10 | + close(to_cgi_fds[0]); | |
11 | + close(to_cgi_fds[1]); | |
12 | log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno)); | |
13 | return -1; | |
14 | } | |
15 | @@ -1035,6 +1037,10 @@ | |
16 | case -1: | |
17 | /* error */ | |
18 | log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed:", strerror(errno)); | |
19 | + close(from_cgi_fds[0]); | |
20 | + close(from_cgi_fds[1]); | |
21 | + close(to_cgi_fds[0]); | |
22 | + close(to_cgi_fds[1]); | |
23 | return -1; | |
24 | break; | |
25 | default: { | |
26 | @@ -1181,6 +1187,7 @@ | |
27 | plugin_config *s = p->config_storage[0]; | |
28 | ||
29 | PATCH(cgi); | |
30 | + PATCH(execute_x_only); | |
31 | ||
32 | /* skip the first, the global context */ | |
33 | for (i = 1; i < srv->config_context->used; i++) { | |
34 | Index: src/base.h | |
35 | =================================================================== | |
36 | --- src/base.h (.../tags/lighttpd-1.4.25) | |
37 | +++ src/base.h (.../branches/lighttpd-1.4.x) | |
38 | @@ -431,7 +431,6 @@ | |
39 | ||
40 | #ifdef USE_OPENSSL | |
41 | SSL *ssl; | |
42 | - buffer *ssl_error_want_reuse_buffer; | |
43 | # ifndef OPENSSL_NO_TLSEXT | |
44 | buffer *tlsext_server_name; | |
45 | # endif | |
46 | Index: src/mod_rewrite.c | |
47 | =================================================================== | |
48 | --- src/mod_rewrite.c (.../tags/lighttpd-1.4.25) | |
49 | +++ src/mod_rewrite.c (.../branches/lighttpd-1.4.x) | |
50 | @@ -394,7 +394,7 @@ | |
51 | buffer_reset(con->request.uri); | |
52 | ||
53 | start = 0; | |
54 | - for (k = 0; k < pattern_len; k++) { | |
55 | + for (k = 0; k+1 < pattern_len; k++) { | |
56 | if (pattern[k] == '$' || pattern[k] == '%') { | |
57 | /* got one */ | |
58 | ||
9d2ca5f8 ER |
59 | Index: src/connections.c |
60 | =================================================================== | |
61 | --- src/connections.c (.../tags/lighttpd-1.4.25) | |
62 | +++ src/connections.c (.../branches/lighttpd-1.4.x) | |
1530c5cf ER |
63 | @@ -192,40 +192,42 @@ |
64 | ||
65 | static int connection_handle_read_ssl(server *srv, connection *con) { | |
66 | #ifdef USE_OPENSSL | |
67 | - int r, ssl_err, len, count = 0; | |
68 | + int r, ssl_err, len, count = 0, read_offset, toread; | |
69 | buffer *b = NULL; | |
70 | ||
71 | if (!con->conf.is_ssl) return -1; | |
72 | ||
73 | - /* don't resize the buffer if we were in SSL_ERROR_WANT_* */ | |
74 | - | |
75 | ERR_clear_error(); | |
76 | do { | |
77 | - if (!con->ssl_error_want_reuse_buffer) { | |
78 | - b = buffer_init(); | |
79 | - buffer_prepare_copy(b, SSL_pending(con->ssl) + (16 * 1024)); /* the pending bytes + 16kb */ | |
80 | + if (NULL != con->read_queue->last) { | |
81 | + b = con->read_queue->last->mem; | |
82 | + } | |
83 | ||
84 | + if (NULL == b || b->size - b->used < 1024) { | |
85 | + b = chunkqueue_get_append_buffer(con->read_queue); | |
86 | + len = SSL_pending(con->ssl); | |
87 | + if (len < 4*1024) len = 4*1024; /* always alloc >= 4k buffer */ | |
88 | + buffer_prepare_copy(b, len + 1); | |
89 | + | |
90 | /* overwrite everything with 0 */ | |
91 | memset(b->ptr, 0, b->size); | |
92 | - } else { | |
93 | - b = con->ssl_error_want_reuse_buffer; | |
94 | } | |
95 | ||
96 | - len = SSL_read(con->ssl, b->ptr, b->size - 1); | |
97 | - con->ssl_error_want_reuse_buffer = NULL; /* reuse it only once */ | |
98 | + read_offset = (b->used > 0) ? b->used - 1 : 0; | |
99 | + toread = b->size - 1 - read_offset; | |
100 | ||
101 | + len = SSL_read(con->ssl, b->ptr + read_offset, toread); | |
102 | + | |
103 | if (len > 0) { | |
104 | - b->used = len; | |
105 | + if (b->used > 0) b->used--; | |
106 | + b->used += len; | |
107 | b->ptr[b->used++] = '\0'; | |
108 | ||
109 | - /* we move the buffer to the chunk-queue, no need to free it */ | |
110 | + con->bytes_read += len; | |
111 | ||
112 | - chunkqueue_append_buffer_weak(con->read_queue, b); | |
113 | count += len; | |
114 | - con->bytes_read += len; | |
115 | - b = NULL; | |
116 | } | |
117 | - } while (len > 0 && count < MAX_READ_LIMIT); | |
118 | + } while (len == toread && count < MAX_READ_LIMIT); | |
119 | ||
120 | ||
121 | if (len < 0) { | |
122 | @@ -234,11 +236,11 @@ | |
123 | case SSL_ERROR_WANT_READ: | |
124 | case SSL_ERROR_WANT_WRITE: | |
125 | con->is_readable = 0; | |
126 | - con->ssl_error_want_reuse_buffer = b; | |
127 | ||
128 | - b = NULL; | |
129 | + /* the manual says we have to call SSL_read with the same arguments next time. | |
130 | + * we ignore this restriction; no one has complained about it in 1.5 yet, so it probably works anyway. | |
131 | + */ | |
132 | ||
133 | - /* we have to steal the buffer from the queue-queue */ | |
134 | return 0; | |
135 | case SSL_ERROR_SYSCALL: | |
136 | /** | |
137 | @@ -297,16 +299,11 @@ | |
138 | ||
139 | connection_set_state(srv, con, CON_STATE_ERROR); | |
140 | ||
141 | - buffer_free(b); | |
142 | - | |
143 | return -1; | |
144 | } else if (len == 0) { | |
145 | con->is_readable = 0; | |
146 | /* the other end close the connection -> KEEP-ALIVE */ | |
147 | ||
148 | - /* pipelining */ | |
149 | - buffer_free(b); | |
150 | - | |
151 | return -2; | |
152 | } | |
153 | ||
154 | @@ -321,26 +318,41 @@ | |
155 | static int connection_handle_read(server *srv, connection *con) { | |
156 | int len; | |
157 | buffer *b; | |
158 | - int toread; | |
159 | + int toread, read_offset; | |
160 | ||
161 | if (con->conf.is_ssl) { | |
162 | return connection_handle_read_ssl(srv, con); | |
163 | } | |
164 | ||
165 | + b = (NULL != con->read_queue->last) ? con->read_queue->last->mem : NULL; | |
166 | + | |
167 | + /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells | |
168 | + * us more than 4kb is available | |
169 | + * if FIONREAD doesn't signal a big chunk we fill the previous buffer | |
170 | + * if it has >= 1kb free | |
171 | + */ | |
172 | #if defined(__WIN32) | |
173 | - b = chunkqueue_get_append_buffer(con->read_queue); | |
174 | - buffer_prepare_copy(b, 4 * 1024); | |
175 | - len = recv(con->fd, b->ptr, b->size - 1, 0); | |
176 | -#else | |
177 | - if (ioctl(con->fd, FIONREAD, &toread) || toread == 0) { | |
178 | + if (NULL == b || b->size - b->used < 1024) { | |
179 | b = chunkqueue_get_append_buffer(con->read_queue); | |
180 | buffer_prepare_copy(b, 4 * 1024); | |
181 | + } | |
182 | + | |
183 | + read_offset = (b->used == 0) ? 0 : b->used - 1; | |
184 | + len = recv(con->fd, b->ptr + read_offset, b->size - 1 - read_offset, 0); | |
185 | +#else | |
186 | + if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) { | |
187 | + if (NULL == b || b->size - b->used < 1024) { | |
188 | + b = chunkqueue_get_append_buffer(con->read_queue); | |
189 | + buffer_prepare_copy(b, 4 * 1024); | |
190 | + } | |
191 | } else { | |
192 | if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT; | |
193 | b = chunkqueue_get_append_buffer(con->read_queue); | |
194 | buffer_prepare_copy(b, toread + 1); | |
195 | } | |
196 | - len = read(con->fd, b->ptr, b->size - 1); | |
197 | + | |
198 | + read_offset = (b->used == 0) ? 0 : b->used - 1; | |
199 | + len = read(con->fd, b->ptr + read_offset, b->size - 1 - read_offset); | |
200 | #endif | |
201 | ||
202 | if (len < 0) { | |
203 | @@ -374,7 +386,8 @@ | |
204 | con->is_readable = 0; | |
205 | } | |
206 | ||
207 | - b->used = len; | |
208 | + if (b->used > 0) b->used--; | |
209 | + b->used += len; | |
210 | b->ptr[b->used++] = '\0'; | |
211 | ||
212 | con->bytes_read += len; | |
213 | @@ -850,13 +863,6 @@ | |
214 | /* The cond_cache gets reset in response.c */ | |
215 | /* config_cond_cache_reset(srv, con); */ | |
216 | ||
217 | -#ifdef USE_OPENSSL | |
218 | - if (con->ssl_error_want_reuse_buffer) { | |
219 | - buffer_free(con->ssl_error_want_reuse_buffer); | |
220 | - con->ssl_error_want_reuse_buffer = NULL; | |
221 | - } | |
222 | -#endif | |
223 | - | |
224 | con->header_len = 0; | |
225 | con->in_error_handler = 0; | |
226 | ||
227 | @@ -945,62 +951,50 @@ | |
9d2ca5f8 ER |
228 | last_chunk = NULL; |
229 | last_offset = 0; | |
230 | ||
231 | - for (c = cq->first; !last_chunk && c; c = c->next) { | |
232 | + for (c = cq->first; c; c = c->next) { | |
233 | buffer b; | |
234 | size_t i; | |
235 | ||
236 | b.ptr = c->mem->ptr + c->offset; | |
237 | b.used = c->mem->used - c->offset; | |
238 | + if (b.used > 0) b.used--; /* buffer "used" includes terminating zero */ | |
239 | ||
240 | - for (i = 0; !last_chunk && i < b.used; i++) { | |
241 | + for (i = 0; i < b.used; i++) { | |
242 | char ch = b.ptr[i]; | |
243 | - size_t have_chars = 0; | |
244 | ||
245 | - switch (ch) { | |
246 | - case '\r': | |
247 | - /* we have to do a 4 char lookup */ | |
248 | - have_chars = b.used - i - 1; | |
249 | + if ('\r' == ch) { | |
250 | + /* chec if \n\r\n follows */ | |
251 | + size_t j = i+1; | |
252 | + chunk *cc = c; | |
253 | + const char header_end[] = "\r\n\r\n"; | |
254 | + int header_end_match_pos = 1; | |
255 | ||
256 | - if (have_chars >= 4) { | |
257 | - /* all chars are in this buffer */ | |
258 | + for ( ; cc; cc = cc->next, j = 0 ) { | |
259 | + buffer bb; | |
260 | + bb.ptr = cc->mem->ptr + cc->offset; | |
261 | + bb.used = cc->mem->used - cc->offset; | |
262 | + if (bb.used > 0) bb.used--; /* buffer "used" includes terminating zero */ | |
263 | ||
264 | - if (0 == strncmp(b.ptr + i, "\r\n\r\n", 4)) { | |
265 | - /* found */ | |
266 | - last_chunk = c; | |
267 | - last_offset = i + 4; | |
268 | + for ( ; j < bb.used; j++) { | |
269 | + ch = bb.ptr[j]; | |
270 | ||
271 | - break; | |
272 | - } | |
273 | - } else { | |
274 | - chunk *lookahead_chunk = c->next; | |
275 | - size_t missing_chars; | |
276 | - /* looks like the following chars are not in the same chunk */ | |
277 | - | |
278 | - missing_chars = 4 - have_chars; | |
279 | - | |
280 | - if (lookahead_chunk && lookahead_chunk->type == MEM_CHUNK) { | |
281 | - /* is the chunk long enough to contain the other chars ? */ | |
282 | - | |
283 | - if (lookahead_chunk->mem->used > missing_chars) { | |
284 | - if (0 == strncmp(b.ptr + i, "\r\n\r\n", have_chars) && | |
285 | - 0 == strncmp(lookahead_chunk->mem->ptr, "\r\n\r\n" + have_chars, missing_chars)) { | |
286 | - | |
287 | - last_chunk = lookahead_chunk; | |
288 | - last_offset = missing_chars; | |
289 | - | |
290 | - break; | |
291 | + if (ch == header_end[header_end_match_pos]) { | |
292 | + header_end_match_pos++; | |
293 | + if (4 == header_end_match_pos) { | |
294 | + last_chunk = cc; | |
295 | + last_offset = j+1; | |
296 | + goto found_header_end; | |
297 | } | |
298 | } else { | |
299 | - /* a splited \r \n */ | |
300 | - break; | |
301 | + goto reset_search; | |
302 | } | |
303 | } | |
304 | } | |
305 | - | |
306 | - break; | |
307 | } | |
308 | +reset_search: ; | |
309 | } | |
310 | } | |
311 | +found_header_end: | |
312 | ||
313 | /* found */ | |
314 | if (last_chunk) { | |
1530c5cf ER |
315 | @@ -1140,8 +1134,15 @@ |
316 | } else { | |
317 | buffer *b; | |
318 | ||
319 | - b = chunkqueue_get_append_buffer(dst_cq); | |
320 | - buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead); | |
321 | + if (dst_cq->last && | |
322 | + dst_cq->last->type == MEM_CHUNK) { | |
323 | + b = dst_cq->last->mem; | |
324 | + } else { | |
325 | + b = chunkqueue_get_append_buffer(dst_cq); | |
326 | + /* prepare buffer size for remaining POST data; is < 64kb */ | |
327 | + buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in + 1); | |
328 | + } | |
329 | + buffer_append_string_len(b, c->mem->ptr + c->offset, toRead); | |
330 | } | |
331 | ||
332 | c->offset += toRead; | |
333 | Index: src/chunk.c | |
334 | =================================================================== | |
335 | --- src/chunk.c (.../tags/lighttpd-1.4.25) | |
336 | +++ src/chunk.c (.../branches/lighttpd-1.4.x) | |
337 | @@ -197,8 +197,6 @@ | |
338 | int chunkqueue_append_buffer_weak(chunkqueue *cq, buffer *mem) { | |
339 | chunk *c; | |
340 | ||
341 | - if (mem->used == 0) return 0; | |
342 | - | |
343 | c = chunkqueue_get_unused_chunk(cq); | |
344 | c->type = MEM_CHUNK; | |
345 | c->offset = 0; | |
346 | Index: src/mod_proxy.c | |
347 | =================================================================== | |
348 | --- src/mod_proxy.c (.../tags/lighttpd-1.4.25) | |
349 | +++ src/mod_proxy.c (.../branches/lighttpd-1.4.x) | |
350 | @@ -1047,12 +1047,33 @@ | |
351 | * | |
352 | */ | |
353 | ||
354 | - proxy_connection_close(srv, hctx); | |
355 | - joblist_append(srv, con); | |
356 | + if (hctx->host) { | |
357 | + hctx->host->is_disabled = 1; | |
358 | + hctx->host->disable_ts = srv->cur_ts; | |
359 | + log_error_write(srv, __FILE__, __LINE__, "sbdd", "proxy-server disabled:", | |
360 | + hctx->host->host, | |
361 | + hctx->host->port, | |
362 | + hctx->fd); | |
363 | ||
364 | - con->http_status = 503; | |
365 | - con->mode = DIRECT; | |
366 | + /* disable this server */ | |
367 | + hctx->host->is_disabled = 1; | |
368 | + hctx->host->disable_ts = srv->cur_ts; | |
369 | ||
370 | + proxy_connection_close(srv, hctx); | |
371 | + | |
372 | + /* reset the enviroment and restart the sub-request */ | |
373 | + buffer_reset(con->physical.path); | |
374 | + con->mode = DIRECT; | |
375 | + | |
376 | + joblist_append(srv, con); | |
377 | + } else { | |
378 | + proxy_connection_close(srv, hctx); | |
379 | + joblist_append(srv, con); | |
380 | + | |
381 | + con->mode = DIRECT; | |
382 | + con->http_status = 503; | |
383 | + } | |
384 | + | |
385 | return HANDLER_FINISHED; | |
386 | } | |
387 | ||
388 | Index: src/mod_redirect.c | |
389 | =================================================================== | |
390 | --- src/mod_redirect.c (.../tags/lighttpd-1.4.25) | |
391 | +++ src/mod_redirect.c (.../branches/lighttpd-1.4.x) | |
392 | @@ -210,7 +210,7 @@ | |
393 | buffer_reset(p->location); | |
394 | ||
395 | start = 0; | |
396 | - for (k = 0; k < pattern_len; k++) { | |
397 | + for (k = 0; k + 1 < pattern_len; k++) { | |
398 | if (pattern[k] == '$' || pattern[k] == '%') { | |
399 | /* got one */ | |
400 | ||
401 | Index: src/mod_fastcgi.c | |
402 | =================================================================== | |
403 | --- src/mod_fastcgi.c (.../tags/lighttpd-1.4.25) | |
404 | +++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x) | |
405 | @@ -2307,6 +2307,9 @@ | |
406 | filename = pos; | |
407 | if (NULL == (range = strchr(pos, ' '))) { | |
408 | /* missing range */ | |
409 | + if (p->conf.debug) { | |
410 | + log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't find range after filename:", filename); | |
411 | + } | |
412 | return 1; | |
413 | } | |
414 | buffer_copy_string_len(srv->tmp_buf, filename, range - filename); | |
415 | @@ -2338,14 +2341,24 @@ | |
416 | char *rpos = NULL; | |
417 | errno = 0; | |
418 | begin_range = strtoll(range, &rpos, 10); | |
419 | - if (errno != 0 || begin_range < 0 || rpos == range) return 1; | |
420 | - if ('-' != *rpos++) return 1; | |
421 | + if (errno != 0 || begin_range < 0 || rpos == range) goto range_failed; | |
422 | + if ('-' != *rpos++) goto range_failed; | |
423 | if (rpos != pos) { | |
424 | range = rpos; | |
425 | end_range = strtoll(range, &rpos, 10); | |
426 | - if (errno != 0 || end_range < 0 || rpos == range) return 1; | |
427 | + if (errno != 0 || end_range < 0 || rpos == range) goto range_failed; | |
428 | } | |
429 | - if (rpos != pos) return 1; | |
430 | + if (rpos != pos) goto range_failed; | |
431 | + | |
432 | + goto range_success; | |
433 | + | |
434 | +range_failed: | |
435 | + if (p->conf.debug) { | |
436 | + log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't decode range after filename:", filename); | |
437 | + } | |
438 | + return 1; | |
439 | + | |
440 | +range_success: ; | |
441 | } | |
442 | ||
443 | /* no parameters accepted */ | |
444 | Index: src/mod_accesslog.c | |
445 | =================================================================== | |
446 | --- src/mod_accesslog.c (.../tags/lighttpd-1.4.25) | |
447 | +++ src/mod_accesslog.c (.../branches/lighttpd-1.4.x) | |
448 | @@ -788,6 +788,13 @@ | |
449 | buffer_append_string_len(b, CONST_STR_LEN("-")); | |
450 | } | |
451 | break; | |
452 | + case FORMAT_ENV: | |
453 | + if (NULL != (ds = (data_string *)array_get_element(con->environment, p->conf.parsed_format->ptr[j]->string->ptr))) { | |
454 | + accesslog_append_escaped(b, ds->value); | |
455 | + } else { | |
456 | + buffer_append_string_len(b, CONST_STR_LEN("-")); | |
457 | + } | |
458 | + break; | |
459 | case FORMAT_FILENAME: | |
460 | if (con->physical.path->used > 1) { | |
461 | buffer_append_string_buffer(b, con->physical.path); | |
462 | @@ -864,7 +871,6 @@ | |
463 | { 'A', FORMAT_LOCAL_ADDR }, | |
464 | { 'C', FORMAT_COOKIE }, | |
465 | { 'D', FORMAT_TIME_USED_MS }, | |
466 | - { 'e', FORMAT_ENV }, | |
467 | */ | |
468 | ||
469 | break; | |
9d2ca5f8 ER |
470 | Index: tests/request.t |
471 | =================================================================== | |
472 | --- tests/request.t (.../tags/lighttpd-1.4.25) | |
473 | +++ tests/request.t (.../branches/lighttpd-1.4.x) | |
474 | @@ -8,7 +8,7 @@ | |
475 | ||
476 | use strict; | |
477 | use IO::Socket; | |
478 | -use Test::More tests => 41; | |
479 | +use Test::More tests => 42; | |
480 | use LightyTest; | |
481 | ||
482 | my $tf = LightyTest->new(); | |
483 | @@ -389,5 +389,14 @@ | |
484 | $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304, '-Content-Length' => '' } ]; | |
485 | ok($tf->handle_http($t) == 0, 'Status 304 has no Content-Length (#1002)'); | |
486 | ||
487 | +$t->{REQUEST} = ( <<EOF | |
488 | +GET /12345.txt HTTP/1.0 | |
489 | +Host: 123.example.org | |
490 | +EOF | |
491 | + ); | |
492 | +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain' } ]; | |
493 | +$t->{SLOWREQUEST} = 1; | |
494 | +ok($tf->handle_http($t) == 0, 'GET, slow \\r\\n\\r\\n (#2105)'); | |
495 | + | |
496 | ok($tf->stop_proc == 0, "Stopping lighttpd"); | |
497 | ||
498 | Index: tests/LightyTest.pm | |
499 | =================================================================== | |
500 | --- tests/LightyTest.pm (.../tags/lighttpd-1.4.25) | |
501 | +++ tests/LightyTest.pm (.../branches/lighttpd-1.4.x) | |
502 | @@ -76,7 +76,7 @@ | |
503 | kill('TERM', $pid) or return -1; | |
504 | return -1 if ($pid != waitpid($pid, 0)); | |
505 | } else { | |
506 | - diag("Process not started, nothing to stop"); | |
507 | + diag("\nProcess not started, nothing to stop"); | |
508 | return -1; | |
509 | } | |
510 | ||
511 | @@ -98,7 +98,7 @@ | |
512 | return -1; | |
513 | } | |
514 | if (0 >= $timeout) { | |
515 | - diag("Timeout while trying to connect; killing child"); | |
516 | + diag("\nTimeout while trying to connect; killing child"); | |
517 | kill('TERM', $child); | |
518 | return -1; | |
519 | } | |
520 | @@ -128,10 +128,10 @@ | |
521 | } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'valgrind') { | |
522 | $cmdline = "valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --log-file=valgrind ".$cmdline; | |
523 | } | |
524 | - # diag("starting lighttpd at :".$self->{PORT}.", cmdline: ".$cmdline ); | |
525 | + # diag("\nstarting lighttpd at :".$self->{PORT}.", cmdline: ".$cmdline ); | |
526 | my $child = fork(); | |
527 | if (not defined $child) { | |
528 | - diag("Fork failed"); | |
529 | + diag("\nFork failed"); | |
530 | return -1; | |
531 | } | |
532 | if ($child == 0) { | |
533 | @@ -139,7 +139,7 @@ | |
534 | } | |
535 | ||
536 | if (0 != $self->wait_for_port_with_proc($self->{PORT}, $child)) { | |
537 | - diag(sprintf('The process %i is not up', $child)); | |
538 | + diag(sprintf('\nThe process %i is not up', $child)); | |
539 | return -1; | |
540 | } | |
541 | ||
542 | @@ -157,6 +157,7 @@ | |
543 | ||
544 | my @request = $t->{REQUEST}; | |
545 | my @response = $t->{RESPONSE}; | |
546 | + my $slow = defined $t->{SLOWREQUEST}; | |
547 | my $is_debug = $ENV{"TRACE_HTTP"}; | |
548 | ||
549 | my $remote = | |
550 | @@ -165,33 +166,56 @@ | |
551 | PeerPort => $self->{PORT}); | |
552 | ||
553 | if (not defined $remote) { | |
554 | - diag("connect failed: $!"); | |
555 | + diag("\nconnect failed: $!"); | |
556 | return -1; | |
557 | } | |
558 | ||
559 | $remote->autoflush(1); | |
560 | ||
561 | - diag("sending request header to ".$host.":".$self->{PORT}) if $is_debug; | |
562 | - foreach(@request) { | |
563 | - # pipeline requests | |
564 | - s/\r//g; | |
565 | - s/\n/$EOL/g; | |
566 | + if (!$slow) { | |
567 | + diag("\nsending request header to ".$host.":".$self->{PORT}) if $is_debug; | |
568 | + foreach(@request) { | |
569 | + # pipeline requests | |
570 | + s/\r//g; | |
571 | + s/\n/$EOL/g; | |
572 | ||
573 | - print $remote $_.$BLANK; | |
574 | - diag("<< ".$_) if $is_debug; | |
575 | + print $remote $_.$BLANK; | |
576 | + diag("\n<< ".$_) if $is_debug; | |
577 | + } | |
578 | + shutdown($remote, 1); # I've stopped writing data | |
579 | + } else { | |
580 | + diag("\nsending request header to ".$host.":".$self->{PORT}) if $is_debug; | |
581 | + foreach(@request) { | |
582 | + # pipeline requests | |
583 | + chomp; | |
584 | + s/\r//g; | |
585 | + s/\n/$EOL/g; | |
586 | + | |
587 | + print $remote $_; | |
588 | + diag("<< ".$_."\n") if $is_debug; | |
589 | + select(undef, undef, undef, 0.1); | |
590 | + print $remote "\015"; | |
591 | + select(undef, undef, undef, 0.1); | |
592 | + print $remote "\012"; | |
593 | + select(undef, undef, undef, 0.1); | |
594 | + print $remote "\015"; | |
595 | + select(undef, undef, undef, 0.1); | |
596 | + print $remote "\012"; | |
597 | + select(undef, undef, undef, 0.1); | |
598 | + } | |
599 | + | |
600 | } | |
601 | - shutdown($remote, 1); # I've stopped writing data | |
602 | - diag("... done") if $is_debug; | |
603 | + diag("\n... done") if $is_debug; | |
604 | ||
605 | my $lines = ""; | |
606 | ||
607 | - diag("receiving response") if $is_debug; | |
608 | + diag("\nreceiving response") if $is_debug; | |
609 | # read everything | |
610 | while(<$remote>) { | |
611 | $lines .= $_; | |
612 | diag(">> ".$_) if $is_debug; | |
613 | } | |
614 | - diag("... done") if $is_debug; | |
615 | + diag("\n... done") if $is_debug; | |
616 | ||
617 | close $remote; | |
618 | ||
619 | @@ -209,7 +233,7 @@ | |
620 | (my $line, $lines) = split($EOL, $lines, 2); | |
621 | ||
622 | # header finished | |
623 | - last if(length($line) == 0); | |
624 | + last if(!defined $line or length($line) == 0); | |
625 | ||
626 | if ($ln == 0) { | |
627 | # response header | |
628 | @@ -221,21 +245,21 @@ | |
629 | (my $h = $1) =~ tr/[A-Z]/[a-z]/; | |
630 | ||
631 | if (defined $resp_hdr{$h}) { | |
632 | -# diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n", | |
633 | +# diag(sprintf("\nheader '%s' is duplicated: '%s' and '%s'\n", | |
634 | # $h, $resp_hdr{$h}, $2)); | |
635 | $resp_hdr{$h} .= ', '.$2; | |
636 | } else { | |
637 | $resp_hdr{$h} = $2; | |
638 | } | |
639 | } else { | |
640 | - diag(sprintf("unexpected line '%s'\n", $line)); | |
641 | + diag(sprintf("\nunexpected line '%s'", $line)); | |
642 | return -1; | |
643 | } | |
644 | } | |
645 | } | |
646 | ||
647 | if (not defined($resp_line)) { | |
648 | - diag(sprintf("empty response\n")); | |
649 | + diag(sprintf("\nempty response")); | |
650 | return -1; | |
651 | } | |
652 | ||
653 | @@ -259,29 +283,29 @@ | |
654 | # check conditions | |
655 | if ($resp_line =~ /^(HTTP\/1\.[01]) ([0-9]{3}) .+$/) { | |
656 | if ($href->{'HTTP-Protocol'} ne $1) { | |
657 | - diag(sprintf("proto failed: expected '%s', got '%s'\n", $href->{'HTTP-Protocol'}, $1)); | |
658 | + diag(sprintf("\nproto failed: expected '%s', got '%s'", $href->{'HTTP-Protocol'}, $1)); | |
659 | return -1; | |
660 | } | |
661 | if ($href->{'HTTP-Status'} ne $2) { | |
662 | - diag(sprintf("status failed: expected '%s', got '%s'\n", $href->{'HTTP-Status'}, $2)); | |
663 | + diag(sprintf("\nstatus failed: expected '%s', got '%s'", $href->{'HTTP-Status'}, $2)); | |
664 | return -1; | |
665 | } | |
666 | } else { | |
667 | - diag(sprintf("unexpected resp_line '%s'\n", $resp_line)); | |
668 | + diag(sprintf("\nunexpected resp_line '%s'", $resp_line)); | |
669 | return -1; | |
670 | } | |
671 | ||
672 | if (defined $href->{'HTTP-Content'}) { | |
673 | $resp_body = "" unless defined $resp_body; | |
674 | if ($href->{'HTTP-Content'} ne $resp_body) { | |
675 | - diag(sprintf("body failed: expected '%s', got '%s'\n", $href->{'HTTP-Content'}, $resp_body)); | |
676 | + diag(sprintf("\nbody failed: expected '%s', got '%s'", $href->{'HTTP-Content'}, $resp_body)); | |
677 | return -1; | |
678 | } | |
679 | } | |
680 | ||
681 | if (defined $href->{'-HTTP-Content'}) { | |
682 | if (defined $resp_body && $resp_body ne '') { | |
683 | - diag(sprintf("body failed: expected empty body, got '%s'\n", $resp_body)); | |
684 | + diag(sprintf("\nbody failed: expected empty body, got '%s'", $resp_body)); | |
685 | return -1; | |
686 | } | |
687 | } | |
688 | @@ -309,12 +333,12 @@ | |
689 | ||
690 | if ($key_inverted) { | |
691 | if (defined $resp_hdr{$k}) { | |
692 | - diag(sprintf("header '%s' MUST not be set\n", $k)); | |
693 | + diag(sprintf("\nheader '%s' MUST not be set", $k)); | |
694 | return -1; | |
695 | } | |
696 | } else { | |
697 | if (not defined $resp_hdr{$k}) { | |
698 | - diag(sprintf("required header '%s' is missing\n", $k)); | |
699 | + diag(sprintf("\nrequired header '%s' is missing", $k)); | |
700 | return -1; | |
701 | } | |
702 | } | |
703 | @@ -322,12 +346,12 @@ | |
704 | if ($verify_value) { | |
705 | if ($href->{$_} =~ /^\/(.+)\/$/) { | |
706 | if ($resp_hdr{$k} !~ /$1/) { | |
707 | - diag(sprintf("response-header failed: expected '%s', got '%s', regex: %s\n", | |
708 | + diag(sprintf("\nresponse-header failed: expected '%s', got '%s', regex: %s", | |
709 | $href->{$_}, $resp_hdr{$k}, $1)); | |
710 | return -1; | |
711 | } | |
712 | } elsif ($href->{$_} ne $resp_hdr{$k}) { | |
713 | - diag(sprintf("response-header failed: expected '%s', got '%s'\n", | |
714 | + diag(sprintf("\nresponse-header failed: expected '%s', got '%s'", | |
715 | $href->{$_}, $resp_hdr{$k})); | |
716 | return -1; | |
717 | } | |
718 | @@ -337,7 +361,7 @@ | |
719 | ||
720 | # we should have sucked up everything | |
721 | if (defined $lines) { | |
722 | - diag(sprintf("unexpected lines '%s'\n", $lines)); | |
723 | + diag(sprintf("\nunexpected lines '%s'", $lines)); | |
724 | return -1; | |
725 | } | |
726 | ||
727 | @@ -348,7 +372,7 @@ | |
728 | my ($self, $binary, $port) = @_; | |
729 | my $child = fork(); | |
730 | if (not defined $child) { | |
731 | - diag("Couldn't fork\n"); | |
732 | + diag("\nCouldn't fork"); | |
733 | return -1; | |
734 | } | |
735 | if ($child == 0) { | |
736 | @@ -362,7 +386,7 @@ | |
737 | exec $binary or die($?); | |
738 | } else { | |
739 | if (0 != $self->wait_for_port_with_proc($port, $child)) { | |
740 | - diag(sprintf('The process %i is not up (port %i, %s)', $child, $port, $binary)); | |
741 | + diag(sprintf("\nThe process %i is not up (port %i, %s)", $child, $port, $binary)); | |
742 | return -1; | |
743 | } | |
744 | return $child; | |
745 | Index: tests/run-tests.pl | |
746 | =================================================================== | |
747 | --- tests/run-tests.pl (.../tags/lighttpd-1.4.25) | |
748 | +++ tests/run-tests.pl (.../branches/lighttpd-1.4.x) | |
749 | @@ -17,4 +17,4 @@ | |
750 | } | |
751 | } | |
752 | closedir DIR; | |
753 | -runtests @fs; | |
754 | +runtests (sort @fs); | |
ceb30c4b ER |
755 | Index: configure.ac |
756 | =================================================================== | |
ceb30c4b ER |
757 | Index: SConstruct |
758 | =================================================================== | |
759 | Index: NEWS | |
760 | =================================================================== | |
479990d7 | 761 | --- NEWS (.../tags/lighttpd-1.4.25) |
cc37bbfb | 762 | +++ NEWS (.../branches/lighttpd-1.4.x) |
1530c5cf | 763 | @@ -3,7 +3,18 @@ |
ceb30c4b ER |
764 | NEWS |
765 | ==== | |
766 | ||
479990d7 | 767 | -- 1.4.25 - |
9a17f7bd | 768 | +- 1.4.26 - |
1530c5cf ER |
769 | + * Fix request parser to handle packets with splitted \r\n\r\n (fixes #2105) |
770 | + * Remove dependency on automake >= 1.11 with m4_ifdef check | |
771 | + * mod_accesslog: support %e (fixes #2113, thx presbrey) | |
772 | + * Fix mod_cgi cgi.execute-x-only option in global block | |
773 | + * mod_fastcgi: x-sendfile2 parse error debugging | |
774 | + * Fix mod_proxy dead host detection if connect() fails | |
775 | + * Fix fd leaks in mod_cgi (fds not closed on pipe/fork failures, found by Rodrigo, fixes #2158, #2159) | |
776 | + * Fix segfault with broken rewrite/redirect patterns (fixes #2140, found by crypt) | |
777 | + * Append to previous buffer in con read (fixes #2147, found by liming, CVE-2010-0295) | |
9a17f7bd ER |
778 | + |
779 | +- 1.4.25 - 2009-11-21 | |
479990d7 ER |
780 | * mod_magnet: fix pairs() for normal tables and strings (fixes #1307) |
781 | * mod_magnet: add traceback for printing lua errors | |
782 | * mod_rewrite: fix compile error if compiled without pcre | |
ceb30c4b ER |
783 | Index: CMakeLists.txt |
784 | =================================================================== |