diff options
Diffstat (limited to 'libs/libcurl/src/sendf.c')
-rw-r--r-- | libs/libcurl/src/sendf.c | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index 67b431f645..390907fae8 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -289,6 +289,13 @@ static CURLcode cw_download_write(struct Curl_easy *data, if(nwrite == wmax) {
data->req.download_done = TRUE;
}
+
+ if((type & CLIENTWRITE_EOS) && !data->req.no_body &&
+ (data->req.maxdownload > data->req.bytecount)) {
+ failf(data, "end of response with %" CURL_FORMAT_CURL_OFF_T
+ " bytes missing", data->req.maxdownload - data->req.bytecount);
+ return CURLE_PARTIAL_FILE;
+ }
}
/* Error on too large filesize is handled below, after writing
@@ -309,7 +316,9 @@ static CURLcode cw_download_write(struct Curl_easy *data, }
/* Update stats, write and report progress */
data->req.bytecount += nwrite;
- ++data->req.bodywrites;
+#ifdef USE_HYPER
+ data->req.bodywritten = TRUE;
+#endif
result = Curl_pgrsSetDownloadCounter(data, data->req.bytecount);
if(result)
return result;
@@ -597,6 +606,14 @@ CURLcode Curl_creader_def_unpause(struct Curl_easy *data, return CURLE_OK;
}
+bool Curl_creader_def_is_paused(struct Curl_easy *data,
+ struct Curl_creader *reader)
+{
+ (void)data;
+ (void)reader;
+ return FALSE;
+}
+
void Curl_creader_def_done(struct Curl_easy *data,
struct Curl_creader *reader, int premature)
{
@@ -615,6 +632,7 @@ struct cr_in_ctx { BIT(seen_eos);
BIT(errored);
BIT(has_used_cb);
+ BIT(is_paused);
};
static CURLcode cr_in_init(struct Curl_easy *data, struct Curl_creader *reader)
@@ -637,6 +655,8 @@ static CURLcode cr_in_read(struct Curl_easy *data, struct cr_in_ctx *ctx = reader->ctx;
size_t nread;
+ ctx->is_paused = FALSE;
+
/* Once we have errored, we will return the same error forever */
if(ctx->errored) {
*pnread = 0;
@@ -688,12 +708,14 @@ static CURLcode cr_in_read(struct Curl_easy *data, case CURL_READFUNC_PAUSE:
if(data->conn->handler->flags & PROTOPT_NONETWORK) {
/* protocols that work without network cannot be paused. This is
- actually only FILE:// just now, and it can't pause since the transfer
- isn't done using the "normal" procedure. */
+ actually only FILE:// just now, and it cannot pause since the transfer
+ is not done using the "normal" procedure. */
failf(data, "Read callback asked for PAUSE when not supported");
return CURLE_READ_ERROR;
}
/* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
+ CURL_TRC_READ(data, "cr_in_read, callback returned CURL_READFUNC_PAUSE");
+ ctx->is_paused = TRUE;
data->req.keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
*pnread = 0;
*peos = FALSE;
@@ -764,7 +786,7 @@ static CURLcode cr_in_resume_from(struct Curl_easy *data, failf(data, "Could not seek stream");
return CURLE_READ_ERROR;
}
- /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+ /* when seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */
do {
char scratch[4*1024];
size_t readthisamountnow =
@@ -798,7 +820,7 @@ static CURLcode cr_in_resume_from(struct Curl_easy *data, return CURLE_PARTIAL_FILE;
}
}
- /* we've passed, proceed as normal */
+ /* we have passed, proceed as normal */
return CURLE_OK;
}
@@ -850,12 +872,28 @@ static CURLcode cr_in_rewind(struct Curl_easy *data, }
/* no callback set or failure above, makes us fail at once */
- failf(data, "necessary data rewind wasn't possible");
+ failf(data, "necessary data rewind was not possible");
return CURLE_SEND_FAIL_REWIND;
}
return CURLE_OK;
}
+static CURLcode cr_in_unpause(struct Curl_easy *data,
+ struct Curl_creader *reader)
+{
+ struct cr_in_ctx *ctx = reader->ctx;
+ (void)data;
+ ctx->is_paused = FALSE;
+ return CURLE_OK;
+}
+
+static bool cr_in_is_paused(struct Curl_easy *data,
+ struct Curl_creader *reader)
+{
+ struct cr_in_ctx *ctx = reader->ctx;
+ (void)data;
+ return ctx->is_paused;
+}
static const struct Curl_crtype cr_in = {
"cr-in",
@@ -866,7 +904,8 @@ static const struct Curl_crtype cr_in = { cr_in_total_length,
cr_in_resume_from,
cr_in_rewind,
- Curl_creader_def_unpause,
+ cr_in_unpause,
+ cr_in_is_paused,
Curl_creader_def_done,
sizeof(struct cr_in_ctx)
};
@@ -979,13 +1018,19 @@ static CURLcode cr_lc_read(struct Curl_easy *data, return result;
start = i + 1;
if(!data->set.crlf && (data->state.infilesize != -1)) {
- /* we're here only because FTP is in ASCII mode...
+ /* we are here only because FTP is in ASCII mode...
bump infilesize for the LF we just added */
data->state.infilesize++;
/* comment: this might work for FTP, but in HTTP we could not change
* the content length after having started the request... */
}
}
+
+ if(start < i) { /* leftover */
+ result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n);
+ if(result)
+ return result;
+ }
}
DEBUGASSERT(!Curl_bufq_is_empty(&ctx->buf));
@@ -1022,6 +1067,7 @@ static const struct Curl_crtype cr_lc = { Curl_creader_def_resume_from,
Curl_creader_def_rewind,
Curl_creader_def_unpause,
+ Curl_creader_def_is_paused,
Curl_creader_def_done,
sizeof(struct cr_lc_ctx)
};
@@ -1195,6 +1241,7 @@ static const struct Curl_crtype cr_null = { Curl_creader_def_resume_from,
Curl_creader_def_rewind,
Curl_creader_def_unpause,
+ Curl_creader_def_is_paused,
Curl_creader_def_done,
sizeof(struct Curl_creader)
};
@@ -1294,6 +1341,7 @@ static const struct Curl_crtype cr_buf = { cr_buf_resume_from,
Curl_creader_def_rewind,
Curl_creader_def_unpause,
+ Curl_creader_def_is_paused,
Curl_creader_def_done,
sizeof(struct cr_buf_ctx)
};
@@ -1356,6 +1404,18 @@ CURLcode Curl_creader_unpause(struct Curl_easy *data) return result;
}
+bool Curl_creader_is_paused(struct Curl_easy *data)
+{
+ struct Curl_creader *reader = data->req.reader_stack;
+
+ while(reader) {
+ if(reader->crt->is_paused(data, reader))
+ return TRUE;
+ reader = reader->next;
+ }
+ return FALSE;
+}
+
void Curl_creader_done(struct Curl_easy *data, int premature)
{
struct Curl_creader *reader = data->req.reader_stack;
|