1
/***************************************************************************
3
* Project ___| | | | _ \| |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at http://curl.haxx.se/docs/copyright.html.
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
21
* $Id: transfer.c,v 1.9 2004/10/13 14:45:30 andy Exp $
22
***************************************************************************/
26
/* -- WIN32 approved -- */
32
#ifdef HAVE_SYS_TYPES_H
33
#include <sys/types.h>
39
#include "strtoofft.h"
42
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
46
#ifdef HAVE_SYS_SOCKET_H
47
#include <sys/socket.h>
49
#ifdef HAVE_NETINET_IN_H
50
#include <netinet/in.h>
57
#ifdef HAVE_ARPA_INET_H
58
#include <arpa/inet.h>
63
#ifdef HAVE_SYS_IOCTL_H
64
#include <sys/ioctl.h>
68
#ifdef HAVE_SYS_PARAM_H
69
#include <sys/param.h>
72
#ifdef HAVE_SYS_SELECT_H
73
#include <sys/select.h>
77
#error "We can't compile without select() support!"
80
#error "We can't compile without socket() support!"
86
#include <curl/curl.h>
89
#include "content_encoding.h"
93
#include "speedcheck.h"
100
#include "http_digest.h"
101
#include "http_ntlm.h"
102
#include "http_negotiate.h"
104
#include "curl_memory.h"
106
#define _MPRINTF_REPLACE /* use our functions only */
107
#include <curl/mprintf.h>
109
/* The last #include file should be: */
110
#include "memdebug.h"
112
#define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */
120
/* We keep this static and global since this is read-only and NEVER
121
changed. It should just remain a blanked-out timeout value. */
122
static struct timeval notimeout={0,0};
125
* This function will call the read callback to fill our buffer with data
128
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
130
struct SessionHandle *data = conn->data;
131
size_t buffersize = (size_t)bytes;
134
if(conn->bits.upload_chunky) {
135
/* if chunked Transfer-Encoding */
136
buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */
137
conn->upload_fromhere += 10; /* 32bit hex + CRLF */
140
/* this function returns a size_t, so we typecast to int to prevent warnings
141
with picky compilers */
142
nread = (int)conn->fread(conn->upload_fromhere, 1,
143
buffersize, conn->fread_in);
145
if(nread == CURL_READFUNC_ABORT) {
146
failf(data, "operation aborted by callback\n");
147
return CURLE_ABORTED_BY_CALLBACK;
150
if(!conn->bits.forbidchunk && conn->bits.upload_chunky) {
151
/* if chunked Transfer-Encoding */
153
int hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
155
/* move buffer pointer */
156
conn->upload_fromhere -= hexlen;
159
/* copy the prefix to the buffer */
160
memcpy(conn->upload_fromhere, hexbuffer, hexlen);
162
/* always append CRLF to the data */
163
memcpy(conn->upload_fromhere + nread, "\r\n", 2);
165
if((nread - hexlen) == 0) {
166
/* mark this as done once this chunk is transfered */
167
conn->keep.upload_done = TRUE;
170
nread+=2; /* for the added CRLF */
181
* Returns TRUE if member of the list matches prefix of string
184
checkhttpprefix(struct SessionHandle *data,
187
struct curl_slist *head = data->set.http200aliases;
190
if (checkprefix(head->data, s))
195
if(checkprefix("HTTP/", s))
203
* Curl_readwrite() is the low-level function to be called when data is to
204
* be read and written to/from the connection.
206
CURLcode Curl_readwrite(struct connectdata *conn,
209
struct Curl_transfer_keeper *k = &conn->keep;
210
struct SessionHandle *data = conn->data;
212
ssize_t nread; /* number of bytes read */
215
/* These two are used only if no other select() or _fdset() have been
216
invoked before this. This typicly happens if you use the multi interface
217
and call curl_multi_perform() without calling curl_multi_fdset()
222
fd_set *readfdp = k->readfdp;
223
fd_set *writefdp = k->writefdp;
224
curl_off_t contentlength;
226
if((k->keepon & KEEP_READ) && !readfdp) {
227
/* reading is requested, but no socket descriptor pointer was set */
228
FD_ZERO(&extrareadfd);
229
FD_SET(conn->sockfd, &extrareadfd);
230
readfdp = &extrareadfd;
232
/* no write, no exceptions, no timeout */
233
select(conn->sockfd+1, readfdp, NULL, NULL, ¬imeout);
235
if((k->keepon & KEEP_WRITE) && !writefdp) {
236
/* writing is requested, but no socket descriptor pointer was set */
237
FD_ZERO(&extrawritefd);
238
FD_SET(conn->writesockfd, &extrawritefd);
239
writefdp = &extrawritefd;
241
/* no read, no exceptions, no timeout */
242
select(conn->writesockfd+1, NULL, writefdp, NULL, ¬imeout);
246
/* If we still have reading to do, we check if we have a readable
247
socket. Sometimes the reafdp is NULL, if no fd_set was done using
248
the multi interface and then we can do nothing but to attempt a
250
if((k->keepon & KEEP_READ) &&
251
(!readfdp || FD_ISSET(conn->sockfd, readfdp))) {
253
bool readdone = TRUE;
255
/* This is where we loop until we have read everything there is to
256
read or we get a EWOULDBLOCK */
258
size_t buffersize = data->set.buffer_size?
259
data->set.buffer_size:BUFSIZE -1;
261
/* receive data from the network! */
262
int readrc = Curl_read(conn, conn->sockfd, k->buf, buffersize, &nread);
264
/* subzero, this would've blocked */
266
break; /* get out of loop */
268
/* get the CURLcode from the int */
269
result = (CURLcode)readrc;
274
if ((k->bytecount == 0) && (k->writebytecount == 0)) {
275
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
276
if(k->wait100_after_headers)
277
/* set time stamp to compare with when waiting for the 100 */
278
k->start100 = Curl_tvnow();
281
didwhat |= KEEP_READ;
283
/* NULL terminate, allowing string ops to be used */
287
/* if we receive 0 or less here, the server closed the connection and
288
we bail out from this! */
289
else if (0 >= nread) {
290
k->keepon &= ~KEEP_READ;
291
FD_ZERO(&k->rkeepfd);
296
/* Default buffer to use when we write the buffer, it may be changed
297
in the flow below before the actual storing is done. */
300
/* Since this is a two-state thing, we check if we are parsing
301
headers at the moment or not. */
303
/* we are in parse-the-header-mode */
304
bool stop_reading = FALSE;
306
/* header line within buffer loop */
313
/* str_start is start of line within buf */
314
k->str_start = k->str;
316
k->end_ptr = strchr (k->str_start, '\n');
319
/* Not a complete header line within buffer, append the data to
320
the end of the headerbuff. */
322
if (k->hbuflen + nread >= data->state.headersize) {
323
/* We enlarge the header buffer as it is too small */
325
size_t newsize=CURLMAX((k->hbuflen+nread)*3/2,
326
data->state.headersize*2);
327
hbufp_index = k->hbufp - data->state.headerbuff;
328
newbuff = (char *)realloc(data->state.headerbuff, newsize);
330
failf (data, "Failed to alloc memory for big header!");
331
return CURLE_OUT_OF_MEMORY;
333
data->state.headersize=newsize;
334
data->state.headerbuff = newbuff;
335
k->hbufp = data->state.headerbuff + hbufp_index;
337
memcpy(k->hbufp, k->str, nread);
340
if (!k->headerline && (k->hbuflen>5)) {
341
/* make a first check that this looks like a HTTP header */
342
if(!checkhttpprefix(data, data->state.headerbuff)) {
343
/* this is not the beginning of a HTTP first header line */
345
k->badheader = HEADER_ALLBAD;
350
break; /* read more and try again */
353
/* decrease the size of the remaining (supposed) header line */
354
rest_length = (k->end_ptr - k->str)+1;
355
nread -= rest_length;
357
k->str = k->end_ptr + 1; /* move past new line */
359
full_length = k->str - k->str_start;
362
* We're about to copy a chunk of data to the end of the
363
* already received header. We make sure that the full string
364
* fit in the allocated header buffer, or else we enlarge
367
if (k->hbuflen + full_length >=
368
data->state.headersize) {
370
size_t newsize=CURLMAX((k->hbuflen+full_length)*3/2,
371
data->state.headersize*2);
372
hbufp_index = k->hbufp - data->state.headerbuff;
373
newbuff = (char *)realloc(data->state.headerbuff, newsize);
375
failf (data, "Failed to alloc memory for big header!");
376
return CURLE_OUT_OF_MEMORY;
378
data->state.headersize= newsize;
379
data->state.headerbuff = newbuff;
380
k->hbufp = data->state.headerbuff + hbufp_index;
383
/* copy to end of line */
384
strncpy (k->hbufp, k->str_start, full_length);
385
k->hbufp += full_length;
386
k->hbuflen += full_length;
388
k->end_ptr = k->hbufp;
390
k->p = data->state.headerbuff;
393
* We now have a FULL header line that p points to
397
/* the first read header */
399
!checkhttpprefix(data, data->state.headerbuff)) {
400
/* this is not the beginning of a HTTP first header line */
403
/* since there's more, this is a partial bad header */
404
k->badheader = HEADER_PARTHEADER;
406
/* this was all we read so its all a bad header */
407
k->badheader = HEADER_ALLBAD;
408
nread = (ssize_t)rest_length;
414
if (('\n' == *k->p) || ('\r' == *k->p)) {
416
/* Zero-length header line means end of headers! */
419
k->p++; /* pass the \r byte */
421
k->p++; /* pass the \n byte */
423
if(100 == k->httpcode) {
425
* We have made a HTTP PUT or POST and this is 1.1-lingo
426
* that tells us that the server is OK with this and ready
427
* to receive the data.
428
* However, we'll get more headers now so we must get
429
* back into the header-parsing state!
432
k->headerline = 0; /* restart the header line counter */
433
/* if we did wait for this do enable write now! */
434
if (k->write_after_100_header) {
436
k->write_after_100_header = FALSE;
437
FD_SET (conn->writesockfd, &k->writefd); /* write */
438
k->keepon |= KEEP_WRITE;
439
k->wkeepfd = k->writefd;
443
k->header = FALSE; /* no more header to parse! */
445
if (417 == k->httpcode) {
447
* we got: "417 Expectation Failed" this means:
448
* we have made a HTTP call and our Expect Header
449
* seems to cause a problem => abort the write operations
450
* (or prevent them from starting).
452
k->write_after_100_header = FALSE;
453
k->keepon &= ~KEEP_WRITE;
454
FD_ZERO(&k->wkeepfd);
457
#ifndef CURL_DISABLE_HTTP
459
* When all the headers have been parsed, see if we should give
460
* up and return an error.
462
if (Curl_http_should_fail(conn)) {
463
failf (data, "The requested URL returned error: %d",
465
return CURLE_HTTP_RETURNED_ERROR;
467
#endif /* CURL_DISABLE_HTTP */
469
/* now, only output this if the header AND body are requested:
471
writetype = CLIENTWRITE_HEADER;
472
if (data->set.include_header)
473
writetype |= CLIENTWRITE_BODY;
475
headerlen = k->p - data->state.headerbuff;
477
result = Curl_client_write(data, writetype,
478
data->state.headerbuff,
483
data->info.header_size += headerlen;
484
conn->headerbytecount += headerlen;
486
conn->deductheadercount =
487
(100 == k->httpcode)?conn->headerbytecount:0;
489
if (conn->resume_from &&
491
(data->set.httpreq==HTTPREQ_GET)) {
492
if(k->httpcode == 416) {
493
/* "Requested Range Not Satisfiable" */
497
/* we wanted to resume a download, although the server
498
* doesn't seem to support this and we did this with a GET
499
* (if it wasn't a GET we did a POST or PUT resume) */
500
failf (data, "HTTP server doesn't seem to support "
501
"byte ranges. Cannot resume.");
502
return CURLE_HTTP_RANGE_ERROR;
505
#ifndef CURL_DISABLE_HTTP
507
/* Curl_http_auth_act() checks what authentication methods
508
* that are available and decides which one (if any) to
509
* use. It will set 'newurl' if an auth metod was picked. */
510
result = Curl_http_auth_act(conn);
515
#endif /* CURL_DISABLE_HTTP */
519
* really end-of-headers.
521
* If we requested a "no body", this is a good time to get
522
* out and return home.
524
if(conn->bits.no_body)
527
/* If we know the expected size of this document, we set the
528
maximum download size to the size of the expected
529
document or else, we won't know when to stop reading!
531
Note that we set the download maximum even if we read a
532
"Connection: close" header, to make sure that
533
"Content-Length: 0" still prevents us from attempting to
534
read the (missing) response-body.
536
/* According to RFC2616 section 4.4, we MUST ignore
537
Content-Length: headers if we are now receiving data
538
using chunked Transfer-Encoding.
544
if(-1 != conn->size) {
545
/* We do this operation even if no_body is true, since this
546
data might be retrieved later with curl_easy_getinfo()
547
and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
549
Curl_pgrsSetDownloadSize(data, conn->size);
550
conn->maxdownload = conn->size;
552
/* If max download size is *zero* (nothing) we already
553
have nothing and can safely return ok now! */
554
if(0 == conn->maxdownload)
558
/* we make sure that this socket isn't read more now */
559
k->keepon &= ~KEEP_READ;
560
FD_ZERO(&k->rkeepfd);
563
break; /* exit header line loop */
566
/* We continue reading headers, so reset the line-based
567
header parsing variables hbufp && hbuflen */
568
k->hbufp = data->state.headerbuff;
574
* Checks for special headers coming up.
577
if (!k->headerline++) {
578
/* This is the first header, it MUST be the error code line
579
or else we consiser this to be the body right away! */
580
int httpversion_major;
581
int nc=sscanf(k->p, " HTTP/%d.%d %3d",
586
k->httpversion += 10 * httpversion_major;
589
/* this is the real world, not a Nirvana
590
NCSA 1.5.x returns this crap when asked for HTTP/1.1
592
nc=sscanf(k->p, " HTTP %3d", &k->httpcode);
595
/* If user has set option HTTP200ALIASES,
596
compare header line against list of aliases
599
if (checkhttpprefix(data, k->p)) {
603
(data->set.httpversion==CURL_HTTP_VERSION_1_0)? 10 : 11;
609
data->info.httpcode = k->httpcode;
610
data->info.httpversion = k->httpversion;
613
* This code executes as part of processing the header. As a
614
* result, it's not totally clear how to interpret the
615
* response code yet as that depends on what other headers may
616
* be present. 401 and 407 may be errors, but may be OK
617
* depending on how authentication is working. Other codes
618
* are definitely errors, so give up here.
620
if (data->set.http_fail_on_error &&
621
(k->httpcode >= 400) &&
622
(k->httpcode != 401) &&
623
(k->httpcode != 407)) {
624
/* serious error, go home! */
625
failf (data, "The requested URL returned error: %d",
627
return CURLE_HTTP_RETURNED_ERROR;
630
if(k->httpversion == 10)
631
/* Default action for HTTP/1.0 must be to close, unless
632
we get one of those fancy headers that tell us the
633
server keeps it open for us! */
634
conn->bits.close = TRUE;
636
switch(k->httpcode) {
638
/* (quote from RFC2616, section 10.2.5): The server has
639
* fulfilled the request but does not need to return an
640
* entity-body ... The 204 response MUST NOT include a
641
* message-body, and thus is always terminated by the first
642
* empty line after the header fields. */
644
case 416: /* Requested Range Not Satisfiable, it has the
645
Content-Length: set as the "real" document but no
646
actual response is sent. */
648
/* (quote from RFC2616, section 10.3.5): The 304 response
649
* MUST NOT contain a message-body, and thus is always
650
* terminated by the first empty line after the header
661
k->header = FALSE; /* this is not a header line */
666
/* Check for Content-Length: header lines to get size. Ignore
667
the header completely if we get a 416 response as then we're
668
resuming a document that we don't get, and this header contains
669
info about the true size of the document we didn't get now. */
670
if ((k->httpcode != 416) &&
671
checkprefix("Content-Length:", k->p)) {
672
contentlength = curlx_strtoofft(k->p+15, NULL, 10);
673
if (data->set.max_filesize &&
674
contentlength > data->set.max_filesize) {
675
failf(data, "Maximum file size exceeded");
676
return CURLE_FILESIZE_EXCEEDED;
678
if(contentlength >= 0)
679
conn->size = contentlength;
681
/* Negative Content-Length is really odd, and we know it
682
happens for example when older Apache servers send large
684
conn->bits.close = TRUE;
685
infof(data, "Negative content-length: %" FORMAT_OFF_T
686
", closing after transfer\n", contentlength);
689
/* check for Content-Type: header lines to get the mime-type */
690
else if (checkprefix("Content-Type:", k->p)) {
695
/* Find the first non-space letter */
697
*start && isspace((int)*start);
700
end = strchr(start, '\r');
702
end = strchr(start, '\n');
705
/* skip all trailing space letters */
706
for(; isspace((int)*end) && (end > start); end--);
708
/* get length of the type */
711
/* allocate memory of a cloned copy */
712
Curl_safefree(data->info.contenttype);
714
data->info.contenttype = malloc(len + 1);
715
if (NULL == data->info.contenttype)
716
return CURLE_OUT_OF_MEMORY;
718
/* copy the content-type string */
719
memcpy(data->info.contenttype, start, len);
720
data->info.contenttype[len] = 0; /* zero terminate */
723
#ifndef CURL_DISABLE_HTTP
724
else if((k->httpversion == 10) &&
725
conn->bits.httpproxy &&
726
Curl_compareheader(k->p,
727
"Proxy-Connection:", "keep-alive")) {
729
* When a HTTP/1.0 reply comes when using a proxy, the
730
* 'Proxy-Connection: keep-alive' line tells us the
731
* connection will be kept alive for our pleasure.
732
* Default action for 1.0 is to close.
734
conn->bits.close = FALSE; /* don't close when done */
735
infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
737
else if((k->httpversion == 10) &&
738
Curl_compareheader(k->p, "Connection:", "keep-alive")) {
740
* A HTTP/1.0 reply with the 'Connection: keep-alive' line
741
* tells us the connection will be kept alive for our
742
* pleasure. Default action for 1.0 is to close.
744
* [RFC2068, section 19.7.1] */
745
conn->bits.close = FALSE; /* don't close when done */
746
infof(data, "HTTP/1.0 connection set to keep alive!\n");
748
else if (Curl_compareheader(k->p, "Connection:", "close")) {
750
* [RFC 2616, section 8.1.2.1]
751
* "Connection: close" is HTTP/1.1 language and means that
752
* the connection will close when this request has been
755
conn->bits.close = TRUE; /* close when done */
757
else if (Curl_compareheader(k->p,
758
"Transfer-Encoding:", "chunked")) {
760
* [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
761
* means that the server will send a series of "chunks". Each
762
* chunk starts with line with info (including size of the
763
* coming block) (terminated with CRLF), then a block of data
764
* with the previously mentioned size. There can be any amount
765
* of chunks, and a chunk-data set to zero signals the
767
conn->bits.chunk = TRUE; /* chunks coming our way */
769
/* init our chunky engine */
770
Curl_httpchunk_init(conn);
772
else if (checkprefix("Content-Encoding:", k->p) &&
773
data->set.encoding) {
775
* Process Content-Encoding. Look for the values: identity,
776
* gzip, deflate, compress, x-gzip and x-compress. x-gzip and
777
* x-compress are the same as gzip and compress. (Sec 3.5 RFC
778
* 2616). zlib cannot handle compress. However, errors are
779
* handled further down when the response body is processed
783
/* Find the first non-space letter */
785
*start && isspace((int)*start);
788
/* Record the content-encoding for later use */
789
if (checkprefix("identity", start))
790
k->content_encoding = IDENTITY;
791
else if (checkprefix("deflate", start))
792
k->content_encoding = DEFLATE;
793
else if (checkprefix("gzip", start)
794
|| checkprefix("x-gzip", start))
795
k->content_encoding = GZIP;
796
else if (checkprefix("compress", start)
797
|| checkprefix("x-compress", start))
798
k->content_encoding = COMPRESS;
800
else if (Curl_compareheader(k->p, "Content-Range:", "bytes")) {
801
/* Content-Range: bytes [num]-
802
Content-Range: bytes: [num]-
804
The second format was added August 1st 2000 by Igor
805
Khristophorov since Sun's webserver JavaWebServer/1.1.1
806
obviously sends the header this way! :-( */
808
char *ptr = strstr(k->p, "bytes");
812
/* stupid colon skip */
815
k->offset = curlx_strtoofft(ptr, NULL, 10);
817
if (conn->resume_from == k->offset)
818
/* we asked for a resume and we got it */
819
k->content_range = TRUE;
821
else if(data->cookies &&
822
checkprefix("Set-Cookie:", k->p)) {
823
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
824
CURL_LOCK_ACCESS_SINGLE);
825
Curl_cookie_add(data,
826
data->cookies, TRUE, k->p+11,
827
/* If there is a custom-set Host: name, use it
828
here, or else use real peer host name. */
829
conn->allocptr.cookiehost?
830
conn->allocptr.cookiehost:conn->host.name,
832
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
834
else if(checkprefix("Last-Modified:", k->p) &&
835
(data->set.timecondition || data->set.get_filetime) ) {
836
time_t secs=time(NULL);
837
k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
839
if(data->set.get_filetime)
840
data->info.filetime = k->timeofdoc;
842
else if((checkprefix("WWW-Authenticate:", k->p) &&
843
(401 == k->httpcode)) ||
844
(checkprefix("Proxy-authenticate:", k->p) &&
845
(407 == k->httpcode))) {
846
result = Curl_http_input_auth(conn, k->httpcode, k->p);
850
else if ((k->httpcode >= 300 && k->httpcode < 400) &&
851
checkprefix("Location:", k->p)) {
852
if(data->set.http_follow_location) {
853
/* this is the URL that the server advices us to get instead */
858
start += 9; /* pass "Location:" */
860
/* Skip spaces and tabs. We do this to support multiple
861
white spaces after the "Location:" keyword. */
862
while(*start && isspace((int)*start ))
865
/* Scan through the string from the end to find the last
866
non-space. k->end_ptr points to the actual terminating zero
867
letter, move pointer one letter back and start from
868
there. This logic strips off trailing whitespace, but keeps
869
any embedded whitespace. */
871
while((ptr>=start) && isspace((int)*ptr))
875
backup = *ptr; /* store the ending letter */
877
*ptr = '\0'; /* zero terminate */
878
conn->newurl = strdup(start); /* clone string */
879
*ptr = backup; /* restore ending letter */
881
return CURLE_OUT_OF_MEMORY;
885
#endif /* CURL_DISABLE_HTTP */
888
* End of header-checks. Write them to the client.
891
writetype = CLIENTWRITE_HEADER;
892
if (data->set.include_header)
893
writetype |= CLIENTWRITE_BODY;
895
if(data->set.verbose)
896
Curl_debug(data, CURLINFO_HEADER_IN,
897
k->p, k->hbuflen, conn->host.dispname);
899
result = Curl_client_write(data, writetype, k->p, k->hbuflen);
903
data->info.header_size += k->hbuflen;
904
conn->headerbytecount += k->hbuflen;
906
/* reset hbufp pointer && hbuflen */
907
k->hbufp = data->state.headerbuff;
910
while (!stop_reading && *k->str); /* header line within buffer */
913
/* We've stopped dealing with input, get out of the do-while loop */
916
/* We might have reached the end of the header part here, but
917
there might be a non-header part left in the end of the read
920
} /* end if header mode */
922
/* This is not an 'else if' since it may be a rest from the header
923
parsing, where the beginning of the buffer is headers and the end
925
if (k->str && !k->header && (nread > 0)) {
927
if(0 == k->bodywrites) {
928
/* These checks are only made the first time we are about to
929
write a piece of the body */
930
if(conn->protocol&PROT_HTTP) {
931
/* HTTP-only checks */
934
if(conn->bits.close) {
935
/* Abort after the headers if "follow Location" is set
936
and we're set to close anyway. */
937
k->keepon &= ~KEEP_READ;
938
FD_ZERO(&k->rkeepfd);
942
/* We have a new url to load, but since we want to be able
943
to re-use this connection properly, we read the full
944
response in "ignore more" */
945
k->ignorebody = TRUE;
946
infof(data, "Ignoring the response-body\n");
948
if(data->set.timecondition && !conn->range) {
949
/* A time condition has been set AND no ranges have been
950
requested. This seems to be what chapter 13.3.4 of
951
RFC 2616 defines to be the correct action for a
953
if((k->timeofdoc > 0) && (data->set.timevalue > 0)) {
954
switch(data->set.timecondition) {
955
case CURL_TIMECOND_IFMODSINCE:
957
if(k->timeofdoc < data->set.timevalue) {
959
"The requested document is not new enough\n");
964
case CURL_TIMECOND_IFUNMODSINCE:
965
if(k->timeofdoc > data->set.timevalue) {
967
"The requested document is not old enough\n");
973
} /* two valid time strings */
974
} /* we have a time condition */
977
} /* this is the first time we write a body part */
980
/* pass data to the debug function before it gets "dechunked" */
981
if(data->set.verbose) {
983
Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
984
k->hbuflen, conn->host.dispname);
985
if(k->badheader == HEADER_PARTHEADER)
986
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread,
987
conn->host.dispname);
990
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread,
991
conn->host.dispname);
994
#ifndef CURL_DISABLE_HTTP
995
if(conn->bits.chunk) {
997
* Bless me father for I have sinned. Here comes a chunked
998
* transfer flying and we need to decode this properly. While
999
* the name says read, this function both reads and writes away
1000
* the data. The returned 'nread' holds the number of actual
1001
* data it wrote to the client. */
1003
Curl_httpchunk_read(conn, k->str, nread, &nread);
1005
if(CHUNKE_OK < res) {
1006
if(CHUNKE_WRITE_ERROR == res) {
1007
failf(data, "Failed writing data");
1008
return CURLE_WRITE_ERROR;
1010
failf(data, "Received problem %d in the chunky parser", res);
1011
return CURLE_RECV_ERROR;
1013
else if(CHUNKE_STOP == res) {
1014
/* we're done reading chunks! */
1015
k->keepon &= ~KEEP_READ; /* read no more */
1016
FD_ZERO(&k->rkeepfd);
1018
/* There are now possibly N number of bytes at the end of the
1019
str buffer that weren't written to the client, but we don't
1020
care about them right now. */
1022
/* If it returned OK, we just keep going */
1024
#endif /* CURL_DISABLE_HTTP */
1026
if((-1 != conn->maxdownload) &&
1027
(k->bytecount + nread >= conn->maxdownload)) {
1028
nread = (ssize_t) (conn->maxdownload - k->bytecount);
1029
if(nread < 0 ) /* this should be unusual */
1032
k->keepon &= ~KEEP_READ; /* we're done reading */
1033
FD_ZERO(&k->rkeepfd);
1036
k->bytecount += nread;
1038
Curl_pgrsSetDownloadCounter(data, k->bytecount);
1040
if(!conn->bits.chunk && (nread || k->badheader)) {
1041
/* If this is chunky transfer, it was already written */
1043
if(k->badheader && !k->ignorebody) {
1044
/* we parsed a piece of data wrongly assuming it was a header
1045
and now we output it as body instead */
1046
result = Curl_client_write(data, CLIENTWRITE_BODY,
1047
data->state.headerbuff,
1050
if(k->badheader < HEADER_ALLBAD) {
1051
/* This switch handles various content encodings. If there's an
1052
error here, be sure to check over the almost identical code
1054
Make sure that ALL_CONTENT_ENCODINGS contains all the
1055
encodings handled here. */
1057
switch (k->content_encoding) {
1060
/* This is the default when the server sends no
1061
Content-Encoding header. See Curl_readwrite_init; the
1062
memset() call initializes k->content_encoding to zero. */
1064
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
1070
/* Assume CLIENTWRITE_BODY; headers are not encoded. */
1071
result = Curl_unencode_deflate_write(data, k, nread);
1075
/* Assume CLIENTWRITE_BODY; headers are not encoded. */
1076
result = Curl_unencode_gzip_write(data, k, nread);
1081
failf (data, "Unrecognized content encoding type. "
1082
"libcurl understands `identity', `deflate' and `gzip' "
1083
"content encodings.");
1084
result = CURLE_BAD_CONTENT_ENCODING;
1089
k->badheader = HEADER_NORMAL; /* taken care of now */
1095
} /* if (! header and data to read ) */
1099
} /* if( read from socket ) */
1101
/* If we still have writing to do, we check if we have a writable
1102
socket. Sometimes the writefdp is NULL, if no fd_set was done using
1103
the multi interface and then we can do nothing but to attempt a
1104
write to be sure. */
1105
if((k->keepon & KEEP_WRITE) &&
1106
(!writefdp || FD_ISSET(conn->writesockfd, writefdp)) ) {
1110
ssize_t bytes_written;
1111
bool writedone=TRUE;
1113
if ((k->bytecount == 0) && (k->writebytecount == 0))
1114
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
1116
didwhat |= KEEP_WRITE;
1119
* We loop here to do the READ and SEND loop until we run out of
1120
* data to send or until we get EWOULDBLOCK back
1124
/* only read more data if there's no upload data already
1125
present in the upload buffer */
1126
if(0 == conn->upload_present) {
1127
/* init the "upload from here" pointer */
1128
conn->upload_fromhere = k->uploadbuf;
1130
if(!k->upload_done) {
1131
/* HTTP pollution, this should be written nicer to become more
1132
protocol agnostic. */
1135
if(k->wait100_after_headers &&
1136
(conn->proto.http->sending == HTTPSEND_BODY)) {
1137
/* If this call is to send body data, we must take some action:
1138
We have sent off the full HTTP 1.1 request, and we shall now
1139
go into the Expect: 100 state and await such a header */
1140
k->wait100_after_headers = FALSE; /* headers sent */
1141
k->write_after_100_header = TRUE; /* wait for the header */
1142
FD_ZERO (&k->writefd); /* clear it */
1143
k->wkeepfd = k->writefd; /* set the keeper variable */
1144
k->keepon &= ~KEEP_WRITE; /* disable writing */
1145
k->start100 = Curl_tvnow(); /* timeout count starts now */
1146
didwhat &= ~KEEP_WRITE; /* we didn't write anything actually */
1150
result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
1154
nread = (ssize_t)fillcount;
1157
nread = 0; /* we're done uploading/reading */
1159
/* the signed int typecase of nread of for systems that has
1163
k->keepon &= ~KEEP_WRITE; /* we're done writing */
1164
FD_ZERO(&k->wkeepfd);
1170
/* store number of bytes available for upload */
1171
conn->upload_present = nread;
1173
/* convert LF to CRLF if so asked */
1174
if (data->set.crlf) {
1175
if(data->state.scratch == NULL)
1176
data->state.scratch = malloc(2*BUFSIZE);
1177
if(data->state.scratch == NULL) {
1178
failf (data, "Failed to alloc scratch buffer!");
1179
return CURLE_OUT_OF_MEMORY;
1181
for(i = 0, si = 0; i < nread; i++, si++) {
1182
if (conn->upload_fromhere[i] == 0x0a) {
1183
data->state.scratch[si++] = 0x0d;
1184
data->state.scratch[si] = 0x0a;
1187
data->state.scratch[si] = conn->upload_fromhere[i];
1190
/* only perform the special operation if we really did replace
1194
/* upload from the new (replaced) buffer instead */
1195
conn->upload_fromhere = data->state.scratch;
1197
/* set the new amount too */
1198
conn->upload_present = nread;
1203
/* We have a partial buffer left from a previous "round". Use
1204
that instead of reading more data */
1207
/* write to socket (send away data) */
1208
result = Curl_write(conn,
1209
conn->writesockfd, /* socket to send to */
1210
conn->upload_fromhere, /* buffer pointer */
1211
conn->upload_present, /* buffer size */
1212
&bytes_written); /* actually send away */
1216
if(data->set.verbose)
1217
/* show the data before we change the pointer upload_fromhere */
1218
Curl_debug(data, CURLINFO_DATA_OUT, conn->upload_fromhere,
1219
bytes_written, conn->host.dispname);
1221
if(conn->upload_present != bytes_written) {
1222
/* we only wrote a part of the buffer (if anything), deal with it! */
1224
/* store the amount of bytes left in the buffer to write */
1225
conn->upload_present -= bytes_written;
1227
/* advance the pointer where to find the buffer when the next send
1229
conn->upload_fromhere += bytes_written;
1231
writedone = TRUE; /* we are done, stop the loop */
1234
/* we've uploaded that buffer now */
1235
conn->upload_fromhere = k->uploadbuf;
1236
conn->upload_present = 0; /* no more bytes left */
1238
if(k->upload_done) {
1239
/* switch off writing, we're done! */
1240
k->keepon &= ~KEEP_WRITE; /* we're done writing */
1241
FD_ZERO(&k->wkeepfd);
1246
k->writebytecount += bytes_written;
1247
Curl_pgrsSetUploadCounter(data, k->writebytecount);
1249
} while(!writedone); /* loop until we're done writing! */
1253
} while(0); /* just to break out from! */
1255
k->now = Curl_tvnow();
1257
/* Update read/write counters */
1258
if(conn->bytecountp)
1259
*conn->bytecountp = k->bytecount; /* read count */
1260
if(conn->writebytecountp)
1261
*conn->writebytecountp = k->writebytecount; /* write count */
1264
/* no read no write, this is a timeout? */
1265
if (k->write_after_100_header) {
1266
/* This should allow some time for the header to arrive, but only a
1267
very short time as otherwise it'll be too much wasted times too
1270
/* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
1272
Therefore, when a client sends this header field to an origin server
1273
(possibly via a proxy) from which it has never seen a 100 (Continue)
1274
status, the client SHOULD NOT wait for an indefinite period before
1275
sending the request body.
1279
long ms = Curl_tvdiff(k->now, k->start100);
1280
if(ms > CURL_TIMEOUT_EXPECT_100) {
1281
/* we've waited long enough, continue anyway */
1282
k->write_after_100_header = FALSE;
1283
FD_SET (conn->writesockfd, &k->writefd); /* write socket */
1284
k->keepon |= KEEP_WRITE;
1285
k->wkeepfd = k->writefd;
1290
if(Curl_pgrsUpdate(conn))
1291
result = CURLE_ABORTED_BY_CALLBACK;
1293
result = Curl_speedcheck(data, k->now);
1297
if (data->set.timeout &&
1298
((Curl_tvdiff(k->now, k->start)/1000) >= data->set.timeout)) {
1299
failf(data, "Operation timed out with %" FORMAT_OFF_T
1300
" out of %" FORMAT_OFF_T " bytes received",
1301
k->bytecount, conn->size);
1302
return CURLE_OPERATION_TIMEOUTED;
1307
* The transfer has been performed. Just make some general checks before
1311
if(!(conn->bits.no_body) && (conn->size != -1) &&
1312
(k->bytecount != conn->size) &&
1314
failf(data, "transfer closed with %" FORMAT_OFF_T
1315
" bytes remaining to read",
1316
conn->size - k->bytecount);
1317
return CURLE_PARTIAL_FILE;
1319
else if(conn->bits.chunk && conn->proto.http->chunk.datasize) {
1320
failf(data, "transfer closed with at least %d bytes remaining",
1321
conn->proto.http->chunk.datasize);
1322
return CURLE_PARTIAL_FILE;
1324
if(Curl_pgrsUpdate(conn))
1325
return CURLE_ABORTED_BY_CALLBACK;
1328
/* Now update the "done" boolean we return */
1336
* Curl_readwrite_init() inits the readwrite session.
1339
CURLcode Curl_readwrite_init(struct connectdata *conn)
1341
struct SessionHandle *data;
1342
struct Curl_transfer_keeper *k = &conn->keep;
1344
/* NB: the content encoding software depends on this initialization of
1345
Curl_transfer_keeper. */
1346
memset(k, 0, sizeof(struct Curl_transfer_keeper));
1348
k->start = Curl_tvnow(); /* start time */
1349
k->now = k->start; /* current time is now */
1350
k->header = TRUE; /* assume header */
1351
k->httpversion = -1; /* unknown at this point */
1353
data = conn->data; /* there's the root struct */
1354
k->buf = data->state.buffer;
1355
k->uploadbuf = data->state.uploadbuffer;
1356
k->maxfd = (conn->sockfd>conn->writesockfd?
1357
conn->sockfd:conn->writesockfd)+1;
1358
k->hbufp = data->state.headerbuff;
1359
k->ignorebody=FALSE;
1361
Curl_pgrsTime(data, TIMER_PRETRANSFER);
1362
Curl_speedinit(data);
1364
Curl_pgrsSetUploadCounter(data, 0);
1365
Curl_pgrsSetDownloadCounter(data, 0);
1367
if (!conn->bits.getheader) {
1370
Curl_pgrsSetDownloadSize(data, conn->size);
1372
/* we want header and/or body, if neither then don't do this! */
1373
if(conn->bits.getheader || !conn->bits.no_body) {
1375
FD_ZERO (&k->readfd); /* clear it */
1376
if(conn->sockfd != CURL_SOCKET_BAD) {
1377
FD_SET (conn->sockfd, &k->readfd); /* read socket */
1378
k->keepon |= KEEP_READ;
1381
FD_ZERO (&k->writefd); /* clear it */
1382
if(conn->writesockfd != CURL_SOCKET_BAD) {
1385
Even if we require a 100-return code before uploading data, we might
1386
need to write data before that since the REQUEST may not have been
1387
finished sent off just yet.
1389
Thus, we must check if the request has been sent before we set the
1390
state info where we wait for the 100-return code
1392
if (data->set.expect100header &&
1393
(conn->proto.http->sending == HTTPSEND_BODY)) {
1394
/* wait with write until we either got 100-continue or a timeout */
1395
k->write_after_100_header = TRUE;
1396
k->start100 = k->start;
1399
if(data->set.expect100header)
1400
/* when we've sent off the rest of the headers, we must await a
1402
k->wait100_after_headers = TRUE;
1403
FD_SET (conn->writesockfd, &k->writefd); /* write socket */
1404
k->keepon |= KEEP_WRITE;
1408
/* get these in backup variables to be able to restore them on each lap in
1409
the select() loop */
1410
k->rkeepfd = k->readfd;
1411
k->wkeepfd = k->writefd;
1419
* Curl_single_fdset() gets called by the multi interface code when the app
1420
* has requested to get the fd_sets for the current connection. This function
1421
* will then be called once for every connection that the multi interface
1422
* keeps track of. This function will only be called for connections that are
1423
* in the proper state to have this information available.
1425
void Curl_single_fdset(struct connectdata *conn,
1426
fd_set *read_fd_set,
1427
fd_set *write_fd_set,
1431
*max_fd = -1; /* init */
1432
if(conn->keep.keepon & KEEP_READ) {
1433
FD_SET(conn->sockfd, read_fd_set);
1434
*max_fd = conn->sockfd;
1435
conn->keep.readfdp = read_fd_set; /* store the address of the set */
1437
if(conn->keep.keepon & KEEP_WRITE) {
1438
FD_SET(conn->writesockfd, write_fd_set);
1440
/* since sockets are curl_socket_t nowadays, we typecast it to int here
1441
to compare it nicely */
1442
if((int)conn->writesockfd > *max_fd)
1443
*max_fd = conn->writesockfd;
1444
conn->keep.writefdp = write_fd_set; /* store the address of the set */
1446
/* we don't use exceptions, only touch that one to prevent compiler
1448
*exc_fd_set = *exc_fd_set;
1455
* This function is what performs the actual transfer. It is capable of
1456
* doing both ways simultaneously.
1457
* The transfer must already have been setup by a call to Curl_Transfer().
1459
* Note that headers are created in a preallocated buffer of a default size.
1460
* That buffer can be enlarged on demand, but it is never shrunken again.
1462
* Parts of this function was once written by the friendly Mark Butler
1463
* <butlerm@xmission.com>.
1467
Transfer(struct connectdata *conn)
1470
struct Curl_transfer_keeper *k = &conn->keep;
1473
if(!(conn->protocol & PROT_FILE))
1474
/* Only do this if we are not transferring FILE:, since the file: treatment
1476
Curl_readwrite_init(conn);
1478
if((conn->sockfd == CURL_SOCKET_BAD) &&
1479
(conn->writesockfd == CURL_SOCKET_BAD))
1480
/* nothing to read, nothing to write, we're already OK! */
1483
/* we want header and/or body, if neither then don't do this! */
1484
if(!conn->bits.getheader && conn->bits.no_body)
1487
k->writefdp = &k->writefd; /* store the address of the set */
1488
k->readfdp = &k->readfd; /* store the address of the set */
1491
struct timeval interval;
1492
k->readfd = k->rkeepfd; /* set these every lap in the loop */
1493
k->writefd = k->wkeepfd;
1494
interval.tv_sec = 1;
1495
interval.tv_usec = 0;
1497
switch (select (k->maxfd, k->readfdp, k->writefdp, NULL, &interval)) {
1498
case -1: /* select() error, stop reading */
1500
/* The EINTR is not serious, and it seems you might get this more
1501
ofen when using the lib in a multi-threaded environment! */
1506
done = TRUE; /* no more read or write */
1508
case 0: /* timeout */
1509
default: /* readable descriptors */
1510
result = Curl_readwrite(conn, &done);
1516
/* "done" signals to us if the transfer(s) are ready */
1523
* Curl_pretransfer() is called immediately before a transfer starts.
1525
CURLcode Curl_pretransfer(struct SessionHandle *data)
1527
if(!data->change.url)
1528
/* we can't do anything wihout URL */
1529
return CURLE_URL_MALFORMAT;
1533
/* Init the SSL session ID cache here. We do it here since we want to do
1534
it after the *_setopt() calls (that could change the size of the cache)
1535
but before any transfer takes place. */
1536
CURLcode res = Curl_SSL_InitSessions(data, data->set.ssl.numsessions);
1542
data->set.followlocation=0; /* reset the location-follow counter */
1543
data->state.this_is_a_follow = FALSE; /* reset this */
1544
data->state.errorbuf = FALSE; /* no error has occurred */
1546
data->state.authproblem = FALSE;
1547
data->state.authhost.want = data->set.httpauth;
1548
data->state.authproxy.want = data->set.proxyauth;
1550
#ifndef CURL_DISABLE_HTTP
1551
/* If there was a list of cookie files to read and we haven't done it before,
1553
if(data->change.cookielist) {
1554
struct curl_slist *list = data->change.cookielist;
1555
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1557
data->cookies = Curl_cookie_init(data,
1560
data->set.cookiesession);
1563
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1564
curl_slist_free_all(data->change.cookielist); /* clean up list */
1565
data->change.cookielist = NULL; /* don't do this again! */
1567
#endif /* CURL_DISABLE_HTTP */
1570
/* Allow data->set.use_port to set which port to use. This needs to be
1571
* disabled for example when we follow Location: headers to URLs using
1572
* different ports! */
1573
data->state.allow_port = TRUE;
1575
#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1576
/*************************************************************
1577
* Tell signal handler to ignore SIGPIPE
1578
*************************************************************/
1579
if(!data->set.no_signal)
1580
data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
1583
Curl_initinfo(data); /* reset session-specific information "variables" */
1584
Curl_pgrsStartNow(data);
1590
* Curl_posttransfer() is called immediately after a transfer ends
1592
CURLcode Curl_posttransfer(struct SessionHandle *data)
1594
#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1595
/* restore the signal handler for SIGPIPE before we get back */
1596
if(!data->set.no_signal)
1597
signal(SIGPIPE, data->state.prev_signal);
1599
(void)data; /* unused parameter */
1606
* strlen_url() returns the length of the given URL if the spaces within the
1607
* URL were properly URL encoded.
1609
static int strlen_url(char *url)
1613
bool left=TRUE; /* left side of the ? */
1615
for(ptr=url; *ptr; ptr++) {
1633
/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in
1634
* the source URL accordingly.
1636
static void strcpy_url(char *output, char *url)
1638
/* we must add this with whitespace-replacing */
1641
char *optr = output;
1642
for(iptr = url; /* read from here */
1643
*iptr; /* until zero byte */
1653
*optr++='%'; /* add a '%' */
1654
*optr++='2'; /* add a '2' */
1655
*optr++='0'; /* add a '0' */
1658
*optr++='+'; /* add a '+' here */
1662
*optr=0; /* zero terminate output buffer */
1667
* Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
1668
* as given by the remote server and set up the new URL to request.
1670
CURLcode Curl_follow(struct SessionHandle *data,
1671
char *newurl) /* this 'newurl' is the Location: string,
1672
and it must be malloc()ed before passed
1675
/* Location: redirect */
1676
char prot[16]; /* URL protocol string storage */
1677
char letter; /* used for a silly sscanf */
1681
if (data->set.maxredirs &&
1682
(data->set.followlocation >= data->set.maxredirs)) {
1683
failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
1684
return CURLE_TOO_MANY_REDIRECTS;
1687
/* mark the next request as a followed location: */
1688
data->state.this_is_a_follow = TRUE;
1690
data->set.followlocation++; /* count location-followers */
1692
if(data->set.http_auto_referer) {
1693
/* We are asked to automatically set the previous URL as the
1694
referer when we get the next URL. We pick the ->url field,
1695
which may or may not be 100% correct */
1697
if(data->change.referer_alloc)
1698
/* If we already have an allocated referer, free this first */
1699
free(data->change.referer);
1701
data->change.referer = strdup(data->change.url);
1702
data->change.referer_alloc = TRUE; /* yes, free this later */
1705
if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) {
1707
*DANG* this is an RFC 2068 violation. The URL is supposed
1708
to be absolute and this doesn't seem to be that!
1710
Instead, we have to TRY to append this new path to the old URL
1711
to the right of the host part. Oh crap, this is doomed to cause
1712
problems in the future...
1717
char *useurl = newurl;
1720
/* we must make our own copy of the URL to play with, as it may
1721
point to read-only data */
1722
char *url_clone=strdup(data->change.url);
1725
return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */
1727
/* protsep points to the start of the host name */
1728
protsep=strstr(url_clone, "//");
1732
protsep+=2; /* pass the slashes */
1734
if('/' != newurl[0]) {
1737
/* First we need to find out if there's a ?-letter in the URL,
1738
and cut it and the right-side of that off */
1739
pathsep = strrchr(protsep, '?');
1743
/* we have a relative path to append to the last slash if
1744
there's one available */
1745
pathsep = strrchr(protsep, '/');
1749
/* Check if there's any slash after the host name, and if so,
1750
remember that position instead */
1751
pathsep = strchr(protsep, '/');
1753
protsep = pathsep+1;
1757
/* now deal with one "./" or any amount of "../" in the newurl
1758
and act accordingly */
1760
if((useurl[0] == '.') && (useurl[1] == '/'))
1761
useurl+=2; /* just skip the "./" */
1763
while((useurl[0] == '.') &&
1764
(useurl[1] == '.') &&
1765
(useurl[2] == '/')) {
1767
useurl+=3; /* pass the "../" */
1772
/* cut off one more level from the right of the original URL */
1773
pathsep = strrchr(protsep, '/');
1784
/* We got a new absolute path for this server, cut off from the
1786
pathsep = strchr(protsep, '/');
1790
/* There was no slash. Now, since we might be operating on a badly
1791
formatted URL, such as "http://www.url.com?id=2380" which doesn't
1792
use a slash separator as it is supposed to, we need to check for a
1793
?-letter as well! */
1794
pathsep = strchr(protsep, '?');
1800
/* If the new part contains a space, this is a mighty stupid redirect
1801
but we still make an effort to do "right". To the left of a '?'
1802
letter we replace each space with %20 while it is replaced with '+'
1803
on the right side of the '?' letter.
1805
newlen = strlen_url(useurl);
1807
urllen = strlen(url_clone);
1809
newest=(char *)malloc( urllen + 1 + /* possible slash */
1810
newlen + 1 /* zero byte */);
1813
free(url_clone); /* don't leak this */
1814
return CURLE_OUT_OF_MEMORY; /* go out from this */
1817
/* copy over the root url part */
1818
memcpy(newest, url_clone, urllen);
1820
/* check if we need to append a slash */
1821
if(('/' == useurl[0]) || (protsep && !*protsep))
1824
newest[urllen++]='/';
1826
/* then append the new piece on the right side */
1827
strcpy_url(&newest[urllen], useurl);
1829
free(newurl); /* newurl is the allocated pointer */
1834
/* This is an absolute URL, don't allow the custom port number */
1835
data->state.allow_port = FALSE;
1837
if(strchr(newurl, ' ')) {
1838
/* This new URL contains at least one space, this is a mighty stupid
1839
redirect but we still make an effort to do "right". */
1840
newlen = strlen_url(newurl);
1842
newest = malloc(newlen+1); /* get memory for this */
1844
strcpy_url(newest, newurl); /* create a space-free URL */
1846
free(newurl); /* that was no good */
1847
newurl = newest; /* use this instead now */
1853
if(data->change.url_alloc)
1854
free(data->change.url);
1856
data->change.url_alloc = TRUE; /* the URL is allocated */
1858
data->change.url = newurl;
1859
newurl = NULL; /* don't free! */
1862
infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
1865
* We get here when the HTTP code is 300-399 (and 401). We need to perform
1866
* differently based on exactly what return code there was.
1868
* News from 7.10.6: we can also get here on a 401 or 407, in case we act on
1869
* a HTTP (proxy-) authentication scheme other than Basic.
1871
switch(data->info.httpcode) {
1872
/* 401 - Act on a www-authentication, we keep on moving and do the
1873
Authorization: XXXX header in the HTTP request code snippet */
1874
/* 407 - Act on a proxy-authentication, we keep on moving and do the
1875
Proxy-Authorization: XXXX header in the HTTP request code snippet */
1876
/* 300 - Multiple Choices */
1877
/* 306 - Not used */
1878
/* 307 - Temporary Redirect */
1879
default: /* for all above (and the unknown ones) */
1880
/* Some codes are explicitly mentioned since I've checked RFC2616 and they
1881
* seem to be OK to POST to.
1884
case 301: /* Moved Permanently */
1885
/* (quote from RFC2616, section 10.3.2):
1887
* Note: When automatically redirecting a POST request after receiving a
1888
* 301 status code, some existing HTTP/1.0 user agents will erroneously
1889
* change it into a GET request.
1893
* Warning: Because most of importants user agents do this obvious RFC2616
1894
* violation, many webservers expect this misbehavior. So these servers
1895
* often answers to a POST request with an error page. To be sure that
1896
* libcurl gets the page that most user agents would get, libcurl has to
1899
if( data->set.httpreq == HTTPREQ_POST
1900
|| data->set.httpreq == HTTPREQ_POST_FORM) {
1902
"Violate RFC 2616/10.3.2 and switch from POST to GET\n");
1903
data->set.httpreq = HTTPREQ_GET;
1906
case 302: /* Found */
1909
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
1910
to change the method on the redirected request. However, most
1911
existing user agent implementations treat 302 as if it were a 303
1912
response, performing a GET on the Location field-value regardless
1913
of the original request method. The status codes 303 and 307 have
1914
been added for servers that wish to make unambiguously clear which
1915
kind of reaction is expected of the client.
1919
Note: Many pre-HTTP/1.1 user agents do not understand the 303
1920
status. When interoperability with such clients is a concern, the
1921
302 status code may be used instead, since most user agents react
1922
to a 302 response as described here for 303.
1924
case 303: /* See Other */
1925
/* Disable both types of POSTs, since doing a second POST when
1926
* following isn't what anyone would want! */
1927
if(data->set.httpreq != HTTPREQ_GET) {
1928
data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
1929
infof(data, "Disables POST, goes with %s\n",
1930
data->set.opt_no_body?"HEAD":"GET");
1933
case 304: /* Not Modified */
1934
/* 304 means we did a conditional request and it was "Not modified".
1935
* We shouldn't get any Location: header in this response!
1938
case 305: /* Use Proxy */
1939
/* (quote from RFC2616, section 10.3.6):
1940
* "The requested resource MUST be accessed through the proxy given
1941
* by the Location field. The Location field gives the URI of the
1942
* proxy. The recipient is expected to repeat this single request
1943
* via the proxy. 305 responses MUST only be generated by origin
1948
Curl_pgrsTime(data, TIMER_REDIRECT);
1949
Curl_pgrsResetTimes(data);
1955
Curl_connect_host(struct SessionHandle *data,
1956
struct connectdata **conn)
1963
Curl_pgrsTime(data, TIMER_STARTSINGLE);
1964
data->change.url_changed = FALSE;
1965
res = Curl_connect(data, conn, &async);
1967
if((CURLE_OK == res) && async) {
1968
/* Now, if async is TRUE here, we need to wait for the name
1970
res = Curl_wait_for_resolv(*conn, NULL);
1972
/* Resolved, continue with the connection */
1973
res = Curl_async_resolved(*conn);
1978
/* If a callback (or something) has altered the URL we should use within
1979
the Curl_connect(), we detect it here and act as if we are redirected
1981
urlchanged = data->change.url_changed;
1982
if ((CURLE_OK == res) && urlchanged) {
1983
res = Curl_done(conn, res);
1984
if(CURLE_OK == res) {
1985
char *gotourl = strdup(data->change.url);
1986
res = Curl_follow(data, gotourl);
1991
} while (urlchanged && res == CURLE_OK);
1999
* Curl_perform() is the internal high-level function that gets called by the
2000
* external curl_easy_perform() function. It inits, performs and cleans up a
2001
* single file transfer.
2003
CURLcode Curl_perform(struct SessionHandle *data)
2007
struct connectdata *conn=NULL;
2008
char *newurl = NULL; /* possibly a new URL to follow to! */
2010
data->state.used_interface = Curl_if_easy;
2012
res = Curl_pretransfer(data);
2017
* It is important that there is NO 'return' from this function at any other
2018
* place than falling down to the end of the function! This is because we
2019
* have cleanup stuff that must be done before we get back, and that is only
2020
* performed after this do-while loop.
2024
res = Curl_connect_host(data, &conn); /* primary connection */
2026
if(res == CURLE_OK) {
2027
if (data->set.source_host) /* 3rd party transfer */
2028
res = Curl_pretransfersec(conn);
2030
conn->sec_conn = NULL;
2033
if(res == CURLE_OK) {
2035
res = Curl_do(&conn);
2037
/* for non 3rd party transfer only */
2038
if(res == CURLE_OK && !data->set.source_host) {
2039
res = Transfer(conn); /* now fetch that URL please */
2040
if(res == CURLE_OK) {
2042
if((conn->keep.bytecount+conn->headerbytecount == 0) &&
2044
/* We got no data and we attempted to re-use a connection. This
2045
might happen if the connection was left alive when we were done
2046
using it before, but that was closed when we wanted to read
2047
from it again. Bad luck. Retry the same request on a fresh
2049
infof(data, "Connection died, retrying a fresh connect\n");
2050
newurl = strdup(conn->data->change.url);
2052
conn->bits.close = TRUE; /* close this connection */
2053
conn->bits.retry = TRUE; /* mark this as a connection we're about
2054
to retry. Marking it this way should
2055
prevent i.e HTTP transfers to return
2056
error just because nothing has been
2061
* We must duplicate the new URL here as the connection data
2062
* may be free()ed in the Curl_done() function.
2064
newurl = conn->newurl?strdup(conn->newurl):NULL;
2067
/* The transfer phase returned error, we mark the connection to get
2068
* closed to prevent being re-used. This is becasue we can't
2069
* possibly know if the connection is in a good shape or not now. */
2070
conn->bits.close = TRUE;
2072
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
2073
/* if we failed anywhere, we must clean up the secondary socket if
2075
sclose(conn->sock[SECONDARYSOCKET]);
2076
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
2080
/* Always run Curl_done(), even if some of the previous calls
2081
failed, but return the previous (original) error code */
2082
res2 = Curl_done(&conn, res);
2088
/* Curl_do() failed, clean up left-overs in the done-call */
2089
res2 = Curl_done(&conn, res);
2094
* Important: 'conn' cannot be used here, since it may have been closed
2095
* in 'Curl_done' or other functions.
2098
if((res == CURLE_OK) && newurl) {
2099
res = Curl_follow(data, newurl);
2100
if(CURLE_OK == res) {
2106
break; /* it only reaches here when this shouldn't loop */
2108
} while(1); /* loop if Location: */
2113
/* run post-transfer uncondionally, but don't clobber the return code if
2114
we already have an error code recorder */
2115
res2 = Curl_posttransfer(data);
2123
* Curl_Transfer() is called to setup some basic properties for the upcoming
2127
Curl_Transfer(struct connectdata *c_conn, /* connection data */
2128
int sockindex, /* socket index to read from or -1 */
2129
curl_off_t size, /* -1 if unknown at this point */
2130
bool getheader, /* TRUE if header parsing is wanted */
2131
curl_off_t *bytecountp, /* return number of bytes read or NULL */
2132
int writesockindex, /* socket index to write to, it may very
2133
well be the same we read from. -1
2135
curl_off_t *writecountp /* return number of bytes written or
2139
struct connectdata *conn = (struct connectdata *)c_conn;
2141
return CURLE_BAD_FUNCTION_ARGUMENT;
2143
curlassert((sockindex <= 1) && (sockindex >= -1));
2145
/* now copy all input parameters */
2146
conn->sockfd = sockindex==-1?
2147
CURL_SOCKET_BAD:conn->sock[sockindex];
2149
conn->bits.getheader = getheader;
2150
conn->bytecountp = bytecountp;
2151
conn->writesockfd = writesockindex==-1?
2152
CURL_SOCKET_BAD:conn->sock[writesockindex];
2153
conn->writebytecountp = writecountp;
2160
* Curl_pretransfersec() prepares the secondary connection (used for 3rd party
2163
CURLcode Curl_pretransfersec(struct connectdata *conn)
2166
struct SessionHandle *data = conn->data;
2167
struct connectdata *sec_conn = NULL; /* secondary connection */
2169
/* update data with source host options */
2170
char *url = aprintf( "%s://%s/", conn->protostr, data->set.source_host);
2173
return CURLE_OUT_OF_MEMORY;
2175
if(data->change.url_alloc)
2176
free(data->change.url);
2178
data->change.url_alloc = TRUE;
2179
data->change.url = url;
2180
data->set.ftpport = data->set.source_port;
2181
data->set.userpwd = data->set.source_userpwd;
2183
/* secondary connection */
2184
status = Curl_connect_host(data, &sec_conn);
2185
if(CURLE_OK == status) {
2186
sec_conn->data = data;
2187
conn->sec_conn = sec_conn;