test-http-payload.c revision 844b0294f9bfc721e37782cada248394b531cea3
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* Copyright (c) 2013-2016 Dovecot authors, see the included COPYING file */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_files_read_dir(const char *path)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* open the directory */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* read entries */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* Close the directory */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_files_init(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* initialize file array */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* obtain all filenames */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_files_deinit(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic struct istream *
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int *status_r, const char **reason_r)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch * Test server
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic const struct http_server_callbacks http_callbacks;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* location: /succes */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_handle_success_request(struct client_request *creq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create(req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* location: /download/... */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int status;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fstream = test_file_open(fpath, &status, &reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req, status, reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create(req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch output = http_server_response_get_payload_output(resp, TRUE);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to send blocking file payload");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished sending blocking payload for %s"
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_set_payload(resp, fstream);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* location: /echo */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_request_read_echo_more(struct client_request *creq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_set_max_buffer_size(creq->payload_output, IO_BLOCK_SIZE);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch ret = o_stream_send_istream(creq->payload_output, creq->payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch o_stream_set_max_buffer_size(creq->payload_output, (size_t)-1);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (creq->payload_output->stream_errno != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "Failed to write all echo payload [%s]", creq->path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "Failed to read all echo payload [%s]", creq->path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (i_stream_have_bytes_left(creq->payload_input))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished receiving payload for %s", creq->path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_input = iostream_temp_finish(&creq->payload_output, 4096);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_set_payload(resp, payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_handle_echo_request(struct client_request *creq,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (void)http_request_get_payload_size(hreq, &size);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get_payload_input(req, TRUE);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch i_stream_create_limit(payload_input, read_server_partial);
f339a8e73beea7684ea634941ea82593dea522eeTimo Sirainen ret = o_stream_send_istream(payload_output, payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to receive blocking echo payload");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_input = iostream_temp_finish(&payload_output, 4096);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished receiving blocking payload for %s", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch resp = http_server_response_create(req, 200, "OK");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_response_add_header(resp, "Content-Type", "text/plain");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch payload_output = http_server_response_get_payload_output(resp, TRUE);
f339a8e73beea7684ea634941ea82593dea522eeTimo Sirainen ret = o_stream_send_istream(payload_output, payload_input);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to send blocking echo payload");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished sending blocking payload for %s", path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_get_payload_input(req, FALSE);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch i_stream_create_limit(creq->payload_input, read_server_partial);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch creq->io = io_add_istream(creq->payload_input,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch pool_t pool = http_server_request_get_pool(req);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void client_request_deinit(struct client_request **_creq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct http_server_request *req = creq->server_req;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *path = hreq->target.url->path, *p;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch struct client *client = (struct client *)context;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "request method=`%s' path=`%s'", hreq->method, path);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req, 404, "Not found");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (strncmp(path, "/download", p-path) == 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_request_fail(req, 404, "Not found");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* client connection */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_connection_destroy(void *context, const char *reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic const struct http_server_callbacks http_callbacks = {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch .connection_destroy = client_connection_destroy,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch client->http_conn = http_server_connection_create(http_server,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void client_deinit(struct client **_client)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_connection_close(&client->http_conn, "deinit");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschclient_connection_destroy(void *context, const char *reason ATTR_UNUSED)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void client_accept(void *context ATTR_UNUSED)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* accept new client */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_server_init(const struct http_server_settings *server_set)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* open server socket */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_server_deinit(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* close server socket */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* deinitialize */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch * Test client
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic unsigned int client_files_first, client_files_last;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch/* download */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_download_continue(void);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_download_finished(struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_download_payload_input(struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* read payload */
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen while ((ret=i_stream_read_more(payload, &pdata, &psize)) > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got data for [%u] (size=%d)",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* compare with file on disk */
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen (tcreq->file, &fdata, &fsize)) > 0 && pleft > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "received data does not match file "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (ret < 0 && tcreq->file->stream_errno != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read file: %s", i_stream_get_error(tcreq->file));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "need more data for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* we will be called again for this request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read request payload: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } if (i_stream_have_bytes_left(tcreq->file)) {
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen if (i_stream_read_more(tcreq->file, &fdata, &fsize) <= 0)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "payload ended prematurely "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "(at least %"PRIuSIZE_T" bytes left)", fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished request for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* finished */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* dereference payload stream; finishes the request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&tcreq->io); /* holds a reference too */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_download_response(const struct http_response *resp,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got response for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "path for [%u]: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fstream = test_file_open(path, &status, &reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got wrong response for %s: %u %s (expected: %u %s)",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch path, resp->status, resp->reason, status, reason);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "HTTP request for %s failed: %u %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "no payload for %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_download_continue(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char *const *paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first <= client_files_last);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch for (; client_files_first < client_files_last &&
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths[client_files_first] == NULL; client_files_first++)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "received until [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (client_files_last - client_files_first) < test_max_pending;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "retrieving %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_port(hreq, bind_port);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_destroy_callback(hreq,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_download(const struct http_client_settings *client_set)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* create client */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* start querying server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_echo_finished(struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_echo_payload_input(struct test_client_request *tcreq)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* read payload */
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen while ((ret=i_stream_read_more(payload, &pdata, &psize)) > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got data for [%u] (size=%d)",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* compare with file on disk */
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen (tcreq->file, &fdata, &fsize)) > 0 && pleft > 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "received data does not match file "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch if (ret < 0 && tcreq->file->stream_errno != 0) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read file: %s", i_stream_get_error(tcreq->file));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "need more data for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* we will be called again for this request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "failed to read request payload: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } if (i_stream_have_bytes_left(tcreq->file)) {
651f981ca065d2365bf2ea07b04318a5402f047aTimo Sirainen if (i_stream_read_more(tcreq->file, &fdata, &fsize) <= 0)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "payload ended prematurely "
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "(at least %"PRIuSIZE_T" bytes left)", fsize);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch } else if (debug) {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "finished request for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* finished */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* dereference payload stream; finishes the request */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch io_remove(&tcreq->io); /* holds a reference too */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_echo_response(const struct http_response *resp,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "got response for [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "path for [%u]: %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "HTTP request for %s failed: %u %s",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fstream = test_file_open(path, &status, NULL);
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch struct istream *partial = i_stream_create_limit
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch // FIXME: check file is empty
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "no payload for %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const char **paths;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch unsigned int count;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch i_assert(client_files_first <= client_files_last);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch for (; client_files_first < client_files_last &&
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch paths[client_files_first] == NULL; client_files_first++)
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch "received until [%u/%u]", client_files_first-1, count);
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch "next blocking: %s", (path == NULL ? "none" : path));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (client_files_last - client_files_first) < test_max_pending;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "skipping %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch "retrieving %s [%u]",
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_port(hreq, bind_port);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_request_set_destroy_callback(hreq,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschtest_client_echo(const struct http_client_settings *client_set)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* create client */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* start querying server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_client_deinit(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_open_server_fd(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch fd_listen = net_listen(&bind_ip, &bind_port, 128);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_client_settings *client_set,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch const struct http_server_settings *server_set,
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* child: server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* parent: client */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* download files from blocking server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* server settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_server_set, 0, sizeof(http_server_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.request_limits.max_payload_size = (uoff_t)-1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* client settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_client_set, 0, sizeof(http_client_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (&http_client_set, &http_server_set, client_init);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* download files from blocking server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* server settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_server_set, 0, sizeof(http_server_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.request_limits.max_payload_size = (uoff_t)-1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* client settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_client_set, 0, sizeof(http_client_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (&http_client_set, &http_server_set, client_init);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch void (*client_init)(const struct http_client_settings *client_set))
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* download files from blocking server */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* server settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_server_set, 0, sizeof(http_server_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_server_set.request_limits.max_payload_size = (uoff_t)-1;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* client settings */
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch memset(&http_client_set, 0, sizeof(http_client_set));
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch http_client_set.max_parallel_connections = 40;
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch (&http_client_set, &http_server_set, client_init);
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_download_server_nonblocking(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload download (server non-blocking)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_download_server_blocking(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload download (server blocking)");
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server non-blocking)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload echo (server blocking)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_echo_server_nonblocking_sync(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload echo (server non-blocking; 100-continue)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void test_echo_server_blocking_sync(void)
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch test_begin("http payload echo (server blocking; 100-continue)");
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Boschstatic void test_echo_server_nonblocking_partial(void)
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server non-blocking; partial short)");
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server non-blocking; partial long)");
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Boschstatic void test_echo_server_blocking_partial(void)
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server blocking; partial short)");
641ab76d7defa171d2b558afcce2e1ac6e49d8b9Stephan Bosch test_begin("http payload echo (server blocking; partial long)");
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_begin("http payload download (client partial)");
ca270e31c9c43f7559b2378cb3ece7e09491e4d9Stephan Bosch test_begin("http payload download (client partial long)");
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschstatic void (*test_functions[])(void) = {
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Bosch /* listen on localhost */