aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-08-02 21:42:29 +0000
committerChristian Grothoff <christian@grothoff.org>2013-08-02 21:42:29 +0000
commitf55c9a8e984e5e28b66b0edf792c6de861b4daee (patch)
tree6e6b9693cd5f4b5c3bdd458f49bea82fc7e51079
parenta8f8a27bc027d4a0f565a6e4e579d64192f5b846 (diff)
downloadlibmicrohttpd-f55c9a8e984e5e28b66b0edf792c6de861b4daee.tar.gz
libmicrohttpd-f55c9a8e984e5e28b66b0edf792c6de861b4daee.zip
-fix connect/content-length handling
-rw-r--r--ChangeLog7
-rw-r--r--src/include/microhttpd.h2
-rw-r--r--src/microhttpd/connection.c98
-rw-r--r--src/microhttpd/connection_https.c1
4 files changed, 63 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index c13662cf..008bb249 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
1Fri Aug 2 20:55:47 CEST 2013
2 Fix HTTP 1.1 compliance with respect to not returning
3 content-length headers for successful "CONNECT" requests.
4 Note that for unsuccessful "CONNECT" requests with an
5 empty response body, users must now explicitly set the
6 content-length header. -CG
7
1Sun Jul 28 16:35:17 CEST 2013 8Sun Jul 28 16:35:17 CEST 2013
2 Fixing build issue (missing #ifdef) in conjunction with 9 Fixing build issue (missing #ifdef) in conjunction with
3 --disable-messages. -blueness 10 --disable-messages. -blueness
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 461c95cd..92827650 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -106,7 +106,7 @@ extern "C"
106/** 106/**
107 * Current version of the library. 107 * Current version of the library.
108 */ 108 */
109#define MHD_VERSION 0x00092104 109#define MHD_VERSION 0x00092105
110 110
111/** 111/**
112 * MHD-internal return code for "YES". 112 * MHD-internal return code for "YES".
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index cfe77edf..e198b6cd 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -141,24 +141,19 @@ MHD_get_connection_values (struct MHD_Connection *connection,
141 141
142 142
143/** 143/**
144 * This function can be used to append an entry to 144 * This function can be used to append an entry to the list of HTTP
145 * the list of HTTP headers of a connection (so that the 145 * headers of a connection (so that the MHD_get_connection_values
146 * MHD_get_connection_values function will return 146 * function will return them -- and the MHD PostProcessor will also
147 * them -- and the MHD PostProcessor will also 147 * see them). This maybe required in certain situations (see Mantis
148 * see them). This maybe required in certain 148 * #1399) where (broken) HTTP implementations fail to supply values
149 * situations (see Mantis #1399) where (broken) 149 * needed by the post processor (or other parts of the application).
150 * HTTP implementations fail to supply values needed 150 *
151 * by the post processor (or other parts of the 151 * This function MUST only be called from within the
152 * application). 152 * MHD_AccessHandlerCallback (otherwise, access maybe improperly
153 * <p> 153 * synchronized). Furthermore, the client must guarantee that the key
154 * This function MUST only be called from within 154 * and value arguments are 0-terminated strings that are NOT freed
155 * the MHD_AccessHandlerCallback (otherwise, access 155 * until the connection is closed. (The easiest way to do this is by
156 * maybe improperly synchronized). Furthermore, 156 * passing only arguments to permanently allocated strings.).
157 * the client must guarantee that the key and
158 * value arguments are 0-terminated strings that
159 * are NOT freed until the connection is closed.
160 * (The easiest way to do this is by passing only
161 * arguments to permanently allocated strings.).
162 * 157 *
163 * @param connection the connection for which a 158 * @param connection the connection for which a
164 * value should be set 159 * value should be set
@@ -186,15 +181,15 @@ MHD_set_connection_value (struct MHD_Connection *connection,
186 pos->next = NULL; 181 pos->next = NULL;
187 /* append 'pos' to the linked list of headers */ 182 /* append 'pos' to the linked list of headers */
188 if (NULL == connection->headers_received_tail) 183 if (NULL == connection->headers_received_tail)
189 { 184 {
190 connection->headers_received = pos; 185 connection->headers_received = pos;
191 connection->headers_received_tail = pos; 186 connection->headers_received_tail = pos;
192 } 187 }
193 else 188 else
194 { 189 {
195 connection->headers_received_tail->next = pos; 190 connection->headers_received_tail->next = pos;
196 connection->headers_received_tail = pos; 191 connection->headers_received_tail = pos;
197 } 192 }
198 return MHD_YES; 193 return MHD_YES;
199} 194}
200 195
@@ -550,9 +545,27 @@ add_extra_headers (struct MHD_Connection *connection)
550 add_close = MHD_YES; /* client asked for it, so add it */ 545 add_close = MHD_YES; /* client asked for it, so add it */
551 546
552 /* if not present, add content length */ 547 /* if not present, add content length */
553 if (NULL == MHD_get_response_header (connection->response, 548 if ( (NULL == MHD_get_response_header (connection->response,
554 MHD_HTTP_HEADER_CONTENT_LENGTH)) 549 MHD_HTTP_HEADER_CONTENT_LENGTH)) &&
550 ( (0 != strcasecmp (connection->method,
551 MHD_HTTP_METHOD_CONNECT)) ||
552 (0 != connection->response->total_size) ) )
555 { 553 {
554 /*
555 Here we add a content-length if one is missing; however,
556 for 'connect' methods, the responses MUST NOT include a
557 content-length header *if* the response code is 2xx (in
558 which case we expect there to be no body). Still,
559 as we don't know the response code here in some cases, we
560 simply only force adding a content-length header if this
561 is not a 'connect' or if the response is not empty
562 (which is kind of more sane, because if some crazy
563 application did return content with a 2xx status code,
564 then having a content-length might again be a good idea).
565
566 Note that the change from 'SHOULD NOT' to 'MUST NOT' is
567 a recent development of the HTTP 1.1 specification.
568 */
556 SPRINTF (buf, 569 SPRINTF (buf,
557 MHD_UNSIGNED_LONG_LONG_PRINTF, 570 MHD_UNSIGNED_LONG_LONG_PRINTF,
558 (MHD_UNSIGNED_LONG_LONG) connection->response->total_size); 571 (MHD_UNSIGNED_LONG_LONG) connection->response->total_size);
@@ -783,12 +796,12 @@ transmit_error_response (struct MHD_Connection *connection,
783 "Error %u (`%s') processing request, closing connection.\n", 796 "Error %u (`%s') processing request, closing connection.\n",
784 status_code, message); 797 status_code, message);
785#endif 798#endif
786 EXTRA_CHECK (connection->response == NULL); 799 EXTRA_CHECK (NULL == connection->response);
787 response = MHD_create_response_from_buffer (strlen (message), 800 response = MHD_create_response_from_buffer (strlen (message),
788 (void *) message, 801 (void *) message,
789 MHD_RESPMEM_PERSISTENT); 802 MHD_RESPMEM_PERSISTENT);
790 MHD_queue_response (connection, status_code, response); 803 MHD_queue_response (connection, status_code, response);
791 EXTRA_CHECK (connection->response != NULL); 804 EXTRA_CHECK (NULL != connection->response);
792 MHD_destroy_response (response); 805 MHD_destroy_response (response);
793 if (MHD_NO == build_header_response (connection)) 806 if (MHD_NO == build_header_response (connection))
794 { 807 {
@@ -1130,10 +1143,10 @@ parse_cookie_header (struct MHD_Connection *connection)
1130 hdr = MHD_lookup_connection_value (connection, 1143 hdr = MHD_lookup_connection_value (connection,
1131 MHD_HEADER_KIND, 1144 MHD_HEADER_KIND,
1132 MHD_HTTP_HEADER_COOKIE); 1145 MHD_HTTP_HEADER_COOKIE);
1133 if (hdr == NULL) 1146 if (NULL == hdr)
1134 return MHD_YES; 1147 return MHD_YES;
1135 cpy = MHD_pool_allocate (connection->pool, strlen (hdr) + 1, MHD_YES); 1148 cpy = MHD_pool_allocate (connection->pool, strlen (hdr) + 1, MHD_YES);
1136 if (cpy == NULL) 1149 if (NULL == cpy)
1137 { 1150 {
1138#if HAVE_MESSAGES 1151#if HAVE_MESSAGES
1139 MHD_DLOG (connection->daemon, "Not enough memory to parse cookies!\n"); 1152 MHD_DLOG (connection->daemon, "Not enough memory to parse cookies!\n");
@@ -1144,9 +1157,9 @@ parse_cookie_header (struct MHD_Connection *connection)
1144 } 1157 }
1145 memcpy (cpy, hdr, strlen (hdr) + 1); 1158 memcpy (cpy, hdr, strlen (hdr) + 1);
1146 pos = cpy; 1159 pos = cpy;
1147 while (pos != NULL) 1160 while (NULL != pos)
1148 { 1161 {
1149 while (*pos == ' ') 1162 while (' ' == *pos)
1150 pos++; /* skip spaces */ 1163 pos++; /* skip spaces */
1151 1164
1152 sce = pos; 1165 sce = pos;
@@ -1183,7 +1196,7 @@ parse_cookie_header (struct MHD_Connection *connection)
1183 } 1196 }
1184 if (semicolon[0] == '\0') 1197 if (semicolon[0] == '\0')
1185 semicolon = NULL; 1198 semicolon = NULL;
1186 if (semicolon != NULL) 1199 if (NULL != semicolon)
1187 { 1200 {
1188 semicolon[0] = '\0'; 1201 semicolon[0] = '\0';
1189 semicolon++; 1202 semicolon++;
@@ -1214,7 +1227,7 @@ static int
1214parse_initial_message_line (struct MHD_Connection *connection, char *line) 1227parse_initial_message_line (struct MHD_Connection *connection, char *line)
1215{ 1228{
1216 char *uri; 1229 char *uri;
1217 char *httpVersion; 1230 char *http_version;
1218 char *args; 1231 char *args;
1219 1232
1220 if (NULL == (uri = strchr (line, ' '))) 1233 if (NULL == (uri = strchr (line, ' ')))
@@ -1224,11 +1237,11 @@ parse_initial_message_line (struct MHD_Connection *connection, char *line)
1224 uri++; 1237 uri++;
1225 while (uri[0] == ' ') 1238 while (uri[0] == ' ')
1226 uri++; 1239 uri++;
1227 httpVersion = strchr (uri, ' '); 1240 http_version = strchr (uri, ' ');
1228 if (httpVersion != NULL) 1241 if (NULL != http_version)
1229 { 1242 {
1230 httpVersion[0] = '\0'; 1243 http_version[0] = '\0';
1231 httpVersion++; 1244 http_version++;
1232 } 1245 }
1233 if (connection->daemon->uri_log_callback != NULL) 1246 if (connection->daemon->uri_log_callback != NULL)
1234 connection->client_context 1247 connection->client_context
@@ -1246,10 +1259,10 @@ parse_initial_message_line (struct MHD_Connection *connection, char *line)
1246 connection, 1259 connection,
1247 uri); 1260 uri);
1248 connection->url = uri; 1261 connection->url = uri;
1249 if (NULL == httpVersion) 1262 if (NULL == http_version)
1250 connection->version = ""; 1263 connection->version = "";
1251 else 1264 else
1252 connection->version = httpVersion; 1265 connection->version = http_version;
1253 return MHD_YES; 1266 return MHD_YES;
1254} 1267}
1255 1268
@@ -1796,7 +1809,6 @@ update_last_activity (struct MHD_Connection *connection)
1796} 1809}
1797 1810
1798 1811
1799
1800/** 1812/**
1801 * This function handles a particular connection when it has been 1813 * This function handles a particular connection when it has been
1802 * determined that there is data to be read off a socket. 1814 * determined that there is data to be read off a socket.
diff --git a/src/microhttpd/connection_https.c b/src/microhttpd/connection_https.c
index 4f49d513..a03b45e2 100644
--- a/src/microhttpd/connection_https.c
+++ b/src/microhttpd/connection_https.c
@@ -131,7 +131,6 @@ MHD_tls_connection_handle_write (struct MHD_Connection *connection)
131static int 131static int
132MHD_tls_connection_handle_idle (struct MHD_Connection *connection) 132MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
133{ 133{
134 struct MHD_Daemon *daemon = connection->daemon;
135 unsigned int timeout; 134 unsigned int timeout;
136 135
137#if DEBUG_STATES 136#if DEBUG_STATES