diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-02-16 07:24:27 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-02-16 07:24:27 +0100 |
commit | a2f8683def34643b64a3c1afd00900fbe99f6d0f (patch) | |
tree | 8e7c0e2e6b8a20e0d71ec96f675a8b90c5277a53 | |
parent | e101aeb4a9e18d506bd93afc87ea55183128f2cd (diff) | |
download | libmicrohttpd-a2f8683def34643b64a3c1afd00900fbe99f6d0f.tar.gz libmicrohttpd-a2f8683def34643b64a3c1afd00900fbe99f6d0f.zip |
implement recv/send adapters
-rw-r--r-- | src/lib/connection_add.c | 116 | ||||
-rw-r--r-- | src/lib/daemon_close_all_connections.c | 2 | ||||
-rw-r--r-- | src/lib/internal.h | 54 | ||||
-rw-r--r-- | src/lib/request_resume.c | 2 |
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 | */ | ||
465 | static ssize_t | ||
466 | recv_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 | */ | ||
518 | static ssize_t | ||
519 | send_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 | */ |
75 | bool | 76 | bool |
76 | MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon) | 77 | MHD_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; |