Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/curl/tests/libtest/cli_upload_pausing.c
2649 views
1
/***************************************************************************
2
* _ _ ____ _
3
* Project ___| | | | _ \| |
4
* / __| | | | |_) | |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
7
*
8
* Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9
*
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at https://curl.se/docs/copyright.html.
13
*
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
17
*
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
20
*
21
* SPDX-License-Identifier: curl
22
*
23
***************************************************************************/
24
/* This is based on the PoC client of issue #11769
25
*/
26
#include "first.h"
27
28
#include "testtrace.h"
29
#include "memdebug.h"
30
31
static size_t total_read = 0;
32
33
static size_t read_callback(char *ptr, size_t size, size_t nmemb,
34
void *userdata)
35
{
36
static const size_t PAUSE_READ_AFTER = 1;
37
38
(void)size;
39
(void)nmemb;
40
(void)userdata;
41
if(total_read >= PAUSE_READ_AFTER) {
42
curl_mfprintf(stderr, "read_callback, return PAUSE\n");
43
return CURL_READFUNC_PAUSE;
44
}
45
else {
46
ptr[0] = '\n';
47
++total_read;
48
curl_mfprintf(stderr, "read_callback, return 1 byte\n");
49
return 1;
50
}
51
}
52
53
static int progress_callback(void *clientp,
54
curl_off_t dltotal,
55
curl_off_t dlnow,
56
curl_off_t ultotal,
57
curl_off_t ulnow)
58
{
59
(void)dltotal;
60
(void)dlnow;
61
(void)ultotal;
62
(void)ulnow;
63
(void)clientp;
64
#if 0
65
/* Used to unpause on progress, but keeping for now. */
66
{
67
CURL *curl = (CURL *)clientp;
68
curl_easy_pause(curl, CURLPAUSE_CONT);
69
/* curl_easy_pause(curl, CURLPAUSE_RECV_CONT); */
70
}
71
#endif
72
return 0;
73
}
74
75
static void usage_upload_pausing(const char *msg)
76
{
77
if(msg)
78
curl_mfprintf(stderr, "%s\n", msg);
79
curl_mfprintf(stderr,
80
"usage: [options] url\n"
81
" upload and pause, options:\n"
82
" -V http_version (http/1.1, h2, h3) http version to use\n"
83
);
84
}
85
86
static CURLcode test_cli_upload_pausing(const char *URL)
87
{
88
CURL *curl = NULL;
89
CURLcode result = CURLE_OK;
90
CURLU *cu;
91
struct curl_slist *resolve = NULL;
92
char resolve_buf[1024];
93
const char *url;
94
char *host = NULL, *port = NULL;
95
long http_version = CURL_HTTP_VERSION_1_1;
96
int ch;
97
98
(void)URL;
99
100
while((ch = cgetopt(test_argc, test_argv, "V:")) != -1) {
101
switch(ch) {
102
case 'V': {
103
if(!strcmp("http/1.1", coptarg))
104
http_version = CURL_HTTP_VERSION_1_1;
105
else if(!strcmp("h2", coptarg))
106
http_version = CURL_HTTP_VERSION_2_0;
107
else if(!strcmp("h3", coptarg))
108
http_version = CURL_HTTP_VERSION_3ONLY;
109
else {
110
usage_upload_pausing("invalid http version");
111
return (CURLcode)1;
112
}
113
break;
114
}
115
default:
116
usage_upload_pausing("invalid option");
117
return (CURLcode)1;
118
}
119
}
120
test_argc -= coptind;
121
test_argv += coptind;
122
123
if(test_argc != 1) {
124
usage_upload_pausing("not enough arguments");
125
return (CURLcode)2;
126
}
127
url = test_argv[0];
128
129
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
130
curl_mfprintf(stderr, "curl_global_init() failed\n");
131
return (CURLcode)3;
132
}
133
134
curl_global_trace("ids,time");
135
136
cu = curl_url();
137
if(!cu) {
138
curl_mfprintf(stderr, "out of memory\n");
139
result = (CURLcode)1;
140
goto cleanup;
141
}
142
if(curl_url_set(cu, CURLUPART_URL, url, 0)) {
143
curl_mfprintf(stderr, "not a URL: '%s'\n", url);
144
result = (CURLcode)1;
145
goto cleanup;
146
}
147
if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) {
148
curl_mfprintf(stderr, "could not get host of '%s'\n", url);
149
result = (CURLcode)1;
150
goto cleanup;
151
}
152
if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) {
153
curl_mfprintf(stderr, "could not get port of '%s'\n", url);
154
result = (CURLcode)1;
155
goto cleanup;
156
}
157
memset(&resolve, 0, sizeof(resolve));
158
curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1",
159
host, port);
160
resolve = curl_slist_append(resolve, resolve_buf);
161
162
curl = curl_easy_init();
163
if(!curl) {
164
curl_mfprintf(stderr, "out of memory\n");
165
result = (CURLcode)1;
166
goto cleanup;
167
}
168
/* We want to use our own read function. */
169
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
170
171
/* It will help us to continue the read function. */
172
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
173
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, curl);
174
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
175
176
/* It will help us to ensure that keepalive does not help. */
177
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
178
curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 1L);
179
curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 1L);
180
curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 1L);
181
182
/* Enable uploading. */
183
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
184
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
185
186
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
187
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
188
189
if(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L) != CURLE_OK ||
190
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, cli_debug_cb) != CURLE_OK ||
191
curl_easy_setopt(curl, CURLOPT_RESOLVE, resolve) != CURLE_OK) {
192
curl_mfprintf(stderr, "something unexpected went wrong - bailing out!\n");
193
result = (CURLcode)2;
194
goto cleanup;
195
}
196
197
curl_easy_setopt(curl, CURLOPT_URL, url);
198
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version);
199
200
result = curl_easy_perform(curl);
201
202
cleanup:
203
204
if(curl)
205
curl_easy_cleanup(curl);
206
curl_slist_free_all(resolve);
207
curl_free(host);
208
curl_free(port);
209
if(cu)
210
curl_url_cleanup(cu);
211
curl_global_cleanup();
212
213
return result;
214
}
215
216