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 handler_t
connection_handle_read_post_state(server
*srv
, connection
*con
) {
319 chunkqueue
*cq
= con
->read_queue
;
320 chunkqueue
*dst_cq
= con
->request_content_queue
;
324 if (con
->is_readable
) {
325 con
->read_idle_ts
= srv
->cur_ts
;
327 switch(connection_handle_read(srv
, con
)) {
329 return HANDLER_ERROR
;
338 chunkqueue_remove_finished_chunks(cq
);
340 if (con
->request
.content_length
<= 64*1024) {
341 /* don't buffer request bodies <= 64k on disk */
342 chunkqueue_steal(dst_cq
, cq
, (off_t
)con
->request
.content_length
- dst_cq
->bytes_in
);
344 else if (0 != chunkqueue_steal_with_tempfiles(srv
, dst_cq
, cq
, (off_t
)con
->request
.content_length
- dst_cq
->bytes_in
)) {
345 /* writing to temp file failed */
346 con
->http_status
= 500; /* Internal Server Error */
349 chunkqueue_reset(con
->write_queue
);
351 return HANDLER_FINISHED
;
354 chunkqueue_remove_finished_chunks(cq
);
356 if (dst_cq
->bytes_in
== (off_t
)con
->request
.content_length
) {
357 /* Content is ready */
358 con
->conf
.stream_request_body
&= ~FDEVENT_STREAM_REQUEST_POLLIN
;
359 if (con
->state
== CON_STATE_READ_POST
) {
360 connection_set_state(srv
, con
, CON_STATE_HANDLE_REQUEST
);
362 return HANDLER_GO_ON
;
363 } else if (is_closed
) {
365 con
->http_status
= 400; /* Bad Request */
368 chunkqueue_reset(con
->write_queue
);
370 return HANDLER_FINISHED
;
372 return HANDLER_ERROR
;
374 con
->conf
.stream_request_body
|= FDEVENT_STREAM_REQUEST_POLLIN
;
375 return (con
->conf
.stream_request_body
& FDEVENT_STREAM_REQUEST
)
377 : HANDLER_WAIT_FOR_EVENT
;
381 void connection_response_reset(server
*srv
, connection
*con
) {
384 con
->http_status
= 0;
385 con
->is_writable
= 1;
386 con
->file_finished
= 0;
387 con
->file_started
= 0;
388 con
->got_response
= 0;
389 con
->parsed_response
= 0;
390 con
->response
.keep_alive
= 0;
391 con
->response
.content_length
= -1;
392 con
->response
.transfer_encoding
= 0;
393 buffer_reset(con
->physical
.path
);
394 array_reset(con
->response
.headers
);
395 chunkqueue_reset(con
->write_queue
);