From 11aed4209e3ee9fcb681f84284544c8c68b196c7 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Sat, 12 Sep 2020 14:50:29 +0000 Subject: [PATCH] TD-1311 --- src/plugins/http/inc/ehttp_parser.h | 97 +++- src/plugins/http/inc/ehttp_util_string.h | 25 +- src/plugins/http/inc/httpInt.h | 7 +- src/plugins/http/src/ehttp_parser.c | 555 +++++++++++------------ src/plugins/http/src/ehttp_util_string.c | 13 +- src/plugins/http/src/httpContext.c | 10 +- src/plugins/http/src/httpServer.c | 7 +- 7 files changed, 357 insertions(+), 357 deletions(-) diff --git a/src/plugins/http/inc/ehttp_parser.h b/src/plugins/http/inc/ehttp_parser.h index be87650128..7ddfcb32db 100644 --- a/src/plugins/http/inc/ehttp_parser.h +++ b/src/plugins/http/inc/ehttp_parser.h @@ -1,36 +1,93 @@ -#ifndef _ehttp_parser_fc7f9ac9_52da_4ee3_b556_deb2e1c3866e -#define _ehttp_parser_fc7f9ac9_52da_4ee3_b556_deb2e1c3866e +#ifndef HTTP_PARSER_H +#define HTTP_PARSER_H -#include +#include "ehttp_util_string.h" +#include "ehttp_gzip.h" -typedef struct ehttp_parser_s ehttp_parser_t; -typedef struct ehttp_parser_callbacks_s ehttp_parser_callbacks_t; -typedef struct ehttp_parser_conf_s ehttp_parser_conf_t; -typedef struct ehttp_status_code_s ehttp_status_code_t; +struct HttpContext; -struct ehttp_parser_callbacks_s { +typedef enum HTTP_PARSER_STATE { + HTTP_PARSER_BEGIN, + HTTP_PARSER_REQUEST_OR_RESPONSE, + HTTP_PARSER_METHOD, + HTTP_PARSER_TARGET, + HTTP_PARSER_HTTP_VERSION, + HTTP_PARSER_SP, + HTTP_PARSER_STATUS_CODE, + HTTP_PARSER_REASON_PHRASE, + HTTP_PARSER_CRLF, + HTTP_PARSER_HEADER, + HTTP_PARSER_HEADER_KEY, + HTTP_PARSER_HEADER_VAL, + HTTP_PARSER_CHUNK_SIZE, + HTTP_PARSER_CHUNK, + HTTP_PARSER_END, + HTTP_PARSER_ERROR, +} HTTP_PARSER_STATE; + +typedef struct HttpParserStatusObj { + int32_t status_code; + const char *status_desc; +} HttpParserStatusObj; + +typedef struct HttpParserCallbackObj { void (*on_request_line)(void *arg, const char *method, const char *target, const char *version, const char *target_raw); void (*on_status_line)(void *arg, const char *version, int status_code, const char *reason_phrase); void (*on_header_field)(void *arg, const char *key, const char *val); void (*on_body)(void *arg, const char *chunk, size_t len); void (*on_end)(void *arg); void (*on_error)(void *arg, int status_code); -}; +} HttpParserCallbackObj; -struct ehttp_parser_conf_s { - size_t flush_block_size; // <=0: immediately -}; +typedef struct HttpParserConfObj { + size_t flush_block_size; // <=0: immediately +} HttpParserConfObj; -ehttp_parser_t* ehttp_parser_create(ehttp_parser_callbacks_t callbacks, ehttp_parser_conf_t conf, void *arg); -void ehttp_parser_destroy(ehttp_parser_t *parser); -int ehttp_parser_parse(ehttp_parser_t *parser, const char *buf, size_t len); -int ehttp_parser_parse_string(ehttp_parser_t *parser, const char *str); -int ehttp_parser_parse_char(ehttp_parser_t *parser, const char c); -int ehttp_parser_parse_end(ehttp_parser_t *parser); +typedef struct HttpParseKvObj { + char *key; + char *val; +} HttpParseKvObj; + +typedef struct HttpParserObj { + HttpParserCallbackObj callbacks; + HttpParserConfObj conf; + void * arg; + char * method; + char * target; + char * target_raw; + char * version; + int http_10 : 2; + int http_11 : 2; + int accept_encoding_gzip : 2; + int accept_encoding_chunked : 2; + int transfer_gzip : 2; + int transfer_chunked : 2; + int content_length_specified : 2; + int content_chunked : 2; + int status_code; + char * reason_phrase; + char * key; + char * val; + HttpParseKvObj * kvs; + size_t kvs_count; + char * auth_basic; + char * auth_taosd; + size_t content_length; + size_t chunk_size; + size_t received_chunk_size; + size_t received_size; + ehttp_gzip_t * gzip; + HttpUtilString str; + HTTP_PARSER_STATE *stacks; + size_t stacks_count; +} HttpParserObj; + +HttpParserObj* httpParserCreate(HttpParserCallbackObj callbacks, HttpParserConfObj conf, void *arg); +void httpParserDestroy(HttpParserObj *parser); +int32_t httpParserBuf(struct HttpContext *pContext, HttpParserObj *parser, const char *buf, int32_t len); char* ehttp_parser_urldecode(const char *enc); const char* ehttp_status_code_get_desc(const int status_code); -#endif // _ehttp_parser_fc7f9ac9_52da_4ee3_b556_deb2e1c3866e - +#endif diff --git a/src/plugins/http/inc/ehttp_util_string.h b/src/plugins/http/inc/ehttp_util_string.h index 46c5a42827..eb44805f96 100644 --- a/src/plugins/http/inc/ehttp_util_string.h +++ b/src/plugins/http/inc/ehttp_util_string.h @@ -1,18 +1,13 @@ -#ifndef _ehttp_util_string_h_99dacde5_2e7d_4662_97d6_04611fde683b_ -#define _ehttp_util_string_h_99dacde5_2e7d_4662_97d6_04611fde683b_ +#ifndef HTTP_UTIL_STRING +#define HTTP_UTIL_STRING -#include +typedef struct HttpUtilString { + char * str; + size_t len; +} HttpUtilString; -typedef struct ehttp_util_string_s ehttp_util_string_t; - -struct ehttp_util_string_s { - char *str; - size_t len; -}; - -void ehttp_util_string_cleanup(ehttp_util_string_t *str); -int ehttp_util_string_append(ehttp_util_string_t *str, const char *s, size_t len); -void ehttp_util_string_clear(ehttp_util_string_t *str); - -#endif // _ehttp_util_string_h_99dacde5_2e7d_4662_97d6_04611fde683b_ +void httpParserCleanupString(HttpUtilString *str); +int32_t httpParserAppendString(HttpUtilString *str, const char *s, int32_t len); +void httpParserClearString(HttpUtilString *str); +#endif diff --git a/src/plugins/http/inc/httpInt.h b/src/plugins/http/inc/httpInt.h index 044b5cc4cc..89972adc87 100644 --- a/src/plugins/http/inc/httpInt.h +++ b/src/plugins/http/inc/httpInt.h @@ -179,10 +179,9 @@ typedef struct { HttpBuf data; // body content HttpBuf token; // auth token HttpDecodeMethod *pMethod; - - ehttp_parser_t *parser; - int inited:2; - int failed:4; + HttpParserObj * parser; + int8_t inited; + int8_t failed; } HttpParser; typedef struct HttpContext { diff --git a/src/plugins/http/src/ehttp_parser.c b/src/plugins/http/src/ehttp_parser.c index 30d37f8a0d..0d0382078f 100644 --- a/src/plugins/http/src/ehttp_parser.c +++ b/src/plugins/http/src/ehttp_parser.c @@ -1,19 +1,20 @@ +#include "os.h" +#include "httpLog.h" +#include "httpContext.h" +#include "ehttp_util_string.h" #include "ehttp_parser.h" #include "ehttp_gzip.h" #include "ehttp_util_string.h" #include "elog.h" + #include #include #include -struct ehttp_status_code_s { - int status_code; - const char *status_desc; -}; -static ehttp_status_code_t status_codes[] = { +static HttpParserStatusObj status_codes[] = { {100, "Continue"}, {101, "Switching Protocol"}, {102, "Processing (WebDAV)"}, @@ -81,7 +82,7 @@ static ehttp_status_code_t status_codes[] = { }; const char* ehttp_status_code_get_desc(const int status_code) { - ehttp_status_code_t *p = status_codes; + HttpParserStatusObj *p = status_codes; while (p->status_code!=0) { if (p->status_code==status_code) return p->status_desc; ++p; @@ -89,74 +90,6 @@ const char* ehttp_status_code_get_desc(const int status_code) { return "Unknow status code"; } -typedef enum HTTP_PARSER_STATE { - HTTP_PARSER_BEGIN, - HTTP_PARSER_REQUEST_OR_RESPONSE, - HTTP_PARSER_METHOD, - HTTP_PARSER_TARGET, - HTTP_PARSER_HTTP_VERSION, - HTTP_PARSER_SP, - HTTP_PARSER_STATUS_CODE, - HTTP_PARSER_REASON_PHRASE, - HTTP_PARSER_CRLF, - HTTP_PARSER_HEADER, - HTTP_PARSER_HEADER_KEY, - HTTP_PARSER_HEADER_VAL, - HTTP_PARSER_CHUNK_SIZE, - HTTP_PARSER_CHUNK, - HTTP_PARSER_END, - HTTP_PARSER_ERROR, -} HTTP_PARSER_STATE; - -typedef struct ehttp_parser_kv_s ehttp_parser_kv_t; - -struct ehttp_parser_kv_s { - char *key; - char *val; -}; - -struct ehttp_parser_s { - ehttp_parser_callbacks_t callbacks; - void *arg; - ehttp_parser_conf_t conf; - - char *method; - char *target; - char *target_raw; - char *version; - - int http_10:2; - int http_11:2; - int accept_encoding_gzip:2; - int accept_encoding_chunked:2; - int transfer_gzip:2; - int transfer_chunked:2; - int content_length_specified:2; - int content_chunked:2; - - - int status_code; - char *reason_phrase; - - char *key; - char *val; - ehttp_parser_kv_t *kvs; - size_t kvs_count; - - char *auth_basic; - - size_t content_length; - - size_t chunk_size; - size_t received_chunk_size; - size_t received_size; - - ehttp_gzip_t *gzip; - ehttp_util_string_t str; - HTTP_PARSER_STATE *stacks; - size_t stacks_count; -}; - static void dummy_on_request_line(void *arg, const char *method, const char *target, const char *version, const char *target_raw) { } @@ -175,15 +108,14 @@ static void dummy_on_end(void *arg) { static void dummy_on_error(void *arg, int status_code) { } +static HTTP_PARSER_STATE httpParserTop(HttpParserObj *parser) { + ASSERT(parser->stacks_count >= 1); + ASSERT(parser->stacks); -static HTTP_PARSER_STATE ehttp_parser_top(ehttp_parser_t *parser) { - EQ_ASSERT(parser->stacks_count >= 1); - EQ_ASSERT(parser->stacks); - - return parser->stacks[parser->stacks_count-1]; + return parser->stacks[parser->stacks_count - 1]; } -static int ehttp_parser_push(ehttp_parser_t *parser, HTTP_PARSER_STATE state) { +static int httpParserPush(HttpParserObj *parser, HTTP_PARSER_STATE state) { size_t n = parser->stacks_count + 1; // HTTP_PARSER_STATE *stacks = (HTTP_PARSER_STATE*)reallocarray(parser->stacks, n, sizeof(*stacks)); HTTP_PARSER_STATE *stacks = (HTTP_PARSER_STATE*)realloc(parser->stacks, n * sizeof(*stacks)); @@ -196,15 +128,15 @@ static int ehttp_parser_push(ehttp_parser_t *parser, HTTP_PARSER_STATE state) { return 0; } -static int ehttp_parser_pop(ehttp_parser_t *parser) { +static int httpParserPop(HttpParserObj *parser) { if (parser->stacks_count <= 0) return -1; --parser->stacks_count; return 0; } -ehttp_parser_t *ehttp_parser_create(ehttp_parser_callbacks_t callbacks, ehttp_parser_conf_t conf, void *arg) { - ehttp_parser_t *parser = (ehttp_parser_t*)calloc(1, sizeof(*parser)); +HttpParserObj *httpParserCreate(HttpParserCallbackObj callbacks, HttpParserConfObj conf, void *arg) { + HttpParserObj *parser = (HttpParserObj*)calloc(1, sizeof(*parser)); if (!parser) return NULL; parser->callbacks = callbacks; @@ -230,16 +162,16 @@ ehttp_parser_t *ehttp_parser_create(ehttp_parser_callbacks_t callbacks, ehttp_pa parser->callbacks.on_error = dummy_on_error; } - ehttp_parser_push(parser, HTTP_PARSER_BEGIN); + httpParserPush(parser, HTTP_PARSER_BEGIN); return parser; } -static void ehttp_parser_kvs_destroy(ehttp_parser_t *parser) { +static void ehttp_parser_kvs_destroy(HttpParserObj *parser) { if (!parser->kvs) return; for (size_t i=0; ikvs_count; ++i) { - ehttp_parser_kv_t *p = &parser->kvs[i]; + HttpParseKvObj *p = &parser->kvs[i]; free(p->key); p->key = NULL; free(p->val); p->val = NULL; } @@ -251,7 +183,7 @@ static void ehttp_parser_kvs_destroy(ehttp_parser_t *parser) { parser->auth_basic = NULL; } -void ehttp_parser_destroy(ehttp_parser_t *parser) { +void httpParserDestroy(HttpParserObj *parser) { if (!parser) return; free(parser->method); parser->method = NULL; @@ -268,7 +200,7 @@ void ehttp_parser_destroy(ehttp_parser_t *parser) { ehttp_parser_kvs_destroy(parser); - ehttp_util_string_cleanup(&parser->str); + httpParserCleanupString(&parser->str); if (parser->gzip) { ehttp_gzip_destroy(parser->gzip); parser->gzip = NULL; @@ -281,52 +213,52 @@ void ehttp_parser_destroy(ehttp_parser_t *parser) { char *ehttp_parser_urldecode(const char *enc) { int ok = 1; - ehttp_util_string_t str = {0}; + HttpUtilString str = {0}; while (*enc) { char *p = strchr(enc, '%'); if (!p) break; int hex, cnt; int n = sscanf(p+1, "%2x%n", &hex, &cnt); if (n!=1 && cnt !=2) { ok = 0; break; } - if (ehttp_util_string_append(&str, enc, p-enc)) { ok = 0; break; } + if (httpParserAppendString(&str, enc, p-enc)) { ok = 0; break; } char c = (char)hex; - if (ehttp_util_string_append(&str, &c, 1)) { ok = 0; break; } + if (httpParserAppendString(&str, &c, 1)) { ok = 0; break; } enc = p+3; } char *dec = NULL; if (ok && *enc) { - if (ehttp_util_string_append(&str, enc, strlen(enc))) { ok = 0; } + if (httpParserAppendString(&str, enc, strlen(enc))) { ok = 0; } } if (ok) { dec = str.str; str.str = NULL; } - ehttp_util_string_cleanup(&str); + httpParserCleanupString(&str); return dec; } static void on_data(ehttp_gzip_t *gzip, void *arg, const char *buf, size_t len) { - ehttp_parser_t *parser = (ehttp_parser_t*)arg; + HttpParserObj *parser = (HttpParserObj*)arg; parser->callbacks.on_body(parser->arg, buf, len); } -static int ehttp_parser_check_field(ehttp_parser_t *parser, const char *key, const char *val) { - int ok = 0; +static int32_t httpParserCheckField(HttpContext *pContext, HttpParserObj *parser, const char *key, const char *val) { + int32_t ok = 0; do { - if (0==strcasecmp(key, "Content-Length")) { - size_t len = 0; - int bytes = 0; - int n = sscanf(val, "%ld%n", &len, &bytes); - if (n==1 && bytes==strlen(val)) { + if (0 == strcasecmp(key, "Content-Length")) { + int32_t len = 0; + int32_t bytes = 0; + int32_t n = sscanf(val, "%d%n", &len, &bytes); + if (n == 1 && bytes == strlen(val)) { parser->content_length = len; - parser->chunk_size = len; + parser->chunk_size = len; parser->content_length_specified = 1; break; } ok = -1; break; } - if (0==strcasecmp(key, "Accept-Encoding")) { + if (0 == strcasecmp(key, "Accept-Encoding")) { if (strstr(val, "gzip")) { parser->accept_encoding_gzip = 1; } @@ -335,13 +267,13 @@ static int ehttp_parser_check_field(ehttp_parser_t *parser, const char *key, con } break; } - if (0==strcasecmp(key, "Content-Encoding")) { - if (0==strcmp(val, "gzip")) { + if (0 == strcasecmp(key, "Content-Encoding")) { + if (0 == strcmp(val, "gzip")) { parser->content_chunked = 1; } break; } - if (0==strcasecmp(key, "Transfer-Encoding")) { + if (0 == strcasecmp(key, "Transfer-Encoding")) { if (strstr(val, "gzip")) { parser->transfer_gzip = 1; ehttp_gzip_conf_t conf = {0}; @@ -352,7 +284,7 @@ static int ehttp_parser_check_field(ehttp_parser_t *parser, const char *key, con parser->gzip = ehttp_gzip_create_decompressor(conf, callbacks, parser); if (!parser->gzip) { - E("failed to create gzip decompressor"); + httpDebug("failed to create gzip decompressor"); ok = -1; break; } @@ -365,24 +297,37 @@ static int ehttp_parser_check_field(ehttp_parser_t *parser, const char *key, con if (0==strcasecmp(key, "Authorization")) { char *t = NULL; char *s = NULL; - int bytes = 0; - int n = sscanf(val, "%ms %ms%n", &t, &s, &bytes); - if (n==2 && t && s && bytes==strlen(val) && strcmp(t, "Basic")) { - free(parser->auth_basic); - parser->auth_basic = s; s = NULL; + int32_t bytes = 0; + int32_t n = sscanf(val, "%ms %ms%n", &t, &s, &bytes); + if (n == 2 && t && s && bytes == strlen(val)) { + if (strcmp(t, "Basic") == 0) { + free(parser->auth_basic); + parser->auth_basic = s; + s = NULL; + } else if (n == 2 && t && s && strcmp(t, "Taosd") == 0) { + free(parser->auth_taosd); + parser->auth_taosd = s; + s = NULL; + } else { + httpError("context:%p, fd:%d, invalid auth, t:%s s:%s", pContext, pContext->fd, t, s); + ok = -1; + } } else { + httpError("context:%p, fd:%d, parse auth failed, t:%s s:%s", pContext, pContext->fd, t, s); ok = -1; } - free(t); free(s); + + free(t); + free(s); break; } } while (0); return ok; } -static int ehttp_parser_kvs_append_kv(ehttp_parser_t *parser, const char *key, const char *val) { - // ehttp_parser_kv_t *kvs = (ehttp_parser_kv_t*)reallocarray(parser->kvs, parser->kvs_count + 1, sizeof(*kvs)); - ehttp_parser_kv_t *kvs = (ehttp_parser_kv_t*)realloc(parser->kvs, (parser->kvs_count + 1) * sizeof(*kvs)); +static int httpParserAppendKv(HttpParserObj *parser, const char *key, const char *val) { + // HttpParseKvObj *kvs = (HttpParseKvObj*)reallocarray(parser->kvs, parser->kvs_count + 1, sizeof(*kvs)); + HttpParseKvObj *kvs = (HttpParseKvObj*)realloc(parser->kvs, (parser->kvs_count + 1) * sizeof(*kvs)); if (!kvs) return -1; parser->kvs = kvs; @@ -403,69 +348,70 @@ static int ehttp_parser_kvs_append_kv(ehttp_parser_t *parser, const char *key, c return -1; } -static int on_begin(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnBegin(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { - if (c=='G' || c=='P' || c=='H' || c=='D' || c=='C' || c=='O' || c=='T') { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (c == 'G' || c == 'P' || c == 'H' || c == 'D' || c == 'C' || c == 'O' || c == 'T') { + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } - ehttp_parser_pop(parser); - ehttp_parser_push(parser, HTTP_PARSER_REQUEST_OR_RESPONSE); + httpParserPop(parser); + httpParserPush(parser, HTTP_PARSER_REQUEST_OR_RESPONSE); break; } - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); } while (0); return ok; } -static int on_request_or_response(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnRquestOrResponse(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { - if (parser->str.len==1) { - if (c=='T' && parser->str.str[0]=='H') { - ehttp_parser_pop(parser); - ehttp_parser_push(parser, HTTP_PARSER_END); - ehttp_parser_push(parser, HTTP_PARSER_HEADER); - ehttp_parser_push(parser, HTTP_PARSER_CRLF); - ehttp_parser_push(parser, HTTP_PARSER_REASON_PHRASE); - ehttp_parser_push(parser, HTTP_PARSER_SP); - ehttp_parser_push(parser, HTTP_PARSER_STATUS_CODE); - ehttp_parser_push(parser, HTTP_PARSER_SP); - ehttp_parser_push(parser, HTTP_PARSER_HTTP_VERSION); + if (parser->str.len == 1) { + if (c == 'T' && parser->str.str[0] == 'H') { + httpParserPop(parser); + httpParserPush(parser, HTTP_PARSER_END); + httpParserPush(parser, HTTP_PARSER_HEADER); + httpParserPush(parser, HTTP_PARSER_CRLF); + httpParserPush(parser, HTTP_PARSER_REASON_PHRASE); + httpParserPush(parser, HTTP_PARSER_SP); + httpParserPush(parser, HTTP_PARSER_STATUS_CODE); + httpParserPush(parser, HTTP_PARSER_SP); + httpParserPush(parser, HTTP_PARSER_HTTP_VERSION); *again = 1; break; } - ehttp_parser_pop(parser); - ehttp_parser_push(parser, HTTP_PARSER_END); - ehttp_parser_push(parser, HTTP_PARSER_HEADER); - ehttp_parser_push(parser, HTTP_PARSER_CRLF); - ehttp_parser_push(parser, HTTP_PARSER_HTTP_VERSION); - ehttp_parser_push(parser, HTTP_PARSER_SP); - ehttp_parser_push(parser, HTTP_PARSER_TARGET); - ehttp_parser_push(parser, HTTP_PARSER_SP); - ehttp_parser_push(parser, HTTP_PARSER_METHOD); + httpParserPop(parser); + httpParserPush(parser, HTTP_PARSER_END); + httpParserPush(parser, HTTP_PARSER_HEADER); + httpParserPush(parser, HTTP_PARSER_CRLF); + httpParserPush(parser, HTTP_PARSER_HTTP_VERSION); + httpParserPush(parser, HTTP_PARSER_SP); + httpParserPush(parser, HTTP_PARSER_TARGET); + httpParserPush(parser, HTTP_PARSER_SP); + httpParserPush(parser, HTTP_PARSER_METHOD); *again = 1; break; } - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); } while (0); return ok; } -static int on_method(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnMethod(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { if (isalnum(c) || strchr("!#$%&'*+-.^_`|~", c)) { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpDebug("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -474,24 +420,24 @@ static int on_method(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char } parser->method = strdup(parser->str.str); if (!parser->method) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); *again = 1; } while (0); return ok; } -static int on_target(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnTarget(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { - if (!isspace(c) && c!='\r' && c!='\n') { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (!isspace(c) && c != '\r' && c != '\n') { + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -499,34 +445,34 @@ static int on_target(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char break; } parser->target_raw = strdup(parser->str.str); - parser->target = ehttp_parser_urldecode(parser->str.str); + parser->target = ehttp_parser_urldecode(parser->str.str); if (!parser->target_raw || !parser->target) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); *again = 1; } while (0); return ok; } -static int on_version(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnVersion(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { const char *prefix = "HTTP/1."; - int len = strlen(prefix); + int32_t len = strlen(prefix); if (parser->str.len < len) { if (prefix[parser->str.len]!=c) { - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); break; } - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -535,13 +481,13 @@ static int on_version(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const cha } if (c!='0' && c!='1') { - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); break; } - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -551,7 +497,7 @@ static int on_version(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const cha parser->version = strdup(parser->str.str); if (!parser->version) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -561,32 +507,32 @@ static int on_version(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const cha parser->callbacks.on_request_line(parser->arg, parser->method, parser->target, parser->version, parser->target_raw); } - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); } while (0); return ok; } -static int on_sp(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnSp(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { + int32_t ok = 0; do { - if (c==' ') { - ehttp_parser_pop(parser); + if (c == ' ') { + httpParserPop(parser); break; } - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + httpDebug("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); } while (0); return ok; } -static int on_status_code(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { +static int32_t httpParserOnStatusCode(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { int ok = 0; do { if (isdigit(c)) { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -594,36 +540,36 @@ static int on_status_code(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const if (parser->str.len < 3) break; sscanf(parser->str.str, "%d", &parser->status_code); - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); break; } - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); } while (0); return ok; } -static int on_reason_phrase(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { +static int32_t httpParserOnReasonPhrase(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { int ok = 0; do { if (c=='\r') { parser->reason_phrase = strdup(parser->str.str); if (!parser->reason_phrase) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } parser->callbacks.on_status_line(parser->arg, parser->version, parser->status_code, parser->reason_phrase); - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); *again = 1; break; } - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -632,10 +578,10 @@ static int on_reason_phrase(ehttp_parser_t *parser, HTTP_PARSER_STATE state, con return ok; } -static int post_process(ehttp_parser_t *parser) { +static int32_t httpParserPostProcess(HttpContext *pContext, HttpParserObj *parser) { if (parser->gzip) { if (ehttp_gzip_finish(parser->gzip)) { - E("gzip failed"); + httpError("context:%p, fd:%d, gzip failed", pContext, pContext->fd); parser->callbacks.on_error(parser->arg, 507); return -1; } @@ -644,28 +590,28 @@ static int post_process(ehttp_parser_t *parser) { return 0; } -static int on_crlf(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnCrlf(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { const char *s = "\r\n"; - int len = strlen(s); + int32_t len = strlen(s); if (s[parser->str.len]!=c) { - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); break; } - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } if (parser->str.len == len) { - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); - if (ehttp_parser_top(parser) == HTTP_PARSER_END) { - ok = post_process(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); + if (httpParserTop(parser) == HTTP_PARSER_END) { + ok = httpParserPostProcess(pContext, parser); } } break; @@ -673,49 +619,49 @@ static int on_crlf(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c return ok; } -static int on_header(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnHeader(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { if (c=='\r') { - ehttp_parser_pop(parser); + httpParserPop(parser); if (parser->transfer_chunked) { - ehttp_parser_push(parser, HTTP_PARSER_CHUNK_SIZE); - ehttp_parser_push(parser, HTTP_PARSER_CRLF); + httpParserPush(parser, HTTP_PARSER_CHUNK_SIZE); + httpParserPush(parser, HTTP_PARSER_CRLF); } else { if (parser->content_length > 0) { - ehttp_parser_push(parser, HTTP_PARSER_CHUNK); + httpParserPush(parser, HTTP_PARSER_CHUNK); } - ehttp_parser_push(parser, HTTP_PARSER_CRLF); + httpParserPush(parser, HTTP_PARSER_CRLF); } *again = 1; break; } if (c!=' ' && c!='\t' && c!=':' ) { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } - ehttp_parser_push(parser, HTTP_PARSER_CRLF); - ehttp_parser_push(parser, HTTP_PARSER_HEADER_VAL); - ehttp_parser_push(parser, HTTP_PARSER_SP); - ehttp_parser_push(parser, HTTP_PARSER_HEADER_KEY); + httpParserPush(parser, HTTP_PARSER_CRLF); + httpParserPush(parser, HTTP_PARSER_HEADER_VAL); + httpParserPush(parser, HTTP_PARSER_SP); + httpParserPush(parser, HTTP_PARSER_HEADER_KEY); break; } - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); } while (0); return ok; } -static int on_header_key(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { +static int httpParserOnHeaderKey(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { int ok = 0; do { if (isalnum(c) || strchr("!#$%&'*+-.^_`|~", c)) { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -725,61 +671,62 @@ static int on_header_key(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const if (c==':') { parser->key = strdup(parser->str.str); if (!parser->key) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); break; } - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); } while (0); return ok; } -static int on_header_val(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnHeaderVal(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { if (c != '\r' && c != '\n' && (!isspace(c) || parser->str.len>0)) { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; } break; } - const char *val = parser->str.str; - ok = ehttp_parser_check_field(parser, parser->key, val); - if (ehttp_parser_kvs_append_kv(parser, parser->key, val)) { + const char *val = parser->str.str; + ok = httpParserCheckField(pContext, parser, parser->key, val); + if (httpParserAppendKv(parser, parser->key, val)) { ok = -1; parser->callbacks.on_error(parser->arg, 507); } else { parser->callbacks.on_header_field(parser->arg, parser->key, val); } - free(parser->key); parser->key = NULL; + free(parser->key); + parser->key = NULL; val = NULL; - if (ok==-1) break; - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); + if (ok == -1) break; + httpParserClearString(&parser->str); + httpParserPop(parser); *again = 1; } while (0); return ok; } -static int on_chunk_size(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; - int bytes; - size_t len; +static int32_t httpParserOnChunkSize(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; + int32_t bytes; + int32_t len; int n; do { if (isxdigit(c)) { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -787,44 +734,44 @@ static int on_chunk_size(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const break; } if (c=='\r') { - n = sscanf(parser->str.str, "%lx%n", &len, &bytes); + n = sscanf(parser->str.str, "%x%n", &len, &bytes); if (n==1 && bytes==strlen(parser->str.str) && len>=0) { if (len==0) { if (parser->content_length_specified == 0 || parser->received_size == parser->content_length) { - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); - ehttp_parser_push(parser, HTTP_PARSER_CRLF); - ehttp_parser_push(parser, HTTP_PARSER_CRLF); + httpParserClearString(&parser->str); + httpParserPop(parser); + httpParserPush(parser, HTTP_PARSER_CRLF); + httpParserPush(parser, HTTP_PARSER_CRLF); *again = 1; break; } } else { if (parser->content_length_specified == 0 || parser->received_size + len <= parser->content_length) { parser->chunk_size = len; - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); - ehttp_parser_push(parser, HTTP_PARSER_CHUNK_SIZE); - ehttp_parser_push(parser, HTTP_PARSER_CRLF); - ehttp_parser_push(parser, HTTP_PARSER_CHUNK); - ehttp_parser_push(parser, HTTP_PARSER_CRLF); + httpParserClearString(&parser->str); + httpParserPop(parser); + httpParserPush(parser, HTTP_PARSER_CHUNK_SIZE); + httpParserPush(parser, HTTP_PARSER_CRLF); + httpParserPush(parser, HTTP_PARSER_CHUNK); + httpParserPush(parser, HTTP_PARSER_CRLF); *again = 1; break; } } } } - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 400); } while (0); return ok; } -static int on_chunk(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { +static int httpParserOnChunk(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { int ok = 0; do { - if (ehttp_util_string_append(&parser->str, &c, 1)) { - E("parser state: %d, char: [%c]%02x, oom", state, c, c); + if (httpParserAppendString(&parser->str, &c, 1)) { + httpError("context:%p, fd:%d, parser state:%d, char:[%c]%02x, oom", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -835,7 +782,7 @@ static int on_chunk(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char if (parser->gzip) { if (ehttp_gzip_write(parser->gzip, parser->str.str, parser->str.len)) { - E("gzip failed"); + httpError("context:%p, fd:%d, gzip failed", pContext, pContext->fd); ok = -1; parser->callbacks.on_error(parser->arg, 507); break; @@ -844,124 +791,128 @@ static int on_chunk(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char parser->callbacks.on_body(parser->arg, parser->str.str, parser->str.len); } parser->received_chunk_size = 0; - ehttp_util_string_clear(&parser->str); - ehttp_parser_pop(parser); - if (ehttp_parser_top(parser) == HTTP_PARSER_END) { - ok = post_process(parser); + httpParserClearString(&parser->str); + httpParserPop(parser); + if (httpParserTop(parser) == HTTP_PARSER_END) { + ok = httpParserPostProcess(pContext, parser); } } while (0); return ok; } -static int on_end(ehttp_parser_t *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnEnd(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + int32_t ok = 0; do { - E("parser state: %d, unexpected char: [%c]%02x", state, c, c); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); ok = -1; parser->callbacks.on_error(parser->arg, 507); } while (0); return ok; } -static int parse_char(ehttp_parser_t *parser, const char c, int *again) { - int ok = 0; - HTTP_PARSER_STATE state = ehttp_parser_top(parser); +static int32_t httpParseChar(HttpContext *pContext, HttpParserObj *parser, const char c, int32_t *again) { + int32_t ok = 0; + HTTP_PARSER_STATE state = httpParserTop(parser); do { if (state == HTTP_PARSER_BEGIN) { - ok = on_begin(parser, state, c, again); + ok = httpParserOnBegin(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_REQUEST_OR_RESPONSE) { - ok = on_request_or_response(parser, state, c, again); + ok = httpParserOnRquestOrResponse(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_METHOD) { - ok = on_method(parser, state, c, again); + ok = httpParserOnMethod(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_TARGET) { - ok = on_target(parser, state, c, again); + ok = httpParserOnTarget(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_HTTP_VERSION) { - ok = on_version(parser, state, c, again); + ok = httpParserOnVersion(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_SP) { - ok = on_sp(parser, state, c, again); + ok = httpParserOnSp(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_STATUS_CODE) { - ok = on_status_code(parser, state, c, again); + ok = httpParserOnStatusCode(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_REASON_PHRASE) { - ok = on_reason_phrase(parser, state, c, again); + ok = httpParserOnReasonPhrase(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_CRLF) { - ok = on_crlf(parser, state, c, again); + ok = httpParserOnCrlf(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_HEADER) { - ok = on_header(parser, state, c, again); + ok = httpParserOnHeader(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_HEADER_KEY) { - ok = on_header_key(parser, state, c, again); + ok = httpParserOnHeaderKey(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_HEADER_VAL) { - ok = on_header_val(parser, state, c, again); + ok = httpParserOnHeaderVal(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_CHUNK_SIZE) { - ok = on_chunk_size(parser, state, c, again); + ok = httpParserOnChunkSize(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_CHUNK) { - ok = on_chunk(parser, state, c, again); + ok = httpParserOnChunk(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_END) { - ok = on_end(parser, state, c, again); + ok = httpParserOnEnd(pContext, parser, state, c, again); break; } if (state == HTTP_PARSER_ERROR) { ok = -2; break; } - E("unknown parser state: %d", state); + + httpError("context:%p, fd:%d, unknown parse state:%d", pContext, pContext->fd, state); ok = -1; parser->callbacks.on_error(parser->arg, 500); } while (0); - if (ok==-1) { - ehttp_parser_push(parser, HTTP_PARSER_ERROR); + + if (ok == -1) { + httpError("context:%p, fd:%d, failed to parse, state:%d ok:%d", pContext, pContext->fd, state, ok); + httpParserPush(parser, HTTP_PARSER_ERROR); } - if (ok==-2) ok = -1; + + if (ok == -2) { + httpError("context:%p, fd:%d, failed to parse, state:%d ok:%d", pContext, pContext->fd, state, ok); + ok = -1; + } + return ok; } -int ehttp_parser_parse_string(ehttp_parser_t *parser, const char *str) { - return ehttp_parser_parse(parser, str, str?strlen(str):0); -} - -int ehttp_parser_parse_char(ehttp_parser_t *parser, const char c) { - return ehttp_parser_parse(parser, &c, 1); -} - -int ehttp_parser_parse(ehttp_parser_t *parser, const char *buf, size_t len) { +int32_t httpParserBuf(HttpContext *pContext, HttpParserObj *parser, const char *buf, int32_t len) { const char *p = buf; - int ret = 0; - size_t i = 0; + int32_t ret = 0; + int32_t i = 0; + while (i < len) { - int again = 0; - ret = parse_char(parser, *p, &again); - if (ret) break; + int32_t again = 0; + ret = httpParseChar(pContext, parser, *p, &again); + if (ret != 0) { + httpError("context:%p, fd:%d, parse failed, ret:%d i:%d len:%d buf:%s", pContext, pContext->fd, ret, i, len, buf); + break; + } if (again) continue; ++p; ++i; } + return ret; } - diff --git a/src/plugins/http/src/ehttp_util_string.c b/src/plugins/http/src/ehttp_util_string.c index 94ebaaafa6..8900aa89bb 100644 --- a/src/plugins/http/src/ehttp_util_string.c +++ b/src/plugins/http/src/ehttp_util_string.c @@ -1,17 +1,14 @@ +#include "os.h" #include "ehttp_util_string.h" -#include -#include - -void ehttp_util_string_cleanup(ehttp_util_string_t *str) { +void httpParserCleanupString(HttpUtilString *str) { free(str->str); str->str = NULL; str->len = 0; } -int ehttp_util_string_append(ehttp_util_string_t *str, const char *s, size_t len) { - // int n = str->str?strlen(str->str):0; - int n = str->len; +int32_t httpParserAppendString(HttpUtilString *str, const char *s, int32_t len) { + int32_t n = str->len; char *p = (char*)realloc(str->str, n + len + 1); if (!p) return -1; strncpy(p+n, s, len); @@ -21,7 +18,7 @@ int ehttp_util_string_append(ehttp_util_string_t *str, const char *s, size_t len return 0; } -void ehttp_util_string_clear(ehttp_util_string_t *str) { +void httpParserClearString(HttpUtilString *str) { if (str->str) { str->str[0] = '\0'; str->len = 0; diff --git a/src/plugins/http/src/httpContext.c b/src/plugins/http/src/httpContext.c index 59c81f5960..987de519c7 100644 --- a/src/plugins/http/src/httpContext.c +++ b/src/plugins/http/src/httpContext.c @@ -26,11 +26,9 @@ #include "httpResp.h" #include "httpSql.h" #include "httpSession.h" - #include "httpContext.h" #include "elog.h" -// dirty tweak extern bool httpGetHttpMethod(HttpContext* pContext); extern bool httpParseURL(HttpContext* pContext); extern bool httpParseHttpVersion(HttpContext* pContext); @@ -74,7 +72,7 @@ static void httpDestroyContext(void *data) { httpFreeMultiCmds(pContext); if (pContext->parser.parser) { - ehttp_parser_destroy(pContext->parser.parser); + httpParserDestroy(pContext->parser.parser); pContext->parser.parser = NULL; } @@ -195,7 +193,7 @@ bool httpInitContext(HttpContext *pContext) { memset(pParser, 0, sizeof(HttpParser)); pParser->pCur = pParser->pLast = pParser->buffer; - ehttp_parser_callbacks_t callbacks = { + HttpParserCallbackObj callbacks = { httpParseOnRequestLine, httpParseOnStatusLine, httpParseOnHeaderField, @@ -203,10 +201,10 @@ bool httpInitContext(HttpContext *pContext) { httpParseOnEnd, httpParseOnError }; - ehttp_parser_conf_t conf = { + HttpParserConfObj conf = { .flush_block_size = 0 }; - pParser->parser = ehttp_parser_create(callbacks, conf, pContext); + pParser->parser = httpParserCreate(callbacks, conf, pContext); pParser->inited = 1; httpDebug("context:%p, fd:%d, parsed:%d", pContext, pContext->fd, pContext->parsed); diff --git a/src/plugins/http/src/httpServer.c b/src/plugins/http/src/httpServer.c index 614cc92700..b42e2cb0aa 100644 --- a/src/plugins/http/src/httpServer.c +++ b/src/plugins/http/src/httpServer.c @@ -352,8 +352,11 @@ static bool httpReadData(HttpContext *pContext) { int nread = (int)taosReadSocket(pContext->fd, buf, sizeof(buf)); if (nread > 0) { buf[nread] = '\0'; - if (ehttp_parser_parse(pParser->parser, buf, nread)) { - httpError("context:%p, fd:%d, init parse failed, close connect", pContext, pContext->fd); + httpTrace("context:%p, fd:%d, nread:%d content:%s", pContext, pContext->fd, nread, buf); + int ok = httpParserBuf(pContext, pParser->parser, buf, nread); + + if (ok) { + httpError("context:%p, fd:%d, init parse failed, reason:%d close connect", pContext, pContext->fd, ok); httpNotifyContextClose(pContext); return false; }