diff options
author | Daniel Stenberg <daniel@haxx.se> | 2008-01-10 10:30:19 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2008-01-10 10:30:19 +0000 |
commit | 18faa509403c39b4914114cfe2966241b62b2959 (patch) | |
tree | bb5e0bf7ac66a313e62263348449afbe4ad924c6 /lib/http.c | |
parent | 0ce484eed901f73cae89e25d9939a249729f15d3 (diff) |
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.
Diffstat (limited to 'lib/http.c')
-rw-r--r-- | lib/http.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/lib/http.c b/lib/http.c index e41a8f750..fd58c06cc 100644 --- a/lib/http.c +++ b/lib/http.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1793,6 +1793,8 @@ CURLcode Curl_http_done(struct connectdata *conn, /* set the proper values (possibly modified on POST) */ conn->fread_func = data->set.fread_func; /* restore */ conn->fread_in = data->set.in; /* restore */ + conn->seek_func = data->set.seek_func; /* restore */ + conn->seek_client = data->set.seek_client; /* restore */ if(http == NULL) return CURLE_OK; @@ -2186,30 +2188,41 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(data->state.resume_from && !data->state.this_is_a_follow) { /* do we still game? */ - curl_off_t passed=0; /* Now, 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 */ - do { - size_t readthisamountnow = (size_t)(data->state.resume_from - passed); - size_t actuallyread; - - if(readthisamountnow > BUFSIZE) - readthisamountnow = BUFSIZE; - - actuallyread = - data->set.fread_func(data->state.buffer, 1, (size_t)readthisamountnow, - data->set.in); - - passed += actuallyread; - if(actuallyread != readthisamountnow) { - failf(data, "Could only read %" FORMAT_OFF_T - " bytes from the input", - passed); + 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_READ_ERROR; } - } while(passed != data->state.resume_from); /* loop until done */ + } + else { + curl_off_t passed=0; + + do { + size_t readthisamountnow = (size_t)(data->state.resume_from - passed); + size_t actuallyread; + + if(readthisamountnow > BUFSIZE) + readthisamountnow = BUFSIZE; + + actuallyread = data->set.fread_func(data->state.buffer, 1, + (size_t)readthisamountnow, + data->set.in); + + passed += actuallyread; + if(actuallyread != readthisamountnow) { + failf(data, "Could only read %" FORMAT_OFF_T + " bytes from the input", + passed); + return CURLE_READ_ERROR; + } + } while(passed != data->state.resume_from); /* loop until done */ + } /* now, decrease the size of the read */ if(data->set.infilesize>0) { |