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