~ubuntu-branches/ubuntu/vivid/curl/vivid

« back to all changes in this revision

Viewing changes to lib/transfer.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Schuldei
  • Date: 2009-04-02 23:35:45 UTC
  • mfrom: (1.1.12 upstream)
  • mto: (3.3.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 38.
  • Revision ID: james.westby@ubuntu.com-20090402233545-8xjr3o2sgce5s4bg
Tags: 7.19.4-1
* New upstream release
* Fix "newer bdb version" <explain what you changed and why> 
  (Closes: #517277)
* resolve libtool version confusion, thanks to 
  Stefanos Harhalakis <v13@v13.gr>
* add new dependency on libgcrypt11-dev due to newly arising binary symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
9
9
 *
10
10
 * This software is licensed as described in the file COPYING, which
11
11
 * you should have received as part of this distribution. The terms
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: transfer.c,v 1.392 2008-05-26 20:39:41 bagder Exp $
 
21
 * $Id: transfer.c,v 1.427 2009-02-27 08:53:10 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
33
33
 
34
34
#include "strtoofft.h"
35
35
#include "strequal.h"
 
36
#include "rawstr.h"
36
37
 
37
38
#ifdef WIN32
38
39
#include <time.h>
62
63
#ifdef HAVE_SYS_IOCTL_H
63
64
#include <sys/ioctl.h>
64
65
#endif
 
66
#ifdef HAVE_SIGNAL_H
65
67
#include <signal.h>
 
68
#endif
66
69
 
67
70
#ifdef HAVE_SYS_PARAM_H
68
71
#include <sys/param.h>
109
112
 
110
113
#define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */
111
114
 
 
115
 
 
116
#ifndef CURL_DISABLE_HTTP
 
117
static CURLcode readwrite_http_headers(struct SessionHandle *data,
 
118
                                       struct connectdata *conn,
 
119
                                       struct SingleRequest *k,
 
120
                                       ssize_t *nread,
 
121
                                       bool *stop_reading);
 
122
#endif /* CURL_DISABLE_HTTP */
 
123
 
112
124
/*
113
125
 * This function will call the read callback to fill our buffer with data
114
126
 * to upload.
122
134
  if(data->req.upload_chunky) {
123
135
    /* if chunked Transfer-Encoding */
124
136
    buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
125
 
    data->req.upload_fromhere += 10; /* 32bit hex + CRLF */
 
137
    data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
126
138
  }
127
139
 
128
140
  /* this function returns a size_t, so we typecast to int to prevent warnings
132
144
 
133
145
  if(nread == CURL_READFUNC_ABORT) {
134
146
    failf(data, "operation aborted by callback");
 
147
    *nreadp = 0;
135
148
    return CURLE_ABORTED_BY_CALLBACK;
136
149
  }
137
150
  else if(nread == CURL_READFUNC_PAUSE) {
138
151
    struct SingleRequest *k = &data->req;
139
 
    k->keepon |= KEEP_READ_PAUSE; /* mark reading as paused */
 
152
    /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
 
153
    k->keepon |= KEEP_WRITE_PAUSE; /* mark socket send as paused */
 
154
    if(data->req.upload_chunky) {
 
155
      /* Back out the preallocation done above */
 
156
      data->req.upload_fromhere -= (8 + 2);
 
157
    }
 
158
    *nreadp = 0;
140
159
    return CURLE_OK; /* nothing was read */
141
160
  }
142
 
  else if((size_t)nread > buffersize)
 
161
  else if((size_t)nread > buffersize) {
143
162
    /* the read function returned a too large value */
 
163
    *nreadp = 0;
 
164
    failf(data, "read function returned funny value");
144
165
    return CURLE_READ_ERROR;
 
166
  }
145
167
 
146
168
  if(!data->req.forbidchunk && data->req.upload_chunky) {
147
169
    /* if chunked Transfer-Encoding */
152
174
    data->req.upload_fromhere -= hexlen;
153
175
    nread += hexlen;
154
176
 
155
 
    /* copy the prefix to the buffer */
 
177
    /* copy the prefix to the buffer, leaving out the NUL */
156
178
    memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
157
179
 
158
180
    /* always append CRLF to the data */
182
204
  return CURLE_OK;
183
205
}
184
206
 
 
207
#ifndef CURL_DISABLE_HTTP
185
208
/*
186
209
 * checkhttpprefix()
187
210
 *
226
249
#endif /* CURL_DOES_CONVERSIONS */
227
250
  return rc;
228
251
}
 
252
#endif   /* CURL_DISABLE_HTTP */
229
253
 
230
254
/*
231
255
 * Curl_readrewind() rewinds the read stream. This is typically used for HTTP
283
307
          return CURLE_OK;
284
308
      }
285
309
 
286
 
      /* no callback set or failure aboe, makes us fail at once */
 
310
      /* no callback set or failure above, makes us fail at once */
287
311
      failf(data, "necessary data rewind wasn't possible");
288
312
      return CURLE_SEND_FAIL_REWIND;
289
313
    }
299
323
    Curl_ssl_data_pending(conn, FIRSTSOCKET);
300
324
}
301
325
 
302
 
#ifndef MIN
303
 
#define MIN(a,b) (a < b ? a : b)
304
 
#endif
305
 
 
306
326
static void read_rewind(struct connectdata *conn,
307
327
                        size_t thismuch)
308
328
{
314
334
    char buf[512 + 1];
315
335
    size_t show;
316
336
 
317
 
    show = MIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
 
337
    show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
318
338
    if(conn->master_buffer) {
319
339
        memcpy(buf, conn->master_buffer + conn->read_pos, show);
320
340
        buf[show] = '\0';
330
350
#endif
331
351
}
332
352
 
 
353
 
 
354
/*
 
355
 * Go ahead and do a read if we have a readable socket or if
 
356
 * the stream was rewound (in which case we have data in a
 
357
 * buffer)
 
358
 */
 
359
static CURLcode readwrite_data(struct SessionHandle *data,
 
360
                               struct connectdata *conn,
 
361
                               struct SingleRequest *k,
 
362
                               int *didwhat, bool *done)
 
363
{
 
364
  CURLcode result = CURLE_OK;
 
365
  ssize_t nread; /* number of bytes read */
 
366
  bool is_empty_data = FALSE;
 
367
 
 
368
  *done = FALSE;
 
369
 
 
370
  /* This is where we loop until we have read everything there is to
 
371
     read or we get a EWOULDBLOCK */
 
372
  do {
 
373
    size_t buffersize = data->set.buffer_size?
 
374
      data->set.buffer_size : BUFSIZE;
 
375
    size_t bytestoread = buffersize;
 
376
    int readrc;
 
377
 
 
378
    if(k->size != -1 && !k->header) {
 
379
      /* make sure we don't read "too much" if we can help it since we
 
380
         might be pipelining and then someone else might want to read what
 
381
         follows! */
 
382
      curl_off_t totalleft = k->size - k->bytecount;
 
383
      if(totalleft < (curl_off_t)bytestoread)
 
384
        bytestoread = (size_t)totalleft;
 
385
    }
 
386
 
 
387
    if(bytestoread) {
 
388
      /* receive data from the network! */
 
389
      readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
 
390
 
 
391
      /* subzero, this would've blocked */
 
392
      if(0 > readrc)
 
393
        break; /* get out of loop */
 
394
 
 
395
      /* get the CURLcode from the int */
 
396
      result = (CURLcode)readrc;
 
397
 
 
398
      if(result>0)
 
399
        return result;
 
400
    }
 
401
    else {
 
402
      /* read nothing but since we wanted nothing we consider this an OK
 
403
         situation to proceed from */
 
404
      nread = 0;
 
405
    }
 
406
 
 
407
    if((k->bytecount == 0) && (k->writebytecount == 0)) {
 
408
      Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 
409
      if(k->exp100 > EXP100_SEND_DATA)
 
410
        /* set time stamp to compare with when waiting for the 100 */
 
411
        k->start100 = Curl_tvnow();
 
412
    }
 
413
 
 
414
    *didwhat |= KEEP_READ;
 
415
    /* indicates data of zero size, i.e. empty file */
 
416
    is_empty_data = (bool)((nread == 0) && (k->bodywrites == 0));
 
417
 
 
418
    /* NUL terminate, allowing string ops to be used */
 
419
    if(0 < nread || is_empty_data) {
 
420
      k->buf[nread] = 0;
 
421
    }
 
422
    else if(0 >= nread) {
 
423
      /* if we receive 0 or less here, the server closed the connection
 
424
         and we bail out from this! */
 
425
      DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
 
426
      k->keepon &= ~KEEP_READ;
 
427
      break;
 
428
    }
 
429
 
 
430
    /* Default buffer to use when we write the buffer, it may be changed
 
431
       in the flow below before the actual storing is done. */
 
432
    k->str = k->buf;
 
433
 
 
434
#ifndef CURL_DISABLE_HTTP
 
435
    /* Since this is a two-state thing, we check if we are parsing
 
436
       headers at the moment or not. */
 
437
    if(k->header) {
 
438
      /* we are in parse-the-header-mode */
 
439
      bool stop_reading = FALSE;
 
440
      result = readwrite_http_headers(data, conn, k, &nread, &stop_reading);
 
441
      if(result)
 
442
        return result;
 
443
      if(stop_reading)
 
444
        /* We've stopped dealing with input, get out of the do-while loop */
 
445
        break;
 
446
    }
 
447
#endif /* CURL_DISABLE_HTTP */
 
448
 
 
449
 
 
450
    /* This is not an 'else if' since it may be a rest from the header
 
451
       parsing, where the beginning of the buffer is headers and the end
 
452
       is non-headers. */
 
453
    if(k->str && !k->header && (nread > 0 || is_empty_data)) {
 
454
 
 
455
#ifndef CURL_DISABLE_HTTP
 
456
      if(0 == k->bodywrites && !is_empty_data) {
 
457
        /* These checks are only made the first time we are about to
 
458
           write a piece of the body */
 
459
        if(conn->protocol&PROT_HTTP) {
 
460
          /* HTTP-only checks */
 
461
 
 
462
          if(data->req.newurl) {
 
463
            if(conn->bits.close) {
 
464
              /* Abort after the headers if "follow Location" is set
 
465
                 and we're set to close anyway. */
 
466
              k->keepon &= ~KEEP_READ;
 
467
              *done = TRUE;
 
468
              return CURLE_OK;
 
469
            }
 
470
            /* We have a new url to load, but since we want to be able
 
471
               to re-use this connection properly, we read the full
 
472
               response in "ignore more" */
 
473
            k->ignorebody = TRUE;
 
474
            infof(data, "Ignoring the response-body\n");
 
475
          }
 
476
          if(data->state.resume_from && !k->content_range &&
 
477
             (data->set.httpreq==HTTPREQ_GET) &&
 
478
             !k->ignorebody) {
 
479
            /* we wanted to resume a download, although the server doesn't
 
480
             * seem to support this and we did this with a GET (if it
 
481
             * wasn't a GET we did a POST or PUT resume) */
 
482
            failf(data, "HTTP server doesn't seem to support "
 
483
                  "byte ranges. Cannot resume.");
 
484
            return CURLE_RANGE_ERROR;
 
485
          }
 
486
 
 
487
          if(data->set.timecondition && !data->state.range) {
 
488
            /* A time condition has been set AND no ranges have been
 
489
               requested. This seems to be what chapter 13.3.4 of
 
490
               RFC 2616 defines to be the correct action for a
 
491
               HTTP/1.1 client */
 
492
            if((k->timeofdoc > 0) && (data->set.timevalue > 0)) {
 
493
              switch(data->set.timecondition) {
 
494
              case CURL_TIMECOND_IFMODSINCE:
 
495
              default:
 
496
                if(k->timeofdoc < data->set.timevalue) {
 
497
                  infof(data,
 
498
                        "The requested document is not new enough\n");
 
499
                  *done = TRUE;
 
500
                  data->info.timecond = TRUE;
 
501
                  return CURLE_OK;
 
502
                }
 
503
                break;
 
504
              case CURL_TIMECOND_IFUNMODSINCE:
 
505
                if(k->timeofdoc > data->set.timevalue) {
 
506
                  infof(data,
 
507
                        "The requested document is not old enough\n");
 
508
                  *done = TRUE;
 
509
                  data->info.timecond = TRUE;
 
510
                  return CURLE_OK;
 
511
                }
 
512
                break;
 
513
              } /* switch */
 
514
            } /* two valid time strings */
 
515
          } /* we have a time condition */
 
516
 
 
517
        } /* this is HTTP */
 
518
      } /* this is the first time we write a body part */
 
519
#endif /* CURL_DISABLE_HTTP */
 
520
      k->bodywrites++;
 
521
 
 
522
      /* pass data to the debug function before it gets "dechunked" */
 
523
      if(data->set.verbose) {
 
524
        if(k->badheader) {
 
525
          Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
 
526
                     (size_t)k->hbuflen, conn);
 
527
          if(k->badheader == HEADER_PARTHEADER)
 
528
            Curl_debug(data, CURLINFO_DATA_IN,
 
529
                       k->str, (size_t)nread, conn);
 
530
        }
 
531
        else
 
532
          Curl_debug(data, CURLINFO_DATA_IN,
 
533
                     k->str, (size_t)nread, conn);
 
534
      }
 
535
 
 
536
#ifndef CURL_DISABLE_HTTP
 
537
      if(k->chunk) {
 
538
        /*
 
539
         * Here comes a chunked transfer flying and we need to decode this
 
540
         * properly.  While the name says read, this function both reads
 
541
         * and writes away the data. The returned 'nread' holds the number
 
542
         * of actual data it wrote to the client.
 
543
         */
 
544
 
 
545
        CHUNKcode res =
 
546
          Curl_httpchunk_read(conn, k->str, nread, &nread);
 
547
 
 
548
        if(CHUNKE_OK < res) {
 
549
          if(CHUNKE_WRITE_ERROR == res) {
 
550
            failf(data, "Failed writing data");
 
551
            return CURLE_WRITE_ERROR;
 
552
          }
 
553
          failf(data, "Received problem %d in the chunky parser", res);
 
554
          return CURLE_RECV_ERROR;
 
555
        }
 
556
        else if(CHUNKE_STOP == res) {
 
557
          size_t dataleft;
 
558
          /* we're done reading chunks! */
 
559
          k->keepon &= ~KEEP_READ; /* read no more */
 
560
 
 
561
          /* There are now possibly N number of bytes at the end of the
 
562
             str buffer that weren't written to the client.
 
563
 
 
564
             We DO care about this data if we are pipelining.
 
565
             Push it back to be read on the next pass. */
 
566
 
 
567
          dataleft = conn->chunk.dataleft;
 
568
          if(dataleft != 0) {
 
569
            infof(conn->data, "Leftovers after chunking. "
 
570
                  " Rewinding %d bytes\n",dataleft);
 
571
            read_rewind(conn, dataleft);
 
572
          }
 
573
        }
 
574
        /* If it returned OK, we just keep going */
 
575
      }
 
576
#endif   /* CURL_DISABLE_HTTP */
 
577
 
 
578
      if((-1 != k->maxdownload) &&
 
579
         (k->bytecount + nread >= k->maxdownload)) {
 
580
        /* The 'excess' amount below can't be more than BUFSIZE which
 
581
           always will fit in a size_t */
 
582
        size_t excess = (size_t)(k->bytecount + nread - k->maxdownload);
 
583
        if(excess > 0 && !k->ignorebody) {
 
584
          infof(data,
 
585
                "Rewinding stream by : %d"
 
586
                " bytes on url %s (size = %" FORMAT_OFF_T
 
587
                ", maxdownload = %" FORMAT_OFF_T
 
588
                ", bytecount = %" FORMAT_OFF_T ", nread = %d)\n",
 
589
                excess, data->state.path,
 
590
                k->size, k->maxdownload, k->bytecount, nread);
 
591
          read_rewind(conn, excess);
 
592
        }
 
593
 
 
594
        nread = (ssize_t) (k->maxdownload - k->bytecount);
 
595
        if(nread < 0 ) /* this should be unusual */
 
596
          nread = 0;
 
597
 
 
598
        k->keepon &= ~KEEP_READ; /* we're done reading */
 
599
      }
 
600
 
 
601
      k->bytecount += nread;
 
602
 
 
603
      Curl_pgrsSetDownloadCounter(data, k->bytecount);
 
604
 
 
605
      if(!k->chunk && (nread || k->badheader || is_empty_data)) {
 
606
        /* If this is chunky transfer, it was already written */
 
607
 
 
608
        if(k->badheader && !k->ignorebody) {
 
609
          /* we parsed a piece of data wrongly assuming it was a header
 
610
             and now we output it as body instead */
 
611
          result = Curl_client_write(conn, CLIENTWRITE_BODY,
 
612
                                     data->state.headerbuff,
 
613
                                     k->hbuflen);
 
614
          if(result)
 
615
            return result;
 
616
        }
 
617
        if(k->badheader < HEADER_ALLBAD) {
 
618
          /* This switch handles various content encodings. If there's an
 
619
             error here, be sure to check over the almost identical code
 
620
             in http_chunks.c.
 
621
             Make sure that ALL_CONTENT_ENCODINGS contains all the
 
622
             encodings handled here. */
 
623
#ifdef HAVE_LIBZ
 
624
          switch (conn->data->set.http_ce_skip ?
 
625
                  IDENTITY : k->content_encoding) {
 
626
          case IDENTITY:
 
627
#endif
 
628
            /* This is the default when the server sends no
 
629
               Content-Encoding header. See Curl_readwrite_init; the
 
630
               memset() call initializes k->content_encoding to zero. */
 
631
            if(!k->ignorebody)
 
632
              result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
 
633
                                         nread);
 
634
#ifdef HAVE_LIBZ
 
635
            break;
 
636
 
 
637
          case DEFLATE:
 
638
            /* Assume CLIENTWRITE_BODY; headers are not encoded. */
 
639
            if(!k->ignorebody)
 
640
              result = Curl_unencode_deflate_write(conn, k, nread);
 
641
            break;
 
642
 
 
643
          case GZIP:
 
644
            /* Assume CLIENTWRITE_BODY; headers are not encoded. */
 
645
            if(!k->ignorebody)
 
646
              result = Curl_unencode_gzip_write(conn, k, nread);
 
647
            break;
 
648
 
 
649
          case COMPRESS:
 
650
          default:
 
651
            failf (data, "Unrecognized content encoding type. "
 
652
                   "libcurl understands `identity', `deflate' and `gzip' "
 
653
                   "content encodings.");
 
654
            result = CURLE_BAD_CONTENT_ENCODING;
 
655
            break;
 
656
          }
 
657
#endif
 
658
        }
 
659
        k->badheader = HEADER_NORMAL; /* taken care of now */
 
660
 
 
661
        if(result)
 
662
          return result;
 
663
      }
 
664
 
 
665
    } /* if(! header and data to read ) */
 
666
 
 
667
    if(is_empty_data) {
 
668
      /* if we received nothing, the server closed the connection and we
 
669
         are done */
 
670
      k->keepon &= ~KEEP_READ;
 
671
    }
 
672
 
 
673
  } while(data_pending(conn));
 
