1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

The fread() callback pointer and associated pointer is now stored in the

connectdata struct instead, and is no longer modified within the 'set' struct
as previously (which was a really BAAAD thing).
This commit is contained in:
Daniel Stenberg 2002-12-09 15:37:54 +00:00
parent c65e088caf
commit 4bcc866c52
6 changed files with 241 additions and 237 deletions

View File

@ -1591,8 +1591,8 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
readthisamountnow = BUFSIZE; readthisamountnow = BUFSIZE;
actuallyread = actuallyread =
data->set.fread(data->state.buffer, 1, readthisamountnow, conn->fread(data->state.buffer, 1, readthisamountnow,
data->set.in); conn->fread_in);
passed += actuallyread; passed += actuallyread;
if(actuallyread != readthisamountnow) { if(actuallyread != readthisamountnow) {
@ -1623,7 +1623,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
} }
} }
/* Send everything on data->set.in to the socket */ /* Send everything on data->state.in to the socket */
if(data->set.ftp_append) { if(data->set.ftp_append) {
/* we append onto the file instead of rewriting it */ /* we append onto the file instead of rewriting it */
FTPSENDF(conn, "APPE %s", ftp->file); FTPSENDF(conn, "APPE %s", ftp->file);

View File

@ -126,8 +126,11 @@ send_buffer *add_buffer_init(void)
* add_buffer_send() sends a buffer and frees all associated memory. * add_buffer_send() sends a buffer and frees all associated memory.
*/ */
static static
CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in, CURLcode add_buffer_send(send_buffer *in,
long *bytes_written) int sockfd,
struct connectdata *conn,
long *bytes_written) /* add the number of sent
bytes to this counter */
{ {
ssize_t amount; ssize_t amount;
CURLcode res; CURLcode res;
@ -149,6 +152,8 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
/* this data _may_ contain binary stuff */ /* this data _may_ contain binary stuff */
Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount); Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount);
*bytes_written += amount;
if(amount != size) { if(amount != size) {
size -= amount; size -= amount;
ptr += amount; ptr += amount;
@ -162,8 +167,6 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in,
free(in->buffer); free(in->buffer);
free(in); free(in);
*bytes_written += amount;
return res; return res;
} }
@ -517,8 +520,9 @@ CURLcode Curl_http_done(struct connectdata *conn)
Curl_formclean(http->sendit); /* Now free that whole lot */ Curl_formclean(http->sendit); /* Now free that whole lot */
data->set.fread = http->storefread; /* restore */ /* set the proper values */
data->set.in = http->in; /* restore */ conn->fread = data->set.fread; /* restore */
conn->fread_in = data->set.in; /* restore */
} }
else if(HTTPREQ_PUT == data->set.httpreq) else if(HTTPREQ_PUT == data->set.httpreq)
conn->bytecount = http->readbytecount + http->writebytecount; conn->bytecount = http->readbytecount + http->writebytecount;
@ -923,13 +927,9 @@ CURLcode Curl_http(struct connectdata *conn)
return CURLE_HTTP_POST_ERROR; return CURLE_HTTP_POST_ERROR;
} }
http->storefread = data->set.fread; /* backup */ /* set the read function to read from the generated form data */
http->in = data->set.in; /* backup */ conn->fread = (curl_read_callback)Curl_FormReader;
conn->fread_in = &http->form;
data->set.fread = (curl_read_callback)
Curl_FormReader; /* set the read function to read from the
generated form data */
data->set.in = (FILE *)&http->form;
if(!conn->bits.upload_chunky) if(!conn->bits.upload_chunky)
/* only add Content-Length if not uploading chunked */ /* only add Content-Length if not uploading chunked */
@ -974,7 +974,7 @@ CURLcode Curl_http(struct connectdata *conn)
Curl_pgrsSetUploadSize(data, http->postsize); Curl_pgrsSetUploadSize(data, http->postsize);
/* fire away the whole request to the server */ /* fire away the whole request to the server */
result = add_buffer_send(conn->firstsocket, conn, req_buffer, result = add_buffer_send(req_buffer, conn->firstsocket, conn,
&data->info.request_size); &data->info.request_size);
if(result) if(result)
failf(data, "Failed sending POST request"); failf(data, "Failed sending POST request");
@ -1004,10 +1004,10 @@ CURLcode Curl_http(struct connectdata *conn)
Curl_pgrsSetUploadSize(data, data->set.infilesize); Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* this sends the buffer and frees all the buffer resources */ /* this sends the buffer and frees all the buffer resources */
result = add_buffer_send(conn->firstsocket, conn, req_buffer, result = add_buffer_send(req_buffer, conn->firstsocket, conn,
&data->info.request_size); &data->info.request_size);
if(result) if(result)
failf(data, "Faied sending POST request"); failf(data, "Failed sending POST request");
else else
/* prepare for transfer */ /* prepare for transfer */
result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE, result = Curl_Transfer(conn, conn->firstsocket, -1, TRUE,
@ -1053,7 +1053,7 @@ CURLcode Curl_http(struct connectdata *conn)
data->set.postfields ); data->set.postfields );
/* issue the request */ /* issue the request */
result = add_buffer_send(conn->firstsocket, conn, req_buffer, result = add_buffer_send(req_buffer, conn->firstsocket, conn,
&data->info.request_size); &data->info.request_size);
if(result) if(result)
@ -1070,7 +1070,7 @@ CURLcode Curl_http(struct connectdata *conn)
add_buffer(req_buffer, "\r\n", 2); add_buffer(req_buffer, "\r\n", 2);
/* issue the request */ /* issue the request */
result = add_buffer_send(conn->firstsocket, conn, req_buffer, result = add_buffer_send(req_buffer, conn->firstsocket, conn,
&data->info.request_size); &data->info.request_size);
if(result) if(result)

