aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-10-16 20:42:54 +0200
committerChristian Grothoff <christian@grothoff.org>2018-10-16 20:44:39 +0200
commit9199e5aa3ac29235ee0326bf6ebc70882c63c268 (patch)
treedd4bcd6c8a1a6b2cdb7de3e5278b306127befcec
parentf7ab8b59a30cbd3c4e1b09906df2d4ffdff0472e (diff)
downloadlibmicrohttpd-9199e5aa3ac29235ee0326bf6ebc70882c63c268.tar.gz
libmicrohttpd-9199e5aa3ac29235ee0326bf6ebc70882c63c268.zip
From: Gauthier Haderer <ghaderer@wyplay.com>
Date: Mon, 15 Oct 2018 14:11:39 +0200 Subject: [PATCH] Add response flag to force version to 1.0 and maintain connection management. The existing MHD_RF_HTTP_VERSION_1_0_ONLY flag already changes MHD's behavior to apply HTTP 1.0 rules for connection management. When enabled, MHD sends a response using the same version as used in the request (is this normal?). What I want is MHD responding as a HTTP 1.0 server with support for connection management headers would do. This is what the MHD_RF_HTTP_VERSION_1_0_RESPONSE response flag is for. You can even combine it with MHD_RF_HTTP_VERSION_1_0_ONLY to change the response's HTTP version while maintaining strict compliance with HTTP 1.0 regarding connection management. This solution is not perfect as this flag is set on the response which is created after header processing. So MHD will behave as a HTTP 1.1 server until the response is queued. It means that an invalid HTTP 1.1 request will fail even if the response is sent with HTTP 1.0 and the request would be valid if interpreted with this version. For example, this request will fail in strict mode: GET /dummy HTTP/1.1 as the Host header is missing and is mandatory in HTTP 1.1, but it should succeed when interpreted with HTTP 1.0. I don't think this is a big issue in practice. Besides, being able to change the HTTP version on a response basis is really convenient when using MHD in a test framework where we need to validate a client against HTTP 1.1 AND HTTP 1.0.
-rw-r--r--ChangeLog4
-rw-r--r--doc/libmicrohttpd.texi27
-rw-r--r--src/include/microhttpd.h13
-rw-r--r--src/microhttpd/connection.c7
4 files changed, 48 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index eb273daf..b8d2c8f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Tue Oct 16 20:43:41 CEST 2018
2 Add MHD_RF_HTTP_VERSION_1_0_RESPONSE option to make MHD
3 act more like an HTTP/1.0 server. -GH
4
1Fri Oct 5 18:44:45 CEST 2018 5Fri Oct 5 18:44:45 CEST 2018
2 MHD_add_response_header() now prevents applications from 6 MHD_add_response_header() now prevents applications from
3 setting a "Transfer-Encoding" header to values other than 7 setting a "Transfer-Encoding" header to values other than
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index b61c94ff..2ecb64e6 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -1144,6 +1144,33 @@ Only respond in conservative HTTP 1.0-mode. In particular,
1144do not (automatically) sent "Connection" headers and always 1144do not (automatically) sent "Connection" headers and always
1145close the connection after generating the response. 1145close the connection after generating the response.
1146 1146
1147By default, MHD will respond using the same HTTP version which
1148was set in the request. You can also set the
1149@code{MHD_RF_HTTP_VERSION_1_0_RESPONSE} flag to force version 1.0
1150in the response.
1151
1152@item MHD_RF_HTTP_VERSION_1_0_RESPONSE
1153Only respond in HTTP 1.0-mode. Contrary to the
1154@code{MHD_RF_HTTP_VERSION_1_0_ONLY} flag, the response's HTTP version will
1155always be set to 1.0 and ``Connection'' headers are still supported.
1156
1157You can even combine this option with MHD_RF_HTTP_VERSION_1_0_ONLY to
1158change the response's HTTP version while maintaining strict compliance
1159with HTTP 1.0 regarding connection management.
1160
1161This solution is not perfect as this flag is set on the response which
1162is created after header processing. So MHD will behave as a HTTP 1.1
1163server until the response is queued. It means that an invalid HTTP 1.1
1164request will fail even if the response is sent with HTTP 1.0 and the
1165request would be valid if interpreted with this version. For example,
1166this request will fail in strict mode:
1167
1168@verbatim
1169GET / HTTP/1.1
1170@end verbatim
1171
1172as the ``Host'' header is missing and is mandatory in HTTP 1.1, but it
1173should succeed when interpreted with HTTP 1.0.
1147@end table 1174@end table
1148@end deftp 1175@end deftp
1149 1176
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index dae41fba..70ecd6e9 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -2623,8 +2623,19 @@ enum MHD_ResponseFlags
2623 * Only respond in conservative HTTP 1.0-mode. In particular, 2623 * Only respond in conservative HTTP 1.0-mode. In particular,
2624 * do not (automatically) sent "Connection" headers and always 2624 * do not (automatically) sent "Connection" headers and always
2625 * close the connection after generating the response. 2625 * close the connection after generating the response.
2626 * By default, MHD will respond using the same HTTP version which
2627 * was set in the request. You can also set the
2628 * #MHD_RF_HTTP_VERSION_1_0_RESPONSE flag to force version 1.0
2629 * in the response.
2626 */ 2630 */
2627 MHD_RF_HTTP_VERSION_1_0_ONLY = 1 2631 MHD_RF_HTTP_VERSION_1_0_ONLY = 1,
2632
2633 /**
2634 * Only respond in HTTP 1.0-mode. Contrary to the
2635 * #MHD_RF_HTTP_VERSION_1_0_ONLY flag, the response's HTTP version will
2636 * always be set to 1.0 and "Connection" headers are still supported.
2637 */
2638 MHD_RF_HTTP_VERSION_1_0_RESPONSE = 2
2628 2639
2629}; 2640};
2630 2641
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 60dc5eb4..3e641d15 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1274,7 +1274,9 @@ keepalive_possible (struct MHD_Connection *connection)
1274 return MHD_NO; 1274 return MHD_NO;
1275 1275
1276 if (MHD_str_equal_caseless_(connection->version, 1276 if (MHD_str_equal_caseless_(connection->version,
1277 MHD_HTTP_VERSION_1_1)) 1277 MHD_HTTP_VERSION_1_1) &&
1278 ( (NULL == connection->response) ||
1279 (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_RESPONSE) ) ) )
1278 { 1280 {
1279 if (MHD_lookup_header_s_token_ci (connection, 1281 if (MHD_lookup_header_s_token_ci (connection,
1280 MHD_HTTP_HEADER_CONNECTION, 1282 MHD_HTTP_HEADER_CONNECTION,
@@ -1449,7 +1451,8 @@ build_header_response (struct MHD_Connection *connection)
1449 (0 != (connection->responseCode & MHD_ICY_FLAG)) 1451 (0 != (connection->responseCode & MHD_ICY_FLAG))
1450 ? "ICY" 1452 ? "ICY"
1451 : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0, 1453 : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0,
1452 connection->version)) 1454 connection->version) ||
1455 (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) )
1453 ? MHD_HTTP_VERSION_1_0 1456 ? MHD_HTTP_VERSION_1_0
1454 : MHD_HTTP_VERSION_1_1), 1457 : MHD_HTTP_VERSION_1_1),
1455 rc, 1458 rc,