#pragma once #include #include #include #include #include #include #include #include /* Copy from http_parser.h */ #define HTTP_METHOD_MAP(XX) \ XX(0, DELETE, DELETE) \ XX(1, GET, GET) \ XX(2, HEAD, HEAD) \ XX(3, POST, POST) \ XX(4, PUT, PUT) \ /* pathological */ \ XX(5, CONNECT, CONNECT) \ XX(6, OPTIONS, OPTIONS) \ XX(7, TRACE, TRACE) \ /* WebDAV */ \ XX(8, COPY, COPY) \ XX(9, LOCK, LOCK) \ XX(10, MKCOL, MKCOL) \ XX(11, MOVE, MOVE) \ XX(12, PROPFIND, PROPFIND) \ XX(13, PROPPATCH, PROPPATCH) \ XX(14, SEARCH, SEARCH) \ XX(15, UNLOCK, UNLOCK) \ XX(16, BIND, BIND) \ XX(17, REBIND, REBIND) \ XX(18, UNBIND, UNBIND) \ XX(19, ACL, ACL) \ /* subversion */ \ XX(20, REPORT, REPORT) \ XX(21, MKACTIVITY, MKACTIVITY) \ XX(22, CHECKOUT, CHECKOUT) \ XX(23, MERGE, MERGE) \ /* upnp */ \ XX(24, MSEARCH, M-SEARCH) \ XX(25, NOTIFY, NOTIFY) \ XX(26, SUBSCRIBE, SUBSCRIBE) \ XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ /* RFC-5789 */ \ XX(28, PATCH, PATCH) \ XX(29, PURGE, PURGE) \ /* CalDAV */ \ XX(30, MKCALENDAR, MKCALENDAR) \ /* RFC-2068, section 19.6.1.2 */ \ XX(31, LINK, LINK) \ XX(32, UNLINK, UNLINK) \ /* icecast */ \ XX(33, SOURCE, SOURCE) \ enum tfe_http_std_method { #define XX(num, name, string) TFE_HTTP_##name = num, HTTP_METHOD_MAP(XX) #undef XX }; enum tfe_http_std_field { TFE_HTTP_UNKNOWN_FIELD = 0, TFE_HTTP_HOST, TFE_HTTP_REFERER, TFE_HTTP_USER_AGENT, TFE_HTTP_COOKIE, TFE_HTTP_PROXY_AUTHORIZATION, TFE_HTTP_AUTHORIZATION, TFE_HTTP_LOCATION, TFE_HTTP_SERVER, TFE_HTTP_ETAG, TFE_HTTP_DATE, TFE_HTTP_TRAILER, TFE_HTTP_TRANSFER_ENCODING, TFE_HTTP_VIA, TFE_HTTP_PRAGMA, TFE_HTTP_CONNECTION, TFE_HTTP_CONT_ENCODING, TFE_HTTP_CONT_LANGUAGE, TFE_HTTP_CONT_LOCATION, TFE_HTTP_CONT_RANGE, TFE_HTTP_CONT_LENGTH, TFE_HTTP_CONT_TYPE, TFE_HTTP_CONT_DISPOSITION, TFE_HTTP_EXPIRES, TFE_HTTP_ACCEPT_ENCODING, }; enum http_ev_bit_number { REQ_HDR_BITNUM = 0, REQ_BODY_BEGIN_BITNUM, REQ_BODY_CONT_BITNUM, REQ_BODY_END_BITNUM, REQ_END_BITNUM, RESP_HDR_BITNUM, RESP_BODY_BEGIN_BITNUM, RESP_BODY_CONT_BITNUM, RESP_BODY_END_BITNUM, RESP_END_BITNUM }; enum tfe_http_event { EV_HTTP_REQ_HDR = 1ULL << REQ_HDR_BITNUM, EV_HTTP_REQ_BODY_BEGIN = 1ULL << REQ_BODY_BEGIN_BITNUM, EV_HTTP_REQ_BODY_CONT = 1ULL << REQ_BODY_CONT_BITNUM, EV_HTTP_REQ_BODY_END = 1ULL << REQ_BODY_END_BITNUM, EV_HTTP_REQ_END = 1ULL << REQ_END_BITNUM, EV_HTTP_RESP_HDR = 1ULL << RESP_HDR_BITNUM, EV_HTTP_RESP_BODY_BEGIN = 1ULL << RESP_BODY_BEGIN_BITNUM, EV_HTTP_RESP_BODY_CONT = 1ULL << RESP_BODY_CONT_BITNUM, EV_HTTP_RESP_BODY_END = 1ULL << RESP_BODY_END_BITNUM, EV_HTTP_RESP_END = 1ULL << RESP_END_BITNUM, }; struct tfe_http_req_spec { enum tfe_http_std_method method; const char * uri; const char * host; const char * url; //uri+host }; struct tfe_http_resp_spec { int resp_code; const char * content_encoding; }; enum tfe_http_direction { TFE_HTTP_REQUEST = 1, TFE_HTTP_RESPONSE = 2 }; struct tfe_http_half_ops { const char * (* ops_http_field_read)(const struct tfe_http_half *, const struct http_field_name *); int (* ops_http_field_write)(struct tfe_http_half *, const struct http_field_name *, const char *); struct tfe_http_half * (* ops_http_allow_write)(const struct tfe_http_half *); const char * (* ops_http_field_iterate)(const struct tfe_http_half *, void **, struct http_field_name *); int (* ops_append_body)(struct tfe_http_half *, char *, size_t, int); void (* ops_free)(struct tfe_http_half * half); }; struct tfe_http_session_ops { struct tfe_http_session * (* ops_allow_write)(const struct tfe_http_session * session); void (* ops_detach)(const struct tfe_http_session * session); void (* ops_drop)(struct tfe_http_session * session); void (* ops_request_set)(struct tfe_http_session * session, struct tfe_http_half * req); void (* ops_response_set)(struct tfe_http_session * session, struct tfe_http_half * resp); struct tfe_http_half * (* ops_request_create)(struct tfe_http_session * session, enum tfe_http_std_method method, const char * uri); struct tfe_http_half * (* ops_response_create)(struct tfe_http_session * session, int resp_code); }; struct tfe_http_half { enum tfe_http_direction direction; const struct tfe_http_half_ops * ops; short major_version; short minor_version; union { struct tfe_http_req_spec req_spec; struct tfe_http_resp_spec resp_spec; }; }; struct tfe_http_session { unsigned int session_id; struct tfe_http_session_ops * ops; struct tfe_http_half * req; struct tfe_http_half * resp; }; struct http_field_name { /* Standard Field */ enum tfe_http_std_field field_id; /* Non-NULL when field_id is HTTP_UNKNOWN_FIELD */ const char * field_name; }; typedef void (http_session_begin_cb)(const struct tfe_stream * stream, const struct tfe_http_session * session, unsigned int thread_id, void ** pme); typedef void (http_session_data_cb)(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event event, const unsigned char * data, size_t datalen, unsigned int thread_id, void ** pme); typedef void (http_session_end_cb)(const struct tfe_stream * stream, const struct tfe_http_session * session, unsigned int thread_id, void ** pme); /* Tools functions for standard HTTP header field name */ struct http_field_name * http_field_name_duplicate(const struct http_field_name * orig); int http_field_name_compare(const struct http_field_name * lvalue, const struct http_field_name * rvalue); const char * http_field_to_string(const struct http_field_name * field); void http_field_destory(struct http_field_name *); /* Tools functions for standard HTTP method */ const char * http_std_method_to_string(enum tfe_http_std_method method); enum tfe_http_std_method http_std_method_construct(const char * str_method); static inline const char * tfe_http_field_read(const struct tfe_http_half * half, const struct http_field_name * name) { return half->ops->ops_http_field_read(half, name); } static inline int tfe_http_field_write(struct tfe_http_half * half, const struct http_field_name * name, const char * value) { return half->ops->ops_http_field_write(half, name, value); } static inline struct tfe_http_half * tfe_http_allow_write(const struct tfe_http_half * half) { return half->ops->ops_http_allow_write(half); } static inline const char * tfe_http_field_iterate(const struct tfe_http_half * half, void ** interator, struct http_field_name * name) { return half->ops->ops_http_field_iterate(half, interator, name); } static inline int tfe_http_half_append_body(struct tfe_http_half * half, char * buff, size_t size, int flag) { return half->ops->ops_append_body(half, buff, size, flag); } static inline void tfe_http_half_free(struct tfe_http_half * half) { return half->ops->ops_free(half); } static inline struct tfe_http_session * tfe_http_session_allow_write(const struct tfe_http_session * session) { return session->ops->ops_allow_write(session); } static inline void tfe_http_session_detach(const struct tfe_http_session * session) { return session->ops->ops_detach(session); } static inline void tfe_http_session_drop(struct tfe_http_session * session) { return session->ops->ops_drop(session); } static inline void tfe_http_session_request_set(struct tfe_http_session * session, struct tfe_http_half * req) { return session->ops->ops_request_set(session, req); } static inline void tfe_http_session_response_set(struct tfe_http_session * session, struct tfe_http_half * resp) { return session->ops->ops_response_set(session, resp); } static inline struct tfe_http_half * tfe_http_session_request_create(struct tfe_http_session * session, enum tfe_http_std_method method, const char * uri) { return session->ops->ops_request_create(session, method, uri); } static inline struct tfe_http_half * tfe_http_session_response_create(struct tfe_http_session * session, int resp_code) { return session->ops->ops_response_create(session, resp_code); } //@flag EV_HTTP_RESP_BODY_END, EV_HTTP_RESP_BODY_FULL, //suspend stream on EV_HTTP_REQ_BODY_BEGIN, resume when EV_HTTP_REQ_BODY_END. /* handler_ { tfe_http_response_frag_create; tfe_http_session_set_half; } rpc_cb_ { tfe_http_set_field tfe_http_append_body tfe_http_write(); } rpc_finish_cb_ { tfe_http_write_finish(); }; */ /* TODO: transfer these declaration to ht_frame.h */ struct http_frame_plugin_status { void * pme; unsigned int detached; unsigned int preempt; }; struct http_frame_session_ctx * http_frame_raise_session_begin(const tfe_stream * stream, struct tfe_http_session * ht_session, unsigned int thread_id); void http_frame_raise_session_end(struct http_frame_session_ctx * ht_frame, struct tfe_stream * stream, struct tfe_http_session * ht_session, unsigned int thread_id); void http_frame_raise_event(struct http_frame_session_ctx * ht_frame, const struct tfe_stream * stream, struct tfe_http_session * ht_session, enum tfe_http_event event, const unsigned char * data, size_t datalen, unsigned int thread_id); void http_frame_currect_plugin_detach(struct http_frame_session_ctx * ht_frame); int http_frame_currect_plugin_preempt(struct http_frame_session_ctx * ht_frame);