Home | History | Annotate | Download | only in lib
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel (at) 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 
    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 
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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 
    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
    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
    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 
    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  */
    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  */
    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  */
   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  */
   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  */
   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  */
   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  */
   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
   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  */
   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 */
   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
   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. */
   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
   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 
   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  */
   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 */
   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 
   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 
   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  */
   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
   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
   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
   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  */
   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 
   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  */
   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