aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/transfer.c96
1 files changed, 64 insertions, 32 deletions
diff --git a/lib/transfer.c b/lib/transfer.c
index 4111653b1..b57560b56 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -197,12 +197,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
didwhat |= KEEP_READ;
/* NULL terminate, allowing string ops to be used */
- if (0 < (signed int) nread)
+ if (0 < nread)
k->buf[nread] = 0;
/* if we receive 0 or less here, the server closed the connection and
we bail out from this! */
- else if (0 >= (signed int) nread) {
+ else if (0 >= nread) {
k->keepon &= ~KEEP_READ;
FD_ZERO(&k->rkeepfd);
break;
@@ -591,7 +591,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* 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
is non-headers. */
- if (k->str && !k->header && ((signed int)nread > 0)) {
+ if (k->str && !k->header && (nread > 0)) {
if(0 == k->bodywrites) {
/* These checks are only made the first time we are about to
@@ -672,7 +672,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if((-1 != conn->maxdownload) &&
(k->bytecount + nread >= conn->maxdownload)) {
nread = conn->maxdownload - k->bytecount;
- if((signed int)nread < 0 ) /* this should be unusual */
+ if(nread < 0 ) /* this should be unusual */
nread = 0;
k->keepon &= ~KEEP_READ; /* we're done reading */
@@ -699,53 +699,84 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* write */
int i, si;
- size_t bytes_written;
+ ssize_t bytes_written;
if ((k->bytecount == 0) && (k->writebytecount == 0))
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
didwhat |= KEEP_WRITE;
- nread = data->set.fread(k->buf, 1, conn->upload_bufsize,
- data->set.in);
+ /* only read more data if there's no upload data already
+ present in the upload buffer */
+ if(0 == conn->upload_present) {
+ /* init the "upload from here" pointer */
+ conn->upload_fromhere = k->uploadbuf;
+
+ nread = data->set.fread(conn->upload_fromhere, 1,
+ conn->upload_bufsize,
+ data->set.in);
+
+ /* the signed int typecase of nread of for systems that has
+ unsigned size_t */
+ if (nread<=0) {
+ /* done */
+ k->keepon &= ~KEEP_WRITE; /* we're done writing */
+ FD_ZERO(&k->wkeepfd);
+ break;
+ }
- /* the signed int typecase of nread of for systems that has
- unsigned size_t */
- if ((signed int)nread<=0) {
- /* done */
- k->keepon &= ~KEEP_WRITE; /* we're done writing */
- FD_ZERO(&k->wkeepfd);
- break;
- }
- k->writebytecount += nread;
- Curl_pgrsSetUploadCounter(data, (double)k->writebytecount);
+ /* store number of bytes available for upload */
+ conn->upload_present = nread;
- /* convert LF to CRLF if so asked */
- if (data->set.crlf) {
- for(i = 0, si = 0; i < (int)nread; i++, si++) {
- if (k->buf[i] == 0x0a) {
- data->state.scratch[si++] = 0x0d;
- data->state.scratch[si] = 0x0a;
- }
- else {
- data->state.scratch[si] = k->buf[i];
+ /* convert LF to CRLF if so asked */
+ if (data->set.crlf) {
+ for(i = 0, si = 0; i < nread; i++, si++) {
+ if (k->buf[i] == 0x0a) {
+ data->state.scratch[si++] = 0x0d;
+ data->state.scratch[si] = 0x0a;
+ }
+ else {
+ data->state.scratch[si] = k->uploadbuf[i];
+ }
}
+ nread = si;
+ k->buf = data->state.scratch; /* point to the new buffer */
}
- nread = si;
- k->buf = data->state.scratch; /* point to the new buffer */
+ }
+ else {
+ /* We have a partial buffer left from a previous "round". Use
+ that instead of reading more data */
+
}
/* write to socket */
- result = Curl_write(conn, conn->writesockfd, k->buf, nread,
+ result = Curl_write(conn,
+ conn->writesockfd,
+ conn->upload_fromhere,
+ conn->upload_present,
&bytes_written);
if(result)
return result;
- else if(nread != (int)bytes_written) {
- failf(data, "Failed uploading data");
- return CURLE_WRITE_ERROR;
+ else if(conn->upload_present != bytes_written) {
+ /* we only wrote a part of the buffer (if anything), deal with it! */
+
+ /* store the amount of bytes left in the buffer to write */
+ conn->upload_present -= bytes_written;
+
+ /* advance the pointer where to find the buffer when the next send
+ is to happen */
+ conn->upload_fromhere += bytes_written;
}
else if(data->set.crlf)
k->buf = data->state.buffer; /* put it back on the buffer */
+ else {
+ /* we've uploaded that buffer now */
+ conn->upload_fromhere = k->uploadbuf;
+ conn->upload_present = 0; /* no more bytes left */
+ }
+
+ k->writebytecount += nread;
+ Curl_pgrsSetUploadCounter(data, (double)k->writebytecount);
}
@@ -838,6 +869,7 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
data = conn->data; /* there's the root struct */
k->buf = data->state.buffer;
+ k->uploadbuf = data->state.uploadbuffer;
k->maxfd = (conn->sockfd>conn->writesockfd?
conn->sockfd:conn->writesockfd)+1;
k->hbufp = data->state.headerbuff;