aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-07-25 17:36:37 +0000
committerng0 <ng0@n0.is>2019-07-25 17:36:37 +0000
commit3dfbaa2a4c7c22a21ff974e2aacbb199fc3aa7c4 (patch)
tree8dd97eef8e2ce57f56d7e3f91a6be2d5e82d6108 /src/microhttpd
parent5bfd85fc577faa16598d2d6602057644d3d8e088 (diff)
downloadlibmicrohttpd-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.c240
-rw-r--r--src/microhttpd/mhd_send.h3
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 */
288static ssize_t
289sendfile_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
117static ssize_t
118sendfile_adapter (struct MHD_Connection *connection);
116#endif /* MHD_SEND_H */ 119#endif /* MHD_SEND_H */