674
 
 
675
  if(((k->keepon & (KEEP_READ|KEEP_WRITE)) == KEEP_WRITE) &&
 
676
     conn->bits.close ) {
 
677
    /* When we've read the entire thing and the close bit is set, the server
 
678
       may now close the connection. If there's now any kind of sending going
 
679
       on from our side, we need to stop that immediately. */
 
680
    infof(data, "we are done reading and this is set to close, stop send\n");
 
681
    k->keepon &= ~KEEP_WRITE; /* no writing anymore either */
 
682
  }
 
683
 
 
684
  return CURLE_OK;
 
685
}
 
686
 
 
687
#ifndef CURL_DISABLE_HTTP
 
688
/*
 
689
 * Read any HTTP header lines from the server and pass them to the client app.
 
690
 */
 
691
static CURLcode readwrite_http_headers(struct SessionHandle *data,
 
692
                                       struct connectdata *conn,
 
693
                                       struct SingleRequest *k,
 
694
                                       ssize_t *nread,
 
695
                                       bool *stop_reading)
 
696
{
 
697
  CURLcode result;
 
698
 
 
699
  /* header line within buffer loop */
 
700
  do {
 
701
    size_t hbufp_index;
 
702
    size_t rest_length;
 
703
    size_t full_length;
 
704
    int writetype;
 
705
 
 
706
    /* str_start is start of line within buf */
 
707
    k->str_start = k->str;
 
708
 
 
709
    /* data is in network encoding so use 0x0a instead of '\n' */
 
710
    k->end_ptr = memchr(k->str_start, 0x0a, *nread);
 
711
 
 
712
    if(!k->end_ptr) {
 
713
      /* Not a complete header line within buffer, append the data to
 
714
         the end of the headerbuff. */
 
715
 
 
716
      if(k->hbuflen + *nread >= data->state.headersize) {
 
717
        /* We enlarge the header buffer as it is too small */
 
718
        char *newbuff;
 
719
        size_t newsize=CURLMAX((k->hbuflen+*nread)*3/2,
 
720
                               data->state.headersize*2);
 
721
        hbufp_index = k->hbufp - data->state.headerbuff;
 
722
        newbuff = realloc(data->state.headerbuff, newsize);
 
723
        if(!newbuff) {
 
724
          failf (data, "Failed to alloc memory for big header!");
 
725
          return CURLE_OUT_OF_MEMORY;
 
726
        }
 
727
        data->state.headersize=newsize;
 
728
        data->state.headerbuff = newbuff;
 
729
        k->hbufp = data->state.headerbuff + hbufp_index;
 
730
      }
 
731
      memcpy(k->hbufp, k->str, *nread);
 
732
      k->hbufp += *nread;
 
733
      k->hbuflen += *nread;
 
734
      if(!k->headerline && (k->hbuflen>5)) {
 
735
        /* make a first check that this looks like a HTTP header */
 
736
        if(!checkhttpprefix(data, data->state.headerbuff)) {
 
737
          /* this is not the beginning of a HTTP first header line */
 
738
          k->header = FALSE;
 
739
          k->badheader = HEADER_ALLBAD;
 
740
          break;
 
741
        }
 
742
      }
 
743
 
 
744
      break; /* read more and try again */
 
745
    }
 
746
 
 
747
    /* decrease the size of the remaining (supposed) header line */
 
748
    rest_length = (k->end_ptr - k->str)+1;
 
749
    *nread -= (ssize_t)rest_length;
 
750
 
 
751
    k->str = k->end_ptr + 1; /* move past new line */
 
752
 
 
753
    full_length = k->str - k->str_start;
 
754
 
 
755
    /*
 
756
     * We're about to copy a chunk of data to the end of the
 
757
     * already received header. We make sure that the full string
 
758
     * fit in the allocated header buffer, or else we enlarge
 
759
     * it.
 
760
     */
 
761
    if(k->hbuflen + full_length >=
 
762
       data->state.headersize) {
 
763
      char *newbuff;
 
764
      size_t newsize=CURLMAX((k->hbuflen+full_length)*3/2,
 
765
                             data->state.headersize*2);
 
766
      hbufp_index = k->hbufp - data->state.headerbuff;
 
767
      newbuff = realloc(data->state.headerbuff, newsize);
 
768
      if(!newbuff) {
 
769
        failf (data, "Failed to alloc memory for big header!");
 
770
        return CURLE_OUT_OF_MEMORY;
 
771
      }
 
772
      data->state.headersize= newsize;
 
773
      data->state.headerbuff = newbuff;
 
774
      k->hbufp = data->state.headerbuff + hbufp_index;
 
775
    }
 
776
 
 
777
    /* copy to end of line */
 
778
    memcpy(k->hbufp, k->str_start, full_length);
 
779
    k->hbufp += full_length;
 
780
    k->hbuflen += full_length;
 
781
    *k->hbufp = 0;
 
782
    k->end_ptr = k->hbufp;
 
783
 
 
784
    k->p = data->state.headerbuff;
 
785
 
 
786
    /****
 
787
     * We now have a FULL header line that p points to
 
788
     *****/
 
789
 
 
790
    if(!k->headerline) {
 
791
      /* the first read header */
 
792
      if((k->hbuflen>5) &&
 
793
         !checkhttpprefix(data, data->state.headerbuff)) {
 
794
        /* this is not the beginning of a HTTP first header line */
 
795
        k->header = FALSE;
 
796
        if(*nread)
 
797
          /* since there's more, this is a partial bad header */
 
798
          k->badheader = HEADER_PARTHEADER;
 
799
        else {
 
800
          /* this was all we read so it's all a bad header */
 
801
          k->badheader = HEADER_ALLBAD;
 
802
          *nread = (ssize_t)rest_length;
 
803
        }
 
804
        break;
 
805
      }
 
806
    }
 
807
 
 
808
    /* headers are in network encoding so
 
809
       use 0x0a and 0x0d instead of '\n' and '\r' */
 
810
    if((0x0a == *k->p) || (0x0d == *k->p)) {
 
811
      size_t headerlen;
 
812
      /* Zero-length header line means end of headers! */
 
813
 
 
814
#ifdef CURL_DOES_CONVERSIONS
 
815
      if(0x0d == *k->p) {
 
816
        *k->p = '\r'; /* replace with CR in host encoding */
 
817
        k->p++;       /* pass the CR byte */
 
818
      }
 
819
      if(0x0a == *k->p) {
 
820
        *k->p = '\n'; /* replace with LF in host encoding */
 
821
        k->p++;       /* pass the LF byte */
 
822
      }
 
823
#else
 
824
      if('\r' == *k->p)
 
825
        k->p++; /* pass the \r byte */
 
826
      if('\n' == *k->p)
 
827
        k->p++; /* pass the \n byte */
 
828
#endif /* CURL_DOES_CONVERSIONS */
 
829
 
 
830
      if(100 <= k->httpcode && 199 >= k->httpcode) {
 
831
        /*
 
832
         * We have made a HTTP PUT or POST and this is 1.1-lingo
 
833
         * that tells us that the server is OK with this and ready
 
834
         * to receive the data.
 
835
         * However, we'll get more headers now so we must get
 
836
         * back into the header-parsing state!
 
837
         */
 
838
        k->header = TRUE;
 
839
        k->headerline = 0; /* restart the header line counter */
 
840
 
 
841
        /* if we did wait for this do enable write now! */
 
842
        if(k->exp100) {
 
843
          k->exp100 = EXP100_SEND_DATA;
 
844
          k->keepon |= KEEP_WRITE;
 
845
        }
 
846
      }
 
847
      else {
 
848
        k->header = FALSE; /* no more header to parse! */
 
849
 
 
850
        if((k->size == -1) && !k->chunk && !conn->bits.close &&
 
851
           (conn->httpversion >= 11) ) {
 
852
          /* On HTTP 1.1, when connection is not to get closed, but no
 
853
             Content-Length nor Content-Encoding chunked have been
 
854
             received, according to RFC2616 section 4.4 point 5, we
 
855
             assume that the server will close the connection to
 
856
             signal the end of the document. */
 
857
          infof(data, "no chunk, no close, no size. Assume close to "
 
858
                "signal end\n");
 
859
          conn->bits.close = TRUE;
 
860
        }
 
861
      }
 
862
 
 
863
      if(417 == k->httpcode) {
 
864
        /*
 
865
         * we got: "417 Expectation Failed" this means:
 
866
         * we have made a HTTP call and our Expect Header
 
867
         * seems to cause a problem => abort the write operations
 
868
         * (or prevent them from starting).
 
869
         */
 
870
        k->exp100 = EXP100_FAILED;
 
871
        k->keepon &= ~KEEP_WRITE;
 
872
      }
 
873
 
 
874
      /*
 
875
       * When all the headers have been parsed, see if we should give
 
876
       * up and return an error.
 
877
       */
 
878
      if(Curl_http_should_fail(conn)) {
 
879
        failf (data, "The requested URL returned error: %d",
 
880
               k->httpcode);
 
881
        return CURLE_HTTP_RETURNED_ERROR;
 
882
      }
 
883
 
 
884
      /* now, only output this if the header AND body are requested:
 
885
       */
 
886
      writetype = CLIENTWRITE_HEADER;
 
887
      if(data->set.include_header)
 
888
        writetype |= CLIENTWRITE_BODY;
 
889
 
 
890
      headerlen = k->p - data->state.headerbuff;
 
891
 
 
892
      result = Curl_client_write(conn, writetype,
 
893
                                 data->state.headerbuff,
 
894
                                 headerlen);
 
895
      if(result)
 
896
        return result;
 
897
 
 
898
      data->info.header_size += (long)headerlen;
 
899
      data->req.headerbytecount += (long)headerlen;
 
900
 
 
901
      data->req.deductheadercount =
 
902
        (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
 
903
 
 
904
      if(data->state.resume_from &&
 
905
         (data->set.httpreq==HTTPREQ_GET) &&
 
906
         (k->httpcode == 416)) {
 
907
        /* "Requested Range Not Satisfiable" */
 
908
        *stop_reading = TRUE;
 
909
      }
 
910
 
 
911
      if(!*stop_reading) {
 
912
        /* Curl_http_auth_act() checks what authentication methods
 
913
         * that are available and decides which one (if any) to
 
914
         * use. It will set 'newurl' if an auth method was picked. */
 
915
        result = Curl_http_auth_act(conn);
 
916
 
 
917
        if(result)
 
918
          return result;
 
919
 
 
920
        if(conn->bits.rewindaftersend) {
 
921
          /* We rewind after a complete send, so thus we continue
 
922
             sending now */
 
923
          infof(data, "Keep sending data to get tossed away!\n");
 
924
          k->keepon |= KEEP_WRITE;
 
925
        }
 
926
      }
 
927
 
 
928
      if(!k->header) {
 
929
        /*
 
930
         * really end-of-headers.
 
931
         *
 
932
         * If we requested a "no body", this is a good time to get
 
933
         * out and return home.
 
934
         */
 
935
        if(data->set.opt_no_body)
 
936
          *stop_reading = TRUE;
 
937
        else {
 
938
          /* If we know the expected size of this document, we set the
 
939
             maximum download size to the size of the expected
 
940
             document or else, we won't know when to stop reading!
 
941
 
 
942
             Note that we set the download maximum even if we read a
 
943
             "Connection: close" header, to make sure that
 
944
             "Content-Length: 0" still prevents us from attempting to
 
945
             read the (missing) response-body.
 
946
          */
 
947
          /* According to RFC2616 section 4.4, we MUST ignore
 
948
             Content-Length: headers if we are now receiving data
 
949
             using chunked Transfer-Encoding.
 
950
          */
 
951
          if(k->chunk)
 
952
            k->size=-1;
 
953
 
 
954
        }
 
955
        if(-1 != k->size) {
 
956
          /* We do this operation even if no_body is true, since this
 
957
             data might be retrieved later with curl_easy_getinfo()
 
958
             and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
 
959
 
 
960
          Curl_pgrsSetDownloadSize(data, k->size);
 
961
          k->maxdownload = k->size;
 
962
        }
 
963
        /* If max download size is *zero* (nothing) we already
 
964
           have nothing and can safely return ok now! */
 
965
        if(0 == k->maxdownload)
 
966
          *stop_reading = TRUE;
 
967
 
 
968
        if(*stop_reading) {
 
969
          /* we make sure that this socket isn't read more now */
 
970
          k->keepon &= ~KEEP_READ;
 
971
        }
 
972
 
 
973
        if(data->set.verbose)
 
974
          Curl_debug(data, CURLINFO_HEADER_IN,
 
975
                     k->str_start, headerlen, conn);
 
976
        break;          /* exit header line loop */
 
977
      }
 
978
 
 
979
      /* We continue reading headers, so reset the line-based
 
980
         header parsing variables hbufp && hbuflen */
 
981
      k->hbufp = data->state.headerbuff;
 
982
      k->hbuflen = 0;
 
983
      continue;
 
984
    }
 
985
 
 
986
    /*
 
987
     * Checks for special headers coming up.
 
988
     */
 
989
 
 
990
    if(!k->headerline++) {
 
991
      /* This is the first header, it MUST be the error code line
 
992
         or else we consider this to be the body right away! */
 
993
      int httpversion_major;
 
994
      int nc;
 
995
#ifdef CURL_DOES_CONVERSIONS
 
996
#define HEADER1 scratch
 
997
#define SCRATCHSIZE 21
 
998
      CURLcode res;
 
999
      char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
 
1000
      /* We can't really convert this yet because we
 
1001
         don't know if it's the 1st header line or the body.
 
1002
         So we do a partial conversion into a scratch area,
 
1003
         leaving the data at k->p as-is.
 
1004
      */
 
1005
      strncpy(&scratch[0], k->p, SCRATCHSIZE);
 
1006
      scratch[SCRATCHSIZE] = 0; /* null terminate */
 
1007
      res = Curl_convert_from_network(data,
 
1008
                                      &scratch[0],
 
1009
                                      SCRATCHSIZE);
 
1010
      if(CURLE_OK != res) {
 
1011
        /* Curl_convert_from_network calls failf if unsuccessful */
 
1012
        return res;
 
1013
      }
 
1014
#else
 
1015
#define HEADER1 k->p /* no conversion needed, just use k->p */
 
1016
#endif /* CURL_DOES_CONVERSIONS */
 
1017
 
 
1018
      nc = sscanf(HEADER1,
 
1019
                  " HTTP/%d.%d %3d",
 
1020
                  &httpversion_major,
 
1021
                  &conn->httpversion,
 
1022
                  &k->httpcode);
 
1023
      if(nc==3) {
 
1024
        conn->httpversion += 10 * httpversion_major;
 
1025
      }
 
1026
      else {
 
1027
        /* this is the real world, not a Nirvana
 
1028
           NCSA 1.5.x returns this crap when asked for HTTP/1.1
 
1029
        */
 
1030
        nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
 
1031
        conn->httpversion = 10;
 
1032
 
 
1033
        /* If user has set option HTTP200ALIASES,
 
1034
           compare header line against list of aliases
 
1035
        */
 
1036
        if(!nc) {
 
1037
          if(checkhttpprefix(data, k->p)) {
 
1038
            nc = 1;
 
1039
            k->httpcode = 200;
 
1040
            conn->httpversion = 10;
 
1041
          }
 
1042
        }
 
1043
      }
 
1044
 
 
1045
      if(nc) {
 
1046
        data->info.httpcode = k->httpcode;
 
1047
        data->info.httpversion = conn->httpversion;
 
1048
        if (!data->state.httpversion ||
 
1049
            data->state.httpversion > conn->httpversion)
 
1050
          /* store the lowest server version we encounter */
 
1051
          data->state.httpversion = conn->httpversion;
 
1052
 
 
1053
        /*
 
1054
         * This code executes as part of processing the header.  As a
 
1055
         * result, it's not totally clear how to interpret the
 
1056
         * response code yet as that depends on what other headers may
 
1057
         * be present.  401 and 407 may be errors, but may be OK
 
1058
         * depending on how authentication is working.  Other codes
 
1059
         * are definitely errors, so give up here.
 
1060
         */
 
1061
        if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
 
1062
           ((k->httpcode != 401) || !conn->bits.user_passwd) &&
 
1063
           ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
 
1064
 
 
1065
          if(data->state.resume_from &&
 
1066
             (data->set.httpreq==HTTPREQ_GET) &&
 
1067
             (k->httpcode == 416)) {
 
1068
            /* "Requested Range Not Satisfiable", just proceed and
 
1069
               pretend this is no error */
 
1070
          }
 
1071
          else {
 
1072
            /* serious error, go home! */
 
1073
            failf (data, "The requested URL returned error: %d",
 
1074
                   k->httpcode);
 
1075
            return CURLE_HTTP_RETURNED_ERROR;
 
1076
          }
 
1077
        }
 
1078
 
 
1079
        if(conn->httpversion == 10) {
 
1080
          /* Default action for HTTP/1.0 must be to close, unless
 
1081
             we get one of those fancy headers that tell us the
 
1082
             server keeps it open for us! */
 
1083
          infof(data, "HTTP 1.0, assume close after body\n");
 
1084
          conn->bits.close = TRUE;
 
1085
        }
 
1086
        else if(conn->httpversion >= 11 &&
 
1087
                !conn->bits.close) {
 
1088
          /* If HTTP version is >= 1.1 and connection is persistent
 
1089
             server supports pipelining. */
 
1090
          DEBUGF(infof(data,
 
1091
                       "HTTP 1.1 or later with persistent connection, "
 
1092
                       "pipelining supported\n"));
 
1093
          conn->server_supports_pipelining = TRUE;
 
1094
        }
 
1095
 
 
1096
        switch(k->httpcode) {
 
1097
        case 204:
 
1098
          /* (quote from RFC2616, section 10.2.5): The server has
 
1099
           * fulfilled the request but does not need to return an
 
1100
           * entity-body ... The 204 response MUST NOT include a
 
1101
           * message-body, and thus is always terminated by the first
 
1102
           * empty line after the header fields. */
 
1103
          /* FALLTHROUGH */
 
1104
        case 416: /* Requested Range Not Satisfiable, it has the
 
1105
                     Content-Length: set as the "real" document but no
 
1106
                     actual response is sent. */
 
1107
        case 304:
 
1108
          /* (quote from RFC2616, section 10.3.5): The 304 response
 
1109
           * MUST NOT contain a message-body, and thus is always
 
1110
           * terminated by the first empty line after the header
 
1111
           * fields.  */
 
1112
          if(data->set.timecondition)
 
1113
            data->info.timecond = TRUE;
 
1114
          k->size=0;
 
1115
          k->maxdownload=0;
 
1116
          k->ignorecl = TRUE; /* ignore Content-Length headers */
 
1117
          break;
 
1118
        default:
 
1119
          /* nothing */
 
1120
          break;
 
1121
        }
 
1122
      }
 
1123
      else {
 
1124
        k->header = FALSE;   /* this is not a header line */
 
1125
        break;
 
1126
      }
 
1127
    }
 
1128
 
 
1129
#ifdef CURL_DOES_CONVERSIONS
 
1130
    /* convert from the network encoding */
 
1131
    result = Curl_convert_from_network(data, k->p, strlen(k->p));
 
1132
    if(CURLE_OK != result) {
 
1133
      return(result);
 
1134
    }
 
1135
    /* Curl_convert_from_network calls failf if unsuccessful */
 
1136
#endif /* CURL_DOES_CONVERSIONS */
 
1137
 
 
1138
    /* Check for Content-Length: header lines to get size. Ignore
 
1139
       the header completely if we get a 416 response as then we're
 
1140
       resuming a document that we don't get, and this header contains
 
1141
       info about the true size of the document we didn't get now. */
 
1142
    if(!k->ignorecl && !data->set.ignorecl &&
 
1143
       checkprefix("Content-Length:", k->p)) {
 
1144
      curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
 
1145
      if(data->set.max_filesize &&
 
1146
         contentlength > data->set.max_filesize) {
 
1147
        failf(data, "Maximum file size exceeded");
 
1148
        return CURLE_FILESIZE_EXCEEDED;
 
1149
      }
 
1150
      if(contentlength >= 0) {
 
1151
        k->size = contentlength;
 
1152
        k->maxdownload = k->size;
 
1153
        /* we set the progress download size already at this point
 
1154
           just to make it easier for apps/callbacks to extract this
 
1155
           info as soon as possible */
 
1156
        Curl_pgrsSetDownloadSize(data, k->size);
 
1157
      }
 
1158
      else {
 
1159
        /* Negative Content-Length is really odd, and we know it
 
1160
           happens for example when older Apache servers send large
 
1161
           files */
 
1162
        conn->bits.close = TRUE;
 
1163
        infof(data, "Negative content-length: %" FORMAT_OFF_T
 
1164
              ", closing after transfer\n", contentlength);
 
1165
      }
 
1166
    }
 
1167
    /* check for Content-Type: header lines to get the MIME-type */
 
1168
    else if(checkprefix("Content-Type:", k->p)) {
 
1169
      char *contenttype = Curl_copy_header_value(k->p);
 
1170
      if (!contenttype)
 
1171
        return CURLE_OUT_OF_MEMORY;
 
1172
      if (!*contenttype)
 
1173
        /* ignore empty data */
 
1174
        free(contenttype);
 
1175
      else {
 
1176
        Curl_safefree(data->info.contenttype);
 
1177
        data->info.contenttype = contenttype;
 
1178
      }
 
1179
    }
 
1180
    else if((conn->httpversion == 10) &&
 
1181
            conn->bits.httpproxy &&
 
1182
            Curl_compareheader(k->p,
 
1183
                               "Proxy-Connection:", "keep-alive")) {
 
1184
      /*
 
1185
       * When a HTTP/1.0 reply comes when using a proxy, the
 
1186
       * 'Proxy-Connection: keep-alive' line tells us the
 
1187
       * connection will be kept alive for our pleasure.
 
1188
       * Default action for 1.0 is to close.
 
1189
       */
 
1190
      conn->bits.close = FALSE; /* don't close when done */
 
1191
      infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
 
1192
    }
 
1193
    else if((conn->httpversion == 11) &&
 
1194
            conn->bits.httpproxy &&
 
1195
            Curl_compareheader(k->p,
 
1196
                               "Proxy-Connection:", "close")) {
 
1197
      /*
 
1198
       * We get a HTTP/1.1 response from a proxy and it says it'll
 
1199
       * close down after this transfer.
 
1200
       */
 
1201
      conn->bits.close = TRUE; /* close when done */
 
1202
      infof(data, "HTTP/1.1 proxy connection set close!\n");
 
1203
    }
 
1204
    else if((conn->httpversion == 10) &&
 
1205
            Curl_compareheader(k->p, "Connection:", "keep-alive")) {
 
1206
      /*
 
1207
       * A HTTP/1.0 reply with the 'Connection: keep-alive' line
 
1208
       * tells us the connection will be kept alive for our
 
1209
       * pleasure.  Default action for 1.0 is to close.
 
1210
       *
 
1211
       * [RFC2068, section 19.7.1] */
 
1212
      conn->bits.close = FALSE; /* don't close when done */
 
1213
      infof(data, "HTTP/1.0 connection set to keep alive!\n");
 
1214
    }
 
1215
    else if(Curl_compareheader(k->p, "Connection:", "close")) {
 
1216
      /*
 
1217
       * [RFC 2616, section 8.1.2.1]
 
1218
       * "Connection: close" is HTTP/1.1 language and means that
 
1219
       * the connection will close when this request has been
 
1220
       * served.
 
1221
       */
 
1222
      conn->bits.close = TRUE; /* close when done */
 
1223
    }
 
1224
    else if(Curl_compareheader(k->p,
 
1225
                               "Transfer-Encoding:", "chunked")) {
 
1226
      /*
 
1227
       * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
 
1228
       * means that the server will send a series of "chunks". Each
 
1229
       * chunk starts with line with info (including size of the
 
1230
       * coming block) (terminated with CRLF), then a block of data
 
1231
       * with the previously mentioned size. There can be any amount
 
1232
       * of chunks, and a chunk-data set to zero signals the
 
1233
       * end-of-chunks. */
 
1234
      k->chunk = TRUE; /* chunks coming our way */
 
1235
 
 
1236
      /* init our chunky engine */
 
1237
      Curl_httpchunk_init(conn);
 
1238
    }
 
1239
 
 
1240
    else if(checkprefix("Trailer:", k->p) ||
 
1241
            checkprefix("Trailers:", k->p)) {
 
1242
      /*
 
1243
       * This test helps Curl_httpchunk_read() to determine to look
 
1244
       * for well formed trailers after the zero chunksize record. In
 
1245
       * this case a CRLF is required after the zero chunksize record
 
1246
       * when no trailers are sent, or after the last trailer record.
 
1247
       *
 
1248
       * It seems both Trailer: and Trailers: occur in the wild.
 
1249
       */
 
1250
      k->trailerhdrpresent = TRUE;
 
1251
    }
 
1252
 
 
1253
    else if(checkprefix("Content-Encoding:", k->p) &&
 
1254
            data->set.str[STRING_ENCODING]) {
 
1255
      /*
 
1256
       * Process Content-Encoding. Look for the values: identity,
 
1257
       * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
 
1258
       * x-compress are the same as gzip and compress. (Sec 3.5 RFC
 
1259
       * 2616). zlib cannot handle compress.  However, errors are
 
1260
       * handled further down when the response body is processed
 
1261
       */
 
1262
      char *start;
 
1263
 
 
1264
      /* Find the first non-space letter */
 
1265
      start = k->p + 17;
 
1266
      while(*start && ISSPACE(*start))
 
1267
        start++;
 
1268
 
 
1269
      /* Record the content-encoding for later use */
 
1270
      if(checkprefix("identity", start))
 
1271
        k->content_encoding = IDENTITY;
 
1272
      else if(checkprefix("deflate", start))
 
1273
        k->content_encoding = DEFLATE;
 
1274
      else if(checkprefix("gzip", start)
 
1275
              || checkprefix("x-gzip", start))
 
1276
        k->content_encoding = GZIP;
 
1277
      else if(checkprefix("compress", start)
 
1278
              || checkprefix("x-compress", start))
 
1279
        k->content_encoding = COMPRESS;
 
1280
    }
 
1281
    else if(checkprefix("Content-Range:", k->p)) {
 
1282
      /* Content-Range: bytes [num]-
 
1283
         Content-Range: bytes: [num]-
 
1284
         Content-Range: [num]-
 
1285
 
 
1286
         The second format was added since Sun's webserver
 
1287
         JavaWebServer/1.1.1 obviously sends the header this way!
 
1288
         The third added since some servers use that!
 
1289
      */
 
1290
 
 
1291
      char *ptr = k->p + 14;
 
1292
 
 
1293
      /* Move forward until first digit */
 
1294
      while(*ptr && !ISDIGIT(*ptr))
 
1295
        ptr++;
 
1296
 
 
1297
      k->offset = curlx_strtoofft(ptr, NULL, 10);
 
1298
 
 
1299
      if(data->state.resume_from == k->offset)
 
1300
        /* we asked for a resume and we got it */
 
1301
        k->content_range = TRUE;
 
1302
    }
 
1303
#if !defined(CURL_DISABLE_COOKIES)
 
1304
    else if(data->cookies &&
 
1305
            checkprefix("Set-Cookie:", k->p)) {
 
1306
      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
 
1307
                      CURL_LOCK_ACCESS_SINGLE);
 
1308
      Curl_cookie_add(data,
 
1309
                      data->cookies, TRUE, k->p+11,
 
1310
                      /* If there is a custom-set Host: name, use it
 
1311
                         here, or else use real peer host name. */
 
1312
                      conn->allocptr.cookiehost?
 
1313
                      conn->allocptr.cookiehost:conn->host.name,
 
1314
                      data->state.path);
 
1315
      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
 
1316
    }
 
1317
#endif
 
1318
    else if(checkprefix("Last-Modified:", k->p) &&
 
1319
            (data->set.timecondition || data->set.get_filetime) ) {
 
1320
      time_t secs=time(NULL);
 
1321
      k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
 
1322
                                  &secs);
 
1323
      if(data->set.get_filetime)
 
1324
        data->info.filetime = (long)k->timeofdoc;
 
1325
    }
 
1326
    else if((checkprefix("WWW-Authenticate:", k->p) &&
 
1327
             (401 == k->httpcode)) ||
 
1328
            (checkprefix("Proxy-authenticate:", k->p) &&
 
1329
             (407 == k->httpcode))) {
 
1330
      result = Curl_http_input_auth(conn, k->httpcode, k->p);
 
1331
      if(result)
 
1332
        return result;
 
1333
    }
 
1334
    else if((k->httpcode >= 300 && k->httpcode < 400) &&
 
1335
            checkprefix("Location:", k->p)) {
 
1336
      /* this is the URL that the server advises us to use instead */
 
1337
      char *location = Curl_copy_header_value(k->p);
 
1338
      if (!location)
 
1339
        return CURLE_OUT_OF_MEMORY;
 
1340
      if (!*location)
 
1341
        /* ignore empty data */
 
1342
        free(location);
 
1343
      else {
 
1344
        DEBUGASSERT(!data->req.location);
 
1345
        data->req.location = location;
 
1346
 
 
1347
        if(data->set.http_follow_location) {
 
1348
          DEBUGASSERT(!data->req.newurl);
 
1349
          data->req.newurl = strdup(data->req.location); /* clone */
 
1350
          if(!data->req.newurl)
 
1351
            return CURLE_OUT_OF_MEMORY;
 
1352
 
 
1353
          /* some cases of POST and PUT etc needs to rewind the data
 
1354
             stream at this point */
 
1355
          result = Curl_http_perhapsrewind(conn);
 
1356
          if(result)
 
1357
            return result;
 
1358
        }
 
1359
      }
 
1360
    }
 
1361
 
 
1362
    /*
 
1363
     * End of header-checks. Write them to the client.
 
1364
     */
 
1365
 
 
1366
    writetype = CLIENTWRITE_HEADER;
 
1367
    if(data->set.include_header)
 
1368
      writetype |= CLIENTWRITE_BODY;
 
1369
 
 
1370
    if(data->set.verbose)
 
1371
      Curl_debug(data, CURLINFO_HEADER_IN,
 
1372
                 k->p, (size_t)k->hbuflen, conn);
 
1373
 
 
1374
    result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
 
1375
    if(result)
 
1376
      return result;
 
1377
 
 
1378
    data->info.header_size += (long)k->hbuflen;
 
1379
    data->req.headerbytecount += (long)k->hbuflen;
 
1380
 
 
1381
    /* reset hbufp pointer && hbuflen */
 
1382
    k->hbufp = data->state.headerbuff;
 
1383
    k->hbuflen = 0;
 
1384
  }
 
