Annotation of embedaddon/curl/tests/libtest/lib670.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: #include <time.h>
24:
25: #include "test.h"
26:
27: #include "memdebug.h"
28:
29: #define PAUSE_TIME 2
30:
31:
32: static const char name[] = "field";
33:
34: struct ReadThis {
35: CURL *easy;
36: time_t origin;
37: int count;
38: };
39:
40:
41: static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp)
42: {
43: struct ReadThis *pooh = (struct ReadThis *) userp;
44: time_t delta;
45:
46: if(size * nmemb < 1)
47: return 0;
48:
49: switch(pooh->count++) {
50: case 0:
51: *ptr = '\x41'; /* ASCII A. */
52: return 1;
53: case 1:
54: pooh->origin = time(NULL);
55: return CURL_READFUNC_PAUSE;
56: case 2:
57: delta = time(NULL) - pooh->origin;
58: *ptr = delta >= PAUSE_TIME? '\x42': '\x41'; /* ASCII A or B. */
59: return 1;
60: case 3:
61: return 0;
62: }
63: fprintf(stderr, "Read callback called after EOF\n");
64: exit(1);
65: }
66:
67: #if !defined(LIB670) && !defined(LIB672)
68: static int xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
69: curl_off_t ultotal, curl_off_t ulnow)
70: {
71: struct ReadThis *pooh = (struct ReadThis *) clientp;
72:
73: (void) dltotal;
74: (void) dlnow;
75: (void) ultotal;
76: (void) ulnow;
77:
78: if(pooh->origin) {
79: time_t delta = time(NULL) - pooh->origin;
80:
81: if(delta >= 4 * PAUSE_TIME) {
82: fprintf(stderr, "unpausing failed: drain problem?\n");
83: return CURLE_ABORTED_BY_CALLBACK;
84: }
85:
86: if(delta >= PAUSE_TIME)
87: curl_easy_pause(pooh->easy, CURLPAUSE_CONT);
88: }
89:
90: return 0;
91: }
92: #endif
93:
94: int test(char *URL)
95: {
96: #if defined(LIB670) || defined(LIB671)
97: curl_mime *mime = NULL;
98: curl_mimepart *part;
99: #else
100: CURLFORMcode formrc;
101: struct curl_httppost *formpost = NULL;
102: struct curl_httppost *lastptr = NULL;
103: #endif
104: #if defined(LIB670) || defined(LIB672)
105: CURLM *multi = NULL;
106: CURLMcode mres;
107: CURLMsg *msg;
108: int msgs_left;
109: int still_running = 0;
110: #endif
111:
112: struct ReadThis pooh;
113: CURLcode result;
114: int res = TEST_ERR_FAILURE;
115:
116: /*
117: * Check proper pausing/unpausing from a mime or form read callback.
118: */
119:
120: if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
121: fprintf(stderr, "curl_global_init() failed\n");
122: return TEST_ERR_MAJOR_BAD;
123: }
124:
125: pooh.origin = (time_t) 0;
126: pooh.count = 0;
127: pooh.easy = curl_easy_init();
128:
129: /* First set the URL that is about to receive our POST. */
130: test_setopt(pooh.easy, CURLOPT_URL, URL);
131:
132: /* get verbose debug output please */
133: test_setopt(pooh.easy, CURLOPT_VERBOSE, 1L);
134:
135: /* include headers in the output */
136: test_setopt(pooh.easy, CURLOPT_HEADER, 1L);
137:
138: #if defined(LIB670) || defined(LIB671)
139: /* Build the mime tree. */
140: mime = curl_mime_init(pooh.easy);
141: part = curl_mime_addpart(mime);
142: result = curl_mime_name(part, name);
143: if(!result)
144: res = curl_mime_data_cb(part, (curl_off_t) 2, read_callback,
145: NULL, NULL, &pooh);
146:
147: if(result) {
148: fprintf(stderr,
149: "Something went wrong when building the mime structure: %d\n",
150: (int) result);
151: goto test_cleanup;
152: }
153:
154: /* Bind mime data to its easy handle. */
155: if(!res)
156: test_setopt(pooh.easy, CURLOPT_MIMEPOST, mime);
157: #else
158: /* Build the form. */
159: formrc = curl_formadd(&formpost, &lastptr,
160: CURLFORM_COPYNAME, name,
161: CURLFORM_STREAM, &pooh,
162: CURLFORM_CONTENTLEN, (curl_off_t) 2,
163: CURLFORM_END);
164: if(formrc) {
165: fprintf(stderr, "curl_formadd() = %d\n", (int) formrc);
166: goto test_cleanup;
167: }
168:
169: /* We want to use our own read function. */
170: test_setopt(pooh.easy, CURLOPT_READFUNCTION, read_callback);
171:
172: /* Send a multi-part formpost. */
173: test_setopt(pooh.easy, CURLOPT_HTTPPOST, formpost);
174: #endif
175:
176: #if defined(LIB670) || defined(LIB672)
177: /* Use the multi interface. */
178: multi = curl_multi_init();
179: mres = curl_multi_add_handle(multi, pooh.easy);
180: while(!mres) {
181: struct timeval timeout;
182: int rc = 0;
183: fd_set fdread;
184: fd_set fdwrite;
185: fd_set fdexcept;
186: int maxfd = -1;
187:
188: mres = curl_multi_perform(multi, &still_running);
189: if(!still_running || mres != CURLM_OK)
190: break;
191:
192: if(pooh.origin) {
193: time_t delta = time(NULL) - pooh.origin;
194:
195: if(delta >= 4 * PAUSE_TIME) {
196: fprintf(stderr, "unpausing failed: drain problem?\n");
197: res = CURLE_OPERATION_TIMEDOUT;
198: break;
199: }
200:
201: if(delta >= PAUSE_TIME)
202: curl_easy_pause(pooh.easy, CURLPAUSE_CONT);
203: }
204:
205: FD_ZERO(&fdread);
206: FD_ZERO(&fdwrite);
207: FD_ZERO(&fdexcept);
208: timeout.tv_sec = 0;
209: timeout.tv_usec = 1000000 * PAUSE_TIME / 10;
210: mres = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcept, &maxfd);
211: if(mres)
212: break;
213: #if defined(WIN32) || defined(_WIN32)
214: if(maxfd == -1)
215: Sleep(100);
216: else
217: #endif
218: rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcept, &timeout);
219: if(rc == -1) {
220: fprintf(stderr, "Select error\n");
221: break;
222: }
223: }
224:
225: if(mres != CURLM_OK)
226: for(;;) {
227: msg = curl_multi_info_read(multi, &msgs_left);
228: if(!msg)
229: break;
230: if(msg->msg == CURLMSG_DONE) {
231: result = msg->data.result;
232: res = (int) result;
233: }
234: }
235:
236: curl_multi_remove_handle(multi, pooh.easy);
237: curl_multi_cleanup(multi);
238:
239: #else
240: /* Use the easy interface. */
241: test_setopt(pooh.easy, CURLOPT_XFERINFODATA, &pooh);
242: test_setopt(pooh.easy, CURLOPT_XFERINFOFUNCTION, xferinfo);
243: test_setopt(pooh.easy, CURLOPT_NOPROGRESS, 0L);
244: result = curl_easy_perform(pooh.easy);
245: res = (int) result;
246: #endif
247:
248:
249: test_cleanup:
250: curl_easy_cleanup(pooh.easy);
251: #if defined(LIB670) || defined(LIB671)
252: curl_mime_free(mime);
253: #else
254: curl_formfree(formpost);
255: #endif
256:
257: curl_global_cleanup();
258: return res;
259: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>