diff --git a/src/tests/basic/libtest.h b/src/tests/basic/libtest.h index 252051d3..f315a321 100644 --- a/src/tests/basic/libtest.h +++ b/src/tests/basic/libtest.h @@ -131,6 +131,19 @@ MHDT_client_put_data (void *cls, const struct MHDT_PhaseContext *pc); +/** + * Run chunked upload against the base URL and expect a + * 204 No Content response. + * + * @param cls 0-terminated string with data to PUT + * @param pc context for the client + * @return error message, NULL on success + */ +const char * +MHDT_client_chunk_data (void *cls, + const struct MHDT_PhaseContext *pc); + + /** * A phase defines some server and client-side * behaviors to execute. diff --git a/src/tests/basic/libtest_convenience_client_request.c b/src/tests/basic/libtest_convenience_client_request.c index 7d85b6c3..a008c82c 100644 --- a/src/tests/basic/libtest_convenience_client_request.c +++ b/src/tests/basic/libtest_convenience_client_request.c @@ -407,6 +407,11 @@ struct ReadBuffer */ size_t pos; + /** + * Number of chunks to user when sending. + */ + unsigned int chunks; + }; @@ -433,6 +438,12 @@ read_cb (void *ptr, return CURLE_WRITE_ERROR; if (limit > rb->len - rb->pos) limit = rb->len - rb->pos; + if ( (rb->chunks > 1) && + (limit > 1) ) + { + limit /= rb->chunks; + rb->chunks--; + } memcpy (ptr, rb->buf + rb->pos, limit); @@ -502,3 +513,59 @@ MHDT_client_put_data ( curl_easy_cleanup (c); return NULL; } + + +const char * +MHDT_client_chunk_data ( + void *cls, + const struct MHDT_PhaseContext *pc) +{ + const char *text = cls; + struct ReadBuffer rb = { + .buf = text, + .len = strlen (text), + .chunks = 2 + }; + CURL *c; + + c = curl_easy_init (); + if (NULL == c) + return "Failed to initialize Curl handle"; + if (CURLE_OK != + curl_easy_setopt (c, + CURLOPT_URL, + pc->base_url)) + { + curl_easy_cleanup (c); + return "Failed to set URL for curl request"; + } + if (CURLE_OK != + curl_easy_setopt (c, + CURLOPT_UPLOAD, + 1L)) + { + curl_easy_cleanup (c); + return "Failed to set PUT method for curl request"; + } + if (CURLE_OK != + curl_easy_setopt (c, + CURLOPT_READFUNCTION, + &read_cb)) + { + curl_easy_cleanup (c); + return "Failed to set READFUNCTION for curl request"; + } + if (CURLE_OK != + curl_easy_setopt (c, + CURLOPT_READDATA, + &rb)) + { + curl_easy_cleanup (c); + return "Failed to set READFUNCTION for curl request"; + } + PERFORM_REQUEST (c); + CHECK_STATUS (c, + MHD_HTTP_STATUS_NO_CONTENT); + curl_easy_cleanup (c); + return NULL; +} diff --git a/src/tests/basic/test_client_server.c b/src/tests/basic/test_client_server.c index 13edc705..d68538d3 100644 --- a/src/tests/basic/test_client_server.c +++ b/src/tests/basic/test_client_server.c @@ -167,6 +167,14 @@ main (int argc, char *argv[]) .client_cb_cls = "simple-upload-value", .timeout_ms = 5, }, + { + .label = "client PUT with 2 chunks", + .server_cb = &MHDT_server_reply_check_upload, + .server_cb_cls = "chunky-upload-value", + .client_cb = &MHDT_client_chunk_data, + .client_cb_cls = "chunky-upload-value", + .timeout_ms = 5, + }, { .label = "client request with custom header", .server_cb = &MHDT_server_reply_check_header, @@ -192,7 +200,6 @@ main (int argc, char *argv[]) .timeout_ms = 5, .num_clients = 10 }, - // TODO: chunked upload // TODO: chunked download { .label = NULL,