1385
  while(!*stop_reading && *k->str); /* header line within buffer */
 
1386
 
 
1387
  /* We might have reached the end of the header part here, but
 
1388
     there might be a non-header part left in the end of the read
 
1389
     buffer. */
 
1390
 
 
1391
  return CURLE_OK;
 
1392
}
 
1393
#endif   /* CURL_DISABLE_HTTP */
 
1394
 
 
1395
/*
 
1396
 * Send data to upload to the server, when the socket is writable.
 
1397
 */
 
1398
static CURLcode readwrite_upload(struct SessionHandle *data,
 
1399
                                 struct connectdata *conn,
 
1400
                                 struct SingleRequest *k,
 
1401
                                 int *didwhat)
 
1402
{
 
1403
  ssize_t i, si;
 
1404
  ssize_t bytes_written;
 
1405
  CURLcode result;
 
1406
  ssize_t nread; /* number of bytes read */
 
1407
 
 
1408
  if((k->bytecount == 0) && (k->writebytecount == 0))
 
1409
    Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 
1410
 
 
1411
  *didwhat |= KEEP_WRITE;
 
1412
 
 
1413
  /*
 
1414
   * We loop here to do the READ and SEND loop until we run out of
 
1415
   * data to send or until we get EWOULDBLOCK back
 
1416
   */
 
1417
  do {
 
1418
 
 
1419
    /* only read more data if there's no upload data already
 
1420
       present in the upload buffer */
 
1421
    if(0 == data->req.upload_present) {
 
1422
      /* init the "upload from here" pointer */
 
1423
      data->req.upload_fromhere = k->uploadbuf;
 
1424
 
 
1425
      if(!k->upload_done) {
 
1426
        /* HTTP pollution, this should be written nicer to become more
 
1427
           protocol agnostic. */
 
1428
        int fillcount;
 
1429
 
 
1430
        if((k->exp100 == EXP100_SENDING_REQUEST) &&
 
1431
           (data->state.proto.http->sending == HTTPSEND_BODY)) {
 
1432
          /* If this call is to send body data, we must take some action:
 
1433
             We have sent off the full HTTP 1.1 request, and we shall now
 
1434
             go into the Expect: 100 state and await such a header */
 
1435
          k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
 
1436
          k->keepon &= ~KEEP_WRITE;         /* disable writing */
 
1437
          k->start100 = Curl_tvnow();       /* timeout count starts now */
 
1438
          *didwhat &= ~KEEP_WRITE;  /* we didn't write anything actually */
 
1439
          break;
 
1440
        }
 
1441
 
 
1442
        result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
 
1443
        if(result)
 
1444
          return result;
 
1445
 
 
1446
        nread = (ssize_t)fillcount;
 
1447
      }
 
1448
      else
 
1449
        nread = 0; /* we're done uploading/reading */
 
1450
 
 
1451
      if(!nread && (k->keepon & KEEP_WRITE_PAUSE)) {
 
1452
        /* this is a paused transfer */
 
1453
        break;
 
1454
      }
 
1455
      else if(nread<=0) {
 
1456
        /* done */
 
1457
        k->keepon &= ~KEEP_WRITE; /* we're done writing */
 
1458
 
 
1459
        if(conn->bits.rewindaftersend) {
 
1460
          result = Curl_readrewind(conn);
 
1461
          if(result)
 
1462
            return result;
 
1463
        }
 
1464
        break;
 
1465
      }
 
1466
 
 
1467
      /* store number of bytes available for upload */
 
1468
      data->req.upload_present = nread;
 
1469
 
 
1470
      /* convert LF to CRLF if so asked */
 
1471
#ifdef CURL_DO_LINEEND_CONV
 
1472
      /* always convert if we're FTPing in ASCII mode */
 
1473
      if((data->set.crlf) || (data->set.prefer_ascii))
 
1474
#else
 
1475
        if(data->set.crlf)
 
1476
#endif /* CURL_DO_LINEEND_CONV */
 
1477
        {
 
1478
          if(data->state.scratch == NULL)
 
1479
            data->state.scratch = malloc(2*BUFSIZE);
 
1480
          if(data->state.scratch == NULL) {
 
1481
            failf (data, "Failed to alloc scratch buffer!");
 
1482
            return CURLE_OUT_OF_MEMORY;
 
1483
          }
 
1484
          /*
 
1485
           * ASCII/EBCDIC Note: This is presumably a text (not binary)
 
1486
           * transfer so the data should already be in ASCII.
 
1487
           * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
 
1488
           * must be used instead of the escape sequences \r & \n.
 
1489
           */
 
1490
          for(i = 0, si = 0; i < nread; i++, si++) {
 
1491
            if(data->req.upload_fromhere[i] == 0x0a) {
 
1492
              data->state.scratch[si++] = 0x0d;
 
1493
              data->state.scratch[si] = 0x0a;
 
1494
              if(!data->set.crlf) {
 
1495
                /* we're here only because FTP is in ASCII mode...
 
1496
                   bump infilesize for the LF we just added */
 
1497
                data->set.infilesize++;
 
1498
              }
 
1499
            }
 
1500
            else
 
1501
              data->state.scratch[si] = data->req.upload_fromhere[i];
 
1502
          }
 
1503
          if(si != nread) {
 
1504
            /* only perform the special operation if we really did replace
 
1505
               anything */
 
1506
            nread = si;
 
1507
 
 
1508
            /* upload from the new (replaced) buffer instead */
 
1509
            data->req.upload_fromhere = data->state.scratch;
 
1510
 
 
1511
            /* set the new amount too */
 
1512
            data->req.upload_present = nread;
 
1513
          }
 
1514
        }
 
1515
    } /* if 0 == data->req.upload_present */
 
1516
    else {
 
1517
      /* We have a partial buffer left from a previous "round". Use
 
1518
         that instead of reading more data */
 
1519
    }
 
1520
 
 
1521
    /* write to socket (send away data) */
 
1522
    result = Curl_write(conn,
 
1523
                        conn->writesockfd,     /* socket to send to */
 
1524
                        data->req.upload_fromhere, /* buffer pointer */
 
1525
                        data->req.upload_present,  /* buffer size */
 
1526
                        &bytes_written);       /* actually send away */
 
1527
 
 
1528
    if(result)
 
1529
      return result;
 
1530
 
 
1531
    if(data->set.verbose)
 
1532
      /* show the data before we change the pointer upload_fromhere */
 
1533
      Curl_debug(data, CURLINFO_DATA_OUT, data->req.upload_fromhere,
 
1534
                 (size_t)bytes_written, conn);
 
1535
 
 
1536
    if(data->req.upload_present != bytes_written) {
 
1537
      /* we only wrote a part of the buffer (if anything), deal with it! */
 
1538
 
 
1539
      /* store the amount of bytes left in the buffer to write */
 
1540
      data->req.upload_present -= bytes_written;
 
1541
 
 
1542
      /* advance the pointer where to find the buffer when the next send
 
1543
         is to happen */
 
1544
      data->req.upload_fromhere += bytes_written;
 
1545
    }
 
1546
    else {
 
1547
      /* we've uploaded that buffer now */
 
1548
      data->req.upload_fromhere = k->uploadbuf;
 
1549
      data->req.upload_present = 0; /* no more bytes left */
 
1550
 
 
1551
      if(k->upload_done) {
 
1552
        /* switch off writing, we're done! */
 
1553
        k->keepon &= ~KEEP_WRITE; /* we're done writing */
 
1554
      }
 
1555
    }
 
1556
 
 
1557
    k->writebytecount += bytes_written;
 
1558
    Curl_pgrsSetUploadCounter(data, k->writebytecount);
 
1559
 
 
1560
  } while(0); /* just to break out from! */
 
1561
 
 
1562
  return CURLE_OK;
 
1563
}
 
