Hi,

I attached a patch which adds a response flag to force version to HTTP 1.0
in
responses but still maintaining 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 I need to validate a client against
HTTP 1.1 AND HTTP 1.0 as I can start a single server for the whole set
of tests to run.

Do you think this is something you could consider integrating mainstream?

Regards,


Gauthier
From 900dec76fb169a1572714988f88fe965bbcdcab2 Mon Sep 17 00:00:00 2001
From: Gauthier Haderer <[email protected]>
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.
---
 src/include/microhttpd.h    | 13 ++++++++++++-
 src/microhttpd/connection.c |  7 +++++--
 2 files changed, 17 insertions(+), 3 deletions(-)

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
    * Only respond in conservative HTTP 1.0-mode.   In particular,
    * do not (automatically) sent "Connection" headers and always
    * close the connection after generating the response.
+   * By default, MHD will respond using the same HTTP version which
+   * was set in the request. You can also set the
+   * #MHD_RF_HTTP_VERSION_1_0_RESPONSE flag to force version 1.0
+   * in the response.
    */
-  MHD_RF_HTTP_VERSION_1_0_ONLY = 1
+  MHD_RF_HTTP_VERSION_1_0_ONLY = 1,
+
+  /**
+   * Only respond in HTTP 1.0-mode. Contrary to the
+   * #MHD_RF_HTTP_VERSION_1_0_ONLY flag, the response's HTTP version will
+   * always be set to 1.0 and "Connection" headers are still supported.
+   */
+  MHD_RF_HTTP_VERSION_1_0_RESPONSE = 2
 
 };
 
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)
     return MHD_NO;
 
   if (MHD_str_equal_caseless_(connection->version,
-                              MHD_HTTP_VERSION_1_1))
+                              MHD_HTTP_VERSION_1_1) &&
+      ( (NULL == connection->response) ||
+        (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_RESPONSE) ) ) )
     {
       if (MHD_lookup_header_s_token_ci (connection,
                                         MHD_HTTP_HEADER_CONNECTION,
@@ -1449,7 +1451,8 @@ build_header_response (struct MHD_Connection *connection)
 		     (0 != (connection->responseCode & MHD_ICY_FLAG))
 		     ? "ICY"
 		     : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0,
-						   connection->version))
+						   connection->version) ||
+		       (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) )
 			 ? MHD_HTTP_VERSION_1_0
 			 : MHD_HTTP_VERSION_1_1),
 		     rc,
-- 
2.17.1

Reply via email to