summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLu <[email protected]>2018-06-19 20:22:36 +0800
committerLu <[email protected]>2018-06-19 20:22:36 +0800
commitcd3eca7a277db00302675149b1416ba330de8065 (patch)
tree7991ff9995be555ea17094838a5b43b8b6a980c7 /src
parent1e11d48dadf8a1c8b948228ef15a386c213df1c1 (diff)
HttpRedirect功能测试通过
Diffstat (limited to 'src')
-rw-r--r--src/http.h69
-rw-r--r--src/http1.cc213
-rw-r--r--src/httpaction.cc31
-rw-r--r--src/httpscan.cc82
-rw-r--r--src/httpscan.h2
-rw-r--r--src/main.cc2
-rw-r--r--src/pxyconn.cc9
7 files changed, 255 insertions, 153 deletions
diff --git a/src/http.h b/src/http.h
index dfae767..13bb481 100644
--- a/src/http.h
+++ b/src/http.h
@@ -48,6 +48,8 @@ public:
/* 四元组信息获取 */
virtual const struct sockaddr * SockAddrSource() const = 0;
virtual const struct sockaddr * SockAddrDest() const = 0;
+
+ virtual void Write(std::unique_ptr<HttpSession> http_session) = 0;
virtual void Close() = 0;
protected:
@@ -79,11 +81,6 @@ public:
HttpConnection & connection() const
{ return http_connection_; }
- void context(const std::shared_ptr<void> & ctx)
- { context_ = ctx; }
- const std::shared_ptr<void> & context()
- { return context_; }
-
virtual void SetRequestHeaderCallback(http_session_cb_t cb)
{ request_header_cb_ = cb; }
virtual void SetRequestBodyCallback(http_session_cb_t cb)
@@ -94,13 +91,34 @@ public:
{ response_body_cb_ = cb; }
virtual void CallRequestHeaderCallback()
- { request_header_cb_(*this); }
+ { __call_session_callback(request_header_cb_, tag_request_header_cb_); }
virtual void CallRequestBodyCallback()
- { request_body_cb_(*this); }
+ { __call_session_callback(request_body_cb_, tag_request_body_cb_); }
virtual void CallResponseHeaderCallback()
- { response_header_cb_(*this); }
+ { __call_session_callback(response_header_cb_, tag_response_header_cb_); }
virtual void CallResponseBodyCallback()
- { response_body_cb_(*this); }
+ { __call_session_callback(response_body_cb_, tag_response_body_cb_); }
+
+ enum CallbackTag
+ {
+ kCallbackTagIgnore,
+ kCallBackTagOnce,
+ kCallbackTagRepeat
+ };
+
+ virtual void SetRequestHeaderTag(enum CallbackTag tag)
+ { tag_request_header_cb_ = tag; }
+ virtual void SetRequestBodyTag(enum CallbackTag tag)
+ { tag_request_body_cb_ = tag; }
+ virtual void SetResponseHeaderTag(enum CallbackTag tag)
+ { tag_response_header_cb_ = tag; }
+ virtual void SetResponseBodyTag(enum CallbackTag tag)
+ { tag_response_body_cb_ = tag; }
+
+ virtual void DropMe()
+ { need_to_drop_ = true; }
+ virtual bool NeedToDrop()
+ { return need_to_drop_; }
protected:
HttpConnection & http_connection_;
@@ -113,6 +131,26 @@ protected:
http_session_cb_t request_body_cb_{nullptr};
http_session_cb_t response_header_cb_{nullptr};
http_session_cb_t response_body_cb_{nullptr};
+
+ /* Call tag */
+ enum CallbackTag tag_request_header_cb_{kCallBackTagOnce};
+ enum CallbackTag tag_request_body_cb_{kCallBackTagOnce};
+ enum CallbackTag tag_response_header_cb_{kCallBackTagOnce};
+ enum CallbackTag tag_response_body_cb_{kCallBackTagOnce};
+
+ /* Drop tag */
+ bool need_to_drop_{false};
+
+private:
+ void __call_session_callback(const http_session_cb_t & cb, enum CallbackTag & cb_tag)
+ {
+ while (cb_tag != kCallbackTagIgnore)
+ {
+ cb(*this);
+ if (cb_tag == kCallBackTagOnce) cb_tag = kCallbackTagIgnore;
+ if (cb_tag == kCallbackTagRepeat) cb_tag = kCallBackTagOnce;
+ }
+ }
};
class HttpRequest
@@ -176,15 +214,16 @@ public:
};
std::unique_ptr<HttpRequest> HttpRequestFactory(int primary_version, int second_version);
-std::unique_ptr<HttpResponse> HttpResponseFactory(int primary_version, int second_version);
+std::unique_ptr<HttpResponse> HttpResponseFactory(short major_version, short minor_version);
#include "pxyconn.h"
class Http1Connection : public HttpConnection
{
public:
- Http1Connection(const struct sockaddr_storage & source, const struct sockaddr_storage & dest)
- : sockaddr_source_(source), sockaddr_dest_(dest)
+ Http1Connection(struct bufferevent * bev_downstream, struct bufferevent * bev_upstream,
+ const struct sockaddr_storage & source, const struct sockaddr_storage & dest)
+ : bev_downstream_(bev_downstream), bev_upstream_(bev_upstream), sockaddr_source_(source), sockaddr_dest_(dest)
{}
~Http1Connection() = default;
@@ -200,6 +239,8 @@ public:
int on_connection_read_response(pxy_conn_ctx_t * conn_ctx, struct bufferevent * bev);
int on_connection_close(pxy_conn_ctx_t * conn_ctx, struct bufferevent * bev);
+ void Write(std::unique_ptr<HttpSession> http_session) override;
+
const sockaddr * SockAddrSource() const override;
const sockaddr * SockAddrDest() const override;
@@ -217,6 +258,10 @@ private:
/* connection info */
struct sockaddr_storage sockaddr_source_;
struct sockaddr_storage sockaddr_dest_;
+
+ /* upstream bev */
+ struct bufferevent * bev_upstream_;
+ struct bufferevent * bev_downstream_;
};
#endif //TFE_HTTP_H
diff --git a/src/http1.cc b/src/http1.cc
index a43474f..895b7d4 100644
--- a/src/http1.cc
+++ b/src/http1.cc
@@ -29,8 +29,8 @@ public:
Http1Request();
virtual ~Http1Request() = default;
- virtual ssize_t ConstructFromMemory(const char *buf, size_t buflen);
- virtual ssize_t ConstructFromEvBuf(struct evbuffer *evbuf_ptr);
+ virtual ssize_t ConstructFromMemory(const char * buf, size_t buflen);
+ virtual ssize_t ConstructFromEvBuf(struct evbuffer * evbuf_ptr);
virtual evbuffer_unique_ptr_t StolenEvbuf()
{ return std::move(evbuf_content_raw_); }
@@ -48,10 +48,10 @@ public:
bool Complete() override
{ return request_complete_; }
- const std::string &Url() const override;
- void Url(const std::string &url) override;
- const std::string &HeaderValue(const std::string &field) override;
- void HeaderValue(const std::string &field, const std::string &value) override;
+ const std::string & Url() const override;
+ void Url(const std::string & url) override;
+ const std::string & HeaderValue(const std::string & field) override;
+ void HeaderValue(const std::string & field, const std::string & value) override;
private:
std::string str_uri{};
@@ -74,25 +74,27 @@ Http1Request::Http1Request()
http_parser_init(parser_.get(), HTTP_REQUEST);
}
-ssize_t Http1Request::ConstructFromMemory(const char *buf, size_t buflen)
+ssize_t Http1Request::ConstructFromMemory(const char * buf, size_t buflen)
{
- static http_data_cb __http_parser_cb_on_uri = [](http_parser *parser, const char *at, size_t length) -> int
+ static http_data_cb __http_parser_cb_on_uri = [](http_parser * parser, const char * at, size_t length) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Request *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Request *>(parser->data);
__ptr_this->str_uri = std::string(at, at + length);
return 0;
};
- static http_data_cb __http_parser_cb_on_header_field = [](http_parser *parser, const char *at, size_t length) -> int
+ static http_data_cb
+ __http_parser_cb_on_header_field = [](http_parser * parser, const char * at, size_t length) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Request *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Request *>(parser->data);
__ptr_this->str_last_header_field_ = std::string(at, at + length);
return 0;
};
- static http_data_cb __http_parser_cb_on_header_value = [](http_parser *parser, const char *at, size_t length) -> int
+ static http_data_cb
+ __http_parser_cb_on_header_value = [](http_parser * parser, const char * at, size_t length) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Request *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Request *>(parser->data);
__ptr_this->str_headers[__ptr_this->str_last_header_field_] = std::string(at, at + length);
/* 对于Host字段,合成URL */
@@ -104,24 +106,24 @@ ssize_t Http1Request::ConstructFromMemory(const char *buf, size_t buflen)
return 0;
};
- static http_cb __http_parser_cb_on_message_complete = [](http_parser *parser) -> int
+ static http_cb __http_parser_cb_on_message_complete = [](http_parser * parser) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Request *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Request *>(parser->data);
__ptr_this->request_complete_ = true;
return 0;
};
static struct http_parser_settings __parser_setting =
- {
- nullptr, /* on_message_begin */
- __http_parser_cb_on_uri, /* on_url */
- nullptr, /* on_status */
- __http_parser_cb_on_header_field, /* on_header_field */
- __http_parser_cb_on_header_value, /* on_header_value */
- __http_parser_cb_on_message_complete, /* on_headers_complete */
- nullptr, /* on_body */
- nullptr /* on_message_complete */
- };
+ {
+ nullptr, /* on_message_begin */
+ __http_parser_cb_on_uri, /* on_url */
+ nullptr, /* on_status */
+ __http_parser_cb_on_header_field, /* on_header_field */
+ __http_parser_cb_on_header_value, /* on_header_value */
+ __http_parser_cb_on_message_complete, /* on_headers_complete */
+ nullptr, /* on_body */
+ nullptr /* on_message_complete */
+ };
parser_->data = this;
size_t sz_parsed = http_parser_execute(parser_.get(), &__parser_setting, buf, buflen);
@@ -137,10 +139,10 @@ ssize_t Http1Request::ConstructFromMemory(const char *buf, size_t buflen)
return sz_parsed;
}
-ssize_t Http1Request::ConstructFromEvBuf(struct evbuffer *evbuf_ptr)
+ssize_t Http1Request::ConstructFromEvBuf(struct evbuffer * evbuf_ptr)
{
/* 展平输入的Buffer为线性空间 */
- auto *__data_ptr = (const char *) (evbuffer_pullup(evbuf_ptr, -1));
+ auto * __data_ptr = (const char *) (evbuffer_pullup(evbuf_ptr, -1));
size_t __data_len = evbuffer_get_length(evbuf_ptr);
/* 解析输入的Buffer */
@@ -148,7 +150,7 @@ ssize_t Http1Request::ConstructFromEvBuf(struct evbuffer *evbuf_ptr)
if (forward_len < 0) return forward_len;
/* 已解析的部分,从原Buffer中抽离出来 */
- struct evbuffer *reserved_buffer = evbuffer_new();
+ struct evbuffer * reserved_buffer = evbuffer_new();
evbuffer_remove_buffer(evbuf_ptr, reserved_buffer, static_cast<size_t>(forward_len));
/* 保存在上下文中 */
@@ -158,10 +160,10 @@ ssize_t Http1Request::ConstructFromEvBuf(struct evbuffer *evbuf_ptr)
void Http1Request::ForEachHeader(HttpRequest::for_each_header_cb_t cb)
{
- for (auto &__iterate : str_headers)
+ for (auto & __iterate : str_headers)
{
- const std::string &__key = __iterate.first;
- const std::string &__value = __iterate.second;
+ const std::string & __key = __iterate.first;
+ const std::string & __value = __iterate.second;
cb(__key, __value);
}
@@ -169,22 +171,22 @@ void Http1Request::ForEachHeader(HttpRequest::for_each_header_cb_t cb)
return;
}
-const std::string &Http1Request::Url() const
+const std::string & Http1Request::Url() const
{
return str_uri;
}
-void Http1Request::Url(const std::string &url)
+void Http1Request::Url(const std::string & url)
{
str_uri = url;
}
-const std::string &Http1Request::HeaderValue(const std::string &field)
+const std::string & Http1Request::HeaderValue(const std::string & field)
{
return str_headers[field];
}
-void Http1Request::HeaderValue(const std::string &field, const std::string &value)
+void Http1Request::HeaderValue(const std::string & field, const std::string & value)
{
str_headers[field] = value;
}
@@ -193,12 +195,12 @@ void Http1Request::HeaderValue(const std::string &field, const std::string &valu
// HTTP Response Parser Implementation for HTTP 1.0/1.1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static const char *informational_phrases[] = {
+static const char * informational_phrases[] = {
/* 100 */ "Continue",
/* 101 */ "Switching Protocols"
};
-static const char *success_phrases[] = {
+static const char * success_phrases[] = {
/* 200 */ "OK",
/* 201 */ "Created",
/* 202 */ "Accepted",
@@ -208,7 +210,7 @@ static const char *success_phrases[] = {
/* 206 */ "Partial Content"
};
-static const char *redirection_phrases[] = {
+static const char * redirection_phrases[] = {
/* 300 */ "Multiple Choices",
/* 301 */ "Moved Permanently",
/* 302 */ "Found",
@@ -218,7 +220,7 @@ static const char *redirection_phrases[] = {
/* 307 */ "Temporary Redirect"
};
-static const char *client_error_phrases[] = {
+static const char * client_error_phrases[] = {
/* 400 */ "Bad Request",
/* 401 */ "Unauthorized",
/* 402 */ "Payment Required",
@@ -239,7 +241,7 @@ static const char *client_error_phrases[] = {
/* 417 */ "Expectation Failed"
};
-static const char *server_error_phrases[] = {
+static const char * server_error_phrases[] = {
/* 500 */ "Internal Server Error",
/* 501 */ "Not Implemented",
/* 502 */ "Bad Gateway",
@@ -248,7 +250,7 @@ static const char *server_error_phrases[] = {
/* 505 */ "HTTP Version not supported"
};
-const char *__resp_code_to_str(int resp_code)
+const char * __resp_code_to_str(int resp_code)
{
if (resp_code >= 101 && resp_code <= 102) return informational_phrases[resp_code - 101];
if (resp_code >= 200 && resp_code <= 206) return success_phrases[resp_code - 200];
@@ -262,11 +264,11 @@ const char *__resp_code_to_str(int resp_code)
class Http1Response : public HttpResponse
{
public:
- Http1Response();
+ Http1Response(short major_version, short minor_version);
virtual ~Http1Response() = default;
- virtual ssize_t ConstructFromMemory(const char *buf, size_t buflen);
- virtual ssize_t ConstructFromEvBuf(struct evbuffer *evbuf_len);
+ virtual ssize_t ConstructFromMemory(const char * buf, size_t buflen);
+ virtual ssize_t ConstructFromEvBuf(struct evbuffer * evbuf_len);
evbuffer_unique_ptr_t StolenEvBuf()
{ return std::move(evbuf_content_raw_); }
@@ -284,14 +286,14 @@ public:
{ return parse_complete_; }
virtual void Construct() final;
void ResponseCode(int code) override;
- const std::string &HeaderValue(const std::string &field) override;
- void HeaderValue(const std::string &field, const std::string &value) override;
+ const std::string & HeaderValue(const std::string & field) override;
+ void HeaderValue(const std::string & field, const std::string & value) override;
void ForEachHeader(for_each_header_cb_t cb) override;
private:
int resp_code_;
- short resp_version_major_;
- short resp_version_minor_;
+ short resp_version_major_{1};
+ short resp_version_minor_{1};
std::map<std::string, std::string> str_headers{};
std::string str_last_header_field_{};
@@ -304,38 +306,39 @@ private:
evbuffer_unique_ptr_t evbuf_content_raw_{nullptr};
};
-Http1Response::Http1Response()
+Http1Response::Http1Response(short major_version, short minor_version) : resp_version_major_(major_version),
+ resp_version_minor_(minor_version)
{
http_parser_init(parser_.get(), HTTP_RESPONSE);
}
-ssize_t Http1Response::ConstructFromMemory(const char *buf, size_t buflen)
+ssize_t Http1Response::ConstructFromMemory(const char * buf, size_t buflen)
{
struct http_parser_settings __parser_setting{nullptr};
- __parser_setting.on_status = [](http_parser *parser, const char *at, size_t length) -> int
+ __parser_setting.on_status = [](http_parser * parser, const char * at, size_t length) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Response *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Response *>(parser->data);
return 0;
};
- __parser_setting.on_header_field = [](http_parser *parser, const char *at, size_t length) -> int
+ __parser_setting.on_header_field = [](http_parser * parser, const char * at, size_t length) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Response *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Response *>(parser->data);
__ptr_this->str_last_header_field_ = std::string(at, at + length);
return 0;
};
- __parser_setting.on_header_value = [](http_parser *parser, const char *at, size_t length) -> int
+ __parser_setting.on_header_value = [](http_parser * parser, const char * at, size_t length) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Response *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Response *>(parser->data);
__ptr_this->str_headers[__ptr_this->str_last_header_field_] = std::string(at, at + length);
return 0;
};
- __parser_setting.on_message_complete = [](http_parser *parser) -> int
+ __parser_setting.on_message_complete = [](http_parser * parser) -> int
{
- auto *__ptr_this = reinterpret_cast<Http1Response *>(parser->data);
+ auto * __ptr_this = reinterpret_cast<Http1Response *>(parser->data);
__ptr_this->parse_complete_ = true;
return 0;
};
@@ -354,10 +357,10 @@ ssize_t Http1Response::ConstructFromMemory(const char *buf, size_t buflen)
return sz_parsed;
}
-ssize_t Http1Response::ConstructFromEvBuf(struct evbuffer *evbuf_ptr)
+ssize_t Http1Response::ConstructFromEvBuf(struct evbuffer * evbuf_ptr)
{
/* 展平输入的Buffer为线性空间 */
- auto *__data_ptr = (const char *) (evbuffer_pullup(evbuf_ptr, -1));
+ auto * __data_ptr = (const char *) (evbuffer_pullup(evbuf_ptr, -1));
size_t __data_len = evbuffer_get_length(evbuf_ptr);
/* 解析输入的Buffer */
@@ -365,7 +368,7 @@ ssize_t Http1Response::ConstructFromEvBuf(struct evbuffer *evbuf_ptr)
if (forward_len < 0) return forward_len;
/* 已解析的部分,从原Buffer中抽离出来 */
- struct evbuffer *reserved_buffer = evbuffer_new();
+ struct evbuffer * reserved_buffer = evbuffer_new();
evbuffer_remove_buffer(evbuf_ptr, reserved_buffer, static_cast<size_t>(forward_len));
/* 保存在上下文中 */
@@ -377,23 +380,27 @@ void Http1Response::Construct()
{
/* 新申请EvBuffer */
evbuffer_unique_ptr_t evbuf_construct = evbuffer_unique_ptr_t(evbuffer_new());
- struct evbuffer *evbuf_ptr = evbuf_construct.get();
+ struct evbuffer * evbuf_ptr = evbuf_construct.get();
/* 应答第一行 */
evbuffer_add_printf(evbuf_ptr, "HTTP/%d.%d %d %s\r\n",
resp_version_major_, resp_version_minor_, resp_code_, __resp_code_to_str(resp_code_));
/* 应答头部 */
- for (const auto &__iterate : str_headers)
+ for (const auto & __iterate : str_headers)
{
- const auto &__header_field = __iterate.first;
- const auto &__header_value = __iterate.second;
+ const auto & __header_field = __iterate.first;
+ const auto & __header_value = __iterate.second;
evbuffer_add_printf(evbuf_ptr, "%s:%s\r\n", __header_field.c_str(), __header_value.c_str());
}
+ /* 结尾行 */
+ evbuffer_add_printf(evbuf_ptr, "\r\n");
+
/* TODO: 消息体的构建 */
evbuf_content_raw_ = std::move(evbuf_construct);
+ parse_complete_ = true;
}
void Http1Response::ResponseCode(int code)
@@ -401,12 +408,12 @@ void Http1Response::ResponseCode(int code)
resp_code_ = code;
}
-const std::string &Http1Response::HeaderValue(const std::string &field)
+const std::string & Http1Response::HeaderValue(const std::string & field)
{
return str_headers[field];
}
-void Http1Response::HeaderValue(const std::string &field, const std::string &value)
+void Http1Response::HeaderValue(const std::string & field, const std::string & value)
{
str_headers[field] = value;
}
@@ -416,26 +423,28 @@ void Http1Response::ForEachHeader(HttpResponse::for_each_header_cb_t cb)
return;
}
-int Http1Connection::on_connection_close(pxy_conn_ctx_t *conn_ctx, struct bufferevent *bev)
+int Http1Connection::on_connection_close(pxy_conn_ctx_t * conn_ctx, struct bufferevent * bev)
{
return 0;
}
-int Http1Connection::on_connection_read_request(pxy_conn_ctx_t *conn_ctx, pxy_conn_desc_t *conn_this,
- pxy_conn_desc_t *conn_other)
+int Http1Connection::on_connection_read_request(pxy_conn_ctx_t * conn_ctx, pxy_conn_desc_t * conn_this,
+ pxy_conn_desc_t * conn_other)
{
/* Get the last session */
auto & http_session = last_uncomplete_session();
auto & request = dynamic_cast<Http1Request &>(http_session.request());
- auto *downstream_evbuf = bufferevent_get_input(conn_this->bev);
- auto *upstream_evbuf = bufferevent_get_output(conn_other->bev);
+ auto * downstream_evbuf = bufferevent_get_input(conn_this->bev);
+ auto * upstream_evbuf = bufferevent_get_output(conn_other->bev);
ssize_t forward_len = request.ConstructFromEvBuf(downstream_evbuf);
if (forward_len < 0)
{
- LOG(DEBUG) << "RequestConstructFromEvBuf Failed, connection turns to passthrough";
+ LOG(DEBUG) << "ctx = " << conn_ctx << " "
+ << "RequestConstructFromEvBuf Failed, connection turns to passthrough";
+
conn_ctx->passthrough = 1;
return 0;
}
@@ -450,18 +459,15 @@ int Http1Connection::on_connection_read_request(pxy_conn_ctx_t *conn_ctx, pxy_co
{
http_session.CallRequestHeaderCallback();
http_session.CallRequestBodyCallback();
+ }
- /* 转发请求 */
- if (request.Forward())
- {
- auto stolen_raw_evbuf = request.StolenEvbuf();
- evbuffer_add_buffer(upstream_evbuf, stolen_raw_evbuf.release());
- }
-
+ if (http_session.NeedToDrop())
+ {
+ drop_last_session();
return 0;
}
- if (request.ReadOnly())
+ if (request.ReadOnly() || request.Complete())
{
evbuffer_add_buffer(upstream_evbuf, request.StolenEvbuf().release());
return 0;
@@ -470,12 +476,12 @@ int Http1Connection::on_connection_read_request(pxy_conn_ctx_t *conn_ctx, pxy_co
return 0;
}
-int Http1Connection::on_connection_read_response(pxy_conn_ctx_t *conn_ctx, struct bufferevent *bev)
+int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, struct bufferevent * bev)
{
return 0;
}
-HttpSession &Http1Connection::create_new_session()
+HttpSession & Http1Connection::create_new_session()
{
/* Create new session, set a new request */
auto __http_session = std::unique_ptr<HttpSession>(new HttpSession(*this));
@@ -489,7 +495,7 @@ HttpSession &Http1Connection::create_new_session()
return *http_sessions_.back();
}
-HttpSession &Http1Connection::last_uncomplete_session()
+HttpSession & Http1Connection::last_uncomplete_session()
{
if (http_sessions_.cbegin() == http_sessions_.cend())
return create_new_session();
@@ -516,14 +522,34 @@ void Http1Connection::drop_first_session()
http_sessions_.pop_front();
}
-const sockaddr *Http1Connection::SockAddrSource() const
+const sockaddr * Http1Connection::SockAddrSource() const
+{
+ return (const sockaddr *) &sockaddr_source_;
+}
+
+const sockaddr * Http1Connection::SockAddrDest() const
{
- return (const sockaddr *)&sockaddr_source_;
+ return (const sockaddr *) &sockaddr_dest_;
}
-const sockaddr *Http1Connection::SockAddrDest() const
+void Http1Connection::Write(std::unique_ptr<HttpSession> http_session)
{
- return (const sockaddr *)&sockaddr_dest_;
+ auto & http1_request = dynamic_cast<Http1Request &>(http_session->request());
+ auto & http1_response = dynamic_cast<Http1Response &>(http_session->response());
+
+ if (http1_request.Complete())
+ {
+ auto stolen_buffer = http1_request.StolenEvbuf();
+ bufferevent_write_buffer(bev_upstream_, stolen_buffer.release());
+ }
+
+ if (http1_response.Complete())
+ {
+ auto stolen_buffer = http1_response.StolenEvBuf();
+ bufferevent_write_buffer(bev_downstream_, stolen_buffer.release());
+ }
+
+ return;
}
std::unique_ptr<HttpRequest> HttpRequestFactory(int primary_version, int second_version)
@@ -537,13 +563,12 @@ std::unique_ptr<HttpRequest> HttpRequestFactory(int primary_version, int second_
return nullptr;
}
-std::unique_ptr<HttpResponse> HttpResponseFactory(int primary_version, int second_version)
+std::unique_ptr<HttpResponse> HttpResponseFactory(short major_version, short minor_version)
{
- if (primary_version == 1 && second_version == 0)
- return std::move(std::make_unique<Http1Response>());
- if (primary_version == 1 && second_version == 1)
- return std::move(std::make_unique<Http1Response>());
+ if (major_version == 1 && minor_version == 0)
+ return std::move(std::make_unique<Http1Response>(major_version, minor_version));
+ if (major_version == 1 && minor_version == 1)
+ return std::move(std::make_unique<Http1Response>(major_version, minor_version));
- assert(0);
return nullptr;
} \ No newline at end of file
diff --git a/src/httpaction.cc b/src/httpaction.cc
index 897d4a1..0552c39 100644
--- a/src/httpaction.cc
+++ b/src/httpaction.cc
@@ -104,17 +104,32 @@ void HttpActionRedirect::Construct(const std::string &str_kv)
void HttpActionRedirect::do_redirect_action(HttpSession *session)
{
+
+ auto & http_connection = session->connection();
+
/* 创建新的HttpResponse */
- auto http_response = HttpResponseFactory(1, 1);
+ auto http_session = std::make_unique<HttpSession>(http_connection);
+ http_session->request(HttpRequestFactory(1, 0));
+ http_session->response(HttpResponseFactory(1, 0));
/* 构建Redirect Response */
- http_response->ResponseCode(resp_code_);
- http_response->HeaderValue("Location", resp_location_);
- http_response->Construct();
-
- /* 丢弃当前的HTTP Request,替换该请求对应的应答 */
- session->request().Forward(false);
- session->response(std::move(http_response));
+ auto & http_response = http_session->response();
+ http_response.ResponseCode(resp_code_);
+ http_response.HeaderValue("Location", resp_location_);
+ http_response.Construct();
+
+ /* 写新构建的HttpSession */
+ http_connection.Write(std::move(http_session));
+
+ /* 禁用后续的调用流程 */
+ session->SetRequestHeaderTag(HttpSession::kCallbackTagIgnore);
+ session->SetRequestBodyTag(HttpSession::kCallbackTagIgnore);
+ session->SetResponseHeaderTag(HttpSession::kCallbackTagIgnore);
+ session->SetResponseBodyTag(HttpSession::kCallbackTagIgnore);
+
+ /* 丢弃当前的HTTP Session */
+ session->DropMe();
+ return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/httpscan.cc b/src/httpscan.cc
index a2e9a34..407e1ba 100644
--- a/src/httpscan.cc
+++ b/src/httpscan.cc
@@ -21,14 +21,14 @@
#include "compat.h"
#include "logger.h"
-static int __maat_table_register_or_throw(Maat_feather_t feather, const char *str_table)
+static int __maat_table_register_or_throw(Maat_feather_t feather, const char * str_table)
{
int table_id = Maat_table_register(feather, str_table);
if (table_id < 0) throw std::runtime_error("Failed at register maat table " + std::string(str_table));
return table_id;
}
-HttpScan::HttpScan(struct tfe_instance *instance, struct tfe_config *config)
+HttpScan::HttpScan(struct tfe_instance * instance, struct tfe_config * config)
: maat_feather_ref(instance->maat_feather)
{
table_id_ctrl_ip = __maat_table_register_or_throw(maat_feather_ref, "PXY_CTRL_IP");
@@ -39,22 +39,22 @@ HttpScan::HttpScan(struct tfe_instance *instance, struct tfe_config *config)
table_id_ctrl_http_res_body = __maat_table_register_or_throw(maat_feather_ref, "PXY_CTRL_HTTP_RES_BODY");
auto & http_module = instance->http_module;
- http_module->SetHttpConnectionNewCallback([this](Http &ht, HttpConnection &ct) -> void
+ http_module->SetHttpConnectionNewCallback([this](Http & ht, HttpConnection & ct) -> void
{
this->handlerConnectionCreate(ct);
});
- http_module->SetHttpConnectionCloseCallback([this](Http &ht, HttpConnection &ct) -> void
+ http_module->SetHttpConnectionCloseCallback([this](Http & ht, HttpConnection & ct) -> void
{
this->handlerConnectionClose(ct);
});
}
-void HttpScan::handlerConnectionCreate(HttpConnection &ct)
+void HttpScan::handlerConnectionCreate(HttpConnection & ct)
{
/* 新Session的创建处理函数 */
auto __shared_this_ptr = shared_from_this();
- ct.SetSessionNewCallback([__shared_this_ptr](HttpSession &session) -> void
+ ct.SetSessionNewCallback([__shared_this_ptr](HttpSession & session) -> void
{
/* 创建HttpScan的Session Ctx */
auto __scan_ctx = std::make_shared<HttpScanSession>(*__shared_this_ptr);
@@ -64,25 +64,25 @@ void HttpScan::handlerConnectionCreate(HttpConnection &ct)
* 这样,回调时始终保持__scan_ctx的引用计数大于等于1,
* 避免在回调过程中变更回调函数导致ctx析构。
*/
- session.SetRequestHeaderCallback([__scan_ctx](HttpSession &session)
+ session.SetRequestHeaderCallback([__scan_ctx](HttpSession & session)
{
auto __scan_ctx_stack = __scan_ctx;
__scan_ctx_stack->ScanRequestHeader(&session);
});
- session.SetRequestBodyCallback([__scan_ctx](HttpSession &session)
+ session.SetRequestBodyCallback([__scan_ctx](HttpSession & session)
{
auto __scan_ctx_stack = __scan_ctx;
__scan_ctx->ScanRequestBody(&session);
});
- session.SetResponseHeaderCallback([__scan_ctx](HttpSession &session)
+ session.SetResponseHeaderCallback([__scan_ctx](HttpSession & session)
{
auto __scan_ctx_stack = __scan_ctx;
__scan_ctx->ScanResponseHeader(&session);
});
- session.SetResponseBodyCallback([__scan_ctx](HttpSession &session)
+ session.SetResponseBodyCallback([__scan_ctx](HttpSession & session)
{
auto __scan_ctx_stack = __scan_ctx;
__scan_ctx->ScanResponseBody(&session);
@@ -93,7 +93,7 @@ void HttpScan::handlerConnectionCreate(HttpConnection &ct)
ct.SetSessionCloseCallback(nullptr);
}
-void HttpScan::handlerConnectionClose(HttpConnection &ct)
+void HttpScan::handlerConnectionClose(HttpConnection & ct)
{
return;
}
@@ -108,7 +108,7 @@ int HttpScan::connection_bypass_do_action()
return 0;
}
-HttpScanSession::HttpScanSession(const HttpScan &httpscan_module) :
+HttpScanSession::HttpScanSession(const HttpScan & httpscan_module) :
httpscan_module_ref_(httpscan_module)
{
}
@@ -118,15 +118,15 @@ HttpScanSession::~HttpScanSession()
if (maat_scan_mid_ != nullptr) Maat_clean_status(&maat_scan_mid_);
}
-void HttpScanSession::ScanRequestHeader(HttpSession *http_session_ctx)
+void HttpScanSession::ScanRequestHeader(HttpSession * http_session_ctx)
{
- auto &http_request = http_session_ctx->request();
+ auto & http_request = http_session_ctx->request();
int dummy[MAAT_SCAN_RESULT_];
/* 扫描IP地址,获取连接对应的四元组 */
- const auto &connection = http_session_ctx->connection();
- const auto *sockaddr_src = connection.SockAddrSource();
- const auto *sockaddr_dst = connection.SockAddrDest();
+ const auto & connection = http_session_ctx->connection();
+ const auto * sockaddr_src = connection.SockAddrSource();
+ const auto * sockaddr_dst = connection.SockAddrDest();
/* 转换为Sapp中的四元组结构体 */
auto sapp_tuple4_ptr = sockaddr_to_sapp_ipaddr(sockaddr_src, sockaddr_dst);
@@ -136,64 +136,78 @@ void HttpScanSession::ScanRequestHeader(HttpSession *http_session_ctx)
httpscan_module_ref_.table_id_ctrl_ip, sapp_tuple4_ptr.get(),
maat_scan_result_, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ /* 以下所有扫描命中后,配置callback tag为repeat,在本函数返回后,再次调用RequestHeader处理回调
+ * 函数,执行命中动作 */
if (nr_maat_scan_result_ > 0)
+ {
+ http_session_ctx->SetRequestHeaderTag(HttpSession::kCallbackTagRepeat);
return hit_config_and_do_action(http_session_ctx);
+ }
else if (nr_maat_scan_result_ == -1)
+ {
return hit_scan_error();
+ }
/* 扫描HTTP URL */
- const auto &__url = http_request.Url();
+ const auto & __url = http_request.Url();
nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref,
httpscan_module_ref_.table_id_ctrl_http_url, CHARSET_UTF8, __url.c_str(), (int) __url.length(),
maat_scan_result_, dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
if (nr_maat_scan_result_ > 0)
+ {
+ http_session_ctx->SetRequestHeaderTag(HttpSession::kCallbackTagRepeat);
return hit_config_and_do_action(http_session_ctx);
+ }
else if (nr_maat_scan_result_ == -1)
+ {
return hit_scan_error();
+ }
/* 未命中HTTP URL,继续扫描其他HTTP头部字段 */
- http_request.ForEachHeader([this, http_session_ctx](const std::string &field, const std::string &value)
+ http_request.ForEachHeader([this, http_session_ctx](const std::string & field, const std::string & value)
{
/* 增强字符串表,设置区域字段,即Header字段 */
int ret = Maat_set_scan_status(httpscan_module_ref_.maat_feather_ref, &maat_scan_mid_,
MAAT_SET_SCAN_DISTRICT, field.c_str(), (int) field.length());
/* 设置失败 */
- if (ret < 0)
- return hit_scan_error();
-
+ if (ret < 0) return hit_scan_error();
int __dummy[MAAT_SCAN_RESULT_];
nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref,
httpscan_module_ref_.table_id_ctrl_http_req_hdr, MAAT_DEFAULT_CHARSET_,
- value.c_str(), (int) value.length(),
- maat_scan_result_, __dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ value.c_str(), (int) value.length(), maat_scan_result_, __dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
if (nr_maat_scan_result_ > 0)
+ {
+ http_session_ctx->SetRequestHeaderTag(HttpSession::kCallbackTagRepeat);
return hit_config_and_do_action(http_session_ctx);
+ }
else if (nr_maat_scan_result_ == -1)
+ {
return hit_scan_error();
+ }
});
}
-void HttpScanSession::ScanRequestBody(HttpSession *http_session_ctx)
+void HttpScanSession::ScanRequestBody(HttpSession * http_session_ctx)
{
return;
}
-void HttpScanSession::ScanResponseHeader(HttpSession *http_session_ctx)
+void HttpScanSession::ScanResponseHeader(HttpSession * http_session_ctx)
{
return;
}
-void HttpScanSession::ScanResponseBody(HttpSession *http_session_ctx)
+void HttpScanSession::ScanResponseBody(HttpSession * http_session_ctx)
{
return;
}
-void HttpScanSession::hit_config_and_do_action(HttpSession *http_session_ctx)
+void HttpScanSession::hit_config_and_do_action(HttpSession * http_session_ctx)
{
/* 判断命中数量,若为多命中,选择优先级最高的动作执行 */
enum HttpActionType action_type = HttpActionType::kActionMax;
@@ -205,9 +219,9 @@ void HttpScanSession::hit_config_and_do_action(HttpSession *http_session_ctx)
if (maat_scan_result_[i].action <= action_type) do_action_id = i;
}
- Maat_rule_t *hit_maat_rule = &maat_scan_result_[do_action_id];
+ Maat_rule_t * hit_maat_rule = &maat_scan_result_[do_action_id];
auto __action_type = (enum HttpActionType) hit_maat_rule->action;
- const char *__action_string = hit_maat_rule->service_defined;
+ const char * __action_string = hit_maat_rule->service_defined;
/* 创建HttpAction的对象 */
auto action_object = HttpActionFactory(__action_type, __action_string);
@@ -217,25 +231,25 @@ void HttpScanSession::hit_config_and_do_action(HttpSession *http_session_ctx)
action_object->service_id(hit_maat_rule->service_id);
/* 替换HttpSession的事件处理函数,以后的事件由HttpAction处理 */
- http_session_ctx->SetRequestHeaderCallback([action_object](HttpSession &session)
+ http_session_ctx->SetRequestHeaderCallback([action_object](HttpSession & session)
{
auto __action_object = action_object;
__action_object->OnRequestHeader(&session);
});
- http_session_ctx->SetRequestBodyCallback([action_object](HttpSession &session)
+ http_session_ctx->SetRequestBodyCallback([action_object](HttpSession & session)
{
auto __action_object = action_object;
__action_object->OnRequestBody(&session);
});
- http_session_ctx->SetResponseHeaderCallback([action_object](HttpSession &session)
+ http_session_ctx->SetResponseHeaderCallback([action_object](HttpSession & session)
{
auto __action_object = action_object;
__action_object->OnResponseHeader(&session);
});
- http_session_ctx->SetResponseBodyCallback([action_object](HttpSession &session)
+ http_session_ctx->SetResponseBodyCallback([action_object](HttpSession & session)
{
auto __action_object = action_object;
__action_object->OnResponseBody(&session);
diff --git a/src/httpscan.h b/src/httpscan.h
index f2892eb..529e0d1 100644
--- a/src/httpscan.h
+++ b/src/httpscan.h
@@ -84,6 +84,8 @@ private:
Maat_rule_t maat_scan_result_[MAAT_SCAN_RESULT_];
/* 扫描命中数量 */
int nr_maat_scan_result_{0};
+ /* 命中结果后,重新调用上层的处理函数 */
+ bool need_to_recall_event_cb_{false};
};
#endif //TFE_HTTPSCAN_H
diff --git a/src/main.cc b/src/main.cc
index 98190f4..74c1e96 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -288,7 +288,7 @@ main(int argc, char *argv[])
opts = tfe_config_new();
g_tfe_config = opts;
- event_enable_debug_logging(1);
+ event_enable_debug_logging(0);
el::Loggers::getLogger("conntrace");
if (nat_getdefaultname())
diff --git a/src/pxyconn.cc b/src/pxyconn.cc
index a0457a6..1abaa87 100644
--- a/src/pxyconn.cc
+++ b/src/pxyconn.cc
@@ -1356,7 +1356,9 @@ void * __http1_connection_ctx_setup(pxy_conn_ctx_t * ctx)
const auto & __source_address = ctx->spec->listen_addr;
const auto & __dest_address = ctx->spec->connect_addr;
- auto __http1_connection_ctx = std::make_unique<Http1Connection>(__source_address, __dest_address);
+ auto __http1_connection_ctx = std::make_unique<Http1Connection>(
+ ctx->src.bev, ctx->dst.bev, __source_address, __dest_address);
+
auto __http_scan_ctx = std::make_shared<HttpScan>(g_tfe_instance, g_tfe_config);
__http_scan_ctx->handlerConnectionCreate(*__http1_connection_ctx);
@@ -1971,9 +1973,9 @@ static void pxy_fd_readcb(evutil_socket_t fd, short what, void * arg)
{
pxy_conn_ctx_t * ctx = (pxy_conn_ctx_t *) arg;
- CLOG(DEBUG, "conntrace") << string_format("ctx = %p, fd = %d is readable", fd, what, ctx);
+ CLOG(DEBUG, "conntrace") << string_format("ctx = %p, fd = %d is readable", ctx, fd);
CLOG(DEBUG, "conntrace") << string_format("ctx = %p, ctx->spec->http = %d, ctx->spec->ssl = %d, ctx->passthrough = %d",
- ctx, ctx->spec->http, ctx->spec->ssl, ctx->passthrough);
+ ctx, ctx->spec->http, ctx->spec->ssl, ctx->passthrough);
/* for SSL, peek ClientHello and parse SNI from it */
if (ctx->spec->ssl && !ctx->passthrough /*&& ctx->ev*/)
@@ -1992,7 +1994,6 @@ static void pxy_fd_readcb(evutil_socket_t fd, short what, void * arg)
if (n == 0)
{
-
return;
}