Loading CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,9 @@ Changelog Daniel S (11 Jan 2008) - Daniel Egger made CURLOPT_RANGE work on file:// URLs the very same way it already worked for FTP:// URLs. - I made the curl tool switch from using CURLOPT_IOCTLFUNCTION to now use the spanking new CURLOPT_SEEKFUNCTION simply to take advantage of the improved performance for the upload resume cases where you want to upload the last Loading RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ This release includes the following bugfixes: o time zone offsets from -1400 to +1400 are now accepted by the date parser o allows more spaces in WWW/Proxy-Authenticate: headers o curl-config --libs skips /usr/lib64 o range support for file:// transfers This release includes the following known bugs: Loading docs/curl.1 +3 −3 Original line number Diff line number Diff line Loading @@ -974,9 +974,9 @@ This option can be used multiple times. random data. The data is used to seed the random engine for SSL connections. See also the \fI--egd-file\fP option. .IP "-r/--range <range>" (HTTP/FTP) Retrieve a byte range (i.e a partial document) from a HTTP/1.1 or FTP server. Ranges can be specified in a number of ways. (HTTP/FTP/FILE) Retrieve a byte range (i.e a partial document) from a HTTP/1.1, FTP server or a local FILE. Ranges can be specified in a number of ways. .RS .TP 10 .B 0-499 Loading docs/libcurl/curl_easy_setopt.3 +2 −0 Original line number Diff line number Diff line Loading @@ -1119,6 +1119,8 @@ transfers also support several intervals, separated with commas as in \fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP server to send the response document in pieces (using standard MIME separation techniques). Pass a NULL to this option to disable the use of ranges. Ranges work on HTTP, FTP and FILE (since 7.18.0) transfers only. .IP CURLOPT_RESUME_FROM Pass a long as parameter. It contains the offset in number of bytes that you want the transfer to start from. Set this option to 0 to make the transfer Loading lib/file.c +84 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -70,6 +70,7 @@ #endif #include "strtoofft.h" #include "urldata.h" #include <curl/curl.h> #include "progress.h" Loading Loading @@ -119,6 +120,61 @@ const struct Curl_handler Curl_handler_file = { PROT_FILE /* protocol */ }; /* Check if this is a range download, and if so, set the internal variables properly. This code is copied from the FTP implementation and might as well be factored out. */ static CURLcode file_range(struct connectdata *conn) { curl_off_t from, to; curl_off_t totalsize=-1; char *ptr; char *ptr2; struct SessionHandle *data = conn->data; if(data->state.use_range && data->state.range) { from=curlx_strtoofft(data->state.range, &ptr, 0); while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-'))) ptr++; to=curlx_strtoofft(ptr, &ptr2, 0); if(ptr == ptr2) { /* we didn't get any digit */ to=-1; } if((-1 == to) && (from>=0)) { /* X - */ data->state.resume_from = from; DEBUGF(infof(data, "RANGE %" FORMAT_OFF_T " to end of file\n", from)); } else if(from < 0) { /* -Y */ totalsize = -from; data->req.maxdownload = -from; data->state.resume_from = from; DEBUGF(infof(data, "RANGE the last %" FORMAT_OFF_T " bytes\n", totalsize)); } else { /* X-Y */ totalsize = to-from; data->req.maxdownload = totalsize+1; /* include last byte */ data->state.resume_from = from; DEBUGF(infof(data, "RANGE from %" FORMAT_OFF_T " getting %" FORMAT_OFF_T " bytes\n", from, data->req.maxdownload)); } DEBUGF(infof(data, "range-download from %" FORMAT_OFF_T " to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n", from, to, data->req.maxdownload)); } else data->req.maxdownload = -1; return CURLE_OK; } /* * file_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. We emulate a Loading Loading @@ -434,6 +490,20 @@ static CURLcode file_do(struct connectdata *conn, bool *done) return result; } /* Check whether file range has been specified */ file_range(conn); /* Adjust the start offset in case we want to get the N last bytes * of the stream iff the filesize could be determined */ if(data->state.resume_from < 0) { if(!fstated) { failf(data, "Can't get the size of file."); return CURLE_READ_ERROR; } else data->state.resume_from += (curl_off_t)statbuf.st_size; } if(data->state.resume_from <= expected_size) expected_size -= data->state.resume_from; else { Loading @@ -441,6 +511,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done) return CURLE_BAD_DOWNLOAD_RESUME; } /* A high water mark has been specified so we obey... */ if (data->req.maxdownload > 0) expected_size = data->req.maxdownload; if(fstated && (expected_size == 0)) return CURLE_OK; Loading @@ -460,15 +534,20 @@ static CURLcode file_do(struct connectdata *conn, bool *done) Curl_pgrsTime(data, TIMER_STARTTRANSFER); while(res == CURLE_OK) { /* Don't fill a whole buffer if we want less than all data */ if (expected_size < BUFSIZE-1) nread = read(fd, buf, expected_size); else nread = read(fd, buf, BUFSIZE-1); if( nread > 0) buf[nread] = 0; if(nread <= 0) if (nread <= 0 || expected_size == 0) break; bytecount += nread; expected_size -= nread; res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); if(res) Loading Loading
CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,9 @@ Changelog Daniel S (11 Jan 2008) - Daniel Egger made CURLOPT_RANGE work on file:// URLs the very same way it already worked for FTP:// URLs. - I made the curl tool switch from using CURLOPT_IOCTLFUNCTION to now use the spanking new CURLOPT_SEEKFUNCTION simply to take advantage of the improved performance for the upload resume cases where you want to upload the last Loading
RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ This release includes the following bugfixes: o time zone offsets from -1400 to +1400 are now accepted by the date parser o allows more spaces in WWW/Proxy-Authenticate: headers o curl-config --libs skips /usr/lib64 o range support for file:// transfers This release includes the following known bugs: Loading
docs/curl.1 +3 −3 Original line number Diff line number Diff line Loading @@ -974,9 +974,9 @@ This option can be used multiple times. random data. The data is used to seed the random engine for SSL connections. See also the \fI--egd-file\fP option. .IP "-r/--range <range>" (HTTP/FTP) Retrieve a byte range (i.e a partial document) from a HTTP/1.1 or FTP server. Ranges can be specified in a number of ways. (HTTP/FTP/FILE) Retrieve a byte range (i.e a partial document) from a HTTP/1.1, FTP server or a local FILE. Ranges can be specified in a number of ways. .RS .TP 10 .B 0-499 Loading
docs/libcurl/curl_easy_setopt.3 +2 −0 Original line number Diff line number Diff line Loading @@ -1119,6 +1119,8 @@ transfers also support several intervals, separated with commas as in \fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP server to send the response document in pieces (using standard MIME separation techniques). Pass a NULL to this option to disable the use of ranges. Ranges work on HTTP, FTP and FILE (since 7.18.0) transfers only. .IP CURLOPT_RESUME_FROM Pass a long as parameter. It contains the offset in number of bytes that you want the transfer to start from. Set this option to 0 to make the transfer Loading
lib/file.c +84 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -70,6 +70,7 @@ #endif #include "strtoofft.h" #include "urldata.h" #include <curl/curl.h> #include "progress.h" Loading Loading @@ -119,6 +120,61 @@ const struct Curl_handler Curl_handler_file = { PROT_FILE /* protocol */ }; /* Check if this is a range download, and if so, set the internal variables properly. This code is copied from the FTP implementation and might as well be factored out. */ static CURLcode file_range(struct connectdata *conn) { curl_off_t from, to; curl_off_t totalsize=-1; char *ptr; char *ptr2; struct SessionHandle *data = conn->data; if(data->state.use_range && data->state.range) { from=curlx_strtoofft(data->state.range, &ptr, 0); while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-'))) ptr++; to=curlx_strtoofft(ptr, &ptr2, 0); if(ptr == ptr2) { /* we didn't get any digit */ to=-1; } if((-1 == to) && (from>=0)) { /* X - */ data->state.resume_from = from; DEBUGF(infof(data, "RANGE %" FORMAT_OFF_T " to end of file\n", from)); } else if(from < 0) { /* -Y */ totalsize = -from; data->req.maxdownload = -from; data->state.resume_from = from; DEBUGF(infof(data, "RANGE the last %" FORMAT_OFF_T " bytes\n", totalsize)); } else { /* X-Y */ totalsize = to-from; data->req.maxdownload = totalsize+1; /* include last byte */ data->state.resume_from = from; DEBUGF(infof(data, "RANGE from %" FORMAT_OFF_T " getting %" FORMAT_OFF_T " bytes\n", from, data->req.maxdownload)); } DEBUGF(infof(data, "range-download from %" FORMAT_OFF_T " to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n", from, to, data->req.maxdownload)); } else data->req.maxdownload = -1; return CURLE_OK; } /* * file_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. We emulate a Loading Loading @@ -434,6 +490,20 @@ static CURLcode file_do(struct connectdata *conn, bool *done) return result; } /* Check whether file range has been specified */ file_range(conn); /* Adjust the start offset in case we want to get the N last bytes * of the stream iff the filesize could be determined */ if(data->state.resume_from < 0) { if(!fstated) { failf(data, "Can't get the size of file."); return CURLE_READ_ERROR; } else data->state.resume_from += (curl_off_t)statbuf.st_size; } if(data->state.resume_from <= expected_size) expected_size -= data->state.resume_from; else { Loading @@ -441,6 +511,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done) return CURLE_BAD_DOWNLOAD_RESUME; } /* A high water mark has been specified so we obey... */ if (data->req.maxdownload > 0) expected_size = data->req.maxdownload; if(fstated && (expected_size == 0)) return CURLE_OK; Loading @@ -460,15 +534,20 @@ static CURLcode file_do(struct connectdata *conn, bool *done) Curl_pgrsTime(data, TIMER_STARTTRANSFER); while(res == CURLE_OK) { /* Don't fill a whole buffer if we want less than all data */ if (expected_size < BUFSIZE-1) nread = read(fd, buf, expected_size); else nread = read(fd, buf, BUFSIZE-1); if( nread > 0) buf[nread] = 0; if(nread <= 0) if (nread <= 0 || expected_size == 0) break; bytecount += nread; expected_size -= nread; res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); if(res) Loading