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