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