~ubuntu-branches/ubuntu/warty/curl/warty-security

« back to all changes in this revision

Viewing changes to lib/transfer.c

  • Committer: Bazaar Package Importer
  • Author(s): Domenico Andreoli
  • Date: 2004-06-04 19:09:25 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040604190925-wy048bp31320r2z6
Tags: 7.12.0.is.7.11.2-1
* Reverted to version 7.11.2 (closes: #252348).
* Disabled support for libidn (closes: #252367). This is to leave
  curl in unstable as much similar as possible to the one in testing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
 
1
/***************************************************************************
2
2
 *                                  _   _ ____  _     
3
3
 *  Project                     ___| | | |  _ \| |    
4
4
 *                             / __| | | | |_) | |    
5
5
 *                            | (__| |_| |  _ <| |___ 
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
9
 
 *
10
 
 * In order to be useful for every potential user, curl and libcurl are
11
 
 * dual-licensed under the MPL and the MIT/X-derivate licenses.
12
 
 *
 
8
 * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
 
9
 *
 
10
 * This software is licensed as described in the file COPYING, which
 
11
 * you should have received as part of this distribution. The terms
 
12
 * are also available at http://curl.haxx.se/docs/copyright.html.
 
13
 * 
13
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
14
15
 * copies of the Software, and permit persons to whom the Software is
15
 
 * furnished to do so, under the terms of the MPL or the MIT/X-derivate
16
 
 * licenses. You may pick one of these licenses.
 
16
 * furnished to do so, under the terms of the COPYING file.
17
17
 *
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.84 2002/02/28 15:13:35 bagder Exp $
22
 
 *****************************************************************************/
 
21
 * $Id: transfer.c,v 1.221 2004/04/22 20:07:41 bagder Exp $
 
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
25
25
 
29
29
#include <stdarg.h>
30
30
#include <stdlib.h>
31
31
#include <ctype.h>
 
32
#ifdef HAVE_SYS_TYPES_H
32
33
#include <sys/types.h>
 
34
#endif
33
35
#include <sys/stat.h>
34
36
 
35
37
#include <errno.h>
36
38
 
 
39
#include "strtoofft.h"
37
40
#include "strequal.h"
38
41
 
39
42
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
40
 
#include <winsock.h>
41
43
#include <time.h>
42
44
#include <io.h>
43
45
#else
44
46
#ifdef HAVE_SYS_SOCKET_H
45
47
#include <sys/socket.h>
46
48
#endif
 
49
#ifdef HAVE_NETINET_IN_H
47
50
#include <netinet/in.h>
 
51
#endif
48
52
#include <sys/time.h>
49
 
#include <sys/resource.h>
50
53
#ifdef HAVE_UNISTD_H
51
54
#include <unistd.h>
52
55
#endif
57
60
#ifdef HAVE_NET_IF_H
58
61
#include <net/if.h>
59
62
#endif
 
63
#ifdef HAVE_SYS_IOCTL_H
60
64
#include <sys/ioctl.h>
 
65
#endif
61
66
#include <signal.h>
62
67
 
63
68
#ifdef HAVE_SYS_PARAM_H
82
87
#include <curl/types.h>
83
88
#include "netrc.h"
84
89
 
 
90
#include "content_encoding.h"
85
91
#include "hostip.h"
86
92
#include "transfer.h"
87
93
#include "sendf.h"
88
94
#include "speedcheck.h"
89
 
#include "getpass.h"
90
95
#include "progress.h"
91
96
#include "getdate.h"
92
97
#include "http.h"
93
98
#include "url.h"
94
99
#include "getinfo.h"
95
100
#include "ssluse.h"
 
101
#include "http_digest.h"
 
102
#include "http_ntlm.h"
 
103
#include "http_negotiate.h"
 
104
#include "share.h"
96
105
 
97
106
#define _MPRINTF_REPLACE /* use our functions only */
98
107
#include <curl/mprintf.h>
99
108
 
100
109
/* The last #include file should be: */
101
 
#ifdef MALLOCDEBUG
 
110
#ifdef CURLDEBUG
102
111
#include "memdebug.h"
103
112
#endif
104
113
 
105
 
#ifndef min
106
 
#define min(a, b)   ((a) < (b) ? (a) : (b))
107
 
#endif
 
114
#define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */
108
115
 
109
116
enum {
110
117
  KEEP_NONE,
112
119
  KEEP_WRITE
113
120
};
114
121
 
115
 
 
116
 
/*
117
 
 * compareheader()
 
122
/* We keep this static and global since this is read-only and NEVER
 
123
   changed. It should just remain a blanked-out timeout value. */
 
124
static struct timeval notimeout={0,0};
 
125
 
 
126
/*
 
127
 * This function will call the read callback to fill our buffer with data
 
128
 * to upload.
 
129
 */
 
130
static int fillbuffer(struct connectdata *conn,
 
131
                      int bytes)
 
132
{
 
133
  int buffersize = bytes;
 
134
  int nread;
 
135
 
 
136
  if(conn->bits.upload_chunky) {
 
137
    /* if chunked Transfer-Encoding */
 
138
    buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
 
139
    conn->upload_fromhere += 10; /* 32bit hex + CRLF */
 
140
  }
 
141
  
 
142
  nread = conn->fread(conn->upload_fromhere, 1,
 
143
                      buffersize, conn->fread_in);
 
144
          
 
145
  if(!conn->bits.forbidchunk && conn->bits.upload_chunky) {
 
146
    /* if chunked Transfer-Encoding */
 
147
    char hexbuffer[11];
 
148
    int hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
 
149
                          "%x\r\n", nread);
 
150
    /* move buffer pointer */
 
151
    conn->upload_fromhere -= hexlen;
 
152
    nread += hexlen;
 
153
 
 
154
    /* copy the prefix to the buffer */
 
155
    memcpy(conn->upload_fromhere, hexbuffer, hexlen);
 
156
 
 
157
    /* always append CRLF to the data */
 
158
    memcpy(conn->upload_fromhere + nread, "\r\n", 2);
 
159
 
 
160
    if((nread - hexlen) == 0) {
 
161
      /* mark this as done once this chunk is transfered */
 
162
      conn->keep.upload_done = TRUE;
 
163
    }
 
164
 
 
165
    nread+=2; /* for the added CRLF */
 
166
  }
 
167
  return nread;
 
168
}
 
169
 
 
170
/*
 
171
 * checkhttpprefix()
118
172
 *
119
 
 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
120
 
 * Pass headers WITH the colon.
 
173
 * Returns TRUE if member of the list matches prefix of string
121
174
 */
122
175
static bool
123
 
compareheader(char *headerline, /* line to check */
124
 
              const char *header,     /* header keyword _with_ colon */
125
 
              const char *content)    /* content string to find */
 
176
checkhttpprefix(struct SessionHandle *data,
 
177
                const char *s)
126
178
{
127
 
  /* RFC2616, section 4.2 says: "Each header field consists of a name followed
128
 
   * by a colon (":") and the field value. Field names are case-insensitive.
129
 
   * The field value MAY be preceded by any amount of LWS, though a single SP
130
 
   * is preferred." */
131
 
 
132
 
  size_t hlen = strlen(header);
133
 
  size_t clen;
134
 
  size_t len;
135
 
  char *start;
136
 
  char *end;
137
 
 
138
 
  if(!strnequal(headerline, header, hlen))
139
 
    return FALSE; /* doesn't start with header */
140
 
 
141
 
  /* pass the header */
142
 
  start = &headerline[hlen];
143
 
 
144
 
  /* pass all white spaces */
145
 
  while(*start && isspace((int)*start))
146
 
    start++;
147
 
 
148
 
  /* find the end of the header line */
149
 
  end = strchr(start, '\r'); /* lines end with CRLF */
150
 
  if(!end) {
151
 
    /* in case there's a non-standard compliant line here */
152
 
    end = strchr(start, '\n');
153
 
 
154
 
    if(!end)
155
 
      /* hm, there's no line ending here, return false and bail out! */
156
 
      return FALSE;
157
 
  }
158
 
 
159
 
  len = end-start; /* length of the content part of the input line */
160
 
  clen = strlen(content); /* length of the word to find */
161
 
 
162
 
  /* find the content string in the rest of the line */
163
 
  for(;len>=clen;len--, start++) {
164
 
    if(strnequal(start, content, clen))
165
 
      return TRUE; /* match! */
166
 
  }
167
 
 
168
 
  return FALSE; /* no match */
 
179
  struct curl_slist *head = data->set.http200aliases;
 
180
 
 
181
  while (head) {
 
182
    if (checkprefix(head->data, s))
 
183
      return TRUE;
 
184
    head = head->next;
 
185
  }
 
186
 
 
187
  if(checkprefix("HTTP/", s))
 
188
    return TRUE;
 
189
 
 
190
  return FALSE;
169
191
}
170
192
 
171
193
CURLcode Curl_readwrite(struct connectdata *conn,
173
195
{
174
196
  struct Curl_transfer_keeper *k = &conn->keep;
175
197
  struct SessionHandle *data = conn->data;
176
 
  int result;
 
198
  CURLcode result;
177
199
  ssize_t nread; /* number of bytes read */
178
200
  int didwhat=0;
 
201
  
 
202
  /* These two are used only if no other select() or _fdset() have been
 
203
     invoked before this. This typicly happens if you use the multi interface
 
204
     and call curl_multi_perform() without calling curl_multi_fdset()
 
205
     first. */
 
206
  fd_set extrareadfd;
 
207
  fd_set extrawritefd;
 
208
 
 
209
  fd_set *readfdp = k->readfdp;
 
210
  fd_set *writefdp = k->writefdp;
 
211
  curl_off_t contentlength;
 
212
  
 
213
  if((k->keepon & KEEP_READ) && !readfdp) {
 
214
    /* reading is requested, but no socket descriptor pointer was set */
 
215
    FD_ZERO(&extrareadfd);
 
216
    FD_SET(conn->sockfd, &extrareadfd);
 
217
    readfdp = &extrareadfd;
 
218
 
 
219
    /* no write, no exceptions, no timeout */
 
220
    select(conn->sockfd+1, readfdp, NULL, NULL, &notimeout);
 
221
  }
 
222
  if((k->keepon & KEEP_WRITE) && !writefdp) {
 
223
    /* writing is requested, but no socket descriptor pointer was set */
 
224
    FD_ZERO(&extrawritefd);
 
225
    FD_SET(conn->writesockfd, &extrawritefd);
 
226
    writefdp = &extrawritefd;
 
227
 
 
228
    /* no read, no exceptions, no timeout */
 
229
    select(conn->writesockfd+1, NULL, writefdp, NULL, &notimeout);
 
230
  }
179
231
 
180
232
  do {
 
233
    /* If we still have reading to do, we check if we have a readable
 
234
       socket. Sometimes the reafdp is NULL, if no fd_set was done using
 
235
       the multi interface and then we can do nothing but to attempt a
 
236
       read to be sure. */
181
237
    if((k->keepon & KEEP_READ) &&
182
 
       FD_ISSET(conn->sockfd, &k->readfd)) {
183
 
 
184
 
      /* read! */
185
 
      result = Curl_read(conn, conn->sockfd, k->buf,
186
 
                         BUFSIZE -1, &nread);
187
 
 
188
 
      if(0>result)
189
 
        break; /* get out of loop */
190
 
      if(result>0)
191
 
        return result;
192
 
 
193
 
      if ((k->bytecount == 0) && (k->writebytecount == 0))
194
 
        Curl_pgrsTime(data, TIMER_STARTTRANSFER);
195
 
 
196
 
      didwhat |= KEEP_READ;
197
 
 
198
 
      /* NULL terminate, allowing string ops to be used */
199
 
      if (0 < nread)
200
 
        k->buf[nread] = 0;
201
 
 
202
 
      /* if we receive 0 or less here, the server closed the connection and
203
 
         we bail out from this! */
204
 
      else if (0 >= nread) {
205
 
        k->keepon &= ~KEEP_READ;
206
 
        FD_ZERO(&k->rkeepfd);
207
 
        break;
208
 
      }
209
 
 
210
 
      /* Default buffer to use when we write the buffer, it may be changed
211
 
         in the flow below before the actual storing is done. */
212
 
      k->str = k->buf;
213
 
 
214
 
      /* Since this is a two-state thing, we check if we are parsing
215
 
         headers at the moment or not. */          
216
 
      if (k->header) {
217
 
        /* we are in parse-the-header-mode */
218
 
 
219
 
        /* header line within buffer loop */
220
 
        do {
221
 
          int hbufp_index;
222
 
              
223
 
          /* str_start is start of line within buf */
224
 
          k->str_start = k->str;
225
 
              
226
 
          k->end_ptr = strchr (k->str_start, '\n');
227
 
              
228
 
          if (!k->end_ptr) {
229
 
            /* no more complete header lines within buffer */
230
 
            /* copy what is remaining into headerbuff */
231
 
            int str_length = (int)strlen(k->str);
 
238
       (!readfdp || FD_ISSET(conn->sockfd, readfdp))) {
 
239
 
 
240
      bool readdone = TRUE;
 
241
 
 
242
      /* This is where we loop until we have read everything there is to
 
243
         read or we get a EWOULDBLOCK */
 
244
      do {
 
245
        int buffersize = data->set.buffer_size?
 
246
          data->set.buffer_size:BUFSIZE -1;
 
247
 
 
248
        /* receive data from the network! */
 
249
        int readrc = Curl_read(conn, conn->sockfd, k->buf, buffersize, &nread);
 
250
 
 
251
        /* subzero, this would've blocked */
 
252
        if(0>readrc)
 
253
          break; /* get out of loop */
 
254
 
 
255
        /* get the CURLcode from the int */
 
256
        result = (CURLcode)readrc;
 
257
 
 
258
        if(result>0)
 
259
          return result;
 
260
 
 
261
        if ((k->bytecount == 0) && (k->writebytecount == 0)) {
 
262
          Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 
263
          if(k->wait100_after_headers)
 
264
            /* set time stamp to compare with when waiting for the 100 */
 
265
            k->start100 = Curl_tvnow();
 
266
        }
 
267
 
 
268
        didwhat |= KEEP_READ;
 
269
 
 
270
        /* NULL terminate, allowing string ops to be used */
 
271
        if (0 < nread)
 
272
          k->buf[nread] = 0;
 
273
 
 
274
        /* if we receive 0 or less here, the server closed the connection and
 
275
           we bail out from this! */
 
276
        else if (0 >= nread) {
 
277
          k->keepon &= ~KEEP_READ;
 
278
          FD_ZERO(&k->rkeepfd);
 
279
          readdone = TRUE;
 
280
          break;
 
281
        }
 
282
 
 
283
        /* Default buffer to use when we write the buffer, it may be changed
 
284
           in the flow below before the actual storing is done. */
 
285
        k->str = k->buf;
 
286
 
 
287
        /* Since this is a two-state thing, we check if we are parsing
 
288
           headers at the moment or not. */          
 
289
        if (k->header) {
 
290
          /* we are in parse-the-header-mode */
 
291
          bool stop_reading = FALSE;
 
292
 
 
293
          /* header line within buffer loop */
 
294
          do {
 
295
            int hbufp_index;
 
296
            int rest_length;
 
297
            int full_length;
 
298
            int writetype;
 
299
              
 
300
            /* str_start is start of line within buf */
 
301
            k->str_start = k->str;
 
302
              
 
303
            k->end_ptr = strchr (k->str_start, '\n');
 
304
              
 
305
            if (!k->end_ptr) {
 
306
              /* Not a complete header line within buffer, append the data to
 
307
                 the end of the headerbuff. */
 
308
 
 
309
              if (k->hbuflen + nread >= data->state.headersize) {
 
310
                /* We enlarge the header buffer as it is too small */
 
311
                char *newbuff;
 
312
                long newsize=CURLMAX((k->hbuflen+nread)*3/2,
 
313
                                     data->state.headersize*2);
 
314
                hbufp_index = k->hbufp - data->state.headerbuff;
 
315
                newbuff = (char *)realloc(data->state.headerbuff, newsize);
 
316
                if(!newbuff) {
 
317
                  failf (data, "Failed to alloc memory for big header!");
 
318
                  return CURLE_OUT_OF_MEMORY;
 
319
                }
 
320
                data->state.headersize=newsize;
 
321
                data->state.headerbuff = newbuff;
 
322
                k->hbufp = data->state.headerbuff + hbufp_index;
 
323
              }
 
324
              memcpy(k->hbufp, k->str, nread);
 
325
              k->hbufp += nread;
 
326
              k->hbuflen += nread;
 
327
              if (!k->headerline && (k->hbuflen>5)) {
 
328
                /* make a first check that this looks like a HTTP header */
 
329
                if(!checkhttpprefix(data, data->state.headerbuff)) {
 
330
                  /* this is not the beginning of a HTTP first header line */
 
331
                  k->header = FALSE;
 
332
                  k->badheader = HEADER_ALLBAD;
 
333
                  break;
 
334
                }
 
335
              }
 
336
 
 
337
              break; /* read more and try again */
 
338
            }
 
339
 
 
340
            /* decrease the size of the remaining (supposed) header line */
 
341
            rest_length = (k->end_ptr - k->str)+1;
 
342
            nread -= rest_length; 
 
343
 
 
344
            k->str = k->end_ptr + 1; /* move past new line */
 
345
 
 
346
            full_length = k->str - k->str_start;
232
347
 
233
348
            /*
234
 
             * We enlarge the header buffer if it seems to be too
235
 
             * smallish
 
349
             * We're about to copy a chunk of data to the end of the
 
350
             * already received header. We make sure that the full string
 
351
             * fit in the allocated header buffer, or else we enlarge 
 
352
             * it.
236
353
             */
237
 
            if (k->hbuflen + (int)str_length >=
 
354
            if (k->hbuflen + full_length >=
238
355
                data->state.headersize) {
239
356
              char *newbuff;
240
 
              long newsize=MAX((k->hbuflen+str_length)*3/2,
241
 
                               data->state.headersize*2);
 
357
              long newsize=CURLMAX((k->hbuflen+full_length)*3/2,
 
358
                                   data->state.headersize*2);
242
359
              hbufp_index = k->hbufp - data->state.headerbuff;
243
360
              newbuff = (char *)realloc(data->state.headerbuff, newsize);
244
361
              if(!newbuff) {
245
362
                failf (data, "Failed to alloc memory for big header!");
246
 
                return CURLE_READ_ERROR;
 
363
                return CURLE_OUT_OF_MEMORY;
247
364
              }
248
 
              data->state.headersize=newsize;
 
365
              data->state.headersize= newsize;
249
366
              data->state.headerbuff = newbuff;
250
367
              k->hbufp = data->state.headerbuff + hbufp_index;
251
368
            }
252
 
            strcpy (k->hbufp, k->str);
253
 
            k->hbufp += strlen (k->str);
254
 
            k->hbuflen += strlen (k->str);
255
 
            break;              /* read more and try again */
256
 
          }
257
 
 
258
 
          k->str = k->end_ptr + 1; /* move past new line */
259
 
 
260
 
          /*
261
 
           * We're about to copy a chunk of data to the end of the
262
 
           * already received header. We make sure that the full string
263
 
           * fit in the allocated header buffer, or else we enlarge 
264
 
           * it.
265
 
           */
266
 
          if (k->hbuflen + (k->str - k->str_start) >=
267
 
              data->state.headersize) {
268
 
            char *newbuff;
269
 
            long newsize=MAX((k->hbuflen+
270
 
                              (k->str-k->str_start))*3/2,
271
 
                             data->state.headersize*2);
272
 
            hbufp_index = k->hbufp - data->state.headerbuff;
273
 
            newbuff = (char *)realloc(data->state.headerbuff, newsize);
274
 
            if(!newbuff) {
275
 
              failf (data, "Failed to alloc memory for big header!");
276
 
              return CURLE_READ_ERROR;
 
369
 
 
370
            /* copy to end of line */
 
371
            strncpy (k->hbufp, k->str_start, full_length);
 
372
            k->hbufp += full_length;
 
373
            k->hbuflen += full_length;
 
374
            *k->hbufp = 0;
 
375
            k->end_ptr = k->hbufp;
 
376
              
 
377
            k->p = data->state.headerbuff;
 
378
              
 
379
            /****
 
380
             * We now have a FULL header line that p points to
 
381
             *****/
 
382
 
 
383
            if(!k->headerline) {
 
384
              /* the first read header */
 
385
              if((k->hbuflen>5) &&
 
386
                 !checkhttpprefix(data, data->state.headerbuff)) {
 
387
                /* this is not the beginning of a HTTP first header line */
 
388
                k->header = FALSE;
 
389
                if(nread)
 
390
                  /* since there's more, this is a partial bad header */
 
391
                  k->badheader = HEADER_PARTHEADER;
 
392
                else {
 
393
                  /* this was all we read so its all a bad header */
 
394
                  k->badheader = HEADER_ALLBAD;
 
395
                  nread = rest_length;
 
396
                }
 
397
                break;
 
398
              }
277
399
            }
278
 
            data->state.headersize= newsize;
279
 
            data->state.headerbuff = newbuff;
280
 
            k->hbufp = data->state.headerbuff + hbufp_index;
281
 
          }
282
 
 
283
 
          /* copy to end of line */
284
 
          strncpy (k->hbufp, k->str_start, k->str - k->str_start);
285
 
          k->hbufp += k->str - k->str_start;
286
 
          k->hbuflen += k->str - k->str_start;
287
 
          *k->hbufp = 0;
288
 
              
289
 
          k->p = data->state.headerbuff;
290
 
              
291
 
          /****
292
 
           * We now have a FULL header line that p points to
293
 
           *****/
294
 
 
295
 
          if (('\n' == *k->p) || ('\r' == *k->p)) {
296
 
            /* Zero-length header line means end of headers! */
297
 
 
298
 
            if ('\r' == *k->p)
299
 
              k->p++; /* pass the \r byte */
300
 
            if ('\n' == *k->p)
301
 
              k->p++; /* pass the \n byte */
302
 
 
303
 
            if(100 == k->httpcode) {
304
 
              /*
305
 
               * we have made a HTTP PUT or POST and this is 1.1-lingo
306
 
               * that tells us that the server is OK with this and ready
307
 
               * to receive our stuff.
308
 
               * However, we'll get more headers now so we must get
309
 
               * back into the header-parsing state!
310
 
               */
311
 
              k->header = TRUE;
312
 
              k->headerline = 0; /* restart the header line counter */
313
 
              /* if we did wait for this do enable write now! */
314
 
              if (k->write_after_100_header) {
315
 
 
 
400
 
 
401
            if (('\n' == *k->p) || ('\r' == *k->p)) {
 
402
              int headerlen;
 
403
              /* Zero-length header line means end of headers! */
 
404
 
 
405
              if ('\r' == *k->p)
 
406
                k->p++; /* pass the \r byte */
 
407
              if ('\n' == *k->p)
 
408
                k->p++; /* pass the \n byte */
 
409
 
 
410
              if(100 == k->httpcode) {
 
411
                /*
 
412
                 * We have made a HTTP PUT or POST and this is 1.1-lingo
 
413
                 * that tells us that the server is OK with this and ready
 
414
                 * to receive the data.
 
415
                 * However, we'll get more headers now so we must get
 
416
                 * back into the header-parsing state!
 
417
                 */
 
418
                k->header = TRUE;
 
419
                k->headerline = 0; /* restart the header line counter */
 
420
                /* if we did wait for this do enable write now! */
 
421
                if (k->write_after_100_header) {
 
422
 
 
423
                  k->write_after_100_header = FALSE;
 
424
                  FD_SET (conn->writesockfd, &k->writefd); /* write */
 
425
                  k->keepon |= KEEP_WRITE;
 
426
                  k->wkeepfd = k->writefd;
 
427
                }
 
428
              }
 
429
              else
 
430
                k->header = FALSE; /* no more header to parse! */
 
431
 
 
432
              if (417 == k->httpcode) {
 
433
                /*
 
434
                 * we got: "417 Expectation Failed" this means:
 
435
                 * we have made a HTTP call and our Expect Header
 
436
                 * seems to cause a problem => abort the write operations
 
437
                 * (or prevent them from starting).
 
438
                 */
316
439
                k->write_after_100_header = FALSE;
317
 
                FD_SET (conn->writesockfd, &k->writefd); /* write */
318
 
                k->keepon |= KEEP_WRITE;
319
 
                k->wkeepfd = k->writefd;
320
 
              }
321
 
            }
322
 
            else
323
 
              k->header = FALSE; /* no more header to parse! */
324
 
 
325
 
            if (417 == k->httpcode) {
326
 
              /*
327
 
               * we got: "417 Expectation Failed" this means:
328
 
               * we have made a HTTP call and our Expect Header
329
 
               * seems to cause a problem => abort the write operations
330
 
               * (or prevent them from starting
331
 
               */
332
 
              k->write_after_100_header = FALSE;
333
 
              k->keepon &= ~KEEP_WRITE;
334
 
              FD_ZERO(&k->wkeepfd);
335
 
            }
336
 
 
337
 
            /* now, only output this if the header AND body are requested:
338
 
             */
339
 
            k->writetype = CLIENTWRITE_HEADER;
340
 
            if (data->set.http_include_header)
341
 
              k->writetype |= CLIENTWRITE_BODY;
342
 
 
343
 
            result = Curl_client_write(data, k->writetype,
344
 
                                       data->state.headerbuff,
345
 
                                       k->p - data->state.headerbuff);
346
 
            if(result)
347
 
              return result;
348
 
 
349
 
            data->info.header_size += k->p - data->state.headerbuff;
350
 
            conn->headerbytecount += k->p - data->state.headerbuff;
351
 
 
352
 
            if(!k->header) {
353
 
              /*
354
 
               * really end-of-headers.
355
 
               *
356
 
               * If we requested a "no body", this is a good time to get
357
 
               * out and return home.
358
 
               */
359
 
              bool stop_reading = FALSE;
360
 
 
361
 
              if(data->set.no_body)
362
 
                stop_reading = TRUE;
363
 
              else if(!conn->bits.close) {
364
 
                /* If this is not the last request before a close, we must
365
 
                   set the maximum download size to the size of the
366
 
                   expected document or else, we won't know when to stop
367
 
                   reading! */
368
 
                if(-1 != conn->size)
 
440
                k->keepon &= ~KEEP_WRITE;
 
441
                FD_ZERO(&k->wkeepfd);
 
442
              }
 
443
 
 
444
              /*
 
445
              ** Now that all of the headers have been parsed, see
 
446
              ** if we should give up and return an error.
 
447
              */
 
448
              if (Curl_http_should_fail(conn)) {
 
449
                failf (data, "The requested URL returned error: %d",
 
450
                       k->httpcode);
 
451
                return CURLE_HTTP_RETURNED_ERROR;
 
452
              }
 
453
 
 
454
              /* now, only output this if the header AND body are requested:
 
455
               */
 
456
              writetype = CLIENTWRITE_HEADER;
 
457
              if (data->set.include_header)
 
458
                writetype |= CLIENTWRITE_BODY;
 
459
 
 
460
              headerlen = k->p - data->state.headerbuff;
 
461
 
 
462
              result = Curl_client_write(data, writetype,
 
463
                                         data->state.headerbuff,
 
464
                                         headerlen);
 
465
              if(result)
 
466
                return result;
 
467
 
 
468
              data->info.header_size += headerlen;
 
469
              conn->headerbytecount += headerlen;
 
470
 
 
471
              conn->deductheadercount =
 
472
                (100 == k->httpcode)?conn->headerbytecount:0;
 
473
 
 
474
              if (conn->resume_from &&
 
475
                  !k->content_range &&
 
476
                  (data->set.httpreq==HTTPREQ_GET)) {
 
477
                if(k->httpcode == 416) {
 
478
                  /* "Requested Range Not Satisfiable" */
 
479
                  stop_reading = TRUE;
 
480
                }
 
481
                else {
 
482
                  /* we wanted to resume a download, although the server
 
483
                     doesn't seem to support this and we did this with a GET
 
484
                     (if it wasn't a GET we did a POST or PUT resume) */
 
485
                  failf (data, "HTTP server doesn't seem to support "
 
486
                         "byte ranges. Cannot resume.");
 
487
                  return CURLE_HTTP_RANGE_ERROR;
 
488
                }
 
489
              }
 
490
 
 
491
              if(!stop_reading)
 
492
                /* *auth_act() checks what authentication methods that are
 
493
                   available and decides which one (if any) to use. It will
 
494
                   set 'newurl' if an auth metod was picked. */
 
495
                Curl_http_auth_act(conn);
 
496
              
 
497
              if(!k->header) {
 
498
                /*
 
499
                 * really end-of-headers.
 
500
                 *
 
501
                 * If we requested a "no body", this is a good time to get
 
502
                 * out and return home.
 
503
                 */
 
504
                if(conn->bits.no_body)
 
505
                  stop_reading = TRUE;
 
506
                else {
 
507
                  /* If we know the expected size of this document, we set the
 
508
                     maximum download size to the size of the expected
 
509
                     document or else, we won't know when to stop reading!
 
510
 
 
511
                     Note that we set the download maximum even if we read a
 
512
                     "Connection: close" header, to make sure that
 
513
                     "Content-Length: 0" still prevents us from attempting to
 
514
                     read the (missing) response-body.
 
515
                  */
 
516
                  /* According to RFC2616 section 4.4, we MUST ignore
 
517
                     Content-Length: headers if we are now receiving data
 
518
                     using chunked Transfer-Encoding.
 
519
                  */
 
520
                  if(conn->bits.chunk)
 
521
                    conn->size=-1;
 
522
 
 
523
                }
 
524
                if(-1 != conn->size) {
 
525
                  /* We do this operation even if no_body is true, since this
 
526
                     data might be retrieved later with curl_easy_getinfo()
 
527
                     and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
 
528
 
 
529
                  Curl_pgrsSetDownloadSize(data, conn->size);
369
530
                  conn->maxdownload = conn->size;
370
 
 
 
531
                }
371
532
                /* If max download size is *zero* (nothing) we already
372
533
                   have nothing and can safely return ok now! */
373
534
                if(0 == conn->maxdownload)
374
535
                  stop_reading = TRUE;
375
536
                    
376
 
                /* What to do if the size is *not* known? */
377
 
              }
378
 
 
379
 
              if(stop_reading) {
380
 
                /* we make sure that this socket isn't read more now */
381
 
                k->keepon &= ~KEEP_READ;
382
 
                FD_ZERO(&k->rkeepfd);
383
 
                /* for a progress meter/info update before going away */
384
 
                Curl_pgrsUpdate(conn);
385
 
                return CURLE_OK;
386
 
              }
387
 
 
388
 
              break;            /* exit header line loop */
389
 
            }
390
 
 
391
 
            /* We continue reading headers, so reset the line-based
392
 
               header parsing variables hbufp && hbuflen */
393
 
            k->hbufp = data->state.headerbuff;
394
 
            k->hbuflen = 0;
395
 
            continue;
396
 
          }
397
 
 
398
 
          /*
399
 
           * Checks for special headers coming up.
400
 
           */
401
 
              
402
 
          if (!k->headerline++) {
403
 
            /* This is the first header, it MUST be the error code line
404
 
               or else we consiser this to be the body right away! */
405
 
            int httpversion_major;
406
 
            int nc=sscanf (k->p, " HTTP/%d.%d %3d",
407
 
                           &httpversion_major,
408
 
                           &k->httpversion,
409
 
                           &k->httpcode);
410
 
            if (nc==3) {
411
 
              k->httpversion += 10 * httpversion_major;
412
 
            }
413
 
            else {
414
 
              /* this is the real world, not a Nirvana
415
 
                 NCSA 1.5.x returns this crap when asked for HTTP/1.1
416
 
              */
417
 
              nc=sscanf (k->p, " HTTP %3d", &k->httpcode);
418
 
              k->httpversion = 10;
419
 
            }
420
 
 
421
 
            if (nc) {
422
 
              data->info.httpcode = k->httpcode;
423
 
              data->info.httpversion = k->httpversion;
424
 
 
425
 
              /* 404 -> URL not found! */
426
 
              if (data->set.http_fail_on_error &&
427
 
                  (k->httpcode >= 400)) {
428
 
                /* If we have been told to fail hard on HTTP-errors,
429
 
                   here is the check for that: */
430
 
                /* serious error, go home! */
431
 
                failf (data, "The requested file was not found");
432
 
                return CURLE_HTTP_NOT_FOUND;
433
 
              }
434
 
 
435
 
              if(k->httpversion == 10)
436
 
                /* Default action for HTTP/1.0 must be to close, unless
437
 
                   we get one of those fancy headers that tell us the
438
 
                   server keeps it open for us! */
439
 
                conn->bits.close = TRUE;
440
 
 
441
 
              switch(k->httpcode) {
442
 
              case 204:
443
 
                /* (quote from RFC2616, section 10.2.5): The server has
444
 
                 * fulfilled the request but does not need to return an
445
 
                 * entity-body ... The 204 response MUST NOT include a
446
 
                 * message-body, and thus is always terminated by the first
447
 
                 * empty line after the header fields. */
448
 
                /* FALLTHROUGH */
449
 
              case 304:
450
 
                /* (quote from RFC2616, section 10.3.5): The 304 response MUST
451
 
                 * NOT contain a message-body, and thus is always terminated
452
 
                 * by the first empty line after the header fields.  */
453
 
                conn->size=0;
454
 
                break;
455
 
              default:
456
 
                /* nothing */
457
 
                break;
458
 
              }
459
 
            }
460
 
            else {
461
 
              k->header = FALSE;        /* this is not a header line */
462
 
              break;
463
 
            }
464
 
          }
465
 
          /* check for Content-Length: header lines to get size */
466
 
          if (strnequal("Content-Length:", k->p, 15) &&
467
 
              sscanf (k->p+15, " %ld", &k->contentlength)) {
468
 
            conn->size = k->contentlength;
469
 
            Curl_pgrsSetDownloadSize(data, k->contentlength);
470
 
          }
471
 
          /* check for Content-Type: header lines to get the mime-type */
472
 
          else if (strnequal("Content-Type:", k->p, 13)) {
473
 
            char *start;
474
 
            char *end;
475
 
            int len;
476
 
 
477
 
            /* Find the first non-space letter */
478
 
            for(start=k->p+14;
479
 
                *start && isspace((int)*start);
480
 
                start++);
481
 
 
482
 
            /* count all non-space letters following */
483
 
            for(end=start, len=0;
484
 
                *end && !isspace((int)*end);
485
 
                end++, len++);
486
 
 
487
 
            /* allocate memory of a cloned copy */
488
 
            data->info.contenttype = malloc(len + 1);
489
 
            if (NULL == data->info.contenttype)
490
 
              return CURLE_OUT_OF_MEMORY;
491
 
 
492
 
            /* copy the content-type string */
493
 
            memcpy(data->info.contenttype, start, len);
494
 
            data->info.contenttype[len] = 0; /* zero terminate */
495
 
          }
496
 
          else if((k->httpversion == 10) &&
497
 
                  conn->bits.httpproxy &&
498
 
                  compareheader(k->p, "Proxy-Connection:", "keep-alive")) {
499
 
            /*
500
 
             * When a HTTP/1.0 reply comes when using a proxy, the
501
 
             * 'Proxy-Connection: keep-alive' line tells us the
502
 
             * connection will be kept alive for our pleasure.
503
 
             * Default action for 1.0 is to close.
504
 
             */
505
 
            conn->bits.close = FALSE; /* don't close when done */
506
 
            infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
507
 
          }
508
 
          else if((k->httpversion == 10) &&
509
 
                  compareheader(k->p, "Connection:", "keep-alive")) {
510
 
            /*
511
 
             * A HTTP/1.0 reply with the 'Connection: keep-alive' line
512
 
             * tells us the connection will be kept alive for our
513
 
             * pleasure.  Default action for 1.0 is to close.
514
 
             *
515
 
             * [RFC2068, section 19.7.1] */
516
 
            conn->bits.close = FALSE; /* don't close when done */
517
 
            infof(data, "HTTP/1.0 connection set to keep alive!\n");
518
 
          }
519
 
          else if (compareheader(k->p, "Connection:", "close")) {
520
 
            /*
521
 
             * [RFC 2616, section 8.1.2.1]
522
 
             * "Connection: close" is HTTP/1.1 language and means that
523
 
             * the connection will close when this request has been
524
 
             * served.
525
 
             */
526
 
            conn->bits.close = TRUE; /* close when done */
527
 
          }
528
 
          else if (compareheader(k->p, "Transfer-Encoding:", "chunked")) {
529
 
            /*
530
 
             * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
531
 
             * means that the server will send a series of "chunks". Each
532
 
             * chunk starts with line with info (including size of the
533
 
             * coming block) (terminated with CRLF), then a block of data
534
 
             * with the previously mentioned size. There can be any amount
535
 
             * of chunks, and a chunk-data set to zero signals the
536
 
             * end-of-chunks. */
537
 
            conn->bits.chunk = TRUE; /* chunks coming our way */
538
 
 
539
 
            /* init our chunky engine */
540
 
            Curl_httpchunk_init(conn);
541
 
          }
542
 
          else if (strnequal("Content-Range:", k->p, 14)) {
543
 
            if (sscanf (k->p+14, " bytes %d-", &k->offset) ||
544
 
                sscanf (k->p+14, " bytes: %d-", &k->offset)) {
545
 
              /* This second format was added August 1st 2000 by Igor
 
537
                if(stop_reading) {
 
538
                  /* we make sure that this socket isn't read more now */
 
539
                  k->keepon &= ~KEEP_READ;
 
540
                  FD_ZERO(&k->rkeepfd);
 
541
                }
 
542
 
 
543
                break;          /* exit header line loop */
 
544
              }
 
545
 
 
546
              /* We continue reading headers, so reset the line-based
 
547
                 header parsing variables hbufp && hbuflen */
 
548
              k->hbufp = data->state.headerbuff;
 
549
              k->hbuflen = 0;
 
550
              continue;
 
551
            }
 
552
 
 
553
            /*
 
554
             * Checks for special headers coming up.
 
555
             */
 
556
              
 
557
            if (!k->headerline++) {
 
558
              /* This is the first header, it MUST be the error code line
 
559
                 or else we consiser this to be the body right away! */
 
560
              int httpversion_major;
 
561
              int nc=sscanf(k->p, " HTTP/%d.%d %3d",
 
562
                            &httpversion_major,
 
563
                            &k->httpversion,
 
564
                            &k->httpcode);
 
565
              if (nc==3) {
 
566
                k->httpversion += 10 * httpversion_major;
 
567
              }
 
568
              else {
 
569
                /* this is the real world, not a Nirvana
 
570
                   NCSA 1.5.x returns this crap when asked for HTTP/1.1
 
571
                */
 
572
                nc=sscanf(k->p, " HTTP %3d", &k->httpcode);
 
573
                k->httpversion = 10;
 
574
               
 
575
               /* If user has set option HTTP200ALIASES,
 
576
                  compare header line against list of aliases
 
577
               */
 
578
                if (!nc) {
 
579
                  if (checkhttpprefix(data, k->p)) {
 
580
                    nc = 1;
 
581
                    k->httpcode = 200;
 
582
                    k->httpversion =
 
583
                      (data->set.httpversion==CURL_HTTP_VERSION_1_0)? 10 : 11;
 
584
                  }
 
585
                }
 
586
              }
 
587
 
 
588
              if (nc) {
 
589
                data->info.httpcode = k->httpcode;
 
590
                data->info.httpversion = k->httpversion;
 
591
 
 
592
                /*
 
593
                ** This code executes as part of processing
 
594
                ** the header.  As a result, it's not
 
595
                ** totally clear how to interpret the
 
596
                ** response code yet as that depends on what
 
597
                ** other headers may be present.  401 and
 
598
                ** 407 may be errors, but may be OK
 
599
                ** depending on how authentication is
 
600
                ** working.  Other codes are definitely
 
601
                ** errors, so give up here.
 
602
                */
 
603
                if (data->set.http_fail_on_error &&
 
604
                    (k->httpcode >= 400) &&
 
605
                    (k->httpcode != 401) &&
 
606
                    (k->httpcode != 407)) {
 
607
                  /* If we have been told to fail hard on HTTP-errors,
 
608
                     here is the check for that: */
 
609
                  /* serious error, go home! */
 
610
                  failf (data, "The requested URL returned error: %d",
 
611
                         k->httpcode);
 
612
                  return CURLE_HTTP_RETURNED_ERROR;
 
613
                }
 
614
 
 
615
                if(k->httpversion == 10)
 
616
                  /* Default action for HTTP/1.0 must be to close, unless
 
617
                     we get one of those fancy headers that tell us the
 
618
                     server keeps it open for us! */
 
619
                  conn->bits.close = TRUE;
 
620
 
 
621
                switch(k->httpcode) {
 
622
                case 204:
 
623
                  /* (quote from RFC2616, section 10.2.5): The server has
 
624
                   * fulfilled the request but does not need to return an
 
625
                   * entity-body ... The 204 response MUST NOT include a
 
626
                   * message-body, and thus is always terminated by the first
 
627
                   * empty line after the header fields. */
 
628
                  /* FALLTHROUGH */
 
629
                case 416: /* Requested Range Not Satisfiable, it has the
 
630
                             Content-Length: set as the "real" document but no
 
631
                             actual response is sent. */
 
632
                case 304:
 
633
                  /* (quote from RFC2616, section 10.3.5): The 304 response
 
634
                   * MUST NOT contain a message-body, and thus is always
 
635
                   * terminated by the first empty line after the header
 
636
                   * fields.  */
 
637
                  conn->size=0;
 
638
                  conn->maxdownload=0;
 
639
                  break;
 
640
                default:
 
641
                  /* nothing */
 
642
                  break;
 
643
                }
 
644
              }
 
645
              else {
 
646
                k->header = FALSE;   /* this is not a header line */
 
647
                break;
 
648
              }
 
649
            }
 
650
 
 
651
            /* Check for Content-Length: header lines to get size. Ignore
 
652
               the header completely if we get a 416 response as then we're
 
653
               resuming a document that we don't get, and this header contains 
 
654
               info about the true size of the document we didn't get now. */
 
655
            if ((k->httpcode != 416) &&
 
656
                checkprefix("Content-Length:", k->p)) {
 
657
              contentlength = curlx_strtoofft(k->p+15, NULL, 10);
 
658
              if (data->set.max_filesize && contentlength > 
 
659
                  data->set.max_filesize) {
 
660
                failf(data, "Maximum file size exceeded");
 
661
                return CURLE_FILESIZE_EXCEEDED;
 
662
              }
 
663
              conn->size = contentlength;
 
664
            }
 
665
            /* check for Content-Type: header lines to get the mime-type */
 
666
            else if (checkprefix("Content-Type:", k->p)) {
 
667
              char *start;
 
668
              char *end;
 
669
              int len;
 
670
              
 
671
              /* Find the first non-space letter */
 
672
              for(start=k->p+13;
 
673
                  *start && isspace((int)*start);
 
674
                  start++);
 
675
 
 
676
              end = strchr(start, '\r');
 
677
              if(!end)
 
678
                end = strchr(start, '\n');
 
679
 
 
680
              if(end) {
 
681
                /* skip all trailing space letters */
 
682
                for(; isspace((int)*end) && (end > start); end--);
 
683
 
 
684
                /* get length of the type */
 
685
                len = end-start+1;
 
686
              
 
687
                /* allocate memory of a cloned copy */
 
688
                Curl_safefree(data->info.contenttype);
 
689
              
 
690
                data->info.contenttype = malloc(len + 1);
 
691
                if (NULL == data->info.contenttype)
 
692
                  return CURLE_OUT_OF_MEMORY;
 
693
 
 
694
                /* copy the content-type string */
 
695
                memcpy(data->info.contenttype, start, len);
 
696
                data->info.contenttype[len] = 0; /* zero terminate */
 
697
              }
 
698
            }
 
699
            else if((k->httpversion == 10) &&
 
700
                    conn->bits.httpproxy &&
 
701
                    Curl_compareheader(k->p,
 
702
                                       "Proxy-Connection:", "keep-alive")) {
 
703
              /*
 
704
               * When a HTTP/1.0 reply comes when using a proxy, the
 
705
               * 'Proxy-Connection: keep-alive' line tells us the
 
706
               * connection will be kept alive for our pleasure.
 
707
               * Default action for 1.0 is to close.
 
708
               */
 
709
              conn->bits.close = FALSE; /* don't close when done */
 
710
              infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
 
711
            }
 
712
            else if((k->httpversion == 10) &&
 
713
                    Curl_compareheader(k->p, "Connection:", "keep-alive")) {
 
714
              /*
 
715
               * A HTTP/1.0 reply with the 'Connection: keep-alive' line
 
716
               * tells us the connection will be kept alive for our
 
717
               * pleasure.  Default action for 1.0 is to close.
 
718
               *
 
719
               * [RFC2068, section 19.7.1] */
 
720
              conn->bits.close = FALSE; /* don't close when done */
 
721
              infof(data, "HTTP/1.0 connection set to keep alive!\n");
 
722
            }
 
723
            else if (Curl_compareheader(k->p, "Connection:", "close")) {
 
724
              /*
 
725
               * [RFC 2616, section 8.1.2.1]
 
726
               * "Connection: close" is HTTP/1.1 language and means that
 
727
               * the connection will close when this request has been
 
728
               * served.
 
729
               */
 
730
              conn->bits.close = TRUE; /* close when done */
 
731
            }
 
732
            else if (Curl_compareheader(k->p,
 
733
                                        "Transfer-Encoding:", "chunked")) {
 
734
              /*
 
735
               * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
 
736
               * means that the server will send a series of "chunks". Each
 
737
               * chunk starts with line with info (including size of the
 
738
               * coming block) (terminated with CRLF), then a block of data
 
739
               * with the previously mentioned size. There can be any amount
 
740
               * of chunks, and a chunk-data set to zero signals the
 
741
               * end-of-chunks. */
 
742
              conn->bits.chunk = TRUE; /* chunks coming our way */
 
743
 
 
744
              /* init our chunky engine */
 
745
              Curl_httpchunk_init(conn);
 
746
            }
 
747
            else if (checkprefix("Content-Encoding:", k->p) &&
 
748
                     data->set.encoding) {
 
749
              /*
 
750
               * Process Content-Encoding. Look for the values: identity,
 
751
               * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
 
752
               * x-compress are the same as gzip and compress. (Sec 3.5 RFC
 
753
               * 2616). zlib cannot handle compress.  However, errors are
 
754
               * handled further down when the response body is processed
 
755
               */
 
756
              char *start;
 
757
 
 
758
              /* Find the first non-space letter */
 
759
              for(start=k->p+17;
 
760
                  *start && isspace((int)*start);
 
761
                  start++);
 
762
 
 
763
              /* Record the content-encoding for later use */
 
764
              if (checkprefix("identity", start))
 
765
                k->content_encoding = IDENTITY;
 
766
              else if (checkprefix("deflate", start))
 
767
                k->content_encoding = DEFLATE;
 
768
              else if (checkprefix("gzip", start) 
 
769
                       || checkprefix("x-gzip", start))
 
770
                k->content_encoding = GZIP;
 
771
              else if (checkprefix("compress", start) 
 
772
                       || checkprefix("x-compress", start))
 
773
                k->content_encoding = COMPRESS;
 
774
            }
 
775
            else if (Curl_compareheader(k->p, "Content-Range:", "bytes")) {
 
776
              /* Content-Range: bytes [num]-
 
777
                 Content-Range: bytes: [num]-
 
778
 
 
779
                 The second format was added August 1st 2000 by Igor
546
780
                 Khristophorov since Sun's webserver JavaWebServer/1.1.1
547
781
                 obviously sends the header this way! :-( */
548
 
              if (conn->resume_from == k->offset) {
 
782
 
 
783
              char *ptr = strstr(k->p, "bytes");
 
784
              ptr+=5;
 
785
 
 
786
              if(*ptr == ':')
 
787
                /* stupid colon skip */
 
788
                ptr++;
 
789
 
 
790
              k->offset = curlx_strtoofft(ptr, NULL, 10);
 
791
              
 
792
              if (conn->resume_from == k->offset)
549
793
                /* we asked for a resume and we got it */
550
794
                k->content_range = TRUE;
551
 
              }
552
 
            }
553
 
          }
554
 
          else if(data->cookies &&
555
 
                  strnequal("Set-Cookie:", k->p, 11)) {
556
 
            Curl_cookie_add(data->cookies, TRUE, k->p+12, conn->name);
557
 
          }
558
 
          else if(strnequal("Last-Modified:", k->p,
559
 
                            strlen("Last-Modified:")) &&
560
 
                  (data->set.timecondition || data->set.get_filetime) ) {
561
 
            time_t secs=time(NULL);
562
 
            k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
563
 
                                        &secs);
564
 
            if(data->set.get_filetime)
565
 
              data->info.filetime = k->timeofdoc;
566
 
          }
567
 
          else if ((k->httpcode >= 300 && k->httpcode < 400) &&
568
 
                   (data->set.http_follow_location) &&
569
 
                   strnequal("Location:", k->p, 9)) {
570
 
            /* this is the URL that the server advices us to get instead */
571
 
            char *ptr;
572
 
            char *start=k->p;
573
 
            char backup;
574
 
 
575
 
            start += 9; /* pass "Location:" */
576
 
 
577
 
            /* Skip spaces and tabs. We do this to support multiple
578
 
               white spaces after the "Location:" keyword. */
579
 
            while(*start && isspace((int)*start ))
580
 
              start++;
581
 
            ptr = start; /* start scanning here */
582
 
 
583
 
            /* scan through the string to find the end */
584
 
            while(*ptr && !isspace((int)*ptr))
585
 
              ptr++;
586
 
            backup = *ptr; /* store the ending letter */
587
 
            *ptr = '\0';   /* zero terminate */
588
 
            conn->newurl = strdup(start); /* clone string */
589
 
            *ptr = backup; /* restore ending letter */
590
 
          }
591
 
 
592
 
          /*
593
 
           * End of header-checks. Write them to the client.
594
 
           */
595
 
 
596
 
          k->writetype = CLIENTWRITE_HEADER;
597
 
          if (data->set.http_include_header)
598
 
            k->writetype |= CLIENTWRITE_BODY;
599
 
 
600
 
          result = Curl_client_write(data, k->writetype, k->p,
601
 
                                     k->hbuflen);
602
 
          if(result)
603
 
            return result;
604
 
 
605
 
          data->info.header_size += k->hbuflen;
606
 
          conn->headerbytecount += k->hbuflen;
 
795
            }
 
796
            else if(data->cookies &&
 
797
                    checkprefix("Set-Cookie:", k->p)) {
 
798
              Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
 
799
                              CURL_LOCK_ACCESS_SINGLE);
 
800
              Curl_cookie_add(data,
 
801
                              data->cookies, TRUE, k->p+11,
 
802
                              /* If there is a custom-set Host: name, use it
 
803
                                 here, or else use real peer host name. */
 
804
                              conn->allocptr.cookiehost?
 
805
                              conn->allocptr.cookiehost:conn->hostname,
 
806
                              conn->path);
 
807
              Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
 
808
            }
 
809
            else if(checkprefix("Last-Modified:", k->p) &&
 
810
                    (data->set.timecondition || data->set.get_filetime) ) {
 
811
              time_t secs=time(NULL);
 
812
              k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
 
813
                                          &secs);
 
814
              if(data->set.get_filetime)
 
815
                data->info.filetime = k->timeofdoc;
 
816
            }
 
817
            else if((checkprefix("WWW-Authenticate:", k->p) &&
 
818
                     (401 == k->httpcode)) ||
 
819
                    (checkprefix("Proxy-authenticate:", k->p) &&
 
820
                     (407 == k->httpcode))) {
 
821
              result = Curl_http_auth(conn, k->httpcode, k->p);
 
822
              if(result)
 
823
                return result;
 
824
            }
 
825
            else if ((k->httpcode >= 300 && k->httpcode < 400) &&
 
826
                     checkprefix("Location:", k->p)) {
 
827
              if(data->set.http_follow_location) {
 
828
                /* this is the URL that the server advices us to get instead */
 
829
                char *ptr;
 
830
                char *start=k->p;
 
831
                char backup;
 
832
 
 
833
                start += 9; /* pass "Location:" */
 
834
 
 
835
                /* Skip spaces and tabs. We do this to support multiple
 
836
                   white spaces after the "Location:" keyword. */
 
837
                while(*start && isspace((int)*start ))
 
838
                  start++;
 
839
                
 
840
                /* Scan through the string from the end to find the last
 
841
                   non-space. k->end_ptr points to the actual terminating zero
 
842
                   letter, move pointer one letter back and start from
 
843
                   there. This logic strips off trailing whitespace, but keeps
 
844
                   any embedded whitespace. */
 
845
                ptr = k->end_ptr-1;
 
846
                while((ptr>=start) && isspace((int)*ptr))
 
847
                  ptr--;
 
848
                ptr++;
 
849
 
 
850
                backup = *ptr; /* store the ending letter */
 
851
                if(ptr != start) {
 
852
                  *ptr = '\0';   /* zero terminate */
 
853
                  conn->newurl = strdup(start); /* clone string */
 
854
                  *ptr = backup; /* restore ending letter */
 
855
                }
 
856
              }
 
857
#if 0 /* for consideration */
 
858
              else {
 
859
                /* This is a Location: but we have not been instructed to
 
860
                   follow it */
 
861
                infof(data, "We ignore this location header as instructed\n");
 
862
              }
 
863
#endif
 
864
            }
 
865
 
 
866
            /*
 
867
             * End of header-checks. Write them to the client.
 
868
             */
 
869
 
 
870
            writetype = CLIENTWRITE_HEADER;
 
871
            if (data->set.include_header)
 
872
              writetype |= CLIENTWRITE_BODY;
 
873
 
 
874
            if(data->set.verbose)
 
875
              Curl_debug(data, CURLINFO_HEADER_IN,
 
876
                         k->p, k->hbuflen);
 
877
 
 
878
            result = Curl_client_write(data, writetype, k->p, k->hbuflen);
 
879
            if(result)
 
880
              return result;
 
881
 
 
882
            data->info.header_size += k->hbuflen;
 
883
            conn->headerbytecount += k->hbuflen;
607
884
              
608
 
          /* reset hbufp pointer && hbuflen */
609
 
          k->hbufp = data->state.headerbuff;
610
 
          k->hbuflen = 0;
611
 
        }
612
 
        while (*k->str); /* header line within buffer */
613
 
 
614
 
        /* We might have reached the end of the header part here, but
615
 
           there might be a non-header part left in the end of the read
616
 
           buffer. */
617
 
 
618
 
        if (!k->header) {
619
 
          /* the next token and forward is not part of
620
 
             the header! */
621
 
 
622
 
          /* we subtract the remaining header size from the buffer */
623
 
          nread -= (k->str - k->buf);
624
 
        }
625
 
 
626
 
      }                 /* end if header mode */
627
 
 
628
 
      /* This is not an 'else if' since it may be a rest from the header
629
 
         parsing, where the beginning of the buffer is headers and the end
630
 
         is non-headers. */
631
 
      if (k->str && !k->header && (nread > 0)) {
 
885
            /* reset hbufp pointer && hbuflen */
 
886
            k->hbufp = data->state.headerbuff;
 
887
            k->hbuflen = 0;
 
888
          }
 
889
          while (!stop_reading && *k->str); /* header line within buffer */
 
890
 
 
891
          if(stop_reading)
 
892
            /* We've stopped dealing with input, get out of the do-while loop */
 
893
            break;
 
894
 
 
895
          /* We might have reached the end of the header part here, but
 
896
             there might be a non-header part left in the end of the read
 
897
             buffer. */
 
898
 
 
899
        }                       /* end if header mode */
 
900
 
 
901
        /* This is not an 'else if' since it may be a rest from the header
 
902
           parsing, where the beginning of the buffer is headers and the end
 
903
           is non-headers. */
 
904
        if (k->str && !k->header && (nread > 0)) {
632
905
            
633
 
        if(0 == k->bodywrites) {
634
 
          /* These checks are only made the first time we are about to
635
 
             write a piece of the body */
636
 
          if(conn->protocol&PROT_HTTP) {
637
 
            /* HTTP-only checks */
638
 
            if (conn->newurl) {
639
 
              /* abort after the headers if "follow Location" is set */
640
 
              infof (data, "Follow to new URL: %s\n", conn->newurl);
641
 
                k->keepon &= ~KEEP_READ;
642
 
                FD_ZERO(&k->rkeepfd);
643
 
              return CURLE_OK;
644
 
            }
645
 
            else if (conn->resume_from &&
646
 
                     !k->content_range &&
647
 
                     (data->set.httpreq==HTTPREQ_GET)) {
648
 
              /* we wanted to resume a download, although the server
649
 
                 doesn't seem to support this and we did this with a GET
650
 
                 (if it wasn't a GET we did a POST or PUT resume) */
651
 
              failf (data, "HTTP server doesn't seem to support "
652
 
                     "byte ranges. Cannot resume.");
653
 
              return CURLE_HTTP_RANGE_ERROR;
654
 
            }
655
 
            else if(data->set.timecondition && !conn->range) {
656
 
              /* A time condition has been set AND no ranges have been
657
 
                 requested. This seems to be what chapter 13.3.4 of
658
 
                 RFC 2616 defines to be the correct action for a
659
 
                 HTTP/1.1 client */
660
 
              if((k->timeofdoc > 0) && (data->set.timevalue > 0)) {
661
 
                switch(data->set.timecondition) {
662
 
                case TIMECOND_IFMODSINCE:
663
 
                default:
664
 
                  if(k->timeofdoc < data->set.timevalue) {
665
 
                    infof(data,
666
 
                          "The requested document is not new enough\n");
667
 
                    return CURLE_OK;
668
 
                  }
669
 
                  break;
670
 
                case TIMECOND_IFUNMODSINCE:
671
 
                  if(k->timeofdoc > data->set.timevalue) {
672
 
                    infof(data,
673
 
                          "The requested document is not old enough\n");
674
 
                    return CURLE_OK;
675
 
                  }
676
 
                  break;
677
 
                } /* switch */
678
 
              } /* two valid time strings */
679
 
            } /* we have a time condition */
680
 
 
681
 
          } /* this is HTTP */
682
 
        } /* this is the first time we write a body part */
683
 
        k->bodywrites++;
684
 
 
685
 
        if(conn->bits.chunk) {
686
 
          /*
687
 
           * Bless me father for I have sinned. Here comes a chunked
688
 
           * transfer flying and we need to decode this properly.  While
689
 
           * the name says read, this function both reads and writes away
690
 
           * the data. The returned 'nread' holds the number of actual
691
 
           * data it wrote to the client.  */
692
 
          CHUNKcode res =
693
 
            Curl_httpchunk_read(conn, k->str, nread, &nread);
694
 
 
695
 
          if(CHUNKE_OK < res) {
696
 
            failf(data, "Receeived problem in the chunky parser");
697
 
            return CURLE_READ_ERROR;
698
 
          }
699
 
          else if(CHUNKE_STOP == res) {
700
 
            /* we're done reading chunks! */
701
 
            k->keepon &= ~KEEP_READ; /* read no more */
 
906
          if(0 == k->bodywrites) {
 
907
            /* These checks are only made the first time we are about to
 
908
               write a piece of the body */
 
909
            if(conn->protocol&PROT_HTTP) {
 
910
              /* HTTP-only checks */
 
911
 
 
912
              if (conn->newurl) {
 
913
                if(conn->bits.close) {
 
914
                  /* Abort after the headers if "follow Location" is set
 
915
                     and we're set to close anyway. */
 
916
                  k->keepon &= ~KEEP_READ;
 
917
                  FD_ZERO(&k->rkeepfd);
 
918
                  *done = TRUE;
 
919
                  return CURLE_OK;
 
920
                }
 
921
                /* We have a new url to load, but since we want to be able
 
922
                   to re-use this connection properly, we read the full
 
923
                   response in "ignore more" */
 
924
                k->ignorebody = TRUE;
 
925
                infof(data, "Ignoring the response-body\n");
 
926
              }
 
927
              if(data->set.timecondition && !conn->range) {
 
928
                /* A time condition has been set AND no ranges have been
 
929
                   requested. This seems to be what chapter 13.3.4 of
 
930
                   RFC 2616 defines to be the correct action for a
 
931
                   HTTP/1.1 client */
 
932
                if((k->timeofdoc > 0) && (data->set.timevalue > 0)) {
 
933
                  switch(data->set.timecondition) {
 
934
                  case CURL_TIMECOND_IFMODSINCE:
 
935
                  default:
 
936
                    if(k->timeofdoc < data->set.timevalue) {
 
937
                      infof(data,
 
938
                            "The requested document is not new enough\n");
 
939
                      *done = TRUE;
 
940
                      return CURLE_OK;
 
941
                    }
 
942
                    break;
 
943
                  case CURL_TIMECOND_IFUNMODSINCE:
 
944
                    if(k->timeofdoc > data->set.timevalue) {
 
945
                      infof(data,
 
946
                            "The requested document is not old enough\n");
 
947
                      *done = TRUE;
 
948
                      return CURLE_OK;
 
949
                    }
 
950
                    break;
 
951
                  } /* switch */
 
952
                } /* two valid time strings */
 
953
              } /* we have a time condition */
 
954
 
 
955
            } /* this is HTTP */
 
956
          } /* this is the first time we write a body part */
 
957
          k->bodywrites++;
 
958
 
 
959
          /* pass data to the debug function before it gets "dechunked" */
 
960
          if(data->set.verbose) {
 
961
            if(k->badheader) {
 
962
              Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
 
963
                         k->hbuflen);
 
964
              if(k->badheader == HEADER_PARTHEADER)
 
965
                Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
 
966
            }
 
967
            else
 
968
              Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
 
969
          }
 
970
 
 
971
          if(conn->bits.chunk) {
 
972
            /*
 
973
             * Bless me father for I have sinned. Here comes a chunked
 
974
             * transfer flying and we need to decode this properly.  While
 
975
             * the name says read, this function both reads and writes away
 
976
             * the data. The returned 'nread' holds the number of actual
 
977
             * data it wrote to the client.  */
 
978
            CHUNKcode res =
 
979
              Curl_httpchunk_read(conn, k->str, nread, &nread);
 
980
 
 
981
            if(CHUNKE_OK < res) {
 
982
              if(CHUNKE_WRITE_ERROR == res) {
 
983
                failf(data, "Failed writing data");
 
984
                return CURLE_WRITE_ERROR;
 
985
              }
 
986
              failf(data, "Received problem %d in the chunky parser", res);
 
987
              return CURLE_RECV_ERROR;
 
988
            }
 
989
            else if(CHUNKE_STOP == res) {
 
990
              /* we're done reading chunks! */
 
991
              k->keepon &= ~KEEP_READ; /* read no more */
 
992
              FD_ZERO(&k->rkeepfd);
 
993
 
 
994
              /* There are now possibly N number of bytes at the end of the
 
995
                 str buffer that weren't written to the client, but we don't
 
996
                 care about them right now. */
 
997
            }
 
998
            /* If it returned OK, we just keep going */
 
999
          }
 
1000
 
 
1001
          if((-1 != conn->maxdownload) &&
 
1002
             (k->bytecount + nread >= conn->maxdownload)) {
 
1003
            nread = (ssize_t) (conn->maxdownload - k->bytecount);
 
1004
            if(nread < 0 ) /* this should be unusual */
 
1005
              nread = 0;
 
1006
 
 
1007
            k->keepon &= ~KEEP_READ; /* we're done reading */
702
1008
            FD_ZERO(&k->rkeepfd);
703
 
 
704
 
            /* There are now possibly N number of bytes at the end of the
705
 
               str buffer that weren't written to the client, but we don't
706
 
               care about them right now. */
707
1009
          }
708
 
          /* If it returned OK, we just keep going */
709
 
        }
710
 
 
711
 
        if((-1 != conn->maxdownload) &&
712
 
           (k->bytecount + nread >= conn->maxdownload)) {
713
 
          nread = conn->maxdownload - k->bytecount;
714
 
          if(nread < 0 ) /* this should be unusual */
715
 
            nread = 0;
716
 
 
717
 
          k->keepon &= ~KEEP_READ; /* we're done reading */
718
 
          FD_ZERO(&k->rkeepfd);
719
 
        }
720
 
 
721
 
        k->bytecount += nread;
722
 
 
723
 
        Curl_pgrsSetDownloadCounter(data, (double)k->bytecount);
 
1010
 
 
1011
          k->bytecount += nread;
 
1012
 
 
1013
          Curl_pgrsSetDownloadCounter(data, k->bytecount);
724
1014
            
725
 
        if(!conn->bits.chunk && nread) {
726
 
          /* If this is chunky transfer, it was already written */
727
 
          result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
728
 
                                     nread);
729
 
          if(result)
730
 
            return result;
731
 
        }
732
 
 
733
 
      } /* if (! header and data to read ) */
 
1015
          if(!conn->bits.chunk && (nread || k->badheader)) {
 
1016
            /* If this is chunky transfer, it was already written */
 
1017
 
 
1018
            if(k->badheader && !k->ignorebody) {
 
1019
              /* we parsed a piece of data wrongly assuming it was a header
 
1020
                 and now we output it as body instead */
 
1021
              result = Curl_client_write(data, CLIENTWRITE_BODY,
 
1022
                                         data->state.headerbuff,
 
1023
                                         k->hbuflen);
 
1024
            }
 
1025
            if(k->badheader < HEADER_ALLBAD) {
 
1026
              /* This switch handles various content encodings. If there's an
 
1027
                 error here, be sure to check over the almost identical code
 
1028
                 in http_chunks.c.
 
1029
                 Make sure that ALL_CONTENT_ENCODINGS contains all the
 
1030
                 encodings handled here. */
 
1031
#ifdef HAVE_LIBZ
 
1032
              switch (k->content_encoding) {
 
1033
              case IDENTITY:
 
1034
#endif
 
1035
                /* This is the default when the server sends no
 
1036
                   Content-Encoding header. See Curl_readwrite_init; the
 
1037
                   memset() call initializes k->content_encoding to zero. */
 
1038
                if(!k->ignorebody)
 
1039
                  result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, 
 
1040
                                             nread);
 
1041
#ifdef HAVE_LIBZ
 
1042
                break;
 
1043
 
 
1044
              case DEFLATE: 
 
1045
                /* Assume CLIENTWRITE_BODY; headers are not encoded. */
 
1046
                result = Curl_unencode_deflate_write(data, k, nread);
 
1047
                break;
 
1048
 
 
1049
              case GZIP:
 
1050
                /* Assume CLIENTWRITE_BODY; headers are not encoded. */
 
1051
                result = Curl_unencode_gzip_write(data, k, nread);
 
1052
                break;
 
1053
 
 
1054
              case COMPRESS:
 
1055
              default:
 
1056
                failf (data, "Unrecognized content encoding type. "
 
1057
                       "libcurl understands `identity', `deflate' and `gzip' "
 
1058
                       "content encodings.");
 
1059
                result = CURLE_BAD_CONTENT_ENCODING;
 
1060
                break;
 
1061
              }
 
1062
#endif
 
1063
            }
 
1064
            k->badheader = HEADER_NORMAL; /* taken care of now */
 
1065
 
 
1066
            if(result)
 
1067
              return result;
 
1068
          }
 
1069
 
 
1070
        } /* if (! header and data to read ) */
 
1071
 
 
1072
      } while(!readdone);
 
1073
 
734
1074
    } /* if( read from socket ) */
735
1075
 
 
1076
    /* If we still have writing to do, we check if we have a writable
 
1077
       socket. Sometimes the writefdp is NULL, if no fd_set was done using
 
1078
       the multi interface and then we can do nothing but to attempt a
 
1079
       write to be sure. */
736
1080
    if((k->keepon & KEEP_WRITE) &&
737
 
       FD_ISSET(conn->writesockfd, &k->writefd)) {
 
1081
       (!writefdp || FD_ISSET(conn->writesockfd, writefdp)) ) {
738
1082
      /* write */
739
1083
 
740
1084
      int i, si;
741
1085
      ssize_t bytes_written;
 
1086
      bool writedone=TRUE;
742
1087
 
743
1088
      if ((k->bytecount == 0) && (k->writebytecount == 0))
744
1089
        Curl_pgrsTime(data, TIMER_STARTTRANSFER);
745
1090
 
746
1091
      didwhat |= KEEP_WRITE;
747
1092
 
748
 
      /* only read more data if there's no upload data already
749
 
         present in the upload buffer */
750
 
      if(0 == conn->upload_present) {
751
 
        /* init the "upload from here" pointer */
752
 
        conn->upload_fromhere = k->uploadbuf;
753
 
 
754
 
        nread = data->set.fread(conn->upload_fromhere, 1,
755
 
                                BUFSIZE, data->set.in);
756
 
 
757
 
        /* the signed int typecase of nread of for systems that has
758
 
           unsigned size_t */
759
 
        if (nread<=0) {
760
 
          /* done */
761
 
          k->keepon &= ~KEEP_WRITE; /* we're done writing */
762
 
          FD_ZERO(&k->wkeepfd);
763
 
          break;
764
 
        }
765
 
 
766
 
        /* store number of bytes available for upload */
767
 
        conn->upload_present = nread;
768
 
 
769
 
        /* convert LF to CRLF if so asked */
770
 
        if (data->set.crlf) {
771
 
          for(i = 0, si = 0; i < nread; i++, si++) {
772
 
            if (k->buf[i] == 0x0a) {
773
 
              data->state.scratch[si++] = 0x0d;
774
 
              data->state.scratch[si] = 0x0a;
775
 
            }
776
 
            else {
777
 
              data->state.scratch[si] = k->uploadbuf[i];
778
 
            }
779
 
          }
780
 
          nread = si;
781
 
          k->buf = data->state.scratch; /* point to the new buffer */
782
 
        }
783
 
      }
784
 
      else {
785
 
        /* We have a partial buffer left from a previous "round". Use
786
 
           that instead of reading more data */
787
 
      }
788
 
 
789
 
      /* write to socket */
790
 
      result = Curl_write(conn,
791
 
                          conn->writesockfd,
792
 
                          conn->upload_fromhere,
793
 
                          conn->upload_present,
794
 
                          &bytes_written);
795
 
      if(result)
796
 
        return result;
797
 
      else if(conn->upload_present != bytes_written) {
798
 
        /* we only wrote a part of the buffer (if anything), deal with it! */
799
 
 
800
 
        /* store the amount of bytes left in the buffer to write */
801
 
        conn->upload_present -= bytes_written;
802
 
 
803
 
        /* advance the pointer where to find the buffer when the next send
804
 
           is to happen */
805
 
        conn->upload_fromhere += bytes_written;
806
 
      }
807
 
      else if(data->set.crlf)
808
 
        k->buf = data->state.buffer; /* put it back on the buffer */
809
 
      else {
810
 
        /* we've uploaded that buffer now */
811
 
        conn->upload_fromhere = k->uploadbuf;
812
 
        conn->upload_present = 0; /* no more bytes left */
813
 
      }
814
 
 
815
 
      k->writebytecount += bytes_written;
816
 
      Curl_pgrsSetUploadCounter(data, (double)k->writebytecount);
817
 
 
 
1093
      /*
 
1094
       * We loop here to do the READ and SEND loop until we run out of
 
1095
       * data to send or until we get EWOULDBLOCK back
 
1096
       */
 
1097
      do {
 
1098
        
 
1099
        /* only read more data if there's no upload data already
 
1100
           present in the upload buffer */
 
1101
        if(0 == conn->upload_present) {
 
1102
          /* init the "upload from here" pointer */
 
1103
          conn->upload_fromhere = k->uploadbuf;
 
1104
 
 
1105
          if(!k->upload_done) {
 
1106
            /* HTTP pollution, this should be written nicer to become more
 
1107
               protocol agnostic. */
 
1108
 
 
1109
            if(k->wait100_after_headers &&
 
1110
               (conn->proto.http->sending == HTTPSEND_BODY)) {
 
1111
              /* If this call is to send body data, we must take some action:
 
1112
                 We have sent off the full HTTP 1.1 request, and we shall now
 
1113
                 go into the Expect: 100 state and await such a header */
 
1114
              k->wait100_after_headers = FALSE; /* headers sent */
 
1115
              k->write_after_100_header = TRUE; /* wait for the header */
 
1116
              FD_ZERO (&k->writefd);            /* clear it */
 
1117
              k->wkeepfd = k->writefd;          /* set the keeper variable */
 
1118
              k->keepon &= ~KEEP_WRITE;         /* disable writing */
 
1119
              k->start100 = Curl_tvnow();       /* timeout count starts now */
 
1120
              didwhat &= ~KEEP_WRITE;  /* we didn't write anything actually */
 
1121
              break;
 
1122
            }
 
1123
 
 
1124
            nread = fillbuffer(conn, BUFSIZE);
 
1125
          }
 
1126
          else
 
1127
            nread = 0; /* we're done uploading/reading */
 
1128
 
 
1129
          /* the signed int typecase of nread of for systems that has
 
1130
             unsigned size_t */
 
1131
          if (nread<=0) {
 
1132
            /* done */
 
1133
            k->keepon &= ~KEEP_WRITE; /* we're done writing */
 
1134
            FD_ZERO(&k->wkeepfd);
 
1135
            writedone = TRUE;
 
1136
            break;
 
1137
          }
 
1138
 
 
1139
          /* store number of bytes available for upload */
 
1140
          conn->upload_present = nread;
 
1141
 
 
1142
          /* convert LF to CRLF if so asked */
 
1143
          if (data->set.crlf) {
 
1144
              if(data->state.scratch == NULL)
 
1145
                data->state.scratch = malloc(2*BUFSIZE);
 
1146
              if(data->state.scratch == NULL) {
 
1147
                failf (data, "Failed to alloc scratch buffer!");
 
1148
                return CURLE_OUT_OF_MEMORY;
 
1149
              }
 
1150
            for(i = 0, si = 0; i < nread; i++, si++) {
 
1151
              if (conn->upload_fromhere[i] == 0x0a) {
 
1152
                data->state.scratch[si++] = 0x0d;
 
1153
                data->state.scratch[si] = 0x0a;
 
1154
              }
 
1155
              else
 
1156
                data->state.scratch[si] = conn->upload_fromhere[i];
 
1157
            }
 
1158
            if(si != nread) {
 
1159
              /* only perform the special operation if we really did replace
 
1160
                 anything */
 
1161
              nread = si;
 
1162
 
 
1163
              /* upload from the new (replaced) buffer instead */
 
1164
              conn->upload_fromhere = data->state.scratch;
 
1165
 
 
1166
              /* set the new amount too */
 
1167
              conn->upload_present = nread;
 
1168
            }
 
1169
          }
 
1170
        }
 
1171
        else {
 
1172
          /* We have a partial buffer left from a previous "round". Use
 
1173
             that instead of reading more data */
 
1174
        }
 
1175
 
 
1176
        /* write to socket (send away data) */
 
1177
        result = Curl_write(conn,
 
1178
                            conn->writesockfd,     /* socket to send to */
 
1179
                            conn->upload_fromhere, /* buffer pointer */
 
1180
                            conn->upload_present,  /* buffer size */
 
1181
                            &bytes_written);       /* actually send away */
 
1182
        if(result)
 
1183
          return result;
 
1184
 
 
1185
        if(data->set.verbose)
 
1186
          /* show the data before we change the pointer upload_fromhere */
 
1187
          Curl_debug(data, CURLINFO_DATA_OUT, conn->upload_fromhere,
 
1188
                     bytes_written);
 
1189
      
 
1190
        if(conn->upload_present != bytes_written) {
 
1191
          /* we only wrote a part of the buffer (if anything), deal with it! */
 
1192
 
 
1193
          /* store the amount of bytes left in the buffer to write */
 
1194
          conn->upload_present -= bytes_written;
 
1195
 
 
1196
          /* advance the pointer where to find the buffer when the next send
 
1197
             is to happen */
 
1198
          conn->upload_fromhere += bytes_written;
 
1199
 
 
1200
          writedone = TRUE; /* we are done, stop the loop */
 
1201
        }
 
1202
        else {
 
1203
          /* we've uploaded that buffer now */
 
1204
          conn->upload_fromhere = k->uploadbuf;
 
1205
          conn->upload_present = 0; /* no more bytes left */
 
1206
 
 
1207
          if(k->upload_done) {
 
1208
            /* switch off writing, we're done! */
 
1209
            k->keepon &= ~KEEP_WRITE; /* we're done writing */
 
1210
            FD_ZERO(&k->wkeepfd);
 
1211
            writedone = TRUE;
 
1212
          }
 
1213
        }
 
1214
 
 
1215
        k->writebytecount += bytes_written;
 
1216
        Curl_pgrsSetUploadCounter(data, k->writebytecount);
 
1217
 
 
1218
      } while(!writedone); /* loop until we're done writing! */
 
1219
      
818
1220
    }
819
1221
 
820
1222
  } while(0); /* just to break out from! */
