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