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 #define CURL_DISABLE_DEPRECATION /* Using and testing the form api */
25 #include "test.h"
26
27 #include "memdebug.h"
28
29 static char data[] =
30 "this is what we post to the silly web server";
31
32 static const char name[] = "fieldname";
33
34
35 /* This test attempts to use all form API features that are not
36 * used elsewhere.
37 */
38
39 /* curl_formget callback to count characters. */
count_chars(void * userp,const char * buf,size_t len)40 static size_t count_chars(void *userp, const char *buf, size_t len)
41 {
42 size_t *pcounter = (size_t *) userp;
43
44 (void) buf;
45 *pcounter += len;
46 return len;
47 }
48
49
test(char * URL)50 int test(char *URL)
51 {
52 CURL *curl = NULL;
53 CURLcode res = TEST_ERR_MAJOR_BAD;
54 CURLFORMcode formrc;
55 struct curl_slist *headers, *headers2 = NULL;
56 struct curl_httppost *formpost = NULL;
57 struct curl_httppost *lastptr = NULL;
58 struct curl_forms formarray[3];
59 size_t formlength = 0;
60 char flbuf[32];
61 long contentlength = 0;
62
63 if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
64 fprintf(stderr, "curl_global_init() failed\n");
65 return TEST_ERR_MAJOR_BAD;
66 }
67
68 /* Check proper name and data copying, as well as headers. */
69 headers = curl_slist_append(NULL, "X-customheader-1: Header 1 data");
70 if(!headers) {
71 goto test_cleanup;
72 }
73 headers2 = curl_slist_append(headers, "X-customheader-2: Header 2 data");
74 if(!headers2) {
75 goto test_cleanup;
76 }
77 headers = headers2;
78 headers2 = curl_slist_append(headers, "Content-Type: text/plain");
79 if(!headers2) {
80 goto test_cleanup;
81 }
82 headers = headers2;
83 formrc = curl_formadd(&formpost, &lastptr,
84 CURLFORM_COPYNAME, &name,
85 CURLFORM_COPYCONTENTS, &data,
86 CURLFORM_CONTENTHEADER, headers,
87 CURLFORM_END);
88
89 if(formrc) {
90 printf("curl_formadd(1) = %d\n", (int) formrc);
91 goto test_cleanup;
92 }
93
94 contentlength = (long)(strlen(data) - 1);
95
96 /* Use a form array for the non-copy test. */
97 formarray[0].option = CURLFORM_PTRCONTENTS;
98 formarray[0].value = data;
99 formarray[1].option = CURLFORM_CONTENTSLENGTH;
100 formarray[1].value = (char *)(size_t)contentlength;
101 formarray[2].option = CURLFORM_END;
102 formarray[2].value = NULL;
103 formrc = curl_formadd(&formpost,
104 &lastptr,
105 CURLFORM_PTRNAME, name,
106 CURLFORM_NAMELENGTH, strlen(name) - 1,
107 CURLFORM_ARRAY, formarray,
108 CURLFORM_FILENAME, "remotefile.txt",
109 CURLFORM_END);
110
111 if(formrc) {
112 printf("curl_formadd(2) = %d\n", (int) formrc);
113 goto test_cleanup;
114 }
115
116 /* Now change in-memory data to affect CURLOPT_PTRCONTENTS value.
117 Copied values (first field) must not be affected.
118 CURLOPT_PTRNAME actually copies the name thus we do not test this here. */
119 data[0]++;
120
121 /* Check multi-files and content type propagation. */
122 formrc = curl_formadd(&formpost,
123 &lastptr,
124 CURLFORM_COPYNAME, "multifile",
125 CURLFORM_FILE, libtest_arg2, /* Set in first.c. */
126 CURLFORM_FILE, libtest_arg2,
127 CURLFORM_CONTENTTYPE, "text/whatever",
128 CURLFORM_FILE, libtest_arg2,
129 CURLFORM_END);
130
131 if(formrc) {
132 printf("curl_formadd(3) = %d\n", (int) formrc);
133 goto test_cleanup;
134 }
135
136 /* Check data from file content. */
137 formrc = curl_formadd(&formpost,
138 &lastptr,
139 CURLFORM_COPYNAME, "filecontents",
140 CURLFORM_FILECONTENT, libtest_arg2,
141 CURLFORM_END);
142
143 if(formrc) {
144 printf("curl_formadd(4) = %d\n", (int) formrc);
145 goto test_cleanup;
146 }
147
148 /* Measure the current form length.
149 * This is done before including stdin data because we want to reuse it
150 * and stdin cannot be rewound.
151 */
152 curl_formget(formpost, (void *) &formlength, count_chars);
153
154 /* Include length in data for external check. */
155 curl_msnprintf(flbuf, sizeof(flbuf), "%lu", (unsigned long) formlength);
156 formrc = curl_formadd(&formpost,
157 &lastptr,
158 CURLFORM_COPYNAME, "formlength",
159 CURLFORM_COPYCONTENTS, &flbuf,
160 CURLFORM_END);
161 if(formrc) {
162 printf("curl_formadd(5) = %d\n", (int) formrc);
163 goto test_cleanup;
164 }
165
166 /* Check stdin (may be problematic on some platforms). */
167 formrc = curl_formadd(&formpost,
168 &lastptr,
169 CURLFORM_COPYNAME, "standardinput",
170 CURLFORM_FILE, "-",
171 CURLFORM_END);
172 if(formrc) {
173 printf("curl_formadd(6) = %d\n", (int) formrc);
174 goto test_cleanup;
175 }
176
177 curl = curl_easy_init();
178 if(!curl) {
179 fprintf(stderr, "curl_easy_init() failed\n");
180 goto test_cleanup;
181 }
182
183 /* First set the URL that is about to receive our POST. */
184 test_setopt(curl, CURLOPT_URL, URL);
185
186 /* send a multi-part formpost */
187 test_setopt(curl, CURLOPT_HTTPPOST, formpost);
188
189 /* get verbose debug output please */
190 test_setopt(curl, CURLOPT_VERBOSE, 1L);
191
192 test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
193 test_setopt(curl, CURLOPT_POSTREDIR, (long)CURL_REDIR_POST_301);
194
195 /* include headers in the output */
196 test_setopt(curl, CURLOPT_HEADER, 1L);
197
198 /* Perform the request, res will get the return code */
199 res = curl_easy_perform(curl);
200
201 test_cleanup:
202
203 /* always cleanup */
204 curl_easy_cleanup(curl);
205
206 /* now cleanup the formpost chain */
207 curl_formfree(formpost);
208 curl_slist_free_all(headers);
209
210 curl_global_cleanup();
211
212 return res;
213 }
214