aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-02-16 07:24:27 +0100
committerChristian Grothoff <christian@grothoff.org>2018-02-16 07:24:27 +0100
commita2f8683def34643b64a3c1afd00900fbe99f6d0f (patch)
tree8e7c0e2e6b8a20e0d71ec96f675a8b90c5277a53
parente101aeb4a9e18d506bd93afc87ea55183128f2cd (diff)
downloadlibmicrohttpd-a2f8683def34643b64a3c1afd00900fbe99f6d0f.tar.gz
libmicrohttpd-a2f8683def34643b64a3c1afd00900fbe99f6d0f.zip
implement recv/send adapters
-rw-r--r--src/lib/connection_add.c116
-rw-r--r--src/lib/daemon_close_all_connections.c2
-rw-r--r--src/lib/internal.h54
-rw-r--r--src/lib/request_resume.c2
4 files changed, 160 insertions, 14 deletions
diff --git a/src/lib/connection_add.c b/src/lib/connection_add.c
index 0aebe501..178ad929 100644
--- a/src/lib/connection_add.c
+++ b/src/lib/connection_add.c
@@ -29,6 +29,7 @@
29#include "daemon_ip_limit.h" 29#include "daemon_ip_limit.h"
30#include "daemon_select.h" 30#include "daemon_select.h"
31#include "daemon_poll.h" 31#include "daemon_poll.h"
32#include "mhd_sockets.h"
32 33
33 34
34#ifdef UPGRADE_SUPPORT 35#ifdef UPGRADE_SUPPORT
@@ -453,6 +454,113 @@ exit:
453 454
454 455
455/** 456/**
457 * Callback for receiving data from the socket.
458 *
459 * @param connection the MHD connection structure
460 * @param other where to write received data to
461 * @param i maximum size of other (in bytes)
462 * @return positive value for number of bytes actually received or
463 * negative value for error number MHD_ERR_xxx_
464 */
465static ssize_t
466recv_param_adapter (struct MHD_Connection *connection,
467 void *other,
468 size_t i)
469{
470 ssize_t ret;
471
472 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
473 (MHD_REQUEST_CLOSED == connection->request.state) )
474 {
475 return MHD_ERR_NOTCONN_;
476 }
477 if (i > MHD_SCKT_SEND_MAX_SIZE_)
478 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
479
480 ret = MHD_recv_ (connection->socket_fd,
481 other,
482 i);
483 if (0 > ret)
484 {
485 const int err = MHD_socket_get_error_ ();
486 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
487 {
488#ifdef EPOLL_SUPPORT
489 /* Got EAGAIN --- no longer read-ready */
490 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
491#endif /* EPOLL_SUPPORT */
492 return MHD_ERR_AGAIN_;
493 }
494 if (MHD_SCKT_ERR_IS_EINTR_ (err))
495 return MHD_ERR_AGAIN_;
496 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
497 return MHD_ERR_CONNRESET_;
498 /* Treat any other error as hard error. */
499 return MHD_ERR_NOTCONN_;
500 }
501#ifdef EPOLL_SUPPORT
502 else if (i > (size_t)ret)
503 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
504#endif /* EPOLL_SUPPORT */
505 return ret;
506}
507
508
509/**
510 * Callback for writing data to the socket.
511 *
512 * @param connection the MHD connection structure
513 * @param other data to write
514 * @param i number of bytes to write
515 * @return positive value for number of bytes actually sent or
516 * negative value for error number MHD_ERR_xxx_
517 */
518static ssize_t
519send_param_adapter (struct MHD_Connection *connection,
520 const void *other,
521 size_t i)
522{
523 ssize_t ret;
524
525 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
526 (MHD_REQUEST_CLOSED == connection->request.state) )
527 {
528 return MHD_ERR_NOTCONN_;
529 }
530 if (i > MHD_SCKT_SEND_MAX_SIZE_)
531 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
532
533 ret = MHD_send_ (connection->socket_fd,
534 other,
535 i);
536 if (0 > ret)
537 {
538 const int err = MHD_socket_get_error_();
539
540 if (MHD_SCKT_ERR_IS_EAGAIN_(err))
541 {
542#ifdef EPOLL_SUPPORT
543 /* EAGAIN --- no longer write-ready */
544 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
545#endif /* EPOLL_SUPPORT */
546 return MHD_ERR_AGAIN_;
547 }
548 if (MHD_SCKT_ERR_IS_EINTR_ (err))
549 return MHD_ERR_AGAIN_;
550 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
551 return MHD_ERR_CONNRESET_;
552 /* Treat any other error as hard error. */
553 return MHD_ERR_NOTCONN_;
554 }
555#ifdef EPOLL_SUPPORT
556 else if (i > (size_t)ret)
557 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
558#endif /* EPOLL_SUPPORT */
559 return ret;
560}
561
562
563/**
456 * Add another client connection to the set of connections 564 * Add another client connection to the set of connections
457 * managed by MHD. This API is usually not needed (since 565 * managed by MHD. This API is usually not needed (since
458 * MHD will accept inbound connections on the server socket). 566 * MHD will accept inbound connections on the server socket).
@@ -669,9 +777,11 @@ internal_add_connection (struct MHD_Daemon *daemon,
669 } 777 }
670 else 778 else
671#endif /* ! HTTPS_SUPPORT */ 779#endif /* ! HTTPS_SUPPORT */
672 /* set default connection handlers */ 780 {
673 MHD_set_http_callbacks_ (connection); 781 /* set default connection handlers */
674 782 connection->recv_cls = &recv_param_adapter;
783 connection->send_cls = &send_param_adapter;
784 }
675 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 785 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
676 /* Firm check under lock. */ 786 /* Firm check under lock. */
677 if (daemon->connections >= daemon->global_connection_limit) 787 if (daemon->connections >= daemon->global_connection_limit)
diff --git a/src/lib/daemon_close_all_connections.c b/src/lib/daemon_close_all_connections.c
index 5f85214c..570def2c 100644
--- a/src/lib/daemon_close_all_connections.c
+++ b/src/lib/daemon_close_all_connections.c
@@ -111,7 +111,7 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
111 MHD_connection_finish_forward_ (urh->connection); 111 MHD_connection_finish_forward_ (urh->connection);
112 urh->clean_ready = true; 112 urh->clean_ready = true;
113 /* Resuming will move connection to cleanup list. */ 113 /* Resuming will move connection to cleanup list. */
114 MHD_resume_connection (urh->connection); 114 MHD_request_resume (&urh->connection->request);
115 } 115 }
116#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 116#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
117 117
diff --git a/src/lib/internal.h b/src/lib/internal.h
index e958d2a5..f03e101e 100644
--- a/src/lib/internal.h
+++ b/src/lib/internal.h
@@ -494,16 +494,6 @@ struct MHD_Request
494 */ 494 */
495 char *colon; 495 char *colon;
496 496
497 /**
498 * Function used for reading HTTP request stream.
499 */
500 ReceiveCallback recv_cls;
501
502 /**
503 * Function used for writing HTTP response stream.
504 */
505 TransmitCallback send_cls;
506
507#ifdef UPGRADE_SUPPORT 497#ifdef UPGRADE_SUPPORT
508 /** 498 /**
509 * If this connection was upgraded, this points to 499 * If this connection was upgraded, this points to
@@ -741,6 +731,16 @@ struct MHD_Connection
741#endif 731#endif
742 732
743 /** 733 /**
734 * Function used for reading HTTP request stream.
735 */
736 ReceiveCallback recv_cls;
737
738 /**
739 * Function used for writing HTTP response stream.
740 */
741 TransmitCallback send_cls;
742
743 /**
744 * Information about the current request we are processing 744 * Information about the current request we are processing
745 * on this connection. 745 * on this connection.
746 */ 746 */
@@ -1894,4 +1894,38 @@ MHD_parse_arguments_ (struct MHD_Request *request,
1894 1894
1895 1895
1896 1896
1897/**
1898 * Error code similar to EGAIN or EINTR
1899 */
1900#define MHD_ERR_AGAIN_ (-3073)
1901
1902/**
1903 * Connection was hard-closed by remote peer.
1904 */
1905#define MHD_ERR_CONNRESET_ (-3074)
1906
1907/**
1908 * Connection is not connected anymore due to
1909 * network error or any other reason.
1910 */
1911#define MHD_ERR_NOTCONN_ (-3075)
1912
1913/**
1914 * "Not enough memory" error code
1915 */
1916#define MHD_ERR_NOMEM_ (-3076)
1917
1918/**
1919 * "Bad FD" error code
1920 */
1921#define MHD_ERR_BADF_ (-3077)
1922
1923/**
1924 * Error code similar to EINVAL
1925 */
1926#define MHD_ERR_INVAL_ (-3078)
1927
1928
1929
1930
1897#endif 1931#endif
diff --git a/src/lib/request_resume.c b/src/lib/request_resume.c
index b632d200..8a231292 100644
--- a/src/lib/request_resume.c
+++ b/src/lib/request_resume.c
@@ -66,6 +66,7 @@ MHD_request_resume (struct MHD_Request *request)
66/** 66/**
67 * Run through the suspended connections and move any that are no 67 * Run through the suspended connections and move any that are no
68 * longer suspended back to the active state. 68 * longer suspended back to the active state.
69 *
69 * @remark To be called only from thread that process 70 * @remark To be called only from thread that process
70 * daemon's select()/poll()/etc. 71 * daemon's select()/poll()/etc.
71 * 72 *
@@ -74,6 +75,7 @@ MHD_request_resume (struct MHD_Request *request)
74 */ 75 */
75bool 76bool
76MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon) 77MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon)
78/* FIXME: rename connections -> requests? */
77{ 79{
78 struct MHD_Connection *pos; 80 struct MHD_Connection *pos;
79 struct MHD_Connection *prev = NULL; 81 struct MHD_Connection *prev = NULL;