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