return res;
now = Curl_tvnow();
- if(Curl_pgrsUpdate(data))
+ if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
}
now = Curl_tvnow();
- if(Curl_pgrsUpdate(data))
+ if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
close(fd);
CURLE_FTP_COULDNT_SET_BINARY;
}
- if(data->resume_from) {
+ if(conn->resume_from) {
/* we're about to continue the uploading of a file */
/* 1. get already existing file's size. We use the SIZE
command for this which may not exist in the server!
/* 4. lower the infilesize counter */
/* => transfer as usual */
- if(data->resume_from < 0 ) {
+ if(conn->resume_from < 0 ) {
/* we could've got a specified offset from the command line,
but now we know we didn't */
}
/* get the size from the ascii string: */
- data->resume_from = atoi(buf+4);
+ conn->resume_from = atoi(buf+4);
}
- if(data->resume_from) {
+ if(conn->resume_from) {
/* do we still game? */
int passed=0;
/* enable append instead */
input. If we knew it was a proper file we could've just
fseek()ed but we only have a stream here */
do {
- int readthisamountnow = (data->resume_from - passed);
+ int readthisamountnow = (conn->resume_from - passed);
int actuallyread;
if(readthisamountnow > BUFSIZE)
return CURLE_FTP_COULDNT_USE_REST;
}
}
- while(passed != data->resume_from);
+ while(passed != conn->resume_from);
/* now, decrease the size of the read */
if(data->infilesize>0) {
- data->infilesize -= data->resume_from;
+ data->infilesize -= conn->resume_from;
if(data->infilesize <= 0) {
failf(data, "File already completely uploaded\n");
bool dirlist=FALSE;
long downloadsize=-1;
- if(data->bits.set_range && data->range) {
+ if(conn->bits.use_range && conn->range) {
long from, to;
int totalsize=-1;
char *ptr;
char *ptr2;
- from=strtol(data->range, &ptr, 0);
+ from=strtol(conn->range, &ptr, 0);
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
ptr++;
to=strtol(ptr, &ptr2, 0);
}
if((-1 == to) && (from>=0)) {
/* X - */
- data->resume_from = from;
+ conn->resume_from = from;
infof(data, "FTP RANGE %d to end of file\n", from);
}
else if(from < 0) {
/* -Y */
totalsize = -from;
conn->maxdownload = -from;
- data->resume_from = from;
+ conn->resume_from = from;
infof(data, "FTP RANGE the last %d bytes\n", totalsize);
}
else {
/* X-Y */
totalsize = to-from;
conn->maxdownload = totalsize+1; /* include the last mentioned byte */
- data->resume_from = from;
- infof(data, "FTP RANGE from %d getting %d bytes\n", from, conn->maxdownload);
+ conn->resume_from = from;
+ infof(data, "FTP RANGE from %d getting %d bytes\n", from,
+ conn->maxdownload);
}
infof(data, "range-download from %d to %d, totally %d bytes\n",
from, to, totalsize);
CURLE_FTP_COULDNT_SET_BINARY;
}
- if(data->resume_from) {
+ if(conn->resume_from) {
/* Daniel: (August 4, 1999)
*
int foundsize=atoi(buf+4);
/* We got a file size report, so we check that there actually is a
part of the file left to get, or else we go home. */
- if(data->resume_from< 0) {
+ if(conn->resume_from< 0) {
/* We're supposed to download the last abs(from) bytes */
- if(foundsize < -data->resume_from) {
+ if(foundsize < -conn->resume_from) {
failf(data, "Offset (%d) was beyond file size (%d)",
- data->resume_from, foundsize);
+ conn->resume_from, foundsize);
return CURLE_FTP_BAD_DOWNLOAD_RESUME;
}
/* convert to size to download */
- downloadsize = -data->resume_from;
+ downloadsize = -conn->resume_from;
/* download from where? */
- data->resume_from = foundsize - downloadsize;
+ conn->resume_from = foundsize - downloadsize;
}
else {
- if(foundsize < data->resume_from) {
+ if(foundsize < conn->resume_from) {
failf(data, "Offset (%d) was beyond file size (%d)",
- data->resume_from, foundsize);
+ conn->resume_from, foundsize);
return CURLE_FTP_BAD_DOWNLOAD_RESUME;
}
/* Now store the number of bytes we are expected to download */
- downloadsize = foundsize-data->resume_from;
+ downloadsize = foundsize-conn->resume_from;
}
}
/* Set resume file transfer offset */
infof(data, "Instructs server to resume from offset %d\n",
- data->resume_from);
+ conn->resume_from);
- ftpsendf(conn->firstsocket, conn, "REST %d", data->resume_from);
+ ftpsendf(conn->firstsocket, conn, "REST %d", conn->resume_from);
nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode);
if(nread < 0)
if((data->bits.http_post ||
data->bits.http_formpost ||
data->bits.http_put) &&
- data->resume_from) {
+ conn->resume_from) {
/**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have
* got a resume_from value set. The resume value has already created
* file size before we continue this venture in the dark lands of HTTP.
*********************************************************************/
- if(data->resume_from < 0 ) {
+ if(conn->resume_from < 0 ) {
/*
* This is meant to get the size of the present remote-file by itself.
* We don't support this now. Bail out!
*/
- data->resume_from = 0;
+ conn->resume_from = 0;
}
- if(data->resume_from) {
+ if(conn->resume_from) {
/* do we still game? */
int passed=0;
input. If we knew it was a proper file we could've just
fseek()ed but we only have a stream here */
do {
- int readthisamountnow = (data->resume_from - passed);
+ int readthisamountnow = (conn->resume_from - passed);
int actuallyread;
if(readthisamountnow > BUFSIZE)
passed);
return CURLE_READ_ERROR;
}
- } while(passed != data->resume_from); /* loop until done */
+ } while(passed != conn->resume_from); /* loop until done */
/* now, decrease the size of the read */
if(data->infilesize>0) {
- data->infilesize -= data->resume_from;
+ data->infilesize -= conn->resume_from;
if(data->infilesize <= 0) {
failf(data, "File already completely uploaded\n");
/* we've passed, proceed as normal */
}
}
- if(data->bits.set_range) {
+ if(conn->bits.use_range) {
/*
* A range is selected. We use different headers whether we're downloading
* or uploading and we always let customized headers override our internal
*/
if((data->httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) {
- conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->range);
+ conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
}
else if((data->httpreq != HTTPREQ_GET) &&
!checkheaders(data, "Content-Range:")) {
- if(data->resume_from) {
+ if(conn->resume_from) {
/* This is because "resume" was selected */
- long total_expected_size= data->resume_from + data->infilesize;
+ long total_expected_size= conn->resume_from + data->infilesize;
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n",
- data->range, total_expected_size-1,
+ conn->range, total_expected_size-1,
total_expected_size);
}
else {
/* Range was selected and then we just pass the incoming range and
append total size */
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n",
- data->range, data->infilesize);
+ conn->range, data->infilesize);
}
}
}
conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
(conn->bits.user_passwd && conn->allocptr.userpwd)?
conn->allocptr.userpwd:"",
- (data->bits.set_range && conn->allocptr.rangeline)?
+ (conn->bits.use_range && conn->allocptr.rangeline)?
conn->allocptr.rangeline:"",
(data->useragent && *data->useragent && conn->allocptr.uagent)?
conn->allocptr.uagent:"",
*/
-void Curl_pgrsDone(struct UrlData *data)
+void Curl_pgrsDone(struct connectdata *conn)
{
+ struct UrlData *data = conn->data;
if(!(data->progress.flags & PGRS_HIDE)) {
data->progress.lastshow=0;
- Curl_pgrsUpdate(data); /* the final (forced) update */
+ Curl_pgrsUpdate(conn); /* the final (forced) update */
fprintf(data->err, "\n");
}
}
*/
-int Curl_pgrsUpdate(struct UrlData *data)
+int Curl_pgrsUpdate(struct connectdata *conn)
{
struct timeval now;
int result;
double total_transfer;
double total_expected_transfer;
+ struct UrlData *data = conn->data;
+
int nowindex = data->progress.speeder_c% CURR_TIME;
int checkindex;
int count;
double total_estimate;
+
if(data->progress.flags & PGRS_HIDE)
; /* We do enter this function even if we don't wanna see anything, since
this is were lots of the calculations are being made that will be used
even when not displayed! */
else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
if (!data->progress.callback) {
- if(data->resume_from)
+ if(conn->resume_from)
fprintf(data->err, "** Resuming transfer from byte position %d\n",
- data->resume_from);
+ conn->resume_from);
fprintf(data->err,
" %% Total %% Received %% Xferd Average Speed Time Curr.\n"
" Dload Upload Total Current Left Speed\n");
TIMER_LAST /* must be last */
} timerid;
-void Curl_pgrsDone(struct UrlData *data);
+void Curl_pgrsDone(struct connectdata *);
void Curl_pgrsStartNow(struct UrlData *data);
void Curl_pgrsSetDownloadSize(struct UrlData *data, double size);
void Curl_pgrsSetUploadSize(struct UrlData *data, double size);
void Curl_pgrsSetDownloadCounter(struct UrlData *data, double size);
void Curl_pgrsSetUploadCounter(struct UrlData *data, double size);
-int Curl_pgrsUpdate(struct UrlData *data);
+int Curl_pgrsUpdate(struct connectdata *);
void Curl_pgrsTime(struct UrlData *data, timerid timer);
/* This second format was added August 1st 2000 by Igor
Khristophorov since Sun's webserver JavaWebServer/1.1.1
obviously sends the header this way! :-( */
- if (data->resume_from == offset) {
+ if (conn->resume_from == offset) {
/* we asked for a resume and we got it */
content_range = TRUE;
}
infof (data, "Follow to new URL: %s\n", conn->newurl);
return CURLE_OK;
}
- else if (data->resume_from &&
+ else if (conn->resume_from &&
!content_range &&
(data->httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server
"byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR;
}
- else if(data->timecondition && !data->range) {
+ else if(data->timecondition && !conn->range) {
/* A time condition has been set AND no ranges have been
requested. This seems to be what chapter 13.3.4 of
RFC 2616 defines to be the correct action for a
}
now = Curl_tvnow();
- if(Curl_pgrsUpdate(data))
+ if(Curl_pgrsUpdate(conn))
urg = CURLE_ABORTED_BY_CALLBACK;
else
urg = Curl_speedcheck (data, now);
conn->proto.http->chunk.datasize);
return CURLE_PARTIAL_FILE;
}
- if(Curl_pgrsUpdate(data))
+ if(Curl_pgrsUpdate(conn))
return CURLE_ABORTED_BY_CALLBACK;
if(conn->bytecountp)
data->bits.httpproxy=FALSE;
}
-
- if(data->bits.rangestringalloc) {
- free(data->range);
- data->range=NULL;
- data->bits.rangestringalloc=0; /* free now */
- }
-
/* check for allocated [URL] memory to free: */
if(data->freethis)
free(data->freethis);
/*
* What range of the file you want to transfer
*/
- data->range = va_arg(param, char *);
- data->bits.set_range = data->range?1:0;
+ data->set_range = va_arg(param, char *);
+ data->bits.set_range = data->set_range?1:0;
break;
case CURLOPT_RESUME_FROM:
/*
* Resume transfer at the give file position
*/
- data->resume_from = va_arg(param, long);
+ data->set_resume_from = va_arg(param, long);
break;
case CURLOPT_STDERR:
/*
if(!conn)
return CURLE_OK; /* this is closed and fine already */
+ /*
+ * The range string is usually freed in curl_done(), but we might
+ * get here *instead* if we fail prematurely. Thus we need to be able
+ * to free this resource here as well.
+ */
+ if(conn->bits.rangestringalloc) {
+ free(conn->range);
+ conn->bits.rangestringalloc = FALSE;
+ }
+
if(-1 != conn->connectindex) {
/* unlink ourselves! */
infof(conn->data, "Closing live connection (#%d)\n", conn->connectindex);
conn->secondarysocket = -1; /* no file descriptor */
conn->connectindex = -1; /* no index */
conn->bits.httpproxy = data->bits.httpproxy; /* proxy-or-not status */
+ conn->bits.use_range = data->bits.set_range; /* range status */
+ conn->range = data->set_range; /* clone the range setting */
+ conn->resume_from = data->set_resume_from; /* inherite resume_from */
/* Default protocol-independent behavior doesn't support persistant
connections, so we set this to force-close. Protocols that support
* server, we just fail since we can't rewind the file writing from within
* this function.
***********************************************************/
- if(data->resume_from) {
- if(!data->bits.set_range) {
+ if(conn->resume_from) {
+ if(!conn->bits.use_range) {
/* if it already was in use, we just skip this */
- snprintf(resumerange, sizeof(resumerange), "%d-", data->resume_from);
- data->range=strdup(resumerange); /* tell ourselves to fetch this range */
- data->bits.rangestringalloc = TRUE; /* mark as allocated */
- data->bits.set_range = 1; /* switch on range usage */
+ snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from);
+ conn->range=strdup(resumerange); /* tell ourselves to fetch this range */
+ conn->bits.rangestringalloc = TRUE; /* mark as allocated */
+ conn->bits.use_range = 1; /* switch on range usage */
}
}
struct UrlData *data=conn->data;
CURLcode result;
+ /* cleanups done even if the connection is re-used */
+
+ if(conn->bits.rangestringalloc) {
+ free(conn->range);
+ conn->bits.rangestringalloc = FALSE;
+ }
+
/* this calls the protocol-specific function pointer previously set */
if(conn->curl_done)
result = conn->curl_done(conn);
else
result = CURLE_OK;
- Curl_pgrsDone(data); /* done with the operation */
+ Curl_pgrsDone(conn); /* done with the operation */
/* if data->bits.reuse_forbid is TRUE, it means the libcurl client has
forced us to close this no matter what we think.
bool httpproxy; /* if set, this transfer is done through a http proxy */
bool user_passwd; /* do we use user+password for this connection? */
bool proxy_user_passwd; /* user+password for the proxy? */
+
+ bool use_range;
+ bool rangestringalloc; /* the range string is malloc()'ed */
};
/*
char *ppath;
long bytecount;
+ char *range; /* range, if used. See README for detailed specification on
+ this syntax. */
+ int resume_from; /* continue [ftp] transfer from here */
+
char *proxyhost; /* name of the http proxy host */
struct timeval now; /* "current" time */
bool this_is_a_follow; /* this is a followed Location: request */
bool krb4; /* kerberos4 connection requested */
bool proxystringalloc; /* the http proxy string is malloc()'ed */
- bool rangestringalloc; /* the range string is malloc()'ed */
bool urlstringalloc; /* the URL string is malloc()'ed */
bool reuse_forbid; /* if this is forbidden to be reused, close
after use */
struct ssl_config_data ssl; /* this is for ssl-stuff */
char *userpwd; /* <user:password>, if used */
- char *range; /* range, if used. See README for detailed specification on
- this syntax. */
+ char *set_range; /* range, if used. See README for detailed specification on
+ this syntax. */
/* stuff related to HTTP */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */
- int resume_from; /* continue [ftp] transfer from here */
+ int set_resume_from; /* continue [ftp] transfer from here */
char *cookie; /* HTTP cookie string to send */