aboutsummaryrefslogtreecommitdiff
path: root/lib/ftp.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-01-10 10:30:19 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-01-10 10:30:19 +0000
commit18faa509403c39b4914114cfe2966241b62b2959 (patch)
treebb5e0bf7ac66a313e62263348449afbe4ad924c6 /lib/ftp.c
parent0ce484eed901f73cae89e25d9939a249729f15d3 (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/ftp.c')
-rw-r--r--lib/ftp.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 29cbcb0f8..af0fc2f00 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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,31 +1551,39 @@ 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;
- /* TODO: allow the ioctlfunction to provide a fast forward function that
- can be used here and use this method only as a fallback! */
- do {
- curl_off_t readthisamountnow = (data->state.resume_from - passed);
- curl_off_t actuallyread;
-
- if(readthisamountnow > BUFSIZE)
- readthisamountnow = BUFSIZE;
-
- actuallyread = (curl_off_t)
- conn->fread_func(data->state.buffer, 1, (size_t)readthisamountnow,
- conn->fread_in);
-
- passed += actuallyread;
- if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
- /* this checks for greater-than only to make sure that the
- CURL_READFUNC_ABORT return code still aborts */
- failf(data, "Failed to read data");
+ if(conn->seek_func(conn->seek_client,
+ readthisamountnow, SEEK_SET) != 0) {
+ failf(data, "Could not seek stream");
return CURLE_FTP_COULDNT_USE_REST;
}
- } while(passed < data->state.resume_from);
+ }
+
+ else {
+ curl_off_t passed=0;
+ do {
+ curl_off_t readthisamountnow = (data->state.resume_from - passed);
+ curl_off_t actuallyread;
+
+ if(readthisamountnow > BUFSIZE)
+ readthisamountnow = BUFSIZE;
+
+ actuallyread = (curl_off_t)
+ conn->fread_func(data->state.buffer, 1, (size_t)readthisamountnow,
+ conn->fread_in);
+
+ passed += actuallyread;
+ if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
+ /* this checks for greater-than only to make sure that the
+ CURL_READFUNC_ABORT return code still aborts */
+ failf(data, "Failed to read data");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ } while(passed < data->state.resume_from);
+ }
/* now, decrease the size of the read */
if(data->set.infilesize>0) {