Path: blob/main/external/curl/tests/libtest/cli_upload_pausing.c
2649 views
/***************************************************************************1* _ _ ____ _2* Project ___| | | | _ \| |3* / __| | | | |_) | |4* | (__| |_| | _ <| |___5* \___|\___/|_| \_\_____|6*7* Copyright (C) Daniel Stenberg, <[email protected]>, et al.8*9* This software is licensed as described in the file COPYING, which10* you should have received as part of this distribution. The terms11* are also available at https://curl.se/docs/copyright.html.12*13* You may opt to use, copy, modify, merge, publish, distribute and/or sell14* copies of the Software, and permit persons to whom the Software is15* furnished to do so, under the terms of the COPYING file.16*17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY18* KIND, either express or implied.19*20* SPDX-License-Identifier: curl21*22***************************************************************************/23/* This is based on the PoC client of issue #1176924*/25#include "first.h"2627#include "testtrace.h"28#include "memdebug.h"2930static size_t total_read = 0;3132static size_t read_callback(char *ptr, size_t size, size_t nmemb,33void *userdata)34{35static const size_t PAUSE_READ_AFTER = 1;3637(void)size;38(void)nmemb;39(void)userdata;40if(total_read >= PAUSE_READ_AFTER) {41curl_mfprintf(stderr, "read_callback, return PAUSE\n");42return CURL_READFUNC_PAUSE;43}44else {45ptr[0] = '\n';46++total_read;47curl_mfprintf(stderr, "read_callback, return 1 byte\n");48return 1;49}50}5152static int progress_callback(void *clientp,53curl_off_t dltotal,54curl_off_t dlnow,55curl_off_t ultotal,56curl_off_t ulnow)57{58(void)dltotal;59(void)dlnow;60(void)ultotal;61(void)ulnow;62(void)clientp;63#if 064/* Used to unpause on progress, but keeping for now. */65{66CURL *curl = (CURL *)clientp;67curl_easy_pause(curl, CURLPAUSE_CONT);68/* curl_easy_pause(curl, CURLPAUSE_RECV_CONT); */69}70#endif71return 0;72}7374static void usage_upload_pausing(const char *msg)75{76if(msg)77curl_mfprintf(stderr, "%s\n", msg);78curl_mfprintf(stderr,79"usage: [options] url\n"80" upload and pause, options:\n"81" -V http_version (http/1.1, h2, h3) http version to use\n"82);83}8485static CURLcode test_cli_upload_pausing(const char *URL)86{87CURL *curl = NULL;88CURLcode result = CURLE_OK;89CURLU *cu;90struct curl_slist *resolve = NULL;91char resolve_buf[1024];92const char *url;93char *host = NULL, *port = NULL;94long http_version = CURL_HTTP_VERSION_1_1;95int ch;9697(void)URL;9899while((ch = cgetopt(test_argc, test_argv, "V:")) != -1) {100switch(ch) {101case 'V': {102if(!strcmp("http/1.1", coptarg))103http_version = CURL_HTTP_VERSION_1_1;104else if(!strcmp("h2", coptarg))105http_version = CURL_HTTP_VERSION_2_0;106else if(!strcmp("h3", coptarg))107http_version = CURL_HTTP_VERSION_3ONLY;108else {109usage_upload_pausing("invalid http version");110return (CURLcode)1;111}112break;113}114default:115usage_upload_pausing("invalid option");116return (CURLcode)1;117}118}119test_argc -= coptind;120test_argv += coptind;121122if(test_argc != 1) {123usage_upload_pausing("not enough arguments");124return (CURLcode)2;125}126url = test_argv[0];127128if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {129curl_mfprintf(stderr, "curl_global_init() failed\n");130return (CURLcode)3;131}132133curl_global_trace("ids,time");134135cu = curl_url();136if(!cu) {137curl_mfprintf(stderr, "out of memory\n");138result = (CURLcode)1;139goto cleanup;140}141if(curl_url_set(cu, CURLUPART_URL, url, 0)) {142curl_mfprintf(stderr, "not a URL: '%s'\n", url);143result = (CURLcode)1;144goto cleanup;145}146if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) {147curl_mfprintf(stderr, "could not get host of '%s'\n", url);148result = (CURLcode)1;149goto cleanup;150}151if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) {152curl_mfprintf(stderr, "could not get port of '%s'\n", url);153result = (CURLcode)1;154goto cleanup;155}156memset(&resolve, 0, sizeof(resolve));157curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1",158host, port);159resolve = curl_slist_append(resolve, resolve_buf);160161curl = curl_easy_init();162if(!curl) {163curl_mfprintf(stderr, "out of memory\n");164result = (CURLcode)1;165goto cleanup;166}167/* We want to use our own read function. */168curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);169170/* It will help us to continue the read function. */171curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);172curl_easy_setopt(curl, CURLOPT_XFERINFODATA, curl);173curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);174175/* It will help us to ensure that keepalive does not help. */176curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);177curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 1L);178curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 1L);179curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 1L);180181/* Enable uploading. */182curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");183curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);184185curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);186curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);187188if(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L) != CURLE_OK ||189curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, cli_debug_cb) != CURLE_OK ||190curl_easy_setopt(curl, CURLOPT_RESOLVE, resolve) != CURLE_OK) {191curl_mfprintf(stderr, "something unexpected went wrong - bailing out!\n");192result = (CURLcode)2;193goto cleanup;194}195196curl_easy_setopt(curl, CURLOPT_URL, url);197curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version);198199result = curl_easy_perform(curl);200201cleanup:202203if(curl)204curl_easy_cleanup(curl);205curl_slist_free_all(resolve);206curl_free(host);207curl_free(port);208if(cu)209curl_url_cleanup(cu);210curl_global_cleanup();211212return result;213}214215216