* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, 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
#include "url.h"
#include "parsedate.h" /* for the week day and month names */
#include "warnless.h"
+#include "curl_range.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
ZERO_NULL, /* perform_getsock */
file_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* connection_check */
0, /* defport */
CURLPROTO_FILE, /* protocol */
PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
return CURLE_OK;
}
- /*
- 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 Curl_easy *data = conn->data;
-
- if(data->state.use_range && data->state.range) {
- from=curlx_strtoofft(data->state.range, &ptr, 0);
- while(*ptr && (ISSPACE(*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 %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
- from));
- }
- else if(from < 0) {
- /* -Y */
- data->req.maxdownload = -from;
- data->state.resume_from = from;
- DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
- -from));
- }
- else {
- /* X-Y */
- totalsize = to-from;
- data->req.maxdownload = totalsize+1; /* include last byte */
- data->state.resume_from = from;
- DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
- " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
- from, data->req.maxdownload));
- }
- DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
- " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
- CURL_FORMAT_CURL_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
}
/* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
- for(i=0; i < real_path_len; ++i)
+ for(i = 0; i < real_path_len; ++i)
if(actual_path[i] == '/')
actual_path[i] = '\\';
else if(!actual_path[i]) { /* binary zero */
size_t nread;
size_t nwrite;
curl_off_t bytecount = 0;
- struct timeval now = Curl_tvnow();
struct_stat file_stat;
const char *buf2;
failf(data, "Can't get the size of %s", file->path);
return CURLE_WRITE_ERROR;
}
- else
- data->state.resume_from = (curl_off_t)file_stat.st_size;
+ data->state.resume_from = (curl_off_t)file_stat.st_size;
}
while(!result) {
int readcount;
- result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
+ result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount);
if(result)
break;
if(Curl_pgrsUpdate(conn))
result = CURLE_ABORTED_BY_CALLBACK;
else
- result = Curl_speedcheck(data, now);
+ result = Curl_speedcheck(data, Curl_now());
}
if(!result && Curl_pgrsUpdate(conn))
result = CURLE_ABORTED_BY_CALLBACK;
struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
Windows version to have a different struct without
having to redefine the simple word 'stat' */
- curl_off_t expected_size=0;
+ curl_off_t expected_size = 0;
bool size_known;
- bool fstated=FALSE;
+ bool fstated = FALSE;
ssize_t nread;
struct Curl_easy *data = conn->data;
char *buf = data->state.buffer;
curl_off_t bytecount = 0;
int fd;
- struct timeval now = Curl_tvnow();
struct FILEPROTO *file;
*done = TRUE; /* unconditionally */
/* we could stat it, then read out the size */
expected_size = statbuf.st_size;
/* and store the modification time */
- data->info.filetime = (long)statbuf.st_mtime;
+ data->info.filetime = statbuf.st_mtime;
fstated = TRUE;
}
if(fstated && !data->state.range && data->set.timecondition) {
- if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) {
+ if(!Curl_meets_timecondition(data, data->info.filetime)) {
*done = TRUE;
return CURLE_OK;
}
time_t filetime;
struct tm buffer;
const struct tm *tm = &buffer;
- snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
+ char header[80];
+ snprintf(header, sizeof(header),
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
if(result)
return result;
return result;
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
- snprintf(buf, BUFSIZE-1,
+ snprintf(header, sizeof(header),
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
if(!result)
/* set the file size to make it available post transfer */
Curl_pgrsSetDownloadSize(data, expected_size);
}
/* Check whether file range has been specified */
- file_range(conn);
+ result = Curl_range(conn);
+ if(result)
+ return result;
/* Adjust the start offset in case we want to get the N last bytes
* of the stream iff the filesize could be determined */
failf(data, "Can't get the size of file.");
return CURLE_READ_ERROR;
}
- else
- data->state.resume_from += (curl_off_t)statbuf.st_size;
+ data->state.resume_from += (curl_off_t)statbuf.st_size;
}
if(data->state.resume_from <= expected_size)
size_t bytestoread;
if(size_known) {
- bytestoread =
- (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ?
- curlx_sotouz(expected_size) : BUFSIZE - 1;
+ bytestoread = (expected_size < data->set.buffer_size) ?
+ curlx_sotouz(expected_size) : (size_t)data->set.buffer_size;
}
else
- bytestoread = BUFSIZE-1;
+ bytestoread = data->set.buffer_size-1;
nread = read(fd, buf, bytestoread);
if(Curl_pgrsUpdate(conn))
result = CURLE_ABORTED_BY_CALLBACK;
else
- result = Curl_speedcheck(data, now);
+ result = Curl_speedcheck(data, Curl_now());
}
if(Curl_pgrsUpdate(conn))
result = CURLE_ABORTED_BY_CALLBACK;