diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index d8e5c8f1d748f09c67bd6827b9b9441a01b155c5..3f7995f25e5e9c2c103449f09b70145fc006188b 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -97,8 +97,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_APP_ERROR, 0, 0x0211, "Applicatio TAOS_DEFINE_ERROR(TSDB_CODE_TSC_ACTION_IN_PROGRESS, 0, 0x0212, "Action in progress") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DISCONNECTED, 0, 0x0213, "Disconnected from service") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_NO_WRITE_AUTH, 0, 0x0214, "No write permission") -TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED, 0, 0x0215, "Connection killed") -TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, 0, 0x0216, "Syntax errr in SQL") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED, 0, 0x0215, "Connection killed") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, 0, 0x0216, "Syntax errr in SQL") // mnode TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, 0, 0x0300, "Message not processed") @@ -247,6 +247,39 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_ENABLED, 0, 0x0901, "Sync modul // wal TAOS_DEFINE_ERROR(TSDB_CODE_WAL_APP_ERROR, 0, 0x1000, "Unexpected generic error in wal") +// http +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_UNSUPPORT_URL, 0, 0x1100, "http url is not support") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_NO_ENOUGH_MEMORY, 0, 0x1101, "no enough memory") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_INVALID_VERSION, 0, 0x1102, "invalid http version") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_INVALID_CONTENT_LENGTH, 0, 0x1103, "invalid content length") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_CREATE_GZIP_FAILED, 0, 0x1104, "failed to create gzip") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_FINISH_GZIP_FAILED, 0, 0x1105, "failed to finish gzip") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_INVALID_AUTH_TYPE, 0, 0x1106, "invalid type of Authorization") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_INVALID_AUTH_FORMAT, 0, 0x1107, "invalid format of Authorization") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_INVALID_BASIC_AUTH, 0, 0x1108, "invalid basic Authorization") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_INVALID_TAOSD_AUTH, 0, 0x1109, "invalid taosd Authorization") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_METHOD_FAILED, 0, 0x110A, "failed to parse method") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_TARGET_FAILED, 0, 0x110B, "failed to parse target") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_VERSION_FAILED, 0, 0x110C, "failed to parse http version") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_SP_FAILED, 0, 0x110D, "failed to parse sp") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_STATUS_FAILED, 0, 0x110E, "failed to parse status") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_PHRASE_FAILED, 0, 0x110F, "failed to parse phrase") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_CRLF_FAILED, 0, 0x1110, "failed to parse crlf") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_HEADER_FAILED, 0, 0x1111, "failed to parse header") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_HEADER_KEY_FAILED, 0, 0x1112, "failed to parse header key") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_HEADER_VAL_FAILED, 0, 0x1113, "failed to parse header val") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_CHUNK_SIZE_FAILED, 0, 0x1114, "failed to parse chunk size") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_CHUNK_FAILED, 0, 0x1115, "failed to parse chunk") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_END_FAILED, 0, 0x1116, "failed to parse end section") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_INVALID_STATE, 0, 0x1117, "invalid parse state") +TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_PARSE_ERROR_STATE, 0, 0x1118, "failed to parse error section") + + + + + + + #ifdef TAOS_ERROR_C }; #endif diff --git a/src/plugins/http/inc/httpAuth.h b/src/plugins/http/inc/httpAuth.h index b8fabbe1ec28698cd35bf343af092eeb2d840716..4becae63327af2ea8059bdbcb324ca666f2fbccd 100644 --- a/src/plugins/http/inc/httpAuth.h +++ b/src/plugins/http/inc/httpAuth.h @@ -16,8 +16,8 @@ #ifndef TDENGINE_HTTP_TOKEN_H #define TDENGINE_HTTP_TOKEN_H -bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len); -bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int len); -bool httpGenTaosdAuthToken(HttpContext *pContext, char *token, int maxLen); +bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int32_t len); +bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int32_t len); +bool httpGenTaosdAuthToken(HttpContext *pContext, char *token, int32_t maxLen); #endif \ No newline at end of file diff --git a/src/plugins/http/inc/httpGcJson.h b/src/plugins/http/inc/httpGcJson.h index 609bb9b95e6255a6fdf215320b24bbc9292e87e2..0ba860687dfe370d5b418a7c6d7aa28d128d7a5d 100644 --- a/src/plugins/http/inc/httpGcJson.h +++ b/src/plugins/http/inc/httpGcJson.h @@ -24,7 +24,7 @@ void gcCleanQueryJson(HttpContext *pContext); void gcStartQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result); void gcStopQueryJson(HttpContext *pContext, HttpSqlCmd *cmd); -bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows); +bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows); void gcSendHeartBeatResp(HttpContext *pContext, HttpSqlCmd *cmd); diff --git a/src/plugins/http/inc/httpGzip.h b/src/plugins/http/inc/httpGzip.h index b2d6ace9b00d102128b41749b3070d5c45fb3a39..aeac79c9759078efb64669037c54122b2900d132 100644 --- a/src/plugins/http/inc/httpGzip.h +++ b/src/plugins/http/inc/httpGzip.h @@ -1,7 +1,20 @@ -#ifndef _ehttp_gzip_h_9196791b_ac2a_4d73_9979_f4b41abbc4c0_ -#define _ehttp_gzip_h_9196791b_ac2a_4d73_9979_f4b41abbc4c0_ - -#include +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef HTTP_GZIP_H +#define HTTP_GZIP_H #define EHTTP_GZIP_CHUNK_SIZE_DEFAULT (1024*16) @@ -11,20 +24,20 @@ typedef struct ehttp_gzip_callbacks_s ehttp_gzip_callbacks_t; typedef struct ehttp_gzip_conf_s ehttp_gzip_conf_t; struct ehttp_gzip_callbacks_s { - void (*on_data)(ehttp_gzip_t *gzip, void *arg, const char *buf, size_t len); + void (*on_data)(ehttp_gzip_t *gzip, void *arg, const char *buf, int32_t len); }; struct ehttp_gzip_conf_s { - int get_header:2; // 0: not fetching header info - size_t chunk_size; // 0: fallback to default: EHTTP_GZIP_CHUNK_SIZE_DEFAULT + int32_t get_header:2; // 0: not fetching header info + int32_t chunk_size; // 0: fallback to default: EHTTP_GZIP_CHUNK_SIZE_DEFAULT }; ehttp_gzip_t* ehttp_gzip_create_decompressor(ehttp_gzip_conf_t conf, ehttp_gzip_callbacks_t callbacks, void *arg); ehttp_gzip_t* ehttp_gzip_create_compressor(ehttp_gzip_conf_t conf, ehttp_gzip_callbacks_t callbacks, void *arg); void ehttp_gzip_destroy(ehttp_gzip_t *gzip); -int ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, size_t len); -int ehttp_gzip_finish(ehttp_gzip_t *gzip); +int32_t ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, int32_t len); +int32_t ehttp_gzip_finish(ehttp_gzip_t *gzip); #endif // _ehttp_gzip_h_9196791b_ac2a_4d73_9979_f4b41abbc4c0_ diff --git a/src/plugins/http/inc/httpInt.h b/src/plugins/http/inc/httpInt.h index 4348e5e0900d1a746db62030e271aae68a8c2ae1..86e1eeb6d61eb6fd13cee73e9bee09b19b16457c 100644 --- a/src/plugins/http/inc/httpInt.h +++ b/src/plugins/http/inc/httpInt.h @@ -30,51 +30,26 @@ #include "httpParser.h" #define HTTP_MAX_CMD_SIZE 1024 -#define HTTP_MAX_BUFFER_SIZE 1024*1024 - +#define HTTP_MAX_BUFFER_SIZE 1024*1024*8 #define HTTP_LABEL_SIZE 8 #define HTTP_MAX_EVENTS 10 -#define HTTP_BUFFER_SIZE 1024*65 //65k -#define HTTP_DECOMPRESS_BUF_SIZE 1024*64 +#define HTTP_BUFFER_INIT 8192 +#define HTTP_BUFFER_SIZE 8192000 #define HTTP_STEP_SIZE 1024 //http message get process step by step -#define HTTP_MAX_URL 5 //http url stack size #define HTTP_METHOD_SCANNER_SIZE 7 //http method fp size #define HTTP_GC_TARGET_SIZE 512 - -#define HTTP_VERSION_10 0 -#define HTTP_VERSION_11 1 -//#define HTTP_VERSION_12 2 - -#define HTTP_UNCUNKED 0 -#define HTTP_CHUNKED 1 - -#define HTTP_KEEPALIVE_NO_INPUT 0 -#define HTTP_KEEPALIVE_ENABLE 1 -#define HTTP_KEEPALIVE_DISABLE 2 - -#define HTTP_REQTYPE_OTHERS 0 -#define HTTP_REQTYPE_LOGIN 1 -#define HTTP_REQTYPE_HEARTBEAT 2 -#define HTTP_REQTYPE_SINGLE_SQL 3 -#define HTTP_REQTYPE_MULTI_SQL 4 - -#define HTTP_CHECK_BODY_ERROR -1 -#define HTTP_CHECK_BODY_CONTINUE 0 -#define HTTP_CHECK_BODY_SUCCESS 1 - -#define HTTP_READ_DATA_SUCCESS 0 -#define HTTP_READ_DATA_FAILED 1 - #define HTTP_WRITE_RETRY_TIMES 500 #define HTTP_WRITE_WAIT_TIME_MS 5 -#define HTTP_EXPIRED_TIME 60000 -#define HTTP_DELAY_CLOSE_TIME_MS 500 - -#define HTTP_COMPRESS_IDENTITY 0 -#define HTTP_COMPRESS_GZIP 2 - #define HTTP_SESSION_ID_LEN (TSDB_USER_LEN + TSDB_PASSWORD_LEN) +typedef enum HttpReqType { + HTTP_REQTYPE_OTHERS = 0, + HTTP_REQTYPE_LOGIN = 1, + HTTP_REQTYPE_HEARTBEAT = 2, + HTTP_REQTYPE_SINGLE_SQL = 3, + HTTP_REQTYPE_MULTI_SQL = 4 +} HttpReqType; + typedef enum { HTTP_SERVER_INIT, HTTP_SERVER_RUNNING, @@ -83,21 +58,12 @@ typedef enum { } HttpServerStatus; typedef enum { - HTTP_CONTEXT_STATE_READY, - HTTP_CONTEXT_STATE_HANDLING, - HTTP_CONTEXT_STATE_DROPPING, - HTTP_CONTEXT_STATE_CLOSED + HTTP_CONTEXT_STATE_READY, + HTTP_CONTEXT_STATE_HANDLING, + HTTP_CONTEXT_STATE_DROPPING, + HTTP_CONTEXT_STATE_CLOSED } HttpContextState; -struct HttpContext; -struct HttpThread; - -typedef struct { - char id[HTTP_SESSION_ID_LEN]; - int refCount; - void *taos; -} HttpSession; - typedef enum { HTTP_CMD_TYPE_UN_SPECIFIED, HTTP_CMD_TYPE_CREATE_DB, @@ -109,6 +75,15 @@ typedef enum { HTTP_CMD_STATE_NOT_RUN_YET, HTTP_CMD_STATE_RUN_FINISHED } HttpSql typedef enum { HTTP_CMD_RETURN_TYPE_WITH_RETURN, HTTP_CMD_RETURN_TYPE_NO_RETURN } HttpSqlCmdReturnType; +struct HttpContext; +struct HttpThread; + +typedef struct { + char id[HTTP_SESSION_ID_LEN]; + int32_t refCount; + void * taos; +} HttpSession; + typedef struct { // used by single cmd char *nativSql; @@ -158,42 +133,17 @@ typedef struct { void (*setNextCmdFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, int code); } HttpEncodeMethod; -typedef struct { - char *pos; - int32_t len; -} HttpBuf; - typedef enum { EHTTP_CONTEXT_PROCESS_FAILED = 0x01, EHTTP_CONTEXT_PARSER_FAILED = 0x02 } EHTTP_CONTEXT_FAILED_CAUSE; -typedef struct { - char buffer[HTTP_BUFFER_SIZE]; - int bufsize; - char *pLast; - char *pCur; - HttpBuf method; - HttpBuf path[HTTP_MAX_URL]; // url: dbname/meter/query - HttpBuf data; // body content - HttpBuf token; // auth token - HttpDecodeMethod *pMethod; - HttpParserObj * parser; - int8_t inited; - int8_t failed; -} HttpParser; - typedef struct HttpContext { int32_t refCount; - int fd; + int32_t fd; uint32_t accessTimes; uint32_t lastAccessTime; int32_t state; - uint8_t httpVersion; - uint8_t httpChunked; - uint8_t httpKeepAlive; // http1.0 and not keep-alive, close connection immediately - uint8_t acceptEncoding; - uint8_t contentEncoding; uint8_t reqType; uint8_t parsed; char ipstr[22]; @@ -203,12 +153,12 @@ typedef struct HttpContext { void * ppContext; HttpSession *session; z_stream gzipStream; - HttpParser parser; + HttpParser *parser; HttpSqlCmd singleCmd; HttpSqlCmds *multiCmds; JsonBuf * jsonBuf; - void * timer; - HttpEncodeMethod * encodeMethod; + HttpEncodeMethod *encodeMethod; + HttpDecodeMethod *decodeMethod; struct HttpThread *pThread; } HttpContext; @@ -217,9 +167,9 @@ typedef struct HttpThread { HttpContext * pHead; pthread_mutex_t threadMutex; bool stop; - int pollFd; - int numOfContexts; - int threadId; + int32_t pollFd; + int32_t numOfContexts; + int32_t threadId; char label[HTTP_LABEL_SIZE]; bool (*processData)(HttpContext *pContext); } HttpThread; @@ -228,9 +178,9 @@ typedef struct HttpServer { char label[HTTP_LABEL_SIZE]; uint32_t serverIp; uint16_t serverPort; - int fd; - int numOfThreads; - int methodScannerLen; + int32_t fd; + int32_t numOfThreads; + int32_t methodScannerLen; int32_t requestNum; int32_t status; pthread_t thread; diff --git a/src/plugins/http/inc/httpJson.h b/src/plugins/http/inc/httpJson.h index 905460c67b14b4d3305f4071ae5370edb0336ff0..ac0a632137256af96de8503775e5a34fc81b1f1c 100644 --- a/src/plugins/http/inc/httpJson.h +++ b/src/plugins/http/inc/httpJson.h @@ -37,65 +37,65 @@ extern char JsonTrueTkn[]; extern char JsonFalseTkn[]; typedef struct { - int size; - int total; - char* lst; - char buf[JSON_BUFFER_SIZE]; - struct HttpContext* pContext; + int32_t size; + int32_t total; + char* lst; + char buf[JSON_BUFFER_SIZE]; + struct HttpContext* pContext; } JsonBuf; // http response -int httpWriteBuf(struct HttpContext* pContext, const char* buf, int sz); -int httpWriteBufNoTrace(struct HttpContext* pContext, const char* buf, int sz); -int httpWriteBufByFd(struct HttpContext* pContext, const char* buf, int sz); +int32_t httpWriteBuf(struct HttpContext* pContext, const char* buf, int32_t sz); +int32_t httpWriteBufNoTrace(struct HttpContext* pContext, const char* buf, int32_t sz); +int32_t httpWriteBufByFd(struct HttpContext* pContext, const char* buf, int32_t sz); // builder callback typedef void (*httpJsonBuilder)(JsonBuf* buf, void* jsnHandle); // buffer -void httpInitJsonBuf(JsonBuf* buf, struct HttpContext* pContext); -void httpWriteJsonBufHead(JsonBuf* buf); -int httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast); -void httpWriteJsonBufEnd(JsonBuf* buf); +void httpInitJsonBuf(JsonBuf* buf, struct HttpContext* pContext); +void httpWriteJsonBufHead(JsonBuf* buf); +int32_t httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast); +void httpWriteJsonBufEnd(JsonBuf* buf); // value -void httpJsonString(JsonBuf* buf, char* sVal, int len); -void httpJsonOriginString(JsonBuf* buf, char* sVal, int len); -void httpJsonStringForTransMean(JsonBuf* buf, char* SVal, int maxLen); +void httpJsonString(JsonBuf* buf, char* sVal, int32_t len); +void httpJsonOriginString(JsonBuf* buf, char* sVal, int32_t len); +void httpJsonStringForTransMean(JsonBuf* buf, char* SVal, int32_t maxLen); void httpJsonInt64(JsonBuf* buf, int64_t num); void httpJsonTimestamp(JsonBuf* buf, int64_t t, bool us); void httpJsonUtcTimestamp(JsonBuf* buf, int64_t t, bool us); -void httpJsonInt(JsonBuf* buf, int num); +void httpJsonInt(JsonBuf* buf, int32_t num); void httpJsonFloat(JsonBuf* buf, float num); void httpJsonDouble(JsonBuf* buf, double num); void httpJsonNull(JsonBuf* buf); -void httpJsonBool(JsonBuf* buf, int val); +void httpJsonBool(JsonBuf* buf, int32_t val); // pair -void httpJsonPair(JsonBuf* buf, char* name, int nameLen, char* sVal, int valLen); -void httpJsonPairOriginString(JsonBuf* buf, char* name, int nameLen, char* sVal, int valLen); -void httpJsonPairHead(JsonBuf* buf, char* name, int len); -void httpJsonPairIntVal(JsonBuf* buf, char* name, int nNameLen, int num); -void httpJsonPairInt64Val(JsonBuf* buf, char* name, int nNameLen, int64_t num); -void httpJsonPairBoolVal(JsonBuf* buf, char* name, int nNameLen, int num); -void httpJsonPairFloatVal(JsonBuf* buf, char* name, int nNameLen, float num); -void httpJsonPairDoubleVal(JsonBuf* buf, char* name, int nNameLen, double num); -void httpJsonPairNullVal(JsonBuf* buf, char* name, int nNameLen); +void httpJsonPair(JsonBuf* buf, char* name, int32_t nameLen, char* sVal, int32_t valLen); +void httpJsonPairOriginString(JsonBuf* buf, char* name, int32_t nameLen, char* sVal, int32_t valLen); +void httpJsonPairHead(JsonBuf* buf, char* name, int32_t len); +void httpJsonPairIntVal(JsonBuf* buf, char* name, int32_t nNameLen, int32_t num); +void httpJsonPairInt64Val(JsonBuf* buf, char* name, int32_t nNameLen, int64_t num); +void httpJsonPairBoolVal(JsonBuf* buf, char* name, int32_t nNameLen, int32_t num); +void httpJsonPairFloatVal(JsonBuf* buf, char* name, int32_t nNameLen, float num); +void httpJsonPairDoubleVal(JsonBuf* buf, char* name, int32_t nNameLen, double num); +void httpJsonPairNullVal(JsonBuf* buf, char* name, int32_t nNameLen); // object -void httpJsonPairArray(JsonBuf* buf, char* name, int nLen, httpJsonBuilder builder, void* dsHandle); -void httpJsonPairObject(JsonBuf* buf, char* name, int nLen, httpJsonBuilder builder, void* dsHandle); +void httpJsonPairArray(JsonBuf* buf, char* name, int32_t nLen, httpJsonBuilder builder, void* dsHandle); +void httpJsonPairObject(JsonBuf* buf, char* name, int32_t nLen, httpJsonBuilder builder, void* dsHandle); void httpJsonObject(JsonBuf* buf, httpJsonBuilder fnBuilder, void* dsHandle); void httpJsonArray(JsonBuf* buf, httpJsonBuilder fnBuidler, void* jsonHandle); // print -void httpJsonTestBuf(JsonBuf* buf, int safety); +void httpJsonTestBuf(JsonBuf* buf, int32_t safety); void httpJsonToken(JsonBuf* buf, char c); void httpJsonItemToken(JsonBuf* buf); -void httpJsonPrint(JsonBuf* buf, const char* json, int len); +void httpJsonPrint(JsonBuf* buf, const char* json, int32_t len); // quick -void httpJsonPairStatus(JsonBuf* buf, int code); +void httpJsonPairStatus(JsonBuf* buf, int32_t code); // http json printer JsonBuf* httpMallocJsonBuf(struct HttpContext* pContext); diff --git a/src/plugins/http/inc/httpParser.h b/src/plugins/http/inc/httpParser.h index 4facea02861fcb75bce2513799dcf9129f7e1ea2..5694c8f0cdb3ab30ed25a93c18d6fee080332356 100644 --- a/src/plugins/http/inc/httpParser.h +++ b/src/plugins/http/inc/httpParser.h @@ -1,9 +1,23 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + #ifndef HTTP_PARSER_H #define HTTP_PARSER_H - #include "httpGzip.h" -struct HttpContext; +#define HTTP_MAX_URL 5 // http url stack size typedef enum HTTP_PARSER_STATE { HTTP_PARSER_BEGIN, @@ -24,79 +38,82 @@ typedef enum HTTP_PARSER_STATE { HTTP_PARSER_ERROR, } HTTP_PARSER_STATE; -typedef struct HttpParserString { - char * str; - size_t len; -} HttpParserString; - -typedef struct HttpParserStatusObj { - int32_t status_code; - const char *status_desc; -} HttpParserStatusObj; +typedef enum HTTP_AUTH_TYPE { + HTTP_INVALID_AUTH, + HTTP_BASIC_AUTH, + HTTP_TAOSD_AUTH +} HTTP_AUTH_TYPE; -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; +typedef enum HTTP_VERSION { + HTTP_VERSION_10 = 0, + HTTP_VERSION_11 = 1, + HTTP_VERSION_12 = 2, + HTTP_INVALID_VERSION +} HTTP_VERSION; -typedef struct HttpParserConfObj { - size_t flush_block_size; // <=0: immediately -} HttpParserConfObj; +typedef enum HTTP_KEEPALIVE { + HTTP_KEEPALIVE_NO_INPUT = 0, + HTTP_KEEPALIVE_ENABLE = 1, + HTTP_KEEPALIVE_DISABLE = 2 +} HTTP_KEEPALIVE; -typedef struct HttpParseKvObj { - char *key; - char *val; -} HttpParseKvObj; +typedef struct HttpString { + char * str; + int32_t pos; + int32_t size; +} HttpString; -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; - HttpParserString str; - HTTP_PARSER_STATE *stacks; - size_t stacks_count; -} HttpParserObj; +typedef struct HttpStatus { + int32_t code; + char * desc; +} HttpStatus; -void httpParserCleanupString(HttpParserString *str); -int32_t httpParserAppendString(HttpParserString *str, const char *s, int32_t len); -void httpParserClearString(HttpParserString *str); +typedef struct HttpStack{ + int8_t *stacks; + int32_t pos; + int32_t size; +} HttpStack; +struct HttpContext; +typedef struct HttpParser { + struct HttpContext *pContext; + ehttp_gzip_t *gzip; + HttpStack stacks; + HttpString str; + HttpString body; + HttpString path[HTTP_MAX_URL]; + char * method; + char * target; + char * target_raw; + char * version; + char * reasonPhrase; + char * key; + char * val; + char * authContent; + int8_t httpVersion; + int8_t acceptEncodingGzip; + int8_t acceptEncodingChunked; + int8_t contentLengthSpecified; + int8_t contentChunked; + int8_t transferGzip; + int8_t transferChunked; + int8_t keepAlive; + int8_t authType; + int32_t contentLength; + int32_t chunkSize; + int32_t receivedChunkSize; + int32_t receivedSize; + int32_t statusCode; + int8_t inited; + int8_t parsed; + int16_t httpCode; + int32_t parseCode; +} HttpParser; -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); +void httpInitParser(HttpParser *parser); +HttpParser *httpCreateParser(struct HttpContext *pContext); +void httpDestroyParser(HttpParser *parser); +int32_t httpParseBuf(HttpParser *parser, const char *buf, int32_t len); +char * httpGetStatusDesc(int32_t statusCode); #endif diff --git a/src/plugins/http/inc/httpResp.h b/src/plugins/http/inc/httpResp.h index 5eaaa2a0378552d466a7d201981387f018c0614c..9086d0c9d38f671f9cb40a98716e90ef20f63658 100644 --- a/src/plugins/http/inc/httpResp.h +++ b/src/plugins/http/inc/httpResp.h @@ -32,9 +32,9 @@ enum _httpRespTempl { extern const char *httpRespTemplate[]; -void httpSendErrorResp(HttpContext *pContext, int errNo); -void httpSendErrorRespWithDesc(HttpContext *pContext, int errNo, char *desc); -void httpSendTaosdErrorResp(HttpContext *pContext, int errCode); +void httpSendErrorResp(HttpContext *pContext, int32_t errNo); +void httpSendErrorRespWithDesc(HttpContext *pContext, int32_t errNo, char *desc); +void httpSendTaosdErrorResp(HttpContext *pContext, int32_t errCode); void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char* errMsg); void httpSendSuccResp(HttpContext *pContext, char *desc); void httpSendOptionResp(HttpContext *pContext, char *desc); diff --git a/src/plugins/http/inc/httpRestJson.h b/src/plugins/http/inc/httpRestJson.h index 7cff21d190b389361887582c9422bd9e59da35bc..112e845f369c6ae3f0df76d880f84de5aeff5d8d 100644 --- a/src/plugins/http/inc/httpRestJson.h +++ b/src/plugins/http/inc/httpRestJson.h @@ -43,12 +43,12 @@ #define REST_TIMESTAMP_FMT_TIMESTAMP 1 #define REST_TIMESTAMP_FMT_UTC_STRING 2 -void restBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int affect_rows); +void restBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int32_t affect_rows); void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result); -bool restBuildSqlTimestampJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows); -bool restBuildSqlLocalTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows); -bool restBuildSqlUtcTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows); +bool restBuildSqlTimestampJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows); +bool restBuildSqlLocalTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows); +bool restBuildSqlUtcTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows); void restStopSqlJson(HttpContext *pContext, HttpSqlCmd *cmd); #endif \ No newline at end of file diff --git a/src/plugins/http/inc/httpServer.h b/src/plugins/http/inc/httpServer.h index 508baa6112a5e9d81e0864637b66f3aa1c21b79d..58ed3545f35e9d832a330c142d398f2316291aa6 100644 --- a/src/plugins/http/inc/httpServer.h +++ b/src/plugins/http/inc/httpServer.h @@ -21,8 +21,7 @@ bool httpInitConnect(); void httpCleanUpConnect(); -void *httpInitServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle); -void httpCleanUpServer(HttpServer *pServer); -int httpReadDataImp(HttpContext *pContext); +void *httpInitServer(char *ip, uint16_t port, char *label, int32_t numOfThreads, void *fp, void *shandle); +void httpCleanUpServer(HttpServer *pServer); #endif diff --git a/src/plugins/http/inc/httpSql.h b/src/plugins/http/inc/httpSql.h index 09f5b142fb63081cc6d4432e1089a446432d056c..660a65e44dbe5c34433c8b851851f058ab983719 100644 --- a/src/plugins/http/inc/httpSql.h +++ b/src/plugins/http/inc/httpSql.h @@ -19,20 +19,20 @@ int32_t httpAddToSqlCmdBuffer(HttpContext *pContext, const char *const format, ...); int32_t httpAddToSqlCmdBufferNoTerminal(HttpContext *pContext, const char *const format, ...); -int32_t httpAddToSqlCmdBufferWithSize(HttpContext *pContext, int mallocSize); +int32_t httpAddToSqlCmdBufferWithSize(HttpContext *pContext, int32_t mallocSize); int32_t httpAddToSqlCmdBufferTerminal(HttpContext *pContext); -bool httpMallocMultiCmds(HttpContext *pContext, int cmdSize, int bufferSize); -bool httpReMallocMultiCmdsSize(HttpContext *pContext, int cmdSize); -bool httpReMallocMultiCmdsBuffer(HttpContext *pContext, int bufferSize); +bool httpMallocMultiCmds(HttpContext *pContext, int32_t cmdSize, int32_t bufferSize); +bool httpReMallocMultiCmdsSize(HttpContext *pContext, int32_t cmdSize); +bool httpReMallocMultiCmdsBuffer(HttpContext *pContext, int32_t bufferSize); void httpFreeMultiCmds(HttpContext *pContext); HttpSqlCmd *httpNewSqlCmd(HttpContext *pContext); HttpSqlCmd *httpCurrSqlCmd(HttpContext *pContext); -int httpCurSqlCmdPos(HttpContext *pContext); +int32_t httpCurSqlCmdPos(HttpContext *pContext); void httpTrimTableName(char *name); -int httpShrinkTableName(HttpContext *pContext, int pos, char *name); -char *httpGetCmdsString(HttpContext *pContext, int pos); +int32_t httpShrinkTableName(HttpContext *pContext, int32_t pos, char *name); +char *httpGetCmdsString(HttpContext *pContext, int32_t pos); #endif diff --git a/src/plugins/http/inc/httpTgJson.h b/src/plugins/http/inc/httpTgJson.h index bf3aa093ae9132bba67ea2dff7b233c7457ccccd..6b7d0681b601fea07aa6d15c8a8a4dbd675b9b34 100644 --- a/src/plugins/http/inc/httpTgJson.h +++ b/src/plugins/http/inc/httpTgJson.h @@ -24,8 +24,8 @@ void tgInitQueryJson(HttpContext *pContext); void tgCleanQueryJson(HttpContext *pContext); void tgStartQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result); void tgStopQueryJson(HttpContext *pContext, HttpSqlCmd *cmd); -void tgBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int affect_rows); -bool tgCheckFinished(struct HttpContext *pContext, HttpSqlCmd *cmd, int code); -void tgSetNextCmd(struct HttpContext *pContext, HttpSqlCmd *cmd, int code); +void tgBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int32_t affect_rows); +bool tgCheckFinished(struct HttpContext *pContext, HttpSqlCmd *cmd, int32_t code); +void tgSetNextCmd(struct HttpContext *pContext, HttpSqlCmd *cmd, int32_t code); #endif \ No newline at end of file diff --git a/src/plugins/http/inc/httpUtil.h b/src/plugins/http/inc/httpUtil.h index c82f702ebc081da3e1c7821151c38923c605095c..61cd50a77a29ad8b9a2058f4ad569493b18618ac 100644 --- a/src/plugins/http/inc/httpUtil.h +++ b/src/plugins/http/inc/httpUtil.h @@ -17,21 +17,19 @@ #define TDENGINE_HTTP_UTIL_H bool httpCheckUsedbSql(char *sql); -void httpTimeToString(time_t t, char *buf, int buflen); +void httpTimeToString(time_t t, char *buf, int32_t buflen); -bool httpUrlMatch(HttpContext *pContext, int pos, char *cmp); -bool httpParseRequest(HttpContext *pContext); -int httpCheckReadCompleted(HttpContext *pContext); -void httpReadDirtyData(HttpContext *pContext); +bool httpUrlMatch(HttpContext *pContext, int32_t pos, char *cmp); +bool httpParseRequest(HttpContext *pContext); +int32_t httpCheckReadCompleted(HttpContext *pContext); +void httpReadDirtyData(HttpContext *pContext); -int httpGzipDeCompress(char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData); -int httpGzipCompressInit(HttpContext *pContext); -int httpGzipCompress(HttpContext *pContext, char *inSrcData, int32_t inSrcDataLen, +int32_t httpGzipDeCompress(char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData); +int32_t httpGzipCompressInit(HttpContext *pContext); +int32_t httpGzipCompress(HttpContext *pContext, char *inSrcData, int32_t inSrcDataLen, char *outDestData, int32_t *outDestDataLen, bool isTheLast); // http request parser void httpAddMethod(HttpServer *pServer, HttpDecodeMethod *pMethod); - - #endif diff --git a/src/plugins/http/src/httpAuth.c b/src/plugins/http/src/httpAuth.c index dd4d14c709d031dab328098290ba5b6e296d9f58..40bb691b5da27bb593dfb3740e9631dd02edcd47 100644 --- a/src/plugins/http/src/httpAuth.c +++ b/src/plugins/http/src/httpAuth.c @@ -23,9 +23,9 @@ #define KEY_DES_4 4971256377704625728L -bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len) { +bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int32_t len) { token[len] = '\0'; - int outlen = 0; + int32_t outlen = 0; char *base64 = (char *)base64_decode(token, len, &outlen); if (base64 == NULL || outlen == 0) { httpError("context:%p, fd:%d, basic token:%s parsed error", pContext, pContext->fd, token); @@ -40,7 +40,7 @@ bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len) { return false; } - int user_len = (int)(user - base64); + int32_t user_len = (int32_t)(user - base64); if (user_len < 1 || user_len >= TSDB_USER_LEN) { httpError("context:%p, fd:%d, basic token:%s parse user error", pContext, pContext->fd, token); free(base64); @@ -50,7 +50,7 @@ bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len) { pContext->user[user_len] = 0; char *password = user + 1; - int pass_len = (int)((base64 + outlen) - password); + int32_t pass_len = (int32_t)((base64 + outlen) - password); if (pass_len < 1 || pass_len >= TSDB_PASSWORD_LEN) { httpError("context:%p, fd:%d, basic token:%s parse password error", pContext, pContext->fd, token); free(base64); @@ -64,9 +64,9 @@ bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len) { return true; } -bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int len) { +bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int32_t len) { token[len] = '\0'; - int outlen = 0; + int32_t outlen = 0; unsigned char *base64 = base64_decode(token, len, &outlen); if (base64 == NULL || outlen == 0) { httpError("context:%p, fd:%d, taosd token:%s parsed error", pContext, pContext->fd, token); @@ -96,7 +96,7 @@ bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int len) { } } -bool httpGenTaosdAuthToken(HttpContext *pContext, char *token, int maxLen) { +bool httpGenTaosdAuthToken(HttpContext *pContext, char *token, int32_t maxLen) { char buffer[sizeof(pContext->user) + sizeof(pContext->pass)] = {0}; size_t size = sizeof(pContext->user); tstrncpy(buffer, pContext->user, size); @@ -111,7 +111,7 @@ bool httpGenTaosdAuthToken(HttpContext *pContext, char *token, int maxLen) { free(encrypt); free(base64); - httpDebug("context:%p, fd:%d, gen taosd token:%s", pContext, pContext->fd, token); + httpDebug("context:%p, fd:%d, generate taosd token:%s", pContext, pContext->fd, token); return true; } diff --git a/src/plugins/http/src/httpContext.c b/src/plugins/http/src/httpContext.c index d310f27ee621ea6866bb19f23d22f068eb33f3ca..2c65b9d16a97f9616a574ba0ea318d1e301a15de 100644 --- a/src/plugins/http/src/httpContext.c +++ b/src/plugins/http/src/httpContext.c @@ -27,19 +27,7 @@ #include "httpSql.h" #include "httpSession.h" #include "httpContext.h" - -extern bool httpGetHttpMethod(HttpContext* pContext); -extern bool httpParseURL(HttpContext* pContext); -extern bool httpParseHttpVersion(HttpContext* pContext); -extern bool httpGetDecodeMethod(HttpContext* pContext); -extern bool httpParseHead(HttpContext* pContext); - -static void httpParseOnRequestLine(void *arg, const char *method, const char *target, const char *version, const char *target_raw); -static void httpParseOnStatusLine(void *arg, const char *version, int status_code, const char *reason_phrase); -static void httpParseOnHeaderField(void *arg, const char *key, const char *val); -static void httpParseOnBody(void *arg, const char *chunk, size_t len); -static void httpParseOnEnd(void *arg); -static void httpParseOnError(void *arg, int status_code); +#include "httpParser.h" static void httpDestroyContext(void *data); @@ -70,9 +58,9 @@ static void httpDestroyContext(void *data) { httpFreeJsonBuf(pContext); httpFreeMultiCmds(pContext); - if (pContext->parser.parser) { - httpParserDestroy(pContext->parser.parser); - pContext->parser.parser = NULL; + if (pContext->parser) { + httpDestroyParser(pContext->parser); + pContext->parser = NULL; } taosTFree(pContext); @@ -125,9 +113,9 @@ HttpContext *httpCreateContext(int32_t fd) { if (pContext == NULL) return NULL; pContext->fd = fd; - pContext->httpVersion = HTTP_VERSION_10; pContext->lastAccessTime = taosGetTimestampSec(); pContext->state = HTTP_CONTEXT_STATE_READY; + pContext->parser = httpCreateParser(pContext); uint64_t handleVal = (uint64_t)pContext; HttpContext **ppContext = taosCachePut(tsHttpServer.contextCache, &handleVal, sizeof(int64_t), &pContext, sizeof(int64_t), 3000); @@ -164,6 +152,7 @@ void httpReleaseContext(HttpContext *pContext) { return; } + pContext->parser->inited = 0; HttpContext **ppContext = pContext->ppContext; httpDebug("context:%p, is released, data:%p refCount:%d", pContext, ppContext, refCount); @@ -178,45 +167,24 @@ void httpReleaseContext(HttpContext *pContext) { bool httpInitContext(HttpContext *pContext) { pContext->accessTimes++; pContext->lastAccessTime = taosGetTimestampSec(); - pContext->httpVersion = HTTP_VERSION_10; - pContext->httpKeepAlive = HTTP_KEEPALIVE_NO_INPUT; - pContext->httpChunked = HTTP_UNCUNKED; - pContext->acceptEncoding = HTTP_COMPRESS_IDENTITY; - pContext->contentEncoding = HTTP_COMPRESS_IDENTITY; + pContext->reqType = HTTP_REQTYPE_OTHERS; pContext->encodeMethod = NULL; - pContext->timer = NULL; memset(&pContext->singleCmd, 0, sizeof(HttpSqlCmd)); - HttpParser *pParser = &pContext->parser; - memset(pParser, 0, sizeof(HttpParser)); - pParser->pCur = pParser->pLast = pParser->buffer; - - HttpParserCallbackObj callbacks = { - httpParseOnRequestLine, - httpParseOnStatusLine, - httpParseOnHeaderField, - httpParseOnBody, - httpParseOnEnd, - httpParseOnError - }; - HttpParserConfObj conf = { - .flush_block_size = 0 - }; - pParser->parser = httpParserCreate(callbacks, conf, pContext); - pParser->inited = 1; httpDebug("context:%p, fd:%d, parsed:%d", pContext, pContext->fd, pContext->parsed); return true; } void httpCloseContextByApp(HttpContext *pContext) { + HttpParser *parser = pContext->parser; pContext->parsed = false; bool keepAlive = true; - if (pContext->httpVersion == HTTP_VERSION_10 && pContext->httpKeepAlive != HTTP_KEEPALIVE_ENABLE) { + if (parser->httpVersion == HTTP_VERSION_10 && parser->keepAlive != HTTP_KEEPALIVE_ENABLE) { keepAlive = false; - } else if (pContext->httpVersion != HTTP_VERSION_10 && pContext->httpKeepAlive == HTTP_KEEPALIVE_DISABLE) { + } else if (parser->httpVersion != HTTP_VERSION_10 && parser->keepAlive == HTTP_KEEPALIVE_DISABLE) { keepAlive = false; } else { } @@ -262,134 +230,3 @@ void httpCloseContextByServer(HttpContext *pContext) { pContext->parsed = false; httpRemoveContextFromEpoll(pContext); } - -static void httpParseOnRequestLine(void *arg, const char *method, const char *target, const char *version, const char *target_raw) { - HttpContext *pContext = (HttpContext*)arg; - HttpParser *pParser = &pContext->parser; - - int avail = sizeof(pParser->buffer) - (pParser->pLast - pParser->buffer); - int n = snprintf(pParser->pLast, avail, "%s %s %s\r\n", method, target_raw, version); - char *last = pParser->pLast; - - do { - if (n >= avail) { - httpDebug("context:%p, fd:%d, request line(%s,%s,%s,%s), exceeding buffer size", pContext, pContext->fd, method, - target, version, target_raw); - break; - } - pParser->bufsize += n; - - if (!httpGetHttpMethod(pContext)) { - httpDebug("context:%p, fd:%d, request line(%s,%s,%s,%s), parse http method failed", pContext, pContext->fd, - method, target, version, target_raw); - break; - } - if (!httpParseURL(pContext)) { - httpDebug("context:%p, fd:%d, request line(%s,%s,%s,%s), parse http url failed", pContext, pContext->fd, method, - target, version, target_raw); - break; - } - if (!httpParseHttpVersion(pContext)) { - httpDebug("context:%p, fd:%d, request line(%s,%s,%s,%s), parse http version failed", pContext, pContext->fd, - method, target, version, target_raw); - break; - } - if (!httpGetDecodeMethod(pContext)) { - httpDebug("context:%p, fd:%d, request line(%s,%s,%s,%s), get decode method failed", pContext, pContext->fd, - method, target, version, target_raw); - break; - } - - last += n; - pParser->pLast = last; - return; - } while (0); - - pParser->failed |= EHTTP_CONTEXT_PROCESS_FAILED; -} - -static void httpParseOnStatusLine(void *arg, const char *version, int status_code, const char *reason_phrase) { - HttpContext *pContext = (HttpContext*)arg; - HttpParser *pParser = &pContext->parser; - - httpDebug("context:%p, fd:%d, failed to parse status line ", pContext, pContext->fd); - pParser->failed |= EHTTP_CONTEXT_PROCESS_FAILED; -} - -static void httpParseOnHeaderField(void *arg, const char *key, const char *val) { - HttpContext *pContext = (HttpContext*)arg; - HttpParser *pParser = &pContext->parser; - - if (pParser->failed) return; - - httpDebug("context:%p, fd:%d, key:%s val:%s", pContext, pContext->fd, key, val); - int avail = sizeof(pParser->buffer) - (pParser->pLast - pParser->buffer); - int n = snprintf(pParser->pLast, avail, "%s: %s\r\n", key, val); - char *last = pParser->pLast; - - do { - if (n >= avail) { - httpDebug("context:%p, fd:%d, header field(%s,%s), exceeding buffer size", pContext, pContext->fd, key, val); - break; - } - pParser->bufsize += n; - pParser->pCur = pParser->pLast + n; - - if (!httpParseHead(pContext)) { - httpDebug("context:%p, fd:%d, header field(%s,%s), parse failed", pContext, pContext->fd, key, val); - break; - } - - last += n; - pParser->pLast = last; - return; - } while (0); - - pParser->failed |= EHTTP_CONTEXT_PROCESS_FAILED; -} - -static void httpParseOnBody(void *arg, const char *chunk, size_t len) { - HttpContext *pContext = (HttpContext*)arg; - HttpParser *pParser = &pContext->parser; - - if (pParser->failed) return; - - if (pParser->data.pos == 0) { - pParser->data.pos = pParser->pLast; - pParser->data.len = 0; - } - - int avail = sizeof(pParser->buffer) - (pParser->pLast - pParser->buffer); - if (len + 1 >= avail) { - httpError("context:%p, fd:%d, failed parse body, exceeding buffer size", pContext, pContext->fd); - pParser->failed |= EHTTP_CONTEXT_PROCESS_FAILED; - return; - } - - memcpy(pParser->pLast, chunk, len); - pParser->pLast += len; - pParser->data.len += len; -} - -static void httpParseOnEnd(void *arg) { - HttpContext *pContext = (HttpContext*)arg; - HttpParser *pParser = &pContext->parser; - - if (pParser->failed) return; - - if (pParser->data.pos == 0) pParser->data.pos = pParser->pLast; - - if (!pContext->parsed) { - pContext->parsed = true; - } - - httpDebug("context:%p, fd:%d, parse success", pContext, pContext->fd); -} - -static void httpParseOnError(void *arg, int status_code) { - HttpContext *pContext = (HttpContext *)arg; - HttpParser * pParser = &pContext->parser; - - httpError("context:%p, fd:%d, failed to parse, status_code:%d", pContext, pContext->fd, status_code); - pParser->failed |= EHTTP_CONTEXT_PARSER_FAILED; -} diff --git a/src/plugins/http/src/httpGcHandle.c b/src/plugins/http/src/httpGcHandle.c index 09f17cae6604e43368b0749fb08d1fe1e62612f6..e010c77ffda20b8e9456065782d72f20e8eab5cb 100644 --- a/src/plugins/http/src/httpGcHandle.c +++ b/src/plugins/http/src/httpGcHandle.c @@ -47,22 +47,22 @@ static HttpEncodeMethod gcQueryMethod = { void gcInitHandle(HttpServer* pServer) { httpAddMethod(pServer, &gcDecodeMethod); } bool gcGetUserFromUrl(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - if (pParser->path[GC_USER_URL_POS].len >= TSDB_USER_LEN || pParser->path[GC_USER_URL_POS].len <= 0) { + HttpParser* pParser = pContext->parser; + if (pParser->path[GC_USER_URL_POS].pos >= TSDB_USER_LEN || pParser->path[GC_USER_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->user, pParser->path[GC_USER_URL_POS].pos, TSDB_USER_LEN); + tstrncpy(pContext->user, pParser->path[GC_USER_URL_POS].str, TSDB_USER_LEN); return true; } bool gcGetPassFromUrl(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - if (pParser->path[GC_PASS_URL_POS].len >= TSDB_PASSWORD_LEN || pParser->path[GC_PASS_URL_POS].len <= 0) { + HttpParser* pParser = pContext->parser; + if (pParser->path[GC_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[GC_PASS_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->pass, pParser->path[GC_PASS_URL_POS].pos, TSDB_PASSWORD_LEN); + tstrncpy(pContext->pass, pParser->path[GC_PASS_URL_POS].str, TSDB_PASSWORD_LEN); return true; } @@ -144,8 +144,7 @@ bool gcProcessLoginRequest(HttpContext* pContext) { bool gcProcessQueryRequest(HttpContext* pContext) { httpDebug("context:%p, fd:%d, process grafana query msg", pContext, pContext->fd); - HttpParser* pParser = &pContext->parser; - char* filter = pParser->data.pos; + char* filter = pContext->parser->body.str; if (filter == NULL) { httpSendErrorResp(pContext, HTTP_NO_MSG_INPUT); return false; @@ -157,7 +156,7 @@ bool gcProcessQueryRequest(HttpContext* pContext) { return false; } - int size = cJSON_GetArraySize(root); + int32_t size = cJSON_GetArraySize(root); if (size <= 0) { httpSendErrorResp(pContext, HTTP_GC_QUERY_NULL); cJSON_Delete(root); @@ -176,7 +175,7 @@ bool gcProcessQueryRequest(HttpContext* pContext) { return false; } - for (int i = 0; i < size; ++i) { + for (int32_t i = 0; i < size; ++i) { cJSON* query = cJSON_GetArrayItem(root, i); if (query == NULL) continue; @@ -186,14 +185,14 @@ bool gcProcessQueryRequest(HttpContext* pContext) { continue; } - int refIdBuffer = httpAddToSqlCmdBuffer(pContext, refId->valuestring); + int32_t refIdBuffer = httpAddToSqlCmdBuffer(pContext, refId->valuestring); if (refIdBuffer == -1) { httpWarn("context:%p, fd:%d, user:%s, refId buffer is full", pContext, pContext->fd, pContext->user); break; } cJSON* alias = cJSON_GetObjectItem(query, "alias"); - int aliasBuffer = -1; + int32_t aliasBuffer = -1; if (!(alias == NULL || alias->valuestring == NULL || strlen(alias->valuestring) == 0)) { aliasBuffer = httpAddToSqlCmdBuffer(pContext, alias->valuestring); if (aliasBuffer == -1) { @@ -211,7 +210,7 @@ bool gcProcessQueryRequest(HttpContext* pContext) { continue; } - int sqlBuffer = httpAddToSqlCmdBuffer(pContext, sql->valuestring); + int32_t sqlBuffer = httpAddToSqlCmdBuffer(pContext, sql->valuestring); if (sqlBuffer == -1) { httpWarn("context:%p, fd:%d, user:%s, sql buffer is full", pContext, pContext->fd, pContext->user); break; diff --git a/src/plugins/http/src/httpGcJson.c b/src/plugins/http/src/httpGcJson.c index 85cae2420178bb52a90dc89749ebb21051141118..a291641dc376c6d581a137403a1ac623ce9dd5ec 100644 --- a/src/plugins/http/src/httpGcJson.c +++ b/src/plugins/http/src/httpGcJson.c @@ -54,8 +54,8 @@ void gcWriteTargetStartJson(JsonBuf *jsonBuf, char *refId, char *target) { httpJsonToken(jsonBuf, JsonObjStt); // target section - httpJsonPair(jsonBuf, "refId", 5, refId, (int)strlen(refId)); - httpJsonPair(jsonBuf, "target", 6, target, (int)strlen(target)); + httpJsonPair(jsonBuf, "refId", 5, refId, (int32_t)strlen(refId)); + httpJsonPair(jsonBuf, "target", 6, target, (int32_t)strlen(target)); // data begin httpJsonPairHead(jsonBuf, "datapoints", 10); @@ -82,25 +82,25 @@ void gcStopQueryJson(HttpContext *pContext, HttpSqlCmd *cmd) { } } -bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows) { +bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows) { JsonBuf *jsonBuf = httpMallocJsonBuf(pContext); if (jsonBuf == NULL) return false; - int num_fields = taos_num_fields(result); + int32_t num_fields = taos_num_fields(result); TAOS_FIELD *fields = taos_fetch_fields(result); if (num_fields == 0) { return false; } - int precision = taos_result_precision(result); + int32_t precision = taos_result_precision(result); // such as select count(*) from sys.cpu // such as select count(*) from sys.cpu group by ipaddr // such as select count(*) from sys.cpu interval(1d) // such as select count(*) from sys.cpu interval(1d) group by ipaddr // such as select count(*) count(*) from sys.cpu group by ipaddr interval(1d) - int dataFields = -1; - int groupFields = -1; + int32_t dataFields = -1; + int32_t groupFields = -1; bool hasTimestamp = fields[0].type == TSDB_DATA_TYPE_TIMESTAMP; if (hasTimestamp) { dataFields = 1; @@ -119,7 +119,7 @@ bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, } cmd->numOfRows += numOfRows; - for (int k = 0; k < numOfRows; ++k) { + for (int32_t k = 0; k < numOfRows; ++k) { TAOS_ROW row = taos_fetch_row(result); if (row == NULL) { cmd->numOfRows--; @@ -130,9 +130,9 @@ bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, // for group by if (groupFields != -1) { char target[HTTP_GC_TARGET_SIZE] = {0}; - int len; + int32_t len; len = snprintf(target,HTTP_GC_TARGET_SIZE,"%s{",aliasBuffer); - for (int i = dataFields + 1; i= 0; i--) { + for (int32_t i = dataFields; i >= 0; i--) { httpJsonItemToken(jsonBuf); if (row[i] == NULL) { httpJsonOriginString(jsonBuf, "null", 4); @@ -253,13 +253,13 @@ void gcSendHeartBeatResp(HttpContext *pContext, HttpSqlCmd *cmd) { httpInitJsonBuf(jsonBuf, pContext); httpJsonToken(jsonBuf, JsonObjStt); - httpJsonPair(jsonBuf, "message", (int)strlen("message"), desc, (int)strlen(desc)); + httpJsonPair(jsonBuf, "message", (int32_t)strlen("message"), desc, (int32_t)strlen(desc)); httpJsonToken(jsonBuf, JsonObjEnd); char head[1024]; - int hLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_GRAFANA], httpVersionStr[pContext->httpVersion], - httpKeepAliveStr[pContext->httpKeepAlive], (jsonBuf->lst - jsonBuf->buf)); + int32_t hLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_GRAFANA], httpVersionStr[pContext->parser->httpVersion], + httpKeepAliveStr[pContext->parser->keepAlive], (jsonBuf->lst - jsonBuf->buf)); httpWriteBuf(pContext, head, hLen); - httpWriteBuf(pContext, jsonBuf->buf, (int)(jsonBuf->lst - jsonBuf->buf)); + httpWriteBuf(pContext, jsonBuf->buf, (int32_t)(jsonBuf->lst - jsonBuf->buf)); } diff --git a/src/plugins/http/src/httpGzip.c b/src/plugins/http/src/httpGzip.c index 5712aff7eca6961e73a9f721e596d6ad379886fe..54f900c7551d225c4c1c0b72bfa661969af14afa 100644 --- a/src/plugins/http/src/httpGzip.c +++ b/src/plugins/http/src/httpGzip.c @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#define _DEFAULT_SOURCE #include "os.h" #include "zlib.h" #include "httpGzip.h" @@ -16,10 +32,10 @@ struct ehttp_gzip_s { gz_header *header; char *chunk; - int state; + int32_t state; }; -static void dummy_on_data(ehttp_gzip_t *gzip, void *arg, const char *buf, size_t len) { +static void dummy_on_data(ehttp_gzip_t *gzip, void *arg, const char *buf, int32_t len) { } static void ehttp_gzip_cleanup(ehttp_gzip_t *gzip) { @@ -72,7 +88,7 @@ ehttp_gzip_t* ehttp_gzip_create_decompressor(ehttp_gzip_conf_t conf, ehttp_gzip_ // 868 below), inflate() will not automatically decode concatenated gzip streams. // 869 inflate() will return Z_STREAM_END at the end of the gzip stream. The state // 870 would need to be reset to continue decoding a subsequent gzip stream. - int ret = inflateInit2(gzip->gzip, 32); // 32/16? 32/16 + MAX_WBITS + int32_t ret = inflateInit2(gzip->gzip, 32); // 32/16? 32/16 + MAX_WBITS if (ret != Z_OK) break; if (gzip->header) { ret = inflateGetHeader(gzip->gzip, gzip->header); @@ -97,7 +113,7 @@ void ehttp_gzip_destroy(ehttp_gzip_t *gzip) { free(gzip); } -int ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, size_t len) { +int32_t ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, int32_t len) { if (gzip->state != EHTTP_GZIP_READY) return -1; if (len <= 0) return 0; @@ -105,7 +121,7 @@ int ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, size_t len) { gzip->gzip->avail_in = len; while (gzip->gzip->avail_in) { - int ret; + int32_t ret; if (gzip->header) { ret = inflate(gzip->gzip, Z_BLOCK); } else { @@ -117,7 +133,7 @@ int ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, size_t len) { if (ret!=Z_STREAM_END) continue; } - size_t len = gzip->gzip->next_out - (z_const Bytef*)gzip->chunk; + int32_t len = gzip->gzip->next_out - (z_const Bytef*)gzip->chunk; gzip->gzip->next_out[0] = '\0'; gzip->callbacks.on_data(gzip, gzip->arg, gzip->chunk, len); @@ -128,18 +144,18 @@ int ehttp_gzip_write(ehttp_gzip_t *gzip, const char *buf, size_t len) { return 0; } -int ehttp_gzip_finish(ehttp_gzip_t *gzip) { +int32_t ehttp_gzip_finish(ehttp_gzip_t *gzip) { if (gzip->state != EHTTP_GZIP_READY) return -1; gzip->gzip->next_in = NULL; gzip->gzip->avail_in = 0; - int ret; + int32_t ret; ret = inflate(gzip->gzip, Z_FINISH); if (ret != Z_STREAM_END) return -1; - size_t len = gzip->gzip->next_out - (z_const Bytef*)gzip->chunk; + int32_t len = gzip->gzip->next_out - (z_const Bytef*)gzip->chunk; gzip->gzip->next_out[0] = '\0'; gzip->callbacks.on_data(gzip, gzip->arg, gzip->chunk, len); diff --git a/src/plugins/http/src/httpHandle.c b/src/plugins/http/src/httpHandle.c index 59b3268392ad9f8a0bd77ce3cceeb8b148bc37c9..9fb46c573448675951f81e256b1db190898a0959 100644 --- a/src/plugins/http/src/httpHandle.c +++ b/src/plugins/http/src/httpHandle.c @@ -15,240 +15,17 @@ #define _DEFAULT_SOURCE #include "os.h" -#include "taos.h" -#include "tglobal.h" -#include "tsocket.h" -#include "ttimer.h" #include "httpInt.h" #include "httpResp.h" -#include "httpAuth.h" -#include "httpServer.h" #include "httpContext.h" #include "httpHandle.h" -void httpToLowerUrl(char* url) { - /*ignore case */ - while (*url) { - if (*url >= 'A' && *url <= 'Z') { - *url = *url | 0x20; - } - url++; - } -} - -bool httpUrlMatch(HttpContext* pContext, int pos, char* cmp) { - HttpParser* pParser = &pContext->parser; - - if (pos < 0 || pos >= HTTP_MAX_URL) { - return false; - } - - if (pParser->path[pos].len <= 0) { - return false; - } - - if (strcmp(pParser->path[pos].pos, cmp) != 0) { - return false; - } - - return true; -} - -// /account/db/meter HTTP/1.1\r\nHost -bool httpParseURL(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - char* pSeek; - char* pEnd = strchr(pParser->pLast, ' '); - if (pEnd == NULL) { - httpSendErrorResp(pContext, HTTP_UNSUPPORT_URL); - return false; - } - - if (*pParser->pLast != '/') { - httpSendErrorResp(pContext, HTTP_UNSUPPORT_URL); - return false; - } - pParser->pLast++; - - for (int i = 0; i < HTTP_MAX_URL; i++) { - pSeek = strchr(pParser->pLast, '/'); - if (pSeek == NULL) { - break; - } - pParser->path[i].pos = pParser->pLast; - if (pSeek <= pEnd) { - pParser->path[i].len = (int16_t)(pSeek - pParser->pLast); - pParser->path[i].pos[pParser->path[i].len] = 0; - httpToLowerUrl(pParser->path[i].pos); - pParser->pLast = pSeek + 1; - } else { - pParser->path[i].len = (int16_t)(pEnd - pParser->pLast); - pParser->path[i].pos[pParser->path[i].len] = 0; - httpToLowerUrl(pParser->path[i].pos); - pParser->pLast = pEnd + 1; - break; - } - } - pParser->pLast = pEnd + 1; - - if (pParser->path[0].len == 0) { - httpSendErrorResp(pContext, HTTP_UNSUPPORT_URL); - return false; - } - - return true; -} - -bool httpParseHttpVersion(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - char* pEnd = strchr(pParser->pLast, '1'); - if (pEnd == NULL) { - httpError("context:%p, fd:%d, can't find http version at position:%s", pContext, pContext->fd, pParser->pLast); - httpSendErrorResp(pContext, HTTP_PARSE_HTTP_VERSION_ERROR); - return false; - } - - if (*(pEnd + 1) != '.') { - httpError("context:%p, fd:%d, can't find http version at position:%s", pContext, pContext->fd, pParser->pLast); - httpSendErrorResp(pContext, HTTP_PARSE_HTTP_VERSION_ERROR); - return false; - } - - if (*(pEnd + 2) == '0') - pContext->httpVersion = HTTP_VERSION_10; - else if (*(pEnd + 2) == '1') - pContext->httpVersion = HTTP_VERSION_11; - else if (*(pEnd + 2) == '2') - pContext->httpVersion = HTTP_VERSION_11; - else - pContext->httpVersion = HTTP_VERSION_10; - - httpDebug("context:%p, fd:%d, httpVersion:1.%d", pContext, pContext->fd, pContext->httpVersion); - return true; -} - -bool httpGetNextLine(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - while (pParser->buffer + pParser->bufsize - pParser->pCur++ > 0) { - if (*(pParser->pCur) == '\n' && *(pParser->pCur - 1) == '\r') { - // cut the string - *pParser->pCur = 0; - return true; - } - } - - httpSendErrorResp(pContext, HTTP_PARSE_HEAD_ERROR); - - return false; -} - -bool httpGetHttpMethod(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - char* pSeek = strchr(pParser->pLast, ' '); - - if (pSeek == NULL) { - httpError("context:%p, fd:%d, failed to parse httpMethod", pContext, pContext->fd); - httpSendErrorResp(pContext, HTTP_PARSE_HTTP_METHOD_ERROR); - return false; - } - - pParser->method.pos = pParser->pLast; - pParser->method.len = (int16_t)(pSeek - pParser->pLast); - pParser->method.pos[pParser->method.len] = 0; - pParser->pLast = pSeek + 1; - - httpTrace("context:%p, fd:%d, httpMethod:%s", pContext, pContext->fd, pParser->method.pos); - return true; -} - -bool httpGetDecodeMethod(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - - HttpServer* pServer = &tsHttpServer; - int methodLen = pServer->methodScannerLen; - for (int i = 0; i < methodLen; i++) { - HttpDecodeMethod* method = pServer->methodScanner[i]; - if (strcmp(method->module, pParser->path[0].pos) != 0) { - continue; - } - pParser->pMethod = method; - return true; - } - - httpError("context:%p, fd:%d, error:the url is not support, method:%s, path:%s", - pContext, pContext->fd, pParser->method.pos, pParser->path[0].pos); - httpSendErrorResp(pContext, HTTP_UNSUPPORT_URL); - - return false; -} - -bool httpParseHead(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - if (strncasecmp(pParser->pLast, "Content-Length: ", 16) == 0) { - pParser->data.len = (int32_t)atoi(pParser->pLast + 16); - httpTrace("context:%p, fd:%d, Content-Length:%d", pContext, pContext->fd, - pParser->data.len); - } else if (strncasecmp(pParser->pLast, "Accept-Encoding: ", 17) == 0) { - if (tsHttpEnableCompress && strstr(pParser->pLast + 17, "gzip") != NULL) { - pContext->acceptEncoding = HTTP_COMPRESS_GZIP; - httpTrace("context:%p, fd:%d, Accept-Encoding:gzip", pContext, pContext->fd); - } else { - pContext->acceptEncoding = HTTP_COMPRESS_IDENTITY; - httpTrace("context:%p, fd:%d, Accept-Encoding:identity", pContext, pContext->fd); - } - } else if (strncasecmp(pParser->pLast, "Content-Encoding: ", 18) == 0) { - if (strstr(pParser->pLast + 18, "gzip") != NULL) { - pContext->contentEncoding = HTTP_COMPRESS_GZIP; - httpTrace("context:%p, fd:%d, Content-Encoding:gzip", pContext, pContext->fd); - } else { - pContext->contentEncoding = HTTP_COMPRESS_IDENTITY; - httpTrace("context:%p, fd:%d, Content-Encoding:identity", pContext, pContext->fd); - } - } else if (strncasecmp(pParser->pLast, "Connection: ", 12) == 0) { - if (strncasecmp(pParser->pLast + 12, "Keep-Alive", 10) == 0) { - pContext->httpKeepAlive = HTTP_KEEPALIVE_ENABLE; - } else { - pContext->httpKeepAlive = HTTP_KEEPALIVE_DISABLE; - } - httpTrace("context:%p, fd:%d, keepAlive:%d", pContext, pContext->fd, pContext->httpKeepAlive); - } else if (strncasecmp(pParser->pLast, "Transfer-Encoding: ", 19) == 0) { - if (strncasecmp(pParser->pLast + 19, "chunked", 7) == 0) { - pContext->httpChunked = HTTP_CHUNKED; - } - } else if (strncasecmp(pParser->pLast, "Authorization: ", 15) == 0) { - if (strncasecmp(pParser->pLast + 15, "Basic ", 6) == 0) { - pParser->token.pos = pParser->pLast + 21; - pParser->token.len = (int16_t)(pParser->pCur - pParser->token.pos - 1); - bool parsed = httpParseBasicAuthToken(pContext, pParser->token.pos, pParser->token.len); - if (!parsed) { - httpSendErrorResp(pContext, HTTP_INVALID_BASIC_AUTH_TOKEN); - return false; - } - } else if (strncasecmp(pParser->pLast + 15, "Taosd ", 6) == 0) { - pParser->token.pos = pParser->pLast + 21; - pParser->token.len = (int16_t)(pParser->pCur - pParser->token.pos - 1); - bool parsed = httpParseTaosdAuthToken(pContext, pParser->token.pos, pParser->token.len); - if (!parsed) { - httpSendErrorResp(pContext, HTTP_INVALID_TAOSD_AUTH_TOKEN); - return false; - } - } else { - httpSendErrorResp(pContext, HTTP_INVALID_AUTH_TOKEN); - return false; - } - } else { - } - - return true; -} - bool httpDecodeRequest(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - if (pParser->pMethod->decodeFp == NULL) { + if (pContext->decodeMethod->decodeFp == NULL) { return false; } - return (*pParser->pMethod->decodeFp)(pContext); + return (*pContext->decodeMethod->decodeFp)(pContext); } /** @@ -263,7 +40,7 @@ bool httpProcessData(HttpContext* pContext) { } // handle Cross-domain request - if (strcmp(pContext->parser.method.pos, "OPTIONS") == 0) { + if (strcmp(pContext->parser->method, "OPTIONS") == 0) { httpDebug("context:%p, fd:%d, process options request", pContext, pContext->fd); httpSendOptionResp(pContext, "process options request success"); } else { diff --git a/src/plugins/http/src/httpJson.c b/src/plugins/http/src/httpJson.c index e200efbcef14e068f9566f640fe77091d393b749..e02782357c29c721632e3a5c9ba4ccb1046fb049 100644 --- a/src/plugins/http/src/httpJson.c +++ b/src/plugins/http/src/httpJson.c @@ -17,6 +17,7 @@ #include "os.h" #include "taosmsg.h" #include "taoserror.h" +#include "tglobal.h" #include "http.h" #include "httpLog.h" #include "httpCode.h" @@ -38,14 +39,14 @@ char JsonNulTkn[] = "null"; char JsonTrueTkn[] = "true"; char JsonFalseTkn[] = "false"; -int httpWriteBufByFd(struct HttpContext* pContext, const char* buf, int sz) { - int len; - int countWait = 0; - int writeLen = 0; +int32_t httpWriteBufByFd(struct HttpContext* pContext, const char* buf, int32_t sz) { + int32_t len; + int32_t countWait = 0; + int32_t writeLen = 0; do { if (pContext->fd > 2){ - len = (int)taosSend(pContext->fd, buf + writeLen, (size_t)(sz - writeLen), MSG_NOSIGNAL); + len = (int32_t)taosSend(pContext->fd, buf + writeLen, (size_t)(sz - writeLen), MSG_NOSIGNAL); } else { return sz; @@ -68,8 +69,8 @@ int httpWriteBufByFd(struct HttpContext* pContext, const char* buf, int sz) { return writeLen; } -int httpWriteBuf(struct HttpContext* pContext, const char* buf, int sz) { - int writeSz = httpWriteBufByFd(pContext, buf, sz); +int32_t httpWriteBuf(struct HttpContext* pContext, const char* buf, int32_t sz) { + int32_t writeSz = httpWriteBufByFd(pContext, buf, sz); if (writeSz != sz) { httpError("context:%p, fd:%d, dataSize:%d, writeSize:%d, failed to send response:\n%s", pContext, pContext->fd, sz, writeSz, buf); @@ -80,8 +81,8 @@ int httpWriteBuf(struct HttpContext* pContext, const char* buf, int sz) { return writeSz; } -int httpWriteBufNoTrace(struct HttpContext *pContext, const char *buf, int sz) { - int writeSz = httpWriteBufByFd(pContext, buf, sz); +int32_t httpWriteBufNoTrace(struct HttpContext *pContext, const char *buf, int32_t sz) { + int32_t writeSz = httpWriteBufByFd(pContext, buf, sz); if (writeSz != sz) { httpError("context:%p, fd:%d, dataSize:%d, writeSize:%d, failed to send response", pContext, pContext->fd, sz, writeSz); @@ -90,8 +91,8 @@ int httpWriteBufNoTrace(struct HttpContext *pContext, const char *buf, int sz) { return writeSz; } -int httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast) { - int remain = 0; +int32_t httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast) { + int32_t remain = 0; char sLen[24]; uint64_t srcLen = (uint64_t) (buf->lst - buf->buf); @@ -108,28 +109,28 @@ int httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast) { * The remote endpoint then decodes the stream by concatenating the chunks and uncompressing the result. */ - if (buf->pContext->acceptEncoding == HTTP_COMPRESS_IDENTITY) { + if (buf->pContext->parser->acceptEncodingGzip == 0 || !tsHttpEnableCompress) { if (buf->lst == buf->buf) { httpTrace("context:%p, fd:%d, no data need dump", buf->pContext, buf->pContext->fd); return 0; // there is no data to dump. } else { - int len = sprintf(sLen, "%lx\r\n", srcLen); + int32_t len = sprintf(sLen, "%lx\r\n", srcLen); httpTrace("context:%p, fd:%d, write body, chunkSize:%" PRIu64 ", response:\n%s", buf->pContext, buf->pContext->fd, srcLen, buf->buf); httpWriteBufNoTrace(buf->pContext, sLen, len); - remain = httpWriteBufNoTrace(buf->pContext, buf->buf, (int) srcLen); + remain = httpWriteBufNoTrace(buf->pContext, buf->buf, (int32_t)srcLen); } } else { char compressBuf[JSON_BUFFER_SIZE] = {0}; int32_t compressBufLen = JSON_BUFFER_SIZE; - int ret = httpGzipCompress(buf->pContext, buf->buf, srcLen, compressBuf, &compressBufLen, isTheLast); + int32_t ret = httpGzipCompress(buf->pContext, buf->buf, srcLen, compressBuf, &compressBufLen, isTheLast); if (ret == 0) { if (compressBufLen > 0) { - int len = sprintf(sLen, "%x\r\n", compressBufLen); + int32_t len = sprintf(sLen, "%x\r\n", compressBufLen); httpTrace("context:%p, fd:%d, write body, chunkSize:%" PRIu64 ", compressSize:%d, last:%d, response:\n%s", buf->pContext, buf->pContext->fd, srcLen, compressBufLen, isTheLast, buf->buf); httpWriteBufNoTrace(buf->pContext, sLen, len); - remain = httpWriteBufNoTrace(buf->pContext, (const char*)compressBuf, (int)compressBufLen); + remain = httpWriteBufNoTrace(buf->pContext, (const char*)compressBuf, compressBufLen); } else { httpTrace("context:%p, fd:%d, last:%d, compress already dumped, response:\n%s", buf->pContext, buf->pContext->fd, isTheLast, buf->buf); @@ -143,9 +144,9 @@ int httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast) { } httpWriteBufNoTrace(buf->pContext, "\r\n", 2); - buf->total += (int) (buf->lst - buf->buf); + buf->total += (int32_t)(buf->lst - buf->buf); buf->lst = buf->buf; - memset(buf->buf, 0, (size_t) buf->size); + memset(buf->buf, 0, (size_t)buf->size); return remain; } @@ -155,14 +156,14 @@ void httpWriteJsonBufHead(JsonBuf* buf) { } char msg[1024] = {0}; - int len = -1; + int32_t len = -1; - if (buf->pContext->acceptEncoding == HTTP_COMPRESS_IDENTITY) { - len = sprintf(msg, httpRespTemplate[HTTP_RESPONSE_CHUNKED_UN_COMPRESS], httpVersionStr[buf->pContext->httpVersion], - httpKeepAliveStr[buf->pContext->httpKeepAlive]); + if (buf->pContext->parser->acceptEncodingGzip == 0 || !tsHttpEnableCompress) { + len = sprintf(msg, httpRespTemplate[HTTP_RESPONSE_CHUNKED_UN_COMPRESS], httpVersionStr[buf->pContext->parser->httpVersion], + httpKeepAliveStr[buf->pContext->parser->keepAlive]); } else { - len = sprintf(msg, httpRespTemplate[HTTP_RESPONSE_CHUNKED_COMPRESS], httpVersionStr[buf->pContext->httpVersion], - httpKeepAliveStr[buf->pContext->httpKeepAlive]); + len = sprintf(msg, httpRespTemplate[HTTP_RESPONSE_CHUNKED_COMPRESS], httpVersionStr[buf->pContext->parser->httpVersion], + httpKeepAliveStr[buf->pContext->parser->keepAlive]); } httpWriteBuf(buf->pContext, (const char*)msg, len); @@ -185,7 +186,7 @@ void httpInitJsonBuf(JsonBuf* buf, struct HttpContext* pContext) { buf->pContext = pContext; memset(buf->lst, 0, JSON_BUFFER_SIZE); - if (pContext->acceptEncoding == HTTP_COMPRESS_GZIP) { + if (pContext->parser->acceptEncodingGzip == 1 && tsHttpEnableCompress) { httpGzipCompressInit(buf->pContext); } @@ -200,19 +201,19 @@ void httpJsonItemToken(JsonBuf* buf) { if (buf->lst > buf->buf) httpJsonToken(buf, JsonItmTkn); } -void httpJsonString(JsonBuf* buf, char* sVal, int len) { +void httpJsonString(JsonBuf* buf, char* sVal, int32_t len) { httpJsonItemToken(buf); httpJsonToken(buf, JsonStrStt); httpJsonPrint(buf, sVal, len); httpJsonToken(buf, JsonStrEnd); } -void httpJsonOriginString(JsonBuf* buf, char* sVal, int len) { +void httpJsonOriginString(JsonBuf* buf, char* sVal, int32_t len) { httpJsonItemToken(buf); httpJsonPrint(buf, sVal, len); } -void httpJsonStringForTransMean(JsonBuf* buf, char* sVal, int maxLen) { +void httpJsonStringForTransMean(JsonBuf* buf, char* sVal, int32_t maxLen) { httpJsonItemToken(buf); httpJsonToken(buf, JsonStrStt); @@ -221,18 +222,18 @@ void httpJsonStringForTransMean(JsonBuf* buf, char* sVal, int maxLen) { char* lastPos = sVal; char* curPos = sVal; - for (int i = 0; i < maxLen; ++i) { + for (int32_t i = 0; i < maxLen; ++i) { if (*curPos == 0) { break; } if (*curPos == '\"') { - httpJsonPrint(buf, lastPos, (int)(curPos - lastPos)); + httpJsonPrint(buf, lastPos, (int32_t)(curPos - lastPos)); curPos++; lastPos = curPos; httpJsonPrint(buf, "\\\"", 2); } else if (*curPos == '\\') { - httpJsonPrint(buf, lastPos, (int)(curPos - lastPos)); + httpJsonPrint(buf, lastPos, (int32_t)(curPos - lastPos)); curPos++; lastPos = curPos; httpJsonPrint(buf, "\\\\", 2); @@ -242,7 +243,7 @@ void httpJsonStringForTransMean(JsonBuf* buf, char* sVal, int maxLen) { } if (*lastPos) { - httpJsonPrint(buf, lastPos, (int)(curPos - lastPos)); + httpJsonPrint(buf, lastPos, (int32_t)(curPos - lastPos)); } } @@ -258,14 +259,14 @@ void httpJsonInt64(JsonBuf* buf, int64_t num) { void httpJsonTimestamp(JsonBuf* buf, int64_t t, bool us) { char ts[35] = {0}; struct tm *ptm; - int precision = 1000; + int32_t precision = 1000; if (us) { precision = 1000000; } time_t tt = t / precision; ptm = localtime(&tt); - int length = (int) strftime(ts, 35, "%Y-%m-%d %H:%M:%S", ptm); + int32_t length = (int32_t) strftime(ts, 35, "%Y-%m-%d %H:%M:%S", ptm); if (us) { length += snprintf(ts + length, 8, ".%06ld", t % precision); } else { @@ -278,25 +279,25 @@ void httpJsonTimestamp(JsonBuf* buf, int64_t t, bool us) { void httpJsonUtcTimestamp(JsonBuf* buf, int64_t t, bool us) { char ts[40] = {0}; struct tm *ptm; - int precision = 1000; + int32_t precision = 1000; if (us) { precision = 1000000; } time_t tt = t / precision; ptm = localtime(&tt); - int length = (int) strftime(ts, 40, "%Y-%m-%dT%H:%M:%S", ptm); + int32_t length = (int32_t)strftime(ts, 40, "%Y-%m-%dT%H:%M:%S", ptm); if (us) { length += snprintf(ts + length, 8, ".%06ld", t % precision); } else { length += snprintf(ts + length, 5, ".%03ld", t % precision); } - length += (int) strftime(ts + length, 40 - length, "%z", ptm); + length += (int32_t)strftime(ts + length, 40 - length, "%z", ptm); httpJsonString(buf, ts, length); } -void httpJsonInt(JsonBuf* buf, int num) { +void httpJsonInt(JsonBuf* buf, int32_t num) { httpJsonItemToken(buf); httpJsonTestBuf(buf, MAX_NUM_STR_SZ); buf->lst += snprintf(buf->lst, MAX_NUM_STR_SZ, "%d", num); @@ -328,65 +329,65 @@ void httpJsonDouble(JsonBuf* buf, double num) { void httpJsonNull(JsonBuf* buf) { httpJsonString(buf, "null", 4); } -void httpJsonBool(JsonBuf* buf, int val) { +void httpJsonBool(JsonBuf* buf, int32_t val) { if (val == 0) httpJsonPrint(buf, JsonFalseTkn, sizeof(JsonFalseTkn)); else httpJsonPrint(buf, JsonTrueTkn, sizeof(JsonTrueTkn)); } -void httpJsonPairHead(JsonBuf* buf, char* name, int len) { +void httpJsonPairHead(JsonBuf* buf, char* name, int32_t len) { httpJsonItemToken(buf); httpJsonString(buf, name, len); httpJsonToken(buf, JsonPairTkn); } -void httpJsonPair(JsonBuf* buf, char* name, int nameLen, char* sVal, int valLen) { +void httpJsonPair(JsonBuf* buf, char* name, int32_t nameLen, char* sVal, int32_t valLen) { httpJsonPairHead(buf, name, nameLen); httpJsonString(buf, sVal, valLen); } -void httpJsonPairOriginString(JsonBuf* buf, char* name, int nameLen, char* sVal, int valLen) { +void httpJsonPairOriginString(JsonBuf* buf, char* name, int32_t nameLen, char* sVal, int32_t valLen) { httpJsonPairHead(buf, name, nameLen); httpJsonOriginString(buf, sVal, valLen); } -void httpJsonPairIntVal(JsonBuf* buf, char* name, int nNameLen, int num) { +void httpJsonPairIntVal(JsonBuf* buf, char* name, int32_t nNameLen, int32_t num) { httpJsonPairHead(buf, name, nNameLen); httpJsonInt(buf, num); } -void httpJsonPairInt64Val(JsonBuf* buf, char* name, int nNameLen, int64_t num) { +void httpJsonPairInt64Val(JsonBuf* buf, char* name, int32_t nNameLen, int64_t num) { httpJsonPairHead(buf, name, nNameLen); httpJsonInt64(buf, num); } -void httpJsonPairBoolVal(JsonBuf* buf, char* name, int nNameLen, int num) { +void httpJsonPairBoolVal(JsonBuf* buf, char* name, int32_t nNameLen, int32_t num) { httpJsonPairHead(buf, name, nNameLen); httpJsonBool(buf, num); } -void httpJsonPairFloatVal(JsonBuf* buf, char* name, int nNameLen, float num) { +void httpJsonPairFloatVal(JsonBuf* buf, char* name, int32_t nNameLen, float num) { httpJsonPairHead(buf, name, nNameLen); httpJsonFloat(buf, num); } -void httpJsonPairDoubleVal(JsonBuf* buf, char* name, int nNameLen, double num) { +void httpJsonPairDoubleVal(JsonBuf* buf, char* name, int32_t nNameLen, double num) { httpJsonPairHead(buf, name, nNameLen); httpJsonDouble(buf, num); } -void httpJsonPairNullVal(JsonBuf* buf, char* name, int nNameLen) { +void httpJsonPairNullVal(JsonBuf* buf, char* name, int32_t nNameLen) { httpJsonPairHead(buf, name, nNameLen); httpJsonNull(buf); } -void httpJsonPairArray(JsonBuf* buf, char* name, int len, httpJsonBuilder fnBuilder, void* dsHandle) { +void httpJsonPairArray(JsonBuf* buf, char* name, int32_t len, httpJsonBuilder fnBuilder, void* dsHandle) { httpJsonPairHead(buf, name, len); httpJsonArray(buf, fnBuilder, dsHandle); } -void httpJsonPairObject(JsonBuf* buf, char* name, int len, httpJsonBuilder fnBuilder, void* dsHandle) { +void httpJsonPairObject(JsonBuf* buf, char* name, int32_t len, httpJsonBuilder fnBuilder, void* dsHandle) { httpJsonPairHead(buf, name, len); httpJsonObject(buf, fnBuilder, dsHandle); } @@ -405,7 +406,7 @@ void httpJsonArray(JsonBuf* buf, httpJsonBuilder fnBuilder, void* jsonHandle) { httpJsonToken(buf, JsonArrEnd); } -void httpJsonTestBuf(JsonBuf* buf, int safety) { +void httpJsonTestBuf(JsonBuf* buf, int32_t safety) { if ((buf->lst - buf->buf + safety) < buf->size) return; // buf->slot = *buf->lst; httpWriteJsonBufBody(buf, false); @@ -416,7 +417,7 @@ void httpJsonToken(JsonBuf* buf, char c) { *buf->lst++ = c; } -void httpJsonPrint(JsonBuf* buf, const char* json, int len) { +void httpJsonPrint(JsonBuf* buf, const char* json, int32_t len) { if (len == 0 || len >= JSON_BUFFER_SIZE) { return; } @@ -432,7 +433,7 @@ void httpJsonPrint(JsonBuf* buf, const char* json, int len) { buf->lst += len; } -void httpJsonPairStatus(JsonBuf* buf, int code) { +void httpJsonPairStatus(JsonBuf* buf, int32_t code) { if (code == 0) { httpJsonPair(buf, "status", 6, "succ", 4); } else { @@ -445,7 +446,7 @@ void httpJsonPairStatus(JsonBuf* buf, int code) { } else if (code == TSDB_CODE_MND_INVALID_TABLE_NAME) { httpJsonPair(buf, "desc", 4, "failed to create table", 22); } else { - httpJsonPair(buf, "desc", 4, (char*)tstrerror(code), (int)strlen(tstrerror(code))); + httpJsonPair(buf, "desc", 4, (char*)tstrerror(code), (int32_t)strlen(tstrerror(code))); } } } diff --git a/src/plugins/http/src/httpParser.c b/src/plugins/http/src/httpParser.c index c1fd481efd4da22fde2252c6c44e4e73ab7a0af7..0238c39eb8a90d88bd53af8036278c4a32f742e3 100644 --- a/src/plugins/http/src/httpParser.c +++ b/src/plugins/http/src/httpParser.c @@ -1,10 +1,30 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#define _DEFAULT_SOURCE #include "os.h" +#include "taoserror.h" #include "httpLog.h" #include "httpContext.h" #include "httpParser.h" #include "httpGzip.h" +#include "httpAuth.h" -static HttpParserStatusObj status_codes[] = { +static void httpOnData(ehttp_gzip_t *gzip, void *arg, const char *buf, int32_t len); + +static HttpStatus httpStatusCodes[] = { {100, "Continue"}, {101, "Switching Protocol"}, {102, "Processing (WebDAV)"}, @@ -71,127 +91,411 @@ static HttpParserStatusObj status_codes[] = { {0, NULL} }; -const char* ehttp_status_code_get_desc(const int status_code) { - HttpParserStatusObj *p = status_codes; - while (p->status_code!=0) { - if (p->status_code==status_code) return p->status_desc; +char *httpGetStatusDesc(int32_t statusCode) { + HttpStatus *p = httpStatusCodes; + while (p->code != 0) { + if (p->code == statusCode) return p->desc; ++p; } return "Unknow status code"; } -static void dummy_on_request_line(void *arg, const char *method, const char *target, const char *version, const char *target_raw) { +static void httpCleanupString(HttpString *str) { + free(str->str); + str->str = NULL; + str->pos = 0; + str->size = 0; } -static void dummy_on_status_line(void *arg, const char *version, int status_code, const char *reason_phrase) { -} +static int32_t httpAppendString(HttpString *str, const char *s, int32_t len) { + if (str->size == 0) { + str->pos = 0; + str->size = 32; + str->str = malloc(str->size); + } else if (str->pos + len + 1 > str->size) { + str->size *= 10; + str->str = realloc(str->str, str->size); + } else { + } -static void dummy_on_header_field(void *arg, const char *key, const char *val) { -} + if (str->str == NULL) return -1; -static void dummy_on_body(void *arg, const char *chunk, size_t len) { + memcpy(str->str + str->pos, s, len); + str->pos += len; + str->str[str->pos] = 0; + return 0; } -static void dummy_on_end(void *arg) { +static void httpClearString(HttpString *str) { + if (str->str) { + str->str[0] = '\0'; + str->pos = 0; + str->size = 0; + } } -static void dummy_on_error(void *arg, int status_code) { +static int32_t httpOnError(HttpParser *parser, int32_t httpCode, int32_t parseCode) { + HttpContext *pContext = parser->pContext; + if (httpCode != 0) parser->httpCode = httpCode; + if (parseCode != 0) parser->parseCode = parseCode; + httpError("context:%p, fd:%d, parse failed, httpCode:%d parseCode:%d", pContext, pContext->fd, httpCode, parseCode); + return 0; } -static HTTP_PARSER_STATE httpParserTop(HttpParserObj *parser) { - ASSERT(parser->stacks_count >= 1); - ASSERT(parser->stacks); +static int32_t httpOnRequestLine(HttpParser *pParser, char *method, char *target, char *version) { + HttpContext *pContext = pParser->pContext; + httpDebug("context:%p, fd:%d, method:%s target:%s version:%s", pContext, pContext->fd, method, target, version); + + // parse url + char *pStart = target + 1; + for (int32_t i = 0; i < HTTP_MAX_URL; i++) { + char *pSeek = strchr(pStart, '/'); + if (pSeek == NULL) { + pParser->path[i].str = strdup(pStart); + pParser->path[i].size = strlen(pStart); + pParser->path[i].pos = pParser->path[i].size; + break; + } else { + int32_t len = (int32_t)(pSeek - pStart); + pParser->path[i].str = malloc(len + 1); + memcpy(pParser->path[i].str, pStart, len); + pParser->path[i].str[len] = 0; + pParser->path[i].size = len; + pParser->path[i].pos = len; + } + pStart = pSeek + 1; + } - return parser->stacks[parser->stacks_count - 1]; -} + // parse decode method + for (int32_t i = 0; i < tsHttpServer.methodScannerLen; i++) { + HttpDecodeMethod *method = tsHttpServer.methodScanner[i]; + if (strcmp(method->module, pParser->path[0].str) == 0) { + pContext->decodeMethod = method; + break; + } + } -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)); - if (!stacks) return -1; + if (pContext->decodeMethod != NULL) { + httpDebug("context:%p, fd:%d, decode method is %s", pContext, pContext->fd, pContext->decodeMethod->module); + } else { + httpError("context:%p, fd:%d, the url is not support, target:%s", pContext, pContext->fd, target); + httpOnError(pParser, 0, TSDB_CODE_HTTP_UNSUPPORT_URL); + return -1; + } - parser->stacks_count = n; - parser->stacks = stacks; - parser->stacks[n-1] = state; + // parse version + if (pParser->httpVersion < HTTP_VERSION_10 || pParser->httpVersion > HTTP_VERSION_12) { + httpError("context:%p, fd:%d, unsupport httpVersion %d", pContext, pContext->fd, pParser->httpVersion); + httpOnError(pParser, 0, TSDB_CODE_HTTP_INVALID_VERSION); + } else { + httpDebug("context:%p, fd:%d, httpVersion:1.%d", pContext, pContext->fd, pParser->httpVersion); + } return 0; } -static int httpParserPop(HttpParserObj *parser) { - if (parser->stacks_count <= 0) return -1; - --parser->stacks_count; - +static int32_t httpOnStatusLine(HttpParser *pParser, int32_t code, const char *reason) { + HttpContext *pContext = pParser->pContext; + httpError("context:%p, fd:%d, status line, code:%d reason:%s", pContext, pContext->fd, code, reason); return 0; } -HttpParserObj *httpParserCreate(HttpParserCallbackObj callbacks, HttpParserConfObj conf, void *arg) { - HttpParserObj *parser = (HttpParserObj*)calloc(1, sizeof(*parser)); - if (!parser) return NULL; - - parser->callbacks = callbacks; - parser->arg = arg; - parser->conf = conf; +static int32_t httpOnParseHeaderField(HttpParser *parser, const char *key, const char *val) { + HttpContext *pContext = parser->pContext; + httpDebug("context:%p, fd:%d, key:%s val:%s", pContext, pContext->fd, key, 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->contentLength = len; + parser->chunkSize = len; + parser->contentLengthSpecified = 1; + httpDebug("context:%p, fd:%d, contentLength:%d chunkSize:%d contentLengthSpecified:%d", pContext, pContext->fd, + parser->contentLength, parser->chunkSize, parser->contentLengthSpecified); + return 0; + } else { + httpError("context:%p, fd:%d, failed to parser %s:%s", pContext, pContext->fd, key, val); + httpOnError(parser, 0, TSDB_CODE_HTTP_INVALID_CONTENT_LENGTH); + return -1; + } + } - if (parser->callbacks.on_request_line == NULL) { - parser->callbacks.on_request_line = dummy_on_request_line; + else if (0 == strcasecmp(key, "Accept-Encoding")) { + if (strstr(val, "gzip")) { + parser->acceptEncodingGzip = 1; + httpDebug("context:%p, fd:%d, acceptEncodingGzip:%d", pContext, pContext->fd, parser->acceptEncodingGzip); + } + if (strstr(val, "chunked")) { + parser->acceptEncodingChunked = 1; + httpDebug("context:%p, fd:%d, acceptEncodingChunked:%d", pContext, pContext->fd, parser->acceptEncodingChunked); + } + return 0; } - if (parser->callbacks.on_status_line == NULL) { - parser->callbacks.on_status_line = dummy_on_status_line; + + else if (strncasecmp(key, "Connection: ", 12) == 0) { + if (strncasecmp(val, "Keep-Alive", 10) == 0) { + parser->keepAlive = HTTP_KEEPALIVE_ENABLE; + } else { + parser->keepAlive = HTTP_KEEPALIVE_DISABLE; + } + httpTrace("context:%p, fd:%d, keepAlive:%d", pContext, pContext->fd, pContext->parser->keepAlive); } - if (parser->callbacks.on_header_field == NULL) { - parser->callbacks.on_header_field = dummy_on_header_field; + + else if (0 == strcasecmp(key, "Content-Encoding")) { + if (0 == strcmp(val, "gzip")) { + parser->contentChunked = 1; + httpDebug("context:%p, fd:%d, contentChunked:%d", pContext, pContext->fd, parser->contentChunked); + } + return 0; } - if (parser->callbacks.on_body == NULL) { - parser->callbacks.on_body = dummy_on_body; + + else if (0 == strcasecmp(key, "Transfer-Encoding")) { + if (strstr(val, "gzip")) { + parser->transferGzip = 1; + ehttp_gzip_conf_t conf = {0}; + ehttp_gzip_callbacks_t callbacks = {0}; + + callbacks.on_data = httpOnData; + + parser->gzip = ehttp_gzip_create_decompressor(conf, callbacks, parser); + + if (!parser->gzip) { + httpError("context:%p, fd:%d, failed to create gzip decompressor", pContext, pContext->fd); + httpOnError(parser, 0, TSDB_CODE_HTTP_CREATE_GZIP_FAILED); + return -1; + } + } + if (strstr(val, "chunked")) { + parser->transferChunked = 1; + httpDebug("context:%p, fd:%d, transferChunked:%d", pContext, pContext->fd, parser->transferChunked); + } + return 0; } - if (parser->callbacks.on_end == NULL) { - parser->callbacks.on_end = dummy_on_end; + + else if (0 == strcasecmp(key, "Authorization")) { + char * t = NULL; + char * 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->authContent); + parser->authContent = s; + parser->authType = HTTP_BASIC_AUTH; + s = NULL; + free(t); + free(s); + httpDebug("context:%p, fd:%d, basic auth:%s", pContext, pContext->fd, parser->authContent); + int32_t ok = httpParseBasicAuthToken(pContext, parser->authContent, strlen(parser->authContent)); + if (ok != 0) { + httpOnError(parser, 0, TSDB_CODE_HTTP_INVALID_BASIC_AUTH); + return -1; + } + return 0; + } else if (strcmp(t, "Taosd") == 0) { + free(parser->authContent); + parser->authContent = s; + parser->authType = HTTP_TAOSD_AUTH; + s = NULL; + free(t); + free(s); + httpDebug("context:%p, fd:%d, taosd auth:%s", pContext, pContext->fd, parser->authContent); + int32_t ok = httpParseTaosdAuthToken(pContext, parser->authContent, strlen(parser->authContent)); + if (ok != 0) { + httpOnError(parser, 0, TSDB_CODE_HTTP_INVALID_TAOSD_AUTH); + return -1; + } + return 0; + } else { + free(t); + free(s); + parser->authType = HTTP_INVALID_AUTH; + httpError("context:%p, fd:%d, invalid auth, t:%s s:%s", pContext, pContext->fd, t, s); + httpOnError(parser, 0, TSDB_CODE_HTTP_INVALID_AUTH_TYPE); + return -1; + } + } else { + free(t); + free(s); + parser->authType = HTTP_INVALID_AUTH; + httpError("context:%p, fd:%d, parse auth failed, t:%s s:%s", pContext, pContext->fd, t, s); + httpOnError(parser, 0, TSDB_CODE_HTTP_INVALID_AUTH_FORMAT); + return -1; + } } - if (parser->callbacks.on_error == NULL) { - parser->callbacks.on_error = dummy_on_error; + + return 0; +} + +static int32_t httpOnBody(HttpParser *parser, const char *chunk, int32_t len) { + HttpContext *pContext = parser->pContext; + HttpString * buf = &parser->body; + if (parser->parseCode != TSDB_CODE_SUCCESS) return -1; + + int32_t avail = buf->size - buf->pos; + if (len + 1 >= avail) { + if (buf->size >= HTTP_BUFFER_SIZE) { + httpError("context:%p, fd:%d, failed parse body, exceeding buffer size %d", pContext, pContext->fd, buf->size); + httpOnError(parser, 0, TSDB_CODE_HTTP_NO_ENOUGH_MEMORY); + return -1; + } else { + int32_t newSize = buf->size * 10; + newSize = MIN(newSize, HTTP_BUFFER_SIZE); + buf->str = realloc(buf->str, newSize); + if (buf->str == NULL) { + httpError("context:%p, fd:%d, failed parse body, realloc %d failed", pContext, pContext->fd, newSize); + httpOnError(parser, 0, TSDB_CODE_HTTP_NO_ENOUGH_MEMORY); + return -1; + } + buf->size = newSize; + } } - httpParserPush(parser, HTTP_PARSER_BEGIN); + memcpy(buf->str + buf->pos, chunk, len); + buf->pos += len; + buf->str[buf->pos] = 0; - return parser; + return 0; +} + +static int32_t httpOnEnd(HttpParser *parser) { + HttpContext *pContext = parser->pContext; + parser->parsed = true; + + if (parser->parseCode != TSDB_CODE_SUCCESS) { + return -1; + } + + httpDebug("context:%p, fd:%d, parse success", pContext, pContext->fd); + return 0; } -static void ehttp_parser_kvs_destroy(HttpParserObj *parser) { - if (!parser->kvs) return; +static HTTP_PARSER_STATE httpTopStack(HttpParser *parser) { + HttpStack *stack = &parser->stacks; + ASSERT(stack->pos >= 1); - for (size_t i=0; ikvs_count; ++i) { - HttpParseKvObj *p = &parser->kvs[i]; - free(p->key); p->key = NULL; - free(p->val); p->val = NULL; + return stack->stacks[stack->pos - 1]; +} + +static int32_t httpPushStack(HttpParser *parser, HTTP_PARSER_STATE state) { + HttpStack *stack = &parser->stacks; + if (stack->size == 0) { + stack->pos = 0; + stack->size = 32; + stack->stacks = malloc(stack->size * sizeof(int8_t)); + } else if (stack->pos + 1 > stack->size) { + stack->size *= 10; + stack->stacks = realloc(stack->stacks, stack->size * sizeof(int8_t)); + } else { } - free(parser->kvs); - parser->kvs = NULL; - parser->kvs_count = 0; - free(parser->auth_basic); - parser->auth_basic = NULL; + if (stack->stacks == NULL) return -1; + + stack->stacks[stack->pos] = state; + stack->pos++; + + return 0; } -void httpParserDestroy(HttpParserObj *parser) { - if (!parser) return; +static int32_t httpPopStack(HttpParser *parser) { + HttpStack *stack = &parser->stacks; + ASSERT(stack->pos >= 1); + stack->pos--; + return 0; +} + +static void httpClearStack(HttpStack *stack) { + stack->pos = 0; +} + +static int32_t httpCleanupStack(HttpStack *stack) { + free(stack->stacks); + memset(stack, 0, sizeof(HttpStack)); + + return 0; +} + +void httpInitParser(HttpParser *parser) { + HttpContext *pContext = parser->pContext; + httpTrace("context:%p, fd:%d, free parser", pContext, pContext->fd); + + parser->parsed = false; + parser->inited = 1; + parser->httpVersion = 0; + parser->acceptEncodingGzip = 0; + parser->acceptEncodingChunked = 0; + parser->contentLengthSpecified = 0; + parser->contentChunked = 0; + parser->transferGzip = 0; + parser->transferChunked = 0; + parser->keepAlive = 0; + parser->authType = 0; + parser->contentLength = 0; + parser->chunkSize = 0; + parser->receivedChunkSize = 0; + parser->receivedSize = 0; + parser->statusCode = 0; + parser->httpCode = 0; + parser->parseCode = 0; free(parser->method); parser->method = NULL; free(parser->target); parser->target = NULL; free(parser->target_raw); parser->target_raw = NULL; free(parser->version); parser->version = NULL; - free(parser->reason_phrase); parser->reason_phrase = NULL; + free(parser->reasonPhrase); parser->reasonPhrase = NULL; free(parser->key); parser->key = NULL; free(parser->val); parser->val = NULL; - free(parser->auth_basic); parser->auth_basic = NULL; - free(parser->stacks); parser->stacks = NULL; + free(parser->authContent); parser->authContent = NULL; + + httpClearStack(&parser->stacks); + httpClearString(&parser->str); + httpClearString(&parser->body); + for (int32_t i = 0; i < HTTP_MAX_URL; ++i) { + httpClearString(&parser->path[i]); + } + + if (parser->gzip != NULL) { + ehttp_gzip_destroy(parser->gzip); + parser->gzip = NULL; + } - parser->stacks_count = 0; + httpPushStack(parser, HTTP_PARSER_BEGIN); +} - ehttp_parser_kvs_destroy(parser); +HttpParser *httpCreateParser(HttpContext *pContext) { + HttpParser *parser = calloc(1, sizeof(HttpParser)); + if (!parser) return NULL; + httpTrace("context:%p, fd:%d, create parser", pContext, pContext->fd); - httpParserCleanupString(&parser->str); - if (parser->gzip) { + parser->pContext = pContext; + return parser; +} + +void httpDestroyParser(HttpParser *parser) { + HttpContext *pContext = parser->pContext; + httpTrace("context:%p, fd:%d, free parser", pContext, pContext->fd); + + if (!parser) return; + + free(parser->method); parser->method = NULL; + free(parser->target); parser->target = NULL; + free(parser->target_raw); parser->target_raw = NULL; + free(parser->version); parser->version = NULL; + free(parser->reasonPhrase); parser->reasonPhrase = NULL; + free(parser->key); parser->key = NULL; + free(parser->val); parser->val = NULL; + free(parser->authContent); parser->authContent = NULL; + + httpCleanupStack(&parser->stacks); + httpCleanupString(&parser->str); + httpCleanupString(&parser->body); + for (int32_t i = 0; i < HTTP_MAX_URL; ++i) { + httpCleanupString(&parser->path[i]); + } + + if (parser->gzip != NULL) { ehttp_gzip_destroy(parser->gzip); parser->gzip = NULL; } @@ -201,209 +505,106 @@ void httpParserDestroy(HttpParserObj *parser) { #define is_token(c) (strchr("!#$%&'*+-.^_`|~", c) || isdigit(c) || isalpha(c)) -char *ehttp_parser_urldecode(const char *enc) { - int ok = 1; - HttpParserString str = {0}; +char *httpDecodeUrl(const char *enc) { + int32_t ok = 1; + HttpString str = {0}; while (*enc) { char *p = strchr(enc, '%'); if (!p) break; - int hex, cnt; - int n = sscanf(p+1, "%2x%n", &hex, &cnt); + int32_t hex, cnt; + int32_t n = sscanf(p+1, "%2x%n", &hex, &cnt); if (n!=1 && cnt !=2) { ok = 0; break; } - if (httpParserAppendString(&str, enc, p-enc)) { ok = 0; break; } + if (httpAppendString(&str, enc, p-enc)) { ok = 0; break; } char c = (char)hex; - if (httpParserAppendString(&str, &c, 1)) { ok = 0; break; } + if (httpAppendString(&str, &c, 1)) { ok = 0; break; } enc = p+3; } char *dec = NULL; if (ok && *enc) { - if (httpParserAppendString(&str, enc, strlen(enc))) { ok = 0; } + if (httpAppendString(&str, enc, strlen(enc))) { ok = 0; } } if (ok) { dec = str.str; str.str = NULL; } - httpParserCleanupString(&str); + httpCleanupString(&str); return dec; } -static void on_data(ehttp_gzip_t *gzip, void *arg, const char *buf, size_t len) { - HttpParserObj *parser = (HttpParserObj*)arg; - parser->callbacks.on_body(parser->arg, buf, len); +static void httpOnData(ehttp_gzip_t *gzip, void *arg, const char *buf, int32_t len) { + HttpParser *parser = (HttpParser*)arg; + httpOnBody(parser, buf, len); } -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")) { - 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->content_length_specified = 1; - break; - } - ok = -1; - break; - } - if (0 == strcasecmp(key, "Accept-Encoding")) { - if (strstr(val, "gzip")) { - parser->accept_encoding_gzip = 1; - } - if (strstr(val, "chunked")) { - parser->accept_encoding_chunked = 1; - } - break; - } - if (0 == strcasecmp(key, "Content-Encoding")) { - if (0 == strcmp(val, "gzip")) { - parser->content_chunked = 1; - } - break; - } - if (0 == strcasecmp(key, "Transfer-Encoding")) { - if (strstr(val, "gzip")) { - parser->transfer_gzip = 1; - ehttp_gzip_conf_t conf = {0}; - ehttp_gzip_callbacks_t callbacks = {0}; - - callbacks.on_data = on_data; - - parser->gzip = ehttp_gzip_create_decompressor(conf, callbacks, parser); - - if (!parser->gzip) { - httpDebug("failed to create gzip decompressor"); - ok = -1; - break; - } - } - if (strstr(val, "chunked")) { - parser->transfer_chunked = 1; - } - break; - } - if (0==strcasecmp(key, "Authorization")) { - char *t = NULL; - char *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); - break; - } - } while (0); - return ok; -} - -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; - - kvs[parser->kvs_count].key = strdup(key); - kvs[parser->kvs_count].val = strdup(val); - - if (kvs[parser->kvs_count].key && kvs[parser->kvs_count].val) { - ++parser->kvs_count; - return 0; - } - - free(kvs[parser->kvs_count].key); - kvs[parser->kvs_count].key = NULL; - free(kvs[parser->kvs_count].val); - kvs[parser->kvs_count].val = NULL; - - return -1; -} - -static int32_t httpParserOnBegin(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnBegin(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { if (c == 'G' || c == 'P' || c == 'H' || c == 'D' || c == 'C' || c == 'O' || c == 'T') { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_METHOD_FAILED); break; } - httpParserPop(parser); - httpParserPush(parser, HTTP_PARSER_REQUEST_OR_RESPONSE); + httpPopStack(parser); + httpPushStack(parser, HTTP_PARSER_REQUEST_OR_RESPONSE); break; } 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_METHOD_FAILED); } while (0); return ok; } -static int32_t httpParserOnRquestOrResponse(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnRquestOrResponse(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { - if (parser->str.len == 1) { + if (parser->str.pos == 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); + httpPopStack(parser); + httpPushStack(parser, HTTP_PARSER_END); + httpPushStack(parser, HTTP_PARSER_HEADER); + httpPushStack(parser, HTTP_PARSER_CRLF); + httpPushStack(parser, HTTP_PARSER_REASON_PHRASE); + httpPushStack(parser, HTTP_PARSER_SP); + httpPushStack(parser, HTTP_PARSER_STATUS_CODE); + httpPushStack(parser, HTTP_PARSER_SP); + httpPushStack(parser, HTTP_PARSER_HTTP_VERSION); *again = 1; break; } - 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); + httpPopStack(parser); + httpPushStack(parser, HTTP_PARSER_END); + httpPushStack(parser, HTTP_PARSER_HEADER); + httpPushStack(parser, HTTP_PARSER_CRLF); + httpPushStack(parser, HTTP_PARSER_HTTP_VERSION); + httpPushStack(parser, HTTP_PARSER_SP); + httpPushStack(parser, HTTP_PARSER_TARGET); + httpPushStack(parser, HTTP_PARSER_SP); + httpPushStack(parser, HTTP_PARSER_METHOD); *again = 1; break; } 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_METHOD_FAILED); } while (0); return ok; } -static int32_t httpParserOnMethod(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnMethod(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { if (isalnum(c) || strchr("!#$%&'*+-.^_`|~", c)) { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_METHOD_FAILED); break; } break; @@ -412,59 +613,63 @@ static int32_t httpParserOnMethod(HttpContext *pContext, HttpParserObj *parser, if (!parser->method) { 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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_METHOD_FAILED); break; + } else { + httpTrace("context:%p, fd:%d, httpMethod:%s", pContext, pContext->fd, parser->method); } - httpParserClearString(&parser->str); - httpParserPop(parser); + httpClearString(&parser->str); + httpPopStack(parser); *again = 1; } while (0); return ok; } -static int32_t httpParserOnTarget(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnTarget(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { if (!isspace(c) && c != '\r' && c != '\n') { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_TARGET_FAILED); break; } break; } parser->target_raw = strdup(parser->str.str); - parser->target = ehttp_parser_urldecode(parser->str.str); + parser->target = httpDecodeUrl(parser->str.str); if (!parser->target_raw || !parser->target) { 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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_TARGET_FAILED); break; } - httpParserClearString(&parser->str); - httpParserPop(parser); + httpClearString(&parser->str); + httpPopStack(parser); *again = 1; } while (0); return ok; } -static int32_t httpParserOnVersion(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnVersion(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { const char *prefix = "HTTP/1."; int32_t len = strlen(prefix); - if (parser->str.len < len) { - if (prefix[parser->str.len]!=c) { + if (parser->str.pos < len) { + if (prefix[parser->str.pos] != 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_VERSION_FAILED); break; } - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_VERSION_FAILED); break; } break; @@ -473,135 +678,143 @@ static int32_t httpParserOnVersion(HttpContext *pContext, HttpParserObj *parser, if (c!='0' && c!='1') { 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_VERSION_FAILED); break; } - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_VERSION_FAILED); break; } - if (c=='0') parser->http_10 = 1; - if (c=='1') parser->http_11 = 1; + + if (c == '0') parser->httpVersion = HTTP_VERSION_10; + else if (c == '1') parser->httpVersion = HTTP_VERSION_11; + else if (c == '2') parser->httpVersion = HTTP_VERSION_12; + else parser->httpVersion = HTTP_INVALID_VERSION; parser->version = strdup(parser->str.str); if (!parser->version) { 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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_VERSION_FAILED); break; } if (parser->method) { - parser->callbacks.on_request_line(parser->arg, parser->method, parser->target, parser->version, parser->target_raw); + ok = httpOnRequestLine(parser, parser->method, parser->target, parser->version); } - httpParserClearString(&parser->str); - httpParserPop(parser); + httpClearString(&parser->str); + httpPopStack(parser); } while (0); return ok; } -static int32_t httpParserOnSp(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { +static int32_t httpParserOnSp(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { if (c == ' ') { - httpParserPop(parser); + httpPopStack(parser); break; } 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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_SP_FAILED); } while (0); return ok; } -static int32_t httpParserOnStatusCode(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnStatusCode(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; + int32_t ok = 0; do { if (isdigit(c)) { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_STATUS_FAILED); break; } - if (parser->str.len < 3) break; + if (parser->str.pos < 3) break; - sscanf(parser->str.str, "%d", &parser->status_code); - httpParserClearString(&parser->str); - httpParserPop(parser); + sscanf(parser->str.str, "%d", &parser->statusCode); + httpClearString(&parser->str); + httpPopStack(parser); break; } 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_STATUS_FAILED); } while (0); return ok; } -static int32_t httpParserOnReasonPhrase(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnReasonPhrase(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; + int32_t ok = 0; do { - if (c=='\r') { - parser->reason_phrase = strdup(parser->str.str); - if (!parser->reason_phrase) { + if (c == '\r') { + parser->reasonPhrase = strdup(parser->str.str); + if (!parser->reasonPhrase) { 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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_PHRASE_FAILED); break; } - parser->callbacks.on_status_line(parser->arg, parser->version, parser->status_code, parser->reason_phrase); - httpParserClearString(&parser->str); - httpParserPop(parser); + ok = httpOnStatusLine(parser, parser->statusCode, parser->reasonPhrase); + httpClearString(&parser->str); + httpPopStack(parser); *again = 1; break; } - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_PHRASE_FAILED); break; } } while (0); return ok; } -static int32_t httpParserPostProcess(HttpContext *pContext, HttpParserObj *parser) { +static int32_t httpParserPostProcess(HttpParser *parser) { + HttpContext *pContext = parser->pContext; if (parser->gzip) { if (ehttp_gzip_finish(parser->gzip)) { httpError("context:%p, fd:%d, gzip failed", pContext, pContext->fd); - parser->callbacks.on_error(parser->arg, 507); + httpOnError(parser, 507, TSDB_CODE_HTTP_FINISH_GZIP_FAILED); return -1; } } - parser->callbacks.on_end(parser->arg); + httpOnEnd(parser); return 0; } -static int32_t httpParserOnCrlf(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnCrlf(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { const char *s = "\r\n"; int32_t len = strlen(s); - if (s[parser->str.len]!=c) { + if (s[parser->str.pos] != 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_CRLF_FAILED); break; } - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_CRLF_FAILED); break; } - if (parser->str.len == len) { - httpParserClearString(&parser->str); - httpParserPop(parser); - if (httpParserTop(parser) == HTTP_PARSER_END) { - ok = httpParserPostProcess(pContext, parser); + if (parser->str.pos == len) { + httpClearString(&parser->str); + httpPopStack(parser); + if (httpTopStack(parser) == HTTP_PARSER_END) { + ok = httpParserPostProcess(parser); } } break; @@ -609,141 +822,140 @@ static int32_t httpParserOnCrlf(HttpContext *pContext, HttpParserObj *parser, HT return ok; } -static int32_t httpParserOnHeader(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnHeader(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { - if (c=='\r') { - httpParserPop(parser); - if (parser->transfer_chunked) { - httpParserPush(parser, HTTP_PARSER_CHUNK_SIZE); - httpParserPush(parser, HTTP_PARSER_CRLF); + if (c == '\r') { + httpPopStack(parser); + if (parser->transferChunked) { + httpPushStack(parser, HTTP_PARSER_CHUNK_SIZE); + httpPushStack(parser, HTTP_PARSER_CRLF); } else { - if (parser->content_length > 0) { - httpParserPush(parser, HTTP_PARSER_CHUNK); + if (parser->contentLength > 0) { + httpPushStack(parser, HTTP_PARSER_CHUNK); } - httpParserPush(parser, HTTP_PARSER_CRLF); + httpPushStack(parser, HTTP_PARSER_CRLF); } *again = 1; break; } - if (c!=' ' && c!='\t' && c!=':' ) { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (c != ' ' && c != '\t' && c != ':') { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_HEADER_FAILED); break; } - httpParserPush(parser, HTTP_PARSER_CRLF); - httpParserPush(parser, HTTP_PARSER_HEADER_VAL); - httpParserPush(parser, HTTP_PARSER_SP); - httpParserPush(parser, HTTP_PARSER_HEADER_KEY); + httpPushStack(parser, HTTP_PARSER_CRLF); + httpPushStack(parser, HTTP_PARSER_HEADER_VAL); + httpPushStack(parser, HTTP_PARSER_SP); + httpPushStack(parser, HTTP_PARSER_HEADER_KEY); break; } 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_HEADER_FAILED); } while (0); return ok; } -static int httpParserOnHeaderKey(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnHeaderKey(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; + int32_t ok = 0; do { if (isalnum(c) || strchr("!#$%&'*+-.^_`|~", c)) { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_HEADER_KEY_FAILED); break; } break; } - if (c==':') { + if (c == ':') { parser->key = strdup(parser->str.str); if (!parser->key) { 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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_HEADER_KEY_FAILED); break; } - httpParserClearString(&parser->str); - httpParserPop(parser); + httpClearString(&parser->str); + httpPopStack(parser); break; } 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_HEADER_KEY_FAILED); } while (0); return ok; } -static int32_t httpParserOnHeaderVal(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnHeaderVal(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { - if (c != '\r' && c != '\n' && (!isspace(c) || parser->str.len>0)) { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (c != '\r' && c != '\n' && (!isspace(c) || parser->str.pos > 0)) { + if (httpAppendString(&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); + parser->parseCode = TSDB_CODE_HTTP_PARSE_HEADER_VAL_FAILED; + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_HEADER_VAL_FAILED); break; } break; } 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); - } + ok = httpOnParseHeaderField(parser, parser->key, val); free(parser->key); parser->key = NULL; val = NULL; if (ok == -1) break; - httpParserClearString(&parser->str); - httpParserPop(parser); + httpClearString(&parser->str); + httpPopStack(parser); *again = 1; } while (0); return ok; } -static int32_t httpParserOnChunkSize(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnChunkSize(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; int32_t bytes; int32_t len; - int n; + int32_t n; do { if (isxdigit(c)) { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_CHUNK_SIZE_FAILED); break; } break; } - if (c=='\r') { + if (c == '\r') { 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) { - httpParserClearString(&parser->str); - httpParserPop(parser); - httpParserPush(parser, HTTP_PARSER_CRLF); - httpParserPush(parser, HTTP_PARSER_CRLF); + if (n == 1 && bytes == strlen(parser->str.str) && len >= 0) { + if (len == 0) { + if (parser->contentLengthSpecified == 0 || parser->receivedSize == parser->contentLength) { + httpClearString(&parser->str); + httpPopStack(parser); + httpPushStack(parser, HTTP_PARSER_CRLF); + httpPushStack(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; - 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); + if (parser->contentLengthSpecified == 0 || parser->receivedSize + len <= parser->contentLength) { + parser->chunkSize = len; + httpClearString(&parser->str); + httpPopStack(parser); + httpPushStack(parser, HTTP_PARSER_CHUNK_SIZE); + httpPushStack(parser, HTTP_PARSER_CRLF); + httpPushStack(parser, HTTP_PARSER_CHUNK); + httpPushStack(parser, HTTP_PARSER_CRLF); *again = 1; break; } @@ -752,116 +964,119 @@ static int32_t httpParserOnChunkSize(HttpContext *pContext, HttpParserObj *parse } 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); + httpOnError(parser, 400, TSDB_CODE_HTTP_PARSE_CHUNK_SIZE_FAILED); } while (0); return ok; } -static int httpParserOnChunk(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int *again) { - int ok = 0; +static int32_t httpParserOnChunk(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; + int32_t ok = 0; do { - if (httpParserAppendString(&parser->str, &c, 1)) { + if (httpAppendString(&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); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_CHUNK_FAILED); break; } - ++parser->received_size; - ++parser->received_chunk_size; - if (parser->received_chunk_size < parser->chunk_size) break; + ++parser->receivedSize; + ++parser->receivedChunkSize; + if (parser->receivedChunkSize < parser->chunkSize) break; if (parser->gzip) { - if (ehttp_gzip_write(parser->gzip, parser->str.str, parser->str.len)) { + if (ehttp_gzip_write(parser->gzip, parser->str.str, parser->str.pos)) { httpError("context:%p, fd:%d, gzip failed", pContext, pContext->fd); ok = -1; - parser->callbacks.on_error(parser->arg, 507); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_CHUNK_FAILED); break; } } else { - parser->callbacks.on_body(parser->arg, parser->str.str, parser->str.len); + httpOnBody(parser, parser->str.str, parser->str.pos); } - parser->received_chunk_size = 0; - httpParserClearString(&parser->str); - httpParserPop(parser); - if (httpParserTop(parser) == HTTP_PARSER_END) { - ok = httpParserPostProcess(pContext, parser); + parser->receivedChunkSize = 0; + httpClearString(&parser->str); + httpPopStack(parser); + if (httpTopStack(parser) == HTTP_PARSER_END) { + ok = httpParserPostProcess(parser); } } while (0); return ok; } -static int32_t httpParserOnEnd(HttpContext *pContext, HttpParserObj *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { +static int32_t httpParserOnEnd(HttpParser *parser, HTTP_PARSER_STATE state, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; do { - 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); + httpError("context:%p, fd:%d, parser state:%d, unexpected char:[%c]%02x", pContext, pContext->fd, state, c, c); + httpOnError(parser, 507, TSDB_CODE_HTTP_PARSE_END_FAILED); } while (0); return ok; } -static int32_t httpParseChar(HttpContext *pContext, HttpParserObj *parser, const char c, int32_t *again) { +static int32_t httpParseChar(HttpParser *parser, const char c, int32_t *again) { + HttpContext *pContext = parser->pContext; int32_t ok = 0; - HTTP_PARSER_STATE state = httpParserTop(parser); + HTTP_PARSER_STATE state = httpTopStack(parser); do { if (state == HTTP_PARSER_BEGIN) { - ok = httpParserOnBegin(pContext, parser, state, c, again); + ok = httpParserOnBegin(parser, state, c, again); break; } if (state == HTTP_PARSER_REQUEST_OR_RESPONSE) { - ok = httpParserOnRquestOrResponse(pContext, parser, state, c, again); + ok = httpParserOnRquestOrResponse(parser, state, c, again); break; } if (state == HTTP_PARSER_METHOD) { - ok = httpParserOnMethod(pContext, parser, state, c, again); + ok = httpParserOnMethod(parser, state, c, again); break; } if (state == HTTP_PARSER_TARGET) { - ok = httpParserOnTarget(pContext, parser, state, c, again); + ok = httpParserOnTarget(parser, state, c, again); break; } if (state == HTTP_PARSER_HTTP_VERSION) { - ok = httpParserOnVersion(pContext, parser, state, c, again); + ok = httpParserOnVersion(parser, state, c, again); break; } if (state == HTTP_PARSER_SP) { - ok = httpParserOnSp(pContext, parser, state, c, again); + ok = httpParserOnSp(parser, state, c, again); break; } if (state == HTTP_PARSER_STATUS_CODE) { - ok = httpParserOnStatusCode(pContext, parser, state, c, again); + ok = httpParserOnStatusCode(parser, state, c, again); break; } if (state == HTTP_PARSER_REASON_PHRASE) { - ok = httpParserOnReasonPhrase(pContext, parser, state, c, again); + ok = httpParserOnReasonPhrase(parser, state, c, again); break; } if (state == HTTP_PARSER_CRLF) { - ok = httpParserOnCrlf(pContext, parser, state, c, again); + ok = httpParserOnCrlf(parser, state, c, again); break; } if (state == HTTP_PARSER_HEADER) { - ok = httpParserOnHeader(pContext, parser, state, c, again); + ok = httpParserOnHeader(parser, state, c, again); break; } if (state == HTTP_PARSER_HEADER_KEY) { - ok = httpParserOnHeaderKey(pContext, parser, state, c, again); + ok = httpParserOnHeaderKey(parser, state, c, again); break; } if (state == HTTP_PARSER_HEADER_VAL) { - ok = httpParserOnHeaderVal(pContext, parser, state, c, again); + ok = httpParserOnHeaderVal(parser, state, c, again); break; } if (state == HTTP_PARSER_CHUNK_SIZE) { - ok = httpParserOnChunkSize(pContext, parser, state, c, again); + ok = httpParserOnChunkSize(parser, state, c, again); break; } if (state == HTTP_PARSER_CHUNK) { - ok = httpParserOnChunk(pContext, parser, state, c, again); + ok = httpParserOnChunk(parser, state, c, again); break; } if (state == HTTP_PARSER_END) { - ok = httpParserOnEnd(pContext, parser, state, c, again); + ok = httpParserOnEnd(parser, state, c, again); break; } if (state == HTTP_PARSER_ERROR) { @@ -869,32 +1084,34 @@ static int32_t httpParseChar(HttpContext *pContext, HttpParserObj *parser, const break; } - httpError("context:%p, fd:%d, unknown parse state:%d", pContext, pContext->fd, state); ok = -1; - parser->callbacks.on_error(parser->arg, 500); + httpError("context:%p, fd:%d, unknown parse state:%d", pContext, pContext->fd, state); + httpOnError(parser, 500, TSDB_CODE_HTTP_PARSE_INVALID_STATE); } while (0); 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); + httpError("context:%p, fd:%d, failed to parse, state:%d", pContext, pContext->fd, state); + httpPushStack(parser, HTTP_PARSER_ERROR); } if (ok == -2) { - httpError("context:%p, fd:%d, failed to parse, state:%d ok:%d", pContext, pContext->fd, state, ok); ok = -1; + httpError("context:%p, fd:%d, failed to parse, invalid state", pContext, pContext->fd); + httpOnError(parser, 500, TSDB_CODE_HTTP_PARSE_ERROR_STATE); } return ok; } -int32_t httpParserBuf(HttpContext *pContext, HttpParserObj *parser, const char *buf, int32_t len) { +int32_t httpParseBuf(HttpParser *parser, const char *buf, int32_t len) { + HttpContext *pContext = parser->pContext; const char *p = buf; int32_t ret = 0; int32_t i = 0; while (i < len) { int32_t again = 0; - ret = httpParseChar(pContext, parser, *p, &again); + ret = httpParseChar(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; @@ -906,27 +1123,3 @@ int32_t httpParserBuf(HttpContext *pContext, HttpParserObj *parser, const char * return ret; } - -void httpParserCleanupString(HttpParserString *str) { - free(str->str); - str->str = NULL; - str->len = 0; -} - -int32_t httpParserAppendString(HttpParserString *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); - p[n+len] = '\0'; - str->str = p; - str->len = n+len; - return 0; -} - -void httpParserClearString(HttpParserString *str) { - if (str->str) { - str->str[0] = '\0'; - str->len = 0; - } -} diff --git a/src/plugins/http/src/httpQueue.c b/src/plugins/http/src/httpQueue.c index 9625102f7450daf409d35aa532267f3f999d80ab..76632eb508b781af60b9b855b5bf1c92fa686dba 100644 --- a/src/plugins/http/src/httpQueue.c +++ b/src/plugins/http/src/httpQueue.c @@ -39,15 +39,15 @@ typedef struct { typedef struct { void *param; void *result; - int numOfRows; - void (*fp)(void *param, void *result, int numOfRows); + int32_t numOfRows; + void (*fp)(void *param, void *result, int32_t numOfRows); } SHttpResult; static SHttpWorkerPool tsHttpPool; static taos_qset tsHttpQset; static taos_queue tsHttpQueue; -void httpDispatchToResultQueue(void *param, TAOS_RES *result, int numOfRows, void (*fp)(void *param, void *result, int numOfRows)) { +void httpDispatchToResultQueue(void *param, TAOS_RES *result, int32_t numOfRows, void (*fp)(void *param, void *result, int32_t numOfRows)) { if (tsHttpQueue != NULL) { SHttpResult *pMsg = (SHttpResult *)taosAllocateQitem(sizeof(SHttpResult)); pMsg->param = param; diff --git a/src/plugins/http/src/httpResp.c b/src/plugins/http/src/httpResp.c index a7c17dfdbb006f18be8433ac9e905c19047363d4..def8ecf5e1025709884d82e3f629075ec22a5001 100644 --- a/src/plugins/http/src/httpResp.c +++ b/src/plugins/http/src/httpResp.c @@ -45,23 +45,23 @@ const char *httpRespTemplate[] = { "%s 200 OK\r\nAccess-Control-Allow-Origin:*\r\n%sAccess-Control-Allow-Methods:POST, GET, OPTIONS, DELETE, PUT\r\nAccess-Control-Allow-Headers:Accept, Content-Type\r\nContent-Type: application/json;charset=utf-8\r\nContent-Length: %d\r\n\r\n" }; -static void httpSendErrorRespImp(HttpContext *pContext, int httpCode, char *httpCodeStr, int errNo, char *desc) { +static void httpSendErrorRespImp(HttpContext *pContext, int32_t httpCode, char *httpCodeStr, int32_t errNo, char *desc) { httpError("context:%p, fd:%d, code:%d, error:%s", pContext, pContext->fd, httpCode, desc); char head[512] = {0}; char body[512] = {0}; - int bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_ERROR], errNo, desc); - int headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_ERROR], httpVersionStr[pContext->httpVersion], httpCode, - httpCodeStr, httpKeepAliveStr[pContext->httpKeepAlive], bodyLen); + int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_ERROR], errNo, desc); + int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_ERROR], httpVersionStr[pContext->parser->httpVersion], + httpCode, httpCodeStr, httpKeepAliveStr[pContext->parser->keepAlive], bodyLen); httpWriteBuf(pContext, head, headLen); httpWriteBuf(pContext, body, bodyLen); httpCloseContextByApp(pContext); } -void httpSendErrorRespWithDesc(HttpContext *pContext, int errNo, char *desc) { - int httpCode = 500; +void httpSendErrorRespWithDesc(HttpContext *pContext, int32_t errNo, char *desc) { + int32_t httpCode = 500; char *httpCodeStr = "Internal Server Error"; switch (errNo) { case HTTP_SUCCESS: @@ -180,20 +180,20 @@ void httpSendErrorRespWithDesc(HttpContext *pContext, int errNo, char *desc) { } } -void httpSendErrorResp(HttpContext *pContext, int errNo) { httpSendErrorRespWithDesc(pContext, errNo, NULL); } +void httpSendErrorResp(HttpContext *pContext, int32_t errNo) { httpSendErrorRespWithDesc(pContext, errNo, NULL); } -void httpSendTaosdErrorResp(HttpContext *pContext, int errCode) { - int httpCode = 400; +void httpSendTaosdErrorResp(HttpContext *pContext, int32_t errCode) { + int32_t httpCode = 400; httpSendErrorRespImp(pContext, httpCode, "Bad Request", errCode & 0XFFFF, (char*)tstrerror(errCode)); } -void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char* errMsg) { - int httpCode = 400; - char temp[512] = {0}; - int len = sprintf(temp, "invalid SQL: %s", errMsg); +void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char *errMsg) { + int32_t httpCode = 400; + char temp[512] = {0}; + int32_t len = sprintf(temp, "invalid SQL: %s", errMsg); - for (int i = 0; i < len; ++i) { + for (int32_t i = 0; i < len; ++i) { if (temp[i] == '\"') { temp[i] = '\''; } else if (temp[i] == '\n') { @@ -208,9 +208,9 @@ void httpSendSuccResp(HttpContext *pContext, char *desc) { char head[1024] = {0}; char body[1024] = {0}; - int bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], HTTP_SUCCESS, desc); - int headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OK], httpVersionStr[pContext->httpVersion], - httpKeepAliveStr[pContext->httpKeepAlive], bodyLen); + int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], HTTP_SUCCESS, desc); + int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OK], httpVersionStr[pContext->parser->httpVersion], + httpKeepAliveStr[pContext->parser->keepAlive], bodyLen); httpWriteBuf(pContext, head, headLen); httpWriteBuf(pContext, body, bodyLen); @@ -221,9 +221,9 @@ void httpSendOptionResp(HttpContext *pContext, char *desc) { char head[1024] = {0}; char body[1024] = {0}; - int bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], HTTP_SUCCESS, desc); - int headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OPTIONS], httpVersionStr[pContext->httpVersion], - httpKeepAliveStr[pContext->httpKeepAlive], bodyLen); + int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], HTTP_SUCCESS, desc); + int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OPTIONS], httpVersionStr[pContext->parser->httpVersion], + httpKeepAliveStr[pContext->parser->keepAlive], bodyLen); httpWriteBuf(pContext, head, headLen); httpWriteBuf(pContext, body, bodyLen); diff --git a/src/plugins/http/src/httpRestHandle.c b/src/plugins/http/src/httpRestHandle.c index b285b19c3f63466e792815092a6c82875afb61e5..fbdce566f0fbe803df8978a999430b220a0864fa 100644 --- a/src/plugins/http/src/httpRestHandle.c +++ b/src/plugins/http/src/httpRestHandle.c @@ -60,22 +60,22 @@ void restInitHandle(HttpServer* pServer) { } bool restGetUserFromUrl(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - if (pParser->path[REST_USER_URL_POS].len >= TSDB_USER_LEN || pParser->path[REST_USER_URL_POS].len <= 0) { + HttpParser* pParser = pContext->parser; + if (pParser->path[REST_USER_URL_POS].pos >= TSDB_USER_LEN || pParser->path[REST_USER_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->user, pParser->path[REST_USER_URL_POS].pos, TSDB_USER_LEN); + tstrncpy(pContext->user, pParser->path[REST_USER_URL_POS].str, TSDB_USER_LEN); return true; } bool restGetPassFromUrl(HttpContext* pContext) { - HttpParser* pParser = &pContext->parser; - if (pParser->path[REST_PASS_URL_POS].len >= TSDB_PASSWORD_LEN || pParser->path[REST_PASS_URL_POS].len <= 0) { + HttpParser* pParser = pContext->parser; + if (pParser->path[REST_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[REST_PASS_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->pass, pParser->path[REST_PASS_URL_POS].pos, TSDB_PASSWORD_LEN); + tstrncpy(pContext->pass, pParser->path[REST_PASS_URL_POS].str, TSDB_PASSWORD_LEN); return true; } @@ -85,10 +85,10 @@ bool restProcessLoginRequest(HttpContext* pContext) { return true; } -bool restProcessSqlRequest(HttpContext* pContext, int timestampFmt) { +bool restProcessSqlRequest(HttpContext* pContext, int32_t timestampFmt) { httpDebug("context:%p, fd:%d, user:%s, process restful sql msg", pContext, pContext->fd, pContext->user); - char* sql = pContext->parser.data.pos; + char* sql = pContext->parser->body.str; if (sql == NULL) { httpSendErrorResp(pContext, HTTP_NO_SQL_INPUT); return false; diff --git a/src/plugins/http/src/httpRestJson.c b/src/plugins/http/src/httpRestJson.c index c16727faa061ee822e86545c43e25814bbddb1a7..26f04415196a0f93c8fe893ce71a7d704949923c 100644 --- a/src/plugins/http/src/httpRestJson.c +++ b/src/plugins/http/src/httpRestJson.c @@ -21,7 +21,7 @@ #include "httpRestHandle.h" #include "httpRestJson.h" -void restBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int affect_rows) { +void restBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int32_t affect_rows) { JsonBuf *jsonBuf = httpMallocJsonBuf(pContext); if (jsonBuf == NULL) return; @@ -43,7 +43,7 @@ void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) if (jsonBuf == NULL) return; TAOS_FIELD *fields = taos_fetch_fields(result); - int num_fields = taos_num_fields(result); + int32_t num_fields = taos_num_fields(result); httpInitJsonBuf(jsonBuf, pContext); httpWriteJsonBufHead(jsonBuf); @@ -66,9 +66,9 @@ void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) httpJsonItemToken(jsonBuf); httpJsonString(jsonBuf, REST_JSON_AFFECT_ROWS, REST_JSON_AFFECT_ROWS_LEN); } else { - for (int i = 0; i < num_fields; ++i) { + for (int32_t i = 0; i < num_fields; ++i) { httpJsonItemToken(jsonBuf); - httpJsonString(jsonBuf, fields[i].name, (int)strlen(fields[i].name)); + httpJsonString(jsonBuf, fields[i].name, (int32_t)strlen(fields[i].name)); } } @@ -83,16 +83,16 @@ void restStartSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) httpJsonToken(jsonBuf, JsonArrStt); } -bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows, int timestampFormat) { +bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows, int32_t timestampFormat) { JsonBuf *jsonBuf = httpMallocJsonBuf(pContext); if (jsonBuf == NULL) return false; cmd->numOfRows += numOfRows; - int num_fields = taos_num_fields(result); + int32_t num_fields = taos_num_fields(result); TAOS_FIELD *fields = taos_fetch_fields(result); - for (int k = 0; k < numOfRows; ++k) { + for (int32_t k = 0; k < numOfRows; ++k) { TAOS_ROW row = taos_fetch_row(result); if (row == NULL) { cmd->numOfRows--; @@ -104,7 +104,7 @@ bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, httpJsonItemToken(jsonBuf); httpJsonToken(jsonBuf, JsonArrStt); - for (int i = 0; i < num_fields; i++) { + for (int32_t i = 0; i < num_fields; i++) { httpJsonItemToken(jsonBuf); if (row[i] == NULL) { @@ -171,15 +171,15 @@ bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, } } -bool restBuildSqlTimestampJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows) { +bool restBuildSqlTimestampJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows) { return restBuildSqlJson(pContext,cmd, result, numOfRows, REST_TIMESTAMP_FMT_TIMESTAMP); } -bool restBuildSqlLocalTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows) { +bool restBuildSqlLocalTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows) { return restBuildSqlJson(pContext,cmd, result, numOfRows, REST_TIMESTAMP_FMT_LOCAL_STRING); } -bool restBuildSqlUtcTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int numOfRows) { +bool restBuildSqlUtcTimeStringJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result, int32_t numOfRows) { return restBuildSqlJson(pContext,cmd, result, numOfRows, REST_TIMESTAMP_FMT_UTC_STRING); } diff --git a/src/plugins/http/src/httpServer.c b/src/plugins/http/src/httpServer.c index e0d2a90994cb933c109900baba24c938ee61985c..212ce464734c6c61782e9eea1157949de8613d5c 100644 --- a/src/plugins/http/src/httpServer.c +++ b/src/plugins/http/src/httpServer.c @@ -61,7 +61,7 @@ void httpCleanUpConnect() { if (pServer->pThreads == NULL) return; pthread_join(pServer->thread, NULL); - for (int i = 0; i < pServer->numOfThreads; ++i) { + for (int32_t i = 0; i < pServer->numOfThreads; ++i) { HttpThread* pThread = pServer->pThreads + i; if (pThread != NULL) { httpStopThread(pThread); @@ -71,41 +71,11 @@ void httpCleanUpConnect() { httpDebug("http server:%s is cleaned up", pServer->label); } -static bool httpDecompressData(HttpContext *pContext) { - if (pContext->contentEncoding != HTTP_COMPRESS_GZIP) { - httpTraceL("context:%p, fd:%d, content:%s", pContext, pContext->fd, pContext->parser.data.pos); - return true; - } - - char *decompressBuf = calloc(HTTP_DECOMPRESS_BUF_SIZE, 1); - int32_t decompressBufLen = HTTP_DECOMPRESS_BUF_SIZE; - size_t bufsize = sizeof(pContext->parser.buffer) - (pContext->parser.data.pos - pContext->parser.buffer) - 1; - if (decompressBufLen > (int)bufsize) { - decompressBufLen = (int)bufsize; - } - - int ret = httpGzipDeCompress(pContext->parser.data.pos, pContext->parser.data.len, decompressBuf, &decompressBufLen); - - if (ret == 0) { - memcpy(pContext->parser.data.pos, decompressBuf, decompressBufLen); - pContext->parser.data.pos[decompressBufLen] = 0; - httpTraceL("context:%p, fd:%d, rawSize:%d, decompressSize:%d, content:%s", pContext, pContext->fd, - pContext->parser.data.len, decompressBufLen, decompressBuf); - pContext->parser.data.len = decompressBufLen; - } else { - httpError("context:%p, fd:%d, failed to decompress data, rawSize:%d, error:%d", pContext, pContext->fd, - pContext->parser.data.len, ret); - } - - free(decompressBuf); - return ret == 0; -} - static void httpProcessHttpData(void *param) { HttpServer *pServer = &tsHttpServer; HttpThread *pThread = (HttpThread *)param; HttpContext *pContext; - int fdNum; + int32_t fdNum; sigset_t set; sigemptyset(&set); @@ -122,7 +92,7 @@ static void httpProcessHttpData(void *param) { } if (fdNum <= 0) continue; - for (int i = 0; i < fdNum; ++i) { + for (int32_t i = 0; i < fdNum; ++i) { pContext = httpGetContext(events[i].data.ptr); if (pContext == NULL) { httpError("context:%p, is already released, close connect", events[i].data.ptr); @@ -182,13 +152,13 @@ static void httpProcessHttpData(void *param) { } static void *httpAcceptHttpConnection(void *arg) { - int connFd = -1; + int32_t connFd = -1; struct sockaddr_in clientAddr; - int threadId = 0; + int32_t threadId = 0; HttpServer * pServer = &tsHttpServer; HttpThread * pThread = NULL; HttpContext * pContext = NULL; - int totalFds = 0; + int32_t totalFds = 0; sigset_t set; sigemptyset(&set); @@ -208,7 +178,7 @@ static void *httpAcceptHttpConnection(void *arg) { while (1) { socklen_t addrlen = sizeof(clientAddr); - connFd = (int)accept(pServer->fd, (struct sockaddr *)&clientAddr, &addrlen); + connFd = (int32_t)accept(pServer->fd, (struct sockaddr *)&clientAddr, &addrlen); if (connFd == -1) { if (errno == EINVAL) { httpDebug("http server:%s socket was shutdown, exiting...", pServer->label); @@ -219,7 +189,7 @@ static void *httpAcceptHttpConnection(void *arg) { } totalFds = 1; - for (int i = 0; i < pServer->numOfThreads; ++i) { + for (int32_t i = 0; i < pServer->numOfThreads; ++i) { totalFds += pServer->pThreads[i].numOfContexts; } @@ -283,7 +253,7 @@ bool httpInitConnect() { } HttpThread *pThread = pServer->pThreads; - for (int i = 0; i < pServer->numOfThreads; ++i) { + for (int32_t i = 0; i < pServer->numOfThreads; ++i) { sprintf(pThread->label, "%s%d", pServer->label, i); pThread->processData = pServer->processData; pThread->threadId = i; @@ -331,52 +301,39 @@ bool httpInitConnect() { } static bool httpReadData(HttpContext *pContext) { - HttpParser *pParser = &pContext->parser; - ASSERT(!pContext->parsed); - - if (!pParser->parser) { - if (!pParser->inited) { - httpInitContext(pContext); - } - if (!pParser->parser) { - return false; - } + HttpParser *pParser = pContext->parser; + ASSERT(!pParser->parsed); + if (!pParser->inited) { + httpInitParser(pParser); } pContext->accessTimes++; pContext->lastAccessTime = taosGetTimestampSec(); - char buf[HTTP_STEP_SIZE + 1] = {0}; - int nread = (int)taosReadSocket(pContext->fd, buf, sizeof(buf)); + char buf[HTTP_STEP_SIZE + 1] = {0}; + int32_t nread = (int32_t)taosReadSocket(pContext->fd, buf, sizeof(buf)); if (nread > 0) { buf[nread] = '\0'; httpTrace("context:%p, fd:%d, nread:%d content:%s", pContext, pContext->fd, nread, buf); - int ok = httpParserBuf(pContext, pParser->parser, buf, nread); + int32_t ok = httpParseBuf(pParser, buf, nread); if (ok) { - httpError("context:%p, fd:%d, init parse failed, reason:%d close connect", pContext, pContext->fd, ok); + httpError("context:%p, fd:%d, parse failed, ret:%d code:%d close connect", pContext, pContext->fd, ok, pParser->parseCode); httpNotifyContextClose(pContext); return false; } - if (pContext->parser.failed) { - httpError("context:%p, fd:%d, parse failed, close connect", pContext, pContext->fd); + if (pParser->parseCode) { + httpError("context:%p, fd:%d, parse failed, code:%d close connect", pContext, pContext->fd, pParser->parseCode); httpNotifyContextClose(pContext); return false; } - if (pContext->parsed) { - httpDebug("context:%p, fd:%d, read size:%d, dataLen:%d", pContext, pContext->fd, pContext->parser.bufsize, - pContext->parser.data.len); - if (httpDecompressData(pContext)) { - return true; - } else { - httpNotifyContextClose(pContext); - return false; - } + if (pParser->parsed) { + httpDebug("context:%p, fd:%d, len:%d, body:%s", pContext, pContext->fd, pParser->body.pos, pParser->body.str); } - return pContext->parsed; + return true; } else if (nread < 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { httpDebug("context:%p, fd:%d, read from socket error:%d, wait another event", pContext, pContext->fd, errno); diff --git a/src/plugins/http/src/httpSystem.c b/src/plugins/http/src/httpSystem.c index ee43b3c826d2a4f2ab6dc725ae6ae795a12de428..8993b233dd1dde9283679d337845d42f5d649715 100644 --- a/src/plugins/http/src/httpSystem.c +++ b/src/plugins/http/src/httpSystem.c @@ -37,9 +37,9 @@ void opInitHandle(HttpServer* pServer) {} #endif HttpServer tsHttpServer; -void taosInitNote(int numOfNoteLines, int maxNotes, char* lable); +void taosInitNote(int32_t numOfNoteLines, int32_t maxNotes, char* lable); -int httpInitSystem() { +int32_t httpInitSystem() { strcpy(tsHttpServer.label, "rest"); tsHttpServer.serverIp = 0; tsHttpServer.serverPort = tsHttpPort; @@ -60,7 +60,7 @@ int httpInitSystem() { return 0; } -int httpStartSystem() { +int32_t httpStartSystem() { httpInfo("start http server ..."); if (tsHttpServer.status != HTTP_SERVER_INIT) { diff --git a/src/plugins/http/src/httpTgHandle.c b/src/plugins/http/src/httpTgHandle.c index a7444676ae529c5d3091180186f679c3cb681e51..83b31f652b43feec137b812b598eea4d5400f49f 100644 --- a/src/plugins/http/src/httpTgHandle.c +++ b/src/plugins/http/src/httpTgHandle.c @@ -83,16 +83,16 @@ static const char DEFAULT_TELEGRAF_CFG[] = "]}"; typedef struct { - char *name; - char *tbName; - char **fields; - int fieldNum; + char * name; + char * tbName; + char ** fields; + int32_t fieldNum; } STgSchema; typedef struct { STgSchema *schemas; - int size; - int pos; + int32_t size; + int32_t pos; } STgSchemas; static STgSchemas tgSchemas = {0}; @@ -107,7 +107,7 @@ void tgFreeSchema(STgSchema *schema) { schema->tbName = NULL; } if (schema->fields != NULL) { - for (int f = 0; f < schema->fieldNum; ++f) { + for (int32_t f = 0; f < schema->fieldNum; ++f) { if (schema->fields[f] != NULL) { free(schema->fields[f]); schema->fields[f] = NULL; @@ -121,7 +121,7 @@ void tgFreeSchema(STgSchema *schema) { void tgFreeSchemas() { if (tgSchemas.schemas != NULL) { - for (int s = 0; s < tgSchemas.size; ++s) { + for (int32_t s = 0; s < tgSchemas.size; ++s) { tgFreeSchema(&tgSchemas.schemas[s]); } free(tgSchemas.schemas); @@ -130,7 +130,7 @@ void tgFreeSchemas() { } } -void tgInitSchemas(int size) { +void tgInitSchemas(int32_t size) { tgFreeSchemas(); tgSchemas.schemas = calloc(sizeof(STgSchema), size); tgSchemas.size = 0; @@ -154,7 +154,7 @@ void tgParseSchemaMetric(cJSON *metric) { parsedOk = false; goto ParseEnd; } - int nameLen = (int)strlen(name->valuestring); + int32_t nameLen = (int32_t)strlen(name->valuestring); if (nameLen == 0) { parsedOk = false; goto ParseEnd; @@ -177,7 +177,7 @@ void tgParseSchemaMetric(cJSON *metric) { parsedOk = false; goto ParseEnd; } - int tbnameLen = (int)strlen(tbname->valuestring); + int32_t tbnameLen = (int32_t)strlen(tbname->valuestring); if (tbnameLen == 0) { parsedOk = false; goto ParseEnd; @@ -191,7 +191,7 @@ void tgParseSchemaMetric(cJSON *metric) { if (fields == NULL) { goto ParseEnd; } - int fieldSize = cJSON_GetArraySize(fields); + int32_t fieldSize = cJSON_GetArraySize(fields); if (fieldSize <= 0 || fieldSize > TSDB_MAX_COLUMNS) { goto ParseEnd; } @@ -199,7 +199,7 @@ void tgParseSchemaMetric(cJSON *metric) { if (fieldSize > 0) { schema.fields = calloc(sizeof(STgSchema), (size_t)fieldSize); schema.fieldNum = fieldSize; - for (int i = 0; i < fieldSize; i++) { + for (int32_t i = 0; i < fieldSize; i++) { cJSON *field = cJSON_GetArrayItem(fields, i); if (field == NULL) { parsedOk = false; @@ -209,7 +209,7 @@ void tgParseSchemaMetric(cJSON *metric) { parsedOk = false; goto ParseEnd; } - int nameLen = (int)strlen(field->valuestring); + int32_t nameLen = (int32_t)strlen(field->valuestring); if (nameLen == 0 || nameLen >= TSDB_TABLE_NAME_LEN) { parsedOk = false; goto ParseEnd; @@ -227,13 +227,13 @@ ParseEnd: } } -int tgParseSchema(const char *content, char*fileName) { +int32_t tgParseSchema(const char *content, char*fileName) { cJSON *root = cJSON_Parse(content); if (root == NULL) { httpError("failed to parse telegraf schema file:%s, invalid json format, content:%s", fileName, content); return -1; } - int size = 0; + int32_t size = 0; cJSON *metrics = cJSON_GetObjectItem(root, "metrics"); if (metrics != NULL) { size = cJSON_GetArraySize(metrics); @@ -244,7 +244,7 @@ int tgParseSchema(const char *content, char*fileName) { } tgInitSchemas(size); - for (int i = 0; i < size; i++) { + for (int32_t i = 0; i < size; i++) { cJSON *metric = cJSON_GetArrayItem(metrics, i); if (metric != NULL) { tgParseSchemaMetric(metric); @@ -260,7 +260,7 @@ int tgParseSchema(const char *content, char*fileName) { return size; } -int tgReadSchema(char *fileName) { +int32_t tgReadSchema(char *fileName) { FILE *fp = fopen(fileName, "r"); if (fp == NULL) { return -1; @@ -286,7 +286,7 @@ int tgReadSchema(char *fileName) { } content[contentSize] = 0; - int schemaNum = tgParseSchema(content, fileName); + int32_t schemaNum = tgParseSchema(content, fileName); free(content); fclose(fp); @@ -313,53 +313,53 @@ void tgCleanupHandle() { } bool tgGetUserFromUrl(HttpContext *pContext) { - HttpParser *pParser = &pContext->parser; - if (pParser->path[TG_USER_URL_POS].len >= TSDB_USER_LEN || pParser->path[TG_USER_URL_POS].len <= 0) { + HttpParser *pParser = pContext->parser; + if (pParser->path[TG_USER_URL_POS].pos >= TSDB_USER_LEN || pParser->path[TG_USER_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->user, pParser->path[TG_USER_URL_POS].pos, sizeof(pContext->user)); + tstrncpy(pContext->user, pParser->path[TG_USER_URL_POS].str, sizeof(pContext->user)); return true; } bool tgGetPassFromUrl(HttpContext *pContext) { - HttpParser *pParser = &pContext->parser; - if (pParser->path[TG_PASS_URL_POS].len >= TSDB_PASSWORD_LEN || pParser->path[TG_PASS_URL_POS].len <= 0) { + HttpParser *pParser = pContext->parser; + if (pParser->path[TG_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[TG_PASS_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->pass, pParser->path[TG_PASS_URL_POS].pos, sizeof(pContext->pass)); + tstrncpy(pContext->pass, pParser->path[TG_PASS_URL_POS].str, sizeof(pContext->pass)); return true; } char *tgGetDbFromUrl(HttpContext *pContext) { - HttpParser *pParser = &pContext->parser; - if (pParser->path[TG_DB_URL_POS].len <= 0) { + HttpParser *pParser = pContext->parser; + if (pParser->path[TG_DB_URL_POS].pos <= 0) { httpSendErrorResp(pContext, HTTP_TG_DB_NOT_INPUT); return NULL; } - if (pParser->path[TG_DB_URL_POS].len >= TSDB_DB_NAME_LEN) { + if (pParser->path[TG_DB_URL_POS].pos >= TSDB_DB_NAME_LEN) { httpSendErrorResp(pContext, HTTP_TG_DB_TOO_LONG); return NULL; } - return pParser->path[TG_DB_URL_POS].pos; + return pParser->path[TG_DB_URL_POS].str; } -char *tgGetStableName(char *stname, cJSON *fields, int fieldsSize) { - for (int s = 0; s < tgSchemas.size; ++s) { +char *tgGetStableName(char *stname, cJSON *fields, int32_t fieldsSize) { + for (int32_t s = 0; s < tgSchemas.size; ++s) { STgSchema *schema = &tgSchemas.schemas[s]; if (strcasecmp(schema->name, stname) != 0) { continue; } bool schemaMatched = true; - for (int f = 0; f < schema->fieldNum; ++f) { + for (int32_t f = 0; f < schema->fieldNum; ++f) { char *fieldName = schema->fields[f]; bool fieldMatched = false; - for (int i = 0; i < fieldsSize; i++) { + for (int32_t i = 0; i < fieldsSize; i++) { cJSON *field = cJSON_GetArrayItem(fields, i); if (strcasecmp(field->string, fieldName) == 0) { fieldMatched = true; @@ -412,7 +412,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { httpSendErrorResp(pContext, HTTP_TG_METRIC_NAME_NULL); return false; } - int nameLen = (int)strlen(name->valuestring); + int32_t nameLen = (int32_t)strlen(name->valuestring); if (nameLen == 0) { httpSendErrorResp(pContext, HTTP_TG_METRIC_NAME_NULL); return false; @@ -444,7 +444,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { return false; } - int tagsSize = cJSON_GetArraySize(tags); + int32_t tagsSize = cJSON_GetArraySize(tags); if (tagsSize <= 0) { httpSendErrorResp(pContext, HTTP_TG_TAGS_SIZE_0); return false; @@ -457,7 +457,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { cJSON *host = NULL; - for (int i = 0; i < tagsSize; i++) { + for (int32_t i = 0; i < tagsSize; i++) { cJSON *tag = cJSON_GetArrayItem(tags, i); if (tag == NULL) { httpSendErrorResp(pContext, HTTP_TG_TAG_NULL); @@ -518,7 +518,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { return false; } - int fieldsSize = cJSON_GetArraySize(fields); + int32_t fieldsSize = cJSON_GetArraySize(fields); if (fieldsSize <= 0) { httpSendErrorResp(pContext, HTTP_TG_FIELDS_SIZE_0); return false; @@ -529,7 +529,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { return false; } - for (int i = 0; i < fieldsSize; i++) { + for (int32_t i = 0; i < fieldsSize; i++) { cJSON *field = cJSON_GetArrayItem(fields, i); if (field == NULL) { httpSendErrorResp(pContext, HTTP_TG_FIELD_NULL); @@ -579,11 +579,11 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { // order by tag name cJSON *orderedTags[TG_MAX_SORT_TAG_SIZE] = {0}; - int orderTagsLen = 0; - for (int i = 0; i < tagsSize; ++i) { + int32_t orderTagsLen = 0; + for (int32_t i = 0; i < tagsSize; ++i) { cJSON *tag = cJSON_GetArrayItem(tags, i); orderedTags[orderTagsLen++] = tag; - for (int j = orderTagsLen - 1; j >= 1; --j) { + for (int32_t j = orderTagsLen - 1; j >= 1; --j) { cJSON *tag1 = orderedTags[j]; cJSON *tag2 = orderedTags[j - 1]; if (strcasecmp(tag1->string, "host") == 0 || strcmp(tag1->string, tag2->string) < 0) { @@ -609,7 +609,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { httpShrinkTableName(pContext, table_cmd->stable, httpGetCmdsString(pContext, table_cmd->stable)); // stable tag for detail - for (int i = 0; i < orderTagsLen; ++i) { + for (int32_t i = 0; i < orderTagsLen; ++i) { cJSON *tag = orderedTags[i]; stable_cmd->tagNames[i] = table_cmd->tagNames[i] = httpAddToSqlCmdBuffer(pContext, tag->string); @@ -631,7 +631,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { } else { table_cmd->table = stable_cmd->table = httpAddToSqlCmdBufferNoTerminal(pContext, "%s_%d_%d_%s", stname, fieldsSize, orderTagsLen, host->valuestring); } - for (int i = 0; i < orderTagsLen; ++i) { + for (int32_t i = 0; i < orderTagsLen; ++i) { cJSON *tag = orderedTags[i]; if (tag == host) continue; if (tag->type == cJSON_String) @@ -653,7 +653,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { // assembling create stable sql stable_cmd->sql = httpAddToSqlCmdBufferNoTerminal(pContext, "create table if not exists %s.%s(ts timestamp", db, httpGetCmdsString(pContext, table_cmd->stable)); - for (int i = 0; i < fieldsSize; ++i) { + for (int32_t i = 0; i < fieldsSize; ++i) { cJSON *field = cJSON_GetArrayItem(fields, i); char * field_type = "double"; if (field->type == cJSON_String) @@ -668,7 +668,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { } httpAddToSqlCmdBufferNoTerminal(pContext, ") tags("); - for (int i = 0; i < orderTagsLen; ++i) { + for (int32_t i = 0; i < orderTagsLen; ++i) { cJSON *tag = orderedTags[i]; char * tag_type = "bigint"; if (tag->type == cJSON_String) @@ -689,7 +689,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { table_cmd->sql = httpAddToSqlCmdBufferNoTerminal(pContext, "import into %s.%s using %s.%s tags(", db, httpGetCmdsString(pContext, table_cmd->table), db, httpGetCmdsString(pContext, table_cmd->stable)); - for (int i = 0; i < orderTagsLen; ++i) { + for (int32_t i = 0; i < orderTagsLen; ++i) { cJSON *tag = orderedTags[i]; if (i != orderTagsLen - 1) { if (tag->type == cJSON_Number) @@ -719,7 +719,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { } httpAddToSqlCmdBufferNoTerminal(pContext, " values(%" PRId64 ",", timestamp->valueint); - for (int i = 0; i < fieldsSize; ++i) { + for (int32_t i = 0; i < fieldsSize; ++i) { cJSON *field = cJSON_GetArrayItem(fields, i); if (i != fieldsSize - 1) { if (field->type == cJSON_Number) @@ -802,8 +802,7 @@ bool tgProcessSingleMetric(HttpContext *pContext, cJSON *metric, char *db) { bool tgProcessQueryRequest(HttpContext *pContext, char *db) { httpDebug("context:%p, fd:%d, process telegraf query msg", pContext, pContext->fd); - HttpParser *pParser = &pContext->parser; - char * filter = pParser->data.pos; + char *filter = pContext->parser->body.str; if (filter == NULL) { httpSendErrorResp(pContext, HTTP_NO_MSG_INPUT); return false; @@ -817,7 +816,7 @@ bool tgProcessQueryRequest(HttpContext *pContext, char *db) { cJSON *metrics = cJSON_GetObjectItem(root, "metrics"); if (metrics != NULL) { - int size = cJSON_GetArraySize(metrics); + int32_t size = cJSON_GetArraySize(metrics); httpDebug("context:%p, fd:%d, multiple metrics:%d at one time", pContext, pContext->fd, size); if (size <= 0) { httpSendErrorResp(pContext, HTTP_TG_METRICS_NULL); @@ -825,7 +824,7 @@ bool tgProcessQueryRequest(HttpContext *pContext, char *db) { return false; } - int cmdSize = size * 2 + 1; + int32_t cmdSize = size * 2 + 1; if (cmdSize > HTTP_MAX_CMD_SIZE) { httpSendErrorResp(pContext, HTTP_TG_METRICS_SIZE); cJSON_Delete(root); @@ -848,7 +847,7 @@ bool tgProcessQueryRequest(HttpContext *pContext, char *db) { cmd->cmdReturnType = HTTP_CMD_RETURN_TYPE_NO_RETURN; cmd->sql = httpAddToSqlCmdBuffer(pContext, "create database if not exists %s", db); - for (int i = 0; i < size; i++) { + for (int32_t i = 0; i < size; i++) { cJSON *metric = cJSON_GetArrayItem(metrics, i); if (metric != NULL) { if (!tgProcessSingleMetric(pContext, metric, db)) { diff --git a/src/plugins/http/src/httpTgJson.c b/src/plugins/http/src/httpTgJson.c index 5c6985cd69b26a85f1abcb9c73067c9e214f22c5..603092f09df96ae9bc9be2c0c4445d3d3f795ea1 100644 --- a/src/plugins/http/src/httpTgJson.c +++ b/src/plugins/http/src/httpTgJson.c @@ -61,19 +61,19 @@ void tgStartQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result) // data httpJsonItemToken(jsonBuf); httpJsonPair(jsonBuf, "metric", 6, httpGetCmdsString(pContext, cmd->stable), - (int)strlen(httpGetCmdsString(pContext, cmd->metric))); + (int32_t)strlen(httpGetCmdsString(pContext, cmd->metric))); httpJsonItemToken(jsonBuf); httpJsonPair(jsonBuf, "stable", 6, httpGetCmdsString(pContext, cmd->stable), - (int)strlen(httpGetCmdsString(pContext, cmd->stable))); + (int32_t)strlen(httpGetCmdsString(pContext, cmd->stable))); httpJsonItemToken(jsonBuf); httpJsonPair(jsonBuf, "table", 5, httpGetCmdsString(pContext, cmd->table), - (int)strlen(httpGetCmdsString(pContext, cmd->table))); + (int32_t)strlen(httpGetCmdsString(pContext, cmd->table))); httpJsonItemToken(jsonBuf); httpJsonPair(jsonBuf, "timestamp", 9, httpGetCmdsString(pContext, cmd->timestamp), - (int)strlen(httpGetCmdsString(pContext, cmd->timestamp))); // hack way + (int32_t)strlen(httpGetCmdsString(pContext, cmd->timestamp))); // hack way } void tgStopQueryJson(HttpContext *pContext, HttpSqlCmd *cmd) { @@ -88,7 +88,7 @@ void tgStopQueryJson(HttpContext *pContext, HttpSqlCmd *cmd) { httpJsonToken(jsonBuf, JsonObjEnd); } -void tgBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int affect_rows) { +void tgBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int32_t affect_rows) { JsonBuf *jsonBuf = httpMallocJsonBuf(pContext); if (jsonBuf == NULL) return; @@ -96,7 +96,7 @@ void tgBuildSqlAffectRowsJson(HttpContext *pContext, HttpSqlCmd *cmd, int affect httpJsonPairIntVal(jsonBuf, "affected_rows", 13, affect_rows); } -bool tgCheckFinished(struct HttpContext *pContext, HttpSqlCmd *cmd, int code) { +bool tgCheckFinished(struct HttpContext *pContext, HttpSqlCmd *cmd, int32_t code) { HttpSqlCmds *multiCmds = pContext->multiCmds; httpDebug("context:%p, fd:%d, check telegraf command, code:%s, state:%d, type:%d, rettype:%d, tags:%d", pContext, pContext->fd, tstrerror(code), cmd->cmdState, cmd->cmdType, cmd->cmdReturnType, cmd->tagNum); @@ -133,7 +133,7 @@ bool tgCheckFinished(struct HttpContext *pContext, HttpSqlCmd *cmd, int code) { return true; } -void tgSetNextCmd(struct HttpContext *pContext, HttpSqlCmd *cmd, int code) { +void tgSetNextCmd(struct HttpContext *pContext, HttpSqlCmd *cmd, int32_t code) { HttpSqlCmds *multiCmds = pContext->multiCmds; httpDebug("context:%p, fd:%d, get telegraf next command, pos:%d, code:%s, state:%d, type:%d, rettype:%d, tags:%d", pContext, pContext->fd, multiCmds->pos, tstrerror(code), cmd->cmdState, cmd->cmdType, cmd->cmdReturnType, diff --git a/src/plugins/http/src/httpUtil.c b/src/plugins/http/src/httpUtil.c index f6e05dc1aeb3929c8a987db8dd04cf7d7dc19c99..2c8879f8804828fdd9de268ab1b6348df3a6b77c 100644 --- a/src/plugins/http/src/httpUtil.c +++ b/src/plugins/http/src/httpUtil.c @@ -29,7 +29,7 @@ bool httpCheckUsedbSql(char *sql) { return false; } -void httpTimeToString(time_t t, char *buf, int buflen) { +void httpTimeToString(time_t t, char *buf, int32_t buflen) { memset(buf, 0, (size_t)buflen); char ts[32] = {0}; @@ -44,13 +44,13 @@ int32_t httpAddToSqlCmdBuffer(HttpContext *pContext, const char *const format, . HttpSqlCmds *cmd = pContext->multiCmds; if (cmd->buffer == NULL) return -1; - int remainLength = cmd->bufferSize - cmd->bufferPos; + int32_t remainLength = cmd->bufferSize - cmd->bufferPos; if (remainLength < 4096) { if (!httpReMallocMultiCmdsBuffer(pContext, cmd->bufferSize * 2)) return -1; } - char *buffer = cmd->buffer + cmd->bufferPos; - int len = 0; + char * buffer = cmd->buffer + cmd->bufferPos; + int32_t len = 0; va_list argpointer; va_start(argpointer, format); @@ -76,13 +76,13 @@ int32_t httpAddToSqlCmdBufferNoTerminal(HttpContext *pContext, const char *const HttpSqlCmds *cmd = pContext->multiCmds; if (cmd->buffer == NULL) return -1; - int remainLength = cmd->bufferSize - cmd->bufferPos; + int32_t remainLength = cmd->bufferSize - cmd->bufferPos; if (remainLength < 4096) { if (!httpReMallocMultiCmdsBuffer(pContext, cmd->bufferSize * 2)) return -1; } - char *buffer = cmd->buffer + cmd->bufferPos; - int len = 0; + char * buffer = cmd->buffer + cmd->bufferPos; + int32_t len = 0; va_list argpointer; va_start(argpointer, format); @@ -107,7 +107,7 @@ int32_t httpAddToSqlCmdBufferTerminal(HttpContext *pContext) { HttpSqlCmds *cmd = pContext->multiCmds; if (cmd->buffer == NULL) return -1; - int remainLength = cmd->bufferSize - cmd->bufferPos; + int32_t remainLength = cmd->bufferSize - cmd->bufferPos; if (remainLength < 4096) { if (!httpReMallocMultiCmdsBuffer(pContext, cmd->bufferSize * 2)) return -1; } @@ -124,7 +124,7 @@ int32_t httpAddToSqlCmdBufferTerminal(HttpContext *pContext) { return (int32_t)(buffer - cmd->buffer); } -int32_t httpAddToSqlCmdBufferWithSize(HttpContext *pContext, int mallocSize) { +int32_t httpAddToSqlCmdBufferWithSize(HttpContext *pContext, int32_t mallocSize) { HttpSqlCmds *cmd = pContext->multiCmds; if (cmd->buffer == NULL) return -1; @@ -139,7 +139,7 @@ int32_t httpAddToSqlCmdBufferWithSize(HttpContext *pContext, int mallocSize) { return (int32_t)(buffer - cmd->buffer); } -bool httpMallocMultiCmds(HttpContext *pContext, int cmdSize, int bufferSize) { +bool httpMallocMultiCmds(HttpContext *pContext, int32_t cmdSize, int32_t bufferSize) { if (cmdSize > HTTP_MAX_CMD_SIZE) { httpError("context:%p, fd:%d, user:%s, mulitcmd size:%d large then %d", pContext, pContext->fd, pContext->user, cmdSize, HTTP_MAX_CMD_SIZE); @@ -186,7 +186,7 @@ bool httpMallocMultiCmds(HttpContext *pContext, int cmdSize, int bufferSize) { return true; } -bool httpReMallocMultiCmdsSize(HttpContext *pContext, int cmdSize) { +bool httpReMallocMultiCmdsSize(HttpContext *pContext, int32_t cmdSize) { HttpSqlCmds *multiCmds = pContext->multiCmds; if (cmdSize > HTTP_MAX_CMD_SIZE) { @@ -206,7 +206,7 @@ bool httpReMallocMultiCmdsSize(HttpContext *pContext, int cmdSize) { return true; } -bool httpReMallocMultiCmdsBuffer(HttpContext *pContext, int bufferSize) { +bool httpReMallocMultiCmdsBuffer(HttpContext *pContext, int32_t bufferSize) { HttpSqlCmds *multiCmds = pContext->multiCmds; if (bufferSize > HTTP_MAX_BUFFER_SIZE) { @@ -258,7 +258,7 @@ bool httpCompareMethod(HttpDecodeMethod *pSrc, HttpDecodeMethod *pCmp) { } void httpAddMethod(HttpServer *pServer, HttpDecodeMethod *pMethod) { - int pos = 0; + int32_t pos = 0; for (pos = 0; pos < pServer->methodScannerLen; ++pos) { if (httpCompareMethod(pServer->methodScanner[pos], pMethod)) { break; @@ -293,13 +293,13 @@ HttpSqlCmd *httpCurrSqlCmd(HttpContext *pContext) { return multiCmds->cmds + multiCmds->size - 1; } -int httpNextSqlCmdPos(HttpContext *pContext) { +int32_t httpNextSqlCmdPos(HttpContext *pContext) { HttpSqlCmds *multiCmds = pContext->multiCmds; return multiCmds->size; } void httpTrimTableName(char *name) { - for (int i = 0; name[i] != 0; i++) { + for (int32_t i = 0; name[i] != 0; i++) { if (name[i] == ' ' || name[i] == ':' || name[i] == '.' || name[i] == '-' || name[i] == '/' || name[i] == '\'') name[i] = '_'; if (i == TSDB_TABLE_NAME_LEN) { @@ -309,9 +309,9 @@ void httpTrimTableName(char *name) { } } -int httpShrinkTableName(HttpContext *pContext, int pos, char *name) { - int len = 0; - for (int i = 0; name[i] != 0; i++) { +int32_t httpShrinkTableName(HttpContext *pContext, int32_t pos, char *name) { + int32_t len = 0; + for (int32_t i = 0; name[i] != 0; i++) { if (name[i] == ' ' || name[i] == ':' || name[i] == '.' || name[i] == '-' || name[i] == '/' || name[i] == '\'' || name[i] == '\"') name[i] = '_'; @@ -327,7 +327,7 @@ int httpShrinkTableName(HttpContext *pContext, int pos, char *name) { MD5Update(&context, (uint8_t *)name, (uint32_t)len); MD5Final(&context); - int table_name = httpAddToSqlCmdBuffer( + int32_t table_name = httpAddToSqlCmdBuffer( pContext, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", context.digest[0], context.digest[1], context.digest[2], context.digest[3], context.digest[4], context.digest[5], context.digest[6], context.digest[7], context.digest[8], context.digest[9], context.digest[10], context.digest[11], @@ -340,7 +340,7 @@ int httpShrinkTableName(HttpContext *pContext, int pos, char *name) { return table_name; } -char *httpGetCmdsString(HttpContext *pContext, int pos) { +char *httpGetCmdsString(HttpContext *pContext, int32_t pos) { HttpSqlCmds *multiCmds = pContext->multiCmds; if (pos < 0 || pos >= multiCmds->bufferSize) { return ""; @@ -349,8 +349,8 @@ char *httpGetCmdsString(HttpContext *pContext, int pos) { return multiCmds->buffer + pos; } -int httpGzipDeCompress(char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData) { - int err = 0; +int32_t httpGzipDeCompress(char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData) { + int32_t err = 0; z_stream gzipStream = {0}; static char dummyHead[2] = { @@ -393,7 +393,7 @@ int httpGzipDeCompress(char *srcData, int32_t nSrcData, char *destData, int32_t return 0; } -int httpGzipCompressInit(HttpContext *pContext) { +int32_t httpGzipCompressInit(HttpContext *pContext) { pContext->gzipStream.zalloc = (alloc_func) 0; pContext->gzipStream.zfree = (free_func) 0; pContext->gzipStream.opaque = (voidpf) 0; @@ -404,8 +404,8 @@ int httpGzipCompressInit(HttpContext *pContext) { return 0; } -int httpGzipCompress(HttpContext *pContext, char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData, bool isTheLast) { - int err = 0; +int32_t httpGzipCompress(HttpContext *pContext, char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData, bool isTheLast) { + int32_t err = 0; pContext->gzipStream.next_in = (Bytef *) srcData; pContext->gzipStream.avail_in = (uLong) nSrcData; pContext->gzipStream.next_out = (Bytef *) destData; @@ -439,3 +439,21 @@ int httpGzipCompress(HttpContext *pContext, char *srcData, int32_t nSrcData, cha *nDestData = (int32_t) (pContext->gzipStream.total_out); return 0; } + +bool httpUrlMatch(HttpContext* pContext, int32_t pos, char* cmp) { + HttpParser* pParser = pContext->parser; + + if (pos < 0 || pos >= HTTP_MAX_URL) { + return false; + } + + if (pParser->path[pos].pos <= 0) { + return false; + } + + if (strcmp(pParser->path[pos].str, cmp) != 0) { + return false; + } + + return true; +}