Commit 18faa509 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Georg Lippitsch brought CURLOPT_SEEKFUNCTION and CURLOPT_SEEKDATA to allow

libcurl to seek in a given input stream. This is particularly important when
doing upload resumes when there's already a huge part of the file present
remotely. Before, and still if this callback isn't used, libcurl will read
and through away the entire file up to the point to where the resuming
begins (which of course can be a slow opereration depending on file size,
I/O bandwidth and more). This new function will also be preferred to get
used instead of the CURLOPT_IOCTLFUNCTION for seeking back in a stream when
doing multi-stage HTTP auth with POST/PUT.
parent 0ce484ee
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -7,6 +7,16 @@
                                  Changelog

Daniel S (10 Jan 2008)
- Georg Lippitsch brought CURLOPT_SEEKFUNCTION and CURLOPT_SEEKDATA to allow
  libcurl to seek in a given input stream. This is particularly important when
  doing upload resumes when there's already a huge part of the file present
  remotely. Before, and still if this callback isn't used, libcurl will read
  and through away the entire file up to the point to where the resuming
  begins (which of course can be a slow opereration depending on file size,
  I/O bandwidth and more). This new function will also be preferred to get
  used instead of the CURLOPT_IOCTLFUNCTION for seeking back in a stream when
  doing multi-stage HTTP auth with POST/PUT.

- Nikitinskit Dmitriy filed bug report #1868255
  (http://curl.haxx.se/bug/view.cgi?id=1868255) with a patch. It identifies
  and fixes a problem with parsing WWW-Authenticate: headers with additional
+8 −7
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ Curl and libcurl 7.18.0

 Public curl releases:         103
 Command line options:         125
 curl_easy_setopt() options:   148
 curl_easy_setopt() options:   150
 Public functions in libcurl:  56
 Public web site mirrors:      42
 Known libcurl bindings:       36
@@ -10,13 +10,14 @@ Curl and libcurl 7.18.0

This release includes the following changes:
 
 o --data-urlencode was added
 o CURLOPT_PROXY_TRANSFER_MODE was added
 o --no-keep-alive was added, since starting now curl is doing connections with
   keep-alive enabled by default
 o --data-urlencode
 o CURLOPT_PROXY_TRANSFER_MODE
 o --no-keep-alive - now curl does connections with keep-alive enabled by
   default
 o --socks4a added (proxy type CURLPROXY_SOCKS4A for libcurl)
 o --socks5-hostname added (CURLPROXY_SOCKS5_HOSTNAME for libcurl)
 o curl_easy_pause() added
 o curl_easy_pause()
 o CURLOPT_SEEKFUNCTION and CURLOPT_SEEKDATA

This release includes the following bugfixes:

@@ -69,6 +70,6 @@ advice from friends like these:
 Emil Romanus, Alessandro Vesely, Ray Pekowski, Spacen Jasset, Andrew Moise,
 Gilles Blanc, David Wright, Vikram Saxena, Mateusz Loskot, Gary Maxwell,
 Dmitry Kurochkin, Mohun Biswas, Richard Atterer, Maxim Perenesenko,
 Daniel Egger, Jeff Johnson
 Daniel Egger, Jeff Johnson, Nikitinskit Dmitriy, Georg Lippitsch
 
        Thanks! (and sorry if I forgot to mention someone)
+22 −1
Original line number Diff line number Diff line
@@ -171,11 +171,32 @@ something special I/O-related needs to be done that the library can't do by
itself. For now, rewinding the read data stream is the only action it can
request. The rewinding of the read data stream may be necessary when doing a
HTTP PUT or POST with a multi-pass authentication method.  (Option added in
7.12.3)
7.12.3).

Use \fICURLOPT_SEEKFUNCTION\fP instead to provide seeking!
.IP CURLOPT_IOCTLDATA
Pass a pointer that will be untouched by libcurl and passed as the 3rd
argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP.  (Option
added in 7.12.3)
.IP CURLOPT_SEEKFUNCTION
Function pointer that should match the following prototype: \fIint
function(void *instream, curl_off_t offset, int origin);\fP This function gets
called by libcurl to seek to a certain position in the input stream and can be
used to fast forward a file in a resumed upload (instead of reading all
uploaded bytes with the normal read function/callback). It is also called to
rewind a stream when doing a HTTP PUT or POST with a multi-pass authentication
method. The function shall work like "fseek" or "lseek" and accepted SEEK_SET,
SEEK_CUR and SEEK_END as argument for origin, although (in 7.18.0) libcurl
only passes SEEK_SET. The callback must return 0 on success as returning
non-zero will cause the upload operation to fail.

If you forward the input arguments directly to "fseek" or "lseek", note that
the data type for \fIoffset\fP is not the same as defined for curl_off_t on
many systems! (Option added in 7.18.0)
.IP CURLOPT_SEEKDATA
Data pointer to pass to the file read function. If you use the
\fICURLOPT_SEEKFUNCTION\fP option, this is the pointer you'll get as input. If
you don't specify a seek callback, NULL is passed. (Option added in 7.18.0)
.IP CURLOPT_SOCKOPTFUNCTION
Function pointer that should match the \fIcurl_sockopt_callback\fP prototype
found in \fI<curl/curl.h>\fP. This function gets called by libcurl after the
+8 −0
Original line number Diff line number Diff line
@@ -244,6 +244,10 @@ typedef size_t (*curl_write_callback)(char *buffer,
/* This is a return code for the read callback that, when returned, will
   signal libcurl to pause sending data on the current transfer. */
#define CURL_READFUNC_PAUSE 0x10000001
typedef int (*curl_seek_callback)(void *instream,
                                  curl_off_t offset,
				  int origin); /* 'whence' */

typedef size_t (*curl_read_callback)(char *buffer,
                                      size_t size,
                                      size_t nitems,
@@ -1180,6 +1184,10 @@ typedef enum {
  /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
  CINIT(PROXY_TRANSFER_MODE, LONG, 166),

  /* Callback function for seeking in the input stream */
  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
  CINIT(SEEKDATA, OBJECTPOINT, 168),

  CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

+30 −23
Original line number Diff line number Diff line
@@ -1525,7 +1525,6 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
  struct FTP *ftp = conn->data->state.proto.ftp;
  struct SessionHandle *data = conn->data;
  struct ftp_conn *ftpc = &conn->proto.ftpc;
  curl_off_t passed=0;

  if((data->state.resume_from && !sizechecked) ||
     ((data->state.resume_from > 0) && sizechecked)) {
@@ -1552,12 +1551,19 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
    /* enable append */
    data->set.ftp_append = TRUE;

    /* Let's read off the proper amount of bytes from the input. If we knew it
       was a proper file we could've just fseek()ed but we only have a stream
       here */
    /* Let's read off the proper amount of bytes from the input. */
    if(conn->seek_func) {
      curl_off_t readthisamountnow = data->state.resume_from;

      if(conn->seek_func(conn->seek_client,
			 readthisamountnow, SEEK_SET) != 0) {
        failf(data, "Could not seek stream");
        return CURLE_FTP_COULDNT_USE_REST;
      }
    }

    /* TODO: allow the ioctlfunction to provide a fast forward function that
       can be used here and use this method only as a fallback! */
    else {
      curl_off_t passed=0;
      do {
        curl_off_t readthisamountnow = (data->state.resume_from - passed);
        curl_off_t actuallyread;
@@ -1577,6 +1583,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
          return CURLE_FTP_COULDNT_USE_REST;
        }
      } while(passed < data->state.resume_from);
    }

    /* now, decrease the size of the read */
    if(data->set.infilesize>0) {
Loading