aboutsummaryrefslogtreecommitdiff
path: root/src/lib/connection_call_handlers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/connection_call_handlers.c')
-rw-r--r--src/lib/connection_call_handlers.c715
1 files changed, 532 insertions, 183 deletions
diff --git a/src/lib/connection_call_handlers.c b/src/lib/connection_call_handlers.c
index 1eac9c10..346089a2 100644
--- a/src/lib/connection_call_handlers.c
+++ b/src/lib/connection_call_handlers.c
@@ -935,48 +935,405 @@ MHD_request_handle_write_ (struct MHD_Request *request)
935} 935}
936 936
937 937
938#if COMMENTED_OUT_FOR_REWRITE 938/**
939 * Convert @a method to the respective enum value.
940 *
941 * @param method the method string to look up enum value for
942 * @return resulting enum, or generic value for "unknown"
943 */
944static enum MHD_Method
945method_string_to_enum (const char *method)
946{
947 static const struct {
948 const char *key;
949 enum MHD_Method value;
950 } methods[] = {
951 { "OPTIONS", MHD_METHOD_OPTIONS },
952 { "GET", MHD_METHOD_GET },
953 { "HEAD", MHD_METHOD_HEAD },
954 { "POST", MHD_METHOD_POST },
955 { "PUT", MHD_METHOD_PUT },
956 { "DELETE", MHD_METHOD_DELETE },
957 { "TRACE", MHD_METHOD_TRACE },
958 { "CONNECT", MHD_METHOD_CONNECT },
959 { "ACL", MHD_METHOD_ACL },
960 { "BASELINE_CONTROL", MHD_METHOD_BASELINE_CONTROL },
961 { "BIND", MHD_METHOD_BIND },
962 { "CHECKIN", MHD_METHOD_CHECKIN },
963 { "CHECKOUT", MHD_METHOD_CHECKOUT },
964 { "COPY", MHD_METHOD_COPY },
965 { "LABEL", MHD_METHOD_LABEL },
966 { "LINK", MHD_METHOD_LINK },
967 { "LOCK", MHD_METHOD_LOCK },
968 { "MERGE", MHD_METHOD_MERGE },
969 { "MKACTIVITY", MHD_METHOD_MKACTIVITY },
970 { "MKCOL", MHD_METHOD_MKCOL },
971 { "MKREDIRECTREF", MHD_METHOD_MKREDIRECTREF },
972 { "MKWORKSPACE", MHD_METHOD_MKWORKSPACE },
973 { "MOVE", MHD_METHOD_MOVE },
974 { "ORDERPATCH", MHD_METHOD_ORDERPATCH },
975 { "PRI", MHD_METHOD_PRI },
976 { "PROPFIND", MHD_METHOD_PROPFIND },
977 { "PROPPATCH", MHD_METHOD_PROPPATCH },
978 { "REBIND", MHD_METHOD_REBIND },
979 { "REPORT", MHD_METHOD_REPORT },
980 { "SEARCH", MHD_METHOD_SEARCH },
981 { "UNBIND", MHD_METHOD_UNBIND },
982 { "UNCHECKOUT", MHD_METHOD_UNCHECKOUT },
983 { "UNLINK", MHD_METHOD_UNLINK },
984 { "UNLOCK", MHD_METHOD_UNLOCK },
985 { "UPDATE", MHD_METHOD_UPDATE },
986 { "UPDATEDIRECTREF", MHD_METHOD_UPDATEDIRECTREF },
987 { "VERSION-CONTROL", MHD_METHOD_VERSION_CONTROL },
988 { NULL, MHD_METHOD_UNKNOWN } /* must be last! */
989 };
990 unsigned int i;
991
992 for (i=0;NULL != methods[i].key;i++)
993 if (0 ==
994 MHD_str_equal_caseless_ (method,
995 methods[i].key))
996 return methods[i].value;
997 return MHD_METHOD_UNKNOWN;
998}
999
1000
1001/**
1002 * Parse the first line of the HTTP HEADER.
1003 *
1004 * @param connection the connection (updated)
1005 * @param line the first line, not 0-terminated
1006 * @param line_len length of the first @a line
1007 * @return true if the line is ok, false if it is malformed
1008 */
1009static bool
1010parse_initial_message_line (struct MHD_Request *request,
1011 char *line,
1012 size_t line_len)
1013{
1014 struct MHD_Connection *connection = request->connection;
1015 struct MHD_Daemon *daemon = request->daemon;
1016 const char *curi;
1017 char *uri;
1018 char *http_version;
1019 char *args;
1020 unsigned int unused_num_headers;
1021
1022 if (NULL == (uri = memchr (line,
1023 ' ',
1024 line_len)))
1025 return false; /* serious error */
1026 uri[0] = '\0';
1027 request->method_s = line;
1028 request->method = method_string_to_enum (line);
1029 uri++;
1030 /* Skip any spaces. Not required by standard but allow
1031 to be more tolerant. */
1032 while ( (' ' == uri[0]) &&
1033 ( (size_t)(uri - line) < line_len) )
1034 uri++;
1035 if ((size_t)(uri - line) == line_len)
1036 {
1037 curi = "";
1038 uri = NULL;
1039 request->version = "";
1040 args = NULL;
1041 }
1042 else
1043 {
1044 curi = uri;
1045 /* Search from back to accept misformed URI with space */
1046 http_version = line + line_len - 1;
1047 /* Skip any trailing spaces */
1048 while ( (' ' == http_version[0]) &&
1049 (http_version > uri) )
1050 http_version--;
1051 /* Find first space in reverse direction */
1052 while ( (' ' != http_version[0]) &&
1053 (http_version > uri) )
1054 http_version--;
1055 if (http_version > uri)
1056 {
1057 http_version[0] = '\0';
1058 request->version = http_version + 1;
1059 args = memchr (uri,
1060 '?',
1061 http_version - uri);
1062 }
1063 else
1064 {
1065 request->version = "";
1066 args = memchr (uri,
1067 '?',
1068 line_len - (uri - line));
1069 }
1070 }
1071 if (NULL != daemon->uri_log_callback)
1072 {
1073 request->client_aware = true;
1074 request->client_context
1075 = daemon->early_uri_logger_cb (daemon->early_uri_logger_cb_cls,
1076 curi,
1077 request);
1078 }
1079 if (NULL != args)
1080 {
1081 args[0] = '\0';
1082 args++;
1083 /* note that this call clobbers 'args' */
1084 MHD_parse_arguments_ (connection,
1085 MHD_GET_ARGUMENT_KIND,
1086 args,
1087 &connection_add_header,
1088 &unused_num_headers);
1089 }
1090 if (NULL != uri)
1091 daemon->unescape_cb (daemon->unescape_cb_cls,
1092 request,
1093 uri);
1094 request->url = curi;
1095 return MHD_YES;
1096}
1097
1098
1099/**
1100 * Add an entry to the HTTP headers of a request. If this fails,
1101 * transmit an error response (request too big).
1102 *
1103 * @param request the request for which a value should be set
1104 * @param kind kind of the value
1105 * @param key key for the value
1106 * @param value the value itself
1107 * @return false on failure (out of memory), true for success
1108 */
1109static bool
1110connection_add_header (struct MHD_Request *request,
1111 const char *key,
1112 const char *value,
1113 enum MHD_ValueKind kind)
1114{
1115 if (MHD_NO ==
1116 MHD_request_set_value (request,
1117 kind,
1118 key,
1119 value))
1120 {
1121#ifdef HAVE_MESSAGES
1122 MHD_DLOG (request->daemon,
1123 _("Not enough memory in pool to allocate header record!\n"));
1124#endif
1125 transmit_error_response (request->connection,
1126 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
1127 REQUEST_TOO_BIG);
1128 return false;
1129 }
1130 return true;
1131}
1132
1133
1134/**
1135 * We have received (possibly the beginning of) a line in the
1136 * header (or footer). Validate (check for ":") and prepare
1137 * to process.
1138 *
1139 * @param request the request we're processing
1140 * @param line line from the header to process
1141 * @return true on success, false on error (malformed @a line)
1142 */
1143static bool
1144process_header_line (struct MHD_Request *request,
1145 char *line)
1146{
1147 struct MHD_Connection *connection = request->connection;
1148 char *colon;
1149
1150 /* line should be normal header line, find colon */
1151 colon = strchr (line, ':');
1152 if (NULL == colon)
1153 {
1154 /* error in header line, die hard */
1155 CONNECTION_CLOSE_ERROR (connection,
1156 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1157 _("Received malformed line (no colon). Closing connection.\n"));
1158 return false;
1159 }
1160 if (-1 >= request->daemon->strict_for_client)
1161 {
1162 /* check for whitespace before colon, which is not allowed
1163 by RFC 7230 section 3.2.4; we count space ' ' and
1164 tab '\t', but not '\r\n' as those would have ended the line. */
1165 const char *white;
1166
1167 white = strchr (line,
1168 (unsigned char) ' ');
1169 if ( (NULL != white) &&
1170 (white < colon) )
1171 {
1172 CONNECTION_CLOSE_ERROR (connection,
1173 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1174 _("Whitespace before colon forbidden by RFC 7230. Closing connection.\n"));
1175 return false;
1176 }
1177 white = strchr (line,
1178 (unsigned char) '\t');
1179 if ( (NULL != white) &&
1180 (white < colon) )
1181 {
1182 CONNECTION_CLOSE_ERROR (connection,
1183 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1184 _("Tab before colon forbidden by RFC 7230. Closing connection.\n"));
1185 return false;
1186 }
1187 }
1188 /* zero-terminate header */
1189 colon[0] = '\0';
1190 colon++; /* advance to value */
1191 while ( ('\0' != colon[0]) &&
1192 ( (' ' == colon[0]) ||
1193 ('\t' == colon[0]) ) )
1194 colon++;
1195 /* we do the actual adding of the connection
1196 header at the beginning of the while
1197 loop since we need to be able to inspect
1198 the *next* header line (in case it starts
1199 with a space...) */
1200 request->last = line;
1201 request->colon = colon;
1202 return true;
1203}
939 1204
940 1205
941/** 1206/**
942 * This function was created to handle per-connection processing that 1207 * Process a header value that spans multiple lines.
1208 * The previous line(s) are in connection->last.
1209 *
1210 * @param request the request we're processing
1211 * @param line the current input line
1212 * @param kind if the line is complete, add a header
1213 * of the given kind
1214 * @return true if the line was processed successfully
1215 */
1216static bool
1217process_broken_line (struct MHD_Request *request,
1218 char *line,
1219 enum MHD_ValueKind kind)
1220{
1221 struct MHD_Connection *connection = request->connection;
1222 char *last;
1223 char *tmp;
1224 size_t last_len;
1225 size_t tmp_len;
1226
1227 last = request->last;
1228 if ( (' ' == line[0]) ||
1229 ('\t' == line[0]) )
1230 {
1231 /* value was continued on the next line, see
1232 http://www.jmarshall.com/easy/http/ */
1233 last_len = strlen (last);
1234 /* skip whitespace at start of 2nd line */
1235 tmp = line;
1236 while ( (' ' == tmp[0]) ||
1237 ('\t' == tmp[0]) )
1238 tmp++;
1239 tmp_len = strlen (tmp);
1240 /* FIXME: we might be able to do this better (faster!), as most
1241 likely 'last' and 'line' should already be adjacent in
1242 memory; however, doing this right gets tricky if we have a
1243 value continued over multiple lines (in which case we need to
1244 record how often we have done this so we can check for
1245 adjacency); also, in the case where these are not adjacent
1246 (not sure how it can happen!), we would want to allocate from
1247 the end of the pool, so as to not destroy the read-buffer's
1248 ability to grow nicely. */
1249 last = MHD_pool_reallocate (connection->pool,
1250 last,
1251 last_len + 1,
1252 last_len + tmp_len + 1);
1253 if (NULL == last)
1254 {
1255 transmit_error_response (connection,
1256 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
1257 REQUEST_TOO_BIG);
1258 return MHD_NO;
1259 }
1260 memcpy (&last[last_len],
1261 tmp,
1262 tmp_len + 1);
1263 request->last = last;
1264 return MHD_YES; /* possibly more than 2 lines... */
1265 }
1266 mhd_assert ( (NULL != last) &&
1267 (NULL != request->colon) );
1268 if (! request_add_header (request,
1269 last,
1270 request->colon,
1271 kind))
1272 {
1273 transmit_error_response (connection,
1274 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
1275 REQUEST_TOO_BIG);
1276 return false;
1277 }
1278 /* we still have the current line to deal with... */
1279 if ('\0' != line[0])
1280 {
1281 if (! process_header_line (request,
1282 line))
1283 {
1284 transmit_error_response (connection,
1285 MHD_HTTP_BAD_REQUEST,
1286 REQUEST_MALFORMED);
1287 return false;
1288 }
1289 }
1290 return true;
1291}
1292
1293
1294#ifdef REWRITE_IN_PROGRESS
1295
1296/**
1297 * This function was created to handle per-request processing that
943 * has to happen even if the socket cannot be read or written to. 1298 * has to happen even if the socket cannot be read or written to.
944 * @remark To be called only from thread that process connection's 1299 * @remark To be called only from thread that process request's
945 * recv(), send() and response. 1300 * recv(), send() and response.
946 * 1301 *
947 * @param connection connection to handle 1302 * @param request the request to handle
948 * @return #MHD_YES if we should continue to process the 1303 * @return true if we should continue to process the
949 * connection (not dead yet), #MHD_NO if it died 1304 * request (not dead yet), false if it died
950 */ 1305 */
951int 1306bool
952MHD_connection_handle_idle (struct MHD_Connection *connection) 1307MHD_request_handle_idle (struct MHD_Request *request)
953{ 1308{
954 struct MHD_Daemon *daemon = connection->daemon; 1309 struct MHD_Daemon *daemon = request->daemon;
1310 struct MHD_Connection *connection = request->connection;
955 char *line; 1311 char *line;
956 size_t line_len; 1312 size_t line_len;
957 int ret; 1313 int ret;
958 1314
959 connection->in_idle = true; 1315 request->in_idle = true;
960 while (! connection->suspended) 1316 while (! connection->suspended)
961 { 1317 {
962#ifdef HTTPS_SUPPORT 1318#ifdef HTTPS_SUPPORT
963 if (MHD_TLS_CONN_NO_TLS != connection->tls_state) 1319 struct MHD_TLS_Plugin *tls;
964 { /* HTTPS connection. */ 1320
965 if ((MHD_TLS_CONN_INIT <= connection->tls_state) && 1321 if ( (NULL != (tls = daemon->tls_api)) &&
966 (MHD_TLS_CONN_CONNECTED > connection->tls_state)) 1322 (! tls->idle_ready (tls->cls,
967 break; 1323 connection->tls_cs)) )
968 } 1324 break;
969#endif /* HTTPS_SUPPORT */ 1325#endif /* HTTPS_SUPPORT */
970#if DEBUG_STATES 1326#if DEBUG_STATES
971 MHD_DLOG (daemon, 1327 MHD_DLOG (daemon,
1328 MHD_SC_STATE_MACHINE_STATUS_REPORT,
972 _("In function %s handling connection at state: %s\n"), 1329 _("In function %s handling connection at state: %s\n"),
973 __FUNCTION__, 1330 __FUNCTION__,
974 MHD_state_to_string (connection->state)); 1331 MHD_state_to_string (request->state));
975#endif 1332#endif
976 switch (connection->state) 1333 switch (request->state)
977 { 1334 {
978 case MHD_CONNECTION_INIT: 1335 case MHD_REQUEST_INIT:
979 line = get_next_header_line (connection, 1336 line = get_next_header_line (request,
980 &line_len); 1337 &line_len);
981 /* Check for empty string, as we might want 1338 /* Check for empty string, as we might want
982 to tolerate 'spurious' empty lines; also 1339 to tolerate 'spurious' empty lines; also
@@ -985,34 +1342,37 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
985 if ( (NULL == line) || 1342 if ( (NULL == line) ||
986 (0 == line[0]) ) 1343 (0 == line[0]) )
987 { 1344 {
988 if (MHD_CONNECTION_INIT != connection->state) 1345 if (MHD_REQUEST_INIT != request->state)
989 continue; 1346 continue;
990 if (connection->read_closed) 1347 if (connection->read_closed)
991 { 1348 {
992 CONNECTION_CLOSE_ERROR (connection, 1349 CONNECTION_CLOSE_ERROR (connection,
1350 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
993 NULL); 1351 NULL);
994 continue; 1352 continue;
995 } 1353 }
996 break; 1354 break;
997 } 1355 }
998 if (MHD_NO == parse_initial_message_line (connection, 1356 if (MHD_NO ==
999 line, 1357 parse_initial_message_line (request,
1000 line_len)) 1358 line,
1359 line_len))
1001 CONNECTION_CLOSE_ERROR (connection, 1360 CONNECTION_CLOSE_ERROR (connection,
1002 NULL); 1361 NULL);
1003 else 1362 else
1004 connection->state = MHD_CONNECTION_URL_RECEIVED; 1363 request->state = MHD_REQUEST_URL_RECEIVED;
1005 continue; 1364 continue;
1006 case MHD_CONNECTION_URL_RECEIVED: 1365 case MHD_REQUEST_URL_RECEIVED:
1007 line = get_next_header_line (connection, 1366 line = get_next_header_line (request,
1008 NULL); 1367 NULL);
1009 if (NULL == line) 1368 if (NULL == line)
1010 { 1369 {
1011 if (MHD_CONNECTION_URL_RECEIVED != connection->state) 1370 if (MHD_REQUEST_URL_RECEIVED != request->state)
1012 continue; 1371 continue;
1013 if (connection->read_closed) 1372 if (connection->read_closed)
1014 { 1373 {
1015 CONNECTION_CLOSE_ERROR (connection, 1374 CONNECTION_CLOSE_ERROR (connection,
1375 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
1016 NULL); 1376 NULL);
1017 continue; 1377 continue;
1018 } 1378 }
@@ -1020,126 +1380,126 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1020 } 1380 }
1021 if (0 == line[0]) 1381 if (0 == line[0])
1022 { 1382 {
1023 connection->state = MHD_CONNECTION_HEADERS_RECEIVED; 1383 request->state = MHD_REQUEST_HEADERS_RECEIVED;
1024 connection->header_size = (size_t) (line - connection->read_buffer); 1384 request->header_size = (size_t) (line - request->read_buffer);
1025 continue; 1385 continue;
1026 } 1386 }
1027 if (MHD_NO == process_header_line (connection, 1387 if (! process_header_line (request,
1028 line)) 1388 line))
1029 { 1389 {
1030 transmit_error_response (connection, 1390 transmit_error_response (connection,
1031 MHD_HTTP_BAD_REQUEST, 1391 MHD_HTTP_BAD_REQUEST,
1032 REQUEST_MALFORMED); 1392 REQUEST_MALFORMED);
1033 break; 1393 break;
1034 } 1394 }
1035 connection->state = MHD_CONNECTION_HEADER_PART_RECEIVED; 1395 request->state = MHD_REQUEST_HEADER_PART_RECEIVED;
1036 continue; 1396 continue;
1037 case MHD_CONNECTION_HEADER_PART_RECEIVED: 1397 case MHD_REQUEST_HEADER_PART_RECEIVED:
1038 line = get_next_header_line (connection, 1398 line = get_next_header_line (request,
1039 NULL); 1399 NULL);
1040 if (NULL == line) 1400 if (NULL == line)
1041 { 1401 {
1042 if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED) 1402 if (request->state != MHD_REQUEST_HEADER_PART_RECEIVED)
1043 continue; 1403 continue;
1044 if (connection->read_closed) 1404 if (connection->read_closed)
1045 { 1405 {
1046 CONNECTION_CLOSE_ERROR (connection, 1406 CONNECTION_CLOSE_ERROR (connection,
1407 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
1047 NULL); 1408 NULL);
1048 continue; 1409 continue;
1049 } 1410 }
1050 break; 1411 break;
1051 } 1412 }
1052 if (MHD_NO == 1413 if (MHD_NO ==
1053 process_broken_line (connection, 1414 process_broken_line (request,
1054 line, 1415 line,
1055 MHD_HEADER_KIND)) 1416 MHD_HEADER_KIND))
1056 continue; 1417 continue;
1057 if (0 == line[0]) 1418 if (0 == line[0])
1058 { 1419 {
1059 connection->state = MHD_CONNECTION_HEADERS_RECEIVED; 1420 request->state = MHD_REQUEST_HEADERS_RECEIVED;
1060 connection->header_size = (size_t) (line - connection->read_buffer); 1421 request->header_size = (size_t) (line - request->read_buffer);
1061 continue; 1422 continue;
1062 } 1423 }
1063 continue; 1424 continue;
1064 case MHD_CONNECTION_HEADERS_RECEIVED: 1425 case MHD_REQUEST_HEADERS_RECEIVED:
1065 parse_connection_headers (connection); 1426 parse_request_headers (request);
1066 if (MHD_CONNECTION_CLOSED == connection->state) 1427 if (MHD_REQUEST_CLOSED == request->state)
1067 continue; 1428 continue;
1068 connection->state = MHD_CONNECTION_HEADERS_PROCESSED; 1429 request->state = MHD_REQUEST_HEADERS_PROCESSED;
1069 if (connection->suspended) 1430 if (connection->suspended)
1070 break; 1431 break;
1071 continue; 1432 continue;
1072 case MHD_CONNECTION_HEADERS_PROCESSED: 1433 case MHD_REQUEST_HEADERS_PROCESSED:
1073 call_connection_handler (connection); /* first call */ 1434 call_request_handler (request); /* first call */
1074 if (MHD_CONNECTION_CLOSED == connection->state) 1435 if (MHD_REQUEST_CLOSED == request->state)
1075 continue; 1436 continue;
1076 if (need_100_continue (connection)) 1437 if (need_100_continue (request))
1077 { 1438 {
1078 connection->state = MHD_CONNECTION_CONTINUE_SENDING; 1439 request->state = MHD_REQUEST_CONTINUE_SENDING;
1079 if (MHD_NO != socket_flush_possible (connection)) 1440 if (socket_flush_possible (connection))
1080 socket_start_extra_buffering (connection); 1441 socket_start_extra_buffering (connection);
1081 else 1442 else
1082 socket_start_no_buffering (connection); 1443 socket_start_no_buffering (connection);
1083
1084 break; 1444 break;
1085 } 1445 }
1086 if ( (NULL != connection->response) && 1446 if ( (NULL != request->response) &&
1087 ( (MHD_str_equal_caseless_ (connection->method, 1447 ( (MHD_str_equal_caseless_ (request->method,
1088 MHD_HTTP_METHOD_POST)) || 1448 MHD_HTTP_METHOD_POST)) ||
1089 (MHD_str_equal_caseless_ (connection->method, 1449 (MHD_str_equal_caseless_ (request->method,
1090 MHD_HTTP_METHOD_PUT))) ) 1450 MHD_HTTP_METHOD_PUT))) )
1091 { 1451 {
1092 /* we refused (no upload allowed!) */ 1452 /* we refused (no upload allowed!) */
1093 connection->remaining_upload_size = 0; 1453 request->remaining_upload_size = 0;
1094 /* force close, in case client still tries to upload... */ 1454 /* force close, in case client still tries to upload... */
1095 connection->read_closed = true; 1455 connection->read_closed = true;
1096 } 1456 }
1097 connection->state = (0 == connection->remaining_upload_size) 1457 request->state = (0 == request->remaining_upload_size)
1098 ? MHD_CONNECTION_FOOTERS_RECEIVED : MHD_CONNECTION_CONTINUE_SENT; 1458 ? MHD_REQUEST_FOOTERS_RECEIVED : MHD_REQUEST_CONTINUE_SENT;
1099 if (connection->suspended) 1459 if (connection->suspended)
1100 break; 1460 break;
1101 continue; 1461 continue;
1102 case MHD_CONNECTION_CONTINUE_SENDING: 1462 case MHD_REQUEST_CONTINUE_SENDING:
1103 if (connection->continue_message_write_offset == 1463 if (request->continue_message_write_offset ==
1104 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) 1464 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE))
1105 { 1465 {
1106 connection->state = MHD_CONNECTION_CONTINUE_SENT; 1466 request->state = MHD_REQUEST_CONTINUE_SENT;
1107 if (MHD_NO != socket_flush_possible (connection)) 1467 if (MHD_NO != socket_flush_possible (request))
1108 socket_start_no_buffering_flush (connection); 1468 socket_start_no_buffering_flush (request);
1109 else 1469 else
1110 socket_start_normal_buffering (connection); 1470 socket_start_normal_buffering (request);
1111 1471
1112 continue; 1472 continue;
1113 } 1473 }
1114 break; 1474 break;
1115 case MHD_CONNECTION_CONTINUE_SENT: 1475 case MHD_REQUEST_CONTINUE_SENT:
1116 if (0 != connection->read_buffer_offset) 1476 if (0 != request->read_buffer_offset)
1117 { 1477 {
1118 process_request_body (connection); /* loop call */ 1478 process_request_body (request); /* loop call */
1119 if (MHD_CONNECTION_CLOSED == connection->state) 1479 if (MHD_REQUEST_CLOSED == request->state)
1120 continue; 1480 continue;
1121 } 1481 }
1122 if ( (0 == connection->remaining_upload_size) || 1482 if ( (0 == request->remaining_upload_size) ||
1123 ( (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) && 1483 ( (MHD_SIZE_UNKNOWN == request->remaining_upload_size) &&
1124 (0 == connection->read_buffer_offset) && 1484 (0 == request->read_buffer_offset) &&
1125 (connection->read_closed) ) ) 1485 (request->read_closed) ) )
1126 { 1486 {
1127 if ( (connection->have_chunked_upload) && 1487 if ( (request->have_chunked_upload) &&
1128 (! connection->read_closed) ) 1488 (! request->read_closed) )
1129 connection->state = MHD_CONNECTION_BODY_RECEIVED; 1489 request->state = MHD_REQUEST_BODY_RECEIVED;
1130 else 1490 else
1131 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 1491 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
1132 if (connection->suspended) 1492 if (connection->suspended)
1133 break; 1493 break;
1134 continue; 1494 continue;
1135 } 1495 }
1136 break; 1496 break;
1137 case MHD_CONNECTION_BODY_RECEIVED: 1497 case MHD_REQUEST_BODY_RECEIVED:
1138 line = get_next_header_line (connection, 1498 line = get_next_header_line (request,
1139 NULL); 1499 NULL);
1140 if (NULL == line) 1500 if (NULL == line)
1141 { 1501 {
1142 if (connection->state != MHD_CONNECTION_BODY_RECEIVED) 1502 if (request->state != MHD_REQUEST_BODY_RECEIVED)
1143 continue; 1503 continue;
1144 if (connection->read_closed) 1504 if (connection->read_closed)
1145 { 1505 {
@@ -1151,12 +1511,12 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1151 } 1511 }
1152 if (0 == line[0]) 1512 if (0 == line[0])
1153 { 1513 {
1154 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 1514 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
1155 if (connection->suspended) 1515 if (connection->suspended)
1156 break; 1516 break;
1157 continue; 1517 continue;
1158 } 1518 }
1159 if (MHD_NO == process_header_line (connection, 1519 if (MHD_NO == process_header_line (request,
1160 line)) 1520 line))
1161 { 1521 {
1162 transmit_error_response (connection, 1522 transmit_error_response (connection,
@@ -1164,14 +1524,14 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1164 REQUEST_MALFORMED); 1524 REQUEST_MALFORMED);
1165 break; 1525 break;
1166 } 1526 }
1167 connection->state = MHD_CONNECTION_FOOTER_PART_RECEIVED; 1527 request->state = MHD_REQUEST_FOOTER_PART_RECEIVED;
1168 continue; 1528 continue;
1169 case MHD_CONNECTION_FOOTER_PART_RECEIVED: 1529 case MHD_REQUEST_FOOTER_PART_RECEIVED:
1170 line = get_next_header_line (connection, 1530 line = get_next_header_line (request,
1171 NULL); 1531 NULL);
1172 if (NULL == line) 1532 if (NULL == line)
1173 { 1533 {
1174 if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED) 1534 if (request->state != MHD_REQUEST_FOOTER_PART_RECEIVED)
1175 continue; 1535 continue;
1176 if (connection->read_closed) 1536 if (connection->read_closed)
1177 { 1537 {
@@ -1182,66 +1542,66 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1182 break; 1542 break;
1183 } 1543 }
1184 if (MHD_NO == 1544 if (MHD_NO ==
1185 process_broken_line (connection, 1545 process_broken_line (request,
1186 line, 1546 line,
1187 MHD_FOOTER_KIND)) 1547 MHD_FOOTER_KIND))
1188 continue; 1548 continue;
1189 if (0 == line[0]) 1549 if (0 == line[0])
1190 { 1550 {
1191 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 1551 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
1192 if (connection->suspended) 1552 if (connection->suspended)
1193 break; 1553 break;
1194 continue; 1554 continue;
1195 } 1555 }
1196 continue; 1556 continue;
1197 case MHD_CONNECTION_FOOTERS_RECEIVED: 1557 case MHD_REQUEST_FOOTERS_RECEIVED:
1198 call_connection_handler (connection); /* "final" call */ 1558 call_request_handler (request); /* "final" call */
1199 if (connection->state == MHD_CONNECTION_CLOSED) 1559 if (request->state == MHD_REQUEST_CLOSED)
1200 continue; 1560 continue;
1201 if (NULL == connection->response) 1561 if (NULL == request->response)
1202 break; /* try again next time */ 1562 break; /* try again next time */
1203 if (MHD_NO == build_header_response (connection)) 1563 if (MHD_NO == build_header_response (request))
1204 { 1564 {
1205 /* oops - close! */ 1565 /* oops - close! */
1206 CONNECTION_CLOSE_ERROR (connection, 1566 CONNECTION_CLOSE_ERROR (connection,
1207 _("Closing connection (failed to create response header)\n")); 1567 _("Closing connection (failed to create response header)\n"));
1208 continue; 1568 continue;
1209 } 1569 }
1210 connection->state = MHD_CONNECTION_HEADERS_SENDING; 1570 request->state = MHD_REQUEST_HEADERS_SENDING;
1211 if (MHD_NO != socket_flush_possible (connection)) 1571 if (MHD_NO != socket_flush_possible (connection))
1212 socket_start_extra_buffering (connection); 1572 socket_start_extra_buffering (connection);
1213 else 1573 else
1214 socket_start_no_buffering (connection); 1574 socket_start_no_buffering (connection);
1215 1575
1216 break; 1576 break;
1217 case MHD_CONNECTION_HEADERS_SENDING: 1577 case MHD_REQUEST_HEADERS_SENDING:
1218 /* no default action */ 1578 /* no default action */
1219 break; 1579 break;
1220 case MHD_CONNECTION_HEADERS_SENT: 1580 case MHD_REQUEST_HEADERS_SENT:
1221 /* Some clients may take some actions right after header receive */ 1581 /* Some clients may take some actions right after header receive */
1222 if (MHD_NO != socket_flush_possible (connection)) 1582 if (MHD_NO != socket_flush_possible (connection))
1223 socket_start_no_buffering_flush (connection); 1583 socket_start_no_buffering_flush (connection);
1224 1584
1225#ifdef UPGRADE_SUPPORT 1585#ifdef UPGRADE_SUPPORT
1226 if (NULL != connection->response->upgrade_handler) 1586 if (NULL != request->response->upgrade_handler)
1227 { 1587 {
1228 socket_start_normal_buffering (connection); 1588 socket_start_normal_buffering (connection);
1229 connection->state = MHD_CONNECTION_UPGRADE; 1589 request->state = MHD_REQUEST_UPGRADE;
1230 /* This connection is "upgraded". Pass socket to application. */ 1590 /* This request is "upgraded". Pass socket to application. */
1231 if (MHD_YES != 1591 if (MHD_YES !=
1232 MHD_response_execute_upgrade_ (connection->response, 1592 MHD_response_execute_upgrade_ (request->response,
1233 connection)) 1593 request))
1234 { 1594 {
1235 /* upgrade failed, fail hard */ 1595 /* upgrade failed, fail hard */
1236 CONNECTION_CLOSE_ERROR (connection, 1596 CONNECTION_CLOSE_ERROR (connection,
1237 NULL); 1597 NULL);
1238 continue; 1598 continue;
1239 } 1599 }
1240 /* Response is not required anymore for this connection. */ 1600 /* Response is not required anymore for this request. */
1241 if (NULL != connection->response) 1601 if (NULL != request->response)
1242 { 1602 {
1243 struct MHD_Response * const resp = connection->response; 1603 struct MHD_Response * const resp = request->response;
1244 connection->response = NULL; 1604 request->response = NULL;
1245 MHD_destroy_response (resp); 1605 MHD_destroy_response (resp);
1246 } 1606 }
1247 continue; 1607 continue;
@@ -1252,29 +1612,29 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1252 else 1612 else
1253 socket_start_normal_buffering (connection); 1613 socket_start_normal_buffering (connection);
1254 1614
1255 if (connection->have_chunked_upload) 1615 if (request->have_chunked_upload)
1256 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY; 1616 request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY;
1257 else 1617 else
1258 connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY; 1618 request->state = MHD_REQUEST_NORMAL_BODY_UNREADY;
1259 continue; 1619 continue;
1260 case MHD_CONNECTION_NORMAL_BODY_READY: 1620 case MHD_REQUEST_NORMAL_BODY_READY:
1261 /* nothing to do here */ 1621 /* nothing to do here */
1262 break; 1622 break;
1263 case MHD_CONNECTION_NORMAL_BODY_UNREADY: 1623 case MHD_REQUEST_NORMAL_BODY_UNREADY:
1264 if (NULL != connection->response->crc) 1624 if (NULL != request->response->crc)
1265 MHD_mutex_lock_chk_ (&connection->response->mutex); 1625 MHD_mutex_lock_chk_ (&request->response->mutex);
1266 if (0 == connection->response->total_size) 1626 if (0 == request->response->total_size)
1267 { 1627 {
1268 if (NULL != connection->response->crc) 1628 if (NULL != request->response->crc)
1269 MHD_mutex_unlock_chk_ (&connection->response->mutex); 1629 MHD_mutex_unlock_chk_ (&request->response->mutex);
1270 connection->state = MHD_CONNECTION_BODY_SENT; 1630 request->state = MHD_REQUEST_BODY_SENT;
1271 continue; 1631 continue;
1272 } 1632 }
1273 if (try_ready_normal_body (connection)) 1633 if (try_ready_normal_body (request))
1274 { 1634 {
1275 if (NULL != connection->response->crc) 1635 if (NULL != request->response->crc)
1276 MHD_mutex_unlock_chk_ (&connection->response->mutex); 1636 MHD_mutex_unlock_chk_ (&request->response->mutex);
1277 connection->state = MHD_CONNECTION_NORMAL_BODY_READY; 1637 request->state = MHD_REQUEST_NORMAL_BODY_READY;
1278 /* Buffering for flushable socket was already enabled*/ 1638 /* Buffering for flushable socket was already enabled*/
1279 if (MHD_NO == socket_flush_possible (connection)) 1639 if (MHD_NO == socket_flush_possible (connection))
1280 socket_start_no_buffering (connection); 1640 socket_start_no_buffering (connection);
@@ -1283,26 +1643,26 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1283 /* mutex was already unlocked by "try_ready_normal_body */ 1643 /* mutex was already unlocked by "try_ready_normal_body */
1284 /* not ready, no socket action */ 1644 /* not ready, no socket action */
1285 break; 1645 break;
1286 case MHD_CONNECTION_CHUNKED_BODY_READY: 1646 case MHD_REQUEST_CHUNKED_BODY_READY:
1287 /* nothing to do here */ 1647 /* nothing to do here */
1288 break; 1648 break;
1289 case MHD_CONNECTION_CHUNKED_BODY_UNREADY: 1649 case MHD_REQUEST_CHUNKED_BODY_UNREADY:
1290 if (NULL != connection->response->crc) 1650 if (NULL != request->response->crc)
1291 MHD_mutex_lock_chk_ (&connection->response->mutex); 1651 MHD_mutex_lock_chk_ (&request->response->mutex);
1292 if ( (0 == connection->response->total_size) || 1652 if ( (0 == request->response->total_size) ||
1293 (connection->response_write_position == 1653 (request->response_write_position ==
1294 connection->response->total_size) ) 1654 request->response->total_size) )
1295 { 1655 {
1296 if (NULL != connection->response->crc) 1656 if (NULL != request->response->crc)
1297 MHD_mutex_unlock_chk_ (&connection->response->mutex); 1657 MHD_mutex_unlock_chk_ (&request->response->mutex);
1298 connection->state = MHD_CONNECTION_BODY_SENT; 1658 request->state = MHD_REQUEST_BODY_SENT;
1299 continue; 1659 continue;
1300 } 1660 }
1301 if (try_ready_chunked_body (connection)) 1661 if (try_ready_chunked_body (request))
1302 { 1662 {
1303 if (NULL != connection->response->crc) 1663 if (NULL != request->response->crc)
1304 MHD_mutex_unlock_chk_ (&connection->response->mutex); 1664 MHD_mutex_unlock_chk_ (&request->response->mutex);
1305 connection->state = MHD_CONNECTION_CHUNKED_BODY_READY; 1665 request->state = MHD_REQUEST_CHUNKED_BODY_READY;
1306 /* Buffering for flushable socket was already enabled */ 1666 /* Buffering for flushable socket was already enabled */
1307 if (MHD_NO == socket_flush_possible (connection)) 1667 if (MHD_NO == socket_flush_possible (connection))
1308 socket_start_no_buffering (connection); 1668 socket_start_no_buffering (connection);
@@ -1310,31 +1670,31 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1310 } 1670 }
1311 /* mutex was already unlocked by try_ready_chunked_body */ 1671 /* mutex was already unlocked by try_ready_chunked_body */
1312 break; 1672 break;
1313 case MHD_CONNECTION_BODY_SENT: 1673 case MHD_REQUEST_BODY_SENT:
1314 if (MHD_NO == build_header_response (connection)) 1674 if (MHD_NO == build_header_response (request))
1315 { 1675 {
1316 /* oops - close! */ 1676 /* oops - close! */
1317 CONNECTION_CLOSE_ERROR (connection, 1677 CONNECTION_CLOSE_ERROR (connection,
1318 _("Closing connection (failed to create response header)\n")); 1678 _("Closing connection (failed to create response header)\n"));
1319 continue; 1679 continue;
1320 } 1680 }
1321 if ( (! connection->have_chunked_upload) || 1681 if ( (! request->have_chunked_upload) ||
1322 (connection->write_buffer_send_offset == 1682 (request->write_buffer_send_offset ==
1323 connection->write_buffer_append_offset) ) 1683 request->write_buffer_append_offset) )
1324 connection->state = MHD_CONNECTION_FOOTERS_SENT; 1684 request->state = MHD_REQUEST_FOOTERS_SENT;
1325 else 1685 else
1326 connection->state = MHD_CONNECTION_FOOTERS_SENDING; 1686 request->state = MHD_REQUEST_FOOTERS_SENDING;
1327 continue; 1687 continue;
1328 case MHD_CONNECTION_FOOTERS_SENDING: 1688 case MHD_REQUEST_FOOTERS_SENDING:
1329 /* no default action */ 1689 /* no default action */
1330 break; 1690 break;
1331 case MHD_CONNECTION_FOOTERS_SENT: 1691 case MHD_REQUEST_FOOTERS_SENT:
1332 if (MHD_HTTP_PROCESSING == connection->responseCode) 1692 if (MHD_HTTP_PROCESSING == request->responseCode)
1333 { 1693 {
1334 /* After this type of response, we allow sending another! */ 1694 /* After this type of response, we allow sending another! */
1335 connection->state = MHD_CONNECTION_HEADERS_PROCESSED; 1695 request->state = MHD_REQUEST_HEADERS_PROCESSED;
1336 MHD_destroy_response (connection->response); 1696 MHD_destroy_response (request->response);
1337 connection->response = NULL; 1697 request->response = NULL;
1338 /* FIXME: maybe partially reset memory pool? */ 1698 /* FIXME: maybe partially reset memory pool? */
1339 continue; 1699 continue;
1340 } 1700 }
@@ -1343,7 +1703,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1343 else 1703 else
1344 socket_start_normal_buffering (connection); 1704 socket_start_normal_buffering (connection);
1345 1705
1346 MHD_destroy_response (connection->response); 1706 MHD_destroy_response (request->response);
1347 connection->response = NULL; 1707 connection->response = NULL;
1348 if ( (NULL != daemon->notify_completed) && 1708 if ( (NULL != daemon->notify_completed) &&
1349 (connection->client_aware) ) 1709 (connection->client_aware) )
@@ -1354,7 +1714,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1354 &connection->client_context, 1714 &connection->client_context,
1355 MHD_REQUEST_TERMINATED_COMPLETED_OK); 1715 MHD_REQUEST_TERMINATED_COMPLETED_OK);
1356 } 1716 }
1357 if ( (MHD_CONN_USE_KEEPALIVE != connection->keepalive) || 1717 if ( (MHD_CONN_USE_KEEPALIVE != request->keepalive) ||
1358 (connection->read_closed) ) 1718 (connection->read_closed) )
1359 { 1719 {
1360 /* have to close for some reason */ 1720 /* have to close for some reason */
@@ -1362,55 +1722,44 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1362 MHD_REQUEST_TERMINATED_COMPLETED_OK); 1722 MHD_REQUEST_TERMINATED_COMPLETED_OK);
1363 MHD_pool_destroy (connection->pool); 1723 MHD_pool_destroy (connection->pool);
1364 connection->pool = NULL; 1724 connection->pool = NULL;
1365 connection->read_buffer = NULL; 1725 request->read_buffer = NULL;
1366 connection->read_buffer_size = 0; 1726 request->read_buffer_size = 0;
1367 connection->read_buffer_offset = 0; 1727 request->read_buffer_offset = 0;
1368 } 1728 }
1369 else 1729 else
1370 { 1730 {
1371 /* can try to keep-alive */ 1731 /* can try to keep-alive */
1372 if (MHD_NO != socket_flush_possible (connection)) 1732 if (MHD_NO != socket_flush_possible (connection))
1373 socket_start_normal_buffering (connection); 1733 socket_start_normal_buffering (connection);
1374 connection->version = NULL; 1734 request->version = NULL;
1375 connection->state = MHD_CONNECTION_INIT; 1735 request->state = MHD_REQUEST_INIT;
1376 connection->last = NULL; 1736 request->last = NULL;
1377 connection->colon = NULL; 1737 request->colon = NULL;
1378 connection->header_size = 0; 1738 request->header_size = 0;
1379 connection->keepalive = MHD_CONN_KEEPALIVE_UNKOWN; 1739 request->keepalive = MHD_CONN_KEEPALIVE_UNKOWN;
1380 /* Reset the read buffer to the starting size, 1740 /* Reset the read buffer to the starting size,
1381 preserving the bytes we have already read. */ 1741 preserving the bytes we have already read. */
1382 connection->read_buffer 1742 request->read_buffer
1383 = MHD_pool_reset (connection->pool, 1743 = MHD_pool_reset (connection->pool,
1384 connection->read_buffer, 1744 request->read_buffer,
1385 connection->read_buffer_offset, 1745 request->read_buffer_offset,
1386 connection->daemon->pool_size / 2); 1746 daemon->pool_size / 2);
1387 connection->read_buffer_size 1747 request->read_buffer_size
1388 = connection->daemon->pool_size / 2; 1748 = daemon->pool_size / 2;
1389 } 1749 }
1390 connection->client_aware = false; 1750 memset (&request,
1391 connection->client_context = NULL; 1751 0,
1392 connection->continue_message_write_offset = 0; 1752 sizeof (struct MHD_Request));
1393 connection->responseCode = 0; 1753 request->daemon = daemon;
1394 connection->headers_received = NULL; 1754 request->connection = connection;
1395 connection->headers_received_tail = NULL;
1396 connection->response_write_position = 0;
1397 connection->have_chunked_upload = false;
1398 connection->current_chunk_size = 0;
1399 connection->current_chunk_offset = 0;
1400 connection->method = NULL;
1401 connection->url = NULL;
1402 connection->write_buffer = NULL;
1403 connection->write_buffer_size = 0;
1404 connection->write_buffer_send_offset = 0;
1405 connection->write_buffer_append_offset = 0;
1406 continue; 1755 continue;
1407 case MHD_CONNECTION_CLOSED: 1756 case MHD_REQUEST_CLOSED:
1408 cleanup_connection (connection); 1757 cleanup_connection (connection);
1409 connection->in_idle = false; 1758 request->in_idle = false;
1410 return MHD_NO; 1759 return MHD_NO;
1411#ifdef UPGRADE_SUPPORT 1760#ifdef UPGRADE_SUPPORT
1412 case MHD_CONNECTION_UPGRADE: 1761 case MHD_REQUEST_UPGRADE:
1413 connection->in_idle = false; 1762 request->in_idle = false;
1414 return MHD_YES; /* keep open */ 1763 return MHD_YES; /* keep open */
1415#endif /* UPGRADE_SUPPORT */ 1764#endif /* UPGRADE_SUPPORT */
1416 default: 1765 default:
@@ -1428,7 +1777,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1428 { 1777 {
1429 MHD_connection_close_ (connection, 1778 MHD_connection_close_ (connection,
1430 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED); 1779 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
1431 connection->in_idle = false; 1780 request->in_idle = false;
1432 return MHD_YES; 1781 return MHD_YES;
1433 } 1782 }
1434 } 1783 }
@@ -1441,7 +1790,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
1441 ret = MHD_connection_epoll_update_ (connection); 1790 ret = MHD_connection_epoll_update_ (connection);
1442 } 1791 }
1443#endif /* EPOLL_SUPPORT */ 1792#endif /* EPOLL_SUPPORT */
1444 connection->in_idle = false; 1793 request->in_idle = false;
1445 return ret; 1794 return ret;
1446} 1795}
1447 1796