diff options
author | ng0 <ng0@n0.is> | 2019-07-25 17:36:37 +0000 |
---|---|---|
committer | ng0 <ng0@n0.is> | 2019-07-25 17:36:37 +0000 |
commit | 3dfbaa2a4c7c22a21ff974e2aacbb199fc3aa7c4 (patch) | |
tree | 8dd97eef8e2ce57f56d7e3f91a6be2d5e82d6108 /src/microhttpd | |
parent | 5bfd85fc577faa16598d2d6602057644d3d8e088 (diff) | |
download | libmicrohttpd-3dfbaa2a4c7c22a21ff974e2aacbb199fc3aa7c4.tar.gz libmicrohttpd-3dfbaa2a4c7c22a21ff974e2aacbb199fc3aa7c4.zip |
remove code, add prototype to mhd_send.h
Diffstat (limited to 'src/microhttpd')
-rw-r--r-- | src/microhttpd/connection.c | 240 | ||||
-rw-r--r-- | src/microhttpd/mhd_send.h | 3 |
2 files changed, 3 insertions, 240 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 8cc3490b..643ef52a 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -278,246 +278,6 @@ send_param_adapter (struct MHD_Connection *connection, | |||
278 | } | 278 | } |
279 | 279 | ||
280 | 280 | ||
281 | #if defined(_MHD_HAVE_SENDFILE) | ||
282 | /** | ||
283 | * Function for sending responses backed by file FD. | ||
284 | * | ||
285 | * @param connection the MHD connection structure | ||
286 | * @return actual number of bytes sent | ||
287 | */ | ||
288 | static ssize_t | ||
289 | sendfile_adapter (struct MHD_Connection *connection) | ||
290 | { | ||
291 | bool want_cork = false; | ||
292 | bool have_cork; | ||
293 | bool have_more; | ||
294 | bool use_corknopush; | ||
295 | bool using_tls = false; | ||
296 | |||
297 | ssize_t ret; | ||
298 | ssize_t lo_ret; | ||
299 | const int file_fd = connection->response->fd; | ||
300 | uint64_t left; | ||
301 | uint64_t offsetu64; | ||
302 | #ifndef HAVE_SENDFILE64 | ||
303 | const uint64_t max_off_t = (uint64_t)OFF_T_MAX; | ||
304 | #else /* HAVE_SENDFILE64 */ | ||
305 | const uint64_t max_off_t = (uint64_t)OFF64_T_MAX; | ||
306 | #endif /* HAVE_SENDFILE64 */ | ||
307 | #ifdef MHD_LINUX_SOLARIS_SENDFILE | ||
308 | #ifndef HAVE_SENDFILE64 | ||
309 | off_t offset; | ||
310 | #else /* HAVE_SENDFILE64 */ | ||
311 | off64_t offset; | ||
312 | #endif /* HAVE_SENDFILE64 */ | ||
313 | #endif /* MHD_LINUX_SOLARIS_SENDFILE */ | ||
314 | #ifdef HAVE_FREEBSD_SENDFILE | ||
315 | off_t sent_bytes; | ||
316 | int flags = 0; | ||
317 | #endif | ||
318 | #ifdef HAVE_DARWIN_SENDFILE | ||
319 | off_t len; | ||
320 | #endif /* HAVE_DARWIN_SENDFILE */ | ||
321 | const bool used_thr_p_c = (0 != (connection->daemon->options & MHD_USE_THREAD_PER_CONNECTION)); | ||
322 | const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : MHD_SENFILE_CHUNK_; | ||
323 | size_t send_size = 0; | ||
324 | mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender); | ||
325 | |||
326 | offsetu64 = connection->response_write_position + connection->response->fd_off; | ||
327 | left = connection->response->total_size - connection->response_write_position; | ||
328 | /* Do not allow system to stick sending on single fast connection: | ||
329 | * use 128KiB chunks (2MiB for thread-per-connection). */ | ||
330 | send_size = (left > chunk_size) ? chunk_size : (size_t) left; | ||
331 | if (max_off_t < offsetu64) | ||
332 | { /* Retry to send with standard 'send()'. */ | ||
333 | connection->resp_sender = MHD_resp_sender_std; | ||
334 | return MHD_ERR_AGAIN_; | ||
335 | } | ||
336 | #ifdef MHD_LINUX_SOLARIS_SENDFILE | ||
337 | #ifndef HAVE_SENDFILE64 | ||
338 | offset = (off_t) offsetu64; | ||
339 | ret = sendfile (connection->socket_fd, | ||
340 | file_fd, | ||
341 | &offset, | ||
342 | send_size); | ||
343 | #else /* HAVE_SENDFILE64 */ | ||
344 | offset = (off64_t) offsetu64; | ||
345 | ret = sendfile64 (connection->socket_fd, | ||
346 | file_fd, | ||
347 | &offset, | ||
348 | send_size); | ||
349 | #endif /* HAVE_SENDFILE64 */ | ||
350 | if (0 > ret) | ||
351 | { | ||
352 | const int err = MHD_socket_get_error_(); | ||
353 | if (MHD_SCKT_ERR_IS_EAGAIN_(err)) | ||
354 | { | ||
355 | #ifdef EPOLL_SUPPORT | ||
356 | /* EAGAIN --- no longer write-ready */ | ||
357 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
358 | #endif /* EPOLL_SUPPORT */ | ||
359 | return MHD_ERR_AGAIN_; | ||
360 | } | ||
361 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
362 | return MHD_ERR_AGAIN_; | ||
363 | #ifdef HAVE_LINUX_SENDFILE | ||
364 | if (MHD_SCKT_ERR_IS_(err, | ||
365 | MHD_SCKT_EBADF_)) | ||
366 | return MHD_ERR_BADF_; | ||
367 | /* sendfile() failed with EINVAL if mmap()-like operations are not | ||
368 | supported for FD or other 'unusual' errors occurred, so we should try | ||
369 | to fall back to 'SEND'; see also this thread for info on | ||
370 | odd libc/Linux behavior with sendfile: | ||
371 | http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */ | ||
372 | connection->resp_sender = MHD_resp_sender_std; | ||
373 | return MHD_ERR_AGAIN_; | ||
374 | #else /* HAVE_SOLARIS_SENDFILE */ | ||
375 | if ( (EAFNOSUPPORT == err) || | ||
376 | (EINVAL == err) || | ||
377 | (EOPNOTSUPP == err) ) | ||
378 | { /* Retry with standard file reader. */ | ||
379 | connection->resp_sender = MHD_resp_sender_std; | ||
380 | return MHD_ERR_AGAIN_; | ||
381 | } | ||
382 | if ( (ENOTCONN == err) || | ||
383 | (EPIPE == err) ) | ||
384 | { | ||
385 | return MHD_ERR_CONNRESET_; | ||
386 | } | ||
387 | return MHD_ERR_BADF_; /* Fail hard */ | ||
388 | #endif /* HAVE_SOLARIS_SENDFILE */ | ||
389 | } | ||
390 | #ifdef EPOLL_SUPPORT | ||
391 | else if (send_size > (size_t)ret) | ||
392 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
393 | #endif /* EPOLL_SUPPORT */ | ||
394 | #elif defined(HAVE_FREEBSD_SENDFILE) | ||
395 | #ifdef SF_FLAGS | ||
396 | flags = used_thr_p_c ? | ||
397 | freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_; | ||
398 | #endif /* SF_FLAGS */ | ||
399 | if (0 != sendfile (file_fd, | ||
400 | connection->socket_fd, | ||
401 | (off_t) offsetu64, | ||
402 | send_size, | ||
403 | NULL, | ||
404 | &sent_bytes, | ||
405 | flags)) | ||
406 | { | ||
407 | const int err = MHD_socket_get_error_(); | ||
408 | if (MHD_SCKT_ERR_IS_EAGAIN_(err) || | ||
409 | MHD_SCKT_ERR_IS_EINTR_(err) || | ||
410 | EBUSY == err) | ||
411 | { | ||
412 | mhd_assert (SSIZE_MAX >= sent_bytes); | ||
413 | if (0 != sent_bytes) | ||
414 | return (ssize_t)sent_bytes; | ||
415 | |||
416 | return MHD_ERR_AGAIN_; | ||
417 | } | ||
418 | /* Some unrecoverable error. Possibly file FD is not suitable | ||
419 | * for sendfile(). Retry with standard send(). */ | ||
420 | connection->resp_sender = MHD_resp_sender_std; | ||
421 | return MHD_ERR_AGAIN_; | ||
422 | } | ||
423 | mhd_assert (0 < sent_bytes); | ||
424 | mhd_assert (SSIZE_MAX >= sent_bytes); | ||
425 | ret = (ssize_t)sent_bytes; | ||
426 | #elif defined(HAVE_DARWIN_SENDFILE) | ||
427 | len = (off_t)send_size; /* chunk always fit */ | ||
428 | if (0 != sendfile (file_fd, | ||
429 | connection->socket_fd, | ||
430 | (off_t) offsetu64, | ||
431 | &len, | ||
432 | NULL, | ||
433 | 0)) | ||
434 | { | ||
435 | const int err = MHD_socket_get_error_(); | ||
436 | if (MHD_SCKT_ERR_IS_EAGAIN_(err) || | ||
437 | MHD_SCKT_ERR_IS_EINTR_(err)) | ||
438 | { | ||
439 | mhd_assert (0 <= len); | ||
440 | mhd_assert (SSIZE_MAX >= len); | ||
441 | mhd_assert (send_size >= (size_t)len); | ||
442 | if (0 != len) | ||
443 | return (ssize_t)len; | ||
444 | |||
445 | return MHD_ERR_AGAIN_; | ||
446 | } | ||
447 | if (ENOTCONN == err || | ||
448 | EPIPE == err) | ||
449 | return MHD_ERR_CONNRESET_; | ||
450 | if (ENOTSUP == err || | ||
451 | EOPNOTSUPP == err) | ||
452 | { /* This file FD is not suitable for sendfile(). | ||
453 | * Retry with standard send(). */ | ||
454 | connection->resp_sender = MHD_resp_sender_std; | ||
455 | return MHD_ERR_AGAIN_; | ||
456 | } | ||
457 | return MHD_ERR_BADF_; /* Return hard error. */ | ||
458 | } | ||
459 | mhd_assert (0 <= len); | ||
460 | mhd_assert (SSIZE_MAX >= len); | ||
461 | mhd_assert (send_size >= (size_t)len); | ||
462 | ret = (ssize_t)len; | ||
463 | #endif /* HAVE_FREEBSD_SENDFILE */ | ||
464 | |||
465 | ret = lo_ret; | ||
466 | if (0 > ret) | ||
467 | { | ||
468 | /* ! could be avoided by redefining the variable. */ | ||
469 | have_cork = ! connection->sk_tcp_nodelay_on; | ||
470 | |||
471 | #ifdef MSG_MORE | ||
472 | have_more = true; | ||
473 | #else | ||
474 | have_more = false; | ||
475 | #endif | ||
476 | |||
477 | #if TCP_NODELAY | ||
478 | use_corknopush = false; | ||
479 | #elif TCP_CORK | ||
480 | use_corknopush = true; | ||
481 | #elif TCP_NOPUSH | ||
482 | use_corknopush = true; | ||
483 | #endif | ||
484 | |||
485 | #ifdef HTTPS_SUPPORT | ||
486 | using_tls = (0 != (connection->daemon->options & MHD_USE_TLS)); | ||
487 | #endif | ||
488 | |||
489 | #if TCP_CORK | ||
490 | /* When we have CORK, we can have NODELAY on the same system, | ||
491 | * at least since Linux 2.2 and both can be combined since | ||
492 | * Linux 2.5.71. For more details refer to tcp(7) on Linux. | ||
493 | * No other system in 2019-06 has TCP_CORK. */ | ||
494 | if ((! using_tls) && (use_corknopush) && (have_cork && ! want_cork)) | ||
495 | { | ||
496 | MHD_send_socket_state_cork_nodelay_ (connection, | ||
497 | false, | ||
498 | true, | ||
499 | true, | ||
500 | true); | ||
501 | } | ||
502 | #elif TCP_NOPUSH | ||
503 | /* TCP_NOPUSH on FreeBSD is equal to cork on Linux, with the | ||
504 | * exception that we know that TCP_NOPUSH will definitely | ||
505 | * exist and we can disregard TCP_NODELAY unless requested. */ | ||
506 | if ((! using_tls) && (use_corknopush) && (have_cork && ! want_cork)) | ||
507 | { | ||
508 | MHD_send_socket_state_nopush_ (connection, true, false); | ||
509 | } | ||
510 | #endif | ||
511 | return lo_ret; | ||
512 | } | ||
513 | else | ||
514 | { | ||
515 | return ret; | ||
516 | } | ||
517 | } | ||
518 | #endif /* _MHD_HAVE_SENDFILE */ | ||
519 | |||
520 | |||
521 | /** | 281 | /** |
522 | * Check whether is possible to force push socket buffer content as | 282 | * Check whether is possible to force push socket buffer content as |
523 | * partial packet. | 283 | * partial packet. |
diff --git a/src/microhttpd/mhd_send.h b/src/microhttpd/mhd_send.h index 20a054d3..490c8c9b 100644 --- a/src/microhttpd/mhd_send.h +++ b/src/microhttpd/mhd_send.h | |||
@@ -113,4 +113,7 @@ MHD_send_socket_state_cork_nodelay_ (struct MHD_Connection *connection, | |||
113 | bool cork_state, | 113 | bool cork_state, |
114 | bool nodelay_value, | 114 | bool nodelay_value, |
115 | bool nodelay_state); | 115 | bool nodelay_state); |
116 | |||
117 | static ssize_t | ||
118 | sendfile_adapter (struct MHD_Connection *connection); | ||
116 | #endif /* MHD_SEND_H */ | 119 | #endif /* MHD_SEND_H */ |