blob: ff1d6813a0b0671bfdeeab065f9514e087c726d8 [file] [log] [blame]
Kristian Monsen5ab50182010-05-14 18:53:44 +01001/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
Elliott Hughes0128fe42018-02-27 14:57:55 -08008 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
Kristian Monsen5ab50182010-05-14 18:53:44 +01009 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
Alex Deymod15eaac2016-06-28 14:49:26 -070012 * are also available at https://curl.haxx.se/docs/copyright.html.
Kristian Monsen5ab50182010-05-14 18:53:44 +010013 *
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
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070023#include "curl_setup.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010024
25#ifndef CURL_DISABLE_HTTP
Kristian Monsen5ab50182010-05-14 18:53:44 +010026
Kristian Monsen5ab50182010-05-14 18:53:44 +010027#ifdef HAVE_NETINET_IN_H
28#include <netinet/in.h>
29#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +010030
Kristian Monsen5ab50182010-05-14 18:53:44 +010031#ifdef HAVE_NETDB_H
32#include <netdb.h>
33#endif
34#ifdef HAVE_ARPA_INET_H
35#include <arpa/inet.h>
36#endif
37#ifdef HAVE_NET_IF_H
38#include <net/if.h>
39#endif
40#ifdef HAVE_SYS_IOCTL_H
41#include <sys/ioctl.h>
42#endif
43
44#ifdef HAVE_SYS_PARAM_H
45#include <sys/param.h>
46#endif
47
Kristian Monsen5ab50182010-05-14 18:53:44 +010048#include "urldata.h"
49#include <curl/curl.h>
50#include "transfer.h"
51#include "sendf.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010052#include "formdata.h"
Alex Deymo486467e2017-12-19 19:04:07 +010053#include "mime.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010054#include "progress.h"
55#include "curl_base64.h"
56#include "cookie.h"
Alex Deymod15eaac2016-06-28 14:49:26 -070057#include "vauth/vauth.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070058#include "vtls/vtls.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010059#include "http_digest.h"
Alex Deymod15eaac2016-06-28 14:49:26 -070060#include "http_ntlm.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070061#include "curl_ntlm_wb.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010062#include "http_negotiate.h"
63#include "url.h"
64#include "share.h"
65#include "hostip.h"
66#include "http.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010067#include "select.h"
68#include "parsedate.h" /* for the week day and month names */
69#include "strtoofft.h"
70#include "multiif.h"
Elliott Hughescee03382017-06-23 12:17:18 -070071#include "strcase.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010072#include "content_encoding.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070073#include "http_proxy.h"
74#include "warnless.h"
75#include "non-ascii.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070076#include "pipeline.h"
77#include "http2.h"
78#include "connect.h"
Elliott Hughescee03382017-06-23 12:17:18 -070079#include "strdup.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010080
Alex Deymod15eaac2016-06-28 14:49:26 -070081/* The last 3 #include files should be in this order */
82#include "curl_printf.h"
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070083#include "curl_memory.h"
Kristian Monsen5ab50182010-05-14 18:53:44 +010084#include "memdebug.h"
85
Kristian Monsen5ab50182010-05-14 18:53:44 +010086/*
87 * Forward declarations.
88 */
89
90static int http_getsock_do(struct connectdata *conn,
91 curl_socket_t *socks,
92 int numsocks);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -070093static int http_should_fail(struct connectdata *conn);
94
Elliott Hughes1ef06ba2018-05-30 15:43:58 -070095static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
96
Kristian Monsen5ab50182010-05-14 18:53:44 +010097#ifdef USE_SSL
98static CURLcode https_connecting(struct connectdata *conn, bool *done);
99static int https_getsock(struct connectdata *conn,
100 curl_socket_t *socks,
101 int numsocks);
102#else
103#define https_connecting(x,y) CURLE_COULDNT_CONNECT
104#endif
105
106/*
107 * HTTP handler interface.
108 */
109const struct Curl_handler Curl_handler_http = {
110 "HTTP", /* scheme */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700111 Curl_http_setup_conn, /* setup_connection */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100112 Curl_http, /* do_it */
113 Curl_http_done, /* done */
114 ZERO_NULL, /* do_more */
115 Curl_http_connect, /* connect_it */
116 ZERO_NULL, /* connecting */
117 ZERO_NULL, /* doing */
118 ZERO_NULL, /* proto_getsock */
119 http_getsock_do, /* doing_getsock */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700120 ZERO_NULL, /* domore_getsock */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100121 ZERO_NULL, /* perform_getsock */
Alex Deymod15eaac2016-06-28 14:49:26 -0700122 ZERO_NULL, /* disconnect */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700123 ZERO_NULL, /* readwrite */
Elliott Hughes82be86d2017-09-20 17:00:17 -0700124 ZERO_NULL, /* connection_check */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100125 PORT_HTTP, /* defport */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700126 CURLPROTO_HTTP, /* protocol */
127 PROTOPT_CREDSPERREQUEST /* flags */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100128};
129
130#ifdef USE_SSL
131/*
132 * HTTPS handler interface.
133 */
134const struct Curl_handler Curl_handler_https = {
135 "HTTPS", /* scheme */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700136 Curl_http_setup_conn, /* setup_connection */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100137 Curl_http, /* do_it */
138 Curl_http_done, /* done */
139 ZERO_NULL, /* do_more */
140 Curl_http_connect, /* connect_it */
141 https_connecting, /* connecting */
142 ZERO_NULL, /* doing */
143 https_getsock, /* proto_getsock */
144 http_getsock_do, /* doing_getsock */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700145 ZERO_NULL, /* domore_getsock */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100146 ZERO_NULL, /* perform_getsock */
Alex Deymod15eaac2016-06-28 14:49:26 -0700147 ZERO_NULL, /* disconnect */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700148 ZERO_NULL, /* readwrite */
Elliott Hughes82be86d2017-09-20 17:00:17 -0700149 ZERO_NULL, /* connection_check */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100150 PORT_HTTPS, /* defport */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700151 CURLPROTO_HTTPS, /* protocol */
Alex Deymod15eaac2016-06-28 14:49:26 -0700152 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100153};
154#endif
155
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700156CURLcode Curl_http_setup_conn(struct connectdata *conn)
157{
Alex Deymoe3149cc2016-10-05 11:18:42 -0700158 /* allocate the HTTP-specific struct for the Curl_easy, only to survive
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700159 during this request */
160 struct HTTP *http;
161 DEBUGASSERT(conn->data->req.protop == NULL);
162
163 http = calloc(1, sizeof(struct HTTP));
164 if(!http)
165 return CURLE_OUT_OF_MEMORY;
166
Alex Deymo486467e2017-12-19 19:04:07 +0100167 Curl_mime_initpart(&http->form, conn->data);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700168 conn->data->req.protop = http;
169
170 Curl_http2_setup_conn(conn);
Alex Deymod15eaac2016-06-28 14:49:26 -0700171 Curl_http2_setup_req(conn->data);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700172
173 return CURLE_OK;
174}
175
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700176
177/*
178 * checkProxyHeaders() checks the linked list of custom proxy headers
179 * if proxy headers are not available, then it will lookup into http header
180 * link list
181 *
Elliott Hughescac39802018-04-27 16:19:43 -0700182 * It takes a connectdata struct as input instead of the Curl_easy simply to
183 * know if this is a proxy request or not, as it then might check a different
184 * header list. Provide the header prefix without colon!.
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700185 */
186char *Curl_checkProxyheaders(const struct connectdata *conn,
187 const char *thisheader)
188{
189 struct curl_slist *head;
190 size_t thislen = strlen(thisheader);
Alex Deymoe3149cc2016-10-05 11:18:42 -0700191 struct Curl_easy *data = conn->data;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700192
Alex Deymod15eaac2016-06-28 14:49:26 -0700193 for(head = (conn->bits.proxy && data->set.sep_headers) ?
194 data->set.proxyheaders : data->set.headers;
Alex Deymo486467e2017-12-19 19:04:07 +0100195 head; head = head->next) {
Elliott Hughescac39802018-04-27 16:19:43 -0700196 if(strncasecompare(head->data, thisheader, thislen) &&
197 Curl_headersep(head->data[thislen]))
Kristian Monsen5ab50182010-05-14 18:53:44 +0100198 return head->data;
199 }
Alex Deymod15eaac2016-06-28 14:49:26 -0700200
Kristian Monsen5ab50182010-05-14 18:53:44 +0100201 return NULL;
202}
203
204/*
205 * Strip off leading and trailing whitespace from the value in the
206 * given HTTP header line and return a strdupped copy. Returns NULL in
207 * case of allocation failure. Returns an empty string if the header value
208 * consists entirely of whitespace.
209 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700210char *Curl_copy_header_value(const char *header)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100211{
212 const char *start;
213 const char *end;
214 char *value;
215 size_t len;
216
Kristian Monsen5ab50182010-05-14 18:53:44 +0100217 /* Find the end of the header name */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700218 while(*header && (*header != ':'))
219 ++header;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100220
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700221 if(*header)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100222 /* Skip over colon */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700223 ++header;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100224
225 /* Find the first non-space letter */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700226 start = header;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100227 while(*start && ISSPACE(*start))
228 start++;
229
230 /* data is in the host encoding so
231 use '\r' and '\n' instead of 0x0d and 0x0a */
232 end = strchr(start, '\r');
233 if(!end)
234 end = strchr(start, '\n');
235 if(!end)
236 end = strchr(start, '\0');
237 if(!end)
238 return NULL;
239
240 /* skip all trailing space letters */
241 while((end > start) && ISSPACE(*end))
242 end--;
243
244 /* get length of the type */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700245 len = end - start + 1;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100246
247 value = malloc(len + 1);
248 if(!value)
249 return NULL;
250
251 memcpy(value, start, len);
252 value[len] = 0; /* zero terminate */
253
254 return value;
255}
256
257/*
258 * http_output_basic() sets up an Authorization: header (or the proxy version)
259 * for HTTP Basic authentication.
260 *
261 * Returns CURLcode.
262 */
263static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
264{
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700265 size_t size = 0;
266 char *authorization = NULL;
Alex Deymoe3149cc2016-10-05 11:18:42 -0700267 struct Curl_easy *data = conn->data;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100268 char **userp;
269 const char *user;
270 const char *pwd;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700271 CURLcode result;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700272 char *out;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100273
274 if(proxy) {
275 userp = &conn->allocptr.proxyuserpwd;
Elliott Hughescee03382017-06-23 12:17:18 -0700276 user = conn->http_proxy.user;
277 pwd = conn->http_proxy.passwd;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100278 }
279 else {
280 userp = &conn->allocptr.userpwd;
281 user = conn->user;
282 pwd = conn->passwd;
283 }
284
Elliott Hughes82be86d2017-09-20 17:00:17 -0700285 out = aprintf("%s:%s", user, pwd);
286 if(!out)
287 return CURLE_OUT_OF_MEMORY;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700288
Elliott Hughes82be86d2017-09-20 17:00:17 -0700289 result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700290 if(result)
Elliott Hughes82be86d2017-09-20 17:00:17 -0700291 goto fail;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700292
Elliott Hughes82be86d2017-09-20 17:00:17 -0700293 if(!authorization) {
294 result = CURLE_REMOTE_ACCESS_DENIED;
295 goto fail;
296 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700297
298 free(*userp);
299 *userp = aprintf("%sAuthorization: Basic %s\r\n",
Alex Deymod15eaac2016-06-28 14:49:26 -0700300 proxy ? "Proxy-" : "",
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700301 authorization);
302 free(authorization);
Elliott Hughes82be86d2017-09-20 17:00:17 -0700303 if(!*userp) {
304 result = CURLE_OUT_OF_MEMORY;
305 goto fail;
306 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700307
Elliott Hughes82be86d2017-09-20 17:00:17 -0700308 fail:
309 free(out);
310 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100311}
312
313/* pickoneauth() selects the most favourable authentication method from the
314 * ones available and the ones we want.
315 *
316 * return TRUE if one was picked
317 */
318static bool pickoneauth(struct auth *pick)
319{
320 bool picked;
321 /* only deal with authentication we want */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700322 unsigned long avail = pick->avail & pick->want;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100323 picked = TRUE;
324
325 /* The order of these checks is highly relevant, as this will be the order
326 of preference in case of the existence of multiple accepted types. */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700327 if(avail & CURLAUTH_NEGOTIATE)
328 pick->picked = CURLAUTH_NEGOTIATE;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100329 else if(avail & CURLAUTH_DIGEST)
330 pick->picked = CURLAUTH_DIGEST;
331 else if(avail & CURLAUTH_NTLM)
332 pick->picked = CURLAUTH_NTLM;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700333 else if(avail & CURLAUTH_NTLM_WB)
334 pick->picked = CURLAUTH_NTLM_WB;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100335 else if(avail & CURLAUTH_BASIC)
336 pick->picked = CURLAUTH_BASIC;
337 else {
338 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
339 picked = FALSE;
340 }
341 pick->avail = CURLAUTH_NONE; /* clear it here */
342
343 return picked;
344}
345
346/*
347 * Curl_http_perhapsrewind()
348 *
349 * If we are doing POST or PUT {
350 * If we have more data to send {
351 * If we are doing NTLM {
352 * Keep sending since we must not disconnect
353 * }
354 * else {
355 * If there is more than just a little data left to send, close
356 * the current connection by force.
357 * }
358 * }
359 * If we have sent any data {
360 * If we don't have track of all the data {
361 * call app to tell it to rewind
362 * }
363 * else {
364 * rewind internally so that the operation can restart fine
365 * }
366 * }
367 * }
368 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700369static CURLcode http_perhapsrewind(struct connectdata *conn)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100370{
Alex Deymoe3149cc2016-10-05 11:18:42 -0700371 struct Curl_easy *data = conn->data;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700372 struct HTTP *http = data->req.protop;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100373 curl_off_t bytessent;
374 curl_off_t expectsend = -1; /* default is unknown */
375
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700376 if(!http)
377 /* If this is still NULL, we have not reach very far and we can safely
378 skip this rewinding stuff */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100379 return CURLE_OK;
380
381 switch(data->set.httpreq) {
382 case HTTPREQ_GET:
383 case HTTPREQ_HEAD:
384 return CURLE_OK;
385 default:
386 break;
387 }
388
389 bytessent = http->writebytecount;
390
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700391 if(conn->bits.authneg) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100392 /* This is a state where we are known to be negotiating and we don't send
393 any data then. */
394 expectsend = 0;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700395 }
396 else if(!conn->bits.protoconnstart) {
397 /* HTTP CONNECT in progress: there is no body */
398 expectsend = 0;
399 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100400 else {
401 /* figure out how much data we are expected to send */
402 switch(data->set.httpreq) {
403 case HTTPREQ_POST:
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700404 if(data->state.infilesize != -1)
405 expectsend = data->state.infilesize;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100406 break;
407 case HTTPREQ_PUT:
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700408 if(data->state.infilesize != -1)
409 expectsend = data->state.infilesize;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100410 break;
411 case HTTPREQ_POST_FORM:
Alex Deymo486467e2017-12-19 19:04:07 +0100412 case HTTPREQ_POST_MIME:
Kristian Monsen5ab50182010-05-14 18:53:44 +0100413 expectsend = http->postsize;
414 break;
415 default:
416 break;
417 }
418 }
419
420 conn->bits.rewindaftersend = FALSE; /* default */
421
422 if((expectsend == -1) || (expectsend > bytessent)) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700423#if defined(USE_NTLM)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100424 /* There is still data left to send */
425 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700426 (data->state.authhost.picked == CURLAUTH_NTLM) ||
427 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
428 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100429 if(((expectsend - bytessent) < 2000) ||
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700430 (conn->ntlm.state != NTLMSTATE_NONE) ||
431 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100432 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
433 data left to send, keep on sending. */
434
435 /* rewind data when completely done sending! */
Elliott Hughes1ef06ba2018-05-30 15:43:58 -0700436 if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100437 conn->bits.rewindaftersend = TRUE;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700438 infof(data, "Rewind stream after send\n");
439 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100440
441 return CURLE_OK;
442 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700443
Kristian Monsen5ab50182010-05-14 18:53:44 +0100444 if(conn->bits.close)
445 /* this is already marked to get closed */
446 return CURLE_OK;
447
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700448 infof(data, "NTLM send, close instead of sending %"
449 CURL_FORMAT_CURL_OFF_T " bytes\n",
450 (curl_off_t)(expectsend - bytessent));
Kristian Monsen5ab50182010-05-14 18:53:44 +0100451 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700452#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +0100453
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700454 /* This is not NTLM or many bytes left to send: close */
Elliott Hughescee03382017-06-23 12:17:18 -0700455 streamclose(conn, "Mid-auth HTTP and much data left to send");
Kristian Monsen5ab50182010-05-14 18:53:44 +0100456 data->req.size = 0; /* don't download any more than 0 bytes */
457
458 /* There still is data left to send, but this connection is marked for
459 closure so we can safely do the rewind right now */
460 }
461
462 if(bytessent)
463 /* we rewind now at once since if we already sent something */
464 return Curl_readrewind(conn);
465
466 return CURLE_OK;
467}
468
469/*
470 * Curl_http_auth_act() gets called when all HTTP headers have been received
471 * and it checks what authentication methods that are available and decides
472 * which one (if any) to use. It will set 'newurl' if an auth method was
473 * picked.
474 */
475
476CURLcode Curl_http_auth_act(struct connectdata *conn)
477{
Alex Deymoe3149cc2016-10-05 11:18:42 -0700478 struct Curl_easy *data = conn->data;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100479 bool pickhost = FALSE;
480 bool pickproxy = FALSE;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700481 CURLcode result = CURLE_OK;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100482
483 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
484 /* this is a transient response code, ignore */
485 return CURLE_OK;
486
487 if(data->state.authproblem)
488 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
489
490 if(conn->bits.user_passwd &&
491 ((data->req.httpcode == 401) ||
492 (conn->bits.authneg && data->req.httpcode < 300))) {
493 pickhost = pickoneauth(&data->state.authhost);
494 if(!pickhost)
495 data->state.authproblem = TRUE;
496 }
497 if(conn->bits.proxy_user_passwd &&
498 ((data->req.httpcode == 407) ||
499 (conn->bits.authneg && data->req.httpcode < 300))) {
500 pickproxy = pickoneauth(&data->state.authproxy);
501 if(!pickproxy)
502 data->state.authproblem = TRUE;
503 }
504
505 if(pickhost || pickproxy) {
506 /* In case this is GSS auth, the newurl field is already allocated so
507 we must make sure to free it before allocating a new one. As figured
508 out in bug #2284386 */
509 Curl_safefree(data->req.newurl);
510 data->req.newurl = strdup(data->change.url); /* clone URL */
511 if(!data->req.newurl)
512 return CURLE_OUT_OF_MEMORY;
513
514 if((data->set.httpreq != HTTPREQ_GET) &&
515 (data->set.httpreq != HTTPREQ_HEAD) &&
516 !conn->bits.rewindaftersend) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700517 result = http_perhapsrewind(conn);
518 if(result)
519 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100520 }
521 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100522 else if((data->req.httpcode < 300) &&
523 (!data->state.authhost.done) &&
524 conn->bits.authneg) {
525 /* no (known) authentication available,
526 authentication is not "done" yet and
527 no authentication seems to be required and
528 we didn't try HEAD or GET */
529 if((data->set.httpreq != HTTPREQ_GET) &&
530 (data->set.httpreq != HTTPREQ_HEAD)) {
531 data->req.newurl = strdup(data->change.url); /* clone URL */
532 if(!data->req.newurl)
533 return CURLE_OUT_OF_MEMORY;
534 data->state.authhost.done = TRUE;
535 }
536 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700537 if(http_should_fail(conn)) {
Elliott Hughes82be86d2017-09-20 17:00:17 -0700538 failf(data, "The requested URL returned error: %d",
539 data->req.httpcode);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700540 result = CURLE_HTTP_RETURNED_ERROR;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100541 }
542
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700543 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100544}
545
Kristian Monsen5ab50182010-05-14 18:53:44 +0100546/*
547 * Output the correct authentication header depending on the auth type
548 * and whether or not it is to a proxy.
549 */
550static CURLcode
551output_auth_headers(struct connectdata *conn,
552 struct auth *authstatus,
553 const char *request,
554 const char *path,
555 bool proxy)
556{
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700557 const char *auth = NULL;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100558 CURLcode result = CURLE_OK;
Alex Deymod15eaac2016-06-28 14:49:26 -0700559#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
Alex Deymoe3149cc2016-10-05 11:18:42 -0700560 struct Curl_easy *data = conn->data;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700561#endif
562#ifdef USE_SPNEGO
Alex Deymod15eaac2016-06-28 14:49:26 -0700563 struct negotiatedata *negdata = proxy ?
564 &data->state.proxyneg : &data->state.negotiate;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100565#endif
566
567#ifdef CURL_DISABLE_CRYPTO_AUTH
568 (void)request;
569 (void)path;
570#endif
571
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700572#ifdef USE_SPNEGO
573 negdata->state = GSS_AUTHNONE;
574 if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
Kristian Monsen5ab50182010-05-14 18:53:44 +0100575 negdata->context && !GSS_ERROR(negdata->status)) {
Alex Deymod15eaac2016-06-28 14:49:26 -0700576 auth = "Negotiate";
Kristian Monsen5ab50182010-05-14 18:53:44 +0100577 result = Curl_output_negotiate(conn, proxy);
578 if(result)
579 return result;
580 authstatus->done = TRUE;
581 negdata->state = GSS_AUTHSENT;
582 }
583 else
584#endif
585#ifdef USE_NTLM
586 if(authstatus->picked == CURLAUTH_NTLM) {
Alex Deymod15eaac2016-06-28 14:49:26 -0700587 auth = "NTLM";
Kristian Monsen5ab50182010-05-14 18:53:44 +0100588 result = Curl_output_ntlm(conn, proxy);
589 if(result)
590 return result;
591 }
592 else
593#endif
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700594#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
595 if(authstatus->picked == CURLAUTH_NTLM_WB) {
Alex Deymo486467e2017-12-19 19:04:07 +0100596 auth = "NTLM_WB";
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700597 result = Curl_output_ntlm_wb(conn, proxy);
598 if(result)
599 return result;
600 }
601 else
602#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +0100603#ifndef CURL_DISABLE_CRYPTO_AUTH
604 if(authstatus->picked == CURLAUTH_DIGEST) {
Alex Deymod15eaac2016-06-28 14:49:26 -0700605 auth = "Digest";
Kristian Monsen5ab50182010-05-14 18:53:44 +0100606 result = Curl_output_digest(conn,
607 proxy,
608 (const unsigned char *)request,
609 (const unsigned char *)path);
610 if(result)
611 return result;
612 }
613 else
614#endif
615 if(authstatus->picked == CURLAUTH_BASIC) {
616 /* Basic */
617 if((proxy && conn->bits.proxy_user_passwd &&
Elliott Hughescac39802018-04-27 16:19:43 -0700618 !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
Kristian Monsen5ab50182010-05-14 18:53:44 +0100619 (!proxy && conn->bits.user_passwd &&
Elliott Hughescac39802018-04-27 16:19:43 -0700620 !Curl_checkheaders(conn, "Authorization"))) {
Alex Deymod15eaac2016-06-28 14:49:26 -0700621 auth = "Basic";
Kristian Monsen5ab50182010-05-14 18:53:44 +0100622 result = http_output_basic(conn, proxy);
623 if(result)
624 return result;
625 }
Alex Deymod15eaac2016-06-28 14:49:26 -0700626
Kristian Monsen5ab50182010-05-14 18:53:44 +0100627 /* NOTE: this function should set 'done' TRUE, as the other auth
628 functions work that way */
629 authstatus->done = TRUE;
630 }
631
632 if(auth) {
633 infof(data, "%s auth using %s with user '%s'\n",
Alex Deymod15eaac2016-06-28 14:49:26 -0700634 proxy ? "Proxy" : "Server", auth,
Elliott Hughescee03382017-06-23 12:17:18 -0700635 proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
Alex Deymod15eaac2016-06-28 14:49:26 -0700636 (conn->user ? conn->user : ""));
Elliott Hughes82be86d2017-09-20 17:00:17 -0700637 authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100638 }
639 else
Elliott Hughes82be86d2017-09-20 17:00:17 -0700640 authstatus->multipass = FALSE;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100641
642 return CURLE_OK;
643}
644
645/**
646 * Curl_http_output_auth() setups the authentication headers for the
647 * host/proxy and the correct authentication
648 * method. conn->data->state.authdone is set to TRUE when authentication is
649 * done.
650 *
651 * @param conn all information about the current connection
652 * @param request pointer to the request keyword
653 * @param path pointer to the requested path
654 * @param proxytunnel boolean if this is the request setting up a "proxy
655 * tunnel"
656 *
657 * @returns CURLcode
658 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700659CURLcode
660Curl_http_output_auth(struct connectdata *conn,
661 const char *request,
662 const char *path,
663 bool proxytunnel) /* TRUE if this is the request setting
664 up the proxy tunnel */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100665{
666 CURLcode result = CURLE_OK;
Alex Deymoe3149cc2016-10-05 11:18:42 -0700667 struct Curl_easy *data = conn->data;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100668 struct auth *authhost;
669 struct auth *authproxy;
670
671 DEBUGASSERT(data);
672
673 authhost = &data->state.authhost;
674 authproxy = &data->state.authproxy;
675
676 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
677 conn->bits.user_passwd)
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700678 /* continue please */;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100679 else {
680 authhost->done = TRUE;
681 authproxy->done = TRUE;
682 return CURLE_OK; /* no authentication with no user or password */
683 }
684
685 if(authhost->want && !authhost->picked)
686 /* The app has selected one or more methods, but none has been picked
687 so far by a server round-trip. Then we set the picked one to the
688 want one, and if this is one single bit it'll be used instantly. */
689 authhost->picked = authhost->want;
690
691 if(authproxy->want && !authproxy->picked)
692 /* The app has selected one or more methods, but none has been picked so
693 far by a proxy round-trip. Then we set the picked one to the want one,
694 and if this is one single bit it'll be used instantly. */
695 authproxy->picked = authproxy->want;
696
697#ifndef CURL_DISABLE_PROXY
698 /* Send proxy authentication header if needed */
699 if(conn->bits.httpproxy &&
700 (conn->bits.tunnel_proxy == proxytunnel)) {
701 result = output_auth_headers(conn, authproxy, request, path, TRUE);
702 if(result)
703 return result;
704 }
705 else
706#else
707 (void)proxytunnel;
708#endif /* CURL_DISABLE_PROXY */
709 /* we have no proxy so let's pretend we're done authenticating
710 with it */
711 authproxy->done = TRUE;
712
713 /* To prevent the user+password to get sent to other than the original
714 host due to a location-follow, we do some weirdo checks here */
715 if(!data->state.this_is_a_follow ||
716 conn->bits.netrc ||
717 !data->state.first_host ||
Elliott Hughes0128fe42018-02-27 14:57:55 -0800718 data->set.allow_auth_to_other_hosts ||
Elliott Hughescee03382017-06-23 12:17:18 -0700719 strcasecompare(data->state.first_host, conn->host.name)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100720 result = output_auth_headers(conn, authhost, request, path, FALSE);
721 }
722 else
723 authhost->done = TRUE;
724
725 return result;
726}
727
Kristian Monsen5ab50182010-05-14 18:53:44 +0100728/*
729 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
730 * headers. They are dealt with both in the transfer.c main loop and in the
731 * proxy CONNECT loop.
732 */
733
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700734CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
735 const char *auth) /* the first non-space */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100736{
737 /*
738 * This resource requires authentication
739 */
Alex Deymoe3149cc2016-10-05 11:18:42 -0700740 struct Curl_easy *data = conn->data;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100741
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700742#ifdef USE_SPNEGO
743 struct negotiatedata *negdata = proxy?
744 &data->state.proxyneg:&data->state.negotiate;
745#endif
746 unsigned long *availp;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100747 struct auth *authp;
748
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700749 if(proxy) {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100750 availp = &data->info.proxyauthavail;
751 authp = &data->state.authproxy;
752 }
753 else {
Kristian Monsen5ab50182010-05-14 18:53:44 +0100754 availp = &data->info.httpauthavail;
755 authp = &data->state.authhost;
756 }
757
Kristian Monsen5ab50182010-05-14 18:53:44 +0100758 /*
759 * Here we check if we want the specific single authentication (using ==) and
760 * if we do, we initiate usage of it.
761 *
762 * If the provided authentication is wanted as one out of several accepted
763 * types (using &), we OR this authentication type to the authavail
764 * variable.
765 *
766 * Note:
767 *
768 * ->picked is first set to the 'want' value (one or more bits) before the
769 * request is sent, and then it is again set _after_ all response 401/407
770 * headers have been received but then only to a single preferred method
771 * (bit).
Kristian Monsen5ab50182010-05-14 18:53:44 +0100772 */
773
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700774 while(*auth) {
775#ifdef USE_SPNEGO
776 if(checkprefix("Negotiate", auth)) {
Elliott Hughescee03382017-06-23 12:17:18 -0700777 if((authp->avail & CURLAUTH_NEGOTIATE) ||
778 Curl_auth_is_spnego_supported()) {
779 *availp |= CURLAUTH_NEGOTIATE;
780 authp->avail |= CURLAUTH_NEGOTIATE;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100781
Elliott Hughescee03382017-06-23 12:17:18 -0700782 if(authp->picked == CURLAUTH_NEGOTIATE) {
783 if(negdata->state == GSS_AUTHSENT ||
784 negdata->state == GSS_AUTHNONE) {
785 CURLcode result = Curl_input_negotiate(conn, proxy, auth);
786 if(!result) {
787 DEBUGASSERT(!data->req.newurl);
788 data->req.newurl = strdup(data->change.url);
789 if(!data->req.newurl)
790 return CURLE_OUT_OF_MEMORY;
791 data->state.authproblem = FALSE;
792 /* we received a GSS auth token and we dealt with it fine */
793 negdata->state = GSS_AUTHRECV;
794 }
795 else
796 data->state.authproblem = TRUE;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700797 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100798 }
799 }
800 }
801 else
802#endif
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700803#ifdef USE_NTLM
804 /* NTLM support requires the SSL crypto libs */
805 if(checkprefix("NTLM", auth)) {
Elliott Hughescee03382017-06-23 12:17:18 -0700806 if((authp->avail & CURLAUTH_NTLM) ||
807 (authp->avail & CURLAUTH_NTLM_WB) ||
808 Curl_auth_is_ntlm_supported()) {
809 *availp |= CURLAUTH_NTLM;
810 authp->avail |= CURLAUTH_NTLM;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100811
Elliott Hughescee03382017-06-23 12:17:18 -0700812 if(authp->picked == CURLAUTH_NTLM ||
813 authp->picked == CURLAUTH_NTLM_WB) {
814 /* NTLM authentication is picked and activated */
815 CURLcode result = Curl_input_ntlm(conn, proxy, auth);
816 if(!result) {
817 data->state.authproblem = FALSE;
818#ifdef NTLM_WB_ENABLED
819 if(authp->picked == CURLAUTH_NTLM_WB) {
820 *availp &= ~CURLAUTH_NTLM;
821 authp->avail &= ~CURLAUTH_NTLM;
822 *availp |= CURLAUTH_NTLM_WB;
823 authp->avail |= CURLAUTH_NTLM_WB;
824
825 /* Get the challenge-message which will be passed to
826 * ntlm_auth for generating the type 3 message later */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700827 while(*auth && ISSPACE(*auth))
828 auth++;
Elliott Hughescee03382017-06-23 12:17:18 -0700829 if(checkprefix("NTLM", auth)) {
830 auth += strlen("NTLM");
831 while(*auth && ISSPACE(*auth))
832 auth++;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700833 if(*auth) {
834 conn->challenge_header = strdup(auth);
835 if(!conn->challenge_header)
Elliott Hughescee03382017-06-23 12:17:18 -0700836 return CURLE_OUT_OF_MEMORY;
Elliott Hughes82be86d2017-09-20 17:00:17 -0700837 }
Elliott Hughescee03382017-06-23 12:17:18 -0700838 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700839 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700840#endif
Elliott Hughescee03382017-06-23 12:17:18 -0700841 }
842 else {
843 infof(data, "Authentication problem. Ignoring this.\n");
844 data->state.authproblem = TRUE;
845 }
Kristian Monsen5ab50182010-05-14 18:53:44 +0100846 }
847 }
848 }
849 else
850#endif
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700851#ifndef CURL_DISABLE_CRYPTO_AUTH
852 if(checkprefix("Digest", auth)) {
Elliott Hughescee03382017-06-23 12:17:18 -0700853 if((authp->avail & CURLAUTH_DIGEST) != 0)
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700854 infof(data, "Ignoring duplicate digest auth header.\n");
Elliott Hughescee03382017-06-23 12:17:18 -0700855 else if(Curl_auth_is_digest_supported()) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700856 CURLcode result;
Elliott Hughescee03382017-06-23 12:17:18 -0700857
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700858 *availp |= CURLAUTH_DIGEST;
859 authp->avail |= CURLAUTH_DIGEST;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100860
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700861 /* We call this function on input Digest headers even if Digest
862 * authentication isn't activated yet, as we need to store the
Elliott Hughescee03382017-06-23 12:17:18 -0700863 * incoming data from this header in case we are going to use
864 * Digest */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700865 result = Curl_input_digest(conn, proxy, auth);
866 if(result) {
867 infof(data, "Authentication problem. Ignoring this.\n");
868 data->state.authproblem = TRUE;
869 }
870 }
871 }
872 else
873#endif
874 if(checkprefix("Basic", auth)) {
875 *availp |= CURLAUTH_BASIC;
876 authp->avail |= CURLAUTH_BASIC;
877 if(authp->picked == CURLAUTH_BASIC) {
878 /* We asked for Basic authentication but got a 40X back
879 anyway, which basically means our name+password isn't
880 valid. */
881 authp->avail = CURLAUTH_NONE;
882 infof(data, "Authentication problem. Ignoring this.\n");
883 data->state.authproblem = TRUE;
884 }
885 }
886
887 /* there may be multiple methods on one line, so keep reading */
888 while(*auth && *auth != ',') /* read up to the next comma */
889 auth++;
890 if(*auth == ',') /* if we're on a comma, skip it */
891 auth++;
892 while(*auth && ISSPACE(*auth))
893 auth++;
894 }
Alex Deymod15eaac2016-06-28 14:49:26 -0700895
Kristian Monsen5ab50182010-05-14 18:53:44 +0100896 return CURLE_OK;
897}
898
899/**
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700900 * http_should_fail() determines whether an HTTP response has gotten us
Kristian Monsen5ab50182010-05-14 18:53:44 +0100901 * into an error state or not.
902 *
903 * @param conn all information about the current connection
904 *
905 * @retval 0 communications should continue
906 *
907 * @retval 1 communications should not continue
908 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700909static int http_should_fail(struct connectdata *conn)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100910{
Alex Deymoe3149cc2016-10-05 11:18:42 -0700911 struct Curl_easy *data;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100912 int httpcode;
913
914 DEBUGASSERT(conn);
915 data = conn->data;
916 DEBUGASSERT(data);
917
918 httpcode = data->req.httpcode;
919
920 /*
921 ** If we haven't been asked to fail on error,
922 ** don't fail.
923 */
924 if(!data->set.http_fail_on_error)
925 return 0;
926
927 /*
928 ** Any code < 400 is never terminal.
929 */
930 if(httpcode < 400)
931 return 0;
932
Kristian Monsen5ab50182010-05-14 18:53:44 +0100933 /*
934 ** Any code >= 400 that's not 401 or 407 is always
935 ** a terminal error
936 */
Alex Deymod15eaac2016-06-28 14:49:26 -0700937 if((httpcode != 401) && (httpcode != 407))
Kristian Monsen5ab50182010-05-14 18:53:44 +0100938 return 1;
939
940 /*
941 ** All we have left to deal with is 401 and 407
942 */
943 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
944
945 /*
946 ** Examine the current authentication state to see if this
947 ** is an error. The idea is for this function to get
948 ** called after processing all the headers in a response
949 ** message. So, if we've been to asked to authenticate a
950 ** particular stage, and we've done it, we're OK. But, if
951 ** we're already completely authenticated, it's not OK to
952 ** get another 401 or 407.
953 **
954 ** It is possible for authentication to go stale such that
955 ** the client needs to reauthenticate. Once that info is
956 ** available, use it here.
957 */
Kristian Monsen5ab50182010-05-14 18:53:44 +0100958
959 /*
960 ** Either we're not authenticating, or we're supposed to
961 ** be authenticating something else. This is an error.
962 */
963 if((httpcode == 401) && !conn->bits.user_passwd)
964 return TRUE;
965 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
966 return TRUE;
967
968 return data->state.authproblem;
969}
970
971/*
972 * readmoredata() is a "fread() emulation" to provide POST and/or request
973 * data. It is used when a huge POST is to be made and the entire chunk wasn't
974 * sent in the first send(). This function will then be called from the
975 * transfer.c loop when more data is to be sent to the peer.
976 *
977 * Returns the amount of bytes it filled the buffer with.
978 */
979static size_t readmoredata(char *buffer,
980 size_t size,
981 size_t nitems,
982 void *userp)
983{
984 struct connectdata *conn = (struct connectdata *)userp;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700985 struct HTTP *http = conn->data->req.protop;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100986 size_t fullsize = size * nitems;
987
Alex Deymod15eaac2016-06-28 14:49:26 -0700988 if(!http->postsize)
Kristian Monsen5ab50182010-05-14 18:53:44 +0100989 /* nothing to return */
990 return 0;
991
992 /* make sure that a HTTP request is never sent away chunked! */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -0700993 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
Kristian Monsen5ab50182010-05-14 18:53:44 +0100994
995 if(http->postsize <= (curl_off_t)fullsize) {
996 memcpy(buffer, http->postdata, (size_t)http->postsize);
997 fullsize = (size_t)http->postsize;
998
999 if(http->backup.postsize) {
1000 /* move backup data into focus and continue on that */
1001 http->postdata = http->backup.postdata;
1002 http->postsize = http->backup.postsize;
Alex Deymod15eaac2016-06-28 14:49:26 -07001003 conn->data->state.fread_func = http->backup.fread_func;
1004 conn->data->state.in = http->backup.fread_in;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001005
1006 http->sending++; /* move one step up */
1007
Alex Deymo486467e2017-12-19 19:04:07 +01001008 http->backup.postsize = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001009 }
1010 else
1011 http->postsize = 0;
1012
1013 return fullsize;
1014 }
1015
1016 memcpy(buffer, http->postdata, fullsize);
1017 http->postdata += fullsize;
1018 http->postsize -= fullsize;
1019
1020 return fullsize;
1021}
1022
1023/* ------------------------------------------------------------------------- */
1024/* add_buffer functions */
1025
1026/*
1027 * Curl_add_buffer_init() sets up and returns a fine buffer struct
1028 */
1029Curl_send_buffer *Curl_add_buffer_init(void)
1030{
1031 return calloc(1, sizeof(Curl_send_buffer));
1032}
1033
1034/*
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001035 * Curl_add_buffer_free() frees all associated resources.
1036 */
1037void Curl_add_buffer_free(Curl_send_buffer *buff)
1038{
1039 if(buff) /* deal with NULL input */
1040 free(buff->buffer);
1041 free(buff);
1042}
1043
1044/*
Kristian Monsen5ab50182010-05-14 18:53:44 +01001045 * Curl_add_buffer_send() sends a header buffer and frees all associated
1046 * memory. Body data may be appended to the header data if desired.
1047 *
1048 * Returns CURLcode
1049 */
1050CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
Lucas Eckels9bd90e62012-08-06 15:07:02 -07001051 struct connectdata *conn,
1052
1053 /* add the number of sent bytes to this
1054 counter */
1055 long *bytes_written,
1056
1057 /* how much of the buffer contains body data */
1058 size_t included_body_bytes,
1059 int socketindex)
Kristian Monsen5ab50182010-05-14 18:53:44 +01001060
1061{
1062 ssize_t amount;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001063 CURLcode result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001064 char *ptr;
1065 size_t size;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001066 struct HTTP *http = conn->data->req.protop;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001067 size_t sendsize;
1068 curl_socket_t sockfd;
1069 size_t headersize;
1070
1071 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1072
1073 sockfd = conn->sock[socketindex];
1074
1075 /* The looping below is required since we use non-blocking sockets, but due
1076 to the circumstances we will just loop and try again and again etc */
1077
1078 ptr = in->buffer;
1079 size = in->size_used;
1080
1081 headersize = size - included_body_bytes; /* the initial part that isn't body
1082 is header */
1083
1084 DEBUGASSERT(size > included_body_bytes);
1085
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001086 result = Curl_convert_to_network(conn->data, ptr, headersize);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001087 /* Curl_convert_to_network calls failf if unsuccessful */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001088 if(result) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001089 /* conversion failed, free memory and return to the caller */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001090 Curl_add_buffer_free(in);
1091 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001092 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001093
Elliott Hughescee03382017-06-23 12:17:18 -07001094 if((conn->handler->flags & PROTOPT_SSL ||
1095 conn->http_proxy.proxytype == CURLPROXY_HTTPS)
1096 && conn->httpversion != 20) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001097 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1098 when we speak HTTPS, as if only a fraction of it is sent now, this data
1099 needs to fit into the normal read-callback buffer later on and that
1100 buffer is using this size.
1101 */
1102
Elliott Hughes82be86d2017-09-20 17:00:17 -07001103 sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001104
1105 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1106 library when we attempt to re-send this buffer. Sending the same data
1107 is not enough, we must use the exact same address. For this reason, we
1108 must copy the data to the uploadbuffer first, since that is the buffer
1109 we will be using if this send is retried later.
1110 */
1111 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1112 ptr = conn->data->state.uploadbuffer;
1113 }
1114 else
1115 sendsize = size;
1116
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001117 result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001118
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001119 if(!result) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001120 /*
1121 * Note that we may not send the entire chunk at once, and we have a set
1122 * number of data bytes at the end of the big buffer (out of which we may
1123 * only send away a part).
1124 */
1125 /* how much of the header that was sent */
Alex Deymod15eaac2016-06-28 14:49:26 -07001126 size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001127 size_t bodylen = amount - headlen;
1128
1129 if(conn->data->set.verbose) {
1130 /* this data _may_ contain binary stuff */
1131 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001132 if(bodylen) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001133 /* there was body data sent beyond the initial header part, pass that
1134 on to the debug callback too */
1135 Curl_debug(conn->data, CURLINFO_DATA_OUT,
Alex Deymo486467e2017-12-19 19:04:07 +01001136 ptr + headlen, bodylen, conn);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001137 }
1138 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001139
Lucas Eckels9bd90e62012-08-06 15:07:02 -07001140 /* 'amount' can never be a very large value here so typecasting it so a
1141 signed 31 bit value should not cause problems even if ssize_t is
1142 64bit */
1143 *bytes_written += (long)amount;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001144
1145 if(http) {
Alex Deymod15eaac2016-06-28 14:49:26 -07001146 /* if we sent a piece of the body here, up the byte counter for it
1147 accordingly */
1148 http->writebytecount += bodylen;
1149
Kristian Monsen5ab50182010-05-14 18:53:44 +01001150 if((size_t)amount != size) {
1151 /* The whole request could not be sent in one system call. We must
1152 queue it up and send it later when we get the chance. We must not
1153 loop here and wait until it might work again. */
1154
1155 size -= amount;
1156
1157 ptr = in->buffer + amount;
1158
1159 /* backup the currently set pointers */
Alex Deymod15eaac2016-06-28 14:49:26 -07001160 http->backup.fread_func = conn->data->state.fread_func;
1161 http->backup.fread_in = conn->data->state.in;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001162 http->backup.postdata = http->postdata;
1163 http->backup.postsize = http->postsize;
1164
1165 /* set the new pointers for the request-sending */
Alex Deymod15eaac2016-06-28 14:49:26 -07001166 conn->data->state.fread_func = (curl_read_callback)readmoredata;
1167 conn->data->state.in = (void *)conn;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001168 http->postdata = ptr;
1169 http->postsize = (curl_off_t)size;
1170
1171 http->send_buffer = in;
1172 http->sending = HTTPSEND_REQUEST;
1173
1174 return CURLE_OK;
1175 }
1176 http->sending = HTTPSEND_BODY;
1177 /* the full buffer was sent, clean up and return */
1178 }
1179 else {
1180 if((size_t)amount != size)
1181 /* We have no continue-send mechanism now, fail. This can only happen
1182 when this function is used from the CONNECT sending function. We
1183 currently (stupidly) assume that the whole request is always sent
1184 away in the first single chunk.
1185
1186 This needs FIXing.
1187 */
1188 return CURLE_SEND_ERROR;
Elliott Hughes82be86d2017-09-20 17:00:17 -07001189 Curl_pipeline_leave_write(conn);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001190 }
1191 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001192 Curl_add_buffer_free(in);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001193
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001194 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001195}
1196
1197
1198/*
1199 * add_bufferf() add the formatted input to the buffer.
1200 */
1201CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1202{
1203 char *s;
1204 va_list ap;
1205 va_start(ap, fmt);
1206 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1207 va_end(ap);
1208
1209 if(s) {
1210 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1211 free(s);
1212 return result;
1213 }
1214 /* If we failed, we cleanup the whole buffer and return error */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001215 free(in->buffer);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001216 free(in);
1217 return CURLE_OUT_OF_MEMORY;
1218}
1219
1220/*
1221 * add_buffer() appends a memory chunk to the existing buffer
1222 */
1223CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1224{
1225 char *new_rb;
1226 size_t new_size;
1227
1228 if(~size < in->size_used) {
1229 /* If resulting used size of send buffer would wrap size_t, cleanup
1230 the whole buffer and return error. Otherwise the required buffer
1231 size will fit into a single allocatable memory chunk */
1232 Curl_safefree(in->buffer);
1233 free(in);
1234 return CURLE_OUT_OF_MEMORY;
1235 }
1236
1237 if(!in->buffer ||
1238 ((in->size_used + size) > (in->size_max - 1))) {
1239
1240 /* If current buffer size isn't enough to hold the result, use a
1241 buffer size that doubles the required size. If this new size
1242 would wrap size_t, then just use the largest possible one */
1243
Alex Deymod15eaac2016-06-28 14:49:26 -07001244 if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
1245 (~(size * 2) < (in->size_used * 2)))
Kristian Monsen5ab50182010-05-14 18:53:44 +01001246 new_size = (size_t)-1;
1247 else
Alex Deymo486467e2017-12-19 19:04:07 +01001248 new_size = (in->size_used + size) * 2;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001249
1250 if(in->buffer)
1251 /* we have a buffer, enlarge the existing one */
Elliott Hughescee03382017-06-23 12:17:18 -07001252 new_rb = Curl_saferealloc(in->buffer, new_size);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001253 else
1254 /* create a new buffer */
1255 new_rb = malloc(new_size);
1256
1257 if(!new_rb) {
1258 /* If we failed, we cleanup the whole buffer and return error */
Kristian Monsen5ab50182010-05-14 18:53:44 +01001259 free(in);
1260 return CURLE_OUT_OF_MEMORY;
1261 }
1262
1263 in->buffer = new_rb;
1264 in->size_max = new_size;
1265 }
1266 memcpy(&in->buffer[in->size_used], inptr, size);
1267
1268 in->size_used += size;
1269
1270 return CURLE_OK;
1271}
1272
1273/* end of the add_buffer functions */
1274/* ------------------------------------------------------------------------- */
1275
1276
1277
1278/*
1279 * Curl_compareheader()
1280 *
1281 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1282 * Pass headers WITH the colon.
1283 */
1284bool
1285Curl_compareheader(const char *headerline, /* line to check */
1286 const char *header, /* header keyword _with_ colon */
1287 const char *content) /* content string to find */
1288{
1289 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1290 * by a colon (":") and the field value. Field names are case-insensitive.
1291 * The field value MAY be preceded by any amount of LWS, though a single SP
1292 * is preferred." */
1293
1294 size_t hlen = strlen(header);
1295 size_t clen;
1296 size_t len;
1297 const char *start;
1298 const char *end;
1299
Elliott Hughescee03382017-06-23 12:17:18 -07001300 if(!strncasecompare(headerline, header, hlen))
Kristian Monsen5ab50182010-05-14 18:53:44 +01001301 return FALSE; /* doesn't start with header */
1302
1303 /* pass the header */
1304 start = &headerline[hlen];
1305
1306 /* pass all white spaces */
1307 while(*start && ISSPACE(*start))
1308 start++;
1309
1310 /* find the end of the header line */
1311 end = strchr(start, '\r'); /* lines end with CRLF */
1312 if(!end) {
1313 /* in case there's a non-standard compliant line here */
1314 end = strchr(start, '\n');
1315
1316 if(!end)
1317 /* hm, there's no line ending here, use the zero byte! */
1318 end = strchr(start, '\0');
1319 }
1320
1321 len = end-start; /* length of the content part of the input line */
1322 clen = strlen(content); /* length of the word to find */
1323
1324 /* find the content string in the rest of the line */
Alex Deymo486467e2017-12-19 19:04:07 +01001325 for(; len >= clen; len--, start++) {
Elliott Hughescee03382017-06-23 12:17:18 -07001326 if(strncasecompare(start, content, clen))
Kristian Monsen5ab50182010-05-14 18:53:44 +01001327 return TRUE; /* match! */
1328 }
1329
1330 return FALSE; /* no match */
1331}
1332
Kristian Monsen5ab50182010-05-14 18:53:44 +01001333/*
1334 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1335 * the generic Curl_connect().
1336 */
1337CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1338{
Kristian Monsen5ab50182010-05-14 18:53:44 +01001339 CURLcode result;
1340
Kristian Monsen5ab50182010-05-14 18:53:44 +01001341 /* We default to persistent connections. We set this already in this connect
1342 function to make the re-use checks properly be able to check this bit. */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001343 connkeep(conn, "HTTP default");
Kristian Monsen5ab50182010-05-14 18:53:44 +01001344
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001345 /* the CONNECT procedure might not have been completed */
Elliott Hughescee03382017-06-23 12:17:18 -07001346 result = Curl_proxy_connect(conn, FIRSTSOCKET);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001347 if(result)
1348 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001349
Elliott Hughes82be86d2017-09-20 17:00:17 -07001350 if(conn->bits.proxy_connect_closed)
1351 /* this is not an error, just part of the connection negotiation */
1352 return CURLE_OK;
1353
Elliott Hughescee03382017-06-23 12:17:18 -07001354 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
1355 return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
1356
Alex Deymo486467e2017-12-19 19:04:07 +01001357 if(Curl_connect_ongoing(conn))
Kristian Monsen5ab50182010-05-14 18:53:44 +01001358 /* nothing else to do except wait right now - we're not done here. */
1359 return CURLE_OK;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001360
Elliott Hughes1ef06ba2018-05-30 15:43:58 -07001361 if(conn->data->set.haproxyprotocol) {
1362 /* add HAProxy PROXY protocol header */
1363 result = add_haproxy_protocol_header(conn);
1364 if(result)
1365 return result;
1366 }
1367
Elliott Hughes82be86d2017-09-20 17:00:17 -07001368 if(conn->given->protocol & CURLPROTO_HTTPS) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001369 /* perform SSL initialization */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001370 result = https_connecting(conn, done);
1371 if(result)
1372 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001373 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001374 else
Kristian Monsen5ab50182010-05-14 18:53:44 +01001375 *done = TRUE;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001376
1377 return CURLE_OK;
1378}
1379
1380/* this returns the socket to wait for in the DO and DOING state for the multi
1381 interface and then we're always _sending_ a request and thus we wait for
1382 the single socket to become writable only */
1383static int http_getsock_do(struct connectdata *conn,
1384 curl_socket_t *socks,
1385 int numsocks)
1386{
1387 /* write mode */
1388 (void)numsocks; /* unused, we trust it to be at least 1 */
1389 socks[0] = conn->sock[FIRSTSOCKET];
1390 return GETSOCK_WRITESOCK(0);
1391}
1392
Elliott Hughes1ef06ba2018-05-30 15:43:58 -07001393static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
1394{
1395 char proxy_header[128];
1396 Curl_send_buffer *req_buffer;
1397 CURLcode result;
1398 char tcp_version[5];
1399
1400 /* Emit the correct prefix for IPv6 */
1401 if(conn->bits.ipv6) {
1402 strcpy(tcp_version, "TCP6");
1403 }
1404 else {
1405 strcpy(tcp_version, "TCP4");
1406 }
1407
1408 snprintf(proxy_header,
1409 sizeof proxy_header,
1410 "PROXY %s %s %s %li %li\r\n",
1411 tcp_version,
1412 conn->data->info.conn_local_ip,
1413 conn->data->info.conn_primary_ip,
1414 conn->data->info.conn_local_port,
1415 conn->data->info.conn_primary_port);
1416
1417 req_buffer = Curl_add_buffer_init();
1418 if(!req_buffer)
1419 return CURLE_OUT_OF_MEMORY;
1420
1421 result = Curl_add_bufferf(req_buffer, proxy_header);
1422 if(result)
1423 return result;
1424
1425 result = Curl_add_buffer_send(req_buffer,
1426 conn,
1427 &conn->data->info.request_size,
1428 0,
1429 FIRSTSOCKET);
1430
1431 return result;
1432}
1433
Kristian Monsen5ab50182010-05-14 18:53:44 +01001434#ifdef USE_SSL
1435static CURLcode https_connecting(struct connectdata *conn, bool *done)
1436{
1437 CURLcode result;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001438 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
Kristian Monsen5ab50182010-05-14 18:53:44 +01001439
1440 /* perform SSL initialization for this socket */
1441 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1442 if(result)
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001443 connclose(conn, "Failed HTTPS connection");
1444
Kristian Monsen5ab50182010-05-14 18:53:44 +01001445 return result;
1446}
Kristian Monsen5ab50182010-05-14 18:53:44 +01001447
Kristian Monsen5ab50182010-05-14 18:53:44 +01001448static int https_getsock(struct connectdata *conn,
1449 curl_socket_t *socks,
1450 int numsocks)
1451{
Elliott Hughescee03382017-06-23 12:17:18 -07001452 if(conn->handler->flags & PROTOPT_SSL)
1453 return Curl_ssl_getsock(conn, socks, numsocks);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001454 return GETSOCK_BLANK;
1455}
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001456#endif /* USE_SSL */
Kristian Monsen5ab50182010-05-14 18:53:44 +01001457
1458/*
Alex Deymod15eaac2016-06-28 14:49:26 -07001459 * Curl_http_done() gets called after a single HTTP request has been
1460 * performed.
Kristian Monsen5ab50182010-05-14 18:53:44 +01001461 */
1462
1463CURLcode Curl_http_done(struct connectdata *conn,
1464 CURLcode status, bool premature)
1465{
Alex Deymoe3149cc2016-10-05 11:18:42 -07001466 struct Curl_easy *data = conn->data;
Alex Deymod15eaac2016-06-28 14:49:26 -07001467 struct HTTP *http = data->req.protop;
Elliott Hughescee03382017-06-23 12:17:18 -07001468
Elliott Hughes82be86d2017-09-20 17:00:17 -07001469 /* Clear multipass flag. If authentication isn't done yet, then it will get
1470 * a chance to be set back to true when we output the next auth header */
1471 data->state.authhost.multipass = FALSE;
1472 data->state.authproxy.multipass = FALSE;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001473
1474 Curl_unencode_cleanup(conn);
1475
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001476#ifdef USE_SPNEGO
1477 if(data->state.proxyneg.state == GSS_AUTHSENT ||
1478 data->state.negotiate.state == GSS_AUTHSENT) {
1479 /* add forbid re-use if http-code != 401/407 as a WA only needed for
1480 * 401/407 that signal auth failure (empty) otherwise state will be RECV
Alex Deymod15eaac2016-06-28 14:49:26 -07001481 * with current code.
1482 * Do not close CONNECT_ONLY connections. */
1483 if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1484 !data->set.connect_only)
Elliott Hughescee03382017-06-23 12:17:18 -07001485 streamclose(conn, "Negotiate transfer completed");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001486 Curl_cleanup_negotiate(data);
1487 }
1488#endif
1489
Kristian Monsen5ab50182010-05-14 18:53:44 +01001490 /* set the proper values (possibly modified on POST) */
Kristian Monsen5ab50182010-05-14 18:53:44 +01001491 conn->seek_func = data->set.seek_func; /* restore */
1492 conn->seek_client = data->set.seek_client; /* restore */
1493
Alex Deymod15eaac2016-06-28 14:49:26 -07001494 if(!http)
Kristian Monsen5ab50182010-05-14 18:53:44 +01001495 return CURLE_OK;
1496
1497 if(http->send_buffer) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001498 Curl_add_buffer_free(http->send_buffer);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001499 http->send_buffer = NULL; /* clear the pointer */
1500 }
1501
Elliott Hughescee03382017-06-23 12:17:18 -07001502 Curl_http2_done(conn, premature);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001503
Alex Deymo486467e2017-12-19 19:04:07 +01001504 Curl_mime_cleanpart(&http->form);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001505
Alex Deymo486467e2017-12-19 19:04:07 +01001506 switch(data->set.httpreq) {
1507 case HTTPREQ_PUT:
1508 case HTTPREQ_POST_FORM:
1509 case HTTPREQ_POST_MIME:
Kristian Monsen5ab50182010-05-14 18:53:44 +01001510 data->req.bytecount = http->readbytecount + http->writebytecount;
Alex Deymo486467e2017-12-19 19:04:07 +01001511 break;
1512 default:
1513 break;
1514 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001515
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001516 if(status)
1517 return status;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001518
1519 if(!premature && /* this check is pointless when DONE is called before the
1520 entire operation is complete */
1521 !conn->bits.retry &&
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001522 !data->set.connect_only &&
Alex Deymod15eaac2016-06-28 14:49:26 -07001523 (http->readbytecount +
1524 data->req.headerbytecount -
1525 data->req.deductheadercount) <= 0) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001526 /* If this connection isn't simply closed to be retried, AND nothing was
1527 read from the HTTP server (that counts), this can't be right so we
1528 return an error here */
1529 failf(data, "Empty reply from server");
1530 return CURLE_GOT_NOTHING;
1531 }
1532
1533 return CURLE_OK;
1534}
1535
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001536/*
1537 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1538 * to avoid it include:
1539 *
1540 * - if the user specifically requested HTTP 1.0
1541 * - if the server we are connected to only supports 1.0
1542 * - if any server previously contacted to handle this request only supports
1543 * 1.0.
1544 */
Alex Deymoe3149cc2016-10-05 11:18:42 -07001545static bool use_http_1_1plus(const struct Curl_easy *data,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001546 const struct connectdata *conn)
Kristian Monsen5ab50182010-05-14 18:53:44 +01001547{
Alex Deymod15eaac2016-06-28 14:49:26 -07001548 if((data->state.httpversion == 10) || (conn->httpversion == 10))
1549 return FALSE;
1550 if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
1551 (conn->httpversion <= 10))
1552 return FALSE;
1553 return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
1554 (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
Kristian Monsen5ab50182010-05-14 18:53:44 +01001555}
1556
Elliott Hughes82be86d2017-09-20 17:00:17 -07001557static const char *get_http_string(const struct Curl_easy *data,
1558 const struct connectdata *conn)
1559{
1560#ifdef USE_NGHTTP2
1561 if(conn->proto.httpc.h2)
1562 return "2";
1563#endif
1564
1565 if(use_http_1_1plus(data, conn))
1566 return "1.1";
1567
1568 return "1.0";
1569}
1570
Kristian Monsen5ab50182010-05-14 18:53:44 +01001571/* check and possibly add an Expect: header */
Alex Deymoe3149cc2016-10-05 11:18:42 -07001572static CURLcode expect100(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +01001573 struct connectdata *conn,
1574 Curl_send_buffer *req_buffer)
1575{
1576 CURLcode result = CURLE_OK;
1577 const char *ptr;
1578 data->state.expect100header = FALSE; /* default to false unless it is set
1579 to TRUE below */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001580 if(use_http_1_1plus(data, conn) &&
1581 (conn->httpversion != 20)) {
1582 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1583 Expect: 100-continue to the headers which actually speeds up post
1584 operations (as there is one packet coming back from the web server) */
Elliott Hughescac39802018-04-27 16:19:43 -07001585 ptr = Curl_checkheaders(conn, "Expect");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001586 if(ptr) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001587 data->state.expect100header =
1588 Curl_compareheader(ptr, "Expect:", "100-continue");
1589 }
1590 else {
1591 result = Curl_add_bufferf(req_buffer,
1592 "Expect: 100-continue\r\n");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001593 if(!result)
Kristian Monsen5ab50182010-05-14 18:53:44 +01001594 data->state.expect100header = TRUE;
1595 }
1596 }
Alex Deymod15eaac2016-06-28 14:49:26 -07001597
Kristian Monsen5ab50182010-05-14 18:53:44 +01001598 return result;
1599}
1600
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001601enum proxy_use {
1602 HEADER_SERVER, /* direct to server */
1603 HEADER_PROXY, /* regular request to proxy */
1604 HEADER_CONNECT /* sending CONNECT to a proxy */
1605};
1606
Kristian Monsen5ab50182010-05-14 18:53:44 +01001607CURLcode Curl_add_custom_headers(struct connectdata *conn,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001608 bool is_connect,
1609 Curl_send_buffer *req_buffer)
Kristian Monsen5ab50182010-05-14 18:53:44 +01001610{
1611 char *ptr;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001612 struct curl_slist *h[2];
1613 struct curl_slist *headers;
Alex Deymo486467e2017-12-19 19:04:07 +01001614 int numlists = 1; /* by default */
Alex Deymoe3149cc2016-10-05 11:18:42 -07001615 struct Curl_easy *data = conn->data;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001616 int i;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001617
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001618 enum proxy_use proxy;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001619
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001620 if(is_connect)
1621 proxy = HEADER_CONNECT;
1622 else
1623 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1624 HEADER_PROXY:HEADER_SERVER;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001625
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001626 switch(proxy) {
1627 case HEADER_SERVER:
1628 h[0] = data->set.headers;
1629 break;
1630 case HEADER_PROXY:
1631 h[0] = data->set.headers;
1632 if(data->set.sep_headers) {
1633 h[1] = data->set.proxyheaders;
1634 numlists++;
1635 }
1636 break;
1637 case HEADER_CONNECT:
1638 if(data->set.sep_headers)
1639 h[0] = data->set.proxyheaders;
1640 else
1641 h[0] = data->set.headers;
1642 break;
1643 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001644
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001645 /* loop through one or two lists */
Alex Deymo486467e2017-12-19 19:04:07 +01001646 for(i = 0; i < numlists; i++) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001647 headers = h[i];
1648
1649 while(headers) {
Elliott Hughescac39802018-04-27 16:19:43 -07001650 char *semicolonp = NULL;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001651 ptr = strchr(headers->data, ':');
Elliott Hughescac39802018-04-27 16:19:43 -07001652 if(!ptr) {
1653 char *optr;
1654 /* no colon, semicolon? */
1655 ptr = strchr(headers->data, ';');
1656 if(ptr) {
1657 optr = ptr;
1658 ptr++; /* pass the semicolon */
1659 while(*ptr && ISSPACE(*ptr))
1660 ptr++;
1661
1662 if(*ptr) {
1663 /* this may be used for something else in the future */
1664 optr = NULL;
1665 }
1666 else {
1667 if(*(--ptr) == ';') {
1668 /* send no-value custom header if terminated by semicolon */
1669 *ptr = ':';
1670 semicolonp = ptr;
1671 }
1672 }
1673 ptr = optr;
1674 }
1675 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001676 if(ptr) {
1677 /* we require a colon for this to be a true header */
1678
1679 ptr++; /* pass the colon */
1680 while(*ptr && ISSPACE(*ptr))
1681 ptr++;
1682
Elliott Hughescac39802018-04-27 16:19:43 -07001683 if(*ptr || semicolonp) {
1684 /* only send this if the contents was non-blank or done special */
1685 CURLcode result = CURLE_OK;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001686
1687 if(conn->allocptr.host &&
1688 /* a Host: header was sent already, don't pass on any custom Host:
1689 header as that will produce *two* in the same request! */
1690 checkprefix("Host:", headers->data))
1691 ;
1692 else if(data->set.httpreq == HTTPREQ_POST_FORM &&
1693 /* this header (extended by formdata.c) is sent later */
1694 checkprefix("Content-Type:", headers->data))
1695 ;
Alex Deymo486467e2017-12-19 19:04:07 +01001696 else if(data->set.httpreq == HTTPREQ_POST_MIME &&
1697 /* this header is sent later */
1698 checkprefix("Content-Type:", headers->data))
1699 ;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001700 else if(conn->bits.authneg &&
1701 /* while doing auth neg, don't allow the custom length since
1702 we will force length zero then */
Alex Deymo486467e2017-12-19 19:04:07 +01001703 checkprefix("Content-Length:", headers->data))
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001704 ;
1705 else if(conn->allocptr.te &&
1706 /* when asking for Transfer-Encoding, don't pass on a custom
1707 Connection: */
Alex Deymo486467e2017-12-19 19:04:07 +01001708 checkprefix("Connection:", headers->data))
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001709 ;
Elliott Hughescee03382017-06-23 12:17:18 -07001710 else if((conn->httpversion == 20) &&
1711 checkprefix("Transfer-Encoding:", headers->data))
1712 /* HTTP/2 doesn't support chunked requests */
1713 ;
Elliott Hughes0128fe42018-02-27 14:57:55 -08001714 else if(checkprefix("Authorization:", headers->data) &&
1715 /* be careful of sending this potentially sensitive header to
1716 other hosts */
1717 (data->state.this_is_a_follow &&
1718 data->state.first_host &&
1719 !data->set.allow_auth_to_other_hosts &&
1720 !strcasecompare(data->state.first_host, conn->host.name)))
1721 ;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001722 else {
Elliott Hughescac39802018-04-27 16:19:43 -07001723 result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001724 }
Elliott Hughescac39802018-04-27 16:19:43 -07001725 if(semicolonp)
1726 *semicolonp = ';'; /* put back the semicolon */
1727 if(result)
1728 return result;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001729 }
1730 }
1731 headers = headers->next;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001732 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001733 }
Alex Deymod15eaac2016-06-28 14:49:26 -07001734
Kristian Monsen5ab50182010-05-14 18:53:44 +01001735 return CURLE_OK;
1736}
1737
Alex Deymoe3149cc2016-10-05 11:18:42 -07001738CURLcode Curl_add_timecondition(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +01001739 Curl_send_buffer *req_buffer)
1740{
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001741 const struct tm *tm;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001742 struct tm keeptime;
Alex Deymod15eaac2016-06-28 14:49:26 -07001743 CURLcode result;
Elliott Hughes82be86d2017-09-20 17:00:17 -07001744 char datestr[80];
1745 const char *condp;
Alex Deymod15eaac2016-06-28 14:49:26 -07001746
1747 if(data->set.timecondition == CURL_TIMECOND_NONE)
1748 /* no condition was asked for */
1749 return CURLE_OK;
1750
1751 result = Curl_gmtime(data->set.timevalue, &keeptime);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001752 if(result) {
1753 failf(data, "Invalid TIMEVALUE");
1754 return result;
1755 }
1756 tm = &keeptime;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001757
Elliott Hughes82be86d2017-09-20 17:00:17 -07001758 switch(data->set.timecondition) {
1759 default:
1760 return CURLE_BAD_FUNCTION_ARGUMENT;
1761
1762 case CURL_TIMECOND_IFMODSINCE:
1763 condp = "If-Modified-Since";
1764 break;
1765 case CURL_TIMECOND_IFUNMODSINCE:
1766 condp = "If-Unmodified-Since";
1767 break;
1768 case CURL_TIMECOND_LASTMOD:
1769 condp = "Last-Modified";
1770 break;
1771 }
1772
Kristian Monsen5ab50182010-05-14 18:53:44 +01001773 /* The If-Modified-Since header family should have their times set in
1774 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1775 * represented in Greenwich Mean Time (GMT), without exception. For the
1776 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1777 * Time)." (see page 20 of RFC2616).
1778 */
1779
Kristian Monsen5ab50182010-05-14 18:53:44 +01001780 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
Elliott Hughes82be86d2017-09-20 17:00:17 -07001781 snprintf(datestr, sizeof(datestr),
1782 "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
1783 condp,
Kristian Monsen5ab50182010-05-14 18:53:44 +01001784 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1785 tm->tm_mday,
1786 Curl_month[tm->tm_mon],
1787 tm->tm_year + 1900,
1788 tm->tm_hour,
1789 tm->tm_min,
1790 tm->tm_sec);
1791
Elliott Hughes82be86d2017-09-20 17:00:17 -07001792 result = Curl_add_buffer(req_buffer, datestr, strlen(datestr));
Kristian Monsen5ab50182010-05-14 18:53:44 +01001793
1794 return result;
1795}
1796
1797/*
Alex Deymoe3149cc2016-10-05 11:18:42 -07001798 * Curl_http() gets called from the generic multi_do() function when a HTTP
Kristian Monsen5ab50182010-05-14 18:53:44 +01001799 * request is to be performed. This creates and sends a properly constructed
1800 * HTTP request.
1801 */
1802CURLcode Curl_http(struct connectdata *conn, bool *done)
1803{
Alex Deymoe3149cc2016-10-05 11:18:42 -07001804 struct Curl_easy *data = conn->data;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001805 CURLcode result = CURLE_OK;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001806 struct HTTP *http;
1807 const char *ppath = data->state.path;
1808 bool paste_ftp_userpwd = FALSE;
1809 char ftp_typecode[sizeof("/;type=?")] = "";
1810 const char *host = conn->host.name;
1811 const char *te = ""; /* transfer-encoding */
1812 const char *ptr;
1813 const char *request;
1814 Curl_HttpReq httpreq = data->set.httpreq;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001815#if !defined(CURL_DISABLE_COOKIES)
Kristian Monsen5ab50182010-05-14 18:53:44 +01001816 char *addcookies = NULL;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001817#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +01001818 curl_off_t included_body = 0;
1819 const char *httpstring;
1820 Curl_send_buffer *req_buffer;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001821 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
Alex Deymo486467e2017-12-19 19:04:07 +01001822 int seekerr = CURL_SEEKFUNC_CANTSEEK;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001823
1824 /* Always consider the DO phase done after this function call, even if there
1825 may be parts of the request that is not yet sent, since we can deal with
1826 the rest of the request in the PERFORM phase. */
1827 *done = TRUE;
1828
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001829 if(conn->httpversion < 20) { /* unless the connection is re-used and already
1830 http2 */
1831 switch(conn->negnpn) {
Alex Deymod15eaac2016-06-28 14:49:26 -07001832 case CURL_HTTP_VERSION_2:
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001833 conn->httpversion = 20; /* we know we're on HTTP/2 now */
Kristian Monsen5ab50182010-05-14 18:53:44 +01001834
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001835 result = Curl_http2_switched(conn, NULL, 0);
1836 if(result)
1837 return result;
1838 break;
1839 case CURL_HTTP_VERSION_1_1:
1840 /* continue with HTTP/1.1 when explicitly requested */
1841 break;
1842 default:
Alex Deymod15eaac2016-06-28 14:49:26 -07001843 /* Check if user wants to use HTTP/2 with clear TCP*/
1844#ifdef USE_NGHTTP2
1845 if(conn->data->set.httpversion ==
1846 CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
1847 DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
1848 conn->httpversion = 20;
1849
1850 result = Curl_http2_switched(conn, NULL, 0);
1851 if(result)
1852 return result;
1853 }
1854#endif
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001855 break;
1856 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001857 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001858 else {
1859 /* prepare for a http2 request */
1860 result = Curl_http2_setup(conn);
1861 if(result)
1862 return result;
1863 }
1864
1865 http = data->req.protop;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001866
1867 if(!data->state.this_is_a_follow) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001868 /* Free to avoid leaking memory on multiple requests*/
1869 free(data->state.first_host);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001870
1871 data->state.first_host = strdup(conn->host.name);
1872 if(!data->state.first_host)
1873 return CURLE_OUT_OF_MEMORY;
Alex Deymod15eaac2016-06-28 14:49:26 -07001874
1875 data->state.first_remote_port = conn->remote_port;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001876 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001877 http->writebytecount = http->readbytecount = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001878
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001879 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
1880 data->set.upload) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001881 httpreq = HTTPREQ_PUT;
1882 }
1883
1884 /* Now set the 'request' pointer to the proper request string */
1885 if(data->set.str[STRING_CUSTOMREQUEST])
1886 request = data->set.str[STRING_CUSTOMREQUEST];
1887 else {
1888 if(data->set.opt_no_body)
1889 request = "HEAD";
1890 else {
1891 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1892 switch(httpreq) {
1893 case HTTPREQ_POST:
1894 case HTTPREQ_POST_FORM:
Alex Deymo486467e2017-12-19 19:04:07 +01001895 case HTTPREQ_POST_MIME:
Kristian Monsen5ab50182010-05-14 18:53:44 +01001896 request = "POST";
1897 break;
1898 case HTTPREQ_PUT:
1899 request = "PUT";
1900 break;
Elliott Hughes82be86d2017-09-20 17:00:17 -07001901 case HTTPREQ_OPTIONS:
1902 request = "OPTIONS";
1903 break;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001904 default: /* this should never happen */
1905 case HTTPREQ_GET:
1906 request = "GET";
1907 break;
1908 case HTTPREQ_HEAD:
1909 request = "HEAD";
1910 break;
1911 }
1912 }
1913 }
1914
1915 /* The User-Agent string might have been allocated in url.c already, because
1916 it might have been used in the proxy connect, but if we have got a header
1917 with the user-agent string specified, we erase the previously made string
1918 here. */
Elliott Hughescac39802018-04-27 16:19:43 -07001919 if(Curl_checkheaders(conn, "User-Agent")) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001920 free(conn->allocptr.uagent);
Alex Deymo486467e2017-12-19 19:04:07 +01001921 conn->allocptr.uagent = NULL;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001922 }
1923
1924 /* setup the authentication headers */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001925 result = Curl_http_output_auth(conn, request, ppath, FALSE);
Kristian Monsen5ab50182010-05-14 18:53:44 +01001926 if(result)
1927 return result;
1928
Elliott Hughes82be86d2017-09-20 17:00:17 -07001929 if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
Kristian Monsen5ab50182010-05-14 18:53:44 +01001930 (httpreq != HTTPREQ_GET) &&
1931 (httpreq != HTTPREQ_HEAD)) {
1932 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1933 with content-length zero as a "probe". */
1934 conn->bits.authneg = TRUE;
1935 }
1936 else
1937 conn->bits.authneg = FALSE;
1938
1939 Curl_safefree(conn->allocptr.ref);
Elliott Hughescac39802018-04-27 16:19:43 -07001940 if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01001941 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001942 if(!conn->allocptr.ref)
1943 return CURLE_OUT_OF_MEMORY;
1944 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001945 else
1946 conn->allocptr.ref = NULL;
1947
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001948#if !defined(CURL_DISABLE_COOKIES)
Elliott Hughescac39802018-04-27 16:19:43 -07001949 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
Kristian Monsen5ab50182010-05-14 18:53:44 +01001950 addcookies = data->set.str[STRING_COOKIE];
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001951#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +01001952
Elliott Hughescac39802018-04-27 16:19:43 -07001953 if(!Curl_checkheaders(conn, "Accept-Encoding") &&
Kristian Monsen5ab50182010-05-14 18:53:44 +01001954 data->set.str[STRING_ENCODING]) {
1955 Curl_safefree(conn->allocptr.accept_encoding);
1956 conn->allocptr.accept_encoding =
1957 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1958 if(!conn->allocptr.accept_encoding)
1959 return CURLE_OUT_OF_MEMORY;
1960 }
Alex Deymod15eaac2016-06-28 14:49:26 -07001961 else {
1962 Curl_safefree(conn->allocptr.accept_encoding);
1963 conn->allocptr.accept_encoding = NULL;
1964 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01001965
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001966#ifdef HAVE_LIBZ
1967 /* we only consider transfer-encoding magic if libz support is built-in */
1968
Elliott Hughescac39802018-04-27 16:19:43 -07001969 if(!Curl_checkheaders(conn, "TE") &&
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001970 data->set.http_transfer_encoding) {
1971 /* When we are to insert a TE: header in the request, we must also insert
1972 TE in a Connection: header, so we need to merge the custom provided
1973 Connection: header and prevent the original to get sent. Note that if
1974 the user has inserted his/hers own TE: header we don't do this magic
1975 but then assume that the user will handle it all! */
Elliott Hughescac39802018-04-27 16:19:43 -07001976 char *cptr = Curl_checkheaders(conn, "Connection");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001977#define TE_HEADER "TE: gzip\r\n"
1978
1979 Curl_safefree(conn->allocptr.te);
1980
Elliott Hughescac39802018-04-27 16:19:43 -07001981 if(cptr) {
1982 cptr = Curl_copy_header_value(cptr);
1983 if(!cptr)
1984 return CURLE_OUT_OF_MEMORY;
1985 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001986
Elliott Hughescac39802018-04-27 16:19:43 -07001987 /* Create the (updated) Connection: header */
1988 conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
1989 cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
1990
1991 free(cptr);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001992 if(!conn->allocptr.te)
1993 return CURLE_OUT_OF_MEMORY;
Kristian Monsen5ab50182010-05-14 18:53:44 +01001994 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07001995#endif
1996
Alex Deymo486467e2017-12-19 19:04:07 +01001997 switch(httpreq) {
1998 case HTTPREQ_POST_MIME:
1999 http->sendit = &data->set.mimepost;
2000 break;
2001 case HTTPREQ_POST_FORM:
2002 /* Convert the form structure into a mime structure. */
2003 Curl_mime_cleanpart(&http->form);
2004 result = Curl_getformdata(data, &http->form, data->set.httppost,
2005 data->state.fread_func);
2006 if(result)
2007 return result;
2008 http->sendit = &http->form;
2009 break;
2010 default:
2011 http->sendit = NULL;
2012 }
2013
2014 if(http->sendit) {
Elliott Hughescac39802018-04-27 16:19:43 -07002015 const char *cthdr = Curl_checkheaders(conn, "Content-Type");
Alex Deymo486467e2017-12-19 19:04:07 +01002016
2017 /* Read and seek body only. */
2018 http->sendit->flags |= MIME_BODY_ONLY;
2019
2020 /* Prepare the mime structure headers & set content type. */
2021
2022 if(cthdr)
2023 for(cthdr += 13; *cthdr == ' '; cthdr++)
2024 ;
2025 else if(http->sendit->kind == MIMEKIND_MULTIPART)
2026 cthdr = "multipart/form-data";
2027
2028 curl_mime_headers(http->sendit, data->set.headers, 0);
2029 result = Curl_mime_prepare_headers(http->sendit, cthdr,
2030 NULL, MIMESTRATEGY_FORM);
2031 curl_mime_headers(http->sendit, NULL, 0);
2032 if(!result)
2033 result = Curl_mime_rewind(http->sendit);
2034 if(result)
2035 return result;
2036 http->postsize = Curl_mime_size(http->sendit);
2037 }
2038
Elliott Hughescac39802018-04-27 16:19:43 -07002039 ptr = Curl_checkheaders(conn, "Transfer-Encoding");
Elliott Hughescee03382017-06-23 12:17:18 -07002040 if(ptr) {
2041 /* Some kind of TE is requested, check if 'chunked' is chosen */
2042 data->req.upload_chunky =
2043 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
2044 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01002045 else {
Alex Deymo486467e2017-12-19 19:04:07 +01002046 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
2047 (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
2048 http->postsize < 0) ||
2049 (data->set.upload && data->state.infilesize == -1))) {
Elliott Hughescee03382017-06-23 12:17:18 -07002050 if(conn->bits.authneg)
2051 /* don't enable chunked during auth neg */
2052 ;
2053 else if(use_http_1_1plus(data, conn)) {
2054 /* HTTP, upload, unknown file size and not HTTP 1.0 */
2055 data->req.upload_chunky = TRUE;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002056 }
2057 else {
Elliott Hughescee03382017-06-23 12:17:18 -07002058 failf(data, "Chunky upload is not supported by HTTP 1.0");
2059 return CURLE_UPLOAD_FAILED;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002060 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002061 }
Elliott Hughescee03382017-06-23 12:17:18 -07002062 else {
2063 /* else, no chunky upload */
2064 data->req.upload_chunky = FALSE;
2065 }
2066
2067 if(data->req.upload_chunky)
2068 te = "Transfer-Encoding: chunked\r\n";
Kristian Monsen5ab50182010-05-14 18:53:44 +01002069 }
2070
2071 Curl_safefree(conn->allocptr.host);
2072
Elliott Hughescac39802018-04-27 16:19:43 -07002073 ptr = Curl_checkheaders(conn, "Host");
Kristian Monsen5ab50182010-05-14 18:53:44 +01002074 if(ptr && (!data->state.this_is_a_follow ||
Elliott Hughescee03382017-06-23 12:17:18 -07002075 strcasecompare(data->state.first_host, conn->host.name))) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002076#if !defined(CURL_DISABLE_COOKIES)
2077 /* If we have a given custom Host: header, we extract the host name in
2078 order to possibly use it for cookie reasons later on. We only allow the
2079 custom Host: header if this is NOT a redirect, as setting Host: in the
2080 redirected request is being out on thin ice. Except if the host name
2081 is the same as the first one! */
2082 char *cookiehost = Curl_copy_header_value(ptr);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002083 if(!cookiehost)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002084 return CURLE_OUT_OF_MEMORY;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002085 if(!*cookiehost)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002086 /* ignore empty data */
2087 free(cookiehost);
2088 else {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002089 /* If the host begins with '[', we start searching for the port after
2090 the bracket has been closed */
2091 int startsearch = 0;
2092 if(*cookiehost == '[') {
2093 char *closingbracket;
2094 /* since the 'cookiehost' is an allocated memory area that will be
2095 freed later we cannot simply increment the pointer */
2096 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
2097 closingbracket = strchr(cookiehost, ']');
2098 if(closingbracket)
2099 *closingbracket = 0;
2100 }
2101 else {
2102 char *colon = strchr(cookiehost + startsearch, ':');
2103 if(colon)
2104 *colon = 0; /* The host must not include an embedded port number */
2105 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01002106 Curl_safefree(conn->allocptr.cookiehost);
2107 conn->allocptr.cookiehost = cookiehost;
2108 }
2109#endif
2110
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002111 if(strcmp("Host:", ptr)) {
Elliott Hughescac39802018-04-27 16:19:43 -07002112 conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002113 if(!conn->allocptr.host)
2114 return CURLE_OUT_OF_MEMORY;
2115 }
2116 else
2117 /* when clearing the header */
2118 conn->allocptr.host = NULL;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002119 }
2120 else {
2121 /* When building Host: headers, we must put the host name within
2122 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2123
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002124 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2125 (conn->remote_port == PORT_HTTPS)) ||
2126 ((conn->given->protocol&CURLPROTO_HTTP) &&
2127 (conn->remote_port == PORT_HTTP)) )
2128 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
Kristian Monsen5ab50182010-05-14 18:53:44 +01002129 the port number in the host string */
2130 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
2131 conn->bits.ipv6_ip?"[":"",
2132 host,
2133 conn->bits.ipv6_ip?"]":"");
2134 else
Elliott Hughes1ef06ba2018-05-30 15:43:58 -07002135 conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n",
Kristian Monsen5ab50182010-05-14 18:53:44 +01002136 conn->bits.ipv6_ip?"[":"",
2137 host,
2138 conn->bits.ipv6_ip?"]":"",
2139 conn->remote_port);
2140
2141 if(!conn->allocptr.host)
2142 /* without Host: we can't make a nice request */
2143 return CURLE_OUT_OF_MEMORY;
2144 }
2145
2146#ifndef CURL_DISABLE_PROXY
Alex Deymo486467e2017-12-19 19:04:07 +01002147 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002148 /* Using a proxy but does not tunnel through it */
2149
2150 /* The path sent to the proxy is in fact the entire URL. But if the remote
2151 host is a IDN-name, we must make sure that the request we produce only
2152 uses the encoded host name! */
2153 if(conn->host.dispname != conn->host.name) {
2154 char *url = data->change.url;
2155 ptr = strstr(url, conn->host.dispname);
2156 if(ptr) {
2157 /* This is where the display name starts in the URL, now replace this
2158 part with the encoded name. TODO: This method of replacing the host
2159 name is rather crude as I believe there's a slight risk that the
2160 user has entered a user name or password that contain the host name
2161 string. */
2162 size_t currlen = strlen(conn->host.dispname);
2163 size_t newlen = strlen(conn->host.name);
2164 size_t urllen = strlen(url);
2165
2166 char *newurl;
2167
2168 newurl = malloc(urllen + newlen - currlen + 1);
2169 if(newurl) {
2170 /* copy the part before the host name */
2171 memcpy(newurl, url, ptr - url);
2172 /* append the new host name instead of the old */
2173 memcpy(newurl + (ptr - url), conn->host.name, newlen);
2174 /* append the piece after the host name */
2175 memcpy(newurl + newlen + (ptr - url),
2176 ptr + currlen, /* copy the trailing zero byte too */
2177 urllen - (ptr-url) - currlen + 1);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002178 if(data->change.url_alloc) {
2179 Curl_safefree(data->change.url);
2180 data->change.url_alloc = FALSE;
2181 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01002182 data->change.url = newurl;
2183 data->change.url_alloc = TRUE;
2184 }
2185 else
2186 return CURLE_OUT_OF_MEMORY;
2187 }
2188 }
2189 ppath = data->change.url;
2190 if(checkprefix("ftp://", ppath)) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002191 if(data->set.proxy_transfer_mode) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002192 /* when doing ftp, append ;type=<a|i> if not present */
2193 char *type = strstr(ppath, ";type=");
2194 if(type && type[6] && type[7] == 0) {
Elliott Hughes82be86d2017-09-20 17:00:17 -07002195 switch(Curl_raw_toupper(type[6])) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002196 case 'A':
2197 case 'D':
2198 case 'I':
2199 break;
2200 default:
2201 type = NULL;
2202 }
2203 }
2204 if(!type) {
2205 char *p = ftp_typecode;
2206 /* avoid sending invalid URLs like ftp://example.com;type=i if the
2207 * user specified ftp://example.com without the slash */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002208 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002209 *p++ = '/';
2210 }
2211 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2212 data->set.prefer_ascii ? 'a' : 'i');
2213 }
2214 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002215 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002216 paste_ftp_userpwd = TRUE;
2217 }
2218 }
2219#endif /* CURL_DISABLE_PROXY */
2220
Elliott Hughescac39802018-04-27 16:19:43 -07002221 http->p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n";
Kristian Monsen5ab50182010-05-14 18:53:44 +01002222
Alex Deymo486467e2017-12-19 19:04:07 +01002223 if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) &&
Kristian Monsen5ab50182010-05-14 18:53:44 +01002224 data->state.resume_from) {
2225 /**********************************************************************
2226 * Resuming upload in HTTP means that we PUT or POST and that we have
2227 * got a resume_from value set. The resume value has already created
2228 * a Range: header that will be passed along. We need to "fast forward"
2229 * the file the given number of bytes and decrease the assume upload
2230 * file size before we continue this venture in the dark lands of HTTP.
Alex Deymo486467e2017-12-19 19:04:07 +01002231 * Resuming mime/form posting at an offset > 0 has no sense and is ignored.
Kristian Monsen5ab50182010-05-14 18:53:44 +01002232 *********************************************************************/
2233
Alex Deymod15eaac2016-06-28 14:49:26 -07002234 if(data->state.resume_from < 0) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002235 /*
2236 * This is meant to get the size of the present remote-file by itself.
2237 * We don't support this now. Bail out!
2238 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002239 data->state.resume_from = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002240 }
2241
2242 if(data->state.resume_from && !data->state.this_is_a_follow) {
2243 /* do we still game? */
2244
2245 /* Now, let's read off the proper amount of bytes from the
2246 input. */
2247 if(conn->seek_func) {
Elliott Hughescac39802018-04-27 16:19:43 -07002248 Curl_set_in_callback(data, true);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002249 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2250 SEEK_SET);
Elliott Hughescac39802018-04-27 16:19:43 -07002251 Curl_set_in_callback(data, false);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002252 }
2253
2254 if(seekerr != CURL_SEEKFUNC_OK) {
Alex Deymo486467e2017-12-19 19:04:07 +01002255 curl_off_t passed = 0;
Elliott Hughes82be86d2017-09-20 17:00:17 -07002256
Kristian Monsen5ab50182010-05-14 18:53:44 +01002257 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2258 failf(data, "Could not seek stream");
2259 return CURLE_READ_ERROR;
2260 }
2261 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
Elliott Hughes82be86d2017-09-20 17:00:17 -07002262 do {
2263 size_t readthisamountnow =
2264 (data->state.resume_from - passed > data->set.buffer_size) ?
2265 (size_t)data->set.buffer_size :
2266 curlx_sotouz(data->state.resume_from - passed);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002267
Elliott Hughes82be86d2017-09-20 17:00:17 -07002268 size_t actuallyread =
2269 data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2270 data->state.in);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002271
Elliott Hughes82be86d2017-09-20 17:00:17 -07002272 passed += actuallyread;
2273 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2274 /* this checks for greater-than only to make sure that the
2275 CURL_READFUNC_ABORT return code still aborts */
2276 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2277 " bytes from the input", passed);
2278 return CURLE_READ_ERROR;
2279 }
2280 } while(passed < data->state.resume_from);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002281 }
2282
2283 /* now, decrease the size of the read */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002284 if(data->state.infilesize>0) {
2285 data->state.infilesize -= data->state.resume_from;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002286
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002287 if(data->state.infilesize <= 0) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002288 failf(data, "File already completely uploaded");
2289 return CURLE_PARTIAL_FILE;
2290 }
2291 }
2292 /* we've passed, proceed as normal */
2293 }
2294 }
2295 if(data->state.use_range) {
2296 /*
2297 * A range is selected. We use different headers whether we're downloading
2298 * or uploading and we always let customized headers override our internal
2299 * ones if any such are specified.
2300 */
2301 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
Elliott Hughescac39802018-04-27 16:19:43 -07002302 !Curl_checkheaders(conn, "Range")) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002303 /* if a line like this was already allocated, free the previous one */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002304 free(conn->allocptr.rangeline);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002305 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2306 data->state.range);
2307 }
Alex Deymo486467e2017-12-19 19:04:07 +01002308 else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
Elliott Hughescac39802018-04-27 16:19:43 -07002309 !Curl_checkheaders(conn, "Content-Range")) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002310
2311 /* if a line like this was already allocated, free the previous one */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002312 free(conn->allocptr.rangeline);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002313
2314 if(data->set.set_resume_from < 0) {
2315 /* Upload resume was asked for, but we don't know the size of the
2316 remote part so we tell the server (and act accordingly) that we
2317 upload the whole file (again) */
2318 conn->allocptr.rangeline =
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002319 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2320 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2321 data->state.infilesize - 1, data->state.infilesize);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002322
2323 }
2324 else if(data->state.resume_from) {
2325 /* This is because "resume" was selected */
Alex Deymo486467e2017-12-19 19:04:07 +01002326 curl_off_t total_expected_size =
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002327 data->state.resume_from + data->state.infilesize;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002328 conn->allocptr.rangeline =
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002329 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2330 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2331 data->state.range, total_expected_size-1,
2332 total_expected_size);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002333 }
2334 else {
2335 /* Range was selected and then we just pass the incoming range and
2336 append total size */
2337 conn->allocptr.rangeline =
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002338 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2339 data->state.range, data->state.infilesize);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002340 }
2341 if(!conn->allocptr.rangeline)
2342 return CURLE_OUT_OF_MEMORY;
2343 }
2344 }
2345
Elliott Hughes82be86d2017-09-20 17:00:17 -07002346 httpstring = get_http_string(data, conn);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002347
2348 /* initialize a dynamic send-buffer */
2349 req_buffer = Curl_add_buffer_init();
2350
2351 if(!req_buffer)
2352 return CURLE_OUT_OF_MEMORY;
2353
2354 /* add the main request stuff */
2355 /* GET/HEAD/POST/PUT */
2356 result = Curl_add_bufferf(req_buffer, "%s ", request);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002357 if(result)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002358 return result;
2359
Elliott Hughes82be86d2017-09-20 17:00:17 -07002360 if(data->set.str[STRING_TARGET])
2361 ppath = data->set.str[STRING_TARGET];
2362
Kristian Monsen5ab50182010-05-14 18:53:44 +01002363 /* url */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002364 if(paste_ftp_userpwd)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002365 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002366 conn->user, conn->passwd,
2367 ppath + sizeof("ftp://") - 1);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002368 else
2369 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002370 if(result)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002371 return result;
2372
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002373 result =
2374 Curl_add_bufferf(req_buffer,
2375 "%s" /* ftp typecode (;type=x) */
2376 " HTTP/%s\r\n" /* HTTP version */
2377 "%s" /* host */
2378 "%s" /* proxyuserpwd */
2379 "%s" /* userpwd */
2380 "%s" /* range */
2381 "%s" /* user agent */
2382 "%s" /* accept */
2383 "%s" /* TE: */
2384 "%s" /* accept-encoding */
2385 "%s" /* referer */
Elliott Hughescee03382017-06-23 12:17:18 -07002386 "%s" /* Proxy-Connection */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002387 "%s",/* transfer-encoding */
Kristian Monsen5ab50182010-05-14 18:53:44 +01002388
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002389 ftp_typecode,
2390 httpstring,
2391 (conn->allocptr.host?conn->allocptr.host:""),
2392 conn->allocptr.proxyuserpwd?
2393 conn->allocptr.proxyuserpwd:"",
2394 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2395 (data->state.use_range && conn->allocptr.rangeline)?
2396 conn->allocptr.rangeline:"",
2397 (data->set.str[STRING_USERAGENT] &&
2398 *data->set.str[STRING_USERAGENT] &&
2399 conn->allocptr.uagent)?
2400 conn->allocptr.uagent:"",
2401 http->p_accept?http->p_accept:"",
2402 conn->allocptr.te?conn->allocptr.te:"",
2403 (data->set.str[STRING_ENCODING] &&
2404 *data->set.str[STRING_ENCODING] &&
2405 conn->allocptr.accept_encoding)?
2406 conn->allocptr.accept_encoding:"",
2407 (data->change.referer && conn->allocptr.ref)?
2408 conn->allocptr.ref:"" /* Referer: <data> */,
Elliott Hughescee03382017-06-23 12:17:18 -07002409 (conn->bits.httpproxy &&
2410 !conn->bits.tunnel_proxy &&
Elliott Hughescac39802018-04-27 16:19:43 -07002411 !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
Elliott Hughescee03382017-06-23 12:17:18 -07002412 "Proxy-Connection: Keep-Alive\r\n":"",
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002413 te
Kristian Monsen5ab50182010-05-14 18:53:44 +01002414 );
2415
Elliott Hughes82be86d2017-09-20 17:00:17 -07002416 /* clear userpwd and proxyuserpwd to avoid re-using old credentials
2417 * from re-used connections */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002418 Curl_safefree(conn->allocptr.userpwd);
Elliott Hughes82be86d2017-09-20 17:00:17 -07002419 Curl_safefree(conn->allocptr.proxyuserpwd);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002420
2421 if(result)
2422 return result;
2423
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002424 if(!(conn->handler->flags&PROTOPT_SSL) &&
2425 conn->httpversion != 20 &&
Alex Deymod15eaac2016-06-28 14:49:26 -07002426 (data->set.httpversion == CURL_HTTP_VERSION_2)) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002427 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2428 over SSL */
2429 result = Curl_http2_request_upgrade(req_buffer, conn);
2430 if(result)
2431 return result;
2432 }
2433
Kristian Monsen5ab50182010-05-14 18:53:44 +01002434#if !defined(CURL_DISABLE_COOKIES)
2435 if(data->cookies || addcookies) {
Alex Deymo486467e2017-12-19 19:04:07 +01002436 struct Cookie *co = NULL; /* no cookies from start */
2437 int count = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002438
2439 if(data->cookies) {
2440 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2441 co = Curl_cookie_getlist(data->cookies,
2442 conn->allocptr.cookiehost?
2443 conn->allocptr.cookiehost:host,
2444 data->state.path,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002445 (conn->handler->protocol&CURLPROTO_HTTPS)?
2446 TRUE:FALSE);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002447 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2448 }
2449 if(co) {
Alex Deymo486467e2017-12-19 19:04:07 +01002450 struct Cookie *store = co;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002451 /* now loop through all cookies that matched */
2452 while(co) {
2453 if(co->value) {
2454 if(0 == count) {
2455 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2456 if(result)
2457 break;
2458 }
2459 result = Curl_add_bufferf(req_buffer,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002460 "%s%s=%s", count?"; ":"",
2461 co->name, co->value);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002462 if(result)
2463 break;
2464 count++;
2465 }
2466 co = co->next; /* next cookie please */
2467 }
Elliott Hughescee03382017-06-23 12:17:18 -07002468 Curl_cookie_freelist(store);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002469 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002470 if(addcookies && !result) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002471 if(!count)
2472 result = Curl_add_bufferf(req_buffer, "Cookie: ");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002473 if(!result) {
2474 result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
2475 addcookies);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002476 count++;
2477 }
2478 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002479 if(count && !result)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002480 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2481
2482 if(result)
2483 return result;
2484 }
2485#endif
2486
Alex Deymod15eaac2016-06-28 14:49:26 -07002487 result = Curl_add_timecondition(data, req_buffer);
2488 if(result)
2489 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002490
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002491 result = Curl_add_custom_headers(conn, FALSE, req_buffer);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002492 if(result)
2493 return result;
2494
2495 http->postdata = NULL; /* nothing to post at this point */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002496 Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
Kristian Monsen5ab50182010-05-14 18:53:44 +01002497
2498 /* If 'authdone' is FALSE, we must not set the write socket index to the
2499 Curl_transfer() call below, as we're not ready to actually upload any
2500 data yet. */
2501
2502 switch(httpreq) {
2503
Kristian Monsen5ab50182010-05-14 18:53:44 +01002504 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2505
2506 if(conn->bits.authneg)
2507 postsize = 0;
2508 else
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002509 postsize = data->state.infilesize;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002510
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002511 if((postsize != -1) && !data->req.upload_chunky &&
Elliott Hughescac39802018-04-27 16:19:43 -07002512 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002513 /* only add Content-Length if not uploading chunked */
2514 result = Curl_add_bufferf(req_buffer,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002515 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2516 "\r\n", postsize);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002517 if(result)
2518 return result;
2519 }
2520
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002521 if(postsize != 0) {
2522 result = expect100(data, conn, req_buffer);
2523 if(result)
2524 return result;
2525 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01002526
2527 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2528 if(result)
2529 return result;
2530
2531 /* set the upload size to the progress meter */
2532 Curl_pgrsSetUploadSize(data, postsize);
2533
2534 /* this sends the buffer and frees all the buffer resources */
2535 result = Curl_add_buffer_send(req_buffer, conn,
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002536 &data->info.request_size, 0, FIRSTSOCKET);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002537 if(result)
2538 failf(data, "Failed sending PUT request");
2539 else
2540 /* prepare for transfer */
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002541 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2542 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2543 postsize?&http->writebytecount:NULL);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002544 if(result)
2545 return result;
2546 break;
2547
Alex Deymo486467e2017-12-19 19:04:07 +01002548 case HTTPREQ_POST_FORM:
2549 case HTTPREQ_POST_MIME:
2550 /* This is form posting using mime data. */
2551 if(conn->bits.authneg) {
2552 /* nothing to post! */
2553 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2554 if(result)
2555 return result;
2556
2557 result = Curl_add_buffer_send(req_buffer, conn,
2558 &data->info.request_size, 0, FIRSTSOCKET);
2559 if(result)
2560 failf(data, "Failed sending POST request");
2561 else
2562 /* setup variables for the upcoming transfer */
2563 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2564 -1, NULL);
2565 break;
2566 }
2567
2568 postsize = http->postsize;
2569
2570 /* We only set Content-Length and allow a custom Content-Length if
2571 we don't upload data chunked, as RFC2616 forbids us to set both
2572 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2573 if(postsize != -1 && !data->req.upload_chunky &&
Elliott Hughescac39802018-04-27 16:19:43 -07002574 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
Alex Deymo486467e2017-12-19 19:04:07 +01002575 /* we allow replacing this header if not during auth negotiation,
2576 although it isn't very wise to actually set your own */
2577 result = Curl_add_bufferf(req_buffer,
2578 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2579 "\r\n", postsize);
2580 if(result)
2581 return result;
2582 }
2583
2584 /* Output mime-generated headers. */
2585 {
2586 struct curl_slist *hdr;
2587
2588 for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
2589 result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data);
2590 if(result)
2591 return result;
2592 }
2593 }
2594
2595 /* For really small posts we don't use Expect: headers at all, and for
2596 the somewhat bigger ones we allow the app to disable it. Just make
2597 sure that the expect100header is always set to the preferred value
2598 here. */
Elliott Hughescac39802018-04-27 16:19:43 -07002599 ptr = Curl_checkheaders(conn, "Expect");
Alex Deymo486467e2017-12-19 19:04:07 +01002600 if(ptr) {
2601 data->state.expect100header =
2602 Curl_compareheader(ptr, "Expect:", "100-continue");
2603 }
2604 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
2605 result = expect100(data, conn, req_buffer);
2606 if(result)
2607 return result;
2608 }
2609 else
2610 data->state.expect100header = FALSE;
2611
2612 /* make the request end in a true CRLF */
2613 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2614 if(result)
2615 return result;
2616
2617 /* set the upload size to the progress meter */
2618 Curl_pgrsSetUploadSize(data, postsize);
2619
2620 /* Read from mime structure. */
2621 data->state.fread_func = (curl_read_callback) Curl_mime_read;
2622 data->state.in = (void *) http->sendit;
2623 http->sending = HTTPSEND_BODY;
2624
2625 /* this sends the buffer and frees all the buffer resources */
2626 result = Curl_add_buffer_send(req_buffer, conn,
2627 &data->info.request_size, 0, FIRSTSOCKET);
2628 if(result)
2629 failf(data, "Failed sending POST request");
2630 else
2631 /* prepare for transfer */
2632 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2633 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2634 postsize?&http->writebytecount:NULL);
2635 if(result)
2636 return result;
2637
2638 break;
2639
Kristian Monsen5ab50182010-05-14 18:53:44 +01002640 case HTTPREQ_POST:
2641 /* this is the simple POST, using x-www-form-urlencoded style */
2642
2643 if(conn->bits.authneg)
2644 postsize = 0;
Elliott Hughes82be86d2017-09-20 17:00:17 -07002645 else
2646 /* the size of the post body */
2647 postsize = data->state.infilesize;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002648
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002649 /* We only set Content-Length and allow a custom Content-Length if
2650 we don't upload data chunked, as RFC2616 forbids us to set both
2651 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2652 if((postsize != -1) && !data->req.upload_chunky &&
Elliott Hughescac39802018-04-27 16:19:43 -07002653 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002654 /* we allow replacing this header if not during auth negotiation,
2655 although it isn't very wise to actually set your own */
2656 result = Curl_add_bufferf(req_buffer,
2657 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2658 "\r\n", postsize);
2659 if(result)
2660 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002661 }
2662
Elliott Hughescac39802018-04-27 16:19:43 -07002663 if(!Curl_checkheaders(conn, "Content-Type")) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002664 result = Curl_add_bufferf(req_buffer,
2665 "Content-Type: application/"
2666 "x-www-form-urlencoded\r\n");
2667 if(result)
2668 return result;
2669 }
2670
2671 /* For really small posts we don't use Expect: headers at all, and for
2672 the somewhat bigger ones we allow the app to disable it. Just make
2673 sure that the expect100header is always set to the preferred value
2674 here. */
Elliott Hughescac39802018-04-27 16:19:43 -07002675 ptr = Curl_checkheaders(conn, "Expect");
Kristian Monsen5ab50182010-05-14 18:53:44 +01002676 if(ptr) {
2677 data->state.expect100header =
2678 Curl_compareheader(ptr, "Expect:", "100-continue");
2679 }
Elliott Hughes82be86d2017-09-20 17:00:17 -07002680 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002681 result = expect100(data, conn, req_buffer);
2682 if(result)
2683 return result;
2684 }
2685 else
2686 data->state.expect100header = FALSE;
2687
2688 if(data->set.postfields) {
2689
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002690 /* In HTTP2, we send request body in DATA frame regardless of
2691 its size. */
2692 if(conn->httpversion != 20 &&
2693 !data->state.expect100header &&
Alex Deymo486467e2017-12-19 19:04:07 +01002694 (postsize < MAX_INITIAL_POST_SIZE)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002695 /* if we don't use expect: 100 AND
2696 postsize is less than MAX_INITIAL_POST_SIZE
2697
2698 then append the post data to the HTTP request header. This limit
2699 is no magic limit but only set to prevent really huge POSTs to
2700 get the data duplicated with malloc() and family. */
2701
2702 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2703 if(result)
2704 return result;
2705
2706 if(!data->req.upload_chunky) {
2707 /* We're not sending it 'chunked', append it to the request
2708 already now to reduce the number if send() calls */
2709 result = Curl_add_buffer(req_buffer, data->set.postfields,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002710 (size_t)postsize);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002711 included_body = postsize;
2712 }
2713 else {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002714 if(postsize) {
2715 /* Append the POST data chunky-style */
2716 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2717 if(!result) {
2718 result = Curl_add_buffer(req_buffer, data->set.postfields,
2719 (size_t)postsize);
2720 if(!result)
2721 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2722 included_body = postsize + 2;
2723 }
2724 }
2725 if(!result)
2726 result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
2727 /* 0 CR LF CR LF */
2728 included_body += 5;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002729 }
2730 if(result)
2731 return result;
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002732 /* Make sure the progress information is accurate */
2733 Curl_pgrsSetUploadSize(data, postsize);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002734 }
2735 else {
2736 /* A huge POST coming up, do data separate from the request */
2737 http->postsize = postsize;
2738 http->postdata = data->set.postfields;
2739
2740 http->sending = HTTPSEND_BODY;
2741
Alex Deymod15eaac2016-06-28 14:49:26 -07002742 data->state.fread_func = (curl_read_callback)readmoredata;
2743 data->state.in = (void *)conn;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002744
2745 /* set the upload size to the progress meter */
2746 Curl_pgrsSetUploadSize(data, http->postsize);
2747
2748 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2749 if(result)
2750 return result;
2751 }
2752 }
2753 else {
2754 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2755 if(result)
2756 return result;
2757
2758 if(data->req.upload_chunky && conn->bits.authneg) {
2759 /* Chunky upload is selected and we're negotiating auth still, send
2760 end-of-data only */
2761 result = Curl_add_buffer(req_buffer,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002762 "\x30\x0d\x0a\x0d\x0a", 5);
2763 /* 0 CR LF CR LF */
Kristian Monsen5ab50182010-05-14 18:53:44 +01002764 if(result)
2765 return result;
2766 }
2767
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002768 else if(data->state.infilesize) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002769 /* set the upload size to the progress meter */
2770 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2771
2772 /* set the pointer to mark that we will send the post body using the
2773 read callback, but only if we're not in authenticate
2774 negotiation */
2775 if(!conn->bits.authneg) {
2776 http->postdata = (char *)&http->postdata;
2777 http->postsize = postsize;
2778 }
2779 }
2780 }
2781 /* issue the request */
2782 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002783 (size_t)included_body, FIRSTSOCKET);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002784
2785 if(result)
2786 failf(data, "Failed sending HTTP POST request");
2787 else
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002788 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2789 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2790 http->postdata?&http->writebytecount:NULL);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002791 break;
2792
2793 default:
2794 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2795 if(result)
2796 return result;
2797
2798 /* issue the request */
2799 result = Curl_add_buffer_send(req_buffer, conn,
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002800 &data->info.request_size, 0, FIRSTSOCKET);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002801
2802 if(result)
2803 failf(data, "Failed sending HTTP request");
2804 else
2805 /* HTTP GET/HEAD download: */
Lucas Eckels9bd90e62012-08-06 15:07:02 -07002806 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2807 http->postdata?FIRSTSOCKET:-1,
2808 http->postdata?&http->writebytecount:NULL);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002809 }
2810 if(result)
2811 return result;
2812
2813 if(http->writebytecount) {
2814 /* if a request-body has been sent off, we make sure this progress is noted
2815 properly */
2816 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2817 if(Curl_pgrsUpdate(conn))
2818 result = CURLE_ABORTED_BY_CALLBACK;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002819
2820 if(http->writebytecount >= postsize) {
2821 /* already sent the entire request body, mark the "upload" as
2822 complete */
2823 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2824 " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2825 http->writebytecount, postsize);
2826 data->req.upload_done = TRUE;
2827 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2828 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
Elliott Hughes82be86d2017-09-20 17:00:17 -07002829 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002830 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01002831 }
2832
Elliott Hughescee03382017-06-23 12:17:18 -07002833 if((conn->httpversion == 20) && data->req.upload_chunky)
2834 /* upload_chunky was set above to set up the request in a chunky fashion,
2835 but is disabled here again to avoid that the chunked encoded version is
2836 actually used when sending the request body over h2 */
2837 data->req.upload_chunky = FALSE;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002838 return result;
2839}
2840
2841/*
2842 * checkhttpprefix()
2843 *
2844 * Returns TRUE if member of the list matches prefix of string
2845 */
2846static bool
Alex Deymoe3149cc2016-10-05 11:18:42 -07002847checkhttpprefix(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +01002848 const char *s)
2849{
2850 struct curl_slist *head = data->set.http200aliases;
2851 bool rc = FALSE;
2852#ifdef CURL_DOES_CONVERSIONS
2853 /* convert from the network encoding using a scratch area */
2854 char *scratch = strdup(s);
2855 if(NULL == scratch) {
Elliott Hughes82be86d2017-09-20 17:00:17 -07002856 failf(data, "Failed to allocate memory for conversion!");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002857 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
Kristian Monsen5ab50182010-05-14 18:53:44 +01002858 }
Alex Deymo486467e2017-12-19 19:04:07 +01002859 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002860 /* Curl_convert_from_network calls failf if unsuccessful */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002861 free(scratch);
2862 return FALSE; /* can't return CURLE_foobar so return FALSE */
Kristian Monsen5ab50182010-05-14 18:53:44 +01002863 }
2864 s = scratch;
2865#endif /* CURL_DOES_CONVERSIONS */
2866
2867 while(head) {
2868 if(checkprefix(head->data, s)) {
2869 rc = TRUE;
2870 break;
2871 }
2872 head = head->next;
2873 }
2874
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002875 if(!rc && (checkprefix("HTTP/", s)))
Kristian Monsen5ab50182010-05-14 18:53:44 +01002876 rc = TRUE;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002877
2878#ifdef CURL_DOES_CONVERSIONS
2879 free(scratch);
2880#endif /* CURL_DOES_CONVERSIONS */
2881 return rc;
2882}
2883
2884#ifndef CURL_DISABLE_RTSP
2885static bool
Alex Deymoe3149cc2016-10-05 11:18:42 -07002886checkrtspprefix(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +01002887 const char *s)
2888{
Alex Deymo486467e2017-12-19 19:04:07 +01002889 bool result = FALSE;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002890
2891#ifdef CURL_DOES_CONVERSIONS
2892 /* convert from the network encoding using a scratch area */
2893 char *scratch = strdup(s);
2894 if(NULL == scratch) {
Elliott Hughes82be86d2017-09-20 17:00:17 -07002895 failf(data, "Failed to allocate memory for conversion!");
Kristian Monsen5ab50182010-05-14 18:53:44 +01002896 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2897 }
Alex Deymo486467e2017-12-19 19:04:07 +01002898 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002899 /* Curl_convert_from_network calls failf if unsuccessful */
Alex Deymo486467e2017-12-19 19:04:07 +01002900 result = FALSE; /* can't return CURLE_foobar so return FALSE */
Kristian Monsen5ab50182010-05-14 18:53:44 +01002901 }
Alex Deymo486467e2017-12-19 19:04:07 +01002902 else
2903 result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
2904 free(scratch);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002905#else
2906 (void)data; /* unused */
Alex Deymo486467e2017-12-19 19:04:07 +01002907 result = checkprefix("RTSP/", s)? TRUE: FALSE;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002908#endif /* CURL_DOES_CONVERSIONS */
Alex Deymo486467e2017-12-19 19:04:07 +01002909
2910 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002911}
2912#endif /* CURL_DISABLE_RTSP */
2913
2914static bool
Alex Deymoe3149cc2016-10-05 11:18:42 -07002915checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
Kristian Monsen5ab50182010-05-14 18:53:44 +01002916 const char *s)
2917{
2918#ifndef CURL_DISABLE_RTSP
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002919 if(conn->handler->protocol & CURLPROTO_RTSP)
Kristian Monsen5ab50182010-05-14 18:53:44 +01002920 return checkrtspprefix(data, s);
2921#else
2922 (void)conn;
2923#endif /* CURL_DISABLE_RTSP */
2924
2925 return checkhttpprefix(data, s);
2926}
2927
2928/*
2929 * header_append() copies a chunk of data to the end of the already received
2930 * header. We make sure that the full string fit in the allocated header
2931 * buffer, or else we enlarge it.
2932 */
Alex Deymoe3149cc2016-10-05 11:18:42 -07002933static CURLcode header_append(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +01002934 struct SingleRequest *k,
2935 size_t length)
2936{
Elliott Hughescac39802018-04-27 16:19:43 -07002937 size_t newsize = k->hbuflen + length;
2938 if(newsize > CURL_MAX_HTTP_HEADER) {
2939 /* The reason to have a max limit for this is to avoid the risk of a bad
2940 server feeding libcurl with a never-ending header that will cause
2941 reallocs infinitely */
2942 failf(data, "Rejected %zd bytes header (max is %d)!", newsize,
2943 CURL_MAX_HTTP_HEADER);
2944 return CURLE_OUT_OF_MEMORY;
2945 }
2946 if(newsize >= data->state.headersize) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01002947 /* We enlarge the header buffer as it is too small */
2948 char *newbuff;
2949 size_t hbufp_index;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002950
Alex Deymo486467e2017-12-19 19:04:07 +01002951 newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2);
Kristian Monsen5ab50182010-05-14 18:53:44 +01002952 hbufp_index = k->hbufp - data->state.headerbuff;
2953 newbuff = realloc(data->state.headerbuff, newsize);
2954 if(!newbuff) {
Elliott Hughes82be86d2017-09-20 17:00:17 -07002955 failf(data, "Failed to alloc memory for big header!");
Kristian Monsen5ab50182010-05-14 18:53:44 +01002956 return CURLE_OUT_OF_MEMORY;
2957 }
Alex Deymo486467e2017-12-19 19:04:07 +01002958 data->state.headersize = newsize;
Kristian Monsen5ab50182010-05-14 18:53:44 +01002959 data->state.headerbuff = newbuff;
2960 k->hbufp = data->state.headerbuff + hbufp_index;
2961 }
2962 memcpy(k->hbufp, k->str_start, length);
2963 k->hbufp += length;
2964 k->hbuflen += length;
2965 *k->hbufp = 0;
2966
2967 return CURLE_OK;
2968}
2969
Alex Deymoe3149cc2016-10-05 11:18:42 -07002970static void print_http_error(struct Curl_easy *data)
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07002971{
2972 struct SingleRequest *k = &data->req;
2973 char *beg = k->p;
2974
2975 /* make sure that data->req.p points to the HTTP status line */
2976 if(!strncmp(beg, "HTTP", 4)) {
2977
2978 /* skip to HTTP status code */
2979 beg = strchr(beg, ' ');
2980 if(beg && *++beg) {
2981
2982 /* find trailing CR */
2983 char end_char = '\r';
2984 char *end = strchr(beg, end_char);
2985 if(!end) {
2986 /* try to find LF (workaround for non-compliant HTTP servers) */
2987 end_char = '\n';
2988 end = strchr(beg, end_char);
2989 }
2990
2991 if(end) {
2992 /* temporarily replace CR or LF by NUL and print the error message */
2993 *end = '\0';
2994 failf(data, "The requested URL returned error: %s", beg);
2995
2996 /* restore the previously replaced CR or LF */
2997 *end = end_char;
2998 return;
2999 }
3000 }
3001 }
3002
3003 /* fall-back to printing the HTTP status code only */
3004 failf(data, "The requested URL returned error: %d", k->httpcode);
3005}
Kristian Monsen5ab50182010-05-14 18:53:44 +01003006
3007/*
3008 * Read any HTTP header lines from the server and pass them to the client app.
3009 */
Alex Deymoe3149cc2016-10-05 11:18:42 -07003010CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
Kristian Monsen5ab50182010-05-14 18:53:44 +01003011 struct connectdata *conn,
3012 ssize_t *nread,
3013 bool *stop_reading)
3014{
3015 CURLcode result;
3016 struct SingleRequest *k = &data->req;
Elliott Hughes1ef06ba2018-05-30 15:43:58 -07003017 ssize_t onread = *nread;
3018 char *ostr = k->str;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003019
3020 /* header line within buffer loop */
3021 do {
3022 size_t rest_length;
3023 size_t full_length;
3024 int writetype;
3025
3026 /* str_start is start of line within buf */
3027 k->str_start = k->str;
3028
3029 /* data is in network encoding so use 0x0a instead of '\n' */
3030 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
3031
3032 if(!k->end_ptr) {
3033 /* Not a complete header line within buffer, append the data to
3034 the end of the headerbuff. */
3035 result = header_append(data, k, *nread);
3036 if(result)
3037 return result;
3038
3039 if(!k->headerline && (k->hbuflen>5)) {
3040 /* make a first check that this looks like a protocol header */
3041 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
3042 /* this is not the beginning of a protocol first header line */
3043 k->header = FALSE;
3044 k->badheader = HEADER_ALLBAD;
3045 break;
3046 }
3047 }
3048
3049 break; /* read more and try again */
3050 }
3051
3052 /* decrease the size of the remaining (supposed) header line */
Alex Deymo486467e2017-12-19 19:04:07 +01003053 rest_length = (k->end_ptr - k->str) + 1;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003054 *nread -= (ssize_t)rest_length;
3055
3056 k->str = k->end_ptr + 1; /* move past new line */
3057
3058 full_length = k->str - k->str_start;
3059
3060 result = header_append(data, k, full_length);
3061 if(result)
3062 return result;
3063
3064 k->end_ptr = k->hbufp;
3065 k->p = data->state.headerbuff;
3066
3067 /****
3068 * We now have a FULL header line that p points to
3069 *****/
3070
3071 if(!k->headerline) {
3072 /* the first read header */
3073 if((k->hbuflen>5) &&
3074 !checkprotoprefix(data, conn, data->state.headerbuff)) {
3075 /* this is not the beginning of a protocol first header line */
3076 k->header = FALSE;
3077 if(*nread)
3078 /* since there's more, this is a partial bad header */
3079 k->badheader = HEADER_PARTHEADER;
3080 else {
3081 /* this was all we read so it's all a bad header */
3082 k->badheader = HEADER_ALLBAD;
Elliott Hughes1ef06ba2018-05-30 15:43:58 -07003083 *nread = onread;
3084 k->str = ostr;
3085 return CURLE_OK;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003086 }
3087 break;
3088 }
3089 }
3090
3091 /* headers are in network encoding so
3092 use 0x0a and 0x0d instead of '\n' and '\r' */
3093 if((0x0a == *k->p) || (0x0d == *k->p)) {
3094 size_t headerlen;
3095 /* Zero-length header line means end of headers! */
3096
3097#ifdef CURL_DOES_CONVERSIONS
3098 if(0x0d == *k->p) {
3099 *k->p = '\r'; /* replace with CR in host encoding */
3100 k->p++; /* pass the CR byte */
3101 }
3102 if(0x0a == *k->p) {
3103 *k->p = '\n'; /* replace with LF in host encoding */
3104 k->p++; /* pass the LF byte */
3105 }
3106#else
3107 if('\r' == *k->p)
3108 k->p++; /* pass the \r byte */
3109 if('\n' == *k->p)
3110 k->p++; /* pass the \n byte */
3111#endif /* CURL_DOES_CONVERSIONS */
3112
3113 if(100 <= k->httpcode && 199 >= k->httpcode) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003114 /* "A user agent MAY ignore unexpected 1xx status responses." */
3115 switch(k->httpcode) {
3116 case 100:
Elliott Hughescee03382017-06-23 12:17:18 -07003117 /*
3118 * We have made a HTTP PUT or POST and this is 1.1-lingo
3119 * that tells us that the server is OK with this and ready
3120 * to receive the data.
3121 * However, we'll get more headers now so we must get
3122 * back into the header-parsing state!
3123 */
3124 k->header = TRUE;
3125 k->headerline = 0; /* restart the header line counter */
3126
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003127 /* if we did wait for this do enable write now! */
Alex Deymoe3149cc2016-10-05 11:18:42 -07003128 if(k->exp100 > EXP100_SEND_DATA) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003129 k->exp100 = EXP100_SEND_DATA;
3130 k->keepon |= KEEP_SEND;
Elliott Hughes82be86d2017-09-20 17:00:17 -07003131 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003132 }
3133 break;
3134 case 101:
3135 /* Switching Protocols */
3136 if(k->upgr101 == UPGR101_REQUESTED) {
Elliott Hughescee03382017-06-23 12:17:18 -07003137 /* Switching to HTTP/2 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003138 infof(data, "Received 101\n");
3139 k->upgr101 = UPGR101_RECEIVED;
3140
Elliott Hughescee03382017-06-23 12:17:18 -07003141 /* we'll get more headers (HTTP/2 response) */
3142 k->header = TRUE;
3143 k->headerline = 0; /* restart the header line counter */
3144
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003145 /* switch to http2 now. The bytes after response headers
3146 are also processed here, otherwise they are lost. */
3147 result = Curl_http2_switched(conn, k->str, *nread);
3148 if(result)
3149 return result;
3150 *nread = 0;
3151 }
Elliott Hughescee03382017-06-23 12:17:18 -07003152 else {
3153 /* Switching to another protocol (e.g. WebSocket) */
3154 k->header = FALSE; /* no more header to parse! */
3155 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003156 break;
3157 default:
Elliott Hughescee03382017-06-23 12:17:18 -07003158 /* the status code 1xx indicates a provisional response, so
3159 we'll get another set of headers */
3160 k->header = TRUE;
3161 k->headerline = 0; /* restart the header line counter */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003162 break;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003163 }
3164 }
3165 else {
3166 k->header = FALSE; /* no more header to parse! */
3167
3168 if((k->size == -1) && !k->chunk && !conn->bits.close &&
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003169 (conn->httpversion == 11) &&
3170 !(conn->handler->protocol & CURLPROTO_RTSP) &&
3171 data->set.httpreq != HTTPREQ_HEAD) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003172 /* On HTTP 1.1, when connection is not to get closed, but no
Alex Deymo486467e2017-12-19 19:04:07 +01003173 Content-Length nor Transfer-Encoding chunked have been
Kristian Monsen5ab50182010-05-14 18:53:44 +01003174 received, according to RFC2616 section 4.4 point 5, we
3175 assume that the server will close the connection to
3176 signal the end of the document. */
3177 infof(data, "no chunk, no close, no size. Assume close to "
3178 "signal end\n");
Elliott Hughescee03382017-06-23 12:17:18 -07003179 streamclose(conn, "HTTP: No end-of-message indicator");
Kristian Monsen5ab50182010-05-14 18:53:44 +01003180 }
3181 }
3182
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003183 /* At this point we have some idea about the fate of the connection.
3184 If we are closing the connection it may result auth failure. */
3185#if defined(USE_NTLM)
3186 if(conn->bits.close &&
3187 (((data->req.httpcode == 401) &&
3188 (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
3189 ((data->req.httpcode == 407) &&
3190 (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
3191 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3192 data->state.authproblem = TRUE;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003193 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003194#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +01003195
3196 /*
3197 * When all the headers have been parsed, see if we should give
3198 * up and return an error.
3199 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003200 if(http_should_fail(conn)) {
Elliott Hughes82be86d2017-09-20 17:00:17 -07003201 failf(data, "The requested URL returned error: %d",
3202 k->httpcode);
Kristian Monsen5ab50182010-05-14 18:53:44 +01003203 return CURLE_HTTP_RETURNED_ERROR;
3204 }
3205
3206 /* now, only output this if the header AND body are requested:
3207 */
3208 writetype = CLIENTWRITE_HEADER;
3209 if(data->set.include_header)
3210 writetype |= CLIENTWRITE_BODY;
3211
3212 headerlen = k->p - data->state.headerbuff;
3213
3214 result = Curl_client_write(conn, writetype,
3215 data->state.headerbuff,
3216 headerlen);
3217 if(result)
3218 return result;
3219
3220 data->info.header_size += (long)headerlen;
3221 data->req.headerbytecount += (long)headerlen;
3222
3223 data->req.deductheadercount =
3224 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3225
Alex Deymoe3149cc2016-10-05 11:18:42 -07003226 /* Curl_http_auth_act() checks what authentication methods
3227 * that are available and decides which one (if any) to
3228 * use. It will set 'newurl' if an auth method was picked. */
3229 result = Curl_http_auth_act(conn);
Kristian Monsen5ab50182010-05-14 18:53:44 +01003230
Alex Deymoe3149cc2016-10-05 11:18:42 -07003231 if(result)
3232 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003233
Alex Deymoe3149cc2016-10-05 11:18:42 -07003234 if(k->httpcode >= 300) {
3235 if((!conn->bits.authneg) && !conn->bits.close &&
3236 !conn->bits.rewindaftersend) {
3237 /*
3238 * General treatment of errors when about to send data. Including :
3239 * "417 Expectation Failed", while waiting for 100-continue.
3240 *
3241 * The check for close above is done simply because of something
3242 * else has already deemed the connection to get closed then
3243 * something else should've considered the big picture and we
3244 * avoid this check.
3245 *
3246 * rewindaftersend indicates that something has told libcurl to
3247 * continue sending even if it gets discarded
3248 */
3249
3250 switch(data->set.httpreq) {
3251 case HTTPREQ_PUT:
3252 case HTTPREQ_POST:
3253 case HTTPREQ_POST_FORM:
Alex Deymo486467e2017-12-19 19:04:07 +01003254 case HTTPREQ_POST_MIME:
Alex Deymoe3149cc2016-10-05 11:18:42 -07003255 /* We got an error response. If this happened before the whole
3256 * request body has been sent we stop sending and mark the
3257 * connection for closure after we've read the entire response.
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003258 */
Elliott Hughes82be86d2017-09-20 17:00:17 -07003259 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
Alex Deymoe3149cc2016-10-05 11:18:42 -07003260 if(!k->upload_done) {
Elliott Hughescee03382017-06-23 12:17:18 -07003261 if(data->set.http_keep_sending_on_error) {
3262 infof(data, "HTTP error before end of send, keep sending\n");
3263 if(k->exp100 > EXP100_SEND_DATA) {
3264 k->exp100 = EXP100_SEND_DATA;
3265 k->keepon |= KEEP_SEND;
3266 }
3267 }
3268 else {
3269 infof(data, "HTTP error before end of send, stop sending\n");
3270 streamclose(conn, "Stop sending data before everything sent");
3271 k->upload_done = TRUE;
3272 k->keepon &= ~KEEP_SEND; /* don't send */
3273 if(data->state.expect100header)
3274 k->exp100 = EXP100_FAILED;
3275 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003276 }
Alex Deymoe3149cc2016-10-05 11:18:42 -07003277 break;
3278
3279 default: /* default label present to avoid compiler warnings */
3280 break;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003281 }
3282 }
3283
Kristian Monsen5ab50182010-05-14 18:53:44 +01003284 if(conn->bits.rewindaftersend) {
3285 /* We rewind after a complete send, so thus we continue
3286 sending now */
3287 infof(data, "Keep sending data to get tossed away!\n");
3288 k->keepon |= KEEP_SEND;
3289 }
3290 }
3291
3292 if(!k->header) {
3293 /*
3294 * really end-of-headers.
3295 *
3296 * If we requested a "no body", this is a good time to get
3297 * out and return home.
3298 */
3299 if(data->set.opt_no_body)
3300 *stop_reading = TRUE;
Alex Deymod15eaac2016-06-28 14:49:26 -07003301#ifndef CURL_DISABLE_RTSP
3302 else if((conn->handler->protocol & CURLPROTO_RTSP) &&
3303 (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
3304 (k->size <= -1))
3305 /* Respect section 4.4 of rfc2326: If the Content-Length header is
3306 absent, a length 0 must be assumed. It will prevent libcurl from
Alex Deymoe3149cc2016-10-05 11:18:42 -07003307 hanging on DESCRIBE request that got refused for whatever
Alex Deymod15eaac2016-06-28 14:49:26 -07003308 reason */
3309 *stop_reading = TRUE;
3310#endif
Kristian Monsen5ab50182010-05-14 18:53:44 +01003311 else {
3312 /* If we know the expected size of this document, we set the
3313 maximum download size to the size of the expected
3314 document or else, we won't know when to stop reading!
3315
3316 Note that we set the download maximum even if we read a
3317 "Connection: close" header, to make sure that
3318 "Content-Length: 0" still prevents us from attempting to
3319 read the (missing) response-body.
3320 */
3321 /* According to RFC2616 section 4.4, we MUST ignore
3322 Content-Length: headers if we are now receiving data
3323 using chunked Transfer-Encoding.
3324 */
3325 if(k->chunk)
3326 k->maxdownload = k->size = -1;
3327 }
3328 if(-1 != k->size) {
3329 /* We do this operation even if no_body is true, since this
3330 data might be retrieved later with curl_easy_getinfo()
3331 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3332
3333 Curl_pgrsSetDownloadSize(data, k->size);
3334 k->maxdownload = k->size;
3335 }
3336
Elliott Hughes82be86d2017-09-20 17:00:17 -07003337 /* If max download size is *zero* (nothing) we already have
3338 nothing and can safely return ok now! But for HTTP/2, we'd
3339 like to call http2_handle_stream_close to properly close a
3340 stream. In order to do this, we keep reading until we
3341 close the stream. */
3342 if(0 == k->maxdownload
3343#if defined(USE_NGHTTP2)
3344 && !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
3345 conn->httpversion == 20)
3346#endif
3347 )
Kristian Monsen5ab50182010-05-14 18:53:44 +01003348 *stop_reading = TRUE;
3349
3350 if(*stop_reading) {
3351 /* we make sure that this socket isn't read more now */
3352 k->keepon &= ~KEEP_RECV;
3353 }
3354
3355 if(data->set.verbose)
3356 Curl_debug(data, CURLINFO_HEADER_IN,
3357 k->str_start, headerlen, conn);
3358 break; /* exit header line loop */
3359 }
3360
3361 /* We continue reading headers, so reset the line-based
3362 header parsing variables hbufp && hbuflen */
3363 k->hbufp = data->state.headerbuff;
3364 k->hbuflen = 0;
3365 continue;
3366 }
3367
3368 /*
3369 * Checks for special headers coming up.
3370 */
3371
3372 if(!k->headerline++) {
3373 /* This is the first header, it MUST be the error code line
3374 or else we consider this to be the body right away! */
3375 int httpversion_major;
3376 int rtspversion_major;
3377 int nc = 0;
3378#ifdef CURL_DOES_CONVERSIONS
3379#define HEADER1 scratch
3380#define SCRATCHSIZE 21
3381 CURLcode res;
Alex Deymo486467e2017-12-19 19:04:07 +01003382 char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003383 /* We can't really convert this yet because we
3384 don't know if it's the 1st header line or the body.
3385 So we do a partial conversion into a scratch area,
3386 leaving the data at k->p as-is.
3387 */
3388 strncpy(&scratch[0], k->p, SCRATCHSIZE);
3389 scratch[SCRATCHSIZE] = 0; /* null terminate */
3390 res = Curl_convert_from_network(data,
3391 &scratch[0],
3392 SCRATCHSIZE);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003393 if(res)
Kristian Monsen5ab50182010-05-14 18:53:44 +01003394 /* Curl_convert_from_network calls failf if unsuccessful */
3395 return res;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003396#else
3397#define HEADER1 k->p /* no conversion needed, just use k->p */
3398#endif /* CURL_DOES_CONVERSIONS */
3399
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003400 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3401 /*
3402 * https://tools.ietf.org/html/rfc7230#section-3.1.2
3403 *
Elliott Hughes82be86d2017-09-20 17:00:17 -07003404 * The response code is always a three-digit number in HTTP as the spec
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003405 * says. We try to allow any number here, but we cannot make
3406 * guarantees on future behaviors since it isn't within the protocol.
3407 */
Elliott Hughes82be86d2017-09-20 17:00:17 -07003408 char separator;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003409 nc = sscanf(HEADER1,
Elliott Hughes82be86d2017-09-20 17:00:17 -07003410 " HTTP/%1d.%1d%c%3d",
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003411 &httpversion_major,
3412 &conn->httpversion,
Elliott Hughes82be86d2017-09-20 17:00:17 -07003413 &separator,
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003414 &k->httpcode);
Alex Deymoe3149cc2016-10-05 11:18:42 -07003415
3416 if(nc == 1 && httpversion_major == 2 &&
3417 1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
3418 conn->httpversion = 0;
Elliott Hughes82be86d2017-09-20 17:00:17 -07003419 nc = 4;
3420 separator = ' ';
Alex Deymoe3149cc2016-10-05 11:18:42 -07003421 }
3422
Alex Deymo486467e2017-12-19 19:04:07 +01003423 if((nc == 4) && (' ' == separator)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003424 conn->httpversion += 10 * httpversion_major;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003425
3426 if(k->upgr101 == UPGR101_RECEIVED) {
3427 /* supposedly upgraded to http2 now */
3428 if(conn->httpversion != 20)
3429 infof(data, "Lying server, not serving HTTP/2\n");
3430 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01003431 }
Elliott Hughes82be86d2017-09-20 17:00:17 -07003432 else if(!nc) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003433 /* this is the real world, not a Nirvana
3434 NCSA 1.5.x returns this crap when asked for HTTP/1.1
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003435 */
Alex Deymo486467e2017-12-19 19:04:07 +01003436 nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode);
Kristian Monsen5ab50182010-05-14 18:53:44 +01003437 conn->httpversion = 10;
3438
3439 /* If user has set option HTTP200ALIASES,
3440 compare header line against list of aliases
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003441 */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003442 if(!nc) {
3443 if(checkhttpprefix(data, k->p)) {
3444 nc = 1;
3445 k->httpcode = 200;
3446 conn->httpversion = 10;
3447 }
3448 }
3449 }
Elliott Hughes82be86d2017-09-20 17:00:17 -07003450 else {
3451 failf(data, "Unsupported HTTP version in response\n");
3452 return CURLE_UNSUPPORTED_PROTOCOL;
3453 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01003454 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003455 else if(conn->handler->protocol & CURLPROTO_RTSP) {
Alex Deymo486467e2017-12-19 19:04:07 +01003456 char separator;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003457 nc = sscanf(HEADER1,
Alex Deymo486467e2017-12-19 19:04:07 +01003458 " RTSP/%1d.%1d%c%3d",
Kristian Monsen5ab50182010-05-14 18:53:44 +01003459 &rtspversion_major,
3460 &conn->rtspversion,
Alex Deymo486467e2017-12-19 19:04:07 +01003461 &separator,
Kristian Monsen5ab50182010-05-14 18:53:44 +01003462 &k->httpcode);
Alex Deymo486467e2017-12-19 19:04:07 +01003463 if((nc == 4) && (' ' == separator)) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003464 conn->rtspversion += 10 * rtspversion_major;
3465 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3466 }
3467 else {
3468 /* TODO: do we care about the other cases here? */
3469 nc = 0;
3470 }
3471 }
3472
3473 if(nc) {
3474 data->info.httpcode = k->httpcode;
3475
3476 data->info.httpversion = conn->httpversion;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003477 if(!data->state.httpversion ||
3478 data->state.httpversion > conn->httpversion)
Kristian Monsen5ab50182010-05-14 18:53:44 +01003479 /* store the lowest server version we encounter */
3480 data->state.httpversion = conn->httpversion;
3481
3482 /*
3483 * This code executes as part of processing the header. As a
3484 * result, it's not totally clear how to interpret the
3485 * response code yet as that depends on what other headers may
3486 * be present. 401 and 407 may be errors, but may be OK
3487 * depending on how authentication is working. Other codes
3488 * are definitely errors, so give up here.
3489 */
3490 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3491 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3492 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3493
3494 if(data->state.resume_from &&
Alex Deymo486467e2017-12-19 19:04:07 +01003495 (data->set.httpreq == HTTPREQ_GET) &&
Kristian Monsen5ab50182010-05-14 18:53:44 +01003496 (k->httpcode == 416)) {
3497 /* "Requested Range Not Satisfiable", just proceed and
3498 pretend this is no error */
3499 }
3500 else {
3501 /* serious error, go home! */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003502 print_http_error(data);
Kristian Monsen5ab50182010-05-14 18:53:44 +01003503 return CURLE_HTTP_RETURNED_ERROR;
3504 }
3505 }
3506
3507 if(conn->httpversion == 10) {
3508 /* Default action for HTTP/1.0 must be to close, unless
3509 we get one of those fancy headers that tell us the
3510 server keeps it open for us! */
3511 infof(data, "HTTP 1.0, assume close after body\n");
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003512 connclose(conn, "HTTP/1.0 close after body");
3513 }
3514 else if(conn->httpversion == 20 ||
3515 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3516 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
3517
3518 /* HTTP/2 cannot blacklist multiplexing since it is a core
3519 functionality of the protocol */
3520 conn->bundle->multiuse = BUNDLE_MULTIPLEX;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003521 }
3522 else if(conn->httpversion >= 11 &&
3523 !conn->bits.close) {
3524 /* If HTTP version is >= 1.1 and connection is persistent
3525 server supports pipelining. */
3526 DEBUGF(infof(data,
3527 "HTTP 1.1 or later with persistent connection, "
3528 "pipelining supported\n"));
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003529 /* Activate pipelining if needed */
3530 if(conn->bundle) {
3531 if(!Curl_pipeline_site_blacklisted(data, conn))
3532 conn->bundle->multiuse = BUNDLE_PIPELINING;
3533 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01003534 }
3535
3536 switch(k->httpcode) {
3537 case 204:
3538 /* (quote from RFC2616, section 10.2.5): The server has
3539 * fulfilled the request but does not need to return an
3540 * entity-body ... The 204 response MUST NOT include a
3541 * message-body, and thus is always terminated by the first
3542 * empty line after the header fields. */
3543 /* FALLTHROUGH */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003544 case 304:
3545 /* (quote from RFC2616, section 10.3.5): The 304 response
3546 * MUST NOT contain a message-body, and thus is always
3547 * terminated by the first empty line after the header
3548 * fields. */
3549 if(data->set.timecondition)
3550 data->info.timecond = TRUE;
Alex Deymo486467e2017-12-19 19:04:07 +01003551 k->size = 0;
3552 k->maxdownload = 0;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003553 k->ignorecl = TRUE; /* ignore Content-Length headers */
3554 break;
3555 default:
3556 /* nothing */
3557 break;
3558 }
3559 }
3560 else {
3561 k->header = FALSE; /* this is not a header line */
3562 break;
3563 }
3564 }
3565
Kristian Monsen5ab50182010-05-14 18:53:44 +01003566 result = Curl_convert_from_network(data, k->p, strlen(k->p));
Kristian Monsen5ab50182010-05-14 18:53:44 +01003567 /* Curl_convert_from_network calls failf if unsuccessful */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003568 if(result)
3569 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003570
Lucas Eckels9bd90e62012-08-06 15:07:02 -07003571 /* Check for Content-Length: header lines to get size */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003572 if(!k->ignorecl && !data->set.ignorecl &&
3573 checkprefix("Content-Length:", k->p)) {
Alex Deymo486467e2017-12-19 19:04:07 +01003574 curl_off_t contentlength;
Elliott Hughes0128fe42018-02-27 14:57:55 -08003575 CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength);
3576
3577 if(offt == CURL_OFFT_OK) {
Alex Deymo486467e2017-12-19 19:04:07 +01003578 if(data->set.max_filesize &&
3579 contentlength > data->set.max_filesize) {
3580 failf(data, "Maximum file size exceeded");
3581 return CURLE_FILESIZE_EXCEEDED;
3582 }
Elliott Hughes0128fe42018-02-27 14:57:55 -08003583 k->size = contentlength;
3584 k->maxdownload = k->size;
3585 /* we set the progress download size already at this point
3586 just to make it easier for apps/callbacks to extract this
3587 info as soon as possible */
3588 Curl_pgrsSetDownloadSize(data, k->size);
Kristian Monsen5ab50182010-05-14 18:53:44 +01003589 }
Elliott Hughes0128fe42018-02-27 14:57:55 -08003590 else if(offt == CURL_OFFT_FLOW) {
3591 /* out of range */
3592 if(data->set.max_filesize) {
3593 failf(data, "Maximum file size exceeded");
3594 return CURLE_FILESIZE_EXCEEDED;
3595 }
3596 streamclose(conn, "overflow content-length");
3597 infof(data, "Overflow Content-Length: value!\n");
3598 }
3599 else {
3600 /* negative or just rubbish - bad HTTP */
3601 failf(data, "Invalid Content-Length: value");
3602 return CURLE_WEIRD_SERVER_REPLY;
3603 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01003604 }
3605 /* check for Content-Type: header lines to get the MIME-type */
3606 else if(checkprefix("Content-Type:", k->p)) {
3607 char *contenttype = Curl_copy_header_value(k->p);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003608 if(!contenttype)
Kristian Monsen5ab50182010-05-14 18:53:44 +01003609 return CURLE_OUT_OF_MEMORY;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003610 if(!*contenttype)
Kristian Monsen5ab50182010-05-14 18:53:44 +01003611 /* ignore empty data */
3612 free(contenttype);
3613 else {
3614 Curl_safefree(data->info.contenttype);
3615 data->info.contenttype = contenttype;
3616 }
3617 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003618 else if(checkprefix("Server:", k->p)) {
3619 if(conn->httpversion < 20) {
3620 /* only do this for non-h2 servers */
3621 char *server_name = Curl_copy_header_value(k->p);
3622
3623 /* Turn off pipelining if the server version is blacklisted */
3624 if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
3625 if(Curl_pipeline_server_blacklisted(data, server_name))
3626 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
3627 }
3628 free(server_name);
3629 }
3630 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01003631 else if((conn->httpversion == 10) &&
3632 conn->bits.httpproxy &&
3633 Curl_compareheader(k->p,
3634 "Proxy-Connection:", "keep-alive")) {
3635 /*
3636 * When a HTTP/1.0 reply comes when using a proxy, the
3637 * 'Proxy-Connection: keep-alive' line tells us the
3638 * connection will be kept alive for our pleasure.
3639 * Default action for 1.0 is to close.
3640 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003641 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003642 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3643 }
3644 else if((conn->httpversion == 11) &&
3645 conn->bits.httpproxy &&
3646 Curl_compareheader(k->p,
3647 "Proxy-Connection:", "close")) {
3648 /*
3649 * We get a HTTP/1.1 response from a proxy and it says it'll
3650 * close down after this transfer.
3651 */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003652 connclose(conn, "Proxy-Connection: asked to close after done");
Kristian Monsen5ab50182010-05-14 18:53:44 +01003653 infof(data, "HTTP/1.1 proxy connection set close!\n");
3654 }
3655 else if((conn->httpversion == 10) &&
3656 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3657 /*
3658 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3659 * tells us the connection will be kept alive for our
3660 * pleasure. Default action for 1.0 is to close.
3661 *
3662 * [RFC2068, section 19.7.1] */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003663 connkeep(conn, "Connection keep-alive");
Kristian Monsen5ab50182010-05-14 18:53:44 +01003664 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3665 }
3666 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3667 /*
3668 * [RFC 2616, section 8.1.2.1]
3669 * "Connection: close" is HTTP/1.1 language and means that
3670 * the connection will close when this request has been
3671 * served.
3672 */
Elliott Hughescee03382017-06-23 12:17:18 -07003673 streamclose(conn, "Connection: close used");
Kristian Monsen5ab50182010-05-14 18:53:44 +01003674 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003675 else if(checkprefix("Transfer-Encoding:", k->p)) {
3676 /* One or more encodings. We check for chunked and/or a compression
3677 algorithm. */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003678 /*
3679 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3680 * means that the server will send a series of "chunks". Each
3681 * chunk starts with line with info (including size of the
3682 * coming block) (terminated with CRLF), then a block of data
3683 * with the previously mentioned size. There can be any amount
3684 * of chunks, and a chunk-data set to zero signals the
3685 * end-of-chunks. */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003686
Alex Deymo486467e2017-12-19 19:04:07 +01003687 result = Curl_build_unencoding_stack(conn, k->p + 18, TRUE);
3688 if(result)
3689 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003690 }
Kristian Monsen5ab50182010-05-14 18:53:44 +01003691 else if(checkprefix("Content-Encoding:", k->p) &&
Alex Deymod15eaac2016-06-28 14:49:26 -07003692 data->set.str[STRING_ENCODING]) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003693 /*
3694 * Process Content-Encoding. Look for the values: identity,
3695 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3696 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3697 * 2616). zlib cannot handle compress. However, errors are
3698 * handled further down when the response body is processed
3699 */
Alex Deymo486467e2017-12-19 19:04:07 +01003700 result = Curl_build_unencoding_stack(conn, k->p + 17, FALSE);
3701 if(result)
3702 return result;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003703 }
3704 else if(checkprefix("Content-Range:", k->p)) {
3705 /* Content-Range: bytes [num]-
3706 Content-Range: bytes: [num]-
3707 Content-Range: [num]-
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003708 Content-Range: [asterisk]/[total]
Kristian Monsen5ab50182010-05-14 18:53:44 +01003709
3710 The second format was added since Sun's webserver
3711 JavaWebServer/1.1.1 obviously sends the header this way!
3712 The third added since some servers use that!
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003713 The forth means the requested range was unsatisfied.
Kristian Monsen5ab50182010-05-14 18:53:44 +01003714 */
3715
3716 char *ptr = k->p + 14;
3717
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003718 /* Move forward until first digit or asterisk */
3719 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
Kristian Monsen5ab50182010-05-14 18:53:44 +01003720 ptr++;
3721
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003722 /* if it truly stopped on a digit */
3723 if(ISDIGIT(*ptr)) {
Alex Deymo486467e2017-12-19 19:04:07 +01003724 if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) {
3725 if(data->state.resume_from == k->offset)
3726 /* we asked for a resume and we got it */
3727 k->content_range = TRUE;
3728 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003729 }
3730 else
3731 data->state.resume_from = 0; /* get everything */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003732 }
3733#if !defined(CURL_DISABLE_COOKIES)
3734 else if(data->cookies &&
3735 checkprefix("Set-Cookie:", k->p)) {
3736 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3737 CURL_LOCK_ACCESS_SINGLE);
3738 Curl_cookie_add(data,
Elliott Hughes1ef06ba2018-05-30 15:43:58 -07003739 data->cookies, TRUE, FALSE, k->p + 11,
Kristian Monsen5ab50182010-05-14 18:53:44 +01003740 /* If there is a custom-set Host: name, use it
3741 here, or else use real peer host name. */
3742 conn->allocptr.cookiehost?
3743 conn->allocptr.cookiehost:conn->host.name,
3744 data->state.path);
3745 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3746 }
3747#endif
3748 else if(checkprefix("Last-Modified:", k->p) &&
3749 (data->set.timecondition || data->set.get_filetime) ) {
Alex Deymo486467e2017-12-19 19:04:07 +01003750 time_t secs = time(NULL);
3751 k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
Kristian Monsen5ab50182010-05-14 18:53:44 +01003752 &secs);
3753 if(data->set.get_filetime)
Elliott Hughescac39802018-04-27 16:19:43 -07003754 data->info.filetime = k->timeofdoc;
Kristian Monsen5ab50182010-05-14 18:53:44 +01003755 }
3756 else if((checkprefix("WWW-Authenticate:", k->p) &&
3757 (401 == k->httpcode)) ||
3758 (checkprefix("Proxy-authenticate:", k->p) &&
3759 (407 == k->httpcode))) {
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003760
3761 bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3762 char *auth = Curl_copy_header_value(k->p);
3763 if(!auth)
3764 return CURLE_OUT_OF_MEMORY;
3765
3766 result = Curl_http_input_auth(conn, proxy, auth);
3767
3768 free(auth);
3769
Kristian Monsen5ab50182010-05-14 18:53:44 +01003770 if(result)
3771 return result;
3772 }
3773 else if((k->httpcode >= 300 && k->httpcode < 400) &&
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003774 checkprefix("Location:", k->p) &&
3775 !data->req.location) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003776 /* this is the URL that the server advises us to use instead */
3777 char *location = Curl_copy_header_value(k->p);
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003778 if(!location)
Kristian Monsen5ab50182010-05-14 18:53:44 +01003779 return CURLE_OUT_OF_MEMORY;
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003780 if(!*location)
Kristian Monsen5ab50182010-05-14 18:53:44 +01003781 /* ignore empty data */
3782 free(location);
3783 else {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003784 data->req.location = location;
3785
3786 if(data->set.http_follow_location) {
3787 DEBUGASSERT(!data->req.newurl);
3788 data->req.newurl = strdup(data->req.location); /* clone */
3789 if(!data->req.newurl)
3790 return CURLE_OUT_OF_MEMORY;
3791
3792 /* some cases of POST and PUT etc needs to rewind the data
3793 stream at this point */
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003794 result = http_perhapsrewind(conn);
Kristian Monsen5ab50182010-05-14 18:53:44 +01003795 if(result)
3796 return result;
3797 }
3798 }
3799 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003800 else if(conn->handler->protocol & CURLPROTO_RTSP) {
Kristian Monsen5ab50182010-05-14 18:53:44 +01003801 result = Curl_rtsp_parseheader(conn, k->p);
3802 if(result)
3803 return result;
3804 }
Bertrand SIMONNETe6cd7382015-07-01 15:39:44 -07003805
Kristian Monsen5ab50182010-05-14 18:53:44 +01003806 /*
3807 * End of header-checks. Write them to the client.
3808 */
3809
3810 writetype = CLIENTWRITE_HEADER;
3811 if(data->set.include_header)
3812 writetype |= CLIENTWRITE_BODY;
3813
3814 if(data->set.verbose)
3815 Curl_debug(data, CURLINFO_HEADER_IN,
3816 k->p, (size_t)k->hbuflen, conn);
3817
3818 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3819 if(result)
3820 return result;
3821
3822 data->info.header_size += (long)k->hbuflen;
3823 data->req.headerbytecount += (long)k->hbuflen;
3824
3825 /* reset hbufp pointer && hbuflen */
3826 k->hbufp = data->state.headerbuff;
3827 k->hbuflen = 0;
3828 }
Alex Deymoe3149cc2016-10-05 11:18:42 -07003829 while(*k->str); /* header line within buffer */
Kristian Monsen5ab50182010-05-14 18:53:44 +01003830
3831 /* We might have reached the end of the header part here, but
3832 there might be a non-header part left in the end of the read
3833 buffer. */
3834
3835 return CURLE_OK;
3836}
3837
3838#endif /* CURL_DISABLE_HTTP */