1564
 
333
1565
/*
334
1566
 * Curl_readwrite() is the low-level function to be called when data is to
335
1567
 * be read and written to/from the connection.
340
1572
  struct SessionHandle *data = conn->data;
341
1573
  struct SingleRequest *k = &data->req;
342
1574
  CURLcode result;
343
 
  ssize_t nread; /* number of bytes read */
344
1575
  int didwhat=0;
345
1576
 
346
1577
  curl_socket_t fd_read;
347
1578
  curl_socket_t fd_write;
348
 
  curl_off_t contentlength;
349
1579
  int select_res = conn->cselect_bits;
350
1580
 
351
1581
  conn->cselect_bits = 0;
382
1612
     buffer) */
383
1613
  if((k->keepon & KEEP_READ) &&
384
1614
     ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
385
 
    /* read */
386
 
    bool is_empty_data = FALSE;
387
 
 
388
 
    /* This is where we loop until we have read everything there is to
389
 
       read or we get a EWOULDBLOCK */
390
 
    do {
391
 
      size_t buffersize = data->set.buffer_size?
392
 
        data->set.buffer_size : BUFSIZE;
393
 
      size_t bytestoread = buffersize;
394
 
      int readrc;
395
 
 
396
 
      if(k->size != -1 && !k->header) {
397
 
        /* make sure we don't read "too much" if we can help it since we
398
 
           might be pipelining and then someone else might want to read what
399
 
           follows! */
400
 
        curl_off_t totalleft = k->size - k->bytecount;
401
 
        if(totalleft < (curl_off_t)bytestoread)
402
 
          bytestoread = (size_t)totalleft;
403
 
      }
404
 
 
405
 
      if(bytestoread) {
406
 
        /* receive data from the network! */
407
 
        readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
408
 
 
409
 
        /* subzero, this would've blocked */
410
 
        if(0 > readrc)
411
 
          break; /* get out of loop */
412
 
 
413
 
        /* get the CURLcode from the int */
414
 
        result = (CURLcode)readrc;
415
 
 
416
 
        if(result>0)
417
 
          return result;
418
 
      }
419
 
      else {
420
 
        /* read nothing but since we wanted nothing we consider this an OK
421
 
           situation to proceed from */
422
 
        nread = 0;
423
 
        result = CURLE_OK;
424
 
      }
425
 
 
426
 
      if((k->bytecount == 0) && (k->writebytecount == 0)) {
427
 
        Curl_pgrsTime(data, TIMER_STARTTRANSFER);
428
 
        if(k->exp100 > EXP100_SEND_DATA)
429
 
          /* set time stamp to compare with when waiting for the 100 */
430
 
          k->start100 = Curl_tvnow();
431
 
      }
432
 
 
433
 
      didwhat |= KEEP_READ;
434
 
      /* indicates data of zero size, i.e. empty file */
435
 
      is_empty_data = (bool)((nread == 0) && (k->bodywrites == 0));
436
 
 
437
 
      /* NULL terminate, allowing string ops to be used */
438
 
      if(0 < nread || is_empty_data) {
439
 
        k->buf[nread] = 0;
440
 
      }
441
 
      else if(0 >= nread) {
442
 
        /* if we receive 0 or less here, the server closed the connection
443
 
           and we bail out from this! */
444
 
        DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
445
 
        k->keepon &= ~KEEP_READ;
446
 
        break;
447
 
      }
448
 
 
449
 
      /* Default buffer to use when we write the buffer, it may be changed
450
 
         in the flow below before the actual storing is done. */
451
 
      k->str = k->buf;
452
 
 
453
 
      /* Since this is a two-state thing, we check if we are parsing
454
 
         headers at the moment or not. */
455
 
      if(k->header) {
456
 
        /* we are in parse-the-header-mode */
457
 
        bool stop_reading = FALSE;
458
 
 
459
 
        /* header line within buffer loop */
460
 
        do {
461
 
          size_t hbufp_index;
462
 
          size_t rest_length;
463
 
          size_t full_length;
464
 
          int writetype;
465
 
 
466
 
          /* str_start is start of line within buf */
467
 
          k->str_start = k->str;
468
 
 
469
 
          /* data is in network encoding so use 0x0a instead of '\n' */
470
 
          k->end_ptr = memchr(k->str_start, 0x0a, nread);
471
 
 
472
 
          if(!k->end_ptr) {
473
 
            /* Not a complete header line within buffer, append the data to
474
 
               the end of the headerbuff. */
475
 
 
476
 
            if(k->hbuflen + nread >= data->state.headersize) {
477
 
              /* We enlarge the header buffer as it is too small */
478
 
              char *newbuff;
479
 
              size_t newsize=CURLMAX((k->hbuflen+nread)*3/2,
480
 
                                     data->state.headersize*2);
481
 
              hbufp_index = k->hbufp - data->state.headerbuff;
482
 
              newbuff = (char *)realloc(data->state.headerbuff, newsize);
483
 
              if(!newbuff) {
484
 
                failf (data, "Failed to alloc memory for big header!");
485
 
                return CURLE_OUT_OF_MEMORY;
486
 
              }
487
 
              data->state.headersize=newsize;
488
 
              data->state.headerbuff = newbuff;
489
 
              k->hbufp = data->state.headerbuff + hbufp_index;
490
 
            }
491
 
            memcpy(k->hbufp, k->str, nread);
492
 
            k->hbufp += nread;
493
 
            k->hbuflen += nread;
494
 
            if(!k->headerline && (k->hbuflen>5)) {
495
 
              /* make a first check that this looks like a HTTP header */
496
 
              if(!checkhttpprefix(data, data->state.headerbuff)) {
497
 
                /* this is not the beginning of a HTTP first header line */
498
 
                k->header = FALSE;
499
 
                k->badheader = HEADER_ALLBAD;
500
 
                break;
501
 
              }
502
 
            }
503
 
 
504
 
            break; /* read more and try again */
505
 
          }
506
 
 
507
 
          /* decrease the size of the remaining (supposed) header line */
508
 
          rest_length = (k->end_ptr - k->str)+1;
509
 
          nread -= (ssize_t)rest_length;
510
 
 
511
 
          k->str = k->end_ptr + 1; /* move past new line */
512
 
 
513
 
          full_length = k->str - k->str_start;
514
 
 
515
 
          /*
516
 
           * We're about to copy a chunk of data to the end of the
517
 
           * already received header. We make sure that the full string
518
 
           * fit in the allocated header buffer, or else we enlarge
519
 
           * it.
520
 
           */
521
 
          if(k->hbuflen + full_length >=
522
 
             data->state.headersize) {
523
 
            char *newbuff;
524
 
            size_t newsize=CURLMAX((k->hbuflen+full_length)*3/2,
525
 
                                   data->state.headersize*2);
526
 
            hbufp_index = k->hbufp - data->state.headerbuff;
527
 
            newbuff = (char *)realloc(data->state.headerbuff, newsize);
528
 
            if(!newbuff) {
529
 
              failf (data, "Failed to alloc memory for big header!");
530
 
              return CURLE_OUT_OF_MEMORY;
531
 
            }
532
 
            data->state.headersize= newsize;
533
 
            data->state.headerbuff = newbuff;
534
 
            k->hbufp = data->state.headerbuff + hbufp_index;
535
 
          }
536
 
 
537
 
          /* copy to end of line */
538
 
          memcpy(k->hbufp, k->str_start, full_length);
539
 
          k->hbufp += full_length;
540
 
          k->hbuflen += full_length;
541
 
          *k->hbufp = 0;
542
 
          k->end_ptr = k->hbufp;
543
 
 
544
 
          k->p = data->state.headerbuff;
545
 
 
546
 
          /****
547
 
           * We now have a FULL header line that p points to
548
 
           *****/
549
 
 
550
 
          if(!k->headerline) {
551
 
            /* the first read header */
552
 
            if((k->hbuflen>5) &&
553
 
               !checkhttpprefix(data, data->state.headerbuff)) {
554
 
              /* this is not the beginning of a HTTP first header line */
555
 
              k->header = FALSE;
556
 
              if(nread)
557
 
                /* since there's more, this is a partial bad header */
558
 
                k->badheader = HEADER_PARTHEADER;
559
 
              else {
560
 
                /* this was all we read so its all a bad header */
561
 
                k->badheader = HEADER_ALLBAD;
562
 
                nread = (ssize_t)rest_length;
563
 
              }
564
 
              break;
565
 
            }
566
 
          }
567
 
 
568
 
          /* headers are in network encoding so
569
 
             use 0x0a and 0x0d instead of '\n' and '\r' */
570
 
          if((0x0a == *k->p) || (0x0d == *k->p)) {
571
 
            size_t headerlen;
572
 
            /* Zero-length header line means end of headers! */
573
 
 
574
 
#ifdef CURL_DOES_CONVERSIONS
575
 
            if(0x0d == *k->p) {
576
 
              *k->p = '\r'; /* replace with CR in host encoding */
577
 
              k->p++;       /* pass the CR byte */
578
 
            }
579
 
            if(0x0a == *k->p) {
580
 
              *k->p = '\n'; /* replace with LF in host encoding */
581
 
              k->p++;       /* pass the LF byte */
582
 
            }
583
 
#else
584
 
            if('\r' == *k->p)
585
 
              k->p++; /* pass the \r byte */
586
 
            if('\n' == *k->p)
587
 
              k->p++; /* pass the \n byte */
588
 
#endif /* CURL_DOES_CONVERSIONS */
589
 
 
590
 
            if(100 == k->httpcode) {
591
 
              /*
592
 
               * We have made a HTTP PUT or POST and this is 1.1-lingo
593
 
               * that tells us that the server is OK with this and ready
594
 
               * to receive the data.
595
 
               * However, we'll get more headers now so we must get
596
 
               * back into the header-parsing state!
597
 
               */
598
 
              k->header = TRUE;
599
 
              k->headerline = 0; /* restart the header line counter */
600
 
 
601
 
              /* if we did wait for this do enable write now! */
602
 
              if(k->exp100) {
603
 
                k->exp100 = EXP100_SEND_DATA;
604
 
                k->keepon |= KEEP_WRITE;
605
 
              }
606
 
            }
607
 
            else {
608
 
              k->header = FALSE; /* no more header to parse! */
609
 
 
610
 
              if((k->size == -1) && !k->chunk && !conn->bits.close &&
611
 
                 (k->httpversion >= 11) ) {
612
 
                /* On HTTP 1.1, when connection is not to get closed, but no
613
 
                   Content-Length nor Content-Encoding chunked have been
614
 
                   received, according to RFC2616 section 4.4 point 5, we
615
 
                   assume that the server will close the connection to
616
 
                   signal the end of the document. */
617
 
                infof(data, "no chunk, no close, no size. Assume close to "
618
 
                      "signal end\n");
619
 
                conn->bits.close = TRUE;
620
 
              }
621
 
            }
622
 
 
623
 
            if(417 == k->httpcode) {
624
 
              /*
625
 
               * we got: "417 Expectation Failed" this means:
626
 
               * we have made a HTTP call and our Expect Header
627
 
               * seems to cause a problem => abort the write operations
628
 
               * (or prevent them from starting).
629
 
               */
630
 
              k->exp100 = EXP100_FAILED;
631
 
              k->keepon &= ~KEEP_WRITE;
632
 
            }
633
 
 
634
 
#ifndef CURL_DISABLE_HTTP
635
 
            /*
636
 
             * When all the headers have been parsed, see if we should give
637
 
             * up and return an error.
638
 
             */
639
 
            if(Curl_http_should_fail(conn)) {
640
 
              failf (data, "The requested URL returned error: %d",
641
 
                     k->httpcode);
642
 
              return CURLE_HTTP_RETURNED_ERROR;
643
 
            }
644
 
#endif   /* CURL_DISABLE_HTTP */
645
 
 
646
 
            /* now, only output this if the header AND body are requested:
647
 
             */
648
 
            writetype = CLIENTWRITE_HEADER;
649
 
            if(data->set.include_header)
650
 
              writetype |= CLIENTWRITE_BODY;
651
 
 
652
 
            headerlen = k->p - data->state.headerbuff;
653
 
 
654
 
            result = Curl_client_write(conn, writetype,
655
 
                                       data->state.headerbuff,
656
 
                                       headerlen);
657
 
            if(result)
658
 
              return result;
659
 
 
660
 
            data->info.header_size += (long)headerlen;
661
 
            data->req.headerbytecount += (long)headerlen;
662
 
 
663
 
            data->req.deductheadercount =
664
 
              (100 == k->httpcode)?data->req.headerbytecount:0;
665
 
 
666
 
            if(data->state.resume_from &&
667
 
               (data->set.httpreq==HTTPREQ_GET) &&
668
 
               (k->httpcode == 416)) {
669
 
              /* "Requested Range Not Satisfiable" */
670
 
              stop_reading = TRUE;
671
 
            }
672
 
 
673
 
#ifndef CURL_DISABLE_HTTP
674
 
            if(!stop_reading) {
675
 
              /* Curl_http_auth_act() checks what authentication methods
676
 
               * that are available and decides which one (if any) to
677
 
               * use. It will set 'newurl' if an auth metod was picked. */
678
 
              result = Curl_http_auth_act(conn);
679
 
 
680
 
              if(result)
681
 
                return result;
682
 
 
683
 
              if(conn->bits.rewindaftersend) {
684
 
                /* We rewind after a complete send, so thus we continue
685
 
                   sending now */
686
 
                infof(data, "Keep sending data to get tossed away!\n");
687
 
                k->keepon |= KEEP_WRITE;
688
 
              }
689
 
            }
690
 
#endif   /* CURL_DISABLE_HTTP */
691
 
 
692
 
            if(!k->header) {
693
 
              /*
694
 
               * really end-of-headers.
695
 
               *
696
 
               * If we requested a "no body", this is a good time to get
697
 
               * out and return home.
698
 
               */
699
 
              if(data->set.opt_no_body)
700
 
                stop_reading = TRUE;
701
 
              else {
702
 
                /* If we know the expected size of this document, we set the
703
 
                   maximum download size to the size of the expected
704
 
                   document or else, we won't know when to stop reading!
705
 
 
706
 
                   Note that we set the download maximum even if we read a
707
 
                   "Connection: close" header, to make sure that
708
 
                   "Content-Length: 0" still prevents us from attempting to
709
 
                   read the (missing) response-body.
710
 
                */
711
 
                /* According to RFC2616 section 4.4, we MUST ignore
712
 
                   Content-Length: headers if we are now receiving data
713
 
                   using chunked Transfer-Encoding.
714
 
                */
715
 
                if(k->chunk)
716
 
                  k->size=-1;
717
 
 
718
 
              }
719
 
              if(-1 != k->size) {
720
 
                /* We do this operation even if no_body is true, since this
721
 
                   data might be retrieved later with curl_easy_getinfo()
722
 
                   and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
723
 
 
724
 
                Curl_pgrsSetDownloadSize(data, k->size);
725
 
                k->maxdownload = k->size;
726
 
              }
727
 
              /* If max download size is *zero* (nothing) we already
728
 
                 have nothing and can safely return ok now! */
729
 
              if(0 == k->maxdownload)
730
 
                stop_reading = TRUE;
731
 
 
732
 
              if(stop_reading) {
733
 
                /* we make sure that this socket isn't read more now */
734
 
                k->keepon &= ~KEEP_READ;
735
 
              }
736
 
 
737
 
              if(data->set.verbose)
738
 
                Curl_debug(data, CURLINFO_HEADER_IN,
739
 
                           k->str_start, headerlen, conn);
740
 
              break;          /* exit header line loop */
741
 
            }
742
 
 
743
 
            /* We continue reading headers, so reset the line-based
744
 
               header parsing variables hbufp && hbuflen */
745
 
            k->hbufp = data->state.headerbuff;
746
 
            k->hbuflen = 0;
747
 
            continue;
748
 
          }
749
 
 
750
 
          /*
751
 
           * Checks for special headers coming up.
752
 
           */
753
 
 
754
 
          if(!k->headerline++) {
755
 
            /* This is the first header, it MUST be the error code line
756
 
               or else we consider this to be the body right away! */
757
 
            int httpversion_major;
758
 
            int nc;
759
 
#ifdef CURL_DOES_CONVERSIONS
760
 
#define HEADER1 scratch
761
 
#define SCRATCHSIZE 21
762
 
            CURLcode res;
763
 
            char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
764
 
            /* We can't really convert this yet because we
765
 
               don't know if it's the 1st header line or the body.
766
 
               So we do a partial conversion into a scratch area,
767
 
               leaving the data at k->p as-is.
768
 
            */
769
 
            strncpy(&scratch[0], k->p, SCRATCHSIZE);
770
 
            scratch[SCRATCHSIZE] = 0; /* null terminate */
771
 
            res = Curl_convert_from_network(data,
772
 
                                            &scratch[0],
773
 
                                            SCRATCHSIZE);
774
 
            if(CURLE_OK != res) {
775
 
              /* Curl_convert_from_network calls failf if unsuccessful */
776
 
              return res;
777
 
            }
778
 
#else
779
 
#define HEADER1 k->p /* no conversion needed, just use k->p */
780
 
#endif /* CURL_DOES_CONVERSIONS */
781
 
 
782
 
            nc = sscanf(HEADER1,
783
 
                        " HTTP/%d.%d %3d",
784
 
                        &httpversion_major,
785
 
                        &k->httpversion,
786
 
                        &k->httpcode);
787
 
            if(nc==3) {
788
 
              k->httpversion += 10 * httpversion_major;
789
 
            }
790
 
            else {
791
 
              /* this is the real world, not a Nirvana
792
 
                 NCSA 1.5.x returns this crap when asked for HTTP/1.1
793
 
              */
794
 
              nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
795
 
              k->httpversion = 10;
796
 
 
797
 
              /* If user has set option HTTP200ALIASES,
798
 
                 compare header line against list of aliases
799
 
              */
800
 
              if(!nc) {
801
 
                if(checkhttpprefix(data, k->p)) {
802
 
                  nc = 1;
803
 
                  k->httpcode = 200;
804
 
                  k->httpversion = 10;
805
 
                }
806
 
              }
807
 
            }
808
 
 
809
 
            if(nc) {
810
 
              data->info.httpcode = k->httpcode;
811
 
              data->info.httpversion = k->httpversion;
812
 
 
813
 
              /*
814
 
               * This code executes as part of processing the header.  As a
815
 
               * result, it's not totally clear how to interpret the
816
 
               * response code yet as that depends on what other headers may
817
 
               * be present.  401 and 407 may be errors, but may be OK
818
 
               * depending on how authentication is working.  Other codes
819
 
               * are definitely errors, so give up here.
820
 
               */
821
 
              if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
822
 
                 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
823
 
                 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
824
 
 
825
 
                if(data->state.resume_from &&
826
 
                   (data->set.httpreq==HTTPREQ_GET) &&
827
 
                   (k->httpcode == 416)) {
828
 
                  /* "Requested Range Not Satisfiable", just proceed and
829
 
                     pretend this is no error */
830
 
                }
831
 
                else {
832
 
                  /* serious error, go home! */
833
 
                  failf (data, "The requested URL returned error: %d",
834
 
                         k->httpcode);
835
 
                  return CURLE_HTTP_RETURNED_ERROR;
836
 
                }
837
 
              }
838
 
 
839
 
              if(k->httpversion == 10) {
840
 
                /* Default action for HTTP/1.0 must be to close, unless
841
 
                   we get one of those fancy headers that tell us the
842
 
                   server keeps it open for us! */
843
 
                infof(data, "HTTP 1.0, assume close after body\n");
844
 
                conn->bits.close = TRUE;
845
 
              }
846
 
              else if(k->httpversion >= 11 &&
847
 
                      !conn->bits.close) {
848
 
                /* If HTTP version is >= 1.1 and connection is persistent
849
 
                   server supports pipelining. */
850
 
                DEBUGF(infof(data,
851
 
                             "HTTP 1.1 or later with persistent connection, "
852
 
                             "pipelining supported\n"));
853
 
                conn->server_supports_pipelining = TRUE;
854
 
              }
855
 
 
856
 
              switch(k->httpcode) {
857
 
              case 204:
858
 
                /* (quote from RFC2616, section 10.2.5): The server has
859
 
                 * fulfilled the request but does not need to return an
860
 
                 * entity-body ... The 204 response MUST NOT include a
861
 
                 * message-body, and thus is always terminated by the first
862
 
                 * empty line after the header fields. */
863
 
                /* FALLTHROUGH */
864
 
              case 416: /* Requested Range Not Satisfiable, it has the
865
 
                           Content-Length: set as the "real" document but no
866
 
                           actual response is sent. */
867
 
              case 304:
868
 
                /* (quote from RFC2616, section 10.3.5): The 304 response
869
 
                 * MUST NOT contain a message-body, and thus is always
870
 
                 * terminated by the first empty line after the header
871
 
                 * fields.  */
872
 
                k->size=0;
873
 
                k->maxdownload=0;
874
 
                k->ignorecl = TRUE; /* ignore Content-Length headers */
875
 
                break;
876
 
              default:
877
 
                /* nothing */
878
 
                break;
879
 
              }
880
 
            }
881
 
            else {
882
 
              k->header = FALSE;   /* this is not a header line */
883
 
              break;
884
 
            }
885
 
          }
886
 
 
887
 
#ifdef CURL_DOES_CONVERSIONS
888
 
          /* convert from the network encoding */
889
 
          result = Curl_convert_from_network(data, k->p, strlen(k->p));
890
 
          if(CURLE_OK != result) {
891
 
            return(result);
892
 
          }
893
 
          /* Curl_convert_from_network calls failf if unsuccessful */
894
 
#endif /* CURL_DOES_CONVERSIONS */
895
 
 
896
 
          /* Check for Content-Length: header lines to get size. Ignore
897
 
             the header completely if we get a 416 response as then we're
898
 
             resuming a document that we don't get, and this header contains
899
 
             info about the true size of the document we didn't get now. */
900
 
          if(!k->ignorecl && !data->set.ignorecl &&
901
 
             checkprefix("Content-Length:", k->p)) {
902
 
            contentlength = curlx_strtoofft(k->p+15, NULL, 10);
903
 
            if(data->set.max_filesize &&
904
 
               contentlength > data->set.max_filesize) {
905
 
              failf(data, "Maximum file size exceeded");
906
 
              return CURLE_FILESIZE_EXCEEDED;
907
 
            }
908
 
            if(contentlength >= 0) {
909
 
              k->size = contentlength;
910
 
              k->maxdownload = k->size;
911
 
              /* we set the progress download size already at this point
912
 
                 just to make it easier for apps/callbacks to extract this
913
 
                 info as soon as possible */
914
 
              Curl_pgrsSetDownloadSize(data, k->size);
915
 
            }
916
 
            else {
917
 
              /* Negative Content-Length is really odd, and we know it
918
 
                 happens for example when older Apache servers send large
919
 
                 files */
920
 
              conn->bits.close = TRUE;
921
 
              infof(data, "Negative content-length: %" FORMAT_OFF_T
922
 
                    ", closing after transfer\n", contentlength);
923
 
            }
924
 
          }
925
 
          /* check for Content-Type: header lines to get the mime-type */
926
 
          else if(checkprefix("Content-Type:", k->p)) {
927
 
            char *start;
928
 
            char *end;
929
 
            size_t len;
930
 
 
931
 
            /* Find the first non-space letter */
932
 
            for(start=k->p+13;
933
 
                *start && ISSPACE(*start);
934
 
                start++)
935
 
              ;  /* empty loop */
936
 
 
937
 
            /* data is now in the host encoding so
938
 
               use '\r' and '\n' instead of 0x0d and 0x0a */
939
 
            end = strchr(start, '\r');
940
 
            if(!end)
941
 
              end = strchr(start, '\n');
942
 
 
943
 
            if(end) {
944
 
              /* skip all trailing space letters */
945
 
              for(; ISSPACE(*end) && (end > start); end--)
946
 
                ;  /* empty loop */
947
 
 
948
 
              /* get length of the type */
949
 
              len = end-start+1;
950
 
 
951
 
              /* allocate memory of a cloned copy */
952
 
              Curl_safefree(data->info.contenttype);
953
 
 
954
 
              data->info.contenttype = malloc(len + 1);
955
 
              if(NULL == data->info.contenttype)
956
 
                return CURLE_OUT_OF_MEMORY;
957
 
 
958
 
              /* copy the content-type string */
959
 
              memcpy(data->info.contenttype, start, len);
960
 
              data->info.contenttype[len] = 0; /* zero terminate */
961
 
            }
962
 
          }
963
 
#ifndef CURL_DISABLE_HTTP
964
 
          else if((k->httpversion == 10) &&
965
 
                  conn->bits.httpproxy &&
966
 
                  Curl_compareheader(k->p,
967
 
                                     "Proxy-Connection:", "keep-alive")) {
968
 
            /*
969
 
             * When a HTTP/1.0 reply comes when using a proxy, the
970
 
             * 'Proxy-Connection: keep-alive' line tells us the
971
 
             * connection will be kept alive for our pleasure.
972
 
             * Default action for 1.0 is to close.
973
 
             */
974
 
            conn->bits.close = FALSE; /* don't close when done */
975
 
            infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
976
 
          }
977
 
          else if((k->httpversion == 11) &&
978
 
                  conn->bits.httpproxy &&
979
 
                  Curl_compareheader(k->p,
980
 
                                     "Proxy-Connection:", "close")) {
981
 
            /*
982
 
             * We get a HTTP/1.1 response from a proxy and it says it'll
983
 
             * close down after this transfer.
984
 
             */
985
 
            conn->bits.close = TRUE; /* close when done */
986
 
            infof(data, "HTTP/1.1 proxy connection set close!\n");
987
 
          }
988
 
          else if((k->httpversion == 10) &&
989
 
                  Curl_compareheader(k->p, "Connection:", "keep-alive")) {
990
 
            /*
991
 
             * A HTTP/1.0 reply with the 'Connection: keep-alive' line
992
 
             * tells us the connection will be kept alive for our
993
 
             * pleasure.  Default action for 1.0 is to close.
994
 
             *
995
 
             * [RFC2068, section 19.7.1] */
996
 
            conn->bits.close = FALSE; /* don't close when done */
997
 
            infof(data, "HTTP/1.0 connection set to keep alive!\n");
998
 
          }
999
 
          else if(Curl_compareheader(k->p, "Connection:", "close")) {
1000
 
            /*
1001
 
             * [RFC 2616, section 8.1.2.1]
1002
 
             * "Connection: close" is HTTP/1.1 language and means that
1003
 
             * the connection will close when this request has been
1004
 
             * served.
1005
 
             */
1006
 
            conn->bits.close = TRUE; /* close when done */
1007
 
          }
1008
 
          else if(Curl_compareheader(k->p,
1009
 
                                     "Transfer-Encoding:", "chunked")) {
1010
 
            /*
1011
 
             * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
1012
 
             * means that the server will send a series of "chunks". Each
1013
 
             * chunk starts with line with info (including size of the
1014
 
             * coming block) (terminated with CRLF), then a block of data
1015
 
             * with the previously mentioned size. There can be any amount
1016
 
             * of chunks, and a chunk-data set to zero signals the
1017
 
             * end-of-chunks. */
1018
 
            k->chunk = TRUE; /* chunks coming our way */
1019
 
 
1020
 
            /* init our chunky engine */
1021
 
            Curl_httpchunk_init(conn);
1022
 
          }
1023
 
 
1024
 
          else if(checkprefix("Trailer:", k->p) ||
1025
 
                  checkprefix("Trailers:", k->p)) {
1026
 
            /*
1027
 
             * This test helps Curl_httpchunk_read() to determine to look
1028
 
             * for well formed trailers after the zero chunksize record. In
1029
 
             * this case a CRLF is required after the zero chunksize record
1030
 
             * when no trailers are sent, or after the last trailer record.
1031
 
             *
1032
 
             * It seems both Trailer: and Trailers: occur in the wild.
1033
 
             */
1034
 
            k->trailerhdrpresent = TRUE;
1035
 
          }
1036
 
 
1037
 
          else if(checkprefix("Content-Encoding:", k->p) &&
1038
 
                  data->set.str[STRING_ENCODING]) {
1039
 
            /*
1040
 
             * Process Content-Encoding. Look for the values: identity,
1041
 
             * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
1042
 
             * x-compress are the same as gzip and compress. (Sec 3.5 RFC
1043
 
             * 2616). zlib cannot handle compress.  However, errors are
1044
 
             * handled further down when the response body is processed
1045
 
             */
1046
 
            char *start;
1047
 
 
1048
 
            /* Find the first non-space letter */
1049
 
            for(start=k->p+17;
1050
 
                *start && ISSPACE(*start);
1051
 
                start++)
1052
 
              ;  /* empty loop */
1053
 
 
1054
 
            /* Record the content-encoding for later use */
1055
 
            if(checkprefix("identity", start))
1056
 
              k->content_encoding = IDENTITY;
1057
 
            else if(checkprefix("deflate", start))
1058
 
              k->content_encoding = DEFLATE;
1059
 
            else if(checkprefix("gzip", start)
1060
 
                    || checkprefix("x-gzip", start))
1061
 
              k->content_encoding = GZIP;
1062
 
            else if(checkprefix("compress", start)
1063
 
                    || checkprefix("x-compress", start))
1064
 
              k->content_encoding = COMPRESS;
1065
 
          }
1066
 
          else if(checkprefix("Content-Range:", k->p)) {
1067
 
            /* Content-Range: bytes [num]-
1068
 
               Content-Range: bytes: [num]-
1069
 
               Content-Range: [num]-
1070
 
 
1071
 
               The second format was added since Sun's webserver
1072
 
               JavaWebServer/1.1.1 obviously sends the header this way!
1073
 
               The third added since some servers use that!
1074
 
            */
1075
 
 
1076
 
            char *ptr = k->p + 14;
1077
 
 
1078
 
            /* Move forward until first digit */
1079
 
            while(*ptr && !ISDIGIT(*ptr))
1080
 
              ptr++;
1081
 
 
1082
 
            k->offset = curlx_strtoofft(ptr, NULL, 10);
1083
 
 
1084
 
            if(data->state.resume_from == k->offset)
1085
 
              /* we asked for a resume and we got it */
1086
 
              k->content_range = TRUE;
1087
 
          }
1088
 
#if !defined(CURL_DISABLE_COOKIES)
1089
 
          else if(data->cookies &&
1090
 
                  checkprefix("Set-Cookie:", k->p)) {
1091
 
            Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
1092
 
                            CURL_LOCK_ACCESS_SINGLE);
1093
 
            Curl_cookie_add(data,
1094
 
                            data->cookies, TRUE, k->p+11,
1095
 
                            /* If there is a custom-set Host: name, use it
1096
 
                               here, or else use real peer host name. */
1097
 
                            conn->allocptr.cookiehost?
1098
 
                            conn->allocptr.cookiehost:conn->host.name,
1099
 
                            data->state.path);
1100
 
            Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1101
 
          }
1102
 
#endif
1103
 
          else if(checkprefix("Last-Modified:", k->p) &&
1104
 
                  (data->set.timecondition || data->set.get_filetime) ) {
1105
 
            time_t secs=time(NULL);
1106
 
            k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
1107
 
                                        &secs);
1108
 
            if(data->set.get_filetime)
1109
 
              data->info.filetime = (long)k->timeofdoc;
1110
 
          }
1111
 
          else if((checkprefix("WWW-Authenticate:", k->p) &&
1112
 
                   (401 == k->httpcode)) ||
1113
 
                  (checkprefix("Proxy-authenticate:", k->p) &&
1114
 
                   (407 == k->httpcode))) {
1115
 
            result = Curl_http_input_auth(conn, k->httpcode, k->p);
1116
 
            if(result)
1117
 
              return result;
1118
 
          }
1119
 
          else if((k->httpcode >= 300 && k->httpcode < 400) &&
1120
 
                  checkprefix("Location:", k->p)) {
1121
 
            /* this is the URL that the server advices us to use instead */
1122
 
            char *ptr;
1123
 
            char *start=k->p;
1124
 
            char backup;
1125
 
 
1126
 
            start += 9; /* pass "Location:" */
1127
 
 
1128
 
            /* Skip spaces and tabs. We do this to support multiple
1129
 
               white spaces after the "Location:" keyword. */
1130
 
            while(*start && ISSPACE(*start ))
1131
 
              start++;
1132
 
 
1133
 
            /* Scan through the string from the end to find the last
1134
 
               non-space. k->end_ptr points to the actual terminating zero
1135
 
               letter, move pointer one letter back and start from
1136
 
               there. This logic strips off trailing whitespace, but keeps
1137
 
               any embedded whitespace. */
1138
 
            ptr = k->end_ptr-1;
1139
 
            while((ptr>=start) && ISSPACE(*ptr))
1140
 
              ptr--;
1141
 
            ptr++;
1142
 
 
1143
 
            backup = *ptr; /* store the ending letter */
1144
 
            if(ptr != start) {
1145
 
              *ptr = '\0';   /* zero terminate */
1146
 
              data->req.location = strdup(start); /* clone string */
1147
 
              *ptr = backup; /* restore ending letter */
1148
 
              if(!data->req.location)
1149
 
                return CURLE_OUT_OF_MEMORY;
1150
 
              if(data->set.http_follow_location) {
1151
 
                data->req.newurl = strdup(data->req.location); /* clone */
1152
 
                if(!data->req.newurl)
1153
 
                  return CURLE_OUT_OF_MEMORY;
1154
 
              }
1155
 
            }
1156
 
          }
1157
 
#endif   /* CURL_DISABLE_HTTP */
1158
 
 
1159
 
          /*
1160
 
           * End of header-checks. Write them to the client.
1161
 
           */
1162
 
 
1163
 
          writetype = CLIENTWRITE_HEADER;
1164
 
          if(data->set.include_header)
1165
 
            writetype |= CLIENTWRITE_BODY;
1166
 
 
1167
 
          if(data->set.verbose)
1168
 
            Curl_debug(data, CURLINFO_HEADER_IN,
1169
 
                       k->p, (size_t)k->hbuflen, conn);
1170
 
 
1171
 
          result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
1172
 
          if(result)
1173
 
            return result;
1174
 
 
1175
 
          data->info.header_size += (long)k->hbuflen;
1176
 
          data->req.headerbytecount += (long)k->hbuflen;
1177
 
 
1178
 
          /* reset hbufp pointer && hbuflen */
1179
 
          k->hbufp = data->state.headerbuff;
1180
 
          k->hbuflen = 0;
1181
 
        }
1182
 
        while(!stop_reading && *k->str); /* header line within buffer */
1183
 
 
1184
 
        if(stop_reading)
1185
 
          /* We've stopped dealing with input, get out of the do-while loop */
1186
 
          break;
1187
 
 
1188
 
        /* We might have reached the end of the header part here, but
1189
 
           there might be a non-header part left in the end of the read
1190
 
           buffer. */
1191
 
 
1192
 
      }                       /* end if header mode */
