http.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 #include "curl_setup.h"
24 
25 #ifndef CURL_DISABLE_HTTP
26 
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
29 #endif
30 
31 #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 
48 #include "urldata.h"
49 #include <curl/curl.h>
50 #include "transfer.h"
51 #include "sendf.h"
52 #include "formdata.h"
53 #include "mime.h"
54 #include "progress.h"
55 #include "curl_base64.h"
56 #include "cookie.h"
57 #include "vauth/vauth.h"
58 #include "vtls/vtls.h"
59 #include "http_digest.h"
60 #include "http_ntlm.h"
61 #include "curl_ntlm_wb.h"
62 #include "http_negotiate.h"
63 #include "url.h"
64 #include "share.h"
65 #include "hostip.h"
66 #include "http.h"
67 #include "select.h"
68 #include "parsedate.h" /* for the week day and month names */
69 #include "strtoofft.h"
70 #include "multiif.h"
71 #include "strcase.h"
72 #include "content_encoding.h"
73 #include "http_proxy.h"
74 #include "warnless.h"
75 #include "non-ascii.h"
76 #include "conncache.h"
77 #include "pipeline.h"
78 #include "http2.h"
79 #include "connect.h"
80 #include "strdup.h"
81 
82 /* The last 3 #include files should be in this order */
83 #include "curl_printf.h"
84 #include "curl_memory.h"
85 #include "memdebug.h"
86 
87 /*
88  * Forward declarations.
89  */
90 
91 static int http_getsock_do(struct connectdata *conn,
92  curl_socket_t *socks,
93  int numsocks);
94 static int http_should_fail(struct connectdata *conn);
95 
96 #ifdef USE_SSL
97 static CURLcode https_connecting(struct connectdata *conn, bool *done);
98 static int https_getsock(struct connectdata *conn,
99  curl_socket_t *socks,
100  int numsocks);
101 #else
102 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
103 #endif
104 
105 /*
106  * HTTP handler interface.
107  */
109  "HTTP", /* scheme */
110  Curl_http_setup_conn, /* setup_connection */
111  Curl_http, /* do_it */
112  Curl_http_done, /* done */
113  ZERO_NULL, /* do_more */
114  Curl_http_connect, /* connect_it */
115  ZERO_NULL, /* connecting */
116  ZERO_NULL, /* doing */
117  ZERO_NULL, /* proto_getsock */
118  http_getsock_do, /* doing_getsock */
119  ZERO_NULL, /* domore_getsock */
120  ZERO_NULL, /* perform_getsock */
121  ZERO_NULL, /* disconnect */
122  ZERO_NULL, /* readwrite */
123  ZERO_NULL, /* connection_check */
124  PORT_HTTP, /* defport */
125  CURLPROTO_HTTP, /* protocol */
126  PROTOPT_CREDSPERREQUEST /* flags */
127 };
128 
129 #ifdef USE_SSL
130 /*
131  * HTTPS handler interface.
132  */
133 const struct Curl_handler Curl_handler_https = {
134  "HTTPS", /* scheme */
135  Curl_http_setup_conn, /* setup_connection */
136  Curl_http, /* do_it */
137  Curl_http_done, /* done */
138  ZERO_NULL, /* do_more */
139  Curl_http_connect, /* connect_it */
140  https_connecting, /* connecting */
141  ZERO_NULL, /* doing */
142  https_getsock, /* proto_getsock */
143  http_getsock_do, /* doing_getsock */
144  ZERO_NULL, /* domore_getsock */
145  ZERO_NULL, /* perform_getsock */
146  ZERO_NULL, /* disconnect */
147  ZERO_NULL, /* readwrite */
148  ZERO_NULL, /* connection_check */
149  PORT_HTTPS, /* defport */
150  CURLPROTO_HTTPS, /* protocol */
152 };
153 #endif
154 
156 {
157  /* allocate the HTTP-specific struct for the Curl_easy, only to survive
158  during this request */
159  struct HTTP *http;
160  DEBUGASSERT(conn->data->req.protop == NULL);
161 
162  http = calloc(1, sizeof(struct HTTP));
163  if(!http)
164  return CURLE_OUT_OF_MEMORY;
165 
166  Curl_mime_initpart(&http->form, conn->data);
167  conn->data->req.protop = http;
168 
169  Curl_http2_setup_conn(conn);
170  Curl_http2_setup_req(conn->data);
171 
172  return CURLE_OK;
173 }
174 
175 
176 /*
177  * checkProxyHeaders() checks the linked list of custom proxy headers
178  * if proxy headers are not available, then it will lookup into http header
179  * link list
180  *
181  * It takes a connectdata struct as input instead of the Curl_easy simply
182  * to know if this is a proxy request or not, as it then might check a
183  * different header list.
184  */
185 char *Curl_checkProxyheaders(const struct connectdata *conn,
186  const char *thisheader)
187 {
188  struct curl_slist *head;
189  size_t thislen = strlen(thisheader);
190  struct Curl_easy *data = conn->data;
191 
192  for(head = (conn->bits.proxy && data->set.sep_headers) ?
193  data->set.proxyheaders : data->set.headers;
194  head; head = head->next) {
195  if(strncasecompare(head->data, thisheader, thislen))
196  return head->data;
197  }
198 
199  return NULL;
200 }
201 
202 /*
203  * Strip off leading and trailing whitespace from the value in the
204  * given HTTP header line and return a strdupped copy. Returns NULL in
205  * case of allocation failure. Returns an empty string if the header value
206  * consists entirely of whitespace.
207  */
208 char *Curl_copy_header_value(const char *header)
209 {
210  const char *start;
211  const char *end;
212  char *value;
213  size_t len;
214 
215  DEBUGASSERT(header);
216 
217  /* Find the end of the header name */
218  while(*header && (*header != ':'))
219  ++header;
220 
221  if(*header)
222  /* Skip over colon */
223  ++header;
224 
225  /* Find the first non-space letter */
226  start = header;
227  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 */
245  len = end - start + 1;
246 
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  */
263 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
264 {
265  size_t size = 0;
266  char *authorization = NULL;
267  struct Curl_easy *data = conn->data;
268  char **userp;
269  const char *user;
270  const char *pwd;
272  char *out;
273 
274  if(proxy) {
275  userp = &conn->allocptr.proxyuserpwd;
276  user = conn->http_proxy.user;
277  pwd = conn->http_proxy.passwd;
278  }
279  else {
280  userp = &conn->allocptr.userpwd;
281  user = conn->user;
282  pwd = conn->passwd;
283  }
284 
285  out = aprintf("%s:%s", user, pwd);
286  if(!out)
287  return CURLE_OUT_OF_MEMORY;
288 
289  result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
290  if(result)
291  goto fail;
292 
293  if(!authorization) {
295  goto fail;
296  }
297 
298  free(*userp);
299  *userp = aprintf("%sAuthorization: Basic %s\r\n",
300  proxy ? "Proxy-" : "",
301  authorization);
302  free(authorization);
303  if(!*userp) {
304  result = CURLE_OUT_OF_MEMORY;
305  goto fail;
306  }
307 
308  fail:
309  free(out);
310  return result;
311 }
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  */
318 static bool pickoneauth(struct auth *pick)
319 {
320  bool picked;
321  /* only deal with authentication we want */
322  unsigned long avail = pick->avail & pick->want;
323  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. */
327  if(avail & CURLAUTH_NEGOTIATE)
328  pick->picked = CURLAUTH_NEGOTIATE;
329  else if(avail & CURLAUTH_DIGEST)
330  pick->picked = CURLAUTH_DIGEST;
331  else if(avail & CURLAUTH_NTLM)
332  pick->picked = CURLAUTH_NTLM;
333  else if(avail & CURLAUTH_NTLM_WB)
334  pick->picked = CURLAUTH_NTLM_WB;
335  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  */
370 {
371  struct Curl_easy *data = conn->data;
372  struct HTTP *http = data->req.protop;
373  curl_off_t bytessent;
374  curl_off_t expectsend = -1; /* default is unknown */
375 
376  if(!http)
377  /* If this is still NULL, we have not reach very far and we can safely
378  skip this rewinding stuff */
379  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 
391  if(conn->bits.authneg) {
392  /* This is a state where we are known to be negotiating and we don't send
393  any data then. */
394  expectsend = 0;
395  }
396  else if(!conn->bits.protoconnstart) {
397  /* HTTP CONNECT in progress: there is no body */
398  expectsend = 0;
399  }
400  else {
401  /* figure out how much data we are expected to send */
402  switch(data->set.httpreq) {
403  case HTTPREQ_POST:
404  if(data->state.infilesize != -1)
405  expectsend = data->state.infilesize;
406  break;
407  case HTTPREQ_PUT:
408  if(data->state.infilesize != -1)
409  expectsend = data->state.infilesize;
410  break;
411  case HTTPREQ_POST_FORM:
412  case HTTPREQ_POST_MIME:
413  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)) {
423 #if defined(USE_NTLM)
424  /* There is still data left to send */
425  if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
426  (data->state.authhost.picked == CURLAUTH_NTLM) ||
427  (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
428  (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
429  if(((expectsend - bytessent) < 2000) ||
430  (conn->ntlm.state != NTLMSTATE_NONE) ||
431  (conn->proxyntlm.state != NTLMSTATE_NONE)) {
432  /* 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! */
436  if(!conn->bits.authneg) {
437  conn->bits.rewindaftersend = TRUE;
438  infof(data, "Rewind stream after send\n");
439  }
440 
441  return CURLE_OK;
442  }
443 
444  if(conn->bits.close)
445  /* this is already marked to get closed */
446  return CURLE_OK;
447 
448  infof(data, "NTLM send, close instead of sending %"
449  CURL_FORMAT_CURL_OFF_T " bytes\n",
450  (curl_off_t)(expectsend - bytessent));
451  }
452 #endif
453 
454  /* This is not NTLM or many bytes left to send: close */
455  streamclose(conn, "Mid-auth HTTP and much data left to send");
456  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 
477 {
478  struct Curl_easy *data = conn->data;
479  bool pickhost = FALSE;
480  bool pickproxy = FALSE;
482 
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)
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) {
517  result = http_perhapsrewind(conn);
518  if(result)
519  return result;
520  }
521  }
522  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  }
537  if(http_should_fail(conn)) {
538  failf(data, "The requested URL returned error: %d",
539  data->req.httpcode);
540  result = CURLE_HTTP_RETURNED_ERROR;
541  }
542 
543  return result;
544 }
545 
546 /*
547  * Output the correct authentication header depending on the auth type
548  * and whether or not it is to a proxy.
549  */
550 static CURLcode
552  struct auth *authstatus,
553  const char *request,
554  const char *path,
555  bool proxy)
556 {
557  const char *auth = NULL;
559 #if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
560  struct Curl_easy *data = conn->data;
561 #endif
562 #ifdef USE_SPNEGO
563  struct negotiatedata *negdata = proxy ?
564  &data->state.proxyneg : &data->state.negotiate;
565 #endif
566 
567 #ifdef CURL_DISABLE_CRYPTO_AUTH
568  (void)request;
569  (void)path;
570 #endif
571 
572 #ifdef USE_SPNEGO
573  negdata->state = GSS_AUTHNONE;
574  if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
575  negdata->context && !GSS_ERROR(negdata->status)) {
576  auth = "Negotiate";
577  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) {
587  auth = "NTLM";
588  result = Curl_output_ntlm(conn, proxy);
589  if(result)
590  return result;
591  }
592  else
593 #endif
594 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
595  if(authstatus->picked == CURLAUTH_NTLM_WB) {
596  auth = "NTLM_WB";
597  result = Curl_output_ntlm_wb(conn, proxy);
598  if(result)
599  return result;
600  }
601  else
602 #endif
603 #ifndef CURL_DISABLE_CRYPTO_AUTH
604  if(authstatus->picked == CURLAUTH_DIGEST) {
605  auth = "Digest";
606  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 &&
618  !Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
619  (!proxy && conn->bits.user_passwd &&
620  !Curl_checkheaders(conn, "Authorization:"))) {
621  auth = "Basic";
622  result = http_output_basic(conn, proxy);
623  if(result)
624  return result;
625  }
626 
627  /* 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",
634  proxy ? "Proxy" : "Server", auth,
635  proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
636  (conn->user ? conn->user : ""));
637  authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
638  }
639  else
640  authstatus->multipass = FALSE;
641 
642  return CURLE_OK;
643 }
644 
659 CURLcode
661  const char *request,
662  const char *path,
663  bool proxytunnel) /* TRUE if this is the request setting
664  up the proxy tunnel */
665 {
667  struct Curl_easy *data = conn->data;
668  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)
678  /* continue please */;
679  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 ||
719  strcasecompare(data->state.first_host, conn->host.name)) {
720  result = output_auth_headers(conn, authhost, request, path, FALSE);
721  }
722  else
723  authhost->done = TRUE;
724 
725  return result;
726 }
727 
728 /*
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 
734 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
735  const char *auth) /* the first non-space */
736 {
737  /*
738  * This resource requires authentication
739  */
740  struct Curl_easy *data = conn->data;
741 
742 #ifdef USE_SPNEGO
743  struct negotiatedata *negdata = proxy?
744  &data->state.proxyneg:&data->state.negotiate;
745 #endif
746  unsigned long *availp;
747  struct auth *authp;
748 
749  if(proxy) {
750  availp = &data->info.proxyauthavail;
751  authp = &data->state.authproxy;
752  }
753  else {
754  availp = &data->info.httpauthavail;
755  authp = &data->state.authhost;
756  }
757 
758  /*
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).
772  */
773 
774  while(*auth) {
775 #ifdef USE_SPNEGO
776  if(checkprefix("Negotiate", auth)) {
777  if((authp->avail & CURLAUTH_NEGOTIATE) ||
778  Curl_auth_is_spnego_supported()) {
779  *availp |= CURLAUTH_NEGOTIATE;
780  authp->avail |= CURLAUTH_NEGOTIATE;
781 
782  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;
797  }
798  }
799  }
800  }
801  else
802 #endif
803 #ifdef USE_NTLM
804  /* NTLM support requires the SSL crypto libs */
805  if(checkprefix("NTLM", auth)) {
806  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;
811 
812  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 */
827  while(*auth && ISSPACE(*auth))
828  auth++;
829  if(checkprefix("NTLM", auth)) {
830  auth += strlen("NTLM");
831  while(*auth && ISSPACE(*auth))
832  auth++;
833  if(*auth) {
834  conn->challenge_header = strdup(auth);
835  if(!conn->challenge_header)
836  return CURLE_OUT_OF_MEMORY;
837  }
838  }
839  }
840 #endif
841  }
842  else {
843  infof(data, "Authentication problem. Ignoring this.\n");
844  data->state.authproblem = TRUE;
845  }
846  }
847  }
848  }
849  else
850 #endif
851 #ifndef CURL_DISABLE_CRYPTO_AUTH
852  if(checkprefix("Digest", auth)) {
853  if((authp->avail & CURLAUTH_DIGEST) != 0)
854  infof(data, "Ignoring duplicate digest auth header.\n");
855  else if(Curl_auth_is_digest_supported()) {
857 
858  *availp |= CURLAUTH_DIGEST;
859  authp->avail |= CURLAUTH_DIGEST;
860 
861  /* We call this function on input Digest headers even if Digest
862  * authentication isn't activated yet, as we need to store the
863  * incoming data from this header in case we are going to use
864  * Digest */
865  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  }
895 
896  return CURLE_OK;
897 }
898 
909 static int http_should_fail(struct connectdata *conn)
910 {
911  struct Curl_easy *data;
912  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 
933  /*
934  ** Any code >= 400 that's not 401 or 407 is always
935  ** a terminal error
936  */
937  if((httpcode != 401) && (httpcode != 407))
938  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  */
958 
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  */
979 static size_t readmoredata(char *buffer,
980  size_t size,
981  size_t nitems,
982  void *userp)
983 {
984  struct connectdata *conn = (struct connectdata *)userp;
985  struct HTTP *http = conn->data->req.protop;
986  size_t fullsize = size * nitems;
987 
988  if(!http->postsize)
989  /* nothing to return */
990  return 0;
991 
992  /* make sure that a HTTP request is never sent away chunked! */
993  conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
994 
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;
1003  conn->data->state.fread_func = http->backup.fread_func;
1004  conn->data->state.in = http->backup.fread_in;
1005 
1006  http->sending++; /* move one step up */
1007 
1008  http->backup.postsize = 0;
1009  }
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  */
1030 {
1031  return calloc(1, sizeof(Curl_send_buffer));
1032 }
1033 
1034 /*
1035  * Curl_add_buffer_free() frees all associated resources.
1036  */
1038 {
1039  if(buff) /* deal with NULL input */
1040  free(buff->buffer);
1041  free(buff);
1042 }
1043 
1044 /*
1045  * 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  */
1051  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)
1060 
1061 {
1062  ssize_t amount;
1063  CURLcode result;
1064  char *ptr;
1065  size_t size;
1066  struct HTTP *http = conn->data->req.protop;
1067  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 
1086  result = Curl_convert_to_network(conn->data, ptr, headersize);
1087  /* Curl_convert_to_network calls failf if unsuccessful */
1088  if(result) {
1089  /* conversion failed, free memory and return to the caller */
1091  return result;
1092  }
1093 
1094  if((conn->handler->flags & PROTOPT_SSL ||
1096  && conn->httpversion != 20) {
1097  /* 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 
1103  sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE);
1104 
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 
1117  result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1118 
1119  if(!result) {
1120  /*
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 */
1126  size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
1127  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);
1132  if(bodylen) {
1133  /* there was body data sent beyond the initial header part, pass that
1134  on to the debug callback too */
1136  ptr + headlen, bodylen, conn);
1137  }
1138  }
1139 
1140  /* '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;
1144 
1145  if(http) {
1146  /* if we sent a piece of the body here, up the byte counter for it
1147  accordingly */
1148  http->writebytecount += bodylen;
1149 
1150  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 */
1160  http->backup.fread_func = conn->data->state.fread_func;
1161  http->backup.fread_in = conn->data->state.in;
1162  http->backup.postdata = http->postdata;
1163  http->backup.postsize = http->postsize;
1164 
1165  /* set the new pointers for the request-sending */
1167  conn->data->state.in = (void *)conn;
1168  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;
1190  }
1191  }
1193 
1194  return result;
1195 }
1196 
1197 
1198 /*
1199  * add_bufferf() add the formatted input to the buffer.
1200  */
1201 CURLcode 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 */
1215  free(in->buffer);
1216  free(in);
1217  return CURLE_OUT_OF_MEMORY;
1218 }
1219 
1220 /*
1221  * add_buffer() appends a memory chunk to the existing buffer
1222  */
1223 CURLcode 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 
1244  if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
1245  (~(size * 2) < (in->size_used * 2)))
1246  new_size = (size_t)-1;
1247  else
1248  new_size = (in->size_used + size) * 2;
1249 
1250  if(in->buffer)
1251  /* we have a buffer, enlarge the existing one */
1252  new_rb = Curl_saferealloc(in->buffer, new_size);
1253  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 */
1259  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  */
1284 bool
1285 Curl_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 
1300  if(!strncasecompare(headerline, header, hlen))
1301  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 */
1325  for(; len >= clen; len--, start++) {
1326  if(strncasecompare(start, content, clen))
1327  return TRUE; /* match! */
1328  }
1329 
1330  return FALSE; /* no match */
1331 }
1332 
1333 /*
1334  * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1335  * the generic Curl_connect().
1336  */
1337 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1338 {
1339  CURLcode result;
1340 
1341  /* 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. */
1343  connkeep(conn, "HTTP default");
1344 
1345  /* the CONNECT procedure might not have been completed */
1346  result = Curl_proxy_connect(conn, FIRSTSOCKET);
1347  if(result)
1348  return result;
1349 
1350  if(conn->bits.proxy_connect_closed)
1351  /* this is not an error, just part of the connection negotiation */
1352  return CURLE_OK;
1353 
1355  return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
1356 
1357  if(Curl_connect_ongoing(conn))
1358  /* nothing else to do except wait right now - we're not done here. */
1359  return CURLE_OK;
1360 
1361  if(conn->given->protocol & CURLPROTO_HTTPS) {
1362  /* perform SSL initialization */
1363  result = https_connecting(conn, done);
1364  if(result)
1365  return result;
1366  }
1367  else
1368  *done = TRUE;
1369 
1370  return CURLE_OK;
1371 }
1372 
1373 /* this returns the socket to wait for in the DO and DOING state for the multi
1374  interface and then we're always _sending_ a request and thus we wait for
1375  the single socket to become writable only */
1376 static int http_getsock_do(struct connectdata *conn,
1377  curl_socket_t *socks,
1378  int numsocks)
1379 {
1380  /* write mode */
1381  (void)numsocks; /* unused, we trust it to be at least 1 */
1382  socks[0] = conn->sock[FIRSTSOCKET];
1383  return GETSOCK_WRITESOCK(0);
1384 }
1385 
1386 #ifdef USE_SSL
1387 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1388 {
1389  CURLcode result;
1390  DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1391 
1392  /* perform SSL initialization for this socket */
1393  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1394  if(result)
1395  connclose(conn, "Failed HTTPS connection");
1396 
1397  return result;
1398 }
1399 
1400 static int https_getsock(struct connectdata *conn,
1401  curl_socket_t *socks,
1402  int numsocks)
1403 {
1404  if(conn->handler->flags & PROTOPT_SSL)
1405  return Curl_ssl_getsock(conn, socks, numsocks);
1406  return GETSOCK_BLANK;
1407 }
1408 #endif /* USE_SSL */
1409 
1410 /*
1411  * Curl_http_done() gets called after a single HTTP request has been
1412  * performed.
1413  */
1414 
1416  CURLcode status, bool premature)
1417 {
1418  struct Curl_easy *data = conn->data;
1419  struct HTTP *http = data->req.protop;
1420 
1421  /* Clear multipass flag. If authentication isn't done yet, then it will get
1422  * a chance to be set back to true when we output the next auth header */
1423  data->state.authhost.multipass = FALSE;
1424  data->state.authproxy.multipass = FALSE;
1425 
1426  Curl_unencode_cleanup(conn);
1427 
1428 #ifdef USE_SPNEGO
1429  if(data->state.proxyneg.state == GSS_AUTHSENT ||
1430  data->state.negotiate.state == GSS_AUTHSENT) {
1431  /* add forbid re-use if http-code != 401/407 as a WA only needed for
1432  * 401/407 that signal auth failure (empty) otherwise state will be RECV
1433  * with current code.
1434  * Do not close CONNECT_ONLY connections. */
1435  if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1436  !data->set.connect_only)
1437  streamclose(conn, "Negotiate transfer completed");
1438  Curl_cleanup_negotiate(data);
1439  }
1440 #endif
1441 
1442  /* set the proper values (possibly modified on POST) */
1443  conn->seek_func = data->set.seek_func; /* restore */
1444  conn->seek_client = data->set.seek_client; /* restore */
1445 
1446  if(!http)
1447  return CURLE_OK;
1448 
1449  if(http->send_buffer) {
1451  http->send_buffer = NULL; /* clear the pointer */
1452  }
1453 
1454  Curl_http2_done(conn, premature);
1455 
1456  Curl_mime_cleanpart(&http->form);
1457 
1458  switch(data->set.httpreq) {
1459  case HTTPREQ_PUT:
1460  case HTTPREQ_POST_FORM:
1461  case HTTPREQ_POST_MIME:
1462  data->req.bytecount = http->readbytecount + http->writebytecount;
1463  break;
1464  default:
1465  break;
1466  }
1467 
1468  if(status)
1469  return status;
1470 
1471  if(!premature && /* this check is pointless when DONE is called before the
1472  entire operation is complete */
1473  !conn->bits.retry &&
1474  !data->set.connect_only &&
1475  (http->readbytecount +
1476  data->req.headerbytecount -
1477  data->req.deductheadercount) <= 0) {
1478  /* If this connection isn't simply closed to be retried, AND nothing was
1479  read from the HTTP server (that counts), this can't be right so we
1480  return an error here */
1481  failf(data, "Empty reply from server");
1482  return CURLE_GOT_NOTHING;
1483  }
1484 
1485  return CURLE_OK;
1486 }
1487 
1488 /*
1489  * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1490  * to avoid it include:
1491  *
1492  * - if the user specifically requested HTTP 1.0
1493  * - if the server we are connected to only supports 1.0
1494  * - if any server previously contacted to handle this request only supports
1495  * 1.0.
1496  */
1497 static bool use_http_1_1plus(const struct Curl_easy *data,
1498  const struct connectdata *conn)
1499 {
1500  if((data->state.httpversion == 10) || (conn->httpversion == 10))
1501  return FALSE;
1502  if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
1503  (conn->httpversion <= 10))
1504  return FALSE;
1505  return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
1507 }
1508 
1509 static const char *get_http_string(const struct Curl_easy *data,
1510  const struct connectdata *conn)
1511 {
1512 #ifdef USE_NGHTTP2
1513  if(conn->proto.httpc.h2)
1514  return "2";
1515 #endif
1516 
1517  if(use_http_1_1plus(data, conn))
1518  return "1.1";
1519 
1520  return "1.0";
1521 }
1522 
1523 /* check and possibly add an Expect: header */
1525  struct connectdata *conn,
1526  Curl_send_buffer *req_buffer)
1527 {
1529  const char *ptr;
1530  data->state.expect100header = FALSE; /* default to false unless it is set
1531  to TRUE below */
1532  if(use_http_1_1plus(data, conn) &&
1533  (conn->httpversion != 20)) {
1534  /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1535  Expect: 100-continue to the headers which actually speeds up post
1536  operations (as there is one packet coming back from the web server) */
1537  ptr = Curl_checkheaders(conn, "Expect:");
1538  if(ptr) {
1539  data->state.expect100header =
1540  Curl_compareheader(ptr, "Expect:", "100-continue");
1541  }
1542  else {
1543  result = Curl_add_bufferf(req_buffer,
1544  "Expect: 100-continue\r\n");
1545  if(!result)
1546  data->state.expect100header = TRUE;
1547  }
1548  }
1549 
1550  return result;
1551 }
1552 
1554  HEADER_SERVER, /* direct to server */
1555  HEADER_PROXY, /* regular request to proxy */
1556  HEADER_CONNECT /* sending CONNECT to a proxy */
1557 };
1558 
1560  bool is_connect,
1561  Curl_send_buffer *req_buffer)
1562 {
1563  char *ptr;
1564  struct curl_slist *h[2];
1565  struct curl_slist *headers;
1566  int numlists = 1; /* by default */
1567  struct Curl_easy *data = conn->data;
1568  int i;
1569 
1570  enum proxy_use proxy;
1571 
1572  if(is_connect)
1573  proxy = HEADER_CONNECT;
1574  else
1575  proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1577 
1578  switch(proxy) {
1579  case HEADER_SERVER:
1580  h[0] = data->set.headers;
1581  break;
1582  case HEADER_PROXY:
1583  h[0] = data->set.headers;
1584  if(data->set.sep_headers) {
1585  h[1] = data->set.proxyheaders;
1586  numlists++;
1587  }
1588  break;
1589  case HEADER_CONNECT:
1590  if(data->set.sep_headers)
1591  h[0] = data->set.proxyheaders;
1592  else
1593  h[0] = data->set.headers;
1594  break;
1595  }
1596 
1597  /* loop through one or two lists */
1598  for(i = 0; i < numlists; i++) {
1599  headers = h[i];
1600 
1601  while(headers) {
1602  ptr = strchr(headers->data, ':');
1603  if(ptr) {
1604  /* we require a colon for this to be a true header */
1605 
1606  ptr++; /* pass the colon */
1607  while(*ptr && ISSPACE(*ptr))
1608  ptr++;
1609 
1610  if(*ptr) {
1611  /* only send this if the contents was non-blank */
1612 
1613  if(conn->allocptr.host &&
1614  /* a Host: header was sent already, don't pass on any custom Host:
1615  header as that will produce *two* in the same request! */
1616  checkprefix("Host:", headers->data))
1617  ;
1618  else if(data->set.httpreq == HTTPREQ_POST_FORM &&
1619  /* this header (extended by formdata.c) is sent later */
1620  checkprefix("Content-Type:", headers->data))
1621  ;
1622  else if(data->set.httpreq == HTTPREQ_POST_MIME &&
1623  /* this header is sent later */
1624  checkprefix("Content-Type:", headers->data))
1625  ;
1626  else if(conn->bits.authneg &&
1627  /* while doing auth neg, don't allow the custom length since
1628  we will force length zero then */
1629  checkprefix("Content-Length:", headers->data))
1630  ;
1631  else if(conn->allocptr.te &&
1632  /* when asking for Transfer-Encoding, don't pass on a custom
1633  Connection: */
1634  checkprefix("Connection:", headers->data))
1635  ;
1636  else if((conn->httpversion == 20) &&
1637  checkprefix("Transfer-Encoding:", headers->data))
1638  /* HTTP/2 doesn't support chunked requests */
1639  ;
1640  else {
1641  CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1642  headers->data);
1643  if(result)
1644  return result;
1645  }
1646  }
1647  }
1648  else {
1649  ptr = strchr(headers->data, ';');
1650  if(ptr) {
1651 
1652  ptr++; /* pass the semicolon */
1653  while(*ptr && ISSPACE(*ptr))
1654  ptr++;
1655 
1656  if(*ptr) {
1657  /* this may be used for something else in the future */
1658  }
1659  else {
1660  if(*(--ptr) == ';') {
1661  CURLcode result;
1662 
1663  /* send no-value custom header if terminated by semicolon */
1664  *ptr = ':';
1665  result = Curl_add_bufferf(req_buffer, "%s\r\n",
1666  headers->data);
1667 
1668  /* restore the previous value */
1669  *ptr = ';';
1670 
1671  if(result)
1672  return result;
1673  }
1674  }
1675  }
1676  }
1677  headers = headers->next;
1678  }
1679  }
1680 
1681  return CURLE_OK;
1682 }
1683 
1685  Curl_send_buffer *req_buffer)
1686 {
1687  const struct tm *tm;
1688  struct tm keeptime;
1689  CURLcode result;
1690  char datestr[80];
1691  const char *condp;
1692 
1693  if(data->set.timecondition == CURL_TIMECOND_NONE)
1694  /* no condition was asked for */
1695  return CURLE_OK;
1696 
1697  result = Curl_gmtime(data->set.timevalue, &keeptime);
1698  if(result) {
1699  failf(data, "Invalid TIMEVALUE");
1700  return result;
1701  }
1702  tm = &keeptime;
1703 
1704  switch(data->set.timecondition) {
1705  default:
1707 
1709  condp = "If-Modified-Since";
1710  break;
1712  condp = "If-Unmodified-Since";
1713  break;
1714  case CURL_TIMECOND_LASTMOD:
1715  condp = "Last-Modified";
1716  break;
1717  }
1718 
1719  /* The If-Modified-Since header family should have their times set in
1720  * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1721  * represented in Greenwich Mean Time (GMT), without exception. For the
1722  * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1723  * Time)." (see page 20 of RFC2616).
1724  */
1725 
1726  /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1727  snprintf(datestr, sizeof(datestr),
1728  "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
1729  condp,
1730  Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1731  tm->tm_mday,
1732  Curl_month[tm->tm_mon],
1733  tm->tm_year + 1900,
1734  tm->tm_hour,
1735  tm->tm_min,
1736  tm->tm_sec);
1737 
1738  result = Curl_add_buffer(req_buffer, datestr, strlen(datestr));
1739 
1740  return result;
1741 }
1742 
1743 /*
1744  * Curl_http() gets called from the generic multi_do() function when a HTTP
1745  * request is to be performed. This creates and sends a properly constructed
1746  * HTTP request.
1747  */
1748 CURLcode Curl_http(struct connectdata *conn, bool *done)
1749 {
1750  struct Curl_easy *data = conn->data;
1752  struct HTTP *http;
1753  const char *ppath = data->state.path;
1754  bool paste_ftp_userpwd = FALSE;
1755  char ftp_typecode[sizeof("/;type=?")] = "";
1756  const char *host = conn->host.name;
1757  const char *te = ""; /* transfer-encoding */
1758  const char *ptr;
1759  const char *request;
1760  Curl_HttpReq httpreq = data->set.httpreq;
1761 #if !defined(CURL_DISABLE_COOKIES)
1762  char *addcookies = NULL;
1763 #endif
1764  curl_off_t included_body = 0;
1765  const char *httpstring;
1766  Curl_send_buffer *req_buffer;
1767  curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1768  int seekerr = CURL_SEEKFUNC_CANTSEEK;
1769 
1770  /* Always consider the DO phase done after this function call, even if there
1771  may be parts of the request that is not yet sent, since we can deal with
1772  the rest of the request in the PERFORM phase. */
1773  *done = TRUE;
1774 
1775  if(conn->httpversion < 20) { /* unless the connection is re-used and already
1776  http2 */
1777  switch(conn->negnpn) {
1778  case CURL_HTTP_VERSION_2:
1779  conn->httpversion = 20; /* we know we're on HTTP/2 now */
1780 
1781  result = Curl_http2_switched(conn, NULL, 0);
1782  if(result)
1783  return result;
1784  break;
1785  case CURL_HTTP_VERSION_1_1:
1786  /* continue with HTTP/1.1 when explicitly requested */
1787  break;
1788  default:
1789  /* Check if user wants to use HTTP/2 with clear TCP*/
1790 #ifdef USE_NGHTTP2
1791  if(conn->data->set.httpversion ==
1793  DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
1794  conn->httpversion = 20;
1795 
1796  result = Curl_http2_switched(conn, NULL, 0);
1797  if(result)
1798  return result;
1799  }
1800 #endif
1801  break;
1802  }
1803  }
1804  else {
1805  /* prepare for a http2 request */
1806  result = Curl_http2_setup(conn);
1807  if(result)
1808  return result;
1809  }
1810 
1811  http = data->req.protop;
1812 
1813  if(!data->state.this_is_a_follow) {
1814  /* Free to avoid leaking memory on multiple requests*/
1815  free(data->state.first_host);
1816 
1817  data->state.first_host = strdup(conn->host.name);
1818  if(!data->state.first_host)
1819  return CURLE_OUT_OF_MEMORY;
1820 
1821  data->state.first_remote_port = conn->remote_port;
1822  }
1823  http->writebytecount = http->readbytecount = 0;
1824 
1826  data->set.upload) {
1827  httpreq = HTTPREQ_PUT;
1828  }
1829 
1830  /* Now set the 'request' pointer to the proper request string */
1831  if(data->set.str[STRING_CUSTOMREQUEST])
1832  request = data->set.str[STRING_CUSTOMREQUEST];
1833  else {
1834  if(data->set.opt_no_body)
1835  request = "HEAD";
1836  else {
1837  DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1838  switch(httpreq) {
1839  case HTTPREQ_POST:
1840  case HTTPREQ_POST_FORM:
1841  case HTTPREQ_POST_MIME:
1842  request = "POST";
1843  break;
1844  case HTTPREQ_PUT:
1845  request = "PUT";
1846  break;
1847  case HTTPREQ_OPTIONS:
1848  request = "OPTIONS";
1849  break;
1850  default: /* this should never happen */
1851  case HTTPREQ_GET:
1852  request = "GET";
1853  break;
1854  case HTTPREQ_HEAD:
1855  request = "HEAD";
1856  break;
1857  }
1858  }
1859  }
1860 
1861  /* The User-Agent string might have been allocated in url.c already, because
1862  it might have been used in the proxy connect, but if we have got a header
1863  with the user-agent string specified, we erase the previously made string
1864  here. */
1865  if(Curl_checkheaders(conn, "User-Agent:")) {
1866  free(conn->allocptr.uagent);
1867  conn->allocptr.uagent = NULL;
1868  }
1869 
1870  /* setup the authentication headers */
1871  result = Curl_http_output_auth(conn, request, ppath, FALSE);
1872  if(result)
1873  return result;
1874 
1875  if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
1876  (httpreq != HTTPREQ_GET) &&
1877  (httpreq != HTTPREQ_HEAD)) {
1878  /* Auth is required and we are not authenticated yet. Make a PUT or POST
1879  with content-length zero as a "probe". */
1880  conn->bits.authneg = TRUE;
1881  }
1882  else
1883  conn->bits.authneg = FALSE;
1884 
1885  Curl_safefree(conn->allocptr.ref);
1886  if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
1887  conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1888  if(!conn->allocptr.ref)
1889  return CURLE_OUT_OF_MEMORY;
1890  }
1891  else
1892  conn->allocptr.ref = NULL;
1893 
1894 #if !defined(CURL_DISABLE_COOKIES)
1895  if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
1896  addcookies = data->set.str[STRING_COOKIE];
1897 #endif
1898 
1899  if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
1900  data->set.str[STRING_ENCODING]) {
1902  conn->allocptr.accept_encoding =
1903  aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1904  if(!conn->allocptr.accept_encoding)
1905  return CURLE_OUT_OF_MEMORY;
1906  }
1907  else {
1909  conn->allocptr.accept_encoding = NULL;
1910  }
1911 
1912 #ifdef HAVE_LIBZ
1913  /* we only consider transfer-encoding magic if libz support is built-in */
1914 
1915  if(!Curl_checkheaders(conn, "TE:") &&
1916  data->set.http_transfer_encoding) {
1917  /* When we are to insert a TE: header in the request, we must also insert
1918  TE in a Connection: header, so we need to merge the custom provided
1919  Connection: header and prevent the original to get sent. Note that if
1920  the user has inserted his/hers own TE: header we don't do this magic
1921  but then assume that the user will handle it all! */
1922  char *cptr = Curl_checkheaders(conn, "Connection:");
1923 #define TE_HEADER "TE: gzip\r\n"
1924 
1925  Curl_safefree(conn->allocptr.te);
1926 
1927  /* Create the (updated) Connection: header */
1928  conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1929  strdup("Connection: TE\r\n" TE_HEADER);
1930 
1931  if(!conn->allocptr.te)
1932  return CURLE_OUT_OF_MEMORY;
1933  }
1934 #endif
1935 
1936  switch(httpreq) {
1937  case HTTPREQ_POST_MIME:
1938  http->sendit = &data->set.mimepost;
1939  break;
1940  case HTTPREQ_POST_FORM:
1941  /* Convert the form structure into a mime structure. */
1942  Curl_mime_cleanpart(&http->form);
1943  result = Curl_getformdata(data, &http->form, data->set.httppost,
1944  data->state.fread_func);
1945  if(result)
1946  return result;
1947  http->sendit = &http->form;
1948  break;
1949  default:
1950  http->sendit = NULL;
1951  }
1952 
1953  if(http->sendit) {
1954  const char *cthdr = Curl_checkheaders(conn, "Content-Type:");
1955 
1956  /* Read and seek body only. */
1957  http->sendit->flags |= MIME_BODY_ONLY;
1958 
1959  /* Prepare the mime structure headers & set content type. */
1960 
1961  if(cthdr)
1962  for(cthdr += 13; *cthdr == ' '; cthdr++)
1963  ;
1964  else if(http->sendit->kind == MIMEKIND_MULTIPART)
1965  cthdr = "multipart/form-data";
1966 
1967  curl_mime_headers(http->sendit, data->set.headers, 0);
1968  result = Curl_mime_prepare_headers(http->sendit, cthdr,
1969  NULL, MIMESTRATEGY_FORM);
1970  curl_mime_headers(http->sendit, NULL, 0);
1971  if(!result)
1972  result = Curl_mime_rewind(http->sendit);
1973  if(result)
1974  return result;
1975  http->postsize = Curl_mime_size(http->sendit);
1976  }
1977 
1978  ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
1979  if(ptr) {
1980  /* Some kind of TE is requested, check if 'chunked' is chosen */
1981  data->req.upload_chunky =
1982  Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1983  }
1984  else {
1985  if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
1986  (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
1987  http->postsize < 0) ||
1988  (data->set.upload && data->state.infilesize == -1))) {
1989  if(conn->bits.authneg)
1990  /* don't enable chunked during auth neg */
1991  ;
1992  else if(use_http_1_1plus(data, conn)) {
1993  /* HTTP, upload, unknown file size and not HTTP 1.0 */
1994  data->req.upload_chunky = TRUE;
1995  }
1996  else {
1997  failf(data, "Chunky upload is not supported by HTTP 1.0");
1998  return CURLE_UPLOAD_FAILED;
1999  }
2000  }
2001  else {
2002  /* else, no chunky upload */
2003  data->req.upload_chunky = FALSE;
2004  }
2005 
2006  if(data->req.upload_chunky)
2007  te = "Transfer-Encoding: chunked\r\n";
2008  }
2009 
2010  Curl_safefree(conn->allocptr.host);
2011 
2012  ptr = Curl_checkheaders(conn, "Host:");
2013  if(ptr && (!data->state.this_is_a_follow ||
2014  strcasecompare(data->state.first_host, conn->host.name))) {
2015 #if !defined(CURL_DISABLE_COOKIES)
2016  /* If we have a given custom Host: header, we extract the host name in
2017  order to possibly use it for cookie reasons later on. We only allow the
2018  custom Host: header if this is NOT a redirect, as setting Host: in the
2019  redirected request is being out on thin ice. Except if the host name
2020  is the same as the first one! */
2021  char *cookiehost = Curl_copy_header_value(ptr);
2022  if(!cookiehost)
2023  return CURLE_OUT_OF_MEMORY;
2024  if(!*cookiehost)
2025  /* ignore empty data */
2026  free(cookiehost);
2027  else {
2028  /* If the host begins with '[', we start searching for the port after
2029  the bracket has been closed */
2030  int startsearch = 0;
2031  if(*cookiehost == '[') {
2032  char *closingbracket;
2033  /* since the 'cookiehost' is an allocated memory area that will be
2034  freed later we cannot simply increment the pointer */
2035  memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
2036  closingbracket = strchr(cookiehost, ']');
2037  if(closingbracket)
2038  *closingbracket = 0;
2039  }
2040  else {
2041  char *colon = strchr(cookiehost + startsearch, ':');
2042  if(colon)
2043  *colon = 0; /* The host must not include an embedded port number */
2044  }
2046  conn->allocptr.cookiehost = cookiehost;
2047  }
2048 #endif
2049 
2050  if(strcmp("Host:", ptr)) {
2051  conn->allocptr.host = aprintf("%s\r\n", ptr);
2052  if(!conn->allocptr.host)
2053  return CURLE_OUT_OF_MEMORY;
2054  }
2055  else
2056  /* when clearing the header */
2057  conn->allocptr.host = NULL;
2058  }
2059  else {
2060  /* When building Host: headers, we must put the host name within
2061  [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2062 
2063  if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2064  (conn->remote_port == PORT_HTTPS)) ||
2065  ((conn->given->protocol&CURLPROTO_HTTP) &&
2066  (conn->remote_port == PORT_HTTP)) )
2067  /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
2068  the port number in the host string */
2069  conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
2070  conn->bits.ipv6_ip?"[":"",
2071  host,
2072  conn->bits.ipv6_ip?"]":"");
2073  else
2074  conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
2075  conn->bits.ipv6_ip?"[":"",
2076  host,
2077  conn->bits.ipv6_ip?"]":"",
2078  conn->remote_port);
2079 
2080  if(!conn->allocptr.host)
2081  /* without Host: we can't make a nice request */
2082  return CURLE_OUT_OF_MEMORY;
2083  }
2084 
2085 #ifndef CURL_DISABLE_PROXY
2086  if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2087  /* Using a proxy but does not tunnel through it */
2088 
2089  /* The path sent to the proxy is in fact the entire URL. But if the remote
2090  host is a IDN-name, we must make sure that the request we produce only
2091  uses the encoded host name! */
2092  if(conn->host.dispname != conn->host.name) {
2093  char *url = data->change.url;
2094  ptr = strstr(url, conn->host.dispname);
2095  if(ptr) {
2096  /* This is where the display name starts in the URL, now replace this
2097  part with the encoded name. TODO: This method of replacing the host
2098  name is rather crude as I believe there's a slight risk that the
2099  user has entered a user name or password that contain the host name
2100  string. */
2101  size_t currlen = strlen(conn->host.dispname);
2102  size_t newlen = strlen(conn->host.name);
2103  size_t urllen = strlen(url);
2104 
2105  char *newurl;
2106 
2107  newurl = malloc(urllen + newlen - currlen + 1);
2108  if(newurl) {
2109  /* copy the part before the host name */
2110  memcpy(newurl, url, ptr - url);
2111  /* append the new host name instead of the old */
2112  memcpy(newurl + (ptr - url), conn->host.name, newlen);
2113  /* append the piece after the host name */
2114  memcpy(newurl + newlen + (ptr - url),
2115  ptr + currlen, /* copy the trailing zero byte too */
2116  urllen - (ptr-url) - currlen + 1);
2117  if(data->change.url_alloc) {
2118  Curl_safefree(data->change.url);
2119  data->change.url_alloc = FALSE;
2120  }
2121  data->change.url = newurl;
2122  data->change.url_alloc = TRUE;
2123  }
2124  else
2125  return CURLE_OUT_OF_MEMORY;
2126  }
2127  }
2128  ppath = data->change.url;
2129  if(checkprefix("ftp://", ppath)) {
2130  if(data->set.proxy_transfer_mode) {
2131  /* when doing ftp, append ;type=<a|i> if not present */
2132  char *type = strstr(ppath, ";type=");
2133  if(type && type[6] && type[7] == 0) {
2134  switch(Curl_raw_toupper(type[6])) {
2135  case 'A':
2136  case 'D':
2137  case 'I':
2138  break;
2139  default:
2140  type = NULL;
2141  }
2142  }
2143  if(!type) {
2144  char *p = ftp_typecode;
2145  /* avoid sending invalid URLs like ftp://example.com;type=i if the
2146  * user specified ftp://example.com without the slash */
2147  if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
2148  *p++ = '/';
2149  }
2150  snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2151  data->set.prefer_ascii ? 'a' : 'i');
2152  }
2153  }
2154  if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
2155  paste_ftp_userpwd = TRUE;
2156  }
2157  }
2158 #endif /* CURL_DISABLE_PROXY */
2159 
2160  http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
2161 
2162  if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) &&
2163  data->state.resume_from) {
2164  /**********************************************************************
2165  * Resuming upload in HTTP means that we PUT or POST and that we have
2166  * got a resume_from value set. The resume value has already created
2167  * a Range: header that will be passed along. We need to "fast forward"
2168  * the file the given number of bytes and decrease the assume upload
2169  * file size before we continue this venture in the dark lands of HTTP.
2170  * Resuming mime/form posting at an offset > 0 has no sense and is ignored.
2171  *********************************************************************/
2172 
2173  if(data->state.resume_from < 0) {
2174  /*
2175  * This is meant to get the size of the present remote-file by itself.
2176  * We don't support this now. Bail out!
2177  */
2178  data->state.resume_from = 0;
2179  }
2180 
2181  if(data->state.resume_from && !data->state.this_is_a_follow) {
2182  /* do we still game? */
2183 
2184  /* Now, let's read off the proper amount of bytes from the
2185  input. */
2186  if(conn->seek_func) {
2187  seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2188  SEEK_SET);
2189  }
2190 
2191  if(seekerr != CURL_SEEKFUNC_OK) {
2192  curl_off_t passed = 0;
2193 
2194  if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2195  failf(data, "Could not seek stream");
2196  return CURLE_READ_ERROR;
2197  }
2198  /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2199  do {
2200  size_t readthisamountnow =
2201  (data->state.resume_from - passed > data->set.buffer_size) ?
2202  (size_t)data->set.buffer_size :
2203  curlx_sotouz(data->state.resume_from - passed);
2204 
2205  size_t actuallyread =
2206  data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2207  data->state.in);
2208 
2209  passed += actuallyread;
2210  if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2211  /* this checks for greater-than only to make sure that the
2212  CURL_READFUNC_ABORT return code still aborts */
2213  failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2214  " bytes from the input", passed);
2215  return CURLE_READ_ERROR;
2216  }
2217  } while(passed < data->state.resume_from);
2218  }
2219 
2220  /* now, decrease the size of the read */
2221  if(data->state.infilesize>0) {
2222  data->state.infilesize -= data->state.resume_from;
2223 
2224  if(data->state.infilesize <= 0) {
2225  failf(data, "File already completely uploaded");
2226  return CURLE_PARTIAL_FILE;
2227  }
2228  }
2229  /* we've passed, proceed as normal */
2230  }
2231  }
2232  if(data->state.use_range) {
2233  /*
2234  * A range is selected. We use different headers whether we're downloading
2235  * or uploading and we always let customized headers override our internal
2236  * ones if any such are specified.
2237  */
2238  if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2239  !Curl_checkheaders(conn, "Range:")) {
2240  /* if a line like this was already allocated, free the previous one */
2241  free(conn->allocptr.rangeline);
2242  conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2243  data->state.range);
2244  }
2245  else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
2246  !Curl_checkheaders(conn, "Content-Range:")) {
2247 
2248  /* if a line like this was already allocated, free the previous one */
2249  free(conn->allocptr.rangeline);
2250 
2251  if(data->set.set_resume_from < 0) {
2252  /* Upload resume was asked for, but we don't know the size of the
2253  remote part so we tell the server (and act accordingly) that we
2254  upload the whole file (again) */
2255  conn->allocptr.rangeline =
2256  aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2257  "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2258  data->state.infilesize - 1, data->state.infilesize);
2259 
2260  }
2261  else if(data->state.resume_from) {
2262  /* This is because "resume" was selected */
2263  curl_off_t total_expected_size =
2264  data->state.resume_from + data->state.infilesize;
2265  conn->allocptr.rangeline =
2266  aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2267  "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2268  data->state.range, total_expected_size-1,
2269  total_expected_size);
2270  }
2271  else {
2272  /* Range was selected and then we just pass the incoming range and
2273  append total size */
2274  conn->allocptr.rangeline =
2275  aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2276  data->state.range, data->state.infilesize);
2277  }
2278  if(!conn->allocptr.rangeline)
2279  return CURLE_OUT_OF_MEMORY;
2280  }
2281  }
2282 
2283  httpstring = get_http_string(data, conn);
2284 
2285  /* initialize a dynamic send-buffer */
2286  req_buffer = Curl_add_buffer_init();
2287 
2288  if(!req_buffer)
2289  return CURLE_OUT_OF_MEMORY;
2290 
2291  /* add the main request stuff */
2292  /* GET/HEAD/POST/PUT */
2293  result = Curl_add_bufferf(req_buffer, "%s ", request);
2294  if(result)
2295  return result;
2296 
2297  if(data->set.str[STRING_TARGET])
2298  ppath = data->set.str[STRING_TARGET];
2299 
2300  /* url */
2301  if(paste_ftp_userpwd)
2302  result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2303  conn->user, conn->passwd,
2304  ppath + sizeof("ftp://") - 1);
2305  else
2306  result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2307  if(result)
2308  return result;
2309 
2310  result =
2311  Curl_add_bufferf(req_buffer,
2312  "%s" /* ftp typecode (;type=x) */
2313  " HTTP/%s\r\n" /* HTTP version */
2314  "%s" /* host */
2315  "%s" /* proxyuserpwd */
2316  "%s" /* userpwd */
2317  "%s" /* range */
2318  "%s" /* user agent */
2319  "%s" /* accept */
2320  "%s" /* TE: */
2321  "%s" /* accept-encoding */
2322  "%s" /* referer */
2323  "%s" /* Proxy-Connection */
2324  "%s",/* transfer-encoding */
2325 
2326  ftp_typecode,
2327  httpstring,
2328  (conn->allocptr.host?conn->allocptr.host:""),
2329  conn->allocptr.proxyuserpwd?
2330  conn->allocptr.proxyuserpwd:"",
2331  conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2332  (data->state.use_range && conn->allocptr.rangeline)?
2333  conn->allocptr.rangeline:"",
2334  (data->set.str[STRING_USERAGENT] &&
2335  *data->set.str[STRING_USERAGENT] &&
2336  conn->allocptr.uagent)?
2337  conn->allocptr.uagent:"",
2338  http->p_accept?http->p_accept:"",
2339  conn->allocptr.te?conn->allocptr.te:"",
2340  (data->set.str[STRING_ENCODING] &&
2341  *data->set.str[STRING_ENCODING] &&
2342  conn->allocptr.accept_encoding)?
2343  conn->allocptr.accept_encoding:"",
2344  (data->change.referer && conn->allocptr.ref)?
2345  conn->allocptr.ref:"" /* Referer: <data> */,
2346  (conn->bits.httpproxy &&
2347  !conn->bits.tunnel_proxy &&
2348  !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
2349  "Proxy-Connection: Keep-Alive\r\n":"",
2350  te
2351  );
2352 
2353  /* clear userpwd and proxyuserpwd to avoid re-using old credentials
2354  * from re-used connections */
2357 
2358  if(result)
2359  return result;
2360 
2361  if(!(conn->handler->flags&PROTOPT_SSL) &&
2362  conn->httpversion != 20 &&
2363  (data->set.httpversion == CURL_HTTP_VERSION_2)) {
2364  /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2365  over SSL */
2366  result = Curl_http2_request_upgrade(req_buffer, conn);
2367  if(result)
2368  return result;
2369  }
2370 
2371 #if !defined(CURL_DISABLE_COOKIES)
2372  if(data->cookies || addcookies) {
2373  struct Cookie *co = NULL; /* no cookies from start */
2374  int count = 0;
2375 
2376  if(data->cookies) {
2378  co = Curl_cookie_getlist(data->cookies,
2379  conn->allocptr.cookiehost?
2380  conn->allocptr.cookiehost:host,
2381  data->state.path,
2382  (conn->handler->protocol&CURLPROTO_HTTPS)?
2383  TRUE:FALSE);
2385  }
2386  if(co) {
2387  struct Cookie *store = co;
2388  /* now loop through all cookies that matched */
2389  while(co) {
2390  if(co->value) {
2391  if(0 == count) {
2392  result = Curl_add_bufferf(req_buffer, "Cookie: ");
2393  if(result)
2394  break;
2395  }
2396  result = Curl_add_bufferf(req_buffer,
2397  "%s%s=%s", count?"; ":"",
2398  co->name, co->value);
2399  if(result)
2400  break;
2401  count++;
2402  }
2403  co = co->next; /* next cookie please */
2404  }
2405  Curl_cookie_freelist(store);
2406  }
2407  if(addcookies && !result) {
2408  if(!count)
2409  result = Curl_add_bufferf(req_buffer, "Cookie: ");
2410  if(!result) {
2411  result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
2412  addcookies);
2413  count++;
2414  }
2415  }
2416  if(count && !result)
2417  result = Curl_add_buffer(req_buffer, "\r\n", 2);
2418 
2419  if(result)
2420  return result;
2421  }
2422 #endif
2423 
2424  result = Curl_add_timecondition(data, req_buffer);
2425  if(result)
2426  return result;
2427 
2428  result = Curl_add_custom_headers(conn, FALSE, req_buffer);
2429  if(result)
2430  return result;
2431 
2432  http->postdata = NULL; /* nothing to post at this point */
2433  Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
2434 
2435  /* If 'authdone' is FALSE, we must not set the write socket index to the
2436  Curl_transfer() call below, as we're not ready to actually upload any
2437  data yet. */
2438 
2439  switch(httpreq) {
2440 
2441  case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2442 
2443  if(conn->bits.authneg)
2444  postsize = 0;
2445  else
2446  postsize = data->state.infilesize;
2447 
2448  if((postsize != -1) && !data->req.upload_chunky &&
2449  (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
2450  /* only add Content-Length if not uploading chunked */
2451  result = Curl_add_bufferf(req_buffer,
2452  "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2453  "\r\n", postsize);
2454  if(result)
2455  return result;
2456  }
2457 
2458  if(postsize != 0) {
2459  result = expect100(data, conn, req_buffer);
2460  if(result)
2461  return result;
2462  }
2463 
2464  result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2465  if(result)
2466  return result;
2467 
2468  /* set the upload size to the progress meter */
2469  Curl_pgrsSetUploadSize(data, postsize);
2470 
2471  /* this sends the buffer and frees all the buffer resources */
2472  result = Curl_add_buffer_send(req_buffer, conn,
2473  &data->info.request_size, 0, FIRSTSOCKET);
2474  if(result)
2475  failf(data, "Failed sending PUT request");
2476  else
2477  /* prepare for transfer */
2479  &http->readbytecount, postsize?FIRSTSOCKET:-1,
2480  postsize?&http->writebytecount:NULL);
2481  if(result)
2482  return result;
2483  break;
2484 
2485  case HTTPREQ_POST_FORM:
2486  case HTTPREQ_POST_MIME:
2487  /* This is form posting using mime data. */
2488  if(conn->bits.authneg) {
2489  /* nothing to post! */
2490  result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2491  if(result)
2492  return result;
2493 
2494  result = Curl_add_buffer_send(req_buffer, conn,
2495  &data->info.request_size, 0, FIRSTSOCKET);
2496  if(result)
2497  failf(data, "Failed sending POST request");
2498  else
2499  /* setup variables for the upcoming transfer */
2501  -1, NULL);
2502  break;
2503  }
2504 
2505  postsize = http->postsize;
2506 
2507  /* We only set Content-Length and allow a custom Content-Length if
2508  we don't upload data chunked, as RFC2616 forbids us to set both
2509  kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2510  if(postsize != -1 && !data->req.upload_chunky &&
2511  (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
2512  /* we allow replacing this header if not during auth negotiation,
2513  although it isn't very wise to actually set your own */
2514  result = Curl_add_bufferf(req_buffer,
2515  "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2516  "\r\n", postsize);
2517  if(result)
2518  return result;
2519  }
2520 
2521  /* Output mime-generated headers. */
2522  {
2523  struct curl_slist *hdr;
2524 
2525  for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
2526  result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data);
2527  if(result)
2528  return result;
2529  }
2530  }
2531 
2532  /* For really small posts we don't use Expect: headers at all, and for
2533  the somewhat bigger ones we allow the app to disable it. Just make
2534  sure that the expect100header is always set to the preferred value
2535  here. */
2536  ptr = Curl_checkheaders(conn, "Expect:");
2537  if(ptr) {
2538  data->state.expect100header =
2539  Curl_compareheader(ptr, "Expect:", "100-continue");
2540  }
2541  else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
2542  result = expect100(data, conn, req_buffer);
2543  if(result)
2544  return result;
2545  }
2546  else
2547  data->state.expect100header = FALSE;
2548 
2549  /* make the request end in a true CRLF */
2550  result = Curl_add_buffer(req_buffer, "\r\n", 2);
2551  if(result)
2552  return result;
2553 
2554  /* set the upload size to the progress meter */
2555  Curl_pgrsSetUploadSize(data, postsize);
2556 
2557  /* Read from mime structure. */
2559  data->state.in = (void *) http->sendit;
2560  http->sending = HTTPSEND_BODY;
2561 
2562  /* this sends the buffer and frees all the buffer resources */
2563  result = Curl_add_buffer_send(req_buffer, conn,
2564  &data->info.request_size, 0, FIRSTSOCKET);
2565  if(result)
2566  failf(data, "Failed sending POST request");
2567  else
2568  /* prepare for transfer */
2570  &http->readbytecount, postsize?FIRSTSOCKET:-1,
2571  postsize?&http->writebytecount:NULL);
2572  if(result)
2573  return result;
2574 
2575  break;
2576 
2577  case HTTPREQ_POST:
2578  /* this is the simple POST, using x-www-form-urlencoded style */
2579 
2580  if(conn->bits.authneg)
2581  postsize = 0;
2582  else
2583  /* the size of the post body */
2584  postsize = data->state.infilesize;
2585 
2586  /* We only set Content-Length and allow a custom Content-Length if
2587  we don't upload data chunked, as RFC2616 forbids us to set both
2588  kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2589  if((postsize != -1) && !data->req.upload_chunky &&
2590  (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
2591  /* we allow replacing this header if not during auth negotiation,
2592  although it isn't very wise to actually set your own */
2593  result = Curl_add_bufferf(req_buffer,
2594  "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2595  "\r\n", postsize);
2596  if(result)
2597  return result;
2598  }
2599 
2600  if(!Curl_checkheaders(conn, "Content-Type:")) {
2601  result = Curl_add_bufferf(req_buffer,
2602  "Content-Type: application/"
2603  "x-www-form-urlencoded\r\n");
2604  if(result)
2605  return result;
2606  }
2607 
2608  /* For really small posts we don't use Expect: headers at all, and for
2609  the somewhat bigger ones we allow the app to disable it. Just make
2610  sure that the expect100header is always set to the preferred value
2611  here. */
2612  ptr = Curl_checkheaders(conn, "Expect:");
2613  if(ptr) {
2614  data->state.expect100header =
2615  Curl_compareheader(ptr, "Expect:", "100-continue");
2616  }
2617  else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
2618  result = expect100(data, conn, req_buffer);
2619  if(result)
2620  return result;
2621  }
2622  else
2623  data->state.expect100header = FALSE;
2624 
2625  if(data->set.postfields) {
2626 
2627  /* In HTTP2, we send request body in DATA frame regardless of
2628  its size. */
2629  if(conn->httpversion != 20 &&
2630  !data->state.expect100header &&
2631  (postsize < MAX_INITIAL_POST_SIZE)) {
2632  /* if we don't use expect: 100 AND
2633  postsize is less than MAX_INITIAL_POST_SIZE
2634 
2635  then append the post data to the HTTP request header. This limit
2636  is no magic limit but only set to prevent really huge POSTs to
2637  get the data duplicated with malloc() and family. */
2638 
2639  result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2640  if(result)
2641  return result;
2642 
2643  if(!data->req.upload_chunky) {
2644  /* We're not sending it 'chunked', append it to the request
2645  already now to reduce the number if send() calls */
2646  result = Curl_add_buffer(req_buffer, data->set.postfields,
2647  (size_t)postsize);
2648  included_body = postsize;
2649  }
2650  else {
2651  if(postsize) {
2652  /* Append the POST data chunky-style */
2653  result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2654  if(!result) {
2655  result = Curl_add_buffer(req_buffer, data->set.postfields,
2656  (size_t)postsize);
2657  if(!result)
2658  result = Curl_add_buffer(req_buffer, "\r\n", 2);
2659  included_body = postsize + 2;
2660  }
2661  }
2662  if(!result)
2663  result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
2664  /* 0 CR LF CR LF */
2665  included_body += 5;
2666  }
2667  if(result)
2668  return result;
2669  /* Make sure the progress information is accurate */
2670  Curl_pgrsSetUploadSize(data, postsize);
2671  }
2672  else {
2673  /* A huge POST coming up, do data separate from the request */
2674  http->postsize = postsize;
2675  http->postdata = data->set.postfields;
2676 
2677  http->sending = HTTPSEND_BODY;
2678 
2680  data->state.in = (void *)conn;
2681 
2682  /* set the upload size to the progress meter */
2683  Curl_pgrsSetUploadSize(data, http->postsize);
2684 
2685  result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2686  if(result)
2687  return result;
2688  }
2689  }
2690  else {
2691  result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2692  if(result)
2693  return result;
2694 
2695  if(data->req.upload_chunky && conn->bits.authneg) {
2696  /* Chunky upload is selected and we're negotiating auth still, send
2697  end-of-data only */
2698  result = Curl_add_buffer(req_buffer,
2699  "\x30\x0d\x0a\x0d\x0a", 5);
2700  /* 0 CR LF CR LF */
2701  if(result)
2702  return result;
2703  }
2704 
2705  else if(data->state.infilesize) {
2706  /* set the upload size to the progress meter */
2707  Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2708 
2709  /* set the pointer to mark that we will send the post body using the
2710  read callback, but only if we're not in authenticate
2711  negotiation */
2712  if(!conn->bits.authneg) {
2713  http->postdata = (char *)&http->postdata;
2714  http->postsize = postsize;
2715  }
2716  }
2717  }
2718  /* issue the request */
2719  result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2720  (size_t)included_body, FIRSTSOCKET);
2721 
2722  if(result)
2723  failf(data, "Failed sending HTTP POST request");
2724  else
2726  &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2727  http->postdata?&http->writebytecount:NULL);
2728  break;
2729 
2730  default:
2731  result = Curl_add_buffer(req_buffer, "\r\n", 2);
2732  if(result)
2733  return result;
2734 
2735  /* issue the request */
2736  result = Curl_add_buffer_send(req_buffer, conn,
2737  &data->info.request_size, 0, FIRSTSOCKET);
2738 
2739  if(result)
2740  failf(data, "Failed sending HTTP request");
2741  else
2742  /* HTTP GET/HEAD download: */
2744  http->postdata?FIRSTSOCKET:-1,
2745  http->postdata?&http->writebytecount:NULL);
2746  }
2747  if(result)
2748  return result;
2749 
2750  if(http->writebytecount) {
2751  /* if a request-body has been sent off, we make sure this progress is noted
2752  properly */
2754  if(Curl_pgrsUpdate(conn))
2755  result = CURLE_ABORTED_BY_CALLBACK;
2756 
2757  if(http->writebytecount >= postsize) {
2758  /* already sent the entire request body, mark the "upload" as
2759  complete */
2760  infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2761  " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2762  http->writebytecount, postsize);
2763  data->req.upload_done = TRUE;
2764  data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2765  data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2767  }
2768  }
2769 
2770  if((conn->httpversion == 20) && data->req.upload_chunky)
2771  /* upload_chunky was set above to set up the request in a chunky fashion,
2772  but is disabled here again to avoid that the chunked encoded version is
2773  actually used when sending the request body over h2 */
2774  data->req.upload_chunky = FALSE;
2775  return result;
2776 }
2777 
2778 /*
2779  * checkhttpprefix()
2780  *
2781  * Returns TRUE if member of the list matches prefix of string
2782  */
2783 static bool
2785  const char *s)
2786 {
2787  struct curl_slist *head = data->set.http200aliases;
2788  bool rc = FALSE;
2789 #ifdef CURL_DOES_CONVERSIONS
2790  /* convert from the network encoding using a scratch area */
2791  char *scratch = strdup(s);
2792  if(NULL == scratch) {
2793  failf(data, "Failed to allocate memory for conversion!");
2794  return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2795  }
2796  if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
2797  /* Curl_convert_from_network calls failf if unsuccessful */
2798  free(scratch);
2799  return FALSE; /* can't return CURLE_foobar so return FALSE */
2800  }
2801  s = scratch;
2802 #endif /* CURL_DOES_CONVERSIONS */
2803 
2804  while(head) {
2805  if(checkprefix(head->data, s)) {
2806  rc = TRUE;
2807  break;
2808  }
2809  head = head->next;
2810  }
2811 
2812  if(!rc && (checkprefix("HTTP/", s)))
2813  rc = TRUE;
2814 
2815 #ifdef CURL_DOES_CONVERSIONS
2816  free(scratch);
2817 #endif /* CURL_DOES_CONVERSIONS */
2818  return rc;
2819 }
2820 
2821 #ifndef CURL_DISABLE_RTSP
2822 static bool
2824  const char *s)
2825 {
2826  bool result = FALSE;
2827 
2828 #ifdef CURL_DOES_CONVERSIONS
2829  /* convert from the network encoding using a scratch area */
2830  char *scratch = strdup(s);
2831  if(NULL == scratch) {
2832  failf(data, "Failed to allocate memory for conversion!");
2833  return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2834  }
2835  if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
2836  /* Curl_convert_from_network calls failf if unsuccessful */
2837  result = FALSE; /* can't return CURLE_foobar so return FALSE */
2838  }
2839  else
2840  result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
2841  free(scratch);
2842 #else
2843  (void)data; /* unused */
2844  result = checkprefix("RTSP/", s)? TRUE: FALSE;
2845 #endif /* CURL_DOES_CONVERSIONS */
2846 
2847  return result;
2848 }
2849 #endif /* CURL_DISABLE_RTSP */
2850 
2851 static bool
2853  const char *s)
2854 {
2855 #ifndef CURL_DISABLE_RTSP
2856  if(conn->handler->protocol & CURLPROTO_RTSP)
2857  return checkrtspprefix(data, s);
2858 #else
2859  (void)conn;
2860 #endif /* CURL_DISABLE_RTSP */
2861 
2862  return checkhttpprefix(data, s);
2863 }
2864 
2865 /*
2866  * header_append() copies a chunk of data to the end of the already received
2867  * header. We make sure that the full string fit in the allocated header
2868  * buffer, or else we enlarge it.
2869  */
2871  struct SingleRequest *k,
2872  size_t length)
2873 {
2874  if(k->hbuflen + length >= data->state.headersize) {
2875  /* We enlarge the header buffer as it is too small */
2876  char *newbuff;
2877  size_t hbufp_index;
2878  size_t newsize;
2879 
2880  if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2881  /* The reason to have a max limit for this is to avoid the risk of a bad
2882  server feeding libcurl with a never-ending header that will cause
2883  reallocs infinitely */
2884  failf(data, "Avoided giant realloc for header (max is %d)!",
2886  return CURLE_OUT_OF_MEMORY;
2887  }
2888 
2889  newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2);
2890  hbufp_index = k->hbufp - data->state.headerbuff;
2891  newbuff = realloc(data->state.headerbuff, newsize);
2892  if(!newbuff) {
2893  failf(data, "Failed to alloc memory for big header!");
2894  return CURLE_OUT_OF_MEMORY;
2895  }
2896  data->state.headersize = newsize;
2897  data->state.headerbuff = newbuff;
2898  k->hbufp = data->state.headerbuff + hbufp_index;
2899  }
2900  memcpy(k->hbufp, k->str_start, length);
2901  k->hbufp += length;
2902  k->hbuflen += length;
2903  *k->hbufp = 0;
2904 
2905  return CURLE_OK;
2906 }
2907 
2908 static void print_http_error(struct Curl_easy *data)
2909 {
2910  struct SingleRequest *k = &data->req;
2911  char *beg = k->p;
2912 
2913  /* make sure that data->req.p points to the HTTP status line */
2914  if(!strncmp(beg, "HTTP", 4)) {
2915 
2916  /* skip to HTTP status code */
2917  beg = strchr(beg, ' ');
2918  if(beg && *++beg) {
2919 
2920  /* find trailing CR */
2921  char end_char = '\r';
2922  char *end = strchr(beg, end_char);
2923  if(!end) {
2924  /* try to find LF (workaround for non-compliant HTTP servers) */
2925  end_char = '\n';
2926  end = strchr(beg, end_char);
2927  }
2928 
2929  if(end) {
2930  /* temporarily replace CR or LF by NUL and print the error message */
2931  *end = '\0';
2932  failf(data, "The requested URL returned error: %s", beg);
2933 
2934  /* restore the previously replaced CR or LF */
2935  *end = end_char;
2936  return;
2937  }
2938  }
2939  }
2940 
2941  /* fall-back to printing the HTTP status code only */
2942  failf(data, "The requested URL returned error: %d", k->httpcode);
2943 }
2944 
2945 /*
2946  * Read any HTTP header lines from the server and pass them to the client app.
2947  */
2949  struct connectdata *conn,
2950  ssize_t *nread,
2951  bool *stop_reading)
2952 {
2953  CURLcode result;
2954  struct SingleRequest *k = &data->req;
2955 
2956  /* header line within buffer loop */
2957  do {
2958  size_t rest_length;
2959  size_t full_length;
2960  int writetype;
2961 
2962  /* str_start is start of line within buf */
2963  k->str_start = k->str;
2964 
2965  /* data is in network encoding so use 0x0a instead of '\n' */
2966  k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2967 
2968  if(!k->end_ptr) {
2969  /* Not a complete header line within buffer, append the data to
2970  the end of the headerbuff. */
2971  result = header_append(data, k, *nread);
2972  if(result)
2973  return result;
2974 
2975  if(!k->headerline && (k->hbuflen>5)) {
2976  /* make a first check that this looks like a protocol header */
2977  if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2978  /* this is not the beginning of a protocol first header line */
2979  k->header = FALSE;
2980  k->badheader = HEADER_ALLBAD;
2981  break;
2982  }
2983  }
2984 
2985  break; /* read more and try again */
2986  }
2987 
2988  /* decrease the size of the remaining (supposed) header line */
2989  rest_length = (k->end_ptr - k->str) + 1;
2990  *nread -= (ssize_t)rest_length;
2991 
2992  k->str = k->end_ptr + 1; /* move past new line */
2993 
2994  full_length = k->str - k->str_start;
2995 
2996  result = header_append(data, k, full_length);
2997  if(result)
2998  return result;
2999 
3000  k->end_ptr = k->hbufp;
3001  k->p = data->state.headerbuff;
3002 
3003  /****
3004  * We now have a FULL header line that p points to
3005  *****/
3006 
3007  if(!k->headerline) {
3008  /* the first read header */
3009  if((k->hbuflen>5) &&
3010  !checkprotoprefix(data, conn, data->state.headerbuff)) {
3011  /* this is not the beginning of a protocol first header line */
3012  k->header = FALSE;
3013  if(*nread)
3014  /* since there's more, this is a partial bad header */
3016  else {
3017  /* this was all we read so it's all a bad header */
3018  k->badheader = HEADER_ALLBAD;
3019  *nread = (ssize_t)rest_length;
3020  }
3021  break;
3022  }
3023  }
3024 
3025  /* headers are in network encoding so
3026  use 0x0a and 0x0d instead of '\n' and '\r' */
3027  if((0x0a == *k->p) || (0x0d == *k->p)) {
3028  size_t headerlen;
3029  /* Zero-length header line means end of headers! */
3030 
3031 #ifdef CURL_DOES_CONVERSIONS
3032  if(0x0d == *k->p) {
3033  *k->p = '\r'; /* replace with CR in host encoding */
3034  k->p++; /* pass the CR byte */
3035  }
3036  if(0x0a == *k->p) {
3037  *k->p = '\n'; /* replace with LF in host encoding */
3038  k->p++; /* pass the LF byte */
3039  }
3040 #else
3041  if('\r' == *k->p)
3042  k->p++; /* pass the \r byte */
3043  if('\n' == *k->p)
3044  k->p++; /* pass the \n byte */
3045 #endif /* CURL_DOES_CONVERSIONS */
3046 
3047  if(100 <= k->httpcode && 199 >= k->httpcode) {
3048  /* "A user agent MAY ignore unexpected 1xx status responses." */
3049  switch(k->httpcode) {
3050  case 100:
3051  /*
3052  * We have made a HTTP PUT or POST and this is 1.1-lingo
3053  * that tells us that the server is OK with this and ready
3054  * to receive the data.
3055  * However, we'll get more headers now so we must get
3056  * back into the header-parsing state!
3057  */
3058  k->header = TRUE;
3059  k->headerline = 0; /* restart the header line counter */
3060 
3061  /* if we did wait for this do enable write now! */
3062  if(k->exp100 > EXP100_SEND_DATA) {
3063  k->exp100 = EXP100_SEND_DATA;
3064  k->keepon |= KEEP_SEND;
3066  }
3067  break;
3068  case 101:
3069  /* Switching Protocols */
3070  if(k->upgr101 == UPGR101_REQUESTED) {
3071  /* Switching to HTTP/2 */
3072  infof(data, "Received 101\n");
3074 
3075  /* we'll get more headers (HTTP/2 response) */
3076  k->header = TRUE;
3077  k->headerline = 0; /* restart the header line counter */
3078 
3079  /* switch to http2 now. The bytes after response headers
3080  are also processed here, otherwise they are lost. */
3081  result = Curl_http2_switched(conn, k->str, *nread);
3082  if(result)
3083  return result;
3084  *nread = 0;
3085  }
3086  else {
3087  /* Switching to another protocol (e.g. WebSocket) */
3088  k->header = FALSE; /* no more header to parse! */
3089  }
3090  break;
3091  default:
3092  /* the status code 1xx indicates a provisional response, so
3093  we'll get another set of headers */
3094  k->header = TRUE;
3095  k->headerline = 0; /* restart the header line counter */
3096  break;
3097  }
3098  }
3099  else {
3100  k->header = FALSE; /* no more header to parse! */
3101 
3102  if((k->size == -1) && !k->chunk && !conn->bits.close &&
3103  (conn->httpversion == 11) &&
3104  !(conn->handler->protocol & CURLPROTO_RTSP) &&
3105  data->set.httpreq != HTTPREQ_HEAD) {
3106  /* On HTTP 1.1, when connection is not to get closed, but no
3107  Content-Length nor Content-Encoding chunked have been
3108  received, according to RFC2616 section 4.4 point 5, we
3109  assume that the server will close the connection to
3110  signal the end of the document. */
3111  infof(data, "no chunk, no close, no size. Assume close to "
3112  "signal end\n");
3113  streamclose(conn, "HTTP: No end-of-message indicator");
3114  }
3115  }
3116 
3117  /* At this point we have some idea about the fate of the connection.
3118  If we are closing the connection it may result auth failure. */
3119 #if defined(USE_NTLM)
3120  if(conn->bits.close &&
3121  (((data->req.httpcode == 401) &&
3122  (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
3123  ((data->req.httpcode == 407) &&
3124  (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
3125  infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3126  data->state.authproblem = TRUE;
3127  }
3128 #endif
3129 
3130  /*
3131  * When all the headers have been parsed, see if we should give
3132  * up and return an error.
3133  */
3134  if(http_should_fail(conn)) {
3135  failf(data, "The requested URL returned error: %d",
3136  k->httpcode);
3138  }
3139 
3140  /* now, only output this if the header AND body are requested:
3141  */
3142  writetype = CLIENTWRITE_HEADER;
3143  if(data->set.include_header)
3144  writetype |= CLIENTWRITE_BODY;
3145 
3146  headerlen = k->p - data->state.headerbuff;
3147 
3148  result = Curl_client_write(conn, writetype,
3149  data->state.headerbuff,
3150  headerlen);
3151  if(result)
3152  return result;
3153 
3154  data->info.header_size += (long)headerlen;
3155  data->req.headerbytecount += (long)headerlen;
3156 
3157  data->req.deductheadercount =
3158  (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3159 
3160  /* Curl_http_auth_act() checks what authentication methods
3161  * that are available and decides which one (if any) to
3162  * use. It will set 'newurl' if an auth method was picked. */
3163  result = Curl_http_auth_act(conn);
3164 
3165  if(result)
3166  return result;
3167 
3168  if(k->httpcode >= 300) {
3169  if((!conn->bits.authneg) && !conn->bits.close &&
3170  !conn->bits.rewindaftersend) {
3171  /*
3172  * General treatment of errors when about to send data. Including :
3173  * "417 Expectation Failed", while waiting for 100-continue.
3174  *
3175  * The check for close above is done simply because of something
3176  * else has already deemed the connection to get closed then
3177  * something else should've considered the big picture and we
3178  * avoid this check.
3179  *
3180  * rewindaftersend indicates that something has told libcurl to
3181  * continue sending even if it gets discarded
3182  */
3183 
3184  switch(data->set.httpreq) {
3185  case HTTPREQ_PUT:
3186  case HTTPREQ_POST:
3187  case HTTPREQ_POST_FORM:
3188  case HTTPREQ_POST_MIME:
3189  /* We got an error response. If this happened before the whole
3190  * request body has been sent we stop sending and mark the
3191  * connection for closure after we've read the entire response.
3192  */
3194  if(!k->upload_done) {
3195  if(data->set.http_keep_sending_on_error) {
3196  infof(data, "HTTP error before end of send, keep sending\n");
3197  if(k->exp100 > EXP100_SEND_DATA) {
3198  k->exp100 = EXP100_SEND_DATA;
3199  k->keepon |= KEEP_SEND;
3200  }
3201  }
3202  else {
3203  infof(data, "HTTP error before end of send, stop sending\n");
3204  streamclose(conn, "Stop sending data before everything sent");
3205  k->upload_done = TRUE;
3206  k->keepon &= ~KEEP_SEND; /* don't send */
3207  if(data->state.expect100header)
3208  k->exp100 = EXP100_FAILED;
3209  }
3210  }
3211  break;
3212 
3213  default: /* default label present to avoid compiler warnings */
3214  break;
3215  }
3216  }
3217 
3218  if(conn->bits.rewindaftersend) {
3219  /* We rewind after a complete send, so thus we continue
3220  sending now */
3221  infof(data, "Keep sending data to get tossed away!\n");
3222  k->keepon |= KEEP_SEND;
3223  }
3224  }
3225 
3226  if(!k->header) {
3227  /*
3228  * really end-of-headers.
3229  *
3230  * If we requested a "no body", this is a good time to get
3231  * out and return home.
3232  */
3233  if(data->set.opt_no_body)
3234  *stop_reading = TRUE;
3235 #ifndef CURL_DISABLE_RTSP
3236  else if((conn->handler->protocol & CURLPROTO_RTSP) &&
3237  (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
3238  (k->size <= -1))
3239  /* Respect section 4.4 of rfc2326: If the Content-Length header is
3240  absent, a length 0 must be assumed. It will prevent libcurl from
3241  hanging on DESCRIBE request that got refused for whatever
3242  reason */
3243  *stop_reading = TRUE;
3244 #endif
3245  else {
3246  /* If we know the expected size of this document, we set the
3247  maximum download size to the size of the expected
3248  document or else, we won't know when to stop reading!
3249 
3250  Note that we set the download maximum even if we read a
3251  "Connection: close" header, to make sure that
3252  "Content-Length: 0" still prevents us from attempting to
3253  read the (missing) response-body.
3254  */
3255  /* According to RFC2616 section 4.4, we MUST ignore
3256  Content-Length: headers if we are now receiving data
3257  using chunked Transfer-Encoding.
3258  */
3259  if(k->chunk)
3260  k->maxdownload = k->size = -1;
3261  }
3262  if(-1 != k->size) {
3263  /* We do this operation even if no_body is true, since this
3264  data might be retrieved later with curl_easy_getinfo()
3265  and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3266 
3267  Curl_pgrsSetDownloadSize(data, k->size);
3268  k->maxdownload = k->size;
3269  }
3270 
3271  /* If max download size is *zero* (nothing) we already have
3272  nothing and can safely return ok now! But for HTTP/2, we'd
3273  like to call http2_handle_stream_close to properly close a
3274  stream. In order to do this, we keep reading until we
3275  close the stream. */
3276  if(0 == k->maxdownload
3277 #if defined(USE_NGHTTP2)
3278  && !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
3279  conn->httpversion == 20)
3280 #endif
3281  )
3282  *stop_reading = TRUE;
3283 
3284  if(*stop_reading) {
3285  /* we make sure that this socket isn't read more now */
3286  k->keepon &= ~KEEP_RECV;
3287  }
3288 
3289  if(data->set.verbose)
3291  k->str_start, headerlen, conn);
3292  break; /* exit header line loop */
3293  }
3294 
3295  /* We continue reading headers, so reset the line-based
3296  header parsing variables hbufp && hbuflen */
3297  k->hbufp = data->state.headerbuff;
3298  k->hbuflen = 0;
3299  continue;
3300  }
3301 
3302  /*
3303  * Checks for special headers coming up.
3304  */
3305 
3306  if(!k->headerline++) {
3307  /* This is the first header, it MUST be the error code line
3308  or else we consider this to be the body right away! */
3309  int httpversion_major;
3310  int rtspversion_major;
3311  int nc = 0;
3312 #ifdef CURL_DOES_CONVERSIONS
3313 #define HEADER1 scratch
3314 #define SCRATCHSIZE 21
3315  CURLcode res;
3316  char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
3317  /* We can't really convert this yet because we
3318  don't know if it's the 1st header line or the body.
3319  So we do a partial conversion into a scratch area,
3320  leaving the data at k->p as-is.
3321  */
3322  strncpy(&scratch[0], k->p, SCRATCHSIZE);
3323  scratch[SCRATCHSIZE] = 0; /* null terminate */
3324  res = Curl_convert_from_network(data,
3325  &scratch[0],
3326  SCRATCHSIZE);
3327  if(res)
3328  /* Curl_convert_from_network calls failf if unsuccessful */
3329  return res;
3330 #else
3331 #define HEADER1 k->p /* no conversion needed, just use k->p */
3332 #endif /* CURL_DOES_CONVERSIONS */
3333 
3334  if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3335  /*
3336  * https://tools.ietf.org/html/rfc7230#section-3.1.2
3337  *
3338  * The response code is always a three-digit number in HTTP as the spec
3339  * says. We try to allow any number here, but we cannot make
3340  * guarantees on future behaviors since it isn't within the protocol.
3341  */
3342  char separator;
3343  nc = sscanf(HEADER1,
3344  " HTTP/%1d.%1d%c%3d",
3345  &httpversion_major,
3346  &conn->httpversion,
3347  &separator,
3348  &k->httpcode);
3349 
3350  if(nc == 1 && httpversion_major == 2 &&
3351  1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
3352  conn->httpversion = 0;
3353  nc = 4;
3354  separator = ' ';
3355  }
3356 
3357  if((nc == 4) && (' ' == separator)) {
3358  conn->httpversion += 10 * httpversion_major;
3359 
3360  if(k->upgr101 == UPGR101_RECEIVED) {
3361  /* supposedly upgraded to http2 now */
3362  if(conn->httpversion != 20)
3363  infof(data, "Lying server, not serving HTTP/2\n");
3364  }
3365  }
3366  else if(!nc) {
3367  /* this is the real world, not a Nirvana
3368  NCSA 1.5.x returns this crap when asked for HTTP/1.1
3369  */
3370  nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3371  conn->httpversion = 10;
3372 
3373  /* If user has set option HTTP200ALIASES,
3374  compare header line against list of aliases
3375  */
3376  if(!nc) {
3377  if(checkhttpprefix(data, k->p)) {
3378  nc = 1;
3379  k->httpcode = 200;
3380  conn->httpversion = 10;
3381  }
3382  }
3383  }
3384  else {
3385  failf(data, "Unsupported HTTP version in response\n");
3387  }
3388  }
3389  else if(conn->handler->protocol & CURLPROTO_RTSP) {
3390  nc = sscanf(HEADER1,
3391  " RTSP/%d.%d %3d",
3392  &rtspversion_major,
3393  &conn->rtspversion,
3394  &k->httpcode);
3395  if(nc == 3) {
3396  conn->rtspversion += 10 * rtspversion_major;
3397  conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3398  }
3399  else {
3400  /* TODO: do we care about the other cases here? */
3401  nc = 0;
3402  }
3403  }
3404 
3405  if(nc) {
3406  data->info.httpcode = k->httpcode;
3407 
3408  data->info.httpversion = conn->httpversion;
3409  if(!data->state.httpversion ||
3410  data->state.httpversion > conn->httpversion)
3411  /* store the lowest server version we encounter */
3412  data->state.httpversion = conn->httpversion;
3413 
3414  /*
3415  * This code executes as part of processing the header. As a
3416  * result, it's not totally clear how to interpret the
3417  * response code yet as that depends on what other headers may
3418  * be present. 401 and 407 may be errors, but may be OK
3419  * depending on how authentication is working. Other codes
3420  * are definitely errors, so give up here.
3421  */
3422  if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3423  ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3424  ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3425 
3426  if(data->state.resume_from &&
3427  (data->set.httpreq == HTTPREQ_GET) &&
3428  (k->httpcode == 416)) {
3429  /* "Requested Range Not Satisfiable", just proceed and
3430  pretend this is no error */
3431  }
3432  else {
3433  /* serious error, go home! */
3434  print_http_error(data);
3436  }
3437  }
3438 
3439  if(conn->httpversion == 10) {
3440  /* Default action for HTTP/1.0 must be to close, unless
3441  we get one of those fancy headers that tell us the
3442  server keeps it open for us! */
3443  infof(data, "HTTP 1.0, assume close after body\n");
3444  connclose(conn, "HTTP/1.0 close after body");
3445  }
3446  else if(conn->httpversion == 20 ||
3447  (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3448  DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
3449 
3450  /* HTTP/2 cannot blacklist multiplexing since it is a core
3451  functionality of the protocol */
3452  conn->bundle->multiuse = BUNDLE_MULTIPLEX;
3453  }
3454  else if(conn->httpversion >= 11 &&
3455  !conn->bits.close) {
3456  /* If HTTP version is >= 1.1 and connection is persistent
3457  server supports pipelining. */
3458  DEBUGF(infof(data,
3459  "HTTP 1.1 or later with persistent connection, "
3460  "pipelining supported\n"));
3461  /* Activate pipelining if needed */
3462  if(conn->bundle) {
3463  if(!Curl_pipeline_site_blacklisted(data, conn))
3465  }
3466  }
3467 
3468  switch(k->httpcode) {
3469  case 204:
3470  /* (quote from RFC2616, section 10.2.5): The server has
3471  * fulfilled the request but does not need to return an
3472  * entity-body ... The 204 response MUST NOT include a
3473  * message-body, and thus is always terminated by the first
3474  * empty line after the header fields. */
3475  /* FALLTHROUGH */
3476  case 304:
3477  /* (quote from RFC2616, section 10.3.5): The 304 response
3478  * MUST NOT contain a message-body, and thus is always
3479  * terminated by the first empty line after the header
3480  * fields. */
3481  if(data->set.timecondition)
3482  data->info.timecond = TRUE;
3483  k->size = 0;
3484  k->maxdownload = 0;
3485  k->ignorecl = TRUE; /* ignore Content-Length headers */
3486  break;
3487  default:
3488  /* nothing */
3489  break;
3490  }
3491  }
3492  else {
3493  k->header = FALSE; /* this is not a header line */
3494  break;
3495  }
3496  }
3497 
3498  result = Curl_convert_from_network(data, k->p, strlen(k->p));
3499  /* Curl_convert_from_network calls failf if unsuccessful */
3500  if(result)
3501  return result;
3502 
3503  /* Check for Content-Length: header lines to get size */
3504  if(!k->ignorecl && !data->set.ignorecl &&
3505  checkprefix("Content-Length:", k->p)) {
3506  curl_off_t contentlength;
3507  if(!curlx_strtoofft(k->p + 15, NULL, 10, &contentlength)) {
3508  if(data->set.max_filesize &&
3509  contentlength > data->set.max_filesize) {
3510  failf(data, "Maximum file size exceeded");
3511  return CURLE_FILESIZE_EXCEEDED;
3512  }
3513  if(contentlength >= 0) {
3514  k->size = contentlength;
3515  k->maxdownload = k->size;
3516  /* we set the progress download size already at this point
3517  just to make it easier for apps/callbacks to extract this
3518  info as soon as possible */
3519  Curl_pgrsSetDownloadSize(data, k->size);
3520  }
3521  else {
3522  /* Negative Content-Length is really odd, and we know it
3523  happens for example when older Apache servers send large
3524  files */
3525  streamclose(conn, "negative content-length");
3526  infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
3527  ", closing after transfer\n", contentlength);
3528  }
3529  }
3530  else
3531  infof(data, "Illegal Content-Length: header\n");
3532  }
3533  /* check for Content-Type: header lines to get the MIME-type */
3534  else if(checkprefix("Content-Type:", k->p)) {
3535  char *contenttype = Curl_copy_header_value(k->p);
3536  if(!contenttype)
3537  return CURLE_OUT_OF_MEMORY;
3538  if(!*contenttype)
3539  /* ignore empty data */
3540  free(contenttype);
3541  else {
3543  data->info.contenttype = contenttype;
3544  }
3545  }
3546  else if(checkprefix("Server:", k->p)) {
3547  if(conn->httpversion < 20) {
3548  /* only do this for non-h2 servers */
3549  char *server_name = Curl_copy_header_value(k->p);
3550 
3551  /* Turn off pipelining if the server version is blacklisted */
3552  if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
3553  if(Curl_pipeline_server_blacklisted(data, server_name))
3555  }
3556  free(server_name);
3557  }
3558  }
3559  else if((conn->httpversion == 10) &&
3560  conn->bits.httpproxy &&
3561  Curl_compareheader(k->p,
3562  "Proxy-Connection:", "keep-alive")) {
3563  /*
3564  * When a HTTP/1.0 reply comes when using a proxy, the
3565  * 'Proxy-Connection: keep-alive' line tells us the
3566  * connection will be kept alive for our pleasure.
3567  * Default action for 1.0 is to close.
3568  */
3569  connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3570  infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3571  }
3572  else if((conn->httpversion == 11) &&
3573  conn->bits.httpproxy &&
3574  Curl_compareheader(k->p,
3575  "Proxy-Connection:", "close")) {
3576  /*
3577  * We get a HTTP/1.1 response from a proxy and it says it'll
3578  * close down after this transfer.
3579  */
3580  connclose(conn, "Proxy-Connection: asked to close after done");
3581  infof(data, "HTTP/1.1 proxy connection set close!\n");
3582  }
3583  else if((conn->httpversion == 10) &&
3584  Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3585  /*
3586  * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3587  * tells us the connection will be kept alive for our
3588  * pleasure. Default action for 1.0 is to close.
3589  *
3590  * [RFC2068, section 19.7.1] */
3591  connkeep(conn, "Connection keep-alive");
3592  infof(data, "HTTP/1.0 connection set to keep alive!\n");
3593  }
3594  else if(Curl_compareheader(k->p, "Connection:", "close")) {
3595  /*
3596  * [RFC 2616, section 8.1.2.1]
3597  * "Connection: close" is HTTP/1.1 language and means that
3598  * the connection will close when this request has been
3599  * served.
3600  */
3601  streamclose(conn, "Connection: close used");
3602  }
3603  else if(checkprefix("Transfer-Encoding:", k->p)) {
3604  /* One or more encodings. We check for chunked and/or a compression
3605  algorithm. */
3606  /*
3607  * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3608  * means that the server will send a series of "chunks". Each
3609  * chunk starts with line with info (including size of the
3610  * coming block) (terminated with CRLF), then a block of data
3611  * with the previously mentioned size. There can be any amount
3612  * of chunks, and a chunk-data set to zero signals the
3613  * end-of-chunks. */
3614 
3615  char *start;
3616 
3617  /* Find the first non-space letter */
3618  start = k->p + 18;
3619 
3620  for(;;) {
3621  /* skip whitespaces and commas */
3622  while(*start && (ISSPACE(*start) || (*start == ',')))
3623  start++;
3624 
3625  if(checkprefix("chunked", start)) {
3626  k->chunk = TRUE; /* chunks coming our way */
3627 
3628  /* init our chunky engine */
3629  Curl_httpchunk_init(conn);
3630 
3631  start += 7;
3632  }
3633 
3634  if(k->auto_decoding)
3635  /* TODO: we only support the first mentioned compression for now */
3636  break;
3637 
3638  if(checkprefix("identity", start)) {
3639  k->auto_decoding = IDENTITY;
3640  start += 8;
3641  }
3642  else if(checkprefix("deflate", start)) {
3643  k->auto_decoding = DEFLATE;
3644  start += 7;
3645  }
3646  else if(checkprefix("gzip", start)) {
3647  k->auto_decoding = GZIP;
3648  start += 4;
3649  }
3650  else if(checkprefix("x-gzip", start)) {
3651  k->auto_decoding = GZIP;
3652  start += 6;
3653  }
3654  else
3655  /* unknown! */
3656  break;
3657 
3658  }
3659 
3660  }
3661  else if(checkprefix("Content-Encoding:", k->p) &&
3662  data->set.str[STRING_ENCODING]) {
3663  /*
3664  * Process Content-Encoding. Look for the values: identity,
3665  * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3666  * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3667  * 2616). zlib cannot handle compress. However, errors are
3668  * handled further down when the response body is processed
3669  */
3670  char *start;
3671 
3672  /* Find the first non-space letter */
3673  start = k->p + 17;
3674  while(*start && ISSPACE(*start))
3675  start++;
3676 
3677  /* Record the content-encoding for later use */
3678  if(checkprefix("identity", start))
3679  k->auto_decoding = IDENTITY;
3680  else if(checkprefix("deflate", start))
3681  k->auto_decoding = DEFLATE;
3682  else if(checkprefix("gzip", start)
3683  || checkprefix("x-gzip", start))
3684  k->auto_decoding = GZIP;
3685  }
3686  else if(checkprefix("Content-Range:", k->p)) {
3687  /* Content-Range: bytes [num]-
3688  Content-Range: bytes: [num]-
3689  Content-Range: [num]-
3690  Content-Range: [asterisk]/[total]
3691 
3692  The second format was added since Sun's webserver
3693  JavaWebServer/1.1.1 obviously sends the header this way!
3694  The third added since some servers use that!
3695  The forth means the requested range was unsatisfied.
3696  */
3697 
3698  char *ptr = k->p + 14;
3699 
3700  /* Move forward until first digit or asterisk */
3701  while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
3702  ptr++;
3703 
3704  /* if it truly stopped on a digit */
3705  if(ISDIGIT(*ptr)) {
3706  if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) {
3707  if(data->state.resume_from == k->offset)
3708  /* we asked for a resume and we got it */
3709  k->content_range = TRUE;
3710  }
3711  }
3712  else
3713  data->state.resume_from = 0; /* get everything */
3714  }
3715 #if !defined(CURL_DISABLE_COOKIES)
3716  else if(data->cookies &&
3717  checkprefix("Set-Cookie:", k->p)) {
3720  Curl_cookie_add(data,
3721  data->cookies, TRUE, k->p + 11,
3722  /* If there is a custom-set Host: name, use it
3723  here, or else use real peer host name. */
3724  conn->allocptr.cookiehost?
3725  conn->allocptr.cookiehost:conn->host.name,
3726  data->state.path);
3728  }
3729 #endif
3730  else if(checkprefix("Last-Modified:", k->p) &&
3731  (data->set.timecondition || data->set.get_filetime) ) {
3732  time_t secs = time(NULL);
3733  k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
3734  &secs);
3735  if(data->set.get_filetime)
3736  data->info.filetime = (long)k->timeofdoc;
3737  }
3738  else if((checkprefix("WWW-Authenticate:", k->p) &&
3739  (401 == k->httpcode)) ||
3740  (checkprefix("Proxy-authenticate:", k->p) &&
3741  (407 == k->httpcode))) {
3742 
3743  bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3744  char *auth = Curl_copy_header_value(k->p);
3745  if(!auth)
3746  return CURLE_OUT_OF_MEMORY;
3747 
3748  result = Curl_http_input_auth(conn, proxy, auth);
3749 
3750  free(auth);
3751 
3752  if(result)
3753  return result;
3754  }
3755  else if((k->httpcode >= 300 && k->httpcode < 400) &&
3756  checkprefix("Location:", k->p) &&
3757  !data->req.location) {
3758  /* this is the URL that the server advises us to use instead */
3759  char *location = Curl_copy_header_value(k->p);
3760  if(!location)
3761  return CURLE_OUT_OF_MEMORY;
3762  if(!*location)
3763  /* ignore empty data */
3764  free(location);
3765  else {
3766  data->req.location = location;
3767 
3768  if(data->set.http_follow_location) {
3769  DEBUGASSERT(!data->req.newurl);
3770  data->req.newurl = strdup(data->req.location); /* clone */
3771  if(!data->req.newurl)
3772  return CURLE_OUT_OF_MEMORY;
3773 
3774  /* some cases of POST and PUT etc needs to rewind the data
3775  stream at this point */
3776  result = http_perhapsrewind(conn);
3777  if(result)
3778  return result;
3779  }
3780  }
3781  }
3782  else if(conn->handler->protocol & CURLPROTO_RTSP) {
3783  result = Curl_rtsp_parseheader(conn, k->p);
3784  if(result)
3785  return result;
3786  }
3787 
3788  /*
3789  * End of header-checks. Write them to the client.
3790  */
3791 
3792  writetype = CLIENTWRITE_HEADER;
3793  if(data->set.include_header)
3794  writetype |= CLIENTWRITE_BODY;
3795 
3796  if(data->set.verbose)
3798  k->p, (size_t)k->hbuflen, conn);
3799 
3800  result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3801  if(result)
3802  return result;
3803 
3804  data->info.header_size += (long)k->hbuflen;
3805  data->req.headerbytecount += (long)k->hbuflen;
3806 
3807  /* reset hbufp pointer && hbuflen */
3808  k->hbufp = data->state.headerbuff;
3809  k->hbuflen = 0;
3810  }
3811  while(*k->str); /* header line within buffer */
3812 
3813  /* We might have reached the end of the header part here, but
3814  there might be a non-header part left in the end of the read
3815  buffer. */
3816 
3817  return CURLE_OK;
3818 }
3819 
3820 #endif /* CURL_DISABLE_HTTP */
#define free(ptr)
Definition: curl_memory.h:130
bool timecond
Definition: urldata.h:1059
int Curl_debug(struct Curl_easy *data, curl_infotype type, char *ptr, size_t size, struct connectdata *conn)
Definition: sendf.c:819
size_t size_max
Definition: http.h:55
char * str_start
Definition: urldata.h:551
#define PROTOPT_ALPN_NPN
Definition: urldata.h:715
bool upload_chunky
Definition: urldata.h:606
#define CONNECT_FIRSTSOCKET_PROXY_SSL()
Definition: url.h:85
curl_mimepart mimepost
Definition: urldata.h:1563
#define state(x, y)
Definition: ftp.c:100
#define DEFLATE
Definition: urldata.h:566
#define CLIENTWRITE_BODY
Definition: sendf.h:50
char * end_ptr
Definition: urldata.h:552
#define CURLPROTO_HTTP
Definition: curl.h:844
struct ConnectBits bits
Definition: urldata.h:893
CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, struct curl_slist *headers, int take_ownership)
Definition: mime.c:1352
const char *const Curl_wkday[]
Definition: parsedate.c:87
#define CURL_SEEKFUNC_OK
Definition: curl.h:340
bool close
Definition: urldata.h:376
struct UserDefined set
Definition: urldata.h:1762
#define CURLAUTH_BASIC
Definition: curl.h:697
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, const char *auth)
Definition: http.c:734
static bool checkrtspprefix(struct Curl_easy *data, const char *s)
Definition: http.c:2823
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:304
#define connclose(x, y)
Definition: connect.h:141
curl_off_t resume_from
Definition: urldata.h:1338
void Curl_expire_done(struct Curl_easy *data, expire_id id)
Definition: multi.c:2995
curl_off_t size
Definition: urldata.h:519
enum expect100 exp100
Definition: urldata.h:560
bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle, struct connectdata *conn)
Definition: pipeline.c:164
#define MAX_INITIAL_POST_SIZE
Definition: http.h:113
bool opt_no_body
Definition: urldata.h:1631
char * url
Definition: urldata.h:1372
int negnpn
Definition: urldata.h:1027
char * range
Definition: urldata.h:1336
#define FIRSTSOCKET
Definition: urldata.h:487
Curl_HttpReq
Definition: urldata.h:1139
curl_off_t readbytecount
Definition: http.h:137
void Curl_httpchunk_init(struct connectdata *conn)
Definition: http_chunks.c:86
#define streamclose(x, y)
Definition: connect.h:140
CURLcode Curl_http_auth_act(struct connectdata *conn)
Definition: http.c:476
void Curl_add_buffer_free(Curl_send_buffer *buff)
Definition: http.c:1037
curl_off_t set_resume_from
Definition: urldata.h:1559
long filetime
Definition: urldata.h:1055
long request_size
Definition: urldata.h:1062
bool prefer_ascii
Definition: urldata.h:1618
#define GZIP
Definition: urldata.h:567
CURLcode Curl_add_timecondition(struct Curl_easy *data, Curl_send_buffer *req_buffer)
Definition: http.c:1684
bool include_header
Definition: urldata.h:1628
#define CURL_SEEKFUNC_CANTSEEK
Definition: curl.h:342
CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
Definition: http.c:1223
bool http_keep_sending_on_error
Definition: urldata.h:1624
char * first_host
Definition: urldata.h:1259
void Curl_mime_cleanpart(curl_mimepart *part)
Definition: mime.c:1097
int rtspversion
Definition: urldata.h:872
#define failf
Definition: sendf.h:48
char * Curl_checkProxyheaders(const struct connectdata *conn, const char *thisheader)
Definition: http.c:185
char * data
Definition: curl.h:2336
const char *const Curl_month[]
Definition: parsedate.c:92
#define strdup(ptr)
Definition: curl_memory.h:122
bool protoconnstart
Definition: urldata.h:395
XmlRpcServer s
CURLcode Curl_base64_encode(struct Curl_easy *data, const char *inputbuff, size_t insize, char **outptr, size_t *outlen)
Definition: base64.c:291
const struct Curl_handler * handler
Definition: urldata.h:904
#define CURL_MAX_WRITE_SIZE
Definition: curl.h:229
static char server_name[50]
Definition: web_server.c:70
Definition: cookie.h:28
#define DEBUGASSERT(x)
UNITTEST_START char * ptr
Definition: unit1330.c:38
CURLcode
Definition: curl.h:454
static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
Definition: http.c:263
unsigned int flags
Definition: mime.h:115
char * value
Definition: cookie.h:31
#define BUNDLE_NO_MULTIUSE
Definition: conncache.h:33
bool http_transfer_encoding
Definition: urldata.h:1626
#define EXPECT_100_THRESHOLD
Definition: http.h:122
#define Curl_http2_request_upgrade(x, y)
Definition: http2.h:65
bool http_fail_on_error
Definition: urldata.h:1623
#define KEEP_RECV
Definition: urldata.h:453
#define MIME_BODY_ONLY
Definition: mime.h:31
static CURLcode output_auth_headers(struct connectdata *conn, struct auth *authstatus, const char *request, const char *path, bool proxy)
Definition: http.c:551
enum mimekind kind
Definition: mime.h:102
const char * postdata
Definition: http.h:146
CURLcode Curl_mime_prepare_headers(curl_mimepart *part, const char *contenttype, const char *disposition, enum mimestrategy strategy)
Definition: mime.c:1577
enum upgrade101 upgr101
Definition: urldata.h:561
#define SECONDARYSOCKET
Definition: urldata.h:488
static int res
struct hostname host
Definition: urldata.h:833
Curl_HttpReq httpreq
Definition: urldata.h:1582
#define realloc(ptr, size)
Definition: curl_memory.h:128
#define Curl_http2_done(x, y)
Definition: http2.h:72
bool header
Definition: urldata.h:538
bool authneg
Definition: urldata.h:404
#define Curl_ssl_connect_nonblocking(x, y, z)
Definition: vtls.h:267
struct curl_slist * headers
Definition: urldata.h:1560
#define strcasecompare(a, b)
Definition: strcase.h:35
#define malloc(size)
Definition: curl_memory.h:124
void * seek_client
Definition: urldata.h:1536
CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
Definition: http.c:1337
proxy_use
Definition: http.c:1553
bool expect100header
Definition: urldata.h:1314
curl_mimepart form
Definition: http.h:141
bool connect_only
Definition: urldata.h:1653
static CURLcode header_append(struct Curl_easy *data, struct SingleRequest *k, size_t length)
Definition: http.c:2870
char * name
Definition: urldata.h:444
UNITTEST_START int result
Definition: unit1304.c:49
#define CURLPROTO_FTP
Definition: curl.h:846
const char ** p
Definition: unit1394.c:76
const char * p_accept
Definition: http.h:136
static size_t readmoredata(char *buffer, size_t size, size_t nitems, void *userp)
Definition: http.c:979
char buffer[]
Definition: unit1308.c:48
CURLcode Curl_input_digest(struct connectdata *conn, bool proxy, const char *header)
Definition: http_digest.c:43
Definition: http.h:130
bool upload_done
Definition: urldata.h:583
bool this_is_a_follow
Definition: urldata.h:1257
unsigned int i
Definition: unit1303.c:79
struct DynamicStatic change
Definition: urldata.h:1763
char * p
Definition: urldata.h:553
#define CURLMIN(x, y)
Definition: urldata.h:153
static bool use_http_1_1plus(const struct Curl_easy *data, const struct connectdata *conn)
Definition: http.c:1497
int httpcode
Definition: urldata.h:1052
size_t len
Definition: curl_sasl.c:55
struct proxy_info http_proxy
Definition: urldata.h:839
curl_off_t offset
Definition: urldata.h:555
curl_seek_callback seek_func
Definition: urldata.h:965
char * passwd
Definition: urldata.h:866
#define PROTOPT_SSL
Definition: urldata.h:700
unsigned int protocol
Definition: urldata.h:694
bool ignorecl
Definition: urldata.h:1650
long headerbytecount
Definition: urldata.h:529
static int http_should_fail(struct connectdata *conn)
http_should_fail() determines whether an HTTP response has gotten us into an error state or not...
Definition: http.c:909
bool Curl_compareheader(const char *headerline, const char *header, const char *content)
Definition: http.c:1285
long httpversion
Definition: urldata.h:1583
time_t timeofdoc
Definition: urldata.h:575
int Curl_pgrsUpdate(struct connectdata *conn)
Definition: progress.c:350
int headerline
Definition: urldata.h:546
bool content_range
Definition: urldata.h:554
#define BUNDLE_MULTIPLEX
Definition: conncache.h:36
curl_off_t writebytecount
Definition: http.h:138
memcpy(filename, filename1, strlen(filename1))
#define CURLAUTH_NEGOTIATE
Definition: curl.h:699
Definition: urldata.h:1179
#define Curl_http2_switched(x, y, z)
Definition: http2.h:67
bool userpwd_in_url
Definition: urldata.h:421
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
Definition: mime.c:1428
int httpversion
Definition: urldata.h:871
CURLcode Curl_readrewind(struct connectdata *conn)
Definition: transfer.c:268
#define ZERO_NULL
Definition: curlx.c:131
bool http_follow_location
Definition: urldata.h:1625
#define CURLAUTH_NONE
Definition: curl.h:696
CURLSHcode Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
Definition: share.c:231
void * fread_in
Definition: http.h:145
#define CURLPROTO_HTTPS
Definition: curl.h:845
enum SingleRequest::@32 badheader
#define CURLPROTO_RTSP
Definition: curl.h:862
void Curl_setup_transfer(struct connectdata *conn, int sockindex, curl_off_t size, bool getheader, curl_off_t *bytecountp, int writesockindex, curl_off_t *writecountp)
Definition: transfer.c:1989
#define FALSE
char * buffer
Definition: urldata.h:1253
char * contenttype
Definition: urldata.h:1066
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
char * referer
Definition: urldata.h:1374
struct SingleRequest req
Definition: urldata.h:1761
unsigned int flags
Definition: urldata.h:696
UNITTEST_START int rc
Definition: unit1301.c:31
curl_read_callback fread_func
Definition: http.h:144
long deductheadercount
Definition: urldata.h:530
curl_off_t infilesize
Definition: urldata.h:1345
struct curl_slist * http200aliases
Definition: urldata.h:1594
CURLcode Curl_mime_rewind(curl_mimepart *part)
Definition: mime.c:1437
static bool pickoneauth(struct auth *pick)
Definition: http.c:318
bool url_alloc
Definition: urldata.h:1373
static CURLcode http_perhapsrewind(struct connectdata *conn)
Definition: http.c:369
struct curl_slist * next
Definition: curl.h:2337
char * Curl_copy_header_value(const char *header)
Definition: http.c:208
bool proxy
Definition: urldata.h:382
#define ISDIGIT(x)
#define fail(msg)
Definition: curlcheck.h:51
CURLofft curlx_strtoofft(const char *str, char **endp, int base, curl_off_t *num)
Definition: strtoofft.c:215
bool use_range
Definition: urldata.h:1333
bool httpproxy
Definition: urldata.h:383
bool tunnel_proxy
Definition: urldata.h:400
bool http_disable_hostname_check_before_authentication
Definition: urldata.h:1627
UNITTEST_START struct Curl_easy data
Definition: unit1399.c:82
bool Curl_auth_is_digest_supported(void)
Definition: digest.c:318
bool user_passwd
Definition: urldata.h:385
#define strncasecompare(a, b, c)
Definition: strcase.h:36
void * Curl_saferealloc(void *ptr, size_t size)
Definition: strdup.c:93
enum HTTP::@27 sending
#define Curl_convert_from_network(a, b, c)
Definition: non-ascii.h:57
void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:334
#define BUNDLE_PIPELINING
Definition: conncache.h:35
void * send_buffer
Definition: http.h:157
bool forbidchunk
Definition: urldata.h:610
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
Definition: progress.c:322
#define Curl_convert_to_network(a, b, c)
Definition: non-ascii.h:56
#define GETSOCK_BLANK
Definition: multiif.h:42
static int http_getsock_do(struct connectdata *conn, curl_socket_t *socks, int numsocks)
Definition: http.c:1376
int httpversion
Definition: urldata.h:1054
CURL_TYPEOF_CURL_OFF_T curl_off_t
Definition: system.h:420
struct curl_httppost * httppost
Definition: urldata.h:1562
#define CLIENTWRITE_HEADER
Definition: sendf.h:51
#define KEEP_SEND
Definition: urldata.h:454
struct CookieInfo * cookies
Definition: urldata.h:1764
char * passwd
Definition: urldata.h:762
CURLcode Curl_add_buffer_send(Curl_send_buffer *in, struct connectdata *conn, long *bytes_written, size_t included_body_bytes, int socketindex)
Definition: http.c:1050
size_t(* curl_read_callback)(char *buffer, size_t size, size_t nitems, void *instream)
Definition: curl.h:355
char * headerbuff
Definition: urldata.h:1250
struct curltime start
Definition: urldata.h:536
#define CURLAUTH_NTLM
Definition: curl.h:704
CURLcode Curl_write(struct connectdata *conn, curl_socket_t sockfd, const void *mem, size_t len, ssize_t *written)
Definition: sendf.c:318
#define GETSOCK_WRITESOCK(x)
Definition: multiif.h:45
#define GSS_ERROR(status)
Definition: stub_gssapi.h:30
const struct Curl_handler * given
Definition: urldata.h:905
int first_remote_port
Definition: urldata.h:1265
char * path
Definition: urldata.h:1329
void Curl_pipeline_leave_write(struct connectdata *conn)
Definition: pipeline.c:366
Definition: curl.h:455
void * protop
Definition: urldata.h:614
struct http_conn httpc
Definition: urldata.h:999
curl_off_t postsize
Definition: http.h:147
bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle, char *server_name)
Definition: pipeline.c:238
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len)
Definition: sendf.c:624
bool Curl_connect_ongoing(struct connectdata *conn)
Definition: http_proxy.c:144
#define Curl_safefree(ptr)
Definition: memdebug.h:170
bool chunk
Definition: urldata.h:605
bool multipass
Definition: urldata.h:1187
char * name
Definition: cookie.h:30
#define ISSPACE(x)
struct UrlState state
Definition: urldata.h:1769
curl_off_t Curl_mime_size(curl_mimepart *part)
Definition: mime.c:1484
#define aprintf
Definition: curl_printf.h:46
curl_mimepart * sendit
Definition: http.h:131
bool get_filetime
Definition: urldata.h:1616
#define https_connecting(x, y)
Definition: http.c:102
size_t hbuflen
Definition: urldata.h:549
char uploadbuffer[UPLOAD_BUFSIZE+1]
Definition: urldata.h:1254
CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, struct connectdata *conn, ssize_t *nread, bool *stop_reading)
Definition: http.c:2948
time_t timevalue
Definition: urldata.h:1581
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks)
bool rewindaftersend
Definition: urldata.h:408
#define CURL_MAX_HTTP_HEADER
Definition: curl.h:236
static const char * get_http_string(const struct Curl_easy *data, const struct connectdata *conn)
Definition: http.c:1509
#define PORT_HTTPS
Definition: urldata.h:33
bool netrc
Definition: urldata.h:420
struct PureInfo info
Definition: urldata.h:1772
struct curl_slist * proxyheaders
Definition: urldata.h:1561
unsigned long proxyauthavail
Definition: urldata.h:1063
#define Curl_http2_setup_req(x)
Definition: http2.h:69
char * Curl_checkheaders(const struct connectdata *conn, const char *thisheader)
Definition: transfer.c:92
#define ssize_t
Definition: config-win32.h:382
CURLcode Curl_http_output_auth(struct connectdata *conn, const char *request, const char *path, bool proxytunnel)
Curl_http_output_auth() setups the authentication headers for the host/proxy and the correct authenti...
Definition: http.c:660
static bool checkprotoprefix(struct Curl_easy *data, struct connectdata *conn, const char *s)
Definition: http.c:2852
CURLcode Curl_output_digest(struct connectdata *conn, bool proxy, const unsigned char *request, const unsigned char *uripath)
Definition: http_digest.c:70
curl_socket_t sock[2]
Definition: urldata.h:876
CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused)
Definition: parsedate.c:548
struct auth authhost
Definition: urldata.h:1289
char * newurl
Definition: urldata.h:592
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
Definition: mime.c:1161
char * hbufp
Definition: urldata.h:548
CURLcode Curl_gmtime(time_t intime, struct tm *store)
Definition: parsedate.c:570
int auto_decoding
Definition: urldata.h:563
char * buffer
Definition: http.h:54
bool proxy_user_passwd
Definition: urldata.h:386
#define connkeep(x, y)
Definition: connect.h:142
curl_TimeCond timecondition
Definition: urldata.h:1580
char * location
Definition: urldata.h:590
bool done
Definition: urldata.h:1185
int httpversion
Definition: urldata.h:1312
void * in
Definition: urldata.h:1356
const char * postdata
Definition: http.h:133
CURLcode Curl_http_setup_conn(struct connectdata *conn)
Definition: http.c:155
unsigned long avail
Definition: urldata.h:1183
unsigned long picked
Definition: urldata.h:1182
struct connectbundle * bundle
Definition: urldata.h:1026
bool verbose
Definition: urldata.h:1635
#define infof
Definition: sendf.h:44
CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt,...)
Definition: http.c:1201
CURLcode Curl_http_done(struct connectdata *conn, CURLcode status, bool premature)
Definition: http.c:1415
#define Curl_http2_setup_conn(x)
Definition: http2.h:68
void * postfields
Definition: urldata.h:1508
UNITTEST_START int * value
Definition: unit1602.c:51
CURLcode Curl_http(struct connectdata *conn, bool *done)
Definition: http.c:1748
curl_off_t max_filesize
Definition: urldata.h:1599
curl_read_callback fread_func
Definition: urldata.h:1355
CURLSHcode Curl_share_lock(struct Curl_easy *data, curl_lock_data type, curl_lock_access accesstype)
Definition: share.c:213
size_t size_used
Definition: http.h:56
CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header)
Definition: lib/rtsp.c:788
struct curl_slist * curlheaders
Definition: mime.h:109
char * str[STRING_LAST]
Definition: urldata.h:1663
bool ipv6_ip
Definition: urldata.h:387
Curl_send_buffer * Curl_add_buffer_init(void)
Definition: http.c:1029
#define checkprefix(a, b)
Definition: strcase.h:46
#define CURL_HTTP_VERSION_2
Definition: curl.h:1879
struct HTTP::back backup
void * seek_client
Definition: urldata.h:966
#define CURLAUTH_DIGEST
Definition: curl.h:698
char * str
Definition: urldata.h:550
#define Curl_unencode_cleanup(x)
union connectdata::@34 proto
struct auth authproxy
Definition: urldata.h:1290
size_t size
Definition: unit1302.c:52
#define snprintf
Definition: curl_printf.h:42
curl_seek_callback seek_func
Definition: urldata.h:1509
#define PORT_HTTP
Definition: urldata.h:32
size_t headersize
Definition: urldata.h:1251
#define TRUE
unsigned long want
Definition: urldata.h:1180
#define PROTOPT_CREDSPERREQUEST
Definition: urldata.h:713
#define IDENTITY
Definition: urldata.h:565
curl_proxytype proxytype
Definition: urldata.h:760
bool retry
Definition: urldata.h:398
static bool checkhttpprefix(struct Curl_easy *data, const char *s)
Definition: http.c:2784
#define vaprintf
Definition: curl_printf.h:47
#define CURLMAX(x, y)
Definition: urldata.h:152
#define CURLAUTH_PICKNONE
Definition: http.h:98
struct connectdata::dynamically_allocated_data allocptr
const struct Curl_handler Curl_handler_http
Definition: http.c:108
size_t curlx_sotouz(curl_off_t sonum)
Definition: warnless.c:347
static void print_http_error(struct Curl_easy *data)
Definition: http.c:2908
int curl_socket_t
Definition: curl.h:130
#define Curl_http2_setup(x)
Definition: http2.h:66
#define CURLAUTH_NTLM_WB
Definition: curl.h:706
static CURLcode expect100(struct Curl_easy *data, struct connectdata *conn, Curl_send_buffer *req_buffer)
Definition: http.c:1524
bool sep_headers
Definition: urldata.h:1564
unsigned long httpauthavail
Definition: urldata.h:1064
long buffer_size
Definition: urldata.h:1591
int httpcode
Definition: urldata.h:557
#define PROTO_FAMILY_HTTP
Definition: urldata.h:66
char * user
Definition: urldata.h:761
bool upload
Definition: urldata.h:1632
char Curl_raw_toupper(char in)
Definition: strcase.c:31
const char * dispname
Definition: urldata.h:445
curl_off_t bytecount
Definition: urldata.h:526
#define HEADER1
long header_size
Definition: urldata.h:1061
CURLcode Curl_add_custom_headers(struct connectdata *conn, bool is_connect, Curl_send_buffer *req_buffer)
Definition: http.c:1559
Curl_RtspReq rtspreq
Definition: urldata.h:1673
Definition: debug.c:29
bool authproblem
Definition: urldata.h:1292
CURLcode Curl_getformdata(struct Curl_easy *data, curl_mimepart *finalform, struct curl_httppost *post, curl_read_callback fread_func)
Definition: formdata.c:856
int remote_port
Definition: urldata.h:842
char * user
Definition: urldata.h:865
#define calloc(nbelem, size)
Definition: curl_memory.h:126
bool ignorecl
Definition: urldata.h:587
curl_off_t maxdownload
Definition: urldata.h:522
bool proxy_transfer_mode
Definition: urldata.h:1661
curl_off_t postsize
Definition: http.h:132
bool proxy_connect_closed
Definition: urldata.h:425
struct Cookie * next
Definition: cookie.h:29
const char * path
Definition: util.c:192
#define CURL_FORMAT_CURL_OFF_T
Definition: system.h:373
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
Definition: http_proxy.c:72
struct curl_llist_element * head
case 1: list has >1 element, removing head : 1: list size will be decremented by one 2: head will be ...
Definition: unit1300.c:60
#define DEBUGF(x)
struct Curl_easy * data
Definition: urldata.h:791


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:15