[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [libmicrohttpd] branch master updated: fix #5411
From: |
gnunet |
Subject: |
[GNUnet-SVN] [libmicrohttpd] branch master updated: fix #5411 |
Date: |
Fri, 05 Oct 2018 19:23:28 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository libmicrohttpd.
The following commit(s) were added to refs/heads/master by this push:
new 0db81a92 fix #5411
0db81a92 is described below
commit 0db81a9248b12abc74f153ebd642441d0f9c3e58
Author: Christian Grothoff <address@hidden>
AuthorDate: Fri Oct 5 19:23:26 2018 +0200
fix #5411
---
ChangeLog | 10 ++++++
doc/libmicrohttpd.texi | 15 +++++++--
src/microhttpd/connection.c | 79 ++++++++++++++++++++++++++-------------------
src/microhttpd/response.c | 21 ++++++++++++
4 files changed, 90 insertions(+), 35 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 068780e3..eb273daf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Oct 5 18:44:45 CEST 2018
+ MHD_add_response_header() now prevents applications from
+ setting a "Transfer-Encoding" header to values other than
+ "identity" or "chunked" as other transfer encodings are
+ not supported by MHD. (Note that usually MHD will pick the
+ transfer encoding correctly automatically, but applications
+ can use the header to force a particular behavior.)
+ Fixing #5411 (never set Content-length if Transfer-Encoding
+ is given). -CG
+
Sat Jul 14 11:42:15 CEST 2018
Add MHD_OPTION_GNUTLS_PSK_CRED_HANDLER to allow use of PSK with
TLS connections. -CG/TM
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index d2886a25..b61c94ff 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -874,9 +874,9 @@ or higher.
@cindex TLS
@cindex PSK
Use pre-shared key for TLS credentials.
-Pass a pointer to callback of type
+Pass a pointer to callback of type
@code{MHD_PskServerCredentialsCallback} and a closure.
-The function will be called to
+The function will be called to
retrieve the shared key for a given username.
@item MHD_OPTION_DIGEST_AUTH_RANDOM
@@ -2050,6 +2050,17 @@ duplicated into memory blocks embedded in @var{response}.
Notice that the strings must not hold newlines, carriage returns or tab
chars.
+MHD_add_response_header() prevents applications from setting a
+``Transfer-Encoding'' header to values other than ``identity'' or
+``chunked'' as other transfer encodings are not supported by MHD. Note
+that usually MHD will pick the transfer encoding correctly
+automatically, but applications can use the header to force a
+particular behavior.
+
+MHD_add_response_header() also prevents applications from setting a
+``Content-Length'' header. MHD will automatically set a correct
+``Content-Length'' header if it is possible and allowed.
+
Return @code{MHD_NO} on error (i.e. invalid header or content format or
memory allocation error).
@end deftypefun
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 1778c59b..60dc5eb4 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1404,6 +1404,7 @@ try_grow_read_buffer (struct MHD_Connection *connection)
static int
build_header_response (struct MHD_Connection *connection)
{
+ struct MHD_Response *response = connection->response;
size_t size;
size_t off;
struct MHD_HTTP_Header *pos;
@@ -1420,11 +1421,11 @@ build_header_response (struct MHD_Connection
*connection)
bool response_has_close;
bool response_has_keepalive;
const char *have_encoding;
- const char *have_content_length;
int must_add_close;
int must_add_chunked_encoding;
int must_add_keep_alive;
int must_add_content_length;
+ int may_add_content_length;
mhd_assert (NULL != connection->version);
if (0 == connection->version[0])
@@ -1458,7 +1459,7 @@ build_header_response (struct MHD_Connection *connection)
size = off + 2; /* +2 for extra "\r\n" at the end */
kind = MHD_HEADER_KIND;
if ( (0 == (connection->daemon->options &
MHD_USE_SUPPRESS_DATE_NO_CLOCK)) &&
- (NULL == MHD_get_response_header (connection->response,
+ (NULL == MHD_get_response_header (response,
MHD_HTTP_HEADER_DATE)) )
get_date_string (date,
sizeof (date));
@@ -1486,30 +1487,35 @@ build_header_response (struct MHD_Connection
*connection)
switch (connection->state)
{
case MHD_CONNECTION_FOOTERS_RECEIVED:
- response_has_close = MHD_check_response_header_s_token_ci
(connection->response,
+ response_has_close = MHD_check_response_header_s_token_ci (response,
MHD_HTTP_HEADER_CONNECTION,
"close");
- response_has_keepalive = MHD_check_response_header_s_token_ci
(connection->response,
+ response_has_keepalive = MHD_check_response_header_s_token_ci (response,
MHD_HTTP_HEADER_CONNECTION,
"Keep-Alive");
client_requested_close = MHD_lookup_header_s_token_ci (connection,
-
MHD_HTTP_HEADER_CONNECTION,
- "close");
+
MHD_HTTP_HEADER_CONNECTION,
+ "close");
- if (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY))
+ if (0 != (response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY))
connection->keepalive = MHD_CONN_MUST_CLOSE;
#ifdef UPGRADE_SUPPORT
- else if (NULL != connection->response->upgrade_handler)
+ else if (NULL != response->upgrade_handler)
/* If this connection will not be "upgraded", it must be closed. */
connection->keepalive = MHD_CONN_MUST_CLOSE;
#endif /* UPGRADE_SUPPORT */
/* now analyze chunked encoding situation */
connection->have_chunked_upload = false;
-
- if ( (MHD_SIZE_UNKNOWN == connection->response->total_size) &&
+ have_encoding = MHD_get_response_header (response,
+
MHD_HTTP_HEADER_TRANSFER_ENCODING);
+ if (NULL == have_encoding)
+ may_add_content_length = MHD_YES;
+ else
+ may_add_content_length = MHD_NO; /* RFC 7230, Section 3.3.2 forbids
header */
+ if ( (MHD_SIZE_UNKNOWN == response->total_size) &&
#ifdef UPGRADE_SUPPORT
- (NULL == connection->response->upgrade_handler) &&
+ (NULL == response->upgrade_handler) &&
#endif /* UPGRADE_SUPPORT */
(! response_has_close) &&
(! client_requested_close) )
@@ -1523,22 +1529,23 @@ build_header_response (struct MHD_Connection
*connection)
(MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
connection->version) ) )
{
- have_encoding = MHD_get_response_header (connection->response,
-
MHD_HTTP_HEADER_TRANSFER_ENCODING);
if (NULL == have_encoding)
{
must_add_chunked_encoding = MHD_YES;
connection->have_chunked_upload = true;
}
- else if (MHD_str_equal_caseless_ (have_encoding,
- "identity"))
- {
- /* application forced identity encoding, can't do 'chunked'
*/
- must_add_close = MHD_YES;
- }
else
{
- connection->have_chunked_upload = true;
+ if (MHD_str_equal_caseless_ (have_encoding,
+ "identity"))
+ {
+ /* application forced identity encoding, can't do
'chunked' */
+ must_add_close = MHD_YES;
+ }
+ else
+ {
+ connection->have_chunked_upload = true;
+ }
}
}
else
@@ -1556,23 +1563,29 @@ build_header_response (struct MHD_Connection
*connection)
(MHD_CONN_MUST_CLOSE == connection->keepalive)) &&
(! response_has_close) &&
#ifdef UPGRADE_SUPPORT
- (NULL == connection->response->upgrade_handler) &&
+ (NULL == response->upgrade_handler) &&
#endif /* UPGRADE_SUPPORT */
- (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY)
) )
+ (0 == (response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
must_add_close = MHD_YES;
- /* check if we should add a 'content length' header */
- have_content_length = MHD_get_response_header (connection->response,
-
MHD_HTTP_HEADER_CONTENT_LENGTH);
-
- /* MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED and 1xx-status
+ /* check if we must add 'close' header because we cannot add
content-length
+ because it is forbidden AND we don't have a 'chunked' encoding */
+ if ( (! may_add_content_length) &&
+ (! connection->have_chunked_upload) &&
+ (! response_has_close) )
+ must_add_close = MHD_YES;
+ /* #MHD_HTTP_NO_CONTENT, #MHD_HTTP_NOT_MODIFIED and 1xx-status
codes SHOULD NOT have a Content-Length according to spec;
also chunked encoding / unknown length or CONNECT... */
- if ( (MHD_SIZE_UNKNOWN != connection->response->total_size) &&
+ if ( (MHD_SIZE_UNKNOWN != response->total_size) &&
(MHD_HTTP_NO_CONTENT != rc) &&
(MHD_HTTP_NOT_MODIFIED != rc) &&
(MHD_HTTP_OK <= rc) &&
- (NULL == have_content_length) &&
+ (NULL == /* this should always succeed due to check in
+ MHD_add_response_header() */
+ MHD_get_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_LENGTH)) &&
+ (may_add_content_length) &&
( (NULL == connection->method) ||
(! MHD_str_equal_caseless_ (connection->method,
MHD_HTTP_METHOD_CONNECT)) ) )
@@ -1596,7 +1609,7 @@ build_header_response (struct MHD_Connection *connection)
= MHD_snprintf_ (content_length_buf,
sizeof (content_length_buf),
MHD_HTTP_HEADER_CONTENT_LENGTH ": "
MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n",
- (MHD_UNSIGNED_LONG_LONG)
connection->response->total_size);
+ (MHD_UNSIGNED_LONG_LONG) response->total_size);
must_add_content_length = MHD_YES;
}
@@ -1606,7 +1619,7 @@ build_header_response (struct MHD_Connection *connection)
(MHD_NO == must_add_close) &&
(MHD_CONN_MUST_CLOSE != connection->keepalive) &&
#ifdef UPGRADE_SUPPORT
- (NULL == connection->response->upgrade_handler) &&
+ (NULL == response->upgrade_handler) &&
#endif /* UPGRADE_SUPPORT */
(MHD_YES == keepalive_possible (connection)) )
must_add_keep_alive = MHD_YES;
@@ -1638,7 +1651,7 @@ build_header_response (struct MHD_Connection *connection)
mhd_assert (! (must_add_close && must_add_keep_alive) );
mhd_assert (! (must_add_chunked_encoding && must_add_content_length) );
- for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
+ for (pos = response->first_header; NULL != pos; pos = pos->next)
{
/* TODO: add proper support for excluding "Keep-Alive" token. */
if ( (pos->kind == kind) &&
@@ -1700,7 +1713,7 @@ build_header_response (struct MHD_Connection *connection)
content_length_len);
off += content_length_len;
}
- for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
+ for (pos = response->first_header; NULL != pos; pos = pos->next)
{
/* TODO: add proper support for excluding "Keep-Alive" token. */
if ( (pos->kind == kind) &&
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 9de4843d..d7835c20 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -119,6 +119,27 @@ MHD_add_response_header (struct MHD_Response *response,
const char *header,
const char *content)
{
+ if ( (MHD_str_equal_caseless_ (header,
+ MHD_HTTP_HEADER_TRANSFER_ENCODING)) &&
+ (! MHD_str_equal_caseless_ (content,
+ "identity")) &&
+ (! MHD_str_equal_caseless_ (content,
+ "chunked")) )
+ {
+ /* Setting transfer encodings other than "identity" or
+ "chunked" is not allowed. Note that MHD will set the
+ correct transfer encoding if required automatically. */
+ /* NOTE: for compressed bodies, use the "Content-encoding" header */
+ return MHD_NO;
+ }
+ if (MHD_str_equal_caseless_ (header,
+ MHD_HTTP_HEADER_CONTENT_LENGTH))
+ {
+ /* MHD will set Content-length if allowed and possible,
+ reject attempt by application */
+ return MHD_NO;
+ }
+
return add_response_entry (response,
MHD_HEADER_KIND,
header,
--
To stop receiving notification emails like this one, please contact
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [libmicrohttpd] branch master updated: fix #5411,
gnunet <=