变更HTTP业务层回调函数定义,增加session系列操作方法定义及虚接口实现。

* 不提供业务层针对单个数据包(段)的处理函数(返回值),业务层只能对单个session定义操作;
* 通过session的方法(函数)通知解析层对该session的处理方法。
This commit is contained in:
Lu Qiuwen
2018-09-12 15:29:35 +08:00
parent 74a4d38fba
commit 9e59110f8a
8 changed files with 447 additions and 165 deletions

View File

@@ -43,7 +43,7 @@ static const char * __str_std_header_field_map[] =
static enum tfe_http_std_field __str_header_field_to_std_field_id(const char * str_field, size_t len)
{
/* TODO: store the header text in hash table or rbtree, or use AC multistring search algo. */
for (int i = 0; i < TFE_DIM(__str_std_header_field_map); i++)
for (unsigned int i = 0; i < TFE_DIM(__str_std_header_field_map); i++)
{
const char * __std_header_field = __str_std_header_field_map[i];
if (__std_header_field == NULL)
@@ -113,26 +113,19 @@ void __hf_public_req_fill_from_private(struct http_half_private * hf_private, st
struct tfe_http_req_spec * hf_req_spec = &hf_public->req_spec;
/* accept-encoding, host is located in header's K-V structure */
hf_req_spec->method = parser->method;
const static struct http_field_name __accept_encoding_field_name =
{
.field_id = TFE_HTTP_ACCEPT_ENCODING,
.field_name = NULL
};
hf_req_spec->method = (enum tfe_http_std_method) parser->method;
const static struct http_field_name __host_field_name =
{
.field_id = TFE_HTTP_HOST,
.field_name = NULL
};
hf_req_spec->accept_encoding = (char *)tfe_http_field_read(hf_public, &__accept_encoding_field_name);
hf_req_spec->host = (char *)tfe_http_field_read(hf_public, &__host_field_name);
hf_req_spec->host = (char *) tfe_http_field_read(hf_public, &__host_field_name);
/* uri is stored in underlay evbuffer, we need to append a terminal zero */
static const char __zero = 0;
evbuffer_add(hf_private->evbuf_uri, &__zero, sizeof(__zero));
hf_req_spec->uri = (char *)evbuffer_pullup(hf_private->evbuf_uri, evbuffer_get_length(hf_private->evbuf_uri));
hf_req_spec->uri = (char *) evbuffer_pullup(hf_private->evbuf_uri, evbuffer_get_length(hf_private->evbuf_uri));
/* TODO: URL
* url is more complex. need to review RFC */
@@ -153,21 +146,19 @@ void __hf_public_resp_fill_from_private(struct http_half_private * hf_private, s
};
/* Content Encoding */
hf_resp_spec->content_encoding = (char *)tfe_http_field_read(hf_public, &__cont_encoding_field_name);
hf_resp_spec->content_encoding = (char *) tfe_http_field_read(hf_public, &__cont_encoding_field_name);
}
/* ==================================================================================================================
* REQUEST PARSER CALLBACKS
* ================================================================================================================== */
#define __HF_PRIVATE_CHANGE_STATUS(_status, _now, _to) \
#define __HF_PRIVATE_CHANGE_STATUS(_status, _now, _to) \
do { assert(_status == _now); _status = _to; } while(0)
static int __parser_callback_on_message_begin(struct http_parser * parser)
{
struct http_half_private * hf_private = __PARSER_TO_HF_PRIVATE(parser);
enum tfe_http_direction direction = hf_private->hf_public.direction;
assert(hf_private->evbuf_uri == NULL && hf_private->evbuf_body == NULL);
assert(hf_private->evbuf_header_field == NULL && hf_private->evbuf_header_value == NULL);
@@ -179,6 +170,7 @@ static int __parser_callback_on_message_begin(struct http_parser * parser)
hf_private->status_header = STATUS_INIT;
hf_private->status_body = STATUS_INIT;
hf_private->status_message = STATUS_READING;
return 0;
}
@@ -235,6 +227,7 @@ static int __parser_callback_on_headers_complete(http_parser * parser)
__HF_PRIVATE_CHANGE_STATUS(hf_private->status_header, STATUS_READING, STATUS_COMPLETE);
__HF_PRIVATE_CHANGE_STATUS(hf_private->status_body, STATUS_INIT, STATUS_READING);
return 0;
}
@@ -268,6 +261,90 @@ static http_parser_settings __http_half_parse_setting =
.on_chunk_complete = NULL
};
const char * hf_ops_field_read(const struct tfe_http_half * half, const struct http_field_name * field)
{
const struct http_half_private * hf_private = to_hf_private(half);
assert(hf_private->major == 0 || hf_private->major == 1);
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;
}
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)
{
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);
TAILQ_INSERT_TAIL(&hf_private->header_list, __header, next);
return 0;
}
struct tfe_http_half * hf_ops_allow_write(const struct tfe_http_half * half)
{
return (struct tfe_http_half *) half;
}
const char * hf_ops_field_iterate(const struct tfe_http_half * half, void ** iter, struct http_field_name * field)
{
struct http_header_private ** __header_iter = (struct http_header_private **) iter;
const struct http_half_private * hf_private = to_hf_private(half);
if (*__header_iter == NULL)
{
*__header_iter = TAILQ_FIRST(&hf_private->header_list);
}
else
{
*__header_iter = TAILQ_NEXT(*__header_iter, next);
}
if (*__header_iter == NULL) return NULL;
/* Reference of inner data, user should copy it */
field->field_id = (*__header_iter)->field->field_id;
field->field_name = (*__header_iter)->field->field_name;
return (*__header_iter)->value;
}
int hf_ops_append_body(struct tfe_http_half * half, char * buff, size_t size, int flag)
{
return 0;
}
void hf_private_destory(struct http_half_private * hf_private)
{
if (hf_private->parse_object != NULL) free(hf_private->parse_object);
free(hf_private);
}
void hf_ops_free(struct tfe_http_half * half)
{
return hf_private_destory(to_hf_private(half));
}
struct tfe_http_half_ops __http_half_ops =
{
.ops_http_field_read = hf_ops_field_read,
.ops_http_field_write = hf_ops_field_write,
.ops_http_allow_write = hf_ops_allow_write,
.ops_http_field_iterate = hf_ops_field_iterate,
.ops_append_body = hf_ops_append_body,
.ops_free = hf_ops_free
};
struct http_half_private * hf_private_create(tfe_http_direction ht_dir, short major, short minor)
{
struct http_half_private * hf_private = ALLOC(struct http_half_private, 1);
@@ -275,9 +352,8 @@ struct http_half_private * hf_private_create(tfe_http_direction ht_dir, short ma
assert(ht_dir == TFE_HTTP_REQUEST || ht_dir == TFE_HTTP_RESPONSE);
/* PUBLIC */
hf_private->hf_public.major_version = major;
hf_private->hf_public.minor_version = minor;
hf_private->hf_public.direction = ht_dir;
hf_private->hf_public.ops = &__http_half_ops;
/* PRIVATE */
hf_private->parse_object = (struct http_parser *) malloc(sizeof(struct http_parser));
@@ -297,12 +373,6 @@ struct http_half_private * hf_private_create(tfe_http_direction ht_dir, short ma
return hf_private;
}
void hf_private_destory(struct http_half_private * hf_private)
{
if (hf_private->parse_object != NULL) free(hf_private->parse_object);
free(hf_private);
}
int hf_private_parse(struct http_half_private * hf_private, const unsigned char * data, size_t len)
{
assert(hf_private->parse_cursor <= len);
@@ -322,23 +392,21 @@ int hf_private_parse(struct http_half_private * hf_private, const unsigned char
if (sz_parsed && HTTP_PARSER_ERRNO(hf_private->parse_object) == HPE_PAUSED)
{
http_parser_pause(hf_private->parse_object, 0);
ret = 1;
goto __out;
}
hf_private->parse_cursor += sz_parsed;
/* Touch message's boundary, the parser jumps to end */
if (hf_private->status_message == STATUS_COMPLETE)
{
ret = 1;
goto __out;
if (data[hf_private->parse_cursor] == '\r' && data[hf_private->parse_cursor + 1] == '\n')
{
hf_private->parse_cursor++;
}
return 1;
}
/* Some kind of exception happend */
if (sz_parsed && HTTP_PARSER_ERRNO(hf_private->parse_object) > 0)
if (sz_parsed != __len_with_offset)
{
hf_private->parse_errno = HTTP_PARSER_ERRNO(hf_private->parse_object);
ret = -1;
goto __out;
ret = -1; goto __out;
}
__out: