修正HTTP应答构建时缺少Content-Encoding和Content-Length的缺陷。

This commit is contained in:
Lu Qiuwen
2018-09-28 16:43:24 +08:00
parent a58c4677fc
commit 6bce4104d8

View File

@@ -92,6 +92,19 @@ uint16_t __hf_content_encoding_parse(const char * str_content_encoding)
return HTTP_ACCEPT_ENCODING_NONE;
}
const char * __hf_content_encoding_to_str(unsigned int encode)
{
switch (encode)
{
case HTTP_ACCEPT_ENCODING_GZIP: return "gzip";
case HTTP_ACCEPT_ENCODING_X_GZIP: return "x-gzip";
case HTTP_ACCEPT_ENCODING_DEFLATE: return "deflate";
case HTTP_ACCEPT_ENCODING_BZIP2: return "bzip2";
case HTTP_ACCEPT_ENCODING_X_BZIP2: return "x-bzip2";
default: return "";
}
}
/* To flush header field and value which stash in evbuffer */
static void __http_half_header_kv_complete(struct http_half_private * hf_private)
{
@@ -444,16 +457,36 @@ const char * hf_ops_field_read(const struct tfe_http_half * half, const struct h
return __header_found != NULL ? __header_iter->value : NULL;
}
int hf_ops_field_write(struct tfe_http_half * half, const struct http_field_name * name, const char * value)
int hf_ops_field_write(struct tfe_http_half * half, const struct http_field_name * field, const char * value)
{
struct http_half_private * hf_private = to_hf_private(half);
assert(hf_private->major == 0 || hf_private->major == 1);
struct http_header_private * __header = ALLOC(struct http_header_private, 1);
__header->field = http_field_name_duplicate(name);
__header->value = tfe_strdup(value);
struct http_header_private * __header_iter = NULL;
struct http_header_private * __header_found = NULL;
TAILQ_FOREACH(__header_iter, &hf_private->header_list, next)
{
if (http_field_name_compare(__header_iter->field, field) != 0) continue;
__header_found = __header_iter; break;
}
/* Found a header, update a value,
* or insert a new header k-v in the tail of the header list */
if(__header_found != NULL)
{
if (__header_found->value != NULL) free(__header_found->value);
__header_found->value = tfe_strdup(value);
}
else
{
struct http_header_private * __header = ALLOC(struct http_header_private, 1);
__header->field = http_field_name_duplicate(field);
__header->value = tfe_strdup(value);
TAILQ_INSERT_TAIL(&hf_private->header_list, __header, next);
}
TAILQ_INSERT_TAIL(&hf_private->header_list, __header, next);
return 0;
}
@@ -786,6 +819,30 @@ void hf_private_construct(struct http_half_private * hf_private)
evbuffer_drain(hf_private->evbuf_raw, __buf_length);
}
/* Terminal the end of gzip stream */
if (hf_private->evbuf_body && hf_private->cv_compress_object)
{
hf_content_compress_write(hf_private->cv_compress_object, NULL, 0, hf_private->evbuf_body, 1);
}
if (hf_private->content_encoding != HTTP_ACCEPT_ENCODING_NONE)
{
const char * __str_content_encoding = __hf_content_encoding_to_str(hf_private->content_encoding);
const static struct http_field_name __cont_encoding_type_name = {TFE_HTTP_CONT_ENCODING, NULL};
tfe_http_field_write(hf_public, &__cont_encoding_type_name, __str_content_encoding);
}
/* have body, write content-length and content-type */
if (hf_private->evbuf_body)
{
/* To string */
char str_sz_evbuf_body[TFE_STRING_MAX];
snprintf(str_sz_evbuf_body, sizeof(str_sz_evbuf_body) - 1, "%lu", evbuffer_get_length(hf_private->evbuf_body));
const static struct http_field_name __cont_encoding_length_name = {TFE_HTTP_CONT_LENGTH, NULL};
tfe_http_field_write(hf_public, &__cont_encoding_length_name, str_sz_evbuf_body);
}
/* HTTP Request/Response first line */
if (hf_public->direction == TFE_HTTP_REQUEST) __construct_request_line(hf_private);
else __construct_response_line(hf_private);
@@ -804,12 +861,6 @@ void hf_private_construct(struct http_half_private * hf_private)
/* delimitor between header and body */
evbuffer_add_printf(hf_private->evbuf_raw, "\r\n");
/* Terminal the end of gzip stream */
if (hf_private->evbuf_body && hf_private->cv_compress_object)
{
hf_content_compress_write(hf_private->cv_compress_object, NULL, 0, hf_private->evbuf_body, 1);
}
/* add body */
if (hf_private->evbuf_body)
{