1193
 
 
1194
 
      /* This is not an 'else if' since it may be a rest from the header
1195
 
         parsing, where the beginning of the buffer is headers and the end
1196
 
         is non-headers. */
1197
 
      if(k->str && !k->header && (nread > 0 || is_empty_data)) {
1198
 
 
1199
 
        if(0 == k->bodywrites && !is_empty_data) {
1200
 
          /* These checks are only made the first time we are about to
1201
 
             write a piece of the body */
1202
 
          if(conn->protocol&PROT_HTTP) {
1203
 
            /* HTTP-only checks */
1204
 
 
1205
 
            if(data->req.newurl) {
1206
 
              if(conn->bits.close) {
1207
 
                /* Abort after the headers if "follow Location" is set
1208
 
                   and we're set to close anyway. */
1209
 
                k->keepon &= ~KEEP_READ;
1210
 
                *done = TRUE;
1211
 
                return CURLE_OK;
1212
 
              }
1213
 
              /* We have a new url to load, but since we want to be able
1214
 
                 to re-use this connection properly, we read the full
1215
 
                 response in "ignore more" */
1216
 
              k->ignorebody = TRUE;
1217
 
              infof(data, "Ignoring the response-body\n");
1218
 
            }
1219
 
            if(data->state.resume_from && !k->content_range &&
1220
 
               (data->set.httpreq==HTTPREQ_GET) &&
1221
 
               !k->ignorebody) {
1222
 
              /* we wanted to resume a download, although the server doesn't
1223
 
               * seem to support this and we did this with a GET (if it
1224
 
               * wasn't a GET we did a POST or PUT resume) */
1225
 
              failf(data, "HTTP server doesn't seem to support "
1226
 
                    "byte ranges. Cannot resume.");
1227
 
              return CURLE_RANGE_ERROR;
1228
 
            }
1229
 
 
1230
 
            if(data->set.timecondition && !data->state.range) {
1231
 
              /* A time condition has been set AND no ranges have been
1232
 
                 requested. This seems to be what chapter 13.3.4 of
1233
 
                 RFC 2616 defines to be the correct action for a
1234
 
                 HTTP/1.1 client */
1235
 
              if((k->timeofdoc > 0) && (data->set.timevalue > 0)) {
1236
 
                switch(data->set.timecondition) {
1237
 
                case CURL_TIMECOND_IFMODSINCE:
1238
 
                default:
1239
 
                  if(k->timeofdoc < data->set.timevalue) {
1240
 
                    infof(data,
1241
 
                          "The requested document is not new enough\n");
1242
 
                    *done = TRUE;
1243
 
                    return CURLE_OK;
1244
 
                  }
1245
 
                  break;
1246
 
                case CURL_TIMECOND_IFUNMODSINCE:
1247
 
                  if(k->timeofdoc > data->set.timevalue) {
1248
 
                    infof(data,
1249
 
                          "The requested document is not old enough\n");
1250
 
                    *done = TRUE;
1251
 
                    return CURLE_OK;
1252
 
                  }
1253
 
                  break;
1254
 
                } /* switch */
1255
 
              } /* two valid time strings */
1256
 
            } /* we have a time condition */
1257
 
 
1258
 
          } /* this is HTTP */
1259
 
        } /* this is the first time we write a body part */
1260
 
        k->bodywrites++;
1261
 
 
1262
 
        /* pass data to the debug function before it gets "dechunked" */
1263
 
        if(data->set.verbose) {
1264
 
          if(k->badheader) {
1265
 
            Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
1266
 
                       (size_t)k->hbuflen, conn);
1267
 
            if(k->badheader == HEADER_PARTHEADER)
1268
 
              Curl_debug(data, CURLINFO_DATA_IN,
1269
 
                         k->str, (size_t)nread, conn);
1270
 
          }
1271
 
          else
1272
 
            Curl_debug(data, CURLINFO_DATA_IN,
1273
 
                       k->str, (size_t)nread, conn);
1274
 
        }