821
1223
 
 
1224
  k->now = Curl_tvnow();
822
1225
  if(didwhat) {
823
1226
    /* Update read/write counters */
824
1227
    if(conn->bytecountp)
832
1235
      /* This should allow some time for the header to arrive, but only a
833
1236
         very short time as otherwise it'll be too much wasted times too
834
1237
         often. */
835
 
      k->write_after_100_header = FALSE;
836
 
      FD_SET (conn->writesockfd, &k->writefd); /* write socket */
837
 
      k->keepon |= KEEP_WRITE;
838
 
      k->wkeepfd = k->writefd;
 
1238
 
 
1239
      /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
 
1240
         
 
1241
      Therefore, when a client sends this header field to an origin server
 
1242
      (possibly via a proxy) from which it has never seen a 100 (Continue)
 
1243
      status, the client SHOULD NOT wait for an indefinite period before
 
1244
      sending the request body.
 
1245
 
 
1246
      */
 
1247
 
 
1248
      int ms = Curl_tvdiff(k->now, k->start100);
 
1249
      if(ms > CURL_TIMEOUT_EXPECT_100) {
 
1250
        /* we've waited long enough, continue anyway */
 
1251
        k->write_after_100_header = FALSE;
 
1252
        FD_SET (conn->writesockfd, &k->writefd); /* write socket */
 
1253
        k->keepon |= KEEP_WRITE;
 
1254
        k->wkeepfd = k->writefd;
 
1255
      }
839
1256
    }    
