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