修正HTTP应答构建时缺少Content-Encoding和Content-Length的缺陷。
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user