1275
 
 
1276
 
#ifndef CURL_DISABLE_HTTP
1277
 
        if(k->chunk) {
1278
 
          /*
1279
 
           * Here comes a chunked transfer flying and we need to decode this
1280
 
           * properly.  While the name says read, this function both reads
1281
 
           * and writes away the data. The returned 'nread' holds the number
1282
 
           * of actual data it wrote to the client.
1283
 
           */
1284
 
 
1285
 
          CHUNKcode res =
1286
 
            Curl_httpchunk_read(conn, k->str, nread, &nread);
1287
 
 
1288
 
          if(CHUNKE_OK < res) {
1289
 
            if(CHUNKE_WRITE_ERROR == res) {
1290
 
              failf(data, "Failed writing data");
1291
 
              return CURLE_WRITE_ERROR;
1292
 
            }
1293
 
            failf(data, "Received problem %d in the chunky parser", res);
1294
 
            return CURLE_RECV_ERROR;
1295
 
          }
1296
 
          else if(CHUNKE_STOP == res) {
1297
 
            size_t dataleft;
1298
 
            /* we're done reading chunks! */
1299
 
            k->keepon &= ~KEEP_READ; /* read no more */
1300
 
 
1301
 
            /* There are now possibly N number of bytes at the end of the
1302
 
               str buffer that weren't written to the client.
1303
 
 
1304
 
               We DO care about this data if we are pipelining.
1305
 
               Push it back to be read on the next pass. */
1306
 
 
1307
 
            dataleft = conn->chunk.dataleft;
1308
 
            if(dataleft != 0) {
1309
 
              infof(conn->data, "Leftovers after chunking. "
1310
 
                    " Rewinding %d bytes\n",dataleft);
1311
 
              read_rewind(conn, dataleft);
1312
 
            }
1313
 
          }
1314
 
          /* If it returned OK, we just keep going */
1315
 
        }
1316
 
#endif   /* CURL_DISABLE_HTTP */
1317
 
 
1318
 
        if((-1 != k->maxdownload) &&
1319
 
           (k->bytecount + nread >= k->maxdownload)) {
1320
 
          /* The 'excess' amount below can't be more than BUFSIZE which
1321
 
             always will fit in a size_t */
1322
 
          size_t excess = (size_t)(k->bytecount + nread - k->maxdownload);
1323
 
          if(excess > 0 && !k->ignorebody) {
1324
 
            infof(data,
1325
 
                  "Rewinding stream by : %d"
1326
 
                  " bytes on url %s (size = %" FORMAT_OFF_T
1327
 
                  ", maxdownload = %" FORMAT_OFF_T
1328
 
                  ", bytecount = %" FORMAT_OFF_T ", nread = %d)\n",
1329
 
                  excess, data->state.path,
1330
 
                  k->size, k->maxdownload, k->bytecount, nread);
1331
 
            read_rewind(conn, excess);
1332
 
          }
1333
 
 
1334
 
          nread = (ssize_t) (k->maxdownload - k->bytecount);
1335
 
          if(nread < 0 ) /* this should be unusual */
1336
 
            nread = 0;
1337
 
 
1338
 
          k->keepon &= ~KEEP_READ; /* we're done reading */
1339
 
        }
1340
 
 
1341
 
        k->bytecount += nread;
1342
 
 
1343
 
        Curl_pgrsSetDownloadCounter(data, k->bytecount);
