aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-10-25 14:40:02 +0200
committerChristian Grothoff <christian@grothoff.org>2019-10-25 14:43:36 +0200
commit185f740e0684a8758cbf381fe5c44b3ed72d4a40 (patch)
tree854e7f65dede4766b179bf875b68e4aeeb453a9e /src
parent3e2ba2b1ced0b4c9d13961e89e43c3932399f6d6 (diff)
downloadlibmicrohttpd-185f740e0684a8758cbf381fe5c44b3ed72d4a40.tar.gz
libmicrohttpd-185f740e0684a8758cbf381fe5c44b3ed72d4a40.zip
allow clients to override sanity check for content-length header
Diffstat (limited to 'src')
-rw-r--r--src/include/microhttpd.h40
-rw-r--r--src/microhttpd/connection.c5
-rw-r--r--src/microhttpd/daemon.c14
-rw-r--r--src/microhttpd/internal.h6
-rw-r--r--src/microhttpd/response.c32
5 files changed, 75 insertions, 22 deletions
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index e6090fbb..3387e500 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -132,7 +132,7 @@ typedef intptr_t ssize_t;
132 * Current version of the library. 132 * Current version of the library.
133 * 0x01093001 = 1.9.30-1. 133 * 0x01093001 = 1.9.30-1.
134 */ 134 */
135#define MHD_VERSION 0x00096701 135#define MHD_VERSION 0x00096702
136 136
137/** 137/**
138 * MHD-internal return code for "YES". 138 * MHD-internal return code for "YES".
@@ -1691,10 +1691,35 @@ enum MHD_OPTION
1691 * followed by a argument of type `gnutls_certificate_retrieve_function3 *`. 1691 * followed by a argument of type `gnutls_certificate_retrieve_function3 *`.
1692 * This option provides an 1692 * This option provides an
1693 * alternative/extension to #MHD_OPTION_HTTPS_CERT_CALLBACK. 1693 * alternative/extension to #MHD_OPTION_HTTPS_CERT_CALLBACK.
1694 * You must use this version if you want to use OCSP stapling. 1694 * You must use this version if you want to use OCSP stapling.
1695 * Using this option requires GnuTLS 3.6.3 or higher. 1695 * Using this option requires GnuTLS 3.6.3 or higher.
1696 */ 1696 */
1697 MHD_OPTION_HTTPS_CERT_CALLBACK2 = 31 1697 MHD_OPTION_HTTPS_CERT_CALLBACK2 = 31,
1698
1699 /**
1700 * Allows the application to disable certain sanity precautions
1701 * in MHD. With these, the client can break the HTTP protocol,
1702 * so this should never be used in production. The options are,
1703 * however, useful for testing HTTP clients against "broken"
1704 * server implementations.
1705 * This argument must be followed by an "unsigned int", corresponding
1706 * to an `enum MHD_DisableSanityCheck`.
1707 */
1708 MHD_OPTION_SERVER_INSANITY = 32
1709};
1710
1711
1712/**
1713 * Bitfield for the #MHD_OPTION_SERVER_INSANITY specifying
1714 * which santiy checks should be disabled.
1715 */
1716enum MHD_DisableSanityCheck
1717{
1718 /**
1719 * All sanity checks are enabled.
1720 */
1721 MHD_DSC_SANE = 0
1722
1698}; 1723};
1699 1724
1700 1725
@@ -2924,7 +2949,14 @@ enum MHD_ResponseFlags
2924 * #MHD_RF_HTTP_VERSION_1_0_ONLY flag, the response's HTTP version will 2949 * #MHD_RF_HTTP_VERSION_1_0_ONLY flag, the response's HTTP version will
2925 * always be set to 1.0 and "Connection" headers are still supported. 2950 * always be set to 1.0 and "Connection" headers are still supported.
2926 */ 2951 */
2927 MHD_RF_HTTP_VERSION_1_0_RESPONSE = 2 2952 MHD_RF_HTTP_VERSION_1_0_RESPONSE = 2,
2953
2954 /**
2955 * Disable sanity check preventing clients from manually
2956 * setting the HTTP content length option.
2957 */
2958 MHD_RF_INSANITY_HEADER_CONTENT_LENGTH = 4
2959
2928 2960
2929}; 2961};
2930 2962
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 1dbbbd82..2ef0b989 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1430,8 +1430,9 @@ build_header_response (struct MHD_Connection *connection)
1430 (MHD_HTTP_NO_CONTENT != rc) && 1430 (MHD_HTTP_NO_CONTENT != rc) &&
1431 (MHD_HTTP_NOT_MODIFIED != rc) && 1431 (MHD_HTTP_NOT_MODIFIED != rc) &&
1432 (MHD_HTTP_OK <= rc) && 1432 (MHD_HTTP_OK <= rc) &&
1433 (NULL == /* this should always succeed due to check in 1433 (NULL == /* this COULD fail if the check in
1434 MHD_add_response_header() */ 1434 MHD_add_response_header() was bypassed
1435 via #MHD_RF_INSANITY_HEADER_CONTENT_LENGTH */
1435 MHD_get_response_header (response, 1436 MHD_get_response_header (response,
1436 MHD_HTTP_HEADER_CONTENT_LENGTH)) && 1437 MHD_HTTP_HEADER_CONTENT_LENGTH)) &&
1437 (may_add_content_length) && 1438 (may_add_content_length) &&
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 1e5716e3..aec6aa86 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -2182,7 +2182,7 @@ thread_main_handle_connection (void *data)
2182 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN : 2182 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN :
2183 MHD_REQUEST_TERMINATED_WITH_ERROR); 2183 MHD_REQUEST_TERMINATED_WITH_ERROR);
2184 MHD_connection_handle_idle (con); 2184 MHD_connection_handle_idle (con);
2185exit: 2185 exit:
2186 if (NULL != con->response) 2186 if (NULL != con->response)
2187 { 2187 {
2188 MHD_destroy_response (con->response); 2188 MHD_destroy_response (con->response);
@@ -2742,7 +2742,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
2742#endif 2742#endif
2743 } 2743 }
2744 return MHD_YES; 2744 return MHD_YES;
2745cleanup: 2745 cleanup:
2746 if (NULL != daemon->notify_connection) 2746 if (NULL != daemon->notify_connection)
2747 daemon->notify_connection (daemon->notify_connection_cls, 2747 daemon->notify_connection (daemon->notify_connection_cls,
2748 connection, 2748 connection,
@@ -5062,6 +5062,11 @@ parse_options_va (struct MHD_Daemon *daemon,
5062 daemon->uri_log_callback_cls = va_arg (ap, 5062 daemon->uri_log_callback_cls = va_arg (ap,
5063 void *); 5063 void *);
5064 break; 5064 break;
5065 case MHD_OPTION_SERVER_INSANITY:
5066 daemon->insanity_level = (enum MHD_DisableSanityCheck)
5067 va_arg (ap,
5068 unsigned int);
5069 break;
5065#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 5070#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5066 case MHD_OPTION_THREAD_POOL_SIZE: 5071 case MHD_OPTION_THREAD_POOL_SIZE:
5067 daemon->worker_pool_size = va_arg (ap, 5072 daemon->worker_pool_size = va_arg (ap,
@@ -5404,6 +5409,7 @@ parse_options_va (struct MHD_Daemon *daemon,
5404 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 5409 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
5405 case MHD_OPTION_LISTENING_ADDRESS_REUSE: 5410 case MHD_OPTION_LISTENING_ADDRESS_REUSE:
5406 case MHD_OPTION_LISTEN_BACKLOG_SIZE: 5411 case MHD_OPTION_LISTEN_BACKLOG_SIZE:
5412 case MHD_OPTION_SERVER_INSANITY:
5407 if (MHD_YES != parse_options (daemon, 5413 if (MHD_YES != parse_options (daemon,
5408 servaddr, 5414 servaddr,
5409 opt, 5415 opt,
@@ -6547,7 +6553,7 @@ MHD_start_daemon_va (unsigned int flags,
6547 return daemon; 6553 return daemon;
6548 6554
6549#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 6555#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6550thread_failed: 6556 thread_failed:
6551 /* If no worker threads created, then shut down normally. Calling 6557 /* If no worker threads created, then shut down normally. Calling
6552 MHD_stop_daemon (as we do below) doesn't work here since it 6558 MHD_stop_daemon (as we do below) doesn't work here since it
6553 assumes a 0-sized thread pool means we had been in the default 6559 assumes a 0-sized thread pool means we had been in the default
@@ -6571,7 +6577,7 @@ thread_failed:
6571 return NULL; 6577 return NULL;
6572#endif 6578#endif
6573 6579
6574free_and_fail: 6580 free_and_fail:
6575 /* clean up basic memory state in 'daemon' and return NULL to 6581 /* clean up basic memory state in 'daemon' and return NULL to
6576 indicate failure */ 6582 indicate failure */
6577#ifdef EPOLL_SUPPORT 6583#ifdef EPOLL_SUPPORT
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index fa66d265..8f7192e7 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1461,6 +1461,12 @@ struct MHD_Daemon
1461 size_t thread_stack_size; 1461 size_t thread_stack_size;
1462 1462
1463 /** 1463 /**
1464 * Our #MHD_OPTION_SERVER_INSANITY level, bits indicating
1465 * which sanity checks are off.
1466 */
1467 enum MHD_DisableSanityCheck insanity_level;
1468
1469 /**
1464 * Number of worker daemons 1470 * Number of worker daemons
1465 */ 1471 */
1466 unsigned int worker_pool_size; 1472 unsigned int worker_pool_size;
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 112a622a..968fc8c9 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -147,8 +147,10 @@ MHD_add_response_header (struct MHD_Response *response,
147 /* NOTE: for compressed bodies, use the "Content-encoding" header */ 147 /* NOTE: for compressed bodies, use the "Content-encoding" header */
148 return MHD_NO; 148 return MHD_NO;
149 } 149 }
150 if (MHD_str_equal_caseless_ (header, 150 if ( (0 == (MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
151 MHD_HTTP_HEADER_CONTENT_LENGTH)) 151 & response->flags)) &&
152 (MHD_str_equal_caseless_ (header,
153 MHD_HTTP_HEADER_CONTENT_LENGTH)) )
152 { 154 {
153 /* MHD will set Content-length if allowed and possible, 155 /* MHD will set Content-length if allowed and possible,
154 reject attempt by application */ 156 reject attempt by application */
@@ -838,17 +840,20 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
838 return MHD_YES; 840 return MHD_YES;
839 } 841 }
840 else 842 else
841#else 843#endif
842 { 844 {
843 if (0 == 845 if (0 ==
844 MHD_socket_cork_ (connection->socket_fd, 846 MHD_socket_cork_ (connection->socket_fd,
845 true)) 847 true))
848 {
846 connection->sk_cork_on = true; 849 connection->sk_cork_on = true;
847 }
848#endif
849 case MHD_UPGRADE_ACTION_CORK_OFF:
850 if (! connection->sk_cork_on)
851 return MHD_YES; 850 return MHD_YES;
851 }
852 return MHD_NO;
853 }
854 case MHD_UPGRADE_ACTION_CORK_OFF:
855 if (! connection->sk_cork_on)
856 return MHD_YES;
852#ifdef HTTPS_SUPPORT 857#ifdef HTTPS_SUPPORT
853 if (0 != (daemon->options & MHD_USE_TLS) ) 858 if (0 != (daemon->options & MHD_USE_TLS) )
854 { 859 {
@@ -857,17 +862,20 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
857 return MHD_YES; 862 return MHD_YES;
858 } 863 }
859 else 864 else
860#else 865#endif
861 { 866 {
862 if (0 == 867 if (0 ==
863 MHD_socket_cork_ (connection->socket_fd, 868 MHD_socket_cork_ (connection->socket_fd,
864 false)) 869 false))
870 {
865 connection->sk_cork_on = false; 871 connection->sk_cork_on = false;
866 } 872 return MHD_YES;
867#endif 873 }
868 default:
869 /* we don't understand this one */
870 return MHD_NO; 874 return MHD_NO;
875 }
876 default:
877 /* we don't understand this one */
878 return MHD_NO;
871 } 879 }
872} 880}
873 881