lib: move handling of data->req.writer_stack into Curl_client_write()
- move definitions from content_encoding.h to sendf.h - move create/cleanup/add code into sendf.c - installed content_encoding writers will always be called on Curl_client_write(CLIENTWRITE_BODY) - Curl_client_cleanup() frees writers and tempbuffers from paused transfers, irregardless of protocol Closes #11908
This commit is contained in:
parent
d39863d27a
commit
0bd9e137e3
@ -246,11 +246,7 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
|
||||
if(0 == len)
|
||||
return HYPER_ITER_CONTINUE;
|
||||
Curl_debug(data, CURLINFO_DATA_IN, buf, len);
|
||||
if(!data->set.http_ce_skip && k->writer_stack)
|
||||
/* content-encoded data */
|
||||
result = Curl_unencode_write(data, k->writer_stack, buf, len);
|
||||
else
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, buf, len);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, buf, len);
|
||||
|
||||
if(result) {
|
||||
data->state.hresult = result;
|
||||
|
||||
@ -280,9 +280,6 @@ static CURLcode deflate_init_writer(struct Curl_easy *data,
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!writer->downstream)
|
||||
return CURLE_WRITE_ERROR;
|
||||
|
||||
/* Initialize zlib */
|
||||
z->zalloc = (alloc_func) zalloc_cb;
|
||||
z->zfree = (free_func) zfree_cb;
|
||||
@ -337,9 +334,6 @@ static CURLcode gzip_init_writer(struct Curl_easy *data,
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!writer->downstream)
|
||||
return CURLE_WRITE_ERROR;
|
||||
|
||||
/* Initialize zlib */
|
||||
z->zalloc = (alloc_func) zalloc_cb;
|
||||
z->zfree = (free_func) zfree_cb;
|
||||
@ -647,9 +641,6 @@ static CURLcode brotli_init_writer(struct Curl_easy *data,
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
(void) data;
|
||||
|
||||
if(!writer->downstream)
|
||||
return CURLE_WRITE_ERROR;
|
||||
|
||||
bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
|
||||
return bp->br? CURLE_OK: CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -741,9 +732,6 @@ static CURLcode zstd_init_writer(struct Curl_easy *data,
|
||||
|
||||
(void)data;
|
||||
|
||||
if(!writer->downstream)
|
||||
return CURLE_WRITE_ERROR;
|
||||
|
||||
zp->zds = ZSTD_createDStream();
|
||||
zp->decomp = NULL;
|
||||
return zp->zds ? CURLE_OK : CURLE_OUT_OF_MEMORY;
|
||||
@ -822,8 +810,9 @@ static const struct content_encoding zstd_encoding = {
|
||||
static CURLcode identity_init_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) data;
|
||||
return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
|
||||
(void)data;
|
||||
(void)writer;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode identity_unencode_write(struct Curl_easy *data,
|
||||
@ -903,51 +892,13 @@ char *Curl_all_content_encodings(void)
|
||||
}
|
||||
|
||||
|
||||
/* Real client writer: no downstream. */
|
||||
static CURLcode client_init_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) data;
|
||||
return writer->downstream? CURLE_WRITE_ERROR: CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode client_unencode_write(struct Curl_easy *data,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
(void) writer;
|
||||
|
||||
if(!nbytes || k->ignorebody)
|
||||
return CURLE_OK;
|
||||
|
||||
return Curl_client_write(data, CLIENTWRITE_BODY, (char *) buf, nbytes);
|
||||
}
|
||||
|
||||
static void client_close_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) data;
|
||||
(void) writer;
|
||||
}
|
||||
|
||||
static const struct content_encoding client_encoding = {
|
||||
NULL,
|
||||
NULL,
|
||||
client_init_writer,
|
||||
client_unencode_write,
|
||||
client_close_writer,
|
||||
sizeof(struct contenc_writer)
|
||||
};
|
||||
|
||||
|
||||
/* Deferred error dummy writer. */
|
||||
static CURLcode error_init_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) data;
|
||||
return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
|
||||
(void)data;
|
||||
(void)writer;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode error_unencode_write(struct Curl_easy *data,
|
||||
@ -984,31 +935,6 @@ static const struct content_encoding error_encoding = {
|
||||
sizeof(struct contenc_writer)
|
||||
};
|
||||
|
||||
/* Create an unencoding writer stage using the given handler. */
|
||||
static struct contenc_writer *
|
||||
new_unencoding_writer(struct Curl_easy *data,
|
||||
const struct content_encoding *handler,
|
||||
struct contenc_writer *downstream,
|
||||
int order)
|
||||
{
|
||||
struct contenc_writer *writer;
|
||||
|
||||
DEBUGASSERT(handler->writersize >= sizeof(struct contenc_writer));
|
||||
writer = (struct contenc_writer *) calloc(1, handler->writersize);
|
||||
|
||||
if(writer) {
|
||||
writer->handler = handler;
|
||||
writer->downstream = downstream;
|
||||
writer->order = order;
|
||||
if(handler->init_writer(data, writer)) {
|
||||
free(writer);
|
||||
writer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
/* Write data using an unencoding writer stack. "nbytes" is not
|
||||
allowed to be 0. */
|
||||
CURLcode Curl_unencode_write(struct Curl_easy *data,
|
||||
@ -1017,23 +943,11 @@ CURLcode Curl_unencode_write(struct Curl_easy *data,
|
||||
{
|
||||
if(!nbytes)
|
||||
return CURLE_OK;
|
||||
if(!writer)
|
||||
return CURLE_WRITE_ERROR;
|
||||
return writer->handler->unencode_write(data, writer, buf, nbytes);
|
||||
}
|
||||
|
||||
/* Close and clean-up the connection's writer stack. */
|
||||
void Curl_unencode_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
struct contenc_writer *writer = k->writer_stack;
|
||||
|
||||
while(writer) {
|
||||
k->writer_stack = writer->downstream;
|
||||
writer->handler->close_writer(data, writer);
|
||||
free(writer);
|
||||
writer = k->writer_stack;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the content encoding by name. */
|
||||
static const struct content_encoding *find_encoding(const char *name,
|
||||
size_t len)
|
||||
@ -1049,9 +963,6 @@ static const struct content_encoding *find_encoding(const char *name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allow no more than 5 "chained" compression steps */
|
||||
#define MAX_ENCODE_STACK 5
|
||||
|
||||
/* Set-up the unencoding stack from the Content-Encoding header value.
|
||||
* See RFC 7231 section 3.1.2.2. */
|
||||
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
||||
@ -1059,6 +970,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
unsigned int order = is_transfer? 2: 1;
|
||||
CURLcode result;
|
||||
|
||||
do {
|
||||
const char *name;
|
||||
@ -1085,41 +997,19 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
||||
if(is_transfer && !data->set.http_transfer_encoding)
|
||||
/* not requested, ignore */
|
||||
return CURLE_OK;
|
||||
|
||||
encoding = find_encoding(name, namelen);
|
||||
|
||||
if(!k->writer_stack) {
|
||||
k->writer_stack = new_unencoding_writer(data, &client_encoding,
|
||||
NULL, 0);
|
||||
|
||||
if(!k->writer_stack)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!encoding)
|
||||
encoding = &error_encoding; /* Defer error at stack use. */
|
||||
|
||||
if(k->writer_stack_depth++ >= MAX_ENCODE_STACK) {
|
||||
failf(data, "Reject response due to more than %u content encodings",
|
||||
MAX_ENCODE_STACK);
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
/* Stack the unencoding stage. */
|
||||
if(order >= k->writer_stack->order) {
|
||||
writer = new_unencoding_writer(data, encoding,
|
||||
k->writer_stack, order);
|
||||
if(!writer)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
k->writer_stack = writer;
|
||||
}
|
||||
else {
|
||||
struct contenc_writer *w = k->writer_stack;
|
||||
while(w->downstream && order < w->downstream->order)
|
||||
w = w->downstream;
|
||||
writer = new_unencoding_writer(data, encoding,
|
||||
w->downstream, order);
|
||||
if(!writer)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
w->downstream = writer;
|
||||
result = Curl_client_create_writer(&writer, data, encoding, order);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_client_add_writer(data, writer);
|
||||
if(result) {
|
||||
Curl_client_free_writer(data, writer);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} while(*enclist);
|
||||
@ -1149,11 +1039,6 @@ CURLcode Curl_unencode_write(struct Curl_easy *data,
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
void Curl_unencode_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
(void) data;
|
||||
}
|
||||
|
||||
char *Curl_all_content_encodings(void)
|
||||
{
|
||||
return strdup(CONTENT_ENCODING_DEFAULT); /* Satisfy caller. */
|
||||
|
||||
@ -25,26 +25,9 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
struct contenc_writer {
|
||||
const struct content_encoding *handler; /* Encoding handler. */
|
||||
struct contenc_writer *downstream; /* Downstream writer. */
|
||||
unsigned int order; /* Ordering within writer stack. */
|
||||
};
|
||||
|
||||
/* Content encoding writer. */
|
||||
struct content_encoding {
|
||||
const char *name; /* Encoding name. */
|
||||
const char *alias; /* Encoding name alias. */
|
||||
CURLcode (*init_writer)(struct Curl_easy *data,
|
||||
struct contenc_writer *writer);
|
||||
CURLcode (*unencode_write)(struct Curl_easy *data,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes);
|
||||
void (*close_writer)(struct Curl_easy *data,
|
||||
struct contenc_writer *writer);
|
||||
size_t writersize;
|
||||
};
|
||||
struct contenc_writer;
|
||||
|
||||
char *Curl_all_content_encodings(void);
|
||||
|
||||
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
||||
const char *enclist, int is_transfer);
|
||||
@ -52,6 +35,5 @@ CURLcode Curl_unencode_write(struct Curl_easy *data,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes);
|
||||
void Curl_unencode_cleanup(struct Curl_easy *data);
|
||||
char *Curl_all_content_encodings(void);
|
||||
|
||||
#endif /* HEADER_CURL_CONTENT_ENCODING_H */
|
||||
|
||||
@ -1602,8 +1602,6 @@ CURLcode Curl_http_done(struct Curl_easy *data,
|
||||
data->state.authhost.multipass = FALSE;
|
||||
data->state.authproxy.multipass = FALSE;
|
||||
|
||||
Curl_unencode_cleanup(data);
|
||||
|
||||
/* set the proper values (possibly modified on POST) */
|
||||
conn->seek_func = data->set.seek_func; /* restore */
|
||||
conn->seek_client = data->set.seek_client; /* restore */
|
||||
|
||||
@ -175,10 +175,7 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data,
|
||||
|
||||
/* Write the data portion available */
|
||||
if(!data->set.http_te_skip && !k->ignorebody) {
|
||||
if(!data->set.http_ce_skip && k->writer_stack)
|
||||
result = Curl_unencode_write(data, k->writer_stack, datap, piece);
|
||||
else
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, datap, piece);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, datap, piece);
|
||||
|
||||
if(result) {
|
||||
*extrap = result;
|
||||
|
||||
@ -665,7 +665,6 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
unsigned int i;
|
||||
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d",
|
||||
@ -721,12 +720,7 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
|
||||
Curl_safefree(data->state.ulbuf);
|
||||
|
||||
/* if the transfer was completed in a paused state there can be buffered
|
||||
data left to free */
|
||||
for(i = 0; i < data->state.tempcount; i++) {
|
||||
Curl_dyn_free(&data->state.tempwrite[i].b);
|
||||
}
|
||||
data->state.tempcount = 0;
|
||||
Curl_client_cleanup(data);
|
||||
|
||||
CONNCACHE_LOCK(data);
|
||||
Curl_detach_connection(data);
|
||||
|
||||
141
lib/sendf.c
141
lib/sendf.c
@ -40,6 +40,7 @@
|
||||
#include "sendf.h"
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
#include "content_encoding.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "vssh/ssh.h"
|
||||
#include "easyif.h"
|
||||
@ -403,6 +404,14 @@ CURLcode Curl_client_write(struct Curl_easy *data,
|
||||
DEBUGASSERT(!(type & CLIENTWRITE_BODY) || (type == CLIENTWRITE_BODY));
|
||||
/* INFO is only INFO */
|
||||
DEBUGASSERT(!(type & CLIENTWRITE_INFO) || (type == CLIENTWRITE_INFO));
|
||||
|
||||
if(type == CLIENTWRITE_BODY) {
|
||||
if(data->req.ignorebody)
|
||||
return CURLE_OK;
|
||||
|
||||
if(data->req.writer_stack && !data->set.http_ce_skip)
|
||||
return Curl_unencode_write(data, data->req.writer_stack, ptr, len);
|
||||
}
|
||||
return chop_write(data, type, FALSE, ptr, len);
|
||||
}
|
||||
|
||||
@ -438,6 +447,138 @@ CURLcode Curl_client_unpause(struct Curl_easy *data)
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_client_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
struct contenc_writer *writer = data->req.writer_stack;
|
||||
size_t i;
|
||||
|
||||
while(writer) {
|
||||
data->req.writer_stack = writer->downstream;
|
||||
writer->handler->close_writer(data, writer);
|
||||
free(writer);
|
||||
writer = data->req.writer_stack;
|
||||
}
|
||||
|
||||
for(i = 0; i < data->state.tempcount; i++) {
|
||||
Curl_dyn_free(&data->state.tempwrite[i].b);
|
||||
}
|
||||
data->state.tempcount = 0;
|
||||
|
||||
}
|
||||
|
||||
/* Real client writer: no downstream. */
|
||||
static CURLcode client_cew_init(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) data;
|
||||
(void)writer;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode client_cew_write(struct Curl_easy *data,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
(void)writer;
|
||||
if(!nbytes || data->req.ignorebody)
|
||||
return CURLE_OK;
|
||||
return chop_write(data, CLIENTWRITE_BODY, FALSE, (char *)buf, nbytes);
|
||||
}
|
||||
|
||||
static void client_cew_close(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
(void) data;
|
||||
(void) writer;
|
||||
}
|
||||
|
||||
static const struct content_encoding client_cew = {
|
||||
NULL,
|
||||
NULL,
|
||||
client_cew_init,
|
||||
client_cew_write,
|
||||
client_cew_close,
|
||||
sizeof(struct contenc_writer)
|
||||
};
|
||||
|
||||
/* Create an unencoding writer stage using the given handler. */
|
||||
CURLcode Curl_client_create_writer(struct contenc_writer **pwriter,
|
||||
struct Curl_easy *data,
|
||||
const struct content_encoding *ce_handler,
|
||||
int order)
|
||||
{
|
||||
struct contenc_writer *writer;
|
||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
DEBUGASSERT(ce_handler->writersize >= sizeof(struct contenc_writer));
|
||||
writer = (struct contenc_writer *) calloc(1, ce_handler->writersize);
|
||||
if(!writer)
|
||||
goto out;
|
||||
|
||||
writer->handler = ce_handler;
|
||||
writer->order = order;
|
||||
result = ce_handler->init_writer(data, writer);
|
||||
|
||||
out:
|
||||
*pwriter = result? NULL : writer;
|
||||
if(result)
|
||||
free(writer);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_client_free_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
if(writer) {
|
||||
writer->handler->close_writer(data, writer);
|
||||
free(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/* allow no more than 5 "chained" compression steps */
|
||||
#define MAX_ENCODE_STACK 5
|
||||
|
||||
|
||||
static CURLcode init_writer_stack(struct Curl_easy *data)
|
||||
{
|
||||
DEBUGASSERT(!data->req.writer_stack);
|
||||
return Curl_client_create_writer(&data->req.writer_stack,
|
||||
data, &client_cew, 0);
|
||||
}
|
||||
|
||||
CURLcode Curl_client_add_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
if(!data->req.writer_stack) {
|
||||
result = init_writer_stack(data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(data->req.writer_stack_depth++ >= MAX_ENCODE_STACK) {
|
||||
failf(data, "Reject response due to more than %u content encodings",
|
||||
MAX_ENCODE_STACK);
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Stack the unencoding stage. */
|
||||
if(writer->order >= data->req.writer_stack->order) {
|
||||
writer->downstream = data->req.writer_stack;
|
||||
data->req.writer_stack = writer;
|
||||
}
|
||||
else {
|
||||
struct contenc_writer *w = data->req.writer_stack;
|
||||
while(w->downstream && writer->order < w->downstream->order)
|
||||
w = w->downstream;
|
||||
writer->downstream = w->downstream;
|
||||
w->downstream = writer;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Internal read-from-socket function. This is meant to deal with plain
|
||||
* sockets, SSL sockets and kerberos sockets.
|
||||
|
||||
34
lib/sendf.h
34
lib/sendf.h
@ -54,6 +54,40 @@ CURLcode Curl_client_write(struct Curl_easy *data, int type, char *ptr,
|
||||
size_t len) WARN_UNUSED_RESULT;
|
||||
|
||||
CURLcode Curl_client_unpause(struct Curl_easy *data);
|
||||
void Curl_client_cleanup(struct Curl_easy *data);
|
||||
|
||||
struct contenc_writer {
|
||||
const struct content_encoding *handler; /* Encoding handler. */
|
||||
struct contenc_writer *downstream; /* Downstream writer. */
|
||||
unsigned int order; /* Ordering within writer stack. */
|
||||
};
|
||||
|
||||
/* Content encoding writer. */
|
||||
struct content_encoding {
|
||||
const char *name; /* Encoding name. */
|
||||
const char *alias; /* Encoding name alias. */
|
||||
CURLcode (*init_writer)(struct Curl_easy *data,
|
||||
struct contenc_writer *writer);
|
||||
CURLcode (*unencode_write)(struct Curl_easy *data,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes);
|
||||
void (*close_writer)(struct Curl_easy *data,
|
||||
struct contenc_writer *writer);
|
||||
size_t writersize;
|
||||
};
|
||||
|
||||
|
||||
CURLcode Curl_client_create_writer(struct contenc_writer **pwriter,
|
||||
struct Curl_easy *data,
|
||||
const struct content_encoding *ce_handler,
|
||||
int order);
|
||||
|
||||
void Curl_client_free_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer);
|
||||
|
||||
CURLcode Curl_client_add_writer(struct Curl_easy *data,
|
||||
struct contenc_writer *writer);
|
||||
|
||||
|
||||
/* internal read-function, does plain socket, SSL and krb4 */
|
||||
CURLcode Curl_read(struct Curl_easy *data, curl_socket_t sockfd,
|
||||
|
||||
@ -700,19 +700,15 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
in http_chunks.c.
|
||||
Make sure that ALL_CONTENT_ENCODINGS contains all the
|
||||
encodings handled here. */
|
||||
if(data->set.http_ce_skip || !k->writer_stack) {
|
||||
if(!k->ignorebody && nread) {
|
||||
if(!k->ignorebody && nread) {
|
||||
#ifndef CURL_DISABLE_POP3
|
||||
if(conn->handler->protocol & PROTO_FAMILY_POP3)
|
||||
result = Curl_pop3_write(data, k->str, nread);
|
||||
else
|
||||
if(conn->handler->protocol & PROTO_FAMILY_POP3)
|
||||
result = Curl_pop3_write(data, k->str, nread);
|
||||
else
|
||||
#endif /* CURL_DISABLE_POP3 */
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
||||
nread);
|
||||
}
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY, k->str,
|
||||
nread);
|
||||
}
|
||||
else if(!k->ignorebody && nread)
|
||||
result = Curl_unencode_write(data, k->writer_stack, k->str, nread);
|
||||
}
|
||||
k->badheader = HEADER_NORMAL; /* taken care of now */
|
||||
|
||||
|
||||
@ -2033,13 +2033,13 @@ void Curl_free_request_state(struct Curl_easy *data)
|
||||
{
|
||||
Curl_safefree(data->req.p.http);
|
||||
Curl_safefree(data->req.newurl);
|
||||
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
if(data->req.doh) {
|
||||
Curl_close(&data->req.doh->probe[0].easy);
|
||||
Curl_close(&data->req.doh->probe[1].easy);
|
||||
}
|
||||
#endif
|
||||
Curl_client_cleanup(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user