mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Daniel Egger made CURLOPT_RANGE work on file:// URLs the very same way it
already worked for FTP:// URLs
This commit is contained in:
parent
e2c817731a
commit
08adf67969
3
CHANGES
3
CHANGES
@ -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
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
89
lib/file.c
89
lib/file.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
|
||||
@ -70,6 +70,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "progress.h"
|
||||
@ -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
|
||||
@ -287,8 +343,8 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||
|
||||
/* treat the negative resume offset value as the case of "-" */
|
||||
if(data->state.resume_from < 0){
|
||||
if(stat(file->path, &file_stat)){
|
||||
if(data->state.resume_from < 0) {
|
||||
if(stat(file->path, &file_stat)) {
|
||||
fclose(fp);
|
||||
failf(data, "Can't get the size of %s", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
@ -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 {
|
||||
@ -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;
|
||||
|
||||
@ -460,15 +534,20 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
|
||||
|
||||
while(res == CURLE_OK) {
|
||||
nread = read(fd, buf, BUFSIZE-1);
|
||||
/* 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)
|
||||
|
@ -28,26 +28,26 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
||||
test194 test195 test196 test197 test198 test515 test516 test517 test518 \
|
||||
test210 test211 test212 test220 test221 test222 test223 test224 test206 \
|
||||
test207 test208 test209 test213 test240 test241 test242 test519 test214 \
|
||||
test215 test216 test217 test218 test199 test225 test226 test227 \
|
||||
test228 test229 test233 test234 test235 test236 test520 \
|
||||
test237 test238 test239 test243 test245 test246 test247 test248 test249 \
|
||||
test250 test251 test252 test253 test254 test255 test521 test522 test523 \
|
||||
test256 test257 test258 test259 test260 test261 test262 test263 test264 \
|
||||
test265 test266 test267 test268 test269 test270 test271 test272 test273 \
|
||||
test274 test275 test524 test525 test276 test277 test526 test527 test528 \
|
||||
test530 DISABLED test278 test279 test531 test280 test529 test532 test533 \
|
||||
test534 test535 test281 test537 test282 test283 test284 test538 test285 \
|
||||
test286 test307 test308 test287 test400 test288 test600 test601 test602 \
|
||||
test603 test401 test402 test290 test291 test292 test293 test403 test404 \
|
||||
test405 test604 test605 test606 test607 test608 test609 test294 test295 \
|
||||
test296 test297 test298 test610 test611 test612 test406 test407 test408 \
|
||||
test409 test613 test614 test700 test701 test702 test704 test705 test703 \
|
||||
test706 test707 test350 test351 test352 test353 test289 test540 test354 \
|
||||
test231 test1000 test1001 test1002 test1003 test1004 test1005 test1006 \
|
||||
test615 test1007 test541 test1010 test1011 test1012 test542 test543 \
|
||||
test536 test1008 test1009 test2000 test2001 test2002 test2003 test35 \
|
||||
test544 test545 test2004 test546 test1013 test1014 test1015 \
|
||||
test547 test548 test549 test550 test551 test552
|
||||
test215 test216 test217 test218 test199 test225 test226 test227 test228 \
|
||||
test229 test233 test234 test235 test236 test520 test237 test238 test239 \
|
||||
test243 test245 test246 test247 test248 test249 test250 test251 test252 \
|
||||
test253 test254 test255 test521 test522 test523 test256 test257 test258 \
|
||||
test259 test260 test261 test262 test263 test264 test265 test266 test267 \
|
||||
test268 test269 test270 test271 test272 test273 test274 test275 test524 \
|
||||
test525 test276 test277 test526 test527 test528 test530 DISABLED test278 \
|
||||
test279 test531 test280 test529 test532 test533 test534 test535 test281 \
|
||||
test537 test282 test283 test284 test538 test285 test286 test307 test308 \
|
||||
test287 test400 test288 test600 test601 test602 test603 test401 test402 \
|
||||
test290 test291 test292 test293 test403 test404 test405 test604 test605 \
|
||||
test606 test607 test608 test609 test294 test295 test296 test297 test298 \
|
||||
test610 test611 test612 test406 test407 test408 test409 test613 test614 \
|
||||
test700 test701 test702 test704 test705 test703 test706 test707 test350 \
|
||||
test351 test352 test353 test289 test540 test354 test231 test1000 test1001 \
|
||||
test1002 test1003 test1004 test1005 test1006 test615 test1007 test541 \
|
||||
test1010 test1011 test1012 test542 test543 test536 test1008 test1009 \
|
||||
test2000 test2001 test2002 test2003 test35 test544 test545 test2004 \
|
||||
test546 test1013 test1014 test1015 test547 test548 test549 test550 \
|
||||
test551 test552 test1016 test1017 test1018 test1019 test1020
|
||||
|
||||
filecheck:
|
||||
@mkdir test-place; \
|
||||
|
35
tests/data/test1016
Normal file
35
tests/data/test1016
Normal file
@ -0,0 +1,35 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FILE
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
<reply>
|
||||
<data>
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
<name>
|
||||
X-Y range on a file:// URL to stdout
|
||||
</name>
|
||||
<command>
|
||||
-r 1-4 file://localhost/%PWD/log/test1016.txt
|
||||
</command>
|
||||
<file name="log/test1016.txt">
|
||||
1234567890
|
||||
</file>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<stdout nonewline="yes">
|
||||
2345
|
||||
</stdout>
|
||||
</verify>
|
||||
</testcase>
|
35
tests/data/test1017
Normal file
35
tests/data/test1017
Normal file
@ -0,0 +1,35 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FILE
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
<name>
|
||||
0-Y range on a file:// URL to stdout
|
||||
</name>
|
||||
<command>
|
||||
-r 0-3 file://localhost/%PWD/log/test1017.txt
|
||||
</command>
|
||||
<file name="log/test1017.txt">
|
||||
1234567890
|
||||
</file>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<stdout nonewline="yes">
|
||||
1234
|
||||
</stdout>
|
||||
</verify>
|
||||
</testcase>
|
35
tests/data/test1018
Normal file
35
tests/data/test1018
Normal file
@ -0,0 +1,35 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FILE
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
<reply>
|
||||
<data>
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
<name>
|
||||
X-X range on a file:// URL to stdout
|
||||
</name>
|
||||
<command>
|
||||
-r 4-4 file://localhost/%PWD/log/test1018.txt
|
||||
</command>
|
||||
<file name="log/test1018.txt">
|
||||
1234567890
|
||||
</file>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<stdout nonewline="yes">
|
||||
5
|
||||
</stdout>
|
||||
</verify>
|
||||
</testcase>
|
37
tests/data/test1019
Normal file
37
tests/data/test1019
Normal file
@ -0,0 +1,37 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FILE
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
<name>
|
||||
X- range on a file:// URL to stdout
|
||||
</name>
|
||||
<command>
|
||||
-r 7- file://localhost/%PWD/log/test1019.txt
|
||||
</command>
|
||||
<file name="log/test1019.txt">
|
||||
1234567890
|
||||
1234567890
|
||||
</file>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<stdout>
|
||||
890
|
||||
1234567890
|
||||
</stdout>
|
||||
</verify>
|
||||
</testcase>
|
37
tests/data/test1020
Normal file
37
tests/data/test1020
Normal file
@ -0,0 +1,37 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
FILE
|
||||
</keywords>
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
none
|
||||
</server>
|
||||
<name>
|
||||
-Y range on a file:// URL to stdout
|
||||
</name>
|
||||
<command>
|
||||
-r -9 file://localhost/%PWD/log/test1020.txt
|
||||
</command>
|
||||
<file name="log/test1020.txt">
|
||||
1234567890
|
||||
1234567890
|
||||
</file>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<stdout>
|
||||
34567890
|
||||
</stdout>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
Loading…
Reference in New Issue
Block a user