xref: /curl/tests/libtest/lib643.c (revision 71cf0d1f)
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 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.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 #include "test.h"
25 
26 #include "memdebug.h"
27 
28 static char testdata[]=
29   "dummy\n";
30 
31 struct WriteThis {
32   char *readptr;
33   curl_off_t sizeleft;
34 };
35 
read_callback(char * ptr,size_t size,size_t nmemb,void * userp)36 static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp)
37 {
38   struct WriteThis *pooh = (struct WriteThis *)userp;
39   int eof = !*pooh->readptr;
40 
41   if(size*nmemb < 1)
42     return 0;
43 
44 #ifndef LIB645
45   eof = pooh->sizeleft <= 0;
46   if(!eof)
47     pooh->sizeleft--;
48 #endif
49 
50   if(!eof) {
51     *ptr = *pooh->readptr;           /* copy one single byte */
52     pooh->readptr++;                 /* advance pointer */
53     return 1;                        /* we return 1 byte at a time! */
54   }
55 
56   return 0;                         /* no more data left to deliver */
57 }
58 
test_once(char * URL,bool oldstyle)59 static CURLcode test_once(char *URL, bool oldstyle)
60 {
61   CURL *curl;
62   CURLcode res = CURLE_OK;
63 
64   curl_mime *mime = NULL;
65   curl_mimepart *part = NULL;
66   struct WriteThis pooh;
67   struct WriteThis pooh2;
68   curl_off_t datasize = -1;
69 
70   pooh.readptr = testdata;
71 #ifndef LIB645
72   datasize = (curl_off_t)strlen(testdata);
73 #endif
74   pooh.sizeleft = datasize;
75 
76   curl = curl_easy_init();
77   if(!curl) {
78     fprintf(stderr, "curl_easy_init() failed\n");
79     curl_global_cleanup();
80     return TEST_ERR_MAJOR_BAD;
81   }
82 
83   mime = curl_mime_init(curl);
84   if(!mime) {
85     fprintf(stderr, "curl_mime_init() failed\n");
86     curl_easy_cleanup(curl);
87     curl_global_cleanup();
88     return TEST_ERR_MAJOR_BAD;
89   }
90 
91   part = curl_mime_addpart(mime);
92   if(!part) {
93     fprintf(stderr, "curl_mime_addpart(1) failed\n");
94     curl_mime_free(mime);
95     curl_easy_cleanup(curl);
96     curl_global_cleanup();
97     return TEST_ERR_MAJOR_BAD;
98   }
99 
100   /* Fill in the file upload part */
101   if(oldstyle) {
102     res = curl_mime_name(part, "sendfile");
103     if(!res)
104       res = curl_mime_data_cb(part, datasize, read_callback,
105                               NULL, NULL, &pooh);
106     if(!res)
107       res = curl_mime_filename(part, "postit2.c");
108   }
109   else {
110     /* new style */
111     res = curl_mime_name(part, "sendfile alternative");
112     if(!res)
113       res = curl_mime_data_cb(part, datasize, read_callback,
114                               NULL, NULL, &pooh);
115     if(!res)
116       res = curl_mime_filename(part, "file name 2");
117   }
118 
119   if(res)
120     printf("curl_mime_xxx(1) = %s\n", curl_easy_strerror(res));
121 
122   /* Now add the same data with another name and make it not look like
123      a file upload but still using the callback */
124 
125   pooh2.readptr = testdata;
126 #ifndef LIB645
127   datasize = (curl_off_t)strlen(testdata);
128 #endif
129   pooh2.sizeleft = datasize;
130 
131   part = curl_mime_addpart(mime);
132   if(!part) {
133     fprintf(stderr, "curl_mime_addpart(2) failed\n");
134     curl_mime_free(mime);
135     curl_easy_cleanup(curl);
136     curl_global_cleanup();
137     return TEST_ERR_MAJOR_BAD;
138   }
139   /* Fill in the file upload part */
140   res = curl_mime_name(part, "callbackdata");
141   if(!res)
142     res = curl_mime_data_cb(part, datasize, read_callback,
143                             NULL, NULL, &pooh2);
144 
145   if(res)
146     printf("curl_mime_xxx(2) = %s\n", curl_easy_strerror(res));
147 
148   part = curl_mime_addpart(mime);
149   if(!part) {
150     fprintf(stderr, "curl_mime_addpart(3) failed\n");
151     curl_mime_free(mime);
152     curl_easy_cleanup(curl);
153     curl_global_cleanup();
154     return TEST_ERR_MAJOR_BAD;
155   }
156 
157   /* Fill in the filename field */
158   res = curl_mime_name(part, "filename");
159   if(!res)
160     res = curl_mime_data(part, "postit2.c",
161                          CURL_ZERO_TERMINATED);
162 
163   if(res)
164     printf("curl_mime_xxx(3) = %s\n", curl_easy_strerror(res));
165 
166   /* Fill in a submit field too */
167   part = curl_mime_addpart(mime);
168   if(!part) {
169     fprintf(stderr, "curl_mime_addpart(4) failed\n");
170     curl_mime_free(mime);
171     curl_easy_cleanup(curl);
172     curl_global_cleanup();
173     return TEST_ERR_MAJOR_BAD;
174   }
175   res = curl_mime_name(part, "submit");
176   if(!res)
177     res = curl_mime_data(part, "send",
178                          CURL_ZERO_TERMINATED);
179 
180   if(res)
181     printf("curl_mime_xxx(4) = %s\n", curl_easy_strerror(res));
182 
183   part = curl_mime_addpart(mime);
184   if(!part) {
185     fprintf(stderr, "curl_mime_addpart(5) failed\n");
186     curl_mime_free(mime);
187     curl_easy_cleanup(curl);
188     curl_global_cleanup();
189     return TEST_ERR_MAJOR_BAD;
190   }
191   res = curl_mime_name(part, "somename");
192   if(!res)
193     res = curl_mime_filename(part, "somefile.txt");
194   if(!res)
195     res = curl_mime_data(part, "blah blah", 9);
196 
197   if(res)
198     printf("curl_mime_xxx(5) = %s\n", curl_easy_strerror(res));
199 
200   /* First set the URL that is about to receive our POST. */
201   test_setopt(curl, CURLOPT_URL, URL);
202 
203   /* send a multi-part mimepost */
204   test_setopt(curl, CURLOPT_MIMEPOST, mime);
205 
206   /* get verbose debug output please */
207   test_setopt(curl, CURLOPT_VERBOSE, 1L);
208 
209   /* include headers in the output */
210   test_setopt(curl, CURLOPT_HEADER, 1L);
211 
212   /* Perform the request, res will get the return code */
213   res = curl_easy_perform(curl);
214 
215 test_cleanup:
216 
217   /* always cleanup */
218   curl_easy_cleanup(curl);
219 
220   /* now cleanup the mimepost structure */
221   curl_mime_free(mime);
222 
223   return res;
224 }
225 
cyclic_add(void)226 static CURLcode cyclic_add(void)
227 {
228   CURL *easy = curl_easy_init();
229   curl_mime *mime = curl_mime_init(easy);
230   curl_mimepart *part = curl_mime_addpart(mime);
231   CURLcode a1 = curl_mime_subparts(part, mime);
232 
233   if(a1 == CURLE_BAD_FUNCTION_ARGUMENT) {
234     curl_mime *submime = curl_mime_init(easy);
235     curl_mimepart *subpart = curl_mime_addpart(submime);
236 
237     curl_mime_subparts(part, submime);
238     a1 = curl_mime_subparts(subpart, mime);
239   }
240 
241   curl_mime_free(mime);
242   curl_easy_cleanup(easy);
243   if(a1 != CURLE_BAD_FUNCTION_ARGUMENT)
244     /* that should have failed */
245     return (CURLcode)1;
246 
247   return CURLE_OK;
248 }
249 
test(char * URL)250 CURLcode test(char *URL)
251 {
252   CURLcode res;
253 
254   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
255     fprintf(stderr, "curl_global_init() failed\n");
256     return TEST_ERR_MAJOR_BAD;
257   }
258 
259   res = test_once(URL, TRUE); /* old */
260   if(!res)
261     res = test_once(URL, FALSE); /* new */
262 
263   if(!res)
264     res = cyclic_add();
265 
266   curl_global_cleanup();
267 
268   return res;
269 }
270