~ubuntu-branches/ubuntu/gutsy/curl/gutsy

« back to all changes in this revision

Viewing changes to lib/transfer.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2006-06-29 15:04:24 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20060629150424-be178abcwks1n519
Tags: upstream-7.15.4
ImportĀ upstreamĀ versionĀ 7.15.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
9
9
 *
10
10
 * This software is licensed as described in the file COPYING, which
11
11
 * you should have received as part of this distribution. The terms
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: transfer.c,v 1.290 2005/11/24 10:22:47 bagder Exp $
 
21
 * $Id: transfer.c,v 1.299 2006-06-09 07:08:34 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
101
101
#include "share.h"
102
102
#include "memory.h"
103
103
#include "select.h"
 
104
#include "multiif.h"
 
105
#include "easyif.h" /* for Curl_convert_to_network prototype */
104
106
 
105
107
#define _MPRINTF_REPLACE /* use our functions only */
106
108
#include <curl/mprintf.h>
167
169
 
168
170
  *nreadp = nread;
169
171
 
 
172
#ifdef CURL_DOES_CONVERSIONS
 
173
  if(data->ftp_in_ascii_mode) {
 
174
    CURLcode res;
 
175
    res = Curl_convert_to_network(data, conn->upload_fromhere, nread);
 
176
    /* Curl_convert_to_network calls failf if unsuccessful */
 
177
    if(res != CURLE_OK) {
 
178
      return(res);
 
179
    }
 
180
  }
 
181
#endif /* CURL_DOES_CONVERSIONS */
 
182
 
170
183
  return CURLE_OK;
171
184
}
172
185
 
1158
1171
 
1159
1172
              case DEFLATE:
1160
1173
                /* Assume CLIENTWRITE_BODY; headers are not encoded. */
1161
 
                result = Curl_unencode_deflate_write(data, k, nread);
 
1174
                if(!k->ignorebody)
 
1175
                  result = Curl_unencode_deflate_write(data, k, nread);
1162
1176
                break;
1163
1177
 
1164
1178
              case GZIP:
1165
1179
                /* Assume CLIENTWRITE_BODY; headers are not encoded. */
1166
 
                result = Curl_unencode_gzip_write(data, k, nread);
 
1180
                if(!k->ignorebody)
 
1181
                  result = Curl_unencode_gzip_write(data, k, nread);
1167
1182
                break;
1168
1183
 
1169
1184
              case COMPRESS:
1266
1281
          conn->upload_present = nread;
1267
1282
 
1268
1283
          /* convert LF to CRLF if so asked */
 
1284
#ifdef CURL_DO_LINEEND_CONV
 
1285
          /* always convert if we're FTPing in ASCII mode */
 
