[mod_cgi] skip local-redir handling if to self (fixes #2779, #2108)
[lighttpd.git] / src / connections-glue.c
blobd30c229a6e7f91005e6320ffc0d2733076f01102
1 #include "first.h"
3 #include "base.h"
4 #include "connections.h"
5 #include "joblist.h"
6 #include "log.h"
8 #include <errno.h>
10 #ifdef USE_OPENSSL
11 # include <openssl/ssl.h>
12 # include <openssl/err.h>
13 #endif
15 const char *connection_get_state(connection_state_t state) {
16 switch (state) {
17 case CON_STATE_CONNECT: return "connect";
18 case CON_STATE_READ: return "read";
19 case CON_STATE_READ_POST: return "readpost";
20 case CON_STATE_WRITE: return "write";
21 case CON_STATE_CLOSE: return "close";
22 case CON_STATE_ERROR: return "error";
23 case CON_STATE_HANDLE_REQUEST: return "handle-req";
24 case CON_STATE_REQUEST_START: return "req-start";
25 case CON_STATE_REQUEST_END: return "req-end";
26 case CON_STATE_RESPONSE_START: return "resp-start";
27 case CON_STATE_RESPONSE_END: return "resp-end";
28 default: return "(unknown)";
32 const char *connection_get_short_state(connection_state_t state) {
33 switch (state) {
34 case CON_STATE_CONNECT: return ".";
35 case CON_STATE_READ: return "r";
36 case CON_STATE_READ_POST: return "R";
37 case CON_STATE_WRITE: return "W";
38 case CON_STATE_CLOSE: return "C";
39 case CON_STATE_ERROR: return "E";
40 case CON_STATE_HANDLE_REQUEST: return "h";
41 case CON_STATE_REQUEST_START: return "q";
42 case CON_STATE_REQUEST_END: return "Q";
43 case CON_STATE_RESPONSE_START: return "s";
44 case CON_STATE_RESPONSE_END: return "S";
45 default: return "x";
49 int connection_set_state(server *srv, connection *con, connection_state_t state) {
50 UNUSED(srv);
52 con->state = state;
54 return 0;
57 #if 0
58 static void dump_packet(const unsigned char *data, size_t len) {
59 size_t i, j;
61 if (len == 0) return;
63 for (i = 0; i < len; i++) {
64 if (i % 16 == 0) fprintf(stderr, " ");
66 fprintf(stderr, "%02x ", data[i]);
68 if ((i + 1) % 16 == 0) {
69 fprintf(stderr, " ");
70 for (j = 0; j <= i % 16; j++) {
71 unsigned char c;
73 if (i-15+j >= len) break;
75 c = data[i-15+j];
77 fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
80 fprintf(stderr, "\n");
84 if (len % 16 != 0) {
85 for (j = i % 16; j < 16; j++) {
86 fprintf(stderr, " ");
89 fprintf(stderr, " ");
90 for (j = i & ~0xf; j < len; j++) {
91 unsigned char c;
93 c = data[j];
94 fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
96 fprintf(stderr, "\n");
99 #endif
101 static int connection_handle_read_ssl(server *srv, connection *con) {
102 #ifdef USE_OPENSSL
103 int r, ssl_err, len;
104 char *mem = NULL;
105 size_t mem_len = 0;
107 if (!con->srv_socket->is_ssl) return -1;
109 ERR_clear_error();
110 do {
111 chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, SSL_pending(con->ssl));
112 #if 0
113 /* overwrite everything with 0 */
114 memset(mem, 0, mem_len);
115 #endif
117 len = SSL_read(con->ssl, mem, mem_len);
118 if (len > 0) {
119 chunkqueue_use_memory(con->read_queue, len);
120 con->bytes_read += len;
121 } else {
122 chunkqueue_use_memory(con->read_queue, 0);
125 if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) {
126 log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client, killing connection");
127 connection_set_state(srv, con, CON_STATE_ERROR);
128 return -1;
130 } while (len > 0);
132 if (len < 0) {
133 int oerrno = errno;
134 switch ((r = SSL_get_error(con->ssl, len))) {
135 case SSL_ERROR_WANT_WRITE:
136 con->is_writable = -1;
137 case SSL_ERROR_WANT_READ:
138 con->is_readable = 0;
140 /* the manual says we have to call SSL_read with the same arguments next time.
141 * we ignore this restriction; no one has complained about it in 1.5 yet, so it probably works anyway.
144 return 0;
145 case SSL_ERROR_SYSCALL:
147 * man SSL_get_error()
149 * SSL_ERROR_SYSCALL
150 * Some I/O error occurred. The OpenSSL error queue may contain more
151 * information on the error. If the error queue is empty (i.e.
152 * ERR_get_error() returns 0), ret can be used to find out more about
153 * the error: If ret == 0, an EOF was observed that violates the
154 * protocol. If ret == -1, the underlying BIO reported an I/O error
155 * (for socket I/O on Unix systems, consult errno for details).
158 while((ssl_err = ERR_get_error())) {
159 /* get all errors from the error-queue */
160 log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
161 r, ERR_error_string(ssl_err, NULL));
164 switch(oerrno) {
165 default:
166 log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
167 len, r, oerrno,
168 strerror(oerrno));
169 break;
172 break;
173 case SSL_ERROR_ZERO_RETURN:
174 /* clean shutdown on the remote side */
176 if (r == 0) {
177 /* FIXME: later */
180 /* fall thourgh */
181 default:
182 while((ssl_err = ERR_get_error())) {
183 switch (ERR_GET_REASON(ssl_err)) {
184 case SSL_R_SSL_HANDSHAKE_FAILURE:
185 #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
186 case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
187 #endif
188 #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
189 case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
190 #endif
191 #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
192 case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
193 #endif
194 if (!con->conf.log_ssl_noise) continue;
195 break;
196 default:
197 break;
199 /* get all errors from the error-queue */
200 log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
201 r, ERR_error_string(ssl_err, NULL));
203 break;
206 connection_set_state(srv, con, CON_STATE_ERROR);
208 return -1;
209 } else { /*(len == 0)*/
210 con->is_readable = 0;
211 /* the other end close the connection -> KEEP-ALIVE */
213 return -2;
215 #else
216 UNUSED(srv);
217 UNUSED(con);
218 return -1;
219 #endif
222 /* 0: everything ok, -1: error, -2: con closed */
223 int connection_handle_read(server *srv, connection *con) {
224 int len;
225 char *mem = NULL;
226 size_t mem_len = 0;
227 int toread;
229 if (con->srv_socket->is_ssl) {
230 return connection_handle_read_ssl(srv, con);
233 /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
234 * us more than 4kb is available
235 * if FIONREAD doesn't signal a big chunk we fill the previous buffer
236 * if it has >= 1kb free
238 #if defined(__WIN32)
239 chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, 4096);
241 len = recv(con->fd, mem, mem_len, 0);
242 #else /* __WIN32 */
243 if (ioctl(con->fd, FIONREAD, &toread) || toread <= 4*1024) {
244 toread = 4096;
246 else if (toread > MAX_READ_LIMIT) {
247 toread = MAX_READ_LIMIT;
249 chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, toread);
251 len = read(con->fd, mem, mem_len);
252 #endif /* __WIN32 */
254 chunkqueue_use_memory(con->read_queue, len > 0 ? len : 0);
256 if (len < 0) {
257 con->is_readable = 0;
259 #if defined(__WIN32)
261 int lastError = WSAGetLastError();
262 switch (lastError) {
263 case EAGAIN:
264 return 0;
265 case EINTR:
266 /* we have been interrupted before we could read */
267 con->is_readable = 1;
268 return 0;
269 case ECONNRESET:
270 /* suppress logging for this error, expected for keep-alive */
271 break;
272 default:
273 log_error_write(srv, __FILE__, __LINE__, "sd", "connection closed - recv failed: ", lastError);
274 break;
277 #else /* __WIN32 */
278 switch (errno) {
279 case EAGAIN:
280 return 0;
281 case EINTR:
282 /* we have been interrupted before we could read */
283 con->is_readable = 1;
284 return 0;
285 case ECONNRESET:
286 /* suppress logging for this error, expected for keep-alive */
287 break;
288 default:
289 log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
290 break;
292 #endif /* __WIN32 */
294 connection_set_state(srv, con, CON_STATE_ERROR);
296 return -1;
297 } else if (len == 0) {
298 con->is_readable = 0;
299 /* the other end close the connection -> KEEP-ALIVE */
301 /* pipelining */
303 return -2;
304 } else if (len != (ssize_t) mem_len) {
305 /* we got less then expected, wait for the next fd-event */
307 con->is_readable = 0;
310 con->bytes_read += len;
311 #if 0
312 dump_packet(b->ptr, len);
313 #endif
315 return 0;
318 static int connection_handle_read_post_cq_compact(chunkqueue *cq) {
319 /* combine first mem chunk with next non-empty mem chunk
320 * (loop if next chunk is empty) */
321 chunk *c;
322 while (NULL != (c = cq->first) && NULL != c->next) {
323 buffer *mem = c->next->mem;
324 off_t offset = c->next->offset;
325 size_t blen = buffer_string_length(mem) - (size_t)offset;
326 force_assert(c->type == MEM_CHUNK);
327 force_assert(c->next->type == MEM_CHUNK);
328 buffer_append_string_len(c->mem, mem->ptr+offset, blen);
329 c->next->offset = c->offset;
330 c->next->mem = c->mem;
331 c->mem = mem;
332 c->offset = offset + (off_t)blen;
333 chunkqueue_remove_finished_chunks(cq);
334 if (0 != blen) return 1;
336 return 0;
339 static int connection_handle_read_post_chunked_crlf(chunkqueue *cq) {
340 /* caller might check chunkqueue_length(cq) >= 2 before calling here
341 * to limit return value to either 1 for good or -1 for error */
342 chunk *c;
343 buffer *b;
344 char *p;
345 size_t len;
347 /* caller must have called chunkqueue_remove_finished_chunks(cq), so if
348 * chunkqueue is not empty, it contains chunk with at least one char */
349 if (chunkqueue_is_empty(cq)) return 0;
351 c = cq->first;
352 b = c->mem;
353 p = b->ptr+c->offset;
354 if (p[0] != '\r') return -1; /* error */
355 if (p[1] == '\n') return 1;
356 len = buffer_string_length(b) - (size_t)c->offset;
357 if (1 != len) return -1; /* error */
359 while (NULL != (c = c->next)) {
360 b = c->mem;
361 len = buffer_string_length(b) - (size_t)c->offset;
362 if (0 == len) continue;
363 p = b->ptr+c->offset;
364 return (p[0] == '\n') ? 1 : -1; /* error if not '\n' */
366 return 0;
369 handler_t connection_handle_read_post_error(server *srv, connection *con, int http_status) {
370 UNUSED(srv);
372 con->keep_alive = 0;
374 /*(do not change status if response headers already set and possibly sent)*/
375 if (0 != con->bytes_header) return HANDLER_ERROR;
377 con->http_status = http_status;
378 con->mode = DIRECT;
379 chunkqueue_reset(con->write_queue);
380 return HANDLER_FINISHED;
383 static handler_t connection_handle_read_post_chunked(server *srv, connection *con, chunkqueue *cq, chunkqueue *dst_cq) {
385 /* con->conf.max_request_size is in kBytes */
386 const off_t max_request_size = (off_t)con->conf.max_request_size << 10;
387 off_t te_chunked = con->request.te_chunked;
388 do {
389 off_t len = cq->bytes_in - cq->bytes_out;
391 while (0 == te_chunked) {
392 char *p;
393 chunk *c = cq->first;
394 force_assert(c->type == MEM_CHUNK);
395 p = strchr(c->mem->ptr+c->offset, '\n');
396 if (NULL != p) { /* found HTTP chunked header line */
397 off_t hsz = p + 1 - (c->mem->ptr+c->offset);
398 unsigned char *s = (unsigned char *)c->mem->ptr+c->offset;
399 for (unsigned char u;(u=(unsigned char)hex2int(*s))!=0xFF;++s) {
400 if (te_chunked > (~((off_t)-1) >> 4)) {
401 log_error_write(srv, __FILE__, __LINE__, "s",
402 "chunked data size too large -> 400");
403 /* 400 Bad Request */
404 return connection_handle_read_post_error(srv, con, 400);
406 te_chunked <<= 4;
407 te_chunked |= u;
409 while (*s == ' ' || *s == '\t') ++s;
410 if (*s != '\r' && *s != ';') {
411 log_error_write(srv, __FILE__, __LINE__, "s",
412 "chunked header invalid chars -> 400");
413 /* 400 Bad Request */
414 return connection_handle_read_post_error(srv, con, 400);
417 if (hsz >= 1024) {
418 /* prevent theoretical integer overflow
419 * casting to (size_t) and adding 2 (for "\r\n") */
420 log_error_write(srv, __FILE__, __LINE__, "s",
421 "chunked header line too long -> 400");
422 /* 400 Bad Request */
423 return connection_handle_read_post_error(srv, con, 400);
426 if (0 == te_chunked) {
427 /* do not consume final chunked header until
428 * (optional) trailers received along with
429 * request-ending blank line "\r\n" */
430 if (p[0] == '\r' && p[1] == '\n') {
431 /*(common case with no trailers; final \r\n received)*/
432 hsz += 2;
434 else {
435 /* trailers or final CRLF crosses into next cq chunk */
436 hsz -= 2;
437 do {
438 c = cq->first;
439 p = strstr(c->mem->ptr+c->offset+hsz, "\r\n\r\n");
440 } while (NULL == p
441 && connection_handle_read_post_cq_compact(cq));
442 if (NULL == p) {
443 /*(effectively doubles max request field size
444 * potentially received by backend, if in the future
445 * these trailers are added to request headers)*/
446 if ((off_t)buffer_string_length(c->mem) - c->offset
447 < srv->srvconf.max_request_field_size) {
448 break;
450 else {
451 /* ignore excessively long trailers;
452 * disable keep-alive on connection */
453 con->keep_alive = 0;
456 hsz = p + 4 - (c->mem->ptr+c->offset);
457 /* trailers currently ignored, but could be processed
458 * here if 0 == con->conf.stream_request_body, taking
459 * care to reject any fields forbidden in trailers,
460 * making trailers available to CGI and other backends*/
462 chunkqueue_mark_written(cq, (size_t)hsz);
463 con->request.content_length = dst_cq->bytes_in;
464 break; /* done reading HTTP chunked request body */
467 /* consume HTTP chunked header */
468 chunkqueue_mark_written(cq, (size_t)hsz);
469 len = cq->bytes_in - cq->bytes_out;
471 if (0 !=max_request_size
472 && (max_request_size < te_chunked
473 || max_request_size - te_chunked < dst_cq->bytes_in)) {
474 log_error_write(srv, __FILE__, __LINE__, "sos",
475 "request-size too long:",
476 dst_cq->bytes_in + te_chunked, "-> 413");
477 /* 413 Payload Too Large */
478 return connection_handle_read_post_error(srv, con, 413);
481 te_chunked += 2; /*(for trailing "\r\n" after chunked data)*/
483 break; /* read HTTP chunked header */
486 /*(likely better ways to handle chunked header crossing chunkqueue
487 * chunks, but this situation is not expected to occur frequently)*/
488 if ((off_t)buffer_string_length(c->mem) - c->offset >= 1024) {
489 log_error_write(srv, __FILE__, __LINE__, "s",
490 "chunked header line too long -> 400");
491 /* 400 Bad Request */
492 return connection_handle_read_post_error(srv, con, 400);
494 else if (!connection_handle_read_post_cq_compact(cq)) {
495 break;
498 if (0 == te_chunked) break;
500 if (te_chunked > 2) {
501 if (len > te_chunked-2) len = te_chunked-2;
502 if (dst_cq->bytes_in + te_chunked <= 64*1024) {
503 /* avoid buffering request bodies <= 64k on disk */
504 chunkqueue_steal(dst_cq, cq, len);
506 else if (0 != chunkqueue_steal_with_tempfiles(srv,dst_cq,cq,len)) {
507 /* 500 Internal Server Error */
508 return connection_handle_read_post_error(srv, con, 500);
510 te_chunked -= len;
511 len = cq->bytes_in - cq->bytes_out;
514 if (len < te_chunked) break;
516 if (2 == te_chunked) {
517 if (-1 == connection_handle_read_post_chunked_crlf(cq)) {
518 log_error_write(srv, __FILE__, __LINE__, "s",
519 "chunked data missing end CRLF -> 400");
520 /* 400 Bad Request */
521 return connection_handle_read_post_error(srv, con, 400);
523 chunkqueue_mark_written(cq, 2);/*consume \r\n at end of chunk data*/
524 te_chunked -= 2;
527 } while (!chunkqueue_is_empty(cq));
529 con->request.te_chunked = te_chunked;
530 return HANDLER_GO_ON;
533 handler_t connection_handle_read_post_state(server *srv, connection *con) {
534 chunkqueue *cq = con->read_queue;
535 chunkqueue *dst_cq = con->request_content_queue;
537 int is_closed = 0;
539 if (con->is_readable) {
540 con->read_idle_ts = srv->cur_ts;
542 switch(connection_handle_read(srv, con)) {
543 case -1:
544 return HANDLER_ERROR;
545 case -2:
546 is_closed = 1;
547 break;
548 default:
549 break;
553 chunkqueue_remove_finished_chunks(cq);
555 if (-1 == con->request.content_length) { /*(Transfer-Encoding: chunked)*/
556 handler_t rc = connection_handle_read_post_chunked(srv, con, cq, dst_cq);
557 if (HANDLER_GO_ON != rc) return rc;
559 else if (con->request.content_length <= 64*1024) {
560 /* don't buffer request bodies <= 64k on disk */
561 chunkqueue_steal(dst_cq, cq, (off_t)con->request.content_length - dst_cq->bytes_in);
563 else if (0 != chunkqueue_steal_with_tempfiles(srv, dst_cq, cq, (off_t)con->request.content_length - dst_cq->bytes_in)) {
564 /* writing to temp file failed */
565 return connection_handle_read_post_error(srv, con, 500); /* Internal Server Error */
568 chunkqueue_remove_finished_chunks(cq);
570 if (dst_cq->bytes_in == (off_t)con->request.content_length) {
571 /* Content is ready */
572 con->conf.stream_request_body &= ~FDEVENT_STREAM_REQUEST_POLLIN;
573 if (con->state == CON_STATE_READ_POST) {
574 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
576 return HANDLER_GO_ON;
577 } else if (is_closed) {
578 #if 0
579 return connection_handle_read_post_error(srv, con, 400); /* Bad Request */
580 #endif
581 return HANDLER_ERROR;
582 } else {
583 con->conf.stream_request_body |= FDEVENT_STREAM_REQUEST_POLLIN;
584 return (con->conf.stream_request_body & FDEVENT_STREAM_REQUEST)
585 ? HANDLER_GO_ON
586 : HANDLER_WAIT_FOR_EVENT;
590 void connection_response_reset(server *srv, connection *con) {
591 UNUSED(srv);
593 con->mode = DIRECT;
594 con->http_status = 0;
595 con->is_writable = 1;
596 con->file_finished = 0;
597 con->file_started = 0;
598 con->got_response = 0;
599 con->parsed_response = 0;
600 con->response.keep_alive = 0;
601 con->response.content_length = -1;
602 con->response.transfer_encoding = 0;
603 if (con->physical.path) { /*(skip for mod_fastcgi authorizer)*/
604 buffer_reset(con->physical.doc_root);
605 buffer_reset(con->physical.path);
606 buffer_reset(con->physical.basedir);
607 buffer_reset(con->physical.rel_path);
608 buffer_reset(con->physical.etag);
610 array_reset(con->response.headers);
611 chunkqueue_reset(con->write_queue);