Improved handling of "Expect:" request header

Added error reply for unsupported values.
This commit is contained in:
Evgeny Grin (Karlson2k)
2024-09-13 21:00:05 +02:00
parent 55c30b6424
commit a32f2b28da
4 changed files with 59 additions and 14 deletions
+5
View File
@@ -582,6 +582,11 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_TRANSFER_ENCODING_UNSUPPORTED = 40067
,
/**
* "Expect:" value in request is unsupported or invalid.
*/
MHD_SC_EXPECT_HEADER_VALUE_UNSUPPORTED = 40068
,
/**
* The given uploaded, chunked-encoded body was malformed.
*/
+5
View File
@@ -582,6 +582,11 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
*/
MHD_SC_TRANSFER_ENCODING_UNSUPPORTED = 40067
,
/**
* "Expect:" value in request is unsupported or invalid.
*/
MHD_SC_EXPECT_HEADER_VALUE_UNSUPPORTED = 40068
,
/**
* The given uploaded, chunked-encoded body was malformed.
*/
+5
View File
@@ -322,6 +322,11 @@ struct MHD_Request
*/
union mhd_ReqContentParsingData u_proc;
/**
* Have "Expect: 100-continue" request header
*/
bool have_expect_100;
/**
* HTTP version string (i.e. http/1.1). Allocated
* in pool.
+44 -14
View File
@@ -362,6 +362,16 @@
"<body>The Transfer-Encoding used in request is not supported.</body>" \
"</html>"
/**
* Response text used when the request has unsupported "Expect:" value.
*/
#define ERR_RSP_UNSUPPORTED_EXPECT_HDR_VALUE \
"<html>" \
"<head><title>Unsupported 'Expect:'</title></head>" \
"<body>The value of 'Expect:' header used in the request is " \
"not supported.</body>" \
"</html>"
/**
* Response text used when the request has unsupported both headers:
* "Transfer-Encoding:" and "Content-Length:"
@@ -2750,6 +2760,31 @@ mhd_stream_parse_request_headers (struct MHD_Connection *restrict c)
continue;
}
#endif /* COOKIE_SUPPORT */
/* "Expect: 100-continue" */
if (mhd_str_equal_caseless_n_st (MHD_HTTP_HEADER_EXPECT,
f->field.nv.name.cstr,
f->field.nv.name.len))
{
if (mhd_str_equal_caseless_n_st ("100-continue",
f->field.nv.value.cstr,
f->field.nv.value.len))
c->rq.have_expect_100 = true;
else
{
if (0 < c->daemon->req_cfg.strictnees)
{
mhd_LOG_MSG (c->daemon, MHD_SC_EXPECT_HEADER_VALUE_UNSUPPORTED, \
"The 'Expect' header value used in request is " \
"unsupported or invalid.");
mhd_RESPOND_WITH_ERROR_STATIC (c,
MHD_HTTP_STATUS_EXPECTATION_FAILED,
ERR_RSP_UNSUPPORTED_EXPECT_HDR_VALUE);
return;
}
}
continue;
}
}
if (has_trenc && has_cntnlen)
@@ -2799,7 +2834,7 @@ mhd_stream_parse_request_headers (struct MHD_Connection *restrict c)
/**
* Is "100 CONTINUE" needed to be sent for current request?
* Is "100 Continue" needed to be sent for current request?
*
* @param c the connection to check
* @return false 100 CONTINUE is not needed,
@@ -2808,28 +2843,23 @@ mhd_stream_parse_request_headers (struct MHD_Connection *restrict c)
static MHD_FN_PAR_NONNULL_ALL_ bool
need_100_continue (struct MHD_Connection *restrict c)
{
const struct MHD_StringNullable *hvalue;
mhd_assert (MHD_HTTP_VERSION_IS_SUPPORTED (c->rq.http_ver));
mhd_assert (MHD_CONNECTION_HEADERS_PROCESSED <= c->state);
mhd_assert (MHD_CONNECTION_BODY_RECEIVING > c->state);
if (MHD_HTTP_VERSION_1_0 == c->rq.http_ver)
return false;
if (! c->rq.have_expect_100)
return false; /* "100 Continue" has not been requested by the client */
if (0 != c->read_buffer_offset)
return false; /* Part of the content has been received already */
hvalue = mhd_request_get_value_st (&(c->rq),
MHD_VK_HEADER,
MHD_HTTP_HEADER_EXPECT);
if (NULL == hvalue)
return false;
if (0 == c->rq.cntn.cntn_size)
return false; /* There is no content or zero-sized content for this request */
if (mhd_str_equal_caseless_n_st ("100-continue", \
hvalue->cstr, hvalue->len))
return true;
if (MHD_HTTP_VERSION_1_0 == c->rq.http_ver)
return false; /* '100 Continue' is not allowed for HTTP/1.0 */
return false;
return true;
}