1344
 
 
1345
 
        if(!k->chunk && (nread || k->badheader || is_empty_data)) {
1346
 
          /* If this is chunky transfer, it was already written */
1347
 
 
1348
 
          if(k->badheader && !k->ignorebody) {
1349
 
            /* we parsed a piece of data wrongly assuming it was a header
1350
 
               and now we output it as body instead */
1351
 
            result = Curl_client_write(conn, CLIENTWRITE_BODY,
1352
 
                                       data->state.headerbuff,
1353
 
                                       k->hbuflen);
1354
 
            if(result)
1355
 
              return result;
1356
 
          }
1357
 
          if(k->badheader < HEADER_ALLBAD) {
1358
 
            /* This switch handles various content encodings. If there's an
1359
 
               error here, be sure to check over the almost identical code
1360
 
               in http_chunks.c.
1361
 
               Make sure that ALL_CONTENT_ENCODINGS contains all the
1362
 
               encodings handled here. */
1363
 
#ifdef HAVE_LIBZ
1364
 
            switch (conn->data->set.http_ce_skip ?
1365
 
                    IDENTITY : k->content_encoding) {
1366
 
            case IDENTITY:
1367
 
#endif
1368
 
              /* This is the default when the server sends no
1369
 
                 Content-Encoding header. See Curl_readwrite_init; the
1370
 
                 memset() call initializes k->content_encoding to zero. */
1371
 
              if(!k->ignorebody)
1372
 
                result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
1373
 
                                           nread);
1374
 
#ifdef HAVE_LIBZ
1375
 
              break;
1376
 
 
1377
 
            case DEFLATE:
1378
 
              /* Assume CLIENTWRITE_BODY; headers are not encoded. */
1379
 
              if(!k->ignorebody)
1380
 
                result = Curl_unencode_deflate_write(conn, k, nread);
1381
 
              break;
1382
 
 
1383
 
            case GZIP:
1384
 
              /* Assume CLIENTWRITE_BODY; headers are not encoded. */
1385
 
              if(!k->ignorebody)
1386
 
                result = Curl_unencode_gzip_write(conn, k, nread);
1387
 
              break;
1388
 
 
1389
 
            case COMPRESS:
1390
 
            default:
1391
 
              failf (data, "Unrecognized content encoding type. "
1392
 
                     "libcurl understands `identity', `deflate' and `gzip' "
1393
 
                     "content encodings.");
1394
 
              result = CURLE_BAD_CONTENT_ENCODING;
1395
 
              break;
1396
 
            }
1397
 
#endif
1398
 
          }
1399
 
          k->badheader = HEADER_NORMAL; /* taken care of now */
1400
 
 
1401
 
          if(result)
1402
 
            return result;
1403
 
        }
1404
 
 
1405
 
      } /* if(! header and data to read ) */
1406
 
 
1407
 
      if(is_empty_data) {
1408
 
        /* if we received nothing, the server closed the connection and we
1409
 
           are done */
1410
 
        k->keepon &= ~KEEP_READ;
1411
 
      }
1412
 
 
1413
 
    } while(data_pending(conn));
1414
 
 
1415
 
  } /* if( read from socket ) */
 
1615
 
 
1616
    result = readwrite_data(data, conn, k, &didwhat, done);
 
1617
    if(result || *done)
 
1618
      return result;
 
1619
  }
1416
1620
 
1417
1621
  /* If we still have writing to do, we check if we have a writable socket. */
1418
1622
  if((k->keepon & KEEP_WRITE) && (select_res & CURL_CSELECT_OUT)) {
1419
1623
    /* write */
1420
1624
 
1421
 
    ssize_t i, si;
1422
 
    ssize_t bytes_written;
1423
 
 
1424
 
    if((k->bytecount == 0) && (k->writebytecount == 0))
1425
 
      Curl_pgrsTime(data, TIMER_STARTTRANSFER);
1426
 
 
1427
 
    didwhat |= KEEP_WRITE;
1428
 
 
1429
 
    /*
1430
 
     * We loop here to do the READ and SEND loop until we run out of
1431
 
     * data to send or until we get EWOULDBLOCK back
1432
 
     */
1433
 
    do {
1434
 
 
1435
 
      /* only read more data if there's no upload data already
1436
 
         present in the upload buffer */
1437
 
      if(0 == data->req.upload_present) {
1438
 
        /* init the "upload from here" pointer */
1439
 
        data->req.upload_fromhere = k->uploadbuf;
1440
 
 
1441
 
        if(!k->upload_done) {
1442
 
          /* HTTP pollution, this should be written nicer to become more
1443
 
             protocol agnostic. */
1444
 
          int fillcount;
1445
 
 
1446
 
          if((k->exp100 == EXP100_SENDING_REQUEST) &&
1447
 
             (data->state.proto.http->sending == HTTPSEND_BODY)) {
1448
 
            /* If this call is to send body data, we must take some action:
1449
 
               We have sent off the full HTTP 1.1 request, and we shall now
1450
 
               go into the Expect: 100 state and await such a header */
1451
 
            k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
1452
 
            k->keepon &= ~KEEP_WRITE;         /* disable writing */
1453
 
            k->start100 = Curl_tvnow();       /* timeout count starts now */
1454
 
            didwhat &= ~KEEP_WRITE;  /* we didn't write anything actually */
1455
 
            break;
1456
 
          }
1457
 
 
1458
 
          result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
1459
 
          if(result)
1460
 
            return result;
1461
 
 
1462
 
          nread = (ssize_t)fillcount;
1463
 
        }
1464
 
        else
1465
 
          nread = 0; /* we're done uploading/reading */
1466
 
 
1467
 
        if(!nread && (k->keepon & KEEP_READ_PAUSE)) {
1468
 
          /* this is a paused transfer */
1469
 
          break;
1470
 
        }
1471
 
        else if(nread<=0) {
1472
 
          /* done */
1473
 
          k->keepon &= ~KEEP_WRITE; /* we're done writing */
1474
 
 
1475
 
          if(conn->bits.rewindaftersend) {
1476
 
            result = Curl_readrewind(conn);
1477
 
            if(result)
1478
 
              return result;
1479
 
          }
1480
 
          break;
1481
 
        }
1482
 
 
1483
 
        /* store number of bytes available for upload */
1484
 
        data->req.upload_present = nread;
1485
 
 
1486
 
        /* convert LF to CRLF if so asked */
1487
 
#ifdef CURL_DO_LINEEND_CONV
1488
 
        /* always convert if we're FTPing in ASCII mode */
1489
 
        if((data->set.crlf) || (data->set.prefer_ascii))
1490
 
#else
1491
 
          if(data->set.crlf)
1492
 
#endif /* CURL_DO_LINEEND_CONV */
1493
 
          {
1494
 
            if(data->state.scratch == NULL)
1495
 
              data->state.scratch = malloc(2*BUFSIZE);
1496
 
            if(data->state.scratch == NULL) {
1497
 
              failf (data, "Failed to alloc scratch buffer!");
1498
 
              return CURLE_OUT_OF_MEMORY;
1499
 
            }
1500
 
            /*
1501
 
             * ASCII/EBCDIC Note: This is presumably a text (not binary)
1502
 
             * transfer so the data should already be in ASCII.
1503
 
             * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
1504
 
             * must be used instead of the escape sequences \r & \n.
1505
 
             */
1506
 
            for(i = 0, si = 0; i < nread; i++, si++) {
1507
 
              if(data->req.upload_fromhere[i] == 0x0a) {
1508
 
                data->state.scratch[si++] = 0x0d;
1509
 
                data->state.scratch[si] = 0x0a;
1510
 
                if(!data->set.crlf) {
1511
 
                  /* we're here only because FTP is in ASCII mode...
1512
 
                     bump infilesize for the LF we just added */
1513
 
                  data->set.infilesize++;
1514
 
                }
1515
 
              }
1516
 
              else
1517
 
                data->state.scratch[si] = data->req.upload_fromhere[i];
1518
 
            }
1519
 
            if(si != nread) {
1520
 
              /* only perform the special operation if we really did replace
1521
 
                 anything */
1522
 
              nread = si;
1523
 
 
1524
 
              /* upload from the new (replaced) buffer instead */
1525
 
              data->req.upload_fromhere = data->state.scratch;
1526
 
 
1527
 
              /* set the new amount too */
1528
 
              data->req.upload_present = nread;
1529
 
            }
1530
 
          }
1531
 
      } /* if 0 == data->req.upload_present */
1532
 
      else {
1533
 
        /* We have a partial buffer left from a previous "round". Use
1534
 
           that instead of reading more data */
1535
 
      }
1536
 
 
1537
 
      /* write to socket (send away data) */
1538
 
      result = Curl_write(conn,
1539
 
                          conn->writesockfd,     /* socket to send to */
1540
 
                          data->req.upload_fromhere, /* buffer pointer */
1541
 
                          data->req.upload_present,  /* buffer size */
1542
 
                          &bytes_written);       /* actually send away */
1543
 
      if(result)
1544
 
        return result;
1545
 
 
1546
 
      if(data->set.verbose)
1547
 
        /* show the data before we change the pointer upload_fromhere */
1548
 
        Curl_debug(data, CURLINFO_DATA_OUT, data->req.upload_fromhere,
1549
 
                   (size_t)bytes_written, conn);
1550
 
 
1551
 
      if(data->req.upload_present != bytes_written) {
1552
 
        /* we only wrote a part of the buffer (if anything), deal with it! */
1553
 
 
1554
 
        /* store the amount of bytes left in the buffer to write */
1555
 
        data->req.upload_present -= bytes_written;
1556
 
 
1557
 
        /* advance the pointer where to find the buffer when the next send
1558
 
           is to happen */
1559
 
        data->req.upload_fromhere += bytes_written;
1560
 
      }
1561
 
      else {
1562
 
        /* we've uploaded that buffer now */
1563
 
        data->req.upload_fromhere = k->uploadbuf;
1564
 
        data->req.upload_present = 0; /* no more bytes left */
1565
 
 
1566
 
        if(k->upload_done) {
1567
 
          /* switch off writing, we're done! */
1568
 
          k->keepon &= ~KEEP_WRITE; /* we're done writing */
1569
 
        }
1570
 
      }
1571
 
 
1572
 
      k->writebytecount += bytes_written;
1573
 
      Curl_pgrsSetUploadCounter(data, k->writebytecount);
1574
 
 
1575
 
    } while(0); /* just to break out from! */
1576
 
 
1577
 
  } /* if(something to write) */
 
1625
    result = readwrite_upload(data, conn, k, &didwhat);
 
1626
    if(result)
 
1627
      return result;
 
1628
  }
1578
1629
 
1579
1630
  k->now = Curl_tvnow();
1580
1631
  if(didwhat) {
1605
1656
        /* we've waited long enough, continue anyway */
1606
1657
        k->exp100 = EXP100_SEND_DATA;
1607
1658
        k->keepon |= KEEP_WRITE;
 
1659
        infof(data, "Done waiting for 100-continue\n");
1608
1660
      }
1609
1661
    }
1610
1662
  }
1693
1745
  int bitmap = GETSOCK_BLANK;
1694
1746
  unsigned sockindex = 0;
1695
1747
 
 
1748
  if(conn->handler->perform_getsock)
 
1749
    return conn->handler->perform_getsock(conn, sock, numsocks);
 
1750
 
1696
1751
  if(numsocks < 2)
1697
1752
    /* simple check but we might need two slots */
1698
1753
    return GETSOCK_BLANK;
1749
1804
  struct SessionHandle *data = conn->data;
1750
1805
  struct SingleRequest *k = &data->req;
1751
1806
  bool done=FALSE;
 
1807
  bool first=TRUE;
 
1808
  int timeout_ms;
1752
1809
 
1753
1810
  if((conn->sockfd == CURL_SOCKET_BAD) &&
1754
1811
     (conn->writesockfd == CURL_SOCKET_BAD))
1800
1857
       be no traffic during the select interval, we still call
1801
1858
       Curl_readwrite() for the timeout case and if we limit transfer speed we
1802
1859
       must make sure that this function doesn't transfer anything while in
1803
 
       HOLD status. */
1804
 
 
1805
 
    switch (Curl_socket_ready(fd_read, fd_write, 1000)) {
 
1860
       HOLD status.
 
1861
 
 
1862
       The no timeout for the first round is for the protocols for which data
 
1863
       has already been slurped off the socket and thus waiting for action
 
1864
       won't work since it'll wait even though there is already data present
 
1865
       to work with. */
 
1866
    if(first &&
 
1867
       ((fd_read != CURL_SOCKET_BAD) || (fd_write != CURL_SOCKET_BAD)))
 
1868
      /* if this is the first lap and one of the file descriptors is fine
 
1869
         to work with, skip the timeout */
 
1870
      timeout_ms = 0;
 
1871
    else
 
1872
      timeout_ms = 1000;
 
1873
 
 
1874
    switch (Curl_socket_ready(fd_read, fd_write, timeout_ms)) {
1806
1875
    case -1: /* select() error, stop reading */
1807
1876
#ifdef EINTR
1808
1877
      /* The EINTR is not serious, and it seems you might get this more
1809
 
         ofen when using the lib in a multi-threaded environment! */
 
1878
         often when using the lib in a multi-threaded environment! */
1810
1879
      if(SOCKERRNO == EINTR)
1811
 
        ;
1812
 
      else
 
1880
        continue;
1813
1881
#endif
1814
 
        done = TRUE; /* no more read or write */
1815
 
      continue;
 
1882
      return CURLE_RECV_ERROR;  /* indicate a network problem */
1816
1883
    case 0:  /* timeout */
1817
1884
    default: /* readable descriptors */
1818
1885
 
1819
1886
      result = Curl_readwrite(conn, &done);
 
1887
      /* "done" signals to us if the transfer(s) are ready */
1820
1888
      break;
1821
1889
    }
1822
1890
    if(result)
1823
1891
      return result;
1824
1892
 
1825
 
    /* "done" signals to us if the transfer(s) are ready */
 
1893
    first = FALSE; /* not the first lap anymore */
1826
1894
  }
1827
1895
 
1828
1896
  return CURLE_OK;
1835
1903
{
1836
1904
  CURLcode res;
1837
1905
  if(!data->change.url) {
1838
 
    /* we can't do anything wihout URL */
 
1906
    /* we can't do anything without URL */
1839
1907
    failf(data, "No URL set!");
1840
1908
    return CURLE_URL_MALFORMAT;
1841
1909
  }
1850
1918
  data->set.followlocation=0; /* reset the location-follow counter */
1851
1919
  data->state.this_is_a_follow = FALSE; /* reset this */
1852
1920
  data->state.errorbuf = FALSE; /* no error has occurred */
 
1921
  data->state.httpversion = 0; /* don't assume any particular server version */
1853
1922
 
1854
1923
  data->state.authproblem = FALSE;
1855
1924
  data->state.authhost.want = data->set.httpauth;
1856
1925
  data->state.authproxy.want = data->set.proxyauth;
 
1926
  Curl_safefree(data->info.wouldredirect);
 
1927
  data->info.wouldredirect = NULL;
1857
1928
 
1858
1929
  /* If there is a list of cookie files to read, do it now! */
1859
1930
  if(data->change.cookielist) {
1900
1971
  return CURLE_OK;
1901
1972
}
1902
1973
 
 
1974
#ifndef CURL_DISABLE_HTTP
1903
1975
/*
1904
1976
 * strlen_url() returns the length of the given URL if the spaces within the
1905
1977
 * URL were properly URL encoded.
1964
2036
}
1965
2037
 
1966
2038
/*
 
2039
 * Returns true if the given URL is absolute (as opposed to relative)
 
2040
 */
 
2041
static bool is_absolute_url(const char *url)
 
2042
{
 
2043
  char prot[16]; /* URL protocol string storage */
 
2044
  char letter;   /* used for a silly sscanf */
 
2045
 
 
2046
  return (bool)(2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter));
 
2047
}
 
2048
 
 
2049
/*
 
2050
 * Concatenate a relative URL to a base URL making it absolute.
 
2051
 * URL-encodes any spaces.
 
2052
 * The returned pointer must be freed by the caller unless NULL
 
2053
 * (returns NULL on out of memory).
 
2054
 */
 
2055
static char *concat_url(const char *base, const char *relurl)
 
