4 #include "connections.h"
11 # include <openssl/ssl.h>
12 # include <openssl/err.h>
15 const char *connection_get_state(connection_state_t 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
) {
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";
49 int connection_set_state(server
*srv
, connection
*con
, connection_state_t state
) {
58 static void dump_packet(const unsigned char *data
, size_t len
) {
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) {
70 for (j
= 0; j
<= i
% 16; j
++) {
73 if (i
-15+j
>= len
) break;
77 fprintf(stderr
, "%c", c
> 32 && c
< 128 ? c
: '.');
80 fprintf(stderr
, "\n");
85 for (j
= i
% 16; j
< 16; j
++) {
90 for (j
= i
& ~0xf; j
< len
; j
++) {
94 fprintf(stderr
, "%c", c
> 32 && c
< 128 ? c
: '.');
96 fprintf(stderr
, "\n");
101 static int connection_handle_read_ssl(server
*srv
, connection
*con
) {
107 if (!con
->srv_socket
->is_ssl
) return -1;
111 chunkqueue_get_memory(con
->read_queue
, &mem
, &mem_len
, 0, SSL_pending(con
->ssl
));
113 /* overwrite everything with 0 */
114 memset(mem
, 0, mem_len
);
117 len
= SSL_read(con
->ssl
, mem
, mem_len
);
119 chunkqueue_use_memory(con
->read_queue
, len
);
120 con
->bytes_read
+= len
;
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
);
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.
145 case SSL_ERROR_SYSCALL
:
147 * man SSL_get_error()
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
));
166 log_error_write(srv
, __FILE__
, __LINE__
, "sddds", "SSL:",
173 case SSL_ERROR_ZERO_RETURN
:
174 /* clean shutdown on the remote side */
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
:
188 #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
189 case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
:
191 #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
192 case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
:
194 if (!con
->conf
.log_ssl_noise
) continue;
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
));
206 connection_set_state(srv
, con
, CON_STATE_ERROR
);
209 } else { /*(len == 0)*/
210 con
->is_readable
= 0;
211 /* the other end close the connection -> KEEP-ALIVE */
222 /* 0: everything ok, -1: error, -2: con closed */
223 int connection_handle_read(server
*srv
, connection
*con
) {
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
239 chunkqueue_get_memory(con
->read_queue
, &mem
, &mem_len
, 0, 4096);
241 len
= recv(con
->fd
, mem
, mem_len
, 0);
243 if (ioctl(con
->fd
, FIONREAD
, &toread
) || toread
<= 4*1024) {
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
);
254 chunkqueue_use_memory(con
->read_queue
, len
> 0 ? len
: 0);
257 con
->is_readable
= 0;
261 int lastError
= WSAGetLastError();
266 /* we have been interrupted before we could read */
267 con
->is_readable
= 1;
270 /* suppress logging for this error, expected for keep-alive */
273 log_error_write(srv
, __FILE__
, __LINE__
, "sd", "connection closed - recv failed: ", lastError
);
282 /* we have been interrupted before we could read */
283 con
->is_readable
= 1;
286 /* suppress logging for this error, expected for keep-alive */
289 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "connection closed - read failed: ", strerror(errno
), errno
);
294 connection_set_state(srv
, con
, CON_STATE_ERROR
);
297 } else if (len
== 0) {
298 con
->is_readable
= 0;
299 /* the other end close the connection -> KEEP-ALIVE */
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
;
312 dump_packet(b
->ptr
, len
);
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) */
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
;
332 c
->offset
= offset
+ (off_t
)blen
;
333 chunkqueue_remove_finished_chunks(cq
);
334 if (0 != blen
) return 1;
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 */
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;
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
)) {
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' */
369 handler_t
connection_handle_read_post_error(server
*srv
, connection
*con
, int http_status
) {
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
;
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
;
389 off_t len
= cq
->bytes_in
- cq
->bytes_out
;
391 while (0 == te_chunked
) {
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);
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);
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)*/
435 /* trailers or final CRLF crosses into next cq chunk */
439 p
= strstr(c
->mem
->ptr
+c
->offset
+hsz
, "\r\n\r\n");
441 && connection_handle_read_post_cq_compact(cq
));
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
) {
451 /* ignore excessively long trailers;
452 * disable keep-alive on connection */
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
)) {
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);
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*/
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
;
539 if (con
->is_readable
) {
540 con
->read_idle_ts
= srv
->cur_ts
;
542 switch(connection_handle_read(srv
, con
)) {
544 return HANDLER_ERROR
;
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
) {
579 return connection_handle_read_post_error(srv
, con
, 400); /* Bad Request */
581 return HANDLER_ERROR
;
583 con
->conf
.stream_request_body
|= FDEVENT_STREAM_REQUEST_POLLIN
;
584 return (con
->conf
.stream_request_body
& FDEVENT_STREAM_REQUEST
)
586 : HANDLER_WAIT_FOR_EVENT
;
590 void connection_response_reset(server
*srv
, connection
*con
) {
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
);