|  | @@ -57,6 +57,79 @@
 | 
											
												
													
														|  |  #define SLEEP_AFTER_MG_STOP (5)
 |  |  #define SLEEP_AFTER_MG_STOP (5)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +#ifdef HEXDUMP
 | 
											
												
													
														|  | 
 |  | +#else
 | 
											
												
													
														|  | 
 |  | +void
 | 
											
												
													
														|  | 
 |  | +hexDumpth(const char *desc, const void *addr, const int len, int perLine)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	// Silently ignore silly per-line values.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	if (perLine < 4 || perLine > 64)
 | 
											
												
													
														|  | 
 |  | +		perLine = 16;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	int i;
 | 
											
												
													
														|  | 
 |  | +	unsigned char buff[perLine + 1];
 | 
											
												
													
														|  | 
 |  | +	const unsigned char *pc = (const unsigned char *)addr;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	// Output description if given.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	if (desc != NULL)
 | 
											
												
													
														|  | 
 |  | +		fprintf(stderr, "%s:\n", desc);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	// Length checks.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	if (len == 0) {
 | 
											
												
													
														|  | 
 |  | +		fprintf(stderr, "  ZERO LENGTH\n");
 | 
											
												
													
														|  | 
 |  | +		return;
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	if (len < 0) {
 | 
											
												
													
														|  | 
 |  | +		fprintf(stderr, "  NEGATIVE LENGTH: %d\n", len);
 | 
											
												
													
														|  | 
 |  | +		return;
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	// Process every byte in the data.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	for (i = 0; i < len; i++) {
 | 
											
												
													
														|  | 
 |  | +		// Multiple of perLine means new or first line (with line offset).
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		if ((i % perLine) == 0) {
 | 
											
												
													
														|  | 
 |  | +			// Only print previous-line ASCII buffer for lines beyond first.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +			if (i != 0)
 | 
											
												
													
														|  | 
 |  | +				fprintf(stderr, "  %s\n", buff);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +			// Output the offset of current line.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +			fprintf(stderr, "  %04x ", i);
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		// Now the hex code for the specific character.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		fprintf(stderr, " %02x", pc[i]);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		// And buffer a printable ASCII character for later.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better.
 | 
											
												
													
														|  | 
 |  | +			buff[i % perLine] = '.';
 | 
											
												
													
														|  | 
 |  | +		else
 | 
											
												
													
														|  | 
 |  | +			buff[i % perLine] = pc[i];
 | 
											
												
													
														|  | 
 |  | +		buff[(i % perLine) + 1] = '\0';
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	// Pad out last line if not exactly perLine characters.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	while ((i % perLine) != 0) {
 | 
											
												
													
														|  | 
 |  | +		fprintf(stderr, "   ");
 | 
											
												
													
														|  | 
 |  | +		i++;
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	// And print the final ASCII buffer.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	fprintf(stderr, "  %s\n", buff);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +#define HEXDUMP
 | 
											
												
													
														|  | 
 |  | +#endif
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  /* Try to communicate with an external http server. */
 |  |  /* Try to communicate with an external http server. */
 | 
											
												
													
														|  |  static const char *
 |  |  static const char *
 | 
											
												
													
														|  |  get_external_server_ip(void)
 |  |  get_external_server_ip(void)
 | 
											
										
											
												
													
														|  | @@ -2609,6 +2682,36 @@ FormGet(struct mg_connection *conn, void *cbdata)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  static int
 |  |  static int
 | 
											
												
													
														|  | 
 |  | +FormError(struct mg_connection *conn, void *cbdata)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	const struct mg_request_info *req_info = mg_get_request_info(conn);
 | 
											
												
													
														|  | 
 |  | +	int ret;
 | 
											
												
													
														|  | 
 |  | +	struct mg_form_data_handler fdh = {NULL, NULL, NULL, NULL};
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	(void)cbdata;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	ck_assert(req_info != NULL);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	mg_printf(conn, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n");
 | 
											
												
													
														|  | 
 |  | +	fdh.user_data = (void *)&g_field_found_return;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	/* Call the form handler */
 | 
											
												
													
														|  | 
 |  | +	g_field_step = 0;
 | 
											
												
													
														|  | 
 |  | +	g_field_found_return = MG_FORM_FIELD_STORAGE_GET;
 | 
											
												
													
														|  | 
 |  | +	ret = mg_handle_form_request(conn, &fdh);
 | 
											
												
													
														|  | 
 |  | +	g_field_found_return = -888;
 | 
											
												
													
														|  | 
 |  | +	ck_assert_int_eq(ret, -1);
 | 
											
												
													
														|  | 
 |  | +	ck_assert_int_eq(g_field_step, 0);
 | 
											
												
													
														|  | 
 |  | +	mg_printf(conn, "%i\r\n", ret);
 | 
											
												
													
														|  | 
 |  | +	g_field_step = 1000;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	mark_point();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	return 1;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static int
 | 
											
												
													
														|  |  FormStore(struct mg_connection *conn,
 |  |  FormStore(struct mg_connection *conn,
 | 
											
												
													
														|  |            void *cbdata,
 |  |            void *cbdata,
 | 
											
												
													
														|  |            int ret_expected,
 |  |            int ret_expected,
 | 
											
										
											
												
													
														|  | @@ -2727,6 +2830,7 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	ck_assert_str_eq(opt, "8884");
 |  |  	ck_assert_str_eq(opt, "8884");
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	mg_set_request_handler(ctx, "/handle_form", FormGet, NULL);
 |  |  	mg_set_request_handler(ctx, "/handle_form", FormGet, NULL);
 | 
											
												
													
														|  | 
 |  | +	mg_set_request_handler(ctx, "/handle_form_error", FormError, NULL);
 | 
											
												
													
														|  |  	mg_set_request_handler(ctx, "/handle_form_store", FormStore1, NULL);
 |  |  	mg_set_request_handler(ctx, "/handle_form_store", FormStore1, NULL);
 | 
											
												
													
														|  |  	mg_set_request_handler(ctx, "/handle_form_store2", FormStore2, NULL);
 |  |  	mg_set_request_handler(ctx, "/handle_form_store2", FormStore2, NULL);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -2797,6 +2901,23 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	ck_assert_int_eq(client_ri->status_code, 200);
 |  |  	ck_assert_int_eq(client_ri->status_code, 200);
 | 
											
												
													
														|  |  	mg_close_connection(client_conn);
 |  |  	mg_close_connection(client_conn);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +	/*
 | 
											
												
													
														|  | 
 |  | +	 * https://datatracker.ietf.org/doc/html/rfc2046#section-5.1
 | 
											
												
													
														|  | 
 |  | +	 *
 | 
											
												
													
														|  | 
 |  | +	 * multipart-body := [preamble CRLF]
 | 
											
												
													
														|  | 
 |  | +	 *     dash-boundary transport-padding CRLF
 | 
											
												
													
														|  | 
 |  | +	 *     body-part *encapsulation
 | 
											
												
													
														|  | 
 |  | +	 *     close-delimiter transport-padding
 | 
											
												
													
														|  | 
 |  | +	 *     [CRLF epilogue]
 | 
											
												
													
														|  | 
 |  | +	 *
 | 
											
												
													
														|  | 
 |  | +	 * preamble := discard-text
 | 
											
												
													
														|  | 
 |  | +	 * epilogue := discard-text
 | 
											
												
													
														|  | 
 |  | +	 *
 | 
											
												
													
														|  | 
 |  | +	 * discard-text := *(*text CRLF) *text
 | 
											
												
													
														|  | 
 |  | +	 *
 | 
											
												
													
														|  | 
 |  | +	 * text := <any CHAR, including bare CR & bare LF, but NOT including CRLF>
 | 
											
												
													
														|  | 
 |  | +	 */
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	/* Handle form: "POST multipart/form-data" */
 |  |  	/* Handle form: "POST multipart/form-data" */
 | 
											
												
													
														|  |  	multipart_body =
 |  |  	multipart_body =
 | 
											
												
													
														|  |  	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 |  |  	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
										
											
												
													
														|  | @@ -2922,16 +3043,102 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	ck_assert_int_eq(client_ri->status_code, 200);
 |  |  	ck_assert_int_eq(client_ri->status_code, 200);
 | 
											
												
													
														|  |  	mg_close_connection(client_conn);
 |  |  	mg_close_connection(client_conn);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	/* Handle form: "POST multipart/form-data" with chunked transfer encoding */
 | 
											
												
													
														|  | 
 |  | +	/* use the most universal possible (no edge cases) body*/
 | 
											
												
													
														|  | 
 |  | +	client_conn =
 | 
											
												
													
														|  | 
 |  | +	    mg_download("localhost",
 | 
											
												
													
														|  | 
 |  | +	                8884,
 | 
											
												
													
														|  | 
 |  | +	                0,
 | 
											
												
													
														|  | 
 |  | +	                ebuf,
 | 
											
												
													
														|  | 
 |  | +	                sizeof(ebuf),
 | 
											
												
													
														|  | 
 |  | +	                "%s",
 | 
											
												
													
														|  | 
 |  | +	                "POST /handle_form HTTP/1.1\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Host: localhost:8884\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Connection: close\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Content-Type: multipart/form-data; "
 | 
											
												
													
														|  | 
 |  | +	                "boundary=multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Transfer-Encoding: chunked\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "\r\n");
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	ck_assert(client_conn != NULL);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	body_len = strlen(multipart_body);
 | 
											
												
													
														|  | 
 |  | +	chunk_len = 1;
 | 
											
												
													
														|  | 
 |  | +	body_sent = 0;
 | 
											
												
													
														|  | 
 |  | +	while (body_len > body_sent) {
 | 
											
												
													
														|  | 
 |  | +		if (chunk_len > (body_len - body_sent)) {
 | 
											
												
													
														|  | 
 |  | +			chunk_len = body_len - body_sent;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_gt((int)chunk_len, 0);
 | 
											
												
													
														|  | 
 |  | +		mg_printf(client_conn, "%x\r\n", (unsigned int)chunk_len);
 | 
											
												
													
														|  | 
 |  | +		mg_write(client_conn, multipart_body + body_sent, chunk_len);
 | 
											
												
													
														|  | 
 |  | +		mg_printf(client_conn, "\r\n");
 | 
											
												
													
														|  | 
 |  | +		body_sent += chunk_len;
 | 
											
												
													
														|  | 
 |  | +		chunk_len = (chunk_len % 40) + 1;
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	mg_printf(client_conn, "0\r\n\r\n");
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	for (sleep_cnt = 0; sleep_cnt < 30; sleep_cnt++) {
 | 
											
												
													
														|  | 
 |  | +		test_sleep(1);
 | 
											
												
													
														|  | 
 |  | +		if (g_field_step == 1000) {
 | 
											
												
													
														|  | 
 |  | +			break;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	client_ri = mg_get_response_info(client_conn);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	ck_assert(client_ri != NULL);
 | 
											
												
													
														|  | 
 |  | +	ck_assert_int_eq(client_ri->status_code, 200);
 | 
											
												
													
														|  | 
 |  | +	mg_close_connection(client_conn);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	/* Handle form: "POST multipart/form-data" with chunked transfer
 | 
											
												
													
														|  | 
 |  | +	 * encoding, using a quoted boundary string */
 | 
											
												
													
														|  | 
 |  | +	client_conn = mg_download(
 | 
											
												
													
														|  | 
 |  | +	    "localhost",
 | 
											
												
													
														|  | 
 |  | +	    8884,
 | 
											
												
													
														|  | 
 |  | +	    0,
 | 
											
												
													
														|  | 
 |  | +	    ebuf,
 | 
											
												
													
														|  | 
 |  | +	    sizeof(ebuf),
 | 
											
												
													
														|  | 
 |  | +	    "%s",
 | 
											
												
													
														|  | 
 |  | +	    "POST /handle_form HTTP/1.1\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Host: localhost:8884\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Connection: close\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Type: multipart/form-data; "
 | 
											
												
													
														|  | 
 |  | +	    "boundary=\"multipart-form-data-boundary--see-RFC-2388\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Transfer-Encoding: chunked\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n");
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	ck_assert(client_conn != NULL);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	body_len = strlen(multipart_body);
 | 
											
												
													
														|  | 
 |  | +	chunk_len = 1;
 | 
											
												
													
														|  | 
 |  | +	body_sent = 0;
 | 
											
												
													
														|  | 
 |  | +	while (body_len > body_sent) {
 | 
											
												
													
														|  | 
 |  | +		if (chunk_len > (body_len - body_sent)) {
 | 
											
												
													
														|  | 
 |  | +			chunk_len = body_len - body_sent;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_gt((int)chunk_len, 0);
 | 
											
												
													
														|  | 
 |  | +		mg_printf(client_conn, "%x\r\n", (unsigned int)chunk_len);
 | 
											
												
													
														|  | 
 |  | +		mg_write(client_conn, multipart_body + body_sent, chunk_len);
 | 
											
												
													
														|  | 
 |  | +		mg_printf(client_conn, "\r\n");
 | 
											
												
													
														|  | 
 |  | +		body_sent += chunk_len;
 | 
											
												
													
														|  | 
 |  | +		chunk_len = (chunk_len % 40) + 1;
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	mg_printf(client_conn, "0\r\n\r\n");
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	for (sleep_cnt = 0; sleep_cnt < 30; sleep_cnt++) {
 | 
											
												
													
														|  | 
 |  | +		test_sleep(1);
 | 
											
												
													
														|  | 
 |  | +		if (g_field_step == 1000) {
 | 
											
												
													
														|  | 
 |  | +			break;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	client_ri = mg_get_response_info(client_conn);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	ck_assert(client_ri != NULL);
 | 
											
												
													
														|  | 
 |  | +	ck_assert_int_eq(client_ri->status_code, 200);
 | 
											
												
													
														|  | 
 |  | +	mg_close_connection(client_conn);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	/* Handle form: "POST multipart/form-data" without trailing CRLF*/
 |  |  	/* Handle form: "POST multipart/form-data" without trailing CRLF*/
 | 
											
												
													
														|  | -	/*
 |  | 
 | 
											
												
													
														|  | -	 * https://datatracker.ietf.org/doc/html/rfc2046#section-5.1
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * multipart-body := [preamble CRLF]
 |  | 
 | 
											
												
													
														|  | -	 *     dash-boundary transport-padding CRLF
 |  | 
 | 
											
												
													
														|  | -	 *     body-part *encapsulation
 |  | 
 | 
											
												
													
														|  | -	 *     close-delimiter transport-padding
 |  | 
 | 
											
												
													
														|  | -	 *     [CRLF epilogue]
 |  | 
 | 
											
												
													
														|  | -	 */
 |  | 
 | 
											
												
													
														|  |  	multipart_body =
 |  |  	multipart_body =
 | 
											
												
													
														|  |  		"--multipart-form-data-boundary--see-RFC-2388\r\n"
 |  |  		"--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  |  	    "Content-Disposition: form-data; name=\"textin\"\r\n"
 |  |  	    "Content-Disposition: form-data; name=\"textin\"\r\n"
 | 
											
										
											
												
													
														|  | @@ -3057,21 +3264,6 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	mg_close_connection(client_conn);
 |  |  	mg_close_connection(client_conn);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	/* Handle form: "POST multipart/form-data" with epilogue*/
 |  |  	/* Handle form: "POST multipart/form-data" with epilogue*/
 | 
											
												
													
														|  | -	/*
 |  | 
 | 
											
												
													
														|  | -	 * https://datatracker.ietf.org/doc/html/rfc2046#section-5.1
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * multipart-body := [preamble CRLF]
 |  | 
 | 
											
												
													
														|  | -	 *     dash-boundary transport-padding CRLF
 |  | 
 | 
											
												
													
														|  | -	 *     body-part *encapsulation
 |  | 
 | 
											
												
													
														|  | -	 *     close-delimiter transport-padding
 |  | 
 | 
											
												
													
														|  | -	 *     [CRLF epilogue]
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * epilogue := discard-text
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * discard-text := *(*text CRLF) *text
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * text := <any CHAR, including bare CR & bare LF, but NOT including CRLF>
 |  | 
 | 
											
												
													
														|  | -	 */
 |  | 
 | 
											
												
													
														|  |  	multipart_body =
 |  |  	multipart_body =
 | 
											
												
													
														|  |  	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 |  |  	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  |  	    "Content-Disposition: form-data; name=\"textin\"\r\n"
 |  |  	    "Content-Disposition: form-data; name=\"textin\"\r\n"
 | 
											
										
											
												
													
														|  | @@ -3164,16 +3356,16 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	    "\r\n"
 |  |  	    "\r\n"
 | 
											
												
													
														|  |  	    "Text area default text.\r\n"
 |  |  	    "Text area default text.\r\n"
 | 
											
												
													
														|  |  	    "--multipart-form-data-boundary--see-RFC-2388--\r\n"
 |  |  	    "--multipart-form-data-boundary--see-RFC-2388--\r\n"
 | 
											
												
													
														|  | -		"epilogue\r\n"
 |  | 
 | 
											
												
													
														|  | -		"epilogue\r\n"
 |  | 
 | 
											
												
													
														|  | -		"\r\n"
 |  | 
 | 
											
												
													
														|  | -		"epilogue\r\n"
 |  | 
 | 
											
												
													
														|  | -		"\r\n"
 |  | 
 | 
											
												
													
														|  | -		"\r\n"
 |  | 
 | 
											
												
													
														|  | -		"\r\n"
 |  | 
 | 
											
												
													
														|  | -		"epilogue\r\n";
 |  | 
 | 
											
												
													
														|  | 
 |  | +	    "epilogue\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "epilogue\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "1234567890-=!@£$%^&*()_+[]{};'\\:\"|,./<>?`~§\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "epilogue\r\n";
 | 
											
												
													
														|  |  	body_len = strlen(multipart_body);
 |  |  	body_len = strlen(multipart_body);
 | 
											
												
													
														|  | -	ck_assert_uint_eq(body_len, 2366); /* not required */
 |  | 
 | 
											
												
													
														|  | 
 |  | +	ck_assert_uint_eq(body_len, 2453); /* not required */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	client_conn =
 |  |  	client_conn =
 | 
											
												
													
														|  |  	    mg_download("localhost",
 |  |  	    mg_download("localhost",
 | 
											
										
											
												
													
														|  | @@ -3228,6 +3420,9 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	    "\r\n"
 |  |  	    "\r\n"
 | 
											
												
													
														|  |  	    "\r\npreamble"
 |  |  	    "\r\npreamble"
 | 
											
												
													
														|  |  	    "\r\n"
 |  |  	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "1234567890-=!@£$%^&*()_+[]{};'\\:\"|,./<>?`~§\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n\t\t\t   \t\t\t"
 | 
											
												
													
														|  |  	    "\r\n"
 |  |  	    "\r\n"
 | 
											
												
													
														|  |  	    "\r\n"
 |  |  	    "\r\n"
 | 
											
												
													
														|  |  	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 |  |  	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
										
											
												
													
														|  | @@ -3322,7 +3517,7 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	    "Text area default text.\r\n"
 |  |  	    "Text area default text.\r\n"
 | 
											
												
													
														|  |  	    "--multipart-form-data-boundary--see-RFC-2388--\r\n";
 |  |  	    "--multipart-form-data-boundary--see-RFC-2388--\r\n";
 | 
											
												
													
														|  |  	body_len = strlen(multipart_body);
 |  |  	body_len = strlen(multipart_body);
 | 
											
												
													
														|  | -	ck_assert_uint_eq(body_len, 2366); /* not required */
 |  | 
 | 
											
												
													
														|  | 
 |  | +	ck_assert_uint_eq(body_len, 2478); /* not required */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	client_conn =
 |  |  	client_conn =
 | 
											
												
													
														|  |  	    mg_download("localhost",
 |  |  	    mg_download("localhost",
 | 
											
										
											
												
													
														|  | @@ -3353,21 +3548,7 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	ck_assert_int_eq(client_ri->status_code, 200);
 |  |  	ck_assert_int_eq(client_ri->status_code, 200);
 | 
											
												
													
														|  |  	mg_close_connection(client_conn);
 |  |  	mg_close_connection(client_conn);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  	/* Handle form: "POST multipart/form-data" with transport padding*/
 |  |  	/* Handle form: "POST multipart/form-data" with transport padding*/
 | 
											
												
													
														|  | -	/*
 |  | 
 | 
											
												
													
														|  | -	 * https://datatracker.ietf.org/doc/html/rfc2046#section-5.1
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * multipart-body := [preamble CRLF]
 |  | 
 | 
											
												
													
														|  | -	 *     dash-boundary transport-padding CRLF
 |  | 
 | 
											
												
													
														|  | -	 *     body-part *encapsulation
 |  | 
 | 
											
												
													
														|  | -	 *     close-delimiter transport-padding
 |  | 
 | 
											
												
													
														|  | -	 *     [CRLF epilogue]
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * transport-padding := *LWSP-char
 |  | 
 | 
											
												
													
														|  | -	 *
 |  | 
 | 
											
												
													
														|  | -	 * LWSP-char := SPACE / HTAB
 |  | 
 | 
											
												
													
														|  | -	 */
 |  | 
 | 
											
												
													
														|  |  	multipart_body =
 |  |  	multipart_body =
 | 
											
												
													
														|  |  	    "--multipart-form-data-boundary--see-RFC-2388           \r\n"
 |  |  	    "--multipart-form-data-boundary--see-RFC-2388           \r\n"
 | 
											
												
													
														|  |  	    "Content-Disposition: form-data; name=\"textin\"\r\n"
 |  |  	    "Content-Disposition: form-data; name=\"textin\"\r\n"
 | 
											
										
											
												
													
														|  | @@ -3461,7 +3642,7 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	    "Text area default text.\r\n"
 |  |  	    "Text area default text.\r\n"
 | 
											
												
													
														|  |  	    "--multipart-form-data-boundary--see-RFC-2388--\r\n";
 |  |  	    "--multipart-form-data-boundary--see-RFC-2388--\r\n";
 | 
											
												
													
														|  |  	body_len = strlen(multipart_body);
 |  |  	body_len = strlen(multipart_body);
 | 
											
												
													
														|  | -	ck_assert_uint_eq(body_len, 2366); /* not required */
 |  | 
 | 
											
												
													
														|  | 
 |  | +	ck_assert_uint_eq(body_len, 2382); /* not required */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	client_conn =
 |  |  	client_conn =
 | 
											
												
													
														|  |  	    mg_download("localhost",
 |  |  	    mg_download("localhost",
 | 
											
										
											
												
													
														|  | @@ -3492,40 +3673,125 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	ck_assert_int_eq(client_ri->status_code, 200);
 |  |  	ck_assert_int_eq(client_ri->status_code, 200);
 | 
											
												
													
														|  |  	mg_close_connection(client_conn);
 |  |  	mg_close_connection(client_conn);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	/* Handle form: "POST multipart/form-data" with chunked transfer encoding */
 |  | 
 | 
											
												
													
														|  | 
 |  | +	/* Handle form: "POST multipart/form-data" with custom name fields in the
 | 
											
												
													
														|  | 
 |  | +	 * Content-Disposition */
 | 
											
												
													
														|  | 
 |  | +	multipart_body =
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; "
 | 
											
												
													
														|  | 
 |  | +		"custom1name=\"1\"; "
 | 
											
												
													
														|  | 
 |  | +		"custom2name=\"2\"; "
 | 
											
												
													
														|  | 
 |  | +		"custom3name=\"3\"; "
 | 
											
												
													
														|  | 
 |  | +		"custom4name=\"4\"; "
 | 
											
												
													
														|  | 
 |  | +		"name=\"textin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "text\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\t\t\t\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"passwordin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"radio1\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "val1\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=radio2\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "val1\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"check1\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "val1\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"numberin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "1\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"datein\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "1.1.2016\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"colorin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "#80ff00\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"rangein\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "3\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"monthin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"weekin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"timein\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"datetimen\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"datetimelocalin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"emailin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"searchin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"telin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"urlin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"filein\"; filename=\"\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Type: application/octet-stream\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=filesin; filename=\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Type: application/octet-stream\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"selectin\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "opt1\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Content-Disposition: form-data; name=\"message\"\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "Text area default text.\r\n"
 | 
											
												
													
														|  | 
 |  | +	    "--multipart-form-data-boundary--see-RFC-2388--\r\n";
 | 
											
												
													
														|  | 
 |  | +	body_len = strlen(multipart_body);
 | 
											
												
													
														|  | 
 |  | +	ck_assert_uint_eq(body_len, 2439); /* not required */
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	client_conn =
 |  |  	client_conn =
 | 
											
												
													
														|  |  	    mg_download("localhost",
 |  |  	    mg_download("localhost",
 | 
											
												
													
														|  |  	                8884,
 |  |  	                8884,
 | 
											
												
													
														|  |  	                0,
 |  |  	                0,
 | 
											
												
													
														|  |  	                ebuf,
 |  |  	                ebuf,
 | 
											
												
													
														|  |  	                sizeof(ebuf),
 |  |  	                sizeof(ebuf),
 | 
											
												
													
														|  | -	                "%s",
 |  | 
 | 
											
												
													
														|  |  	                "POST /handle_form HTTP/1.1\r\n"
 |  |  	                "POST /handle_form HTTP/1.1\r\n"
 | 
											
												
													
														|  |  	                "Host: localhost:8884\r\n"
 |  |  	                "Host: localhost:8884\r\n"
 | 
											
												
													
														|  |  	                "Connection: close\r\n"
 |  |  	                "Connection: close\r\n"
 | 
											
												
													
														|  |  	                "Content-Type: multipart/form-data; "
 |  |  	                "Content-Type: multipart/form-data; "
 | 
											
												
													
														|  |  	                "boundary=multipart-form-data-boundary--see-RFC-2388\r\n"
 |  |  	                "boundary=multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | -	                "Transfer-Encoding: chunked\r\n"
 |  | 
 | 
											
												
													
														|  | -	                "\r\n");
 |  | 
 | 
											
												
													
														|  | 
 |  | +	                "Content-Length: %u\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "\r\n%s",
 | 
											
												
													
														|  | 
 |  | +	                (unsigned int)body_len,
 | 
											
												
													
														|  | 
 |  | +	                multipart_body);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	ck_assert(client_conn != NULL);
 |  |  	ck_assert(client_conn != NULL);
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -	body_len = strlen(multipart_body);
 |  | 
 | 
											
												
													
														|  | -	chunk_len = 1;
 |  | 
 | 
											
												
													
														|  | -	body_sent = 0;
 |  | 
 | 
											
												
													
														|  | -	while (body_len > body_sent) {
 |  | 
 | 
											
												
													
														|  | -		if (chunk_len > (body_len - body_sent)) {
 |  | 
 | 
											
												
													
														|  | -			chunk_len = body_len - body_sent;
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | -		ck_assert_int_gt((int)chunk_len, 0);
 |  | 
 | 
											
												
													
														|  | -		mg_printf(client_conn, "%x\r\n", (unsigned int)chunk_len);
 |  | 
 | 
											
												
													
														|  | -		mg_write(client_conn, multipart_body + body_sent, chunk_len);
 |  | 
 | 
											
												
													
														|  | -		mg_printf(client_conn, "\r\n");
 |  | 
 | 
											
												
													
														|  | -		body_sent += chunk_len;
 |  | 
 | 
											
												
													
														|  | -		chunk_len = (chunk_len % 40) + 1;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	mg_printf(client_conn, "0\r\n\r\n");
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  	for (sleep_cnt = 0; sleep_cnt < 30; sleep_cnt++) {
 |  |  	for (sleep_cnt = 0; sleep_cnt < 30; sleep_cnt++) {
 | 
											
												
													
														|  |  		test_sleep(1);
 |  |  		test_sleep(1);
 | 
											
												
													
														|  |  		if (g_field_step == 1000) {
 |  |  		if (g_field_step == 1000) {
 | 
											
										
											
												
													
														|  | @@ -3538,41 +3804,29 @@ START_TEST(test_handle_form)
 | 
											
												
													
														|  |  	ck_assert_int_eq(client_ri->status_code, 200);
 |  |  	ck_assert_int_eq(client_ri->status_code, 200);
 | 
											
												
													
														|  |  	mg_close_connection(client_conn);
 |  |  	mg_close_connection(client_conn);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	/* Handle form: "POST multipart/form-data" with chunked transfer
 |  | 
 | 
											
												
													
														|  | -	 * encoding, using a quoted boundary string */
 |  | 
 | 
											
												
													
														|  | -	client_conn = mg_download(
 |  | 
 | 
											
												
													
														|  | -	    "localhost",
 |  | 
 | 
											
												
													
														|  | -	    8884,
 |  | 
 | 
											
												
													
														|  | -	    0,
 |  | 
 | 
											
												
													
														|  | -	    ebuf,
 |  | 
 | 
											
												
													
														|  | -	    sizeof(ebuf),
 |  | 
 | 
											
												
													
														|  | -	    "%s",
 |  | 
 | 
											
												
													
														|  | -	    "POST /handle_form HTTP/1.1\r\n"
 |  | 
 | 
											
												
													
														|  | -	    "Host: localhost:8884\r\n"
 |  | 
 | 
											
												
													
														|  | -	    "Connection: close\r\n"
 |  | 
 | 
											
												
													
														|  | -	    "Content-Type: multipart/form-data; "
 |  | 
 | 
											
												
													
														|  | -	    "boundary=\"multipart-form-data-boundary--see-RFC-2388\"\r\n"
 |  | 
 | 
											
												
													
														|  | -	    "Transfer-Encoding: chunked\r\n"
 |  | 
 | 
											
												
													
														|  | -	    "\r\n");
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -	ck_assert(client_conn != NULL);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | 
 |  | +	/* Handle form error cases */
 | 
											
												
													
														|  | 
 |  | +	/* Handle form: "POST multipart/form-data" empty body */
 | 
											
												
													
														|  | 
 |  | +	multipart_body = "";
 | 
											
												
													
														|  |  	body_len = strlen(multipart_body);
 |  |  	body_len = strlen(multipart_body);
 | 
											
												
													
														|  | -	chunk_len = 1;
 |  | 
 | 
											
												
													
														|  | -	body_sent = 0;
 |  | 
 | 
											
												
													
														|  | -	while (body_len > body_sent) {
 |  | 
 | 
											
												
													
														|  | -		if (chunk_len > (body_len - body_sent)) {
 |  | 
 | 
											
												
													
														|  | -			chunk_len = body_len - body_sent;
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | -		ck_assert_int_gt((int)chunk_len, 0);
 |  | 
 | 
											
												
													
														|  | -		mg_printf(client_conn, "%x\r\n", (unsigned int)chunk_len);
 |  | 
 | 
											
												
													
														|  | -		mg_write(client_conn, multipart_body + body_sent, chunk_len);
 |  | 
 | 
											
												
													
														|  | -		mg_printf(client_conn, "\r\n");
 |  | 
 | 
											
												
													
														|  | -		body_sent += chunk_len;
 |  | 
 | 
											
												
													
														|  | -		chunk_len = (chunk_len % 40) + 1;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	mg_printf(client_conn, "0\r\n\r\n");
 |  | 
 | 
											
												
													
														|  | 
 |  | +	ck_assert_uint_eq(body_len, 0); /* not required */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +	client_conn =
 | 
											
												
													
														|  | 
 |  | +	    mg_download("localhost",
 | 
											
												
													
														|  | 
 |  | +	                8884,
 | 
											
												
													
														|  | 
 |  | +	                0,
 | 
											
												
													
														|  | 
 |  | +	                ebuf,
 | 
											
												
													
														|  | 
 |  | +	                sizeof(ebuf),
 | 
											
												
													
														|  | 
 |  | +	                "POST /handle_form_error HTTP/1.1\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Host: localhost:8884\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Connection: close\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Content-Type: multipart/form-data; "
 | 
											
												
													
														|  | 
 |  | +	                "boundary=multipart-form-data-boundary--see-RFC-2388\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "Content-Length: %u\r\n"
 | 
											
												
													
														|  | 
 |  | +	                "\r\n%s",
 | 
											
												
													
														|  | 
 |  | +	                (unsigned int)body_len,
 | 
											
												
													
														|  | 
 |  | +	                multipart_body);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	ck_assert(client_conn != NULL);
 | 
											
												
													
														|  |  	for (sleep_cnt = 0; sleep_cnt < 30; sleep_cnt++) {
 |  |  	for (sleep_cnt = 0; sleep_cnt < 30; sleep_cnt++) {
 | 
											
												
													
														|  |  		test_sleep(1);
 |  |  		test_sleep(1);
 | 
											
												
													
														|  |  		if (g_field_step == 1000) {
 |  |  		if (g_field_step == 1000) {
 |