1286
          if ((data->set.crlf) || (data->ftp_in_ascii_mode)) {
 
1287
#else
1269
1288
          if (data->set.crlf) {
 
1289
#endif /* CURL_DO_LINEEND_CONV */
1270
1290
              if(data->state.scratch == NULL)
1271
1291
                data->state.scratch = malloc(2*BUFSIZE);
1272
1292
              if(data->state.scratch == NULL) {
1273
1293
                failf (data, "Failed to alloc scratch buffer!");
1274
1294
                return CURLE_OUT_OF_MEMORY;
1275
1295
              }
 
1296
              /*
 
1297
               * ASCII/EBCDIC Note: This is presumably a text (not binary)
 
1298
               * transfer so the data should already be in ASCII.
 
1299
               * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
 
1300
               * must be used instead of the escape sequences \r & \n.
 
1301
               */
1276
1302
            for(i = 0, si = 0; i < nread; i++, si++) {
1277
1303
              if (conn->upload_fromhere[i] == 0x0a) {
1278
1304
                data->state.scratch[si++] = 0x0d;
1279
1305
                data->state.scratch[si] = 0x0a;
 
1306
                if (!data->set.crlf) {
 
1307
                  /* we're here only because FTP is in ASCII mode...
 
1308
                     bump infilesize for the LF we just added */
 
1309
                  data->set.infilesize++;
 
1310
                }
1280
1311
              }
1281
1312
              else
1282
1313
                data->state.scratch[si] = conn->upload_fromhere[i];
1402
1433
 
1403
1434
    if(!(conn->bits.no_body) && (conn->size != -1) &&
1404
1435
       (k->bytecount != conn->size) &&
 
1436
#ifdef CURL_DO_LINEEND_CONV
 
1437
       /* Most FTP servers don't adjust their file SIZE response for CRLFs,
 
1438
          so we'll check to see if the discrepancy can be explained
 
1439
          by the number of CRLFs we've changed to LFs.
 
1440
        */
 
1441
       (k->bytecount != (conn->size + data->state.crlf_conversions)) &&
 
1442
#endif /* CURL_DO_LINEEND_CONV */
1405
1443
       !conn->newurl) {
1406
1444
      failf(data, "transfer closed with %" FORMAT_OFF_T
1407
1445
            " bytes remaining to read",
1508
1546
}
1509
1547
 
1510
1548
/*
1511
 
 * Curl_single_fdset() gets called by the multi interface code when the app
1512
 
 * has requested to get the fd_sets for the current connection. This function
 
1549
 * Curl_single_getsock() gets called by the multi interface code when the app
 
1550
 * has requested to get the sockets for the current connection. This function
1513
1551
 * will then be called once for every connection that the multi interface
1514
1552
 * keeps track of. This function will only be called for connections that are
1515
1553
 * in the proper state to have this information available.
1516
1554
 */
1517
 
void Curl_single_fdset(struct connectdata *conn,
1518
 
                       fd_set *read_fd_set,
1519
 
                       fd_set *write_fd_set,
1520
 
                       fd_set *exc_fd_set,
1521
 
                       int *max_fd)
 
1555
int Curl_single_getsock(struct connectdata *conn,
 
1556
                        curl_socket_t *sock, /* points to numsocks number
 
1557
                                                of sockets */
 
1558
                        int numsocks)
1522
1559
{
1523
 
  *max_fd = -1; /* init */
 
1560
  int bitmap = GETSOCK_BLANK;
 
1561
  int index = 0;
 
1562
 
 
1563
  if(numsocks < 2)
 
1564
    /* simple check but we might need two slots */
 
1565
    return GETSOCK_BLANK;
 
1566
 
1524
1567
  if(conn->keep.keepon & KEEP_READ) {
1525
 
    FD_SET(conn->sockfd, read_fd_set);
1526
 
    *max_fd = (int)conn->sockfd;
 
1568
    bitmap |= GETSOCK_READSOCK(index);
 
1569
    sock[index] = conn->sockfd;
1527
1570
  }
1528
1571
  if(conn->keep.keepon & KEEP_WRITE) {
1529
 
    FD_SET(conn->writesockfd, write_fd_set);
1530
 
 
1531
 
    /* since sockets are curl_socket_t nowadays, we typecast it to int here
1532
 
       to compare it nicely */
1533
 
    if((int)conn->writesockfd > *max_fd)
1534
 
      *max_fd = (int)conn->writesockfd;
 
1572
 
 
1573
    if((conn->sockfd != conn->writesockfd) ||
 
1574
       !(conn->keep.keepon & KEEP_READ)) {
 
1575
      /* only if they are not the same socket or we didn't have a readable
 
1576
         one, we increase index */
 
1577
      if(conn->keep.keepon & KEEP_READ)
 
1578
        index++; /* increase index if we need two entries */
 
1579
      sock[index] = conn->writesockfd;
 
1580
    }
 
1581
 
 
1582
    bitmap |= GETSOCK_WRITESOCK(index);
1535
1583
  }
1536
 
  /* we don't use exceptions, only touch that one to prevent compiler
1537
 
     warnings! */
1538
 
  *exc_fd_set = *exc_fd_set;
 
1584
 
 
1585
  return bitmap;
1539
1586
}
1540
1587
 
1541
1588
 
1765
1812
  size_t newlen;
1766
1813
  char *newest;
1767
1814
 
1768
 
  if ((data->set.maxredirs != -1) &&
1769
 
      (data->set.followlocation >= data->set.maxredirs)) {
1770
 
    failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
1771
 
    return CURLE_TOO_MANY_REDIRECTS;
1772
 
  }
 
1815
  if(!retry) {
 
1816
    if ((data->set.maxredirs != -1) &&
 
1817
        (data->set.followlocation >= data->set.maxredirs)) {
 
1818
      failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
 
1819
      return CURLE_TOO_MANY_REDIRECTS;
 
1820
    }
1773
1821
 
1774
 
  if(!retry)
1775
1822
    /* mark the next request as a followed location: */
1776
1823
    data->state.this_is_a_follow = TRUE;
1777
1824
 
1778
 
  data->set.followlocation++; /* count location-followers */
 
1825
    data->set.followlocation++; /* count location-followers */
 
1826
  }
1779
1827
 
1780
1828
  if(data->set.http_auto_referer) {
1781
1829
    /* We are asked to automatically set the previous URL as the
1824
1872
 
1825
1873
      /* First we need to find out if there's a ?-letter in the URL,
1826
1874
         and cut it and the right-side of that off */
1827
 
      pathsep = strrchr(protsep, '?');
 
1875
      pathsep = strchr(protsep, '?');
1828
1876
      if(pathsep)
1829
1877
        *pathsep=0;
1830
1878
 
2099
2147
  bool retry = FALSE;
2100
2148
 
2101
2149
  if((conn->keep.bytecount+conn->headerbytecount == 0) &&
2102
 
     conn->bits.reuse) {
2103
 
    /* We got no data and we attempted to re-use a connection. This might
2104
 
       happen if the connection was left alive when we were done using it
2105
 
       before, but that was closed when we wanted to read from it again. Bad
2106
 
       luck. Retry the same request on a fresh connect! */
 
2150
     conn->bits.reuse &&
 
2151
     !conn->bits.no_body) {
 
2152
    /* We got no data, we attempted to re-use a connection and yet we want a
 
2153
       "body". This might happen if the connection was left alive when we were
 
2154
       done using it before, but that was closed when we wanted to read from
 
2155
       it again. Bad luck. Retry the same request on a fresh connect! */
2107
2156
    infof(conn->data, "Connection died, retrying a fresh connect\n");
2108
2157
    *url = strdup(conn->data->change.url);
2109
2158
 
2157
2206
 
2158
2207
    if(res == CURLE_OK) {
2159
2208
      bool do_done;
 
2209
      if(data->set.connect_only) {
 
2210
        /* keep connection open for application to use the socket */
 
2211
        conn->bits.close = FALSE;
 
2212
        res = Curl_done(&conn, CURLE_OK);
 
2213
        break;
 
2214
      }
2160
2215
      res = Curl_do(&conn, &do_done);
2161
2216
 
2162
2217
      /* for non 3rd party transfer only */