aboutsummaryrefslogtreecommitdiff
path: root/lib/easy.c
diff options
context:
space:
mode:
authorPatrick Monnerat <pm@datasphere.ch>2014-12-09 15:43:51 +0100
committerPatrick Monnerat <pm@datasphere.ch>2014-12-09 15:43:51 +0100
commit6ea4ee94f96cda494c493fadd9d445d2fd202834 (patch)
treeb6bf439715760316f688cf146457b1186a9a2528 /lib/easy.c
parente63d18fbd195e08d538107db903fccf63a4df7fd (diff)
Curl_client_write() & al.: chop long data, convert data only once.
Diffstat (limited to 'lib/easy.c')
-rw-r--r--lib/easy.c70
1 files changed, 6 insertions, 64 deletions
diff --git a/lib/easy.c b/lib/easy.c
index b547d1dbe..619312b79 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -1026,73 +1026,15 @@ CURLcode curl_easy_pause(CURL *curl, int action)
/* we have a buffer for sending that we now seem to be able to deliver
since the receive pausing is lifted! */
- /* get the pointer, type and length in local copies since the function may
- return PAUSE again and then we'll get a new copy allocted and stored in
+ /* get the pointer in local copy since the function may return PAUSE
+ again and then we'll get a new copy allocted and stored in
the tempwrite variables */
char *tempwrite = data->state.tempwrite;
- char *freewrite = tempwrite; /* store this pointer to free it later */
- size_t tempsize = data->state.tempwritesize;
- int temptype = data->state.tempwritetype;
- size_t chunklen;
-
- /* clear tempwrite here just to make sure it gets cleared if there's no
- further use of it, and make sure we don't clear it after the function
- invoke as it may have been set to a new value by then */
- data->state.tempwrite = NULL;
-
- /* since the write callback API is define to never exceed
- CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
- have more data than that in our buffer here, we must loop sending the
- data in multiple calls until there's no data left or we get another
- pause returned.
-
- A tricky part is that the function we call will "buffer" the data
- itself when it pauses on a particular buffer, so we may need to do some
- extra trickery if we get a pause return here.
- */
- do {
- chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
-
- result = Curl_client_write(data->easy_conn,
- temptype, tempwrite, chunklen);
- if(result)
- /* failures abort the loop at once */
- break;
-
- if(data->state.tempwrite && (tempsize - chunklen)) {
- /* Ouch, the reading is again paused and the block we send is now
- "cached". If this is the final chunk we can leave it like this, but
- if we have more chunks that are cached after this, we need to free
- the newly cached one and put back a version that is truly the entire
- contents that is saved for later
- */
- char *newptr;
-
- /* note that tempsize is still the size as before the callback was
- used, and thus the whole piece of data to keep */
- newptr = realloc(data->state.tempwrite, tempsize);
-
- if(!newptr) {
- free(data->state.tempwrite); /* free old area */
- data->state.tempwrite = NULL;
- result = CURLE_OUT_OF_MEMORY;
- /* tempwrite will be freed further down */
- break;
- }
- data->state.tempwrite = newptr; /* store new pointer */
- memcpy(newptr, tempwrite, tempsize);
- data->state.tempwritesize = tempsize; /* store new size */
- /* tempwrite will be freed further down */
- break; /* go back to pausing until further notice */
- }
- else {
- tempsize -= chunklen; /* left after the call above */
- tempwrite += chunklen; /* advance the pointer */
- }
- } while(!result && tempsize);
-
- free(freewrite); /* this is unconditionally no longer used */
+ data->state.tempwrite = NULL;
+ result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
+ tempwrite, data->state.tempwritesize);
+ free(tempwrite);
}
/* if there's no error and we're not pausing both directions, we want