2056
{
 
2057
  /***
 
2058
   TRY to append this new path to the old URL
 
2059
   to the right of the host part. Oh crap, this is doomed to cause
 
2060
   problems in the future...
 
2061
  */
 
2062
  char *newest;
 
2063
  char *protsep;
 
2064
  char *pathsep;
 
2065
  size_t newlen;
 
2066
 
 
2067
  const char *useurl = relurl;
 
2068
  size_t urllen;
 
2069
 
 
2070
  /* we must make our own copy of the URL to play with, as it may
 
2071
     point to read-only data */
 
2072
  char *url_clone=strdup(base);
 
2073
 
 
2074
  if(!url_clone)
 
2075
    return NULL; /* skip out of this NOW */
 
2076
 
 
2077
  /* protsep points to the start of the host name */
 
2078
  protsep=strstr(url_clone, "//");
 
2079
  if(!protsep)
 
2080
    protsep=url_clone;
 
2081
  else
 
2082
    protsep+=2; /* pass the slashes */
 
2083
 
 
2084
  if('/' != relurl[0]) {
 
2085
    int level=0;
 
2086
 
 
2087
    /* First we need to find out if there's a ?-letter in the URL,
 
2088
       and cut it and the right-side of that off */
 
2089
    pathsep = strchr(protsep, '?');
 
2090
    if(pathsep)
 
2091
      *pathsep=0;
 
2092
 
 
2093
    /* we have a relative path to append to the last slash if there's one
 
2094
       available, or if the new URL is just a query string (starts with a
 
2095
       '?')  we append the new one at the end of the entire currently worked
 
2096
       out URL */
 
2097
    if(useurl[0] != '?') {
 
2098
      pathsep = strrchr(protsep, '/');
 
2099
      if(pathsep)
 
2100
        *pathsep=0;
 
2101
    }
 
2102
 
 
2103
    /* Check if there's any slash after the host name, and if so, remember
 
2104
       that position instead */
 
2105
    pathsep = strchr(protsep, '/');
 
2106
    if(pathsep)
 
2107
      protsep = pathsep+1;
 
2108
    else
 
2109
      protsep = NULL;
 
2110
 
 
2111
    /* now deal with one "./" or any amount of "../" in the newurl
 
2112
       and act accordingly */
 
2113
 
 
2114
    if((useurl[0] == '.') && (useurl[1] == '/'))
 
2115
      useurl+=2; /* just skip the "./" */
 
2116
 
 
2117
    while((useurl[0] == '.') &&
 
2118
          (useurl[1] == '.') &&
 
2119
          (useurl[2] == '/')) {
 
2120
      level++;
 
2121
      useurl+=3; /* pass the "../" */
 
2122
    }
 
2123
 
 
2124
    if(protsep) {
 
2125
      while(level--) {
 
2126
        /* cut off one more level from the right of the original URL */
 
2127
        pathsep = strrchr(protsep, '/');
 
2128
        if(pathsep)
 
2129
          *pathsep=0;
 
2130
        else {
 
2131
          *protsep=0;
 
2132
          break;
 
2133
        }
 
2134
      }
 
2135
    }
 
2136
  }
 
2137
  else {
 
2138
    /* We got a new absolute path for this server, cut off from the
 
2139
       first slash */
 
2140
    pathsep = strchr(protsep, '/');
 
2141
    if(pathsep) {
 
2142
      /* When people use badly formatted URLs, such as
 
2143
         "http://www.url.com?dir=/home/daniel" we must not use the first
 
2144
         slash, if there's a ?-letter before it! */
 
2145
      char *sep = strchr(protsep, '?');
 
2146
      if(sep && (sep < pathsep))
 
2147
        pathsep = sep;
 
2148
      *pathsep=0;
 
2149
    }
 
2150
    else {
 
2151
      /* There was no slash. Now, since we might be operating on a badly
 
2152
         formatted URL, such as "http://www.url.com?id=2380" which doesn't
 
2153
         use a slash separator as it is supposed to, we need to check for a
 
2154
         ?-letter as well! */
 
2155
      pathsep = strchr(protsep, '?');
 
2156
      if(pathsep)
 
2157
        *pathsep=0;
 
2158
    }
 
2159
  }
 
2160
 
 
2161
  /* If the new part contains a space, this is a mighty stupid redirect
 
2162
     but we still make an effort to do "right". To the left of a '?'
 
2163
     letter we replace each space with %20 while it is replaced with '+'
 
2164
     on the right side of the '?' letter.
 
2165
  */
 
2166
  newlen = strlen_url(useurl);
 
2167
 
 
2168
  urllen = strlen(url_clone);
 
2169
 
 
2170
  newest = malloc( urllen + 1 + /* possible slash */
 
2171
                         newlen + 1 /* zero byte */);
 
2172
 
 
2173
  if(!newest) {
 
2174
    free(url_clone); /* don't leak this */
 
2175
    return NULL;
 
2176
  }
 
2177
 
 
2178
  /* copy over the root url part */
 
2179
  memcpy(newest, url_clone, urllen);
 
2180
 
 
2181
  /* check if we need to append a slash */
 
2182
  if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
 
2183
    ;
 
2184
  else
 
2185
    newest[urllen++]='/';
 
2186
 
 
2187
  /* then append the new piece on the right side */
 
2188
  strcpy_url(&newest[urllen], useurl);
 
2189
 
 
2190
  free(url_clone);
 
2191
 
 
2192
  return newest;
 
2193
}
 
2194
#endif /* CURL_DISABLE_HTTP */
 
2195
 
 
2196
/*
1967
2197
 * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
1968
2198
 * as given by the remote server and set up the new URL to request.
1969
2199
 */
1973
2203
                                      here */
1974
2204
                     followtype type) /* see transfer.h */
1975
2205
{
 
2206
#ifdef CURL_DISABLE_HTTP
 
2207
  (void)data;
 
2208
  (void)newurl;
 
2209
  (void)type;
 
2210
  /* Location: following will not happen when HTTP is disabled */
 
2211
  return CURLE_TOO_MANY_REDIRECTS;
 
2212
#else
 
2213
 
1976
2214
  /* Location: redirect */
1977
 
  char prot[16]; /* URL protocol string storage */
1978
 
  char letter;   /* used for a silly sscanf */
1979
 
  size_t newlen;
1980
 
  char *newest;
1981
2215
  bool disallowport = FALSE;
1982
2216
 
1983
2217
  if(type == FOLLOW_REDIR) {
2002
2236
        free(data->change.referer);
2003
2237
 
2004
2238
      data->change.referer = strdup(data->change.url);
 
2239
      if (!data->change.referer) {
 
2240
        data->change.referer_alloc = FALSE;
 
2241
        return CURLE_OUT_OF_MEMORY;
 
2242
      }
2005
2243
      data->change.referer_alloc = TRUE; /* yes, free this later */
2006
2244
    }
2007
2245
  }
2008
2246
 
2009
 
  if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) {
 
2247
  if(!is_absolute_url(newurl))  {
2010
2248
    /***
2011
2249
     *DANG* this is an RFC 2068 violation. The URL is supposed
2012
2250
     to be absolute and this doesn't seem to be that!
2013
 
     ***
2014
 
     Instead, we have to TRY to append this new path to the old URL
2015
 
     to the right of the host part. Oh crap, this is doomed to cause
2016
 
     problems in the future...
2017
 
    */
2018
 
    char *protsep;
2019
 
    char *pathsep;
2020
 
 
2021
 
    char *useurl = newurl;
2022
 
    size_t urllen;
2023
 
 
2024
 
    /* we must make our own copy of the URL to play with, as it may
2025
 
       point to read-only data */
2026
 
    char *url_clone=strdup(data->change.url);
2027
 
 
2028
 
    if(!url_clone)
2029
 
      return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */
2030
 
 
2031
 
    /* protsep points to the start of the host name */
2032
 
    protsep=strstr(url_clone, "//");
2033
 
    if(!protsep)
2034
 
      protsep=url_clone;
2035
 
    else
2036
 
      protsep+=2; /* pass the slashes */
2037
 
 
2038
 
    if('/' != newurl[0]) {
2039
 
      int level=0;
2040
 
 
2041
 
      /* First we need to find out if there's a ?-letter in the URL,
2042
 
         and cut it and the right-side of that off */
2043
 
      pathsep = strchr(protsep, '?');
2044
 
      if(pathsep)
2045
 
        *pathsep=0;
2046
 
 
2047
 
      /* we have a relative path to append to the last slash if there's one
2048
 
         available, or if the new URL is just a query string (starts with a
2049
 
         '?')  we append the new one at the end of the entire currently worked
2050
 
         out URL */
2051
 
      if(useurl[0] != '?') {
2052
 
        pathsep = strrchr(protsep, '/');
2053
 
        if(pathsep)
2054
 
          *pathsep=0;
2055
 
      }
2056
 
 
2057
 
      /* Check if there's any slash after the host name, and if so, remember
2058
 
         that position instead */
2059
 
      pathsep = strchr(protsep, '/');
2060
 
      if(pathsep)
2061
 
        protsep = pathsep+1;
2062
 
      else
2063
 
        protsep = NULL;
2064
 
 
2065
 
      /* now deal with one "./" or any amount of "../" in the newurl
2066
 
         and act accordingly */
2067
 
 
2068
 
      if((useurl[0] == '.') && (useurl[1] == '/'))
2069
 
        useurl+=2; /* just skip the "./" */
2070
 
 
2071
 
      while((useurl[0] == '.') &&
2072
 
            (useurl[1] == '.') &&
2073
 
            (useurl[2] == '/')) {
2074
 
        level++;
2075
 
        useurl+=3; /* pass the "../" */
2076
 
      }
2077
 
 
2078
 
      if(protsep) {
2079
 
        while(level--) {
2080
 
          /* cut off one more level from the right of the original URL */
2081
 
          pathsep = strrchr(protsep, '/');
2082
 
          if(pathsep)
2083
 
            *pathsep=0;
2084
 
          else {
2085
 
            *protsep=0;
2086
 
            break;
2087
 
          }
2088
 
        }
2089
 
      }
2090
 
    }
2091
 
    else {
2092
 
      /* We got a new absolute path for this server, cut off from the
2093
 
         first slash */
2094
 
      pathsep = strchr(protsep, '/');
2095
 
      if(pathsep) {
2096
 
        /* When people use badly formatted URLs, such as
2097
 
           "http://www.url.com?dir=/home/daniel" we must not use the first
2098
 
           slash, if there's a ?-letter before it! */
2099
 
        char *sep = strchr(protsep, '?');
2100
 
        if(sep && (sep < pathsep))
2101
 
          pathsep = sep;
2102
 
        *pathsep=0;
2103
 
      }
2104
 
      else {
2105
 
        /* There was no slash. Now, since we might be operating on a badly
2106
 
           formatted URL, such as "http://www.url.com?id=2380" which doesn't
2107
 
           use a slash separator as it is supposed to, we need to check for a
2108
 
           ?-letter as well! */
2109
 
        pathsep = strchr(protsep, '?');
2110
 
        if(pathsep)
2111
 
          *pathsep=0;
2112
 
      }
2113
 
    }
2114
 
 
2115
 
    /* If the new part contains a space, this is a mighty stupid redirect
2116
 
       but we still make an effort to do "right". To the left of a '?'
2117
 
       letter we replace each space with %20 while it is replaced with '+'
2118
 
       on the right side of the '?' letter.
2119
 
    */
2120
 
    newlen = strlen_url(useurl);
2121
 
 
2122
 
    urllen = strlen(url_clone);
2123
 
 
2124
 
    newest=(char *)malloc( urllen + 1 + /* possible slash */
2125
 
                           newlen + 1 /* zero byte */);
2126
 
 
2127
 
    if(!newest) {
2128
 
      free(url_clone); /* don't leak this */
2129
 
      return CURLE_OUT_OF_MEMORY; /* go out from this */
2130
 
    }
2131
 
 
2132
 
    /* copy over the root url part */
2133
 
    memcpy(newest, url_clone, urllen);
2134
 
 
2135
 
    /* check if we need to append a slash */
2136
 
    if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
2137
 
      ;
2138
 
    else
2139
 
      newest[urllen++]='/';
2140
 
 
2141
 
    /* then append the new piece on the right side */
2142
 
    strcpy_url(&newest[urllen], useurl);
2143
 
 
2144
 
    free(newurl); /* newurl is the allocated pointer */
2145
 
    free(url_clone);
2146
 
    newurl = newest;
 
2251
     */
 
2252
    char *absolute = concat_url(data->change.url, newurl);
 
2253
    if (!absolute)
 
2254
      return CURLE_OUT_OF_MEMORY;
 
2255
    free(newurl);
 
2256
    newurl = absolute;
2147
2257
  }
2148
2258
  else {
2149
2259
    /* This is an absolute URL, don't allow the custom port number */
2152
2262
    if(strchr(newurl, ' ')) {
2153
2263
      /* This new URL contains at least one space, this is a mighty stupid
2154
2264
         redirect but we still make an effort to do "right". */
2155
 
      newlen = strlen_url(newurl);
 
2265
      char *newest;
 
2266
      size_t newlen = strlen_url(newurl);
2156
2267
 
2157
2268
      newest = malloc(newlen+1); /* get memory for this */
2158
 
      if(newest) {
2159
 
        strcpy_url(newest, newurl); /* create a space-free URL */
 
2269
      if (!newest)
 
2270
        return CURLE_OUT_OF_MEMORY;
 
2271
      strcpy_url(newest, newurl); /* create a space-free URL */
2160
2272
 
2161
 
        free(newurl); /* that was no good */
2162
 
        newurl = newest; /* use this instead now */
2163
 
      }
 
2273
      free(newurl); /* that was no good */
 
2274
      newurl = newest; /* use this instead now */
2164
2275
    }
2165
2276
 
2166
2277
  }
2220
2331
     * libcurl gets the page that most user agents would get, libcurl has to
2221
2332
     * force GET.
2222
2333
     *
2223
 
     * This behaviour can be overriden with CURLOPT_POST301.
 
2334
     * This behaviour can be overridden with CURLOPT_POSTREDIR.
2224
2335
     */
2225
2336
    if( (data->set.httpreq == HTTPREQ_POST
2226
2337
         || data->set.httpreq == HTTPREQ_POST_FORM)
2247
2358
    status. When interoperability with such clients is a concern, the
2248
2359
    302 status code may be used instead, since most user agents react
2249
2360
    to a 302 response as described here for 303.
 
2361
 
 
2362
    This behaviour can be overriden with CURLOPT_POSTREDIR
2250
2363
    */
 
2364
    if( (data->set.httpreq == HTTPREQ_POST
 
2365
         || data->set.httpreq == HTTPREQ_POST_FORM)
 
2366
        && !data->set.post302) {
 
2367
      infof(data,
 
2368
            "Violate RFC 2616/10.3.3 and switch from POST to GET\n");
 
2369
      data->set.httpreq = HTTPREQ_GET;
 
2370
    }
 
2371
    break;
 
2372
 
2251
2373
  case 303: /* See Other */
2252
2374
    /* Disable both types of POSTs, since doing a second POST when
2253
2375
     * following isn't what anyone would want! */
2276
2398
  Curl_pgrsResetTimes(data);
2277
2399
 
2278
2400
  return CURLE_OK;
 
2401
#endif /* CURL_DISABLE_HTTP */
2279
2402
}
2280
2403
 
2281
2404
static CURLcode
2383
2506
 
2384
2507
      if(res == CURLE_OK) {
2385
2508
        res = Transfer(conn); /* now fetch that URL please */
2386
 
        if(res == CURLE_OK) {
 
2509
        if((res == CURLE_OK) || (res == CURLE_RECV_ERROR)) {
2387
2510
          bool retry = Curl_retry_request(conn, &newurl);
2388
2511
 
2389
 
          if(retry)
 
2512
          if(retry) {
 
2513
            res = CURLE_OK;
2390
2514
            follow = FOLLOW_RETRY;
2391
 
          else {
 
2515
            if (!newurl)
 
2516
              res = CURLE_OUT_OF_MEMORY;
 
2517
          }
 
2518
          else if (res == CURLE_OK) {
2392
2519
            /*
2393
2520
             * We must duplicate the new URL here as the connection data may
2394
2521
             * be free()ed in the Curl_done() function. We prefer the newurl
2398
2525
            if(data->req.newurl) {
2399
2526
              follow = FOLLOW_REDIR;
2400
2527
              newurl = strdup(data->req.newurl);
 
2528
              if (!newurl)
 
2529
                res = CURLE_OUT_OF_MEMORY;
2401
2530
            }
2402
2531
            else if(data->req.location) {
2403
2532
              follow = FOLLOW_FAKE;
2404
2533
              newurl = strdup(data->req.location);
 
2534
              if (!newurl)
 
2535
                res = CURLE_OUT_OF_MEMORY;
2405
2536
            }
2406
2537
          }
2407
2538
 
2408
2539
          /* in the above cases where 'newurl' gets assigned, we have a fresh
2409
2540
           * allocated memory pointed to */
2410
2541
        }
2411
 
        else {
 
2542
        if(res != CURLE_OK) {
2412
2543
          /* The transfer phase returned error, we mark the connection to get
2413
 
           * closed to prevent being re-used. This is becasue we can't
 
2544
           * closed to prevent being re-used. This is because we can't
2414
2545
           * possibly know if the connection is in a good shape or not now. */
2415
2546
          conn->bits.close = TRUE;
2416
2547
 
2476
2607
      failf(data, "%s", str);
2477
2608
  }
2478
2609
 
2479
 
  /* run post-transfer uncondionally, but don't clobber the return code if
 
2610
  /* run post-transfer unconditionally, but don't clobber the return code if
2480
2611
     we already have an error code recorder */
2481
2612
  res2 = Curl_posttransfer(data);
2482
2613
  if(!res && res2)