View File

@ -275,7 +275,8 @@ int cert_stuff(struct connectdata *conn,
if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx, if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,
key_file, key_file,
file_type) != 1) { file_type) != 1) {
failf(data, "unable to set private key file\n"); failf(data, "unable to set private key file: '%s' type %s\n",
key_file, key_type?key_type:"PEM");
return 0; return 0;
} }
break; break;

View File

@ -597,240 +597,240 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else if(checkprefix("Last-Modified:", k->p) && else if(checkprefix("Last-Modified:", k->p) &&
(data->set.timecondition || data->set.get_filetime) ) { (data->set.timecondition || data->set.get_filetime) ) {
time_t secs=time(NULL); time_t secs=time(NULL);
k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"), k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
&secs); &secs);
if(data->set.get_filetime) if(data->set.get_filetime)
data->info.filetime = k->timeofdoc; data->info.filetime = k->timeofdoc;
}
else if ((k->httpcode >= 300 && k->httpcode < 400) &&
(data->set.http_follow_location) &&
checkprefix("Location:", k->p)) {
/* this is the URL that the server advices us to get instead */
char *ptr;
char *start=k->p;
char backup;
start += 9; /* pass "Location:" */
/* Skip spaces and tabs. We do this to support multiple
white spaces after the "Location:" keyword. */
while(*start && isspace((int)*start ))
start++;
ptr = start; /* start scanning here */
/* scan through the string to find the end */
while(*ptr && !isspace((int)*ptr))
ptr++;
backup = *ptr; /* store the ending letter */
if(ptr != start) {
*ptr = '\0'; /* zero terminate */
conn->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */
} }
} else if ((k->httpcode >= 300 && k->httpcode < 400) &&
(data->set.http_follow_location) &&
checkprefix("Location:", k->p)) {
/* this is the URL that the server advices us to get instead */
char *ptr;
char *start=k->p;
char backup;
/* start += 9; /* pass "Location:" */
* End of header-checks. Write them to the client.
*/
k->writetype = CLIENTWRITE_HEADER; /* Skip spaces and tabs. We do this to support multiple
if (data->set.http_include_header) white spaces after the "Location:" keyword. */
k->writetype |= CLIENTWRITE_BODY; while(*start && isspace((int)*start ))
start++;
ptr = start; /* start scanning here */
if(data->set.verbose) /* scan through the string to find the end */
Curl_debug(data, CURLINFO_HEADER_IN, while(*ptr && !isspace((int)*ptr))
k->p, k->hbuflen); ptr++;
backup = *ptr; /* store the ending letter */
if(ptr != start) {
*ptr = '\0'; /* zero terminate */
conn->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */
}
}
result = Curl_client_write(data, k->writetype, k->p, /*
k->hbuflen); * End of header-checks. Write them to the client.
if(result) */
return result;
data->info.header_size += k->hbuflen; k->writetype = CLIENTWRITE_HEADER;
conn->headerbytecount += k->hbuflen; if (data->set.http_include_header)
k->writetype |= CLIENTWRITE_BODY;
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
k->p, k->hbuflen);
result = Curl_client_write(data, k->writetype, k->p,
k->hbuflen);
if(result)
return result;
data->info.header_size += k->hbuflen;
conn->headerbytecount += k->hbuflen;
/* reset hbufp pointer && hbuflen */ /* reset hbufp pointer && hbuflen */
k->hbufp = data->state.headerbuff; k->hbufp = data->state.headerbuff;
k->hbuflen = 0; k->hbuflen = 0;
} }
while (!stop_reading && *k->str); /* header line within buffer */ while (!stop_reading && *k->str); /* header line within buffer */
if(stop_reading) if(stop_reading)
/* We've stopped dealing with input, get out of the do-while loop */ /* We've stopped dealing with input, get out of the do-while loop */
break; break;
/* We might have reached the end of the header part here, but /* We might have reached the end of the header part here, but
there might be a non-header part left in the end of the read there might be a non-header part left in the end of the read
buffer. */ buffer. */
} /* end if header mode */ } /* end if header mode */
/* This is not an 'else if' since it may be a rest from the header /* This is not an 'else if' since it may be a rest from the header
parsing, where the beginning of the buffer is headers and the end parsing, where the beginning of the buffer is headers and the end
is non-headers. */ is non-headers. */
if (k->str && !k->header && (nread > 0)) { if (k->str && !k->header && (nread > 0)) {
if(0 == k->bodywrites) { if(0 == k->bodywrites) {
/* These checks are only made the first time we are about to /* These checks are only made the first time we are about to
write a piece of the body */ write a piece of the body */
if(conn->protocol&PROT_HTTP) { if(conn->protocol&PROT_HTTP) {
/* HTTP-only checks */ /* HTTP-only checks */
if (conn->newurl) { if (conn->newurl) {
/* abort after the headers if "follow Location" is set */ /* abort after the headers if "follow Location" is set */
infof (data, "Follow to new URL: %s\n", conn->newurl); infof (data, "Follow to new URL: %s\n", conn->newurl);
k->keepon &= ~KEEP_READ; k->keepon &= ~KEEP_READ;
FD_ZERO(&k->rkeepfd); FD_ZERO(&k->rkeepfd);
*done = TRUE; *done = TRUE;
return CURLE_OK; return CURLE_OK;
} }
else if (conn->resume_from && else if (conn->resume_from &&
!k->content_range && !k->content_range &&
(data->set.httpreq==HTTPREQ_GET)) { (data->set.httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server /* we wanted to resume a download, although the server
doesn't seem to support this and we did this with a GET doesn't seem to support this and we did this with a GET
(if it wasn't a GET we did a POST or PUT resume) */ (if it wasn't a GET we did a POST or PUT resume) */
failf (data, "HTTP server doesn't seem to support " failf (data, "HTTP server doesn't seem to support "
"byte ranges. Cannot resume."); "byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR; return CURLE_HTTP_RANGE_ERROR;
} }
else if(data->set.timecondition && !conn->range) { else if(data->set.timecondition && !conn->range) {
/* A time condition has been set AND no ranges have been /* A time condition has been set AND no ranges have been
requested. This seems to be what chapter 13.3.4 of requested. This seems to be what chapter 13.3.4 of
RFC 2616 defines to be the correct action for a RFC 2616 defines to be the correct action for a
HTTP/1.1 client */ HTTP/1.1 client */
if((k->timeofdoc > 0) && (data->set.timevalue > 0)) { if((k->timeofdoc > 0) && (data->set.timevalue > 0)) {
switch(data->set.timecondition) { switch(data->set.timecondition) {
case TIMECOND_IFMODSINCE: case TIMECOND_IFMODSINCE:
default: default:
if(k->timeofdoc < data->set.timevalue) { if(k->timeofdoc < data->set.timevalue) {
infof(data, infof(data,
"The requested document is not new enough\n"); "The requested document is not new enough\n");
*done = TRUE; *done = TRUE;
return CURLE_OK; return CURLE_OK;
} }
break; break;
case TIMECOND_IFUNMODSINCE: case TIMECOND_IFUNMODSINCE:
if(k->timeofdoc > data->set.timevalue) { if(k->timeofdoc > data->set.timevalue) {
infof(data, infof(data,
"The requested document is not old enough\n"); "The requested document is not old enough\n");
*done = TRUE; *done = TRUE;
return CURLE_OK; return CURLE_OK;
} }
break; break;
} /* switch */ } /* switch */
} /* two valid time strings */ } /* two valid time strings */
} /* we have a time condition */ } /* we have a time condition */
} /* this is HTTP */ } /* this is HTTP */
} /* this is the first time we write a body part */ } /* this is the first time we write a body part */
k->bodywrites++; k->bodywrites++;
/* pass data to the debug function before it gets "dechunked" */ /* pass data to the debug function before it gets "dechunked" */
if(data->set.verbose) { if(data->set.verbose) {
if(k->badheader) { if(k->badheader) {
Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff, Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
k->hbuflen); k->hbuflen);
if(k->badheader == HEADER_PARTHEADER) if(k->badheader == HEADER_PARTHEADER)
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
}
else
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread); Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
} }
else
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread);
}
if(conn->bits.chunk) { if(conn->bits.chunk) {
/* /*
* Bless me father for I have sinned. Here comes a chunked * Bless me father for I have sinned. Here comes a chunked
* transfer flying and we need to decode this properly. While * transfer flying and we need to decode this properly. While
* the name says read, this function both reads and writes away * the name says read, this function both reads and writes away
* the data. The returned 'nread' holds the number of actual * the data. The returned 'nread' holds the number of actual
* data it wrote to the client. */ * data it wrote to the client. */
CHUNKcode res = CHUNKcode res =
Curl_httpchunk_read(conn, k->str, nread, &nread); Curl_httpchunk_read(conn, k->str, nread, &nread);
if(CHUNKE_OK < res) { if(CHUNKE_OK < res) {
if(CHUNKE_WRITE_ERROR == res) { if(CHUNKE_WRITE_ERROR == res) {
failf(data, "Failed writing data"); failf(data, "Failed writing data");
return CURLE_WRITE_ERROR; return CURLE_WRITE_ERROR;
}
failf(data, "Received problem in the chunky parser");
return CURLE_RECV_ERROR;
} }
failf(data, "Received problem in the chunky parser"); else if(CHUNKE_STOP == res) {
return CURLE_RECV_ERROR; /* we're done reading chunks! */
k->keepon &= ~KEEP_READ; /* read no more */
FD_ZERO(&k->rkeepfd);
/* There are now possibly N number of bytes at the end of the
str buffer that weren't written to the client, but we don't
care about them right now. */
}
/* If it returned OK, we just keep going */
} }
else if(CHUNKE_STOP == res) {
/* we're done reading chunks! */ if((-1 != conn->maxdownload) &&
k->keepon &= ~KEEP_READ; /* read no more */ (k->bytecount + nread >= conn->maxdownload)) {
nread = conn->maxdownload - k->bytecount;
if(nread < 0 ) /* this should be unusual */
nread = 0;
k->keepon &= ~KEEP_READ; /* we're done reading */
FD_ZERO(&k->rkeepfd); FD_ZERO(&k->rkeepfd);
/* There are now possibly N number of bytes at the end of the
str buffer that weren't written to the client, but we don't
care about them right now. */
} }
/* If it returned OK, we just keep going */
}
if((-1 != conn->maxdownload) && k->bytecount += nread;
(k->bytecount + nread >= conn->maxdownload)) {
nread = conn->maxdownload - k->bytecount;
if(nread < 0 ) /* this should be unusual */
nread = 0;
k->keepon &= ~KEEP_READ; /* we're done reading */ Curl_pgrsSetDownloadCounter(data, (double)k->bytecount);
FD_ZERO(&k->rkeepfd);
}
k->bytecount += nread;
Curl_pgrsSetDownloadCounter(data, (double)k->bytecount);
if(!conn->bits.chunk && (nread || k->badheader)) { if(!conn->bits.chunk && (nread || k->badheader)) {
/* If this is chunky transfer, it was already written */ /* If this is chunky transfer, it was already written */
if(k->badheader) { if(k->badheader) {
/* we parsed a piece of data wrongly assuming it was a header /* we parsed a piece of data wrongly assuming it was a header
and now we output it as body instead */ and now we output it as body instead */
result = Curl_client_write(data, CLIENTWRITE_BODY, result = Curl_client_write(data, CLIENTWRITE_BODY,
data->state.headerbuff, data->state.headerbuff,
k->hbuflen); k->hbuflen);
}
if(k->badheader < HEADER_ALLBAD) {
/* This switch handles various content encodings. If there's an
error here, be sure to check over the almost identical code in
http_chunk.c. 08/29/02 jhrg */
#ifdef HAVE_LIBZ
switch (k->content_encoding) {
case IDENTITY:
#endif
/* This is the default when the server sends no
Content-Encoding header. See Curl_readwrite_init; the
memset() call initializes k->content_encoding to zero.
08/28/02 jhrg */
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
nread);
#ifdef HAVE_LIBZ
break;
case DEFLATE:
/* Assume CLIENTWRITE_BODY; headers are not encoded. */
result = Curl_unencode_deflate_write(data, k, nread);
break;
case GZIP: /* FIXME 08/27/02 jhrg */
case COMPRESS:
default:
failf (data, "Unrecognized content encoding type. "
"libcurl understands `identity' and `deflate' "
"content encodings.");
result = CURLE_BAD_CONTENT_ENCODING;
break;
} }
if(k->badheader < HEADER_ALLBAD) {
/* This switch handles various content encodings. If there's an
error here, be sure to check over the almost identical code
in http_chunk.c. 08/29/02 jhrg */
#ifdef HAVE_LIBZ
switch (k->content_encoding) {
case IDENTITY:
#endif #endif
/* This is the default when the server sends no
Content-Encoding header. See Curl_readwrite_init; the
memset() call initializes k->content_encoding to zero.
08/28/02 jhrg */
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
nread);
#ifdef HAVE_LIBZ
break;
case DEFLATE:
/* Assume CLIENTWRITE_BODY; headers are not encoded. */
result = Curl_unencode_deflate_write(data, k, nread);
break;
case GZIP: /* FIXME 08/27/02 jhrg */
case COMPRESS:
default:
failf (data, "Unrecognized content encoding type. "
"libcurl understands `identity' and `deflate' "
"content encodings.");
result = CURLE_BAD_CONTENT_ENCODING;
break;
}
#endif
}
k->badheader = HEADER_NORMAL; /* taken care of now */
if(result)
return result;
} }
k->badheader = HEADER_NORMAL; /* taken care of now */
if(result) } /* if (! header and data to read ) */
return result;
}
} /* if (! header and data to read ) */
} while(!readdone); } while(!readdone);
@ -874,8 +874,8 @@ k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
conn->upload_fromhere += 10; /* 32bit hex + CRLF */ conn->upload_fromhere += 10; /* 32bit hex + CRLF */
} }
nread = data->set.fread(conn->upload_fromhere, 1, nread = conn->fread(conn->upload_fromhere, 1,
buffersize, data->set.in); buffersize, conn->fread_in);
if(conn->bits.upload_chunky) { if(conn->bits.upload_chunky) {
/* if chunked Transfer-Encoding */ /* if chunked Transfer-Encoding */
@ -944,12 +944,12 @@ k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
that instead of reading more data */ that instead of reading more data */
} }
/* write to socket */ /* write to socket (send away data) */
result = Curl_write(conn, result = Curl_write(conn,
conn->writesockfd, conn->writesockfd, /* socket to send to */
conn->upload_fromhere, conn->upload_fromhere, /* buffer pointer */
conn->upload_present, conn->upload_present, /* buffer size */
&bytes_written); &bytes_written); /* actually send away */
if(result) if(result)
return result; return result;
else if(conn->upload_present != bytes_written) { else if(conn->upload_present != bytes_written) {

View File

@ -1789,6 +1789,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/* else, no chunky upload */ /* else, no chunky upload */
FALSE; FALSE;
conn->fread = data->set.fread;
conn->fread_in = data->set.in;
/*********************************************************** /***********************************************************
* We need to allocate memory to store the path in. We get the size of the * We need to allocate memory to store the path in. We get the size of the
* full URL to be sure, and we need to make it at least 256 bytes since * full URL to be sure, and we need to make it at least 256 bytes since

View File

@ -164,9 +164,6 @@ struct HTTP {
/* For FORM posting */ /* For FORM posting */
struct Form form; struct Form form;
curl_read_callback storefread;
FILE *in;
struct Curl_chunker chunk; struct Curl_chunker chunk;
}; };
@ -458,6 +455,9 @@ struct connectdata {
and the 'upload_present' contains the number of bytes available at this and the 'upload_present' contains the number of bytes available at this
position */ position */
char *upload_fromhere; char *upload_fromhere;
curl_read_callback fread; /* function that reads the input */
void *fread_in; /* pointer to pass to the fread() above */
}; };
/* The end of connectdata. 08/27/02 jhrg */ /* The end of connectdata. 08/27/02 jhrg */
@ -633,7 +633,7 @@ struct UserDefined {
bool free_referer; /* set TRUE if 'referer' points to a string we bool free_referer; /* set TRUE if 'referer' points to a string we
allocated */ allocated */
char *useragent; /* User-Agent string */ char *useragent; /* User-Agent string */
char *encoding; /* Accept-Encoding string 08/28/02 jhrg */ char *encoding; /* Accept-Encoding string */
char *postfields; /* if POST, set the fields' values here */ char *postfields; /* if POST, set the fields' values here */
size_t postfieldsize; /* if POST, this might have a size to use instead of size_t postfieldsize; /* if POST, this might have a size to use instead of
strlen(), and then the data *may* be binary (contain strlen(), and then the data *may* be binary (contain