Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/curl/tests/libtest/lib1533.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
25
/*
26
* This test sends data with CURLOPT_KEEP_SENDING_ON_ERROR.
27
* The server responds with an early error response.
28
* The test is successful if the connection can be reused for the next request,
29
* because this implies that the data has been sent completely to the server.
30
*/
31
32
#include "first.h"
33
34
#include "memdebug.h"
35
36
struct cb_data {
37
CURL *curl;
38
int response_received;
39
int paused;
40
size_t remaining_bytes;
41
};
42
43
static void reset_data(struct cb_data *data, CURL *curl)
44
{
45
data->curl = curl;
46
data->response_received = 0;
47
data->paused = 0;
48
data->remaining_bytes = 3;
49
}
50
51
static size_t t1533_read_cb(char *ptr, size_t size, size_t nitems, void *userp)
52
{
53
struct cb_data *data = (struct cb_data *)userp;
54
55
/* wait until the server has sent all response headers */
56
if(data->response_received) {
57
size_t totalsize = nitems * size;
58
59
size_t bytes_to_send = data->remaining_bytes;
60
if(bytes_to_send > totalsize) {
61
bytes_to_send = totalsize;
62
}
63
64
memset(ptr, 'a', bytes_to_send);
65
data->remaining_bytes -= bytes_to_send;
66
67
return bytes_to_send;
68
}
69
else {
70
data->paused = 1;
71
return CURL_READFUNC_PAUSE;
72
}
73
}
74
75
static size_t t1533_write_cb(char *ptr, size_t size, size_t nmemb, void *userp)
76
{
77
struct cb_data *data = (struct cb_data *)userp;
78
size_t totalsize = nmemb * size;
79
80
(void)ptr;
81
82
/* all response headers have been received */
83
data->response_received = 1;
84
85
if(data->paused) {
86
/* continue to send request body data */
87
data->paused = 0;
88
curl_easy_pause(data->curl, CURLPAUSE_CONT);
89
}
90
91
return totalsize;
92
}
93
94
static CURLcode perform_and_check_connections(CURL *curl,
95
const char *description,
96
long expected_connections)
97
{
98
CURLcode res;
99
long connections = 0;
100
101
res = curl_easy_perform(curl);
102
if(res != CURLE_OK) {
103
curl_mfprintf(stderr, "curl_easy_perform() failed with %d\n", res);
104
return TEST_ERR_MAJOR_BAD;
105
}
106
107
res = curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &connections);
108
if(res != CURLE_OK) {
109
curl_mfprintf(stderr, "curl_easy_getinfo() failed\n");
110
return TEST_ERR_MAJOR_BAD;
111
}
112
113
curl_mfprintf(stderr,
114
"%s: expected: %ld connections; actual: %ld connections\n",
115
description, expected_connections, connections);
116
117
if(connections != expected_connections) {
118
return TEST_ERR_FAILURE;
119
}
120
121
return TEST_ERR_SUCCESS;
122
}
123
124
125
static CURLcode test_lib1533(const char *URL)
126
{
127
struct cb_data data;
128
CURL *curl = NULL;
129
CURLcode res = TEST_ERR_FAILURE;
130
CURLcode result;
131
132
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
133
curl_mfprintf(stderr, "curl_global_init() failed\n");
134
return TEST_ERR_MAJOR_BAD;
135
}
136
137
curl = curl_easy_init();
138
if(!curl) {
139
curl_mfprintf(stderr, "curl_easy_init() failed\n");
140
curl_global_cleanup();
141
return TEST_ERR_MAJOR_BAD;
142
}
143
144
reset_data(&data, curl);
145
146
test_setopt(curl, CURLOPT_URL, URL);
147
test_setopt(curl, CURLOPT_POST, 1L);
148
test_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
149
(curl_off_t)data.remaining_bytes);
150
test_setopt(curl, CURLOPT_VERBOSE, 1L);
151
test_setopt(curl, CURLOPT_READFUNCTION, t1533_read_cb);
152
test_setopt(curl, CURLOPT_READDATA, &data);
153
test_setopt(curl, CURLOPT_WRITEFUNCTION, t1533_write_cb);
154
test_setopt(curl, CURLOPT_WRITEDATA, &data);
155
156
result = perform_and_check_connections(curl,
157
"First request without CURLOPT_KEEP_SENDING_ON_ERROR", 1);
158
if(result != TEST_ERR_SUCCESS) {
159
res = result;
160
goto test_cleanup;
161
}
162
163
reset_data(&data, curl);
164
165
result = perform_and_check_connections(curl,
166
"Second request without CURLOPT_KEEP_SENDING_ON_ERROR", 1);
167
if(result != TEST_ERR_SUCCESS) {
168
res = result;
169
goto test_cleanup;
170
}
171
172
test_setopt(curl, CURLOPT_KEEP_SENDING_ON_ERROR, 1L);
173
174
reset_data(&data, curl);
175
176
result = perform_and_check_connections(curl,
177
"First request with CURLOPT_KEEP_SENDING_ON_ERROR", 1);
178
if(result != TEST_ERR_SUCCESS) {
179
res = result;
180
goto test_cleanup;
181
}
182
183
reset_data(&data, curl);
184
185
result = perform_and_check_connections(curl,
186
"Second request with CURLOPT_KEEP_SENDING_ON_ERROR", 0);
187
if(result != TEST_ERR_SUCCESS) {
188
res = result;
189
goto test_cleanup;
190
}
191
192
res = TEST_ERR_SUCCESS;
193
194
test_cleanup:
195
196
curl_easy_cleanup(curl);
197
198
curl_global_cleanup();
199
200
return res;
201
}
202
203