840
1257
  }
841
1258
 
842
 
  k->now = Curl_tvnow();
843
1259
  if(Curl_pgrsUpdate(conn))
844
1260
    result = CURLE_ABORTED_BY_CALLBACK;
845
1261
  else
849
1265
    
850
1266
  if (data->set.timeout &&
851
1267
      ((Curl_tvdiff(k->now, k->start)/1000) >= data->set.timeout)) {
852
 
    failf (data, "Operation timed out with %d out of %d bytes received",
 
1268
    failf (data, "Operation timed out with %" FORMAT_OFF_T
 
1269
           " out of %" FORMAT_OFF_T " bytes received",
853
1270
           k->bytecount, conn->size);
854
1271
    return CURLE_OPERATION_TIMEOUTED;
855
1272
  }
860
1277
     * returning.
861
1278
     */
862
1279
 
863
 
    if(!(data->set.no_body) && k->contentlength &&
864
 
       (k->bytecount != k->contentlength) &&
 
1280
    if(!(conn->bits.no_body) && (conn->size != -1) &&
 
1281
       (k->bytecount != conn->size) &&
865
1282
       !conn->newurl) {
866
 
      failf(data, "transfer closed with %d bytes remaining to read",
867
 
            k->contentlength-k->bytecount);
 
1283
      failf(data, "transfer closed with %" FORMAT_OFF_T
 
1284
            " bytes remaining to read",
 
1285
            conn->size - k->bytecount);
868
1286
      return CURLE_PARTIAL_FILE;
869
1287
    }
870
1288
    else if(conn->bits.chunk && conn->proto.http->chunk.datasize) {
887
1305
  struct SessionHandle *data = conn->data;
888
1306
  struct Curl_transfer_keeper *k = &conn->keep;
889
1307
 
 
1308
  /* NB: the content encoding software depends on this initialization of
 
1309
     Curl_transfer_keeper. */
890
1310
  memset(k, 0, sizeof(struct Curl_transfer_keeper));
891
1311
 
892
1312
  k->start = Curl_tvnow(); /* start time */
893
1313
  k->now = k->start;   /* current time is now */
894
1314
  k->header = TRUE; /* assume header */
895
1315
  k->httpversion = -1; /* unknown at this point */
896
 
  k->conn = (struct connectdata *)conn; /* store the connection */
897
1316
 
898
1317
  data = conn->data; /* there's the root struct */
899
1318
  k->buf = data->state.buffer;
901
1320
  k->maxfd = (conn->sockfd>conn->writesockfd?
902
1321
              conn->sockfd:conn->writesockfd)+1;
903
1322
  k->hbufp = data->state.headerbuff;
 
1323
  k->ignorebody=FALSE;
904
1324
 
905
1325
  Curl_pgrsTime(data, TIMER_PRETRANSFER);
906
1326
  Curl_speedinit(data);
907
1327
 
908
 
  if (!conn->getheader) {
 
1328
  Curl_pgrsSetUploadCounter(data, 0);
 
1329
  Curl_pgrsSetDownloadCounter(data, 0);
 
1330
 
 
1331
  if (!conn->bits.getheader) {
909
1332
    k->header = FALSE;
910
1333
    if(conn->size > 0)
911
1334
      Curl_pgrsSetDownloadSize(data, conn->size);
912
1335
  }
913
1336
  /* we want header and/or body, if neither then don't do this! */
914
 
  if(conn->getheader || !data->set.no_body) {
 
1337
  if(conn->bits.getheader || !conn->bits.no_body) {
915
1338
 
916
 
    FD_ZERO (&k->readfd);               /* clear it */
917
 
    if(conn->sockfd != -1) {
 
1339
    FD_ZERO (&k->readfd);               /* clear it */
 
1340
    if(conn->sockfd != CURL_SOCKET_BAD) {
918
1341
      FD_SET (conn->sockfd, &k->readfd); /* read socket */
919
1342
      k->keepon |= KEEP_READ;
920
1343
    }
921
1344
 
922
 
    FD_ZERO (&k->writefd);              /* clear it */
923
 
    if(conn->writesockfd != -1) {
924
 
      if (data->set.expect100header)
 
1345
    FD_ZERO (&k->writefd);              /* clear it */
 
1346
    if(conn->writesockfd != CURL_SOCKET_BAD) {
 
1347
      /* HTTP 1.1 magic:
 
1348
 
 
1349
         Even if we require a 100-return code before uploading data, we might
 
1350
         need to write data before that since the REQUEST may not have been
 
1351
         finished sent off just yet.
 
1352
 
 
1353
         Thus, we must check if the request has been sent before we set the
 
1354
         state info where we wait for the 100-return code
 
1355
      */
 
1356
      if (data->set.expect100header &&
 
1357
          (conn->proto.http->sending == HTTPSEND_BODY)) {
925
1358
        /* wait with write until we either got 100-continue or a timeout */
926
1359
        k->write_after_100_header = TRUE;
 
1360
        k->start100 = k->start;
 
1361
      }
927
1362
      else {
 
1363
        if(data->set.expect100header)
 
1364
          /* when we've sent off the rest of the headers, we must await a
 
1365
             100-continue */
 
1366
          k->wait100_after_headers = TRUE;
928
1367
        FD_SET (conn->writesockfd, &k->writefd); /* write socket */
929
1368
        k->keepon |= KEEP_WRITE;
930
1369
      }
950
1389
  if(conn->keep.keepon & KEEP_READ) {
951
1390
    FD_SET(conn->sockfd, read_fd_set);
952
1391
    *max_fd = conn->sockfd;
 
1392
    conn->keep.readfdp = read_fd_set; /* store the address of the set */
953
1393
  }
954
1394
  if(conn->keep.keepon & KEEP_WRITE) {
955
1395
    FD_SET(conn->writesockfd, write_fd_set);
956
 
    if(conn->writesockfd > *max_fd)
 
1396
 
 
1397
    /* since sockets are curl_socket_t nowadays, we typecast it to int here
 
1398
       to compare it nicely */
 
1399
    if((int)conn->writesockfd > *max_fd)
957
1400
      *max_fd = conn->writesockfd;
 
1401
    conn->keep.writefdp = write_fd_set; /* store the address of the set */
958
1402
  }
959
1403
  /* we don't use exceptions, only touch that one to prevent compiler
960
1404
     warnings! */
970
1414
 * The transfer must already have been setup by a call to Curl_Transfer().
971
1415
 *
972
1416
 * Note that headers are created in a preallocated buffer of a default size.
973
 
 * That buffer can be enlarged on demand, but it is never shrinken again.
 
1417
 * That buffer can be enlarged on demand, but it is never shrunken again.
974
1418
 *
975
1419
 * Parts of this function was once written by the friendly Mark Butler
976
1420
 * <butlerm@xmission.com>.
979
1423
static CURLcode
980
1424
Transfer(struct connectdata *conn)
981
1425
{
982
 
  struct SessionHandle *data = conn->data;
983
1426
  CURLcode result;
984
1427
  struct Curl_transfer_keeper *k = &conn->keep;
985
1428
  bool done=FALSE;
986
1429
 
987
 
  Curl_readwrite_init(conn);
 
1430
  if(!(conn->protocol & PROT_FILE))
 
1431
    /* Only do this if we are not transferring FILE:, since the file: treatment
 
1432
       is different*/
 
1433
    Curl_readwrite_init(conn);
988
1434
 
989
 
  if((conn->sockfd == -1) && (conn->writesockfd == -1))
 
1435
  if((conn->sockfd == CURL_SOCKET_BAD) && (conn->writesockfd == CURL_SOCKET_BAD))
990
1436
    /* nothing to read, nothing to write, we're already OK! */
991
1437
    return CURLE_OK;
992
1438
 
993
1439
  /* we want header and/or body, if neither then don't do this! */
994
 
  if(!conn->getheader && data->set.no_body)
 
1440
  if(!conn->bits.getheader && conn->bits.no_body)
995
1441
    return CURLE_OK;
996
1442
 
 
1443
  k->writefdp = &k->writefd; /* store the address of the set */
 
1444
  k->readfdp = &k->readfd;   /* store the address of the set */
 
1445
 
997
1446
  while (!done) {
998
1447
    struct timeval interval;
999
1448
    k->readfd = k->rkeepfd;  /* set these every lap in the loop */
1001
1450
    interval.tv_sec = 1;
1002
1451
    interval.tv_usec = 0;
1003
1452
 
1004
 
    switch (select (k->maxfd, &k->readfd, &k->writefd, NULL,
1005
 
                    &interval)) {
 
1453
    switch (select (k->maxfd, k->readfdp, k->writefdp, NULL, &interval)) {
1006
1454
    case -1: /* select() error, stop reading */
1007
1455
#ifdef EINTR
1008
1456
      /* The EINTR is not serious, and it seems you might get this more
1014
1462
        done = TRUE; /* no more read or write */
1015
1463
      continue;
1016
1464
    case 0:  /* timeout */
1017
 
      result = Curl_readwrite(conn, &done);
1018
 
      break;
1019
 
 
1020
1465
    default: /* readable descriptors */
1021
1466
      result = Curl_readwrite(conn, &done);
1022
1467
      break;
1037
1482
    return CURLE_URL_MALFORMAT;
1038
1483
 
1039
1484
#ifdef USE_SSLEAY
1040
 
  /* Init the SSL session ID cache here. We do it here since we want to
1041
 
     do it after the *_setopt() calls (that could change the size) but
1042
 
     before any transfer. */
1043
 
  Curl_SSL_InitSessions(data, data->set.ssl.numsessions);
 
1485
  {
 
1486
    /* Init the SSL session ID cache here. We do it here since we want to do
 
1487
       it after the *_setopt() calls (that could change the size of the cache)
 
1488
       but before any transfer takes place. */
 
1489
    CURLcode res = Curl_SSL_InitSessions(data, data->set.ssl.numsessions);
 
1490
    if(res)
 
1491
      return res;
 
1492
  }
1044
1493
#endif
1045
1494
 
1046
1495
  data->set.followlocation=0; /* reset the location-follow counter */
1047
1496
  data->state.this_is_a_follow = FALSE; /* reset this */
1048
1497
  data->state.errorbuf = FALSE; /* no error has occurred */
1049
1498
 
 
1499
  /* set preferred authentication, default to basic */
 
1500
 
 
1501
  data->state.authstage = 0; /* initialize authentication later */
 
1502
  data->state.authproblem = FALSE;
 
1503
 
 
1504
  /* If there was a list of cookie files to read and we haven't done it before,
 
1505
     do it now! */
 
1506
  if(data->change.cookielist) {
 
1507
    struct curl_slist *list = data->change.cookielist;
 
1508
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
 
1509
    while(list) {
 
1510
      data->cookies = Curl_cookie_init(data,
 
1511
                                       list->data,
 
1512
                                       data->cookies,
 
1513
                                       data->set.cookiesession);
 
1514
      list = list->next;
 
1515
    }
 
1516
    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
 
1517
    curl_slist_free_all(data->change.cookielist); /* clean up list */
 
1518
    data->change.cookielist = NULL; /* don't do this again! */
 
1519
  }
 
1520
 
 
1521
 
 
1522
 
1050
1523
 /* Allow data->set.use_port to set which port to use. This needs to be
1051
1524
  * disabled for example when we follow Location: headers to URLs using
1052
1525
  * different ports! */
1053
1526
  data->state.allow_port = TRUE;
1054
1527
 
1055
 
#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
 
1528
#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1056
1529
  /*************************************************************
1057
1530
   * Tell signal handler to ignore SIGPIPE
1058
1531
   *************************************************************/
1059
 
  data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
 
1532
  if(!data->set.no_signal)
 
1533
    data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
1060
1534
#endif  
1061
1535
 
1062
1536
  Curl_initinfo(data); /* reset session-specific information "variables" */
1067
1541
 
1068
1542
CURLcode Curl_posttransfer(struct SessionHandle *data)
1069
1543
{
1070
 
#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
 
1544
#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1071
1545
  /* restore the signal handler for SIGPIPE before we get back */
1072
 
  signal(SIGPIPE, data->state.prev_signal);
 
1546
  if(!data->set.no_signal)
 
1547
    signal(SIGPIPE, data->state.prev_signal);
 
1548
#else
 
1549
  (void)data; /* unused parameter */
1073
1550
#endif  
1074
1551
 
1075
1552
  return CURLE_OK;
1076
1553
}
1077
1554
 
 
1555
static int strlen_url(char *url)
 
1556
{
 
1557
  char *ptr;
 
1558
  int newlen=0;
 
1559
  bool left=TRUE; /* left side of the ? */
 
1560
 
 
1561
  for(ptr=url; *ptr; ptr++) {
 
1562
    switch(*ptr) {
 
1563
    case '?':
 
1564
      left=FALSE;
 
1565
    default:
 
1566
      newlen++;
 
1567
      break;
 
1568
    case ' ':
 
1569
      if(left)
 
1570
        newlen+=3;
 
1571
      else
 
1572
        newlen++;
 
1573
      break;
 
1574
    }
 
1575
  }
 
1576
  return newlen;
 
1577
}
 
1578
 
 
1579
static void strcpy_url(char *output, char *url)
 
1580
{
 
1581
  /* we must add this with whitespace-replacing */
 
1582
  bool left=TRUE;
 
1583
  char *iptr;
 
1584
  char *optr = output;
 
1585
  for(iptr = url;    /* read from here */
 
1586
      *iptr;         /* until zero byte */
 
1587
      iptr++) {
 
1588
    switch(*iptr) {
 
1589
    case '?':
 
1590
      left=FALSE;
 
1591
    default:
 
1592
      *optr++=*iptr;
 
1593
      break;
 
1594
    case ' ':
 
1595
      if(left) {
 
1596
        *optr++='%'; /* add a '%' */
 
1597
        *optr++='2'; /* add a '2' */
 
1598
        *optr++='0'; /* add a '0' */
 
1599
      }
 
1600
      else
 
1601
        *optr++='+'; /* add a '+' here */
 
1602
      break;
 
1603
    }
 
1604
  }
 
1605
  *optr=0; /* zero terminate output buffer */
 
1606
 
 
1607
}
 
1608
 
 
1609
CURLcode Curl_follow(struct SessionHandle *data,
 
1610
                     char *newurl) /* this 'newurl' is the Location: string,
 
1611
                                      and it must be malloc()ed before passed
 
1612
                                      here */
 
1613
{
 
1614
  /* Location: redirect */
 
1615
  char prot[16]; /* URL protocol string storage */
 
1616
  char letter;   /* used for a silly sscanf */
 
1617
  int newlen;
 
1618
  char *newest;
 
1619
  
 
1620
  if (data->set.maxredirs &&
 
1621
      (data->set.followlocation >= data->set.maxredirs)) {
 
1622
    failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
 
1623
    return CURLE_TOO_MANY_REDIRECTS;
 
1624
  }
 
1625
 
 
1626
  /* mark the next request as a followed location: */
 
1627
  data->state.this_is_a_follow = TRUE;
 
1628
 
 
1629
  data->set.followlocation++; /* count location-followers */
 
1630
 
 
1631
  if(data->set.http_auto_referer) {
 
1632
    /* We are asked to automatically set the previous URL as the
 
1633
       referer when we get the next URL. We pick the ->url field,
 
1634
       which may or may not be 100% correct */
 
1635
 
 
1636
    if(data->change.referer_alloc)
 
1637
      /* If we already have an allocated referer, free this first */
 
1638
      free(data->change.referer);
 
1639
 
 
1640
    data->change.referer = strdup(data->change.url);
 
1641
    data->change.referer_alloc = TRUE; /* yes, free this later */
 
1642
  }
 
1643
 
 
1644
  if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) {
 
1645
    /***
 
1646
     *DANG* this is an RFC 2068 violation. The URL is supposed
 
1647
     to be absolute and this doesn't seem to be that!
 
1648
     ***
 
1649
     Instead, we have to TRY to append this new path to the old URL
 
1650
     to the right of the host part. Oh crap, this is doomed to cause
 
1651
     problems in the future...
 
1652
    */
 
1653
    char *protsep;
 
1654
    char *pathsep;
 
1655
 
 
1656
    char *useurl = newurl;
 
1657
    int urllen;
 
1658
 
 
1659
    /* we must make our own copy of the URL to play with, as it may
 
1660
       point to read-only data */
 
1661
    char *url_clone=strdup(data->change.url);
 
1662
 
 
1663
    if(!url_clone)
 
1664
      return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */
 
1665
 
 
1666
    /* protsep points to the start of the host name */
 
1667
    protsep=strstr(url_clone, "//");
 
1668
    if(!protsep)
 
1669
      protsep=url_clone;
 
1670
    else
 
1671
      protsep+=2; /* pass the slashes */
 
1672
 
 
1673
    if('/' != newurl[0]) {
 
1674
      int level=0;
 
1675
 
 
1676
      /* First we need to find out if there's a ?-letter in the URL,
 
1677
         and cut it and the right-side of that off */
 
1678
      pathsep = strrchr(protsep, '?');
 
1679
      if(pathsep)
 
1680
        *pathsep=0;
 
1681
      
 
1682
      /* we have a relative path to append to the last slash if
 
1683
         there's one available */
 
1684
      pathsep = strrchr(protsep, '/');
 
1685
      if(pathsep)
 
1686
        *pathsep=0;
 
1687
 
 
1688
      /* Check if there's any slash after the host name, and if so,
 
1689
         remember that position instead */
 
1690
      pathsep = strchr(protsep, '/');
 
1691
      if(pathsep)
 
1692
        protsep = pathsep+1;
 
1693
      else
 
1694
        protsep = NULL;
 
1695
 
 
1696
      /* now deal with one "./" or any amount of "../" in the newurl
 
1697
         and act accordingly */
 
1698
 
 
1699
      if((useurl[0] == '.') && (useurl[1] == '/'))
 
1700
        useurl+=2; /* just skip the "./" */
 
1701
            
 
1702
      while((useurl[0] == '.') &&
 
1703
            (useurl[1] == '.') &&
 
1704
            (useurl[2] == '/')) {
 
1705
        level++; 
 
1706
        useurl+=3; /* pass the "../" */
 
1707
      }
 
1708
 
 
1709
      if(protsep) {
 
1710
        while(level--) {
 
1711
          /* cut off one more level from the right of the original URL */
 
1712
          pathsep = strrchr(protsep, '/');
 
1713
          if(pathsep)
 
1714
            *pathsep=0;
 
1715
          else {
 
1716
            *protsep=0;
 
1717
            break;
 
1718
          }
 
1719
        }
 
1720
      }
 
1721
    }
 
1722
    else {
 
1723
      /* We got a new absolute path for this server, cut off from the
 
1724
         first slash */
 
1725
      pathsep = strchr(protsep, '/');
 
1726
      if(pathsep)
 
1727
        *pathsep=0;
 
1728
      else {
 
1729
        /* There was no slash. Now, since we might be operating on a badly
 
1730
           formatted URL, such as "http://www.url.com?id=2380" which doesn't
 
1731
           use a slash separator as it is supposed to, we need to check for a
 
1732
           ?-letter as well! */
 
1733
        pathsep = strchr(protsep, '?');
 
1734
        if(pathsep)
 
1735
          *pathsep=0;
 
1736
      }
 
1737
    }
 
1738
 
 
1739
    /* If the new part contains a space, this is a mighty stupid redirect
 
1740
       but we still make an effort to do "right". To the left of a '?'
 
1741
       letter we replace each space with %20 while it is replaced with '+'
 
1742
       on the right side of the '?' letter.
 
1743
    */
 
1744
    newlen = strlen_url(useurl);
 
1745
 
 
1746
    urllen = strlen(url_clone);
 
1747
    
 
1748
    newest=(char *)malloc( urllen + 1 + /* possible slash */
 
1749
                           newlen + 1 /* zero byte */);
 
1750
    
 
1751
    if(!newest)
 
1752
      return CURLE_OUT_OF_MEMORY; /* go out from this */
 
1753
 
 
1754
    /* copy over the root url part */
 
1755
    memcpy(newest, url_clone, urllen);
 
1756
 
 
1757
    /* check if we need to append a slash */
 
1758
    if(('/' == useurl[0]) || (protsep && !*protsep))
 
1759
      ;
 
1760
    else
 
1761
      newest[urllen++]='/';
 
1762
 
 
1763
    /* then append the new piece on the right side */
 
1764
    strcpy_url(&newest[urllen], useurl);
 
1765
 
 
1766
    free(newurl); /* newurl is the allocated pointer */
 
1767
    free(url_clone);
 
1768
    newurl = newest;
 
1769
  }
 
1770
  else {
 
1771
    /* This is an absolute URL, don't allow the custom port number */
 
1772
    data->state.allow_port = FALSE;
 
1773
 
 
1774
    if(strchr(newurl, ' ')) {
 
1775
      /* This new URL contains at least one space, this is a mighty stupid
 
1776
         redirect but we still make an effort to do "right". */
 
1777
      newlen = strlen_url(newurl);
 
1778
 
 
1779
      newest = malloc(newlen+1); /* get memory for this */
 
1780
      if(newest) {
 
1781
        strcpy_url(newest, newurl); /* create a space-free URL */
 
1782
 
 
1783
        free(newurl); /* that was no good */
 
1784
        newurl = newest; /* use this instead now */
 
1785
      }
 
1786
    }
 
1787
 
 
1788
  }
 
1789
 
 
1790
  if(data->change.url_alloc)
 
1791
    free(data->change.url);
 
1792
  else
 
1793
    data->change.url_alloc = TRUE; /* the URL is allocated */
 
1794
      
 
1795
  data->change.url = newurl;
 
1796
  newurl = NULL; /* don't free! */
 
1797
 
 
1798
  infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
 
1799
 
 
1800
  /*
 
1801
   * We get here when the HTTP code is 300-399 (and 401). We need to perform
 
1802
   * differently based on exactly what return code there was.
 
1803
   *
 
1804
   * News from 7.10.6: we can also get here on a 401, in case we act on a
 
1805
   * HTTP authentication scheme other than Basic.
 
1806
   */
 
1807
  switch(data->info.httpcode) {
 
1808
  case 401:
 
1809
    /* Act on an authentication, we keep on moving and do the Authorization:
 
1810
       XXXX header in the HTTP request code snippet */
 
1811
    break;
 
1812
  case 300: /* Multiple Choices */
 
1813
  case 306: /* Not used */
 
1814
  case 307: /* Temporary Redirect */
 
1815
  default:  /* for all unknown ones */
 
1816
    /* These are explicitly mention since I've checked RFC2616 and they
 
1817
     * seem to be OK to POST to.
 
1818
     */
 
1819
    break;
 
1820
  case 301: /* Moved Permanently */
 
1821
    /* (quote from RFC2616, section 10.3.2):
 
1822
     * 
 
1823
     *  Note: When automatically redirecting a POST request after
 
1824
     *  receiving a 301 status code, some existing HTTP/1.0 user agents
 
1825
     *  will erroneously change it into a GET request.
 
1826
     *
 
1827
     * ----
 
1828
     * Warning: Because most of importants user agents do this clear
 
1829
     * RFC2616 violation, many webservers expect this misbehavior. So
 
1830
     * these servers often answers to a POST request with an error page.
 
1831
     * To be sure that libcurl gets the page that most user agents
 
1832
     * would get, libcurl has to force GET:
 
1833
     */
 
1834
    if( data->set.httpreq == HTTPREQ_POST
 
1835
        || data->set.httpreq == HTTPREQ_POST_FORM) {
 
1836
      infof(data,
 
1837
            "Violate RFC 2616/10.3.2 and switch from POST to GET\n");
 
1838
      data->set.httpreq = HTTPREQ_GET;
 
1839
    }
 
1840
    break;
 
1841
  case 302: /* Found */
 
1842
    /* (From 10.3.3)
 
1843
       
 
1844
    Note: RFC 1945 and RFC 2068 specify that the client is not allowed
 
1845
    to change the method on the redirected request.  However, most
 
1846
    existing user agent implementations treat 302 as if it were a 303
 
1847
    response, performing a GET on the Location field-value regardless
 
1848
    of the original request method. The status codes 303 and 307 have
 
1849
    been added for servers that wish to make unambiguously clear which
 
1850
    kind of reaction is expected of the client.
 
1851
    
 
1852
    (From 10.3.4)
 
1853
    
 
1854
    Note: Many pre-HTTP/1.1 user agents do not understand the 303
 
1855
    status. When interoperability with such clients is a concern, the
 
1856
    302 status code may be used instead, since most user agents react
 
1857
    to a 302 response as described here for 303.             
 
1858
    */
 
1859
  case 303: /* See Other */
 
1860
    /* Disable both types of POSTs, since doing a second POST when
 
1861
     * following isn't what anyone would want! */
 
1862
    if(data->set.httpreq != HTTPREQ_GET) {
 
1863
      data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
 
1864
      infof(data, "Disables POST, goes with %s\n",
 
1865
            data->set.opt_no_body?"HEAD":"GET");
 
1866
    }
 
1867
    break;
 
1868
  case 304: /* Not Modified */
 
1869
    /* 304 means we did a conditional request and it was "Not modified".
 
1870
     * We shouldn't get any Location: header in this response!
 
1871
     */
 
1872
    break;
 
1873
  case 305: /* Use Proxy */
 
1874
    /* (quote from RFC2616, section 10.3.6):
 
1875
     * "The requested resource MUST be accessed through the proxy given
 
1876
     * by the Location field. The Location field gives the URI of the
 
1877
     * proxy.  The recipient is expected to repeat this single request
 
1878
     * via the proxy. 305 responses MUST only be generated by origin
 
1879
     * servers."
 
1880
     */
 
1881
    break;
 
1882
  }
 
1883
  Curl_pgrsTime(data, TIMER_REDIRECT);
 
1884
  Curl_pgrsResetTimes(data);
 
1885
 
 
1886
  return CURLE_OK;
 
1887
}
 
1888
 
1078
1889
CURLcode Curl_perform(struct SessionHandle *data)
1079
1890
{
1080
1891
  CURLcode res;
1082
1893
  struct connectdata *conn=NULL;
1083
1894
  char *newurl = NULL; /* possibly a new URL to follow to! */
1084
1895
 
 
1896
  data->state.used_interface = Curl_if_easy;
 
1897
 
1085
1898
  res = Curl_pretransfer(data);
1086
1899
  if(res)
1087
1900
    return res;
1088
1901
 
1089
1902
  /*
1090
 
   * It is important that there is NO 'return' from this function any any
1091
 
   * other place than falling down the bottom! This is because we have cleanup
1092
 
   * stuff that must be done before we get back, and that is only performed
1093
 
   * after this do-while loop.
 
1903
   * It is important that there is NO 'return' from this function at any other
 
1904
   * place than falling down to the end of the function! This is because we
 
1905
   * have cleanup stuff that must be done before we get back, and that is only
 
1906
   * performed after this do-while loop.
1094
1907
   */
1095
1908
 
1096
 
  do {
1097
 
    Curl_pgrsTime(data, TIMER_STARTSINGLE);
1098
 
    res = Curl_connect(data, &conn);
 
1909
  do {  
 
1910
    int urlchanged = FALSE;
 
1911
    do {
 
1912
      bool async;
 
1913
      Curl_pgrsTime(data, TIMER_STARTSINGLE);
 
1914
      data->change.url_changed = FALSE;
 
1915
      res = Curl_connect(data, &conn, &async);
 
1916
 
 
1917
      if((CURLE_OK == res) && async) {
 
1918
        /* Now, if async is TRUE here, we need to wait for the name
 
1919
           to resolve */
 
1920
        res = Curl_wait_for_resolv(conn, NULL);
 
1921
        if(CURLE_OK == res)
 
1922
          /* Resolved, continue with the connection */
 
1923
          res = Curl_async_resolved(conn);              
 
1924
      }
 
1925
      if(res)
 
1926
        break;
 
1927
      
 
1928
      /* If a callback (or something) has altered the URL we should use within
 
1929
         the Curl_connect(), we detect it here and act as if we are redirected
 
1930
         to the new URL */
 
1931
      urlchanged = data->change.url_changed;
 
1932
      if ((CURLE_OK == res) && urlchanged) {
 
1933
        res = Curl_done(conn);
 
1934
        if(CURLE_OK == res) {
 
1935
          char *gotourl = strdup(data->change.url);
 
1936
          res = Curl_follow(data, gotourl);
 
1937
          if(res)
 
1938
            free(gotourl);
 
1939
        }
 
1940
      }
 
1941
    } while (urlchanged && res == CURLE_OK) ; 
 
1942
 
1099
1943
    if(res == CURLE_OK) {
1100
1944
      res = Curl_do(&conn);
1101
1945
 
1102
1946
      if(res == CURLE_OK) {
1103
 
        CURLcode res2; /* just a local extra result container */
1104
 
 
1105
 
        if(conn->protocol&PROT_FTPS)
1106
 
          /* FTPS, disable ssl while transfering data */
1107
 
          conn->ssl.use = FALSE;
1108
1947
        res = Transfer(conn); /* now fetch that URL please */
1109
 
        if(conn->protocol&PROT_FTPS)
1110
 
          /* FTPS, enable ssl again after havving transferred data */
1111
 
          conn->ssl.use = TRUE;
1112
 
 
1113
 
        if(res == CURLE_OK)
1114
 
          /*
1115
 
           * We must duplicate the new URL here as the connection data
1116
 
           * may be free()ed in the Curl_done() function.
1117
 
           */
1118
 
          newurl = conn->newurl?strdup(conn->newurl):NULL;
1119
 
        else
 
1948
        if(res == CURLE_OK) {
 
1949
 
 
1950
          if((conn->keep.bytecount+conn->headerbytecount == 0) &&
 
1951
             conn->bits.reuse) {
 
1952
            /* We got no data and we attempted to re-use a connection. This
 
1953
               might happen if the connection was left alive when we were done
 
1954
               using it before, but that was closed when we wanted to read
 
1955
               from it again. Bad luck. Retry the same request on a fresh
 
1956
               connect! */
 
1957
            infof(data, "Connection died, retrying a fresh connect\n");
 
1958
            newurl = strdup(conn->data->change.url);
 
1959
 
 
1960
            conn->bits.close = TRUE; /* close this connection */
 
1961
            conn->bits.retry = TRUE; /* mark this as a connection we're about
 
1962
                                        to retry. Marking it this way should
 
1963
                                        prevent i.e HTTP transfers to return
 
1964
                                        error just because nothing has been
 
1965
                                        transfered! */
 
1966
          }
 
1967
          else
 
1968
            /*
 
1969
             * We must duplicate the new URL here as the connection data
 
1970
             * may be free()ed in the Curl_done() function.
 
1971
             */
 
1972
            newurl = conn->newurl?strdup(conn->newurl):NULL;
 
1973
        }
 
1974
        else {
1120
1975
          /* The transfer phase returned error, we mark the connection to get
1121
1976
           * closed to prevent being re-used. This is becasue we can't
1122
1977
           * possibly know if the connection is in a good shape or not now. */
1123
1978
          conn->bits.close = TRUE;
1124
1979
 
 
1980
          if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
 
1981
            /* if we failed anywhere, we must clean up the secondary socket if
 
1982
               it was used */
 
1983
            sclose(conn->sock[SECONDARYSOCKET]);
 
1984
            conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
 
1985
          }
 
1986
        }
 
1987
 
1125
1988
        /* Always run Curl_done(), even if some of the previous calls
1126
1989
           failed, but return the previous (original) error code */
1127
1990
        res2 = Curl_done(conn);
1136
1999
       */
1137
2000
 
1138
2001
      if((res == CURLE_OK) && newurl) {
1139
 
        /* Location: redirect
1140
 
 
1141
 
           This is assumed to happen for HTTP(S) only!
1142
 
        */
1143
 
        char prot[16]; /* URL protocol string storage */
1144
 
        char letter;   /* used for a silly sscanf */
1145
 
 
1146
 
        if (data->set.maxredirs && (data->set.followlocation >= data->set.maxredirs)) {
1147
 
          failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
1148
 
          res=CURLE_TOO_MANY_REDIRECTS;
1149
 
          break;
1150
 
        }
1151
 
 
1152
 
        /* mark the next request as a followed location: */
1153
 
        data->state.this_is_a_follow = TRUE;
1154
 
 
1155
 
        data->set.followlocation++; /* count location-followers */
1156
 
 
1157
 
        if(data->set.http_auto_referer) {
1158
 
          /* We are asked to automatically set the previous URL as the
1159
 
             referer when we get the next URL. We pick the ->url field,
1160
 
             which may or may not be 100% correct */
1161
 
 
1162
 
          if(data->change.referer_alloc)
1163
 
            /* If we already have an allocated referer, free this first */
1164
 
            free(data->change.referer);
1165
 
 
1166
 
          data->change.referer = strdup(data->change.url);
1167
 
          data->change.referer_alloc = TRUE; /* yes, free this later */
1168
 
        }
1169
 
 
1170
 
        if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) {
1171
 
          /***
1172
 
           *DANG* this is an RFC 2068 violation. The URL is supposed
1173
 
           to be absolute and this doesn't seem to be that!
1174
 
           ***
1175
 
           Instead, we have to TRY to append this new path to the old URL
1176
 
           to the right of the host part. Oh crap, this is doomed to cause
1177
 
           problems in the future...
1178
 
          */
1179
 
          char *protsep;
1180
 
          char *pathsep;
1181
 
          char *newest;
1182
 
 
1183
 
          /* we must make our own copy of the URL to play with, as it may
1184
 
             point to read-only data */
1185
 
          char *url_clone=strdup(data->change.url);
1186
 
 
1187
 
          if(!url_clone) {
1188
 
            res = CURLE_OUT_OF_MEMORY;
1189
 
            break; /* skip out of this loop NOW */
1190
 
          }
1191
 
 
1192
 
          /* protsep points to the start of the host name */
1193
 
          protsep=strstr(url_clone, "//");
1194
 
          if(!protsep)
1195
 
            protsep=url_clone;
1196
 
          else
1197
 
            protsep+=2; /* pass the slashes */
1198
 
 
1199
 
          if('/' != newurl[0]) {
1200
 
            /* First we need to find out if there's a ?-letter in the URL,
1201
 
               and cut it and the right-side of that off */
1202
 
            pathsep = strrchr(protsep, '?');
1203
 
            if(pathsep)
1204
 
              *pathsep=0;
1205
 
 
1206
 
            /* we have a relative path to append to the last slash if
1207
 
               there's one available */
1208
 
            pathsep = strrchr(protsep, '/');
1209
 
            if(pathsep)
1210
 
              *pathsep=0;
1211
 
          }
1212
 
          else {
1213
 
            /* We got a new absolute path for this server, cut off from the
1214
 
               first slash */
1215
 
            pathsep = strchr(protsep, '/');
1216
 
            if(pathsep)
1217
 
              *pathsep=0;
1218
 
          }
1219
 
 
1220
 
          newest=(char *)malloc( strlen(url_clone) +
1221
 
                                 1 + /* possible slash */
1222
 
                                 strlen(newurl) + 1/* zero byte */);
1223
 
 
1224
 
          if(!newest) {
1225
 
            res = CURLE_OUT_OF_MEMORY;
1226
 
            break; /* go go go out from this loop */
1227
 
          }
1228
 
          sprintf(newest, "%s%s%s", url_clone, ('/' == newurl[0])?"":"/",
1229
 
                  newurl);
1230
 
          free(newurl);
1231
 
          free(url_clone);
1232
 
          newurl = newest;
1233
 
        }
1234
 
        else
1235
 
          /* This is an absolute URL, don't allow the custom port number */
1236
 
          data->state.allow_port = FALSE;
1237
 
 
1238
 
        if(data->change.url_alloc)
1239
 
          free(data->change.url);
1240
 
        else
1241
 
          data->change.url_alloc = TRUE; /* the URL is allocated */
1242
 
      
1243
 
        /* TBD: set the URL with curl_setopt() */
1244
 
        data->change.url = newurl;
1245
 
        newurl = NULL; /* don't free! */
1246
 
 
1247
 
        infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
1248
 
 
1249
 
        /*
1250
 
         * We get here when the HTTP code is 300-399. We need to perform
1251
 
         * differently based on exactly what return code there was.
1252
 
         * Discussed on the curl mailing list and posted about on the 26th
1253
 
         * of January 2001.
1254
 
         */
1255
 
        switch(data->info.httpcode) {
1256
 
        case 300: /* Multiple Choices */
1257
 
        case 301: /* Moved Permanently */
1258
 
        case 306: /* Not used */
1259
 
        case 307: /* Temporary Redirect */
1260
 
        default:  /* for all unknown ones */
1261
 
          /* These are explicitly mention since I've checked RFC2616 and they
1262
 
           * seem to be OK to POST to.
1263
 
           */
1264
 
          break;
1265
 
        case 302: /* Found */
1266
 
          /* (From 10.3.3)
1267
 
 
1268
 
            Note: RFC 1945 and RFC 2068 specify that the client is not allowed
1269
 
            to change the method on the redirected request.  However, most
1270
 
            existing user agent implementations treat 302 as if it were a 303
1271
 
            response, performing a GET on the Location field-value regardless
1272
 
            of the original request method. The status codes 303 and 307 have
1273
 
            been added for servers that wish to make unambiguously clear which
1274
 
            kind of reaction is expected of the client.
1275
 
 
1276
 
            (From 10.3.4)
1277
 
 
1278
 
            Note: Many pre-HTTP/1.1 user agents do not understand the 303
1279
 
            status. When interoperability with such clients is a concern, the
1280
 
            302 status code may be used instead, since most user agents react
1281
 
            to a 302 response as described here for 303.             
1282
 
          */
1283
 
        case 303: /* See Other */
1284
 
          /* Disable both types of POSTs, since doing a second POST when
1285
 
           * following isn't what anyone would want! */
1286
 
          data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
1287
 
          infof(data, "Disables POST, goes with GET\n");
1288
 
          break;
1289
 
        case 304: /* Not Modified */
1290
 
          /* 304 means we did a conditional request and it was "Not modified".
1291
 
           * We shouldn't get any Location: header in this response!
1292
 
           */
1293
 
          break;
1294
 
        case 305: /* Use Proxy */
1295
 
          /* (quote from RFC2616, section 10.3.6):
1296
 
           * "The requested resource MUST be accessed through the proxy given
1297
 
           * by the Location field. The Location field gives the URI of the
1298
 
           * proxy.  The recipient is expected to repeat this single request
1299
 
           * via the proxy. 305 responses MUST only be generated by origin
1300
 
           * servers."
1301
 
           */
1302
 
          break;
1303
 
        }
1304
 
        continue;
 
2002
        res = Curl_follow(data, newurl);
 
2003
        if(CURLE_OK == res) {
 
2004
          newurl = NULL;
 
2005
          continue;
 
2006
        }
1305
2007
      }
1306
2008
    }
1307
2009
    break; /* it only reaches here when this shouldn't loop */
1322
2024
 
1323
2025
CURLcode 
1324
2026
Curl_Transfer(struct connectdata *c_conn, /* connection data */
1325
 
              int sockfd,       /* socket to read from or -1 */
1326
 
              int size,         /* -1 if unknown at this point */
1327
 
              bool getheader,   /* TRUE if header parsing is wanted */
1328
 
              long *bytecountp, /* return number of bytes read or NULL */
1329
 
              int writesockfd,  /* socket to write to, it may very well be
1330
 
                                   the same we read from. -1 disables */
1331
 
              long *writebytecountp /* return number of bytes written or
 
2027
              int sockindex,       /* socket index to read from or -1 */
 
2028
              curl_off_t size,     /* -1 if unknown at this point */
 
2029
              bool getheader,      /* TRUE if header parsing is wanted */
 
2030
              curl_off_t *bytecountp, /* return number of bytes read or NULL */
 
2031
              int writesockindex,  /* socket index to write to, it may very
 
2032
                                      well be the same we read from. -1
 
2033
                                      disables */
 
2034
              curl_off_t *writecountp /* return number of bytes written or
1332
2035
                                       NULL */
1333
2036
              )
1334
2037
{
1336
2039
  if(!conn)
1337
2040
    return CURLE_BAD_FUNCTION_ARGUMENT;
1338
2041
 
 
2042
  curlassert((sockindex <= 1) && (sockindex >= -1));
 
2043
 
1339
2044
  /* now copy all input parameters */
1340
 
  conn->sockfd = sockfd;
 
2045
  conn->sockfd = sockindex==-1?
 
2046
    CURL_SOCKET_BAD:conn->sock[sockindex];
1341
2047
  conn->size = size;
1342
 
  conn->getheader = getheader;
 
2048
  conn->bits.getheader = getheader;
1343
2049
  conn->bytecountp = bytecountp;
1344
 
  conn->writesockfd = writesockfd;
1345
 
  conn->writebytecountp = writebytecountp;
 
2050
  conn->writesockfd = writesockindex==-1?
 
2051
    CURL_SOCKET_BAD:conn->sock[writesockindex];
 
2052
  conn->writebytecountp = writecountp;
1346
2053
 
1347
2054
  return CURLE_OK;
1348
2055
 
1349
2056
}
1350
 
          
1351
 
/*
1352
 
 * local variables:
1353
 
 * eval: (load-file "../curl-mode.el")
1354
 
 * end:
1355
 
 * vim600: fdm=marker
1356
 
 * vim: et sw=2 ts=2 sts=2 tw=78
1357
 
 */