From 29afc289bb44dba803d9e5e915dc8f3a07281183 Mon Sep 17 00:00:00 2001 From: xx Date: Thu, 20 Jun 2024 01:39:32 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=AF=B7=E6=B1=82=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- include/net/http_client_plus.h | 4 +- include/net/http_controller.h | 208 +++--- include/net/http_define.h | 88 +-- include/net/http_interface.h | 4 +- include/net/http_parser.h | 130 ---- include/net/http_reqpack.h | 156 ++-- include/net/http_request.h | 124 +-- include/net/http_response.h | 7 +- include/net/make_form.h | 54 +- include/net/util.h | 11 + src/net/http_agent.cpp | 1288 ++++++++++++++++---------------- src/net/http_client_plus.cpp | 54 +- src/net/http_controller.cpp | 440 +++++------ src/net/http_parser.cpp | 378 ---------- src/net/http_reqpack.cpp | 96 +-- src/net/http_request.cpp | 171 +++-- src/net/http_response.cpp | 16 +- src/net/http_router.cpp | 2 +- src/net/http_server_lst.cpp | 90 +-- src/net/http_subscribe.cpp | 2 +- src/net/util.cpp | 55 ++ 22 files changed, 1412 insertions(+), 1968 deletions(-) delete mode 100644 include/net/http_parser.h delete mode 100644 src/net/http_parser.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c87316a..cd80236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(PROJECT_NAME ylib) project(${PROJECT_NAME}) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 20) #set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) # 设置自定义配置类型 diff --git a/include/net/http_client_plus.h b/include/net/http_client_plus.h index a802f8e..d95f312 100644 --- a/include/net/http_client_plus.h +++ b/include/net/http_client_plus.h @@ -26,7 +26,7 @@ namespace ylib bool post(const std::string& url, const std::map& value, bool to_utf8 = false); bool post(const std::string& url, const ylib::json& value, bool to_utf8 = false); bool post(const std::string& url, const ylib::buffer& value); - bool post(const std::string& url, const http::make_form& value); + //bool post(const std::string& url, const http::make_form& value); bool head(const std::string& url); /// /// 连接代理服务器 @@ -90,7 +90,7 @@ namespace ylib // 请求路径 std::string m_path; // 请求方式 - network::http::method m_method; + std::string m_method; // 请求数据 ylib::buffer m_request_body; // [header] 请求 diff --git a/include/net/http_controller.h b/include/net/http_controller.h index 0fdb7ee..d436626 100644 --- a/include/net/http_controller.h +++ b/include/net/http_controller.h @@ -1,104 +1,104 @@ -#pragma once -#include "http_define.h" -#if USE_NET_HTTP_WEBSITE -#include "http_request.h" -#include "http_response.h" -#include "http_reqpack.h" -#include "http_interface.h" -#define _DBL_MIN 2.2250738585072014e-308 // min positive value -#define _DBL_MAX 1.7976931348623158e+308 // max value -#define _INT_MIN (-2147483647 - 1) -#define _INT_MAX 2147483647 -#define _UINT_MAX 0xffffffff -#define _LONG_MIN (-2147483647L - 1) -#define _LONG_MAX 2147483647L -#define _ULONG_MAX 0xffffffff -#ifndef _LLONG_MAX -#define _LLONG_MAX 9223372036854775807 -#endif -#define _LLONG_MIN (-9223372036854775807 - 1) -#define _ULLONG_MAX 0xffffffffffffffff -#define _INT8_MIN (-127 - 1) -#define _INT16_MIN (-32767 - 1) -#define _INT32_MIN (-2147483647 - 1) -#define _INT64_MIN (-9223372036854775807 - 1) -#define _INT8_MAX 127 -#define _INT16_MAX 32767 -#define _INT32_MAX 2147483647 -#define _INT64_MAX 9223372036854775807 -#define _UINT8_MAX 0xff -#define _UINT16_MAX 0xffff -#define _UINT32_MAX 0xffffffff -#define _UINT64_MAX 0xffffffffffffffff -#define _FLT_MIN 1.175494351e-38F // min normalized positive value -#define _FLT_MAX 3.402823466e+38F // max value -using namespace ylib::network::http; - -// 成功回复 -#define REPLY_SUCC rpjson()["code"] = 200;return RT_OK -// 自定义回复 -#define REPLY(CODE,MSG) rpjson()["code"] = CODE;rpjson()["msg"]=MSG;return RT_OK -// 失败回复 -#define REPLY_ERROR(MSG) rpjson()["code"] = -1;rpjson()["msg"]=MSG;return RT_OK -/********************************************************** - * Class:Http控制器接口 - *********************************************************/ -//#define check_qry_json(NAME) request()->parser()->json()[NAME].is_empty() -#define qry_json_string(NAME) request()->parser()->json()[NAME].to(true) -#define qry_json_uint32(NAME) request()->parser()->json()[NAME].to(true) -#define qry_json_uint64(NAME) request()->parser()->json()[NAME].to(true) -#define qry_json_int32(NAME) request()->parser()->json()[NAME].to(true) -#define qry_json_double(NAME) request()->parser()->json()[NAME].to(true) -#define qry_json_short(NAME) request()->parser()->json()[NAME].to(true) -#define qry_json_bool(NAME) request()->parser()->json()[NAME].to(true) -namespace ylib -{ - namespace network - { - namespace http - { - class router; - class controller :public network::http::interface_ - { - public: - controller(); - ~controller(); - network::http::request* request(); - network::http::response* response(); - - //min和max为<=或>= ,若填-1则不使用该条件 - std::string qry_string(const std::string& name,bool exception = true); - int32 qry_int32(const std::string& name, bool exception = true); - uint32 qry_uint32(const std::string& name, bool exception = true); - int64 qry_int64(const std::string& name, bool exception = true); - uint64 qry_uint64(const std::string& name, bool exception = true); - double qry_double(const std::string& name, bool exception = true); - float qry_float(const std::string& name, bool exception = true); - bool qry_empty(const std::string& name, bool exception = true); - bool qry_bool(const std::string& name, bool exception = true); - ylib::buffer qry_buffer(const std::string& name, bool exception); - - // 请求参数 - bool request_param(const std::string& name, std::string& value); - - // 获取回复JSON - inline ylib::json& rpjson() { return response()->sjson["data"]; } - inline ylib::json& rpcode() { return response()->sjson["code"]; } - //inline ylib::json& rp() { return response()->sjson["code"]; } - inline void rp(int code, const std::string& msg = "", const ylib::json& data = ylib::json()) - { - response()->sjson["code"] = code; - response()->sjson["msg"] = msg; - response()->sjson["data"] = data; - }; - - void send(const ylib::json& data); - - friend class router; - private: - network::http::reqpack* m_reqpack = nullptr; - }; - } - } -} -#endif +//#pragma once +//#include "http_define.h" +//#if USE_NET_HTTP_WEBSITE +//#include "http_request.h" +//#include "http_response.h" +//#include "http_reqpack.h" +//#include "http_interface.h" +//#define _DBL_MIN 2.2250738585072014e-308 // min positive value +//#define _DBL_MAX 1.7976931348623158e+308 // max value +//#define _INT_MIN (-2147483647 - 1) +//#define _INT_MAX 2147483647 +//#define _UINT_MAX 0xffffffff +//#define _LONG_MIN (-2147483647L - 1) +//#define _LONG_MAX 2147483647L +//#define _ULONG_MAX 0xffffffff +//#ifndef _LLONG_MAX +//#define _LLONG_MAX 9223372036854775807 +//#endif +//#define _LLONG_MIN (-9223372036854775807 - 1) +//#define _ULLONG_MAX 0xffffffffffffffff +//#define _INT8_MIN (-127 - 1) +//#define _INT16_MIN (-32767 - 1) +//#define _INT32_MIN (-2147483647 - 1) +//#define _INT64_MIN (-9223372036854775807 - 1) +//#define _INT8_MAX 127 +//#define _INT16_MAX 32767 +//#define _INT32_MAX 2147483647 +//#define _INT64_MAX 9223372036854775807 +//#define _UINT8_MAX 0xff +//#define _UINT16_MAX 0xffff +//#define _UINT32_MAX 0xffffffff +//#define _UINT64_MAX 0xffffffffffffffff +//#define _FLT_MIN 1.175494351e-38F // min normalized positive value +//#define _FLT_MAX 3.402823466e+38F // max value +//using namespace ylib::network::http; +// +//// 成功回复 +//#define REPLY_SUCC rpjson()["code"] = 200;return RT_OK +//// 自定义回复 +//#define REPLY(CODE,MSG) rpjson()["code"] = CODE;rpjson()["msg"]=MSG;return RT_OK +//// 失败回复 +//#define REPLY_ERROR(MSG) rpjson()["code"] = -1;rpjson()["msg"]=MSG;return RT_OK +///********************************************************** +// * Class:Http控制器接口 +// *********************************************************/ +////#define check_qry_json(NAME) request()->parser()->json()[NAME].is_empty() +//#define qry_json_string(NAME) request()->parser()->json()[NAME].to(true) +//#define qry_json_uint32(NAME) request()->parser()->json()[NAME].to(true) +//#define qry_json_uint64(NAME) request()->parser()->json()[NAME].to(true) +//#define qry_json_int32(NAME) request()->parser()->json()[NAME].to(true) +//#define qry_json_double(NAME) request()->parser()->json()[NAME].to(true) +//#define qry_json_short(NAME) request()->parser()->json()[NAME].to(true) +//#define qry_json_bool(NAME) request()->parser()->json()[NAME].to(true) +//namespace ylib +//{ +// namespace network +// { +// namespace http +// { +// class router; +// class controller :public network::http::interface_ +// { +// public: +// controller(); +// ~controller(); +// network::http::request* request(); +// network::http::response* response(); +// +// //min和max为<=或>= ,若填-1则不使用该条件 +// std::string qry_string(const std::string& name,bool exception = true); +// int32 qry_int32(const std::string& name, bool exception = true); +// uint32 qry_uint32(const std::string& name, bool exception = true); +// int64 qry_int64(const std::string& name, bool exception = true); +// uint64 qry_uint64(const std::string& name, bool exception = true); +// double qry_double(const std::string& name, bool exception = true); +// float qry_float(const std::string& name, bool exception = true); +// bool qry_empty(const std::string& name, bool exception = true); +// bool qry_bool(const std::string& name, bool exception = true); +// ylib::buffer qry_buffer(const std::string& name, bool exception); +// +// // 请求参数 +// bool request_param(const std::string& name, std::string& value); +// +// // 获取回复JSON +// inline ylib::json& rpjson() { return response()->sjson["data"]; } +// inline ylib::json& rpcode() { return response()->sjson["code"]; } +// //inline ylib::json& rp() { return response()->sjson["code"]; } +// inline void rp(int code, const std::string& msg = "", const ylib::json& data = ylib::json()) +// { +// response()->sjson["code"] = code; +// response()->sjson["msg"] = msg; +// response()->sjson["data"] = data; +// }; +// +// void send(const ylib::json& data); +// +// friend class router; +// private: +// network::http::reqpack* m_reqpack = nullptr; +// }; +// } +// } +//} +//#endif diff --git a/include/net/http_define.h b/include/net/http_define.h index 9c1b8a4..c533c59 100644 --- a/include/net/http_define.h +++ b/include/net/http_define.h @@ -263,89 +263,13 @@ namespace ylib uint64 connid; uint64 index; }; - //struct website_info - //{ - // website_info() - // { - // gzip = false; - // download_maxbaud = 0; - // } - // // 根目录 - // std::string rootdir; - // // GZIP - // bool gzip; - // // 默认编码方式 - // std::string default_codec; - // // 带宽限制 - // uint32 download_maxbaud; - //}; - /*表单信息*/ - struct form_info - { - form_info() - { - start = -1; - length = -1; - } - std::string disposition; - std::string content_type; - std::string name; - std::string filename; - int64 start; - int64 length; - ylib::buffer data; + + struct multipart { + std::map param; + size_t offset = 0; + size_t length = 0; }; - class controller; - //请求类型 - enum content_type - { - CT_FORM = 0, //表单: application/x-www-CT_FORM-urlencoded - CT_JSON = 1, //CT_JSON: application/CT_JSON - CT_TEXT = 2, //文本: text/plain - CT_NIL = 3, //无 - CT_ALL = 4 //所有 - }; - /*HTTP请求类型*/ - enum method - { - GET = 0, - POST = 1, - PUT = 2, - DEL = 3, - OTHER = 4, - HEAD = 5, - ALL = 100 - }; - inline std::string method_to_string(enum method m) { - switch (m) { - case GET: - return "GET"; - case POST: - return "POST"; - case PUT: - return "PUT"; - case DEL: - return "DEL"; - case OTHER: - return "OTHER"; - case ALL: - return "ALL"; - default: - return "unknown"; - } - return ""; - }; - /*控制器内返回结果*/ - enum response_type - { - RT_OK, //成功或已处理 - RT_500, //服务器内部错误 - RT_406, //服务器解析客户端数据失败或格式不正确拒绝解析 - RT_401 //需要鉴权,无权限 - }; - //控制器指针 - typedef response_type(network::http::controller::* HTTP_CTR_FUNCTION)(); - } + } } diff --git a/include/net/http_interface.h b/include/net/http_interface.h index 47dbff9..d134d70 100644 --- a/include/net/http_interface.h +++ b/include/net/http_interface.h @@ -23,8 +23,8 @@ namespace ylib inline void center(network::http::center* center) { m_center = center; } inline network::http::center* center() { return m_center; } private: - network::http::website* m_website; - network::http::center* m_center; + network::http::website* m_website = nullptr; + network::http::center* m_center = nullptr; }; } } diff --git a/include/net/http_parser.h b/include/net/http_parser.h deleted file mode 100644 index e27d846..0000000 --- a/include/net/http_parser.h +++ /dev/null @@ -1,130 +0,0 @@ -#pragma once -#include "http_define.h" -#if USE_NET_HTTP_WEBSITE -#include -namespace ylib -{ - namespace network - { - namespace http - { - class parser; - /************************************************************************* - * class:FORM表单解析器 - *************************************************************************/ - class form_parser { - public: - form_parser(); - ~form_parser(); - - - std::vector names(); - bool get(const std::string& name, form_info& info); - bool write_file(const std::string& name, const std::string& filepath); - - friend class parser; - private: - bool parse(ylib::buffer* data); - void parse_count(std::vector& starts, std::vector& lengths); - void parse_form(uint32 start, uint32 length); - char getchar(size_t index); - private: - ylib::buffer* m_data; - std::map m_infos; - }; - /************************************************************************* - * class:解析器 - *************************************************************************/ - class parser - { - public: - /****************************************************************** - * function:初始化 - * param - * - * url : 请求地址 - * method : 请求类型 - * data : 请求数据 - * content_type : 类型协议头 - ******************************************************************/ - bool init(const std::string& url, const network::http::method& method, const ylib::buffer& data, const std::string& content_type); - public: - parser(); - ~parser(); - - const ylib::json& json(); - std::string text(); - /****************************************************************** - * function:取URL参数 - * param - * name : 名称 - * value : 数据 - ******************************************************************/ - bool url_param(const std::string& name, std::string& value); - bool url_param_exist(const std::string& name); - /****************************************************************** - * function:取URL请求参数名列表 - ******************************************************************/ - std::vector url_param_names(); - /****************************************************************** - * function:取BODY参数 - * param - * name : 名称 - * value : 数据 - ******************************************************************/ - bool body_param(const std::string& name, std::string& value); - bool body_param_exist(const std::string& name); - /****************************************************************** - * function:取BODY请求参数名列表 - ******************************************************************/ - std::vector body_param_names(); - /****************************************************************** - * function:取BODY请求参数名列表 - ******************************************************************/ - form_parser* form(); - - const std::map& url_param() { return m_url_param; } - const std::map& body_param() { return m_body_param; } - private: - /****************************************************************** - * function:解析URL - ******************************************************************/ - void parse_url(const std::string& url, std::map& map); - /****************************************************************** - * function:解析JSON - ******************************************************************/ - void parse_json(); - /****************************************************************** - * function:解析FORM表单 - ******************************************************************/ - void parse_form(); - /****************************************************************** - * function:解析URL格式数据 - ******************************************************************/ - bool read_url_param(const std::map& map, const std::string& name, std::string& value); - - - - private: - // URL参数 - std::map m_url_param; - // BODY参数 - std::map m_body_param; - // JSON参数 - ylib::json m_json_param; - // FORM解析器 - network::http::form_parser m_form; - // 请求地址 - std::string m_url; - // 请求数据 - ylib::buffer m_data; - // 请求内容类型 - std::string m_content_type; - // 请求类型 - network::http::method m_method; - - }; - } - } -} -#endif diff --git a/include/net/http_reqpack.h b/include/net/http_reqpack.h index 8ea004a..b67c85a 100644 --- a/include/net/http_reqpack.h +++ b/include/net/http_reqpack.h @@ -2,8 +2,10 @@ #include "http_define.h" #if USE_NET_HTTP_WEBSITE #include "http_server.h" +#include "http_interface.h" #include "util/strutils.h" #include "util/time.h" + namespace ylib { namespace network @@ -14,99 +16,87 @@ namespace ylib class response; class request; class website; - /************************************************************************* - * class:请求包 - *************************************************************************/ - class reqpack + /// + /// 请求包 + /// + class reqpack:public network::http::interface_ { public: - - reqpack(); + /// + /// 构造函数 + /// + /// + /// + /// + /// + /// + /// + reqpack(const std::string& url, const std::string& host, const ylib::buffer& data, uint64 connid, network::http::server* server,network::http::website* website); ~reqpack(); - - void init(const std::string& url, const std::string& host, const ylib::buffer& data, uint64 connid, network::http::server* server); - void clear(); - network::http::request* request(); - network::http::response* response(); - - const std::string& host() - { - /*获取基本请求信息*/ - return m_host; - } - network::http::method method(); - const std::string& filepath(); - void filepath(const std::string& path); - network::http::server* server() - { - return m_server; - } - ylib::buffer& data() - { - return m_data; - } - const std::string& url() - { - return m_url; - } - const std::string& referrer() - { - return m_referrer; - } - const uint64& connid() - { - return m_connid; - } - network::http::website* website() { - return m_website; - } - void website(network::http::website* website) { - m_website = website; - } - timestamp begin_msec() { - return m_begin_msec; - } - std::string exec_msec() { - return std::to_string(time::now_msec() - m_begin_msec); - } - const std::string& remote() { - if (m_remote_ipaddress.empty()) { - ushort port; - m_server->remote(connid(), m_remote_ipaddress, port); - } - return m_remote_ipaddress; - } + /// + /// 请求对象 + /// + /// + const std::shared_ptr& request(); + /// + /// 回复对象 + /// + /// + const std::shared_ptr& response(); + /// + /// httpserver + /// + /// + network::http::server* server() { return m_server; } + /// + /// 连接ID + /// + /// + uint64 connid() { return m_connid; } + /// + /// 请求完整URL + /// + /// + std::string url() { return m_url; } + /// + /// 请求路径 + /// + /// + std::string filepath() { return m_filepath; } + /// + /// 请求主机 + /// + /// + std::string host() { return m_host; } + /// + /// 请求数据 + /// + /// + ylib::buffer& body() { return m_data; } + /// + /// 附加数据 + /// + /// ylib::json& extra() { return m_extra; } - void extra(ylib::json& e) { m_extra = e; } private: - // 请求主机 - std::string m_host; - // 请求方式 - network::http::method m_method; + // 请求 + std::shared_ptr m_request; + // 回复 + std::shared_ptr m_response; + // httpserver + network::http::server* m_server = nullptr; + // 请求地址 + std::string m_url; // 请求路径 std::string m_filepath; - // HPSERVER - network::http::server* m_server; - // 转发来路 - std::string m_referrer; - // 请求ID - uint64 m_connid; - // 站点 - network::http::website* m_website; - // 接收数据 + // 请求主机 + std::string m_host; + // 请求数据 ylib::buffer m_data; - // URL - std::string m_url; - // 请求发起时间 - timestamp m_begin_msec; - // 远程IP - std::string m_remote_ipaddress; - + // 请求ID + uint64 m_connid = 0; // 附加数据 ylib::json m_extra; - private: - network::http::request* m_request; - network::http::response* m_response; }; } } diff --git a/include/net/http_request.h b/include/net/http_request.h index 6adc43a..6549531 100644 --- a/include/net/http_request.h +++ b/include/net/http_request.h @@ -4,7 +4,6 @@ #include #include #include "http_session.h" -#include "http_parser.h" #include "http_interface.h" namespace ylib { @@ -14,64 +13,93 @@ namespace ylib { class reqpack; class server; - /******************************************************************** - * class:Http请求解析类 - ********************************************************************/ + /// + /// HTTP请求 + /// class request :public network::http::interface_ { public: - request(); + request(network::http::reqpack* reqpack); ~request(); - /*************************************************************************** - * function:取协议头 - * param - * name : 名称 - * value : 内容 - ***************************************************************************/ - bool header(const std::string& name, std::string& value); - - /*************************************************************************** - * function:取请求类型 - ***************************************************************************/ - network::http::method method(); - /*************************************************************************** - * function:取请求路径 - ***************************************************************************/ - std::string filepath(); - /*************************************************************************** - * function:取请求主机 - ***************************************************************************/ - std::string host(); - /*************************************************************************** - * function:取Session - ***************************************************************************/ - network::http::session& session(const std::string& session_id); /// - /// 取TOKEN + /// 取请求头 + /// + /// + /// + /// + bool header(const std::string& name, std::string& value); + /// + /// 请求动作 /// /// - std::string token(); - - - /*************************************************************************** - * function:取reqpack - ***************************************************************************/ + std::string method(); + /// + /// 取请求路径 + /// + /// + std::string filepath(); + /// + /// 取请求主机 + /// + /// + std::string host(); + /// + /// session + /// + /// + /// + network::http::session& session(const std::string& session_id); network::http::reqpack* reqpack(); - /*************************************************************************** - * function:解析器 - ***************************************************************************/ - network::http::parser* parser(); - /*************************************************************************** - * function:Get Browserr Remote Ipaddress - ***************************************************************************/ - std::string remote_ipaddress(bool find_header = false, const std::string& inside_ipaddress = ""); - ushort remote_port(); - friend class reqpack; + /// + /// 远程信息 + /// + /// + ylib::AddressPort remote(); + /// + /// 取请求参数 + /// + /// + /// + /// + bool get_url_param(const std::string& name,std::string& value); + bool get_body_param(const std::string& name, std::string& value); + std::shared_ptr>& url_param() { return m_url_param; } + std::shared_ptr>& body_param() { return m_body_param; } + + /// + /// 表单数据 + /// + /// + const std::shared_ptr>& multipart(); + /// + /// 是否为请求类型 + /// + /// + bool content_type(std::string type_name); + + /// + /// Body + /// + /// + ylib::buffer& body(); + private: - network::http::reqpack* m_reqpack; + + // reqpack + network::http::reqpack* m_reqpack = nullptr; + // session network::http::session m_session; - network::http::parser m_parser; + // 请求动作 + std::string m_method; + private: + // 请求参数[URL] + std::shared_ptr> m_url_param; + // 请求参数[BODY] + std::shared_ptr> m_body_param; + // FORM数据 + std::shared_ptr> m_form; + }; } } diff --git a/include/net/http_response.h b/include/net/http_response.h index 66a0de8..937a74c 100644 --- a/include/net/http_response.h +++ b/include/net/http_response.h @@ -18,9 +18,8 @@ namespace ylib class response :public network::http::interface_ { public: - response(); + response(network::http::reqpack* reqpack); ~response(); - void init(reqpack* rp); bool send(const char* buf, size_t buf_len, ushort stateNum = 200, const std::string& stateDesc = "OK"); bool send(const ylib::buffer& value, ushort stateNum = 200, const std::string& stateDesc = "OK"); bool send(const std::string& value, ushort stateNum = 200, const std::string& stateDesc = "OK"); @@ -36,8 +35,8 @@ namespace ylib bool fileoffset(long filesize, long& start, long& len); private: std::map m_headers; - bool m_response; - network::http::reqpack* m_reqpack; + bool m_response = false; + network::http::reqpack* m_reqpack = nullptr; }; } diff --git a/include/net/make_form.h b/include/net/make_form.h index 3551564..75663e3 100644 --- a/include/net/make_form.h +++ b/include/net/make_form.h @@ -1,27 +1,27 @@ -#pragma once -#include "http_define.h" - -#if USE_NET_HTTP_UTIL -#include "util/vector.hpp" -namespace ylib -{ - namespace network - { - namespace http - { - class make_form - { - public: - make_form(); - ~make_form(); - bool add(const std::string& name, const std::string& value); - bool add(const std::string& name, const std::string& filename, const std::string& content_type, const ylib::buffer& data); - bool make(ylib::buffer& data, std::string& boundary) const; - private: - ylib::vector m_list; - ylib::buffer m_data; - }; - } - } -} -#endif +//#pragma once +//#include "http_define.h" +// +//#if USE_NET_HTTP_UTIL +//#include "util/vector.hpp" +//namespace ylib +//{ +// namespace network +// { +// namespace http +// { +// class make_form +// { +// public: +// make_form(); +// ~make_form(); +// bool add(const std::string& name, const std::string& value); +// bool add(const std::string& name, const std::string& filename, const std::string& content_type, const ylib::buffer& data); +// bool make(ylib::buffer& data, std::string& boundary) const; +// private: +// ylib::vector m_list; +// ylib::buffer m_data; +// }; +// } +// } +//} +//#endif diff --git a/include/net/util.h b/include/net/util.h index 4aac1b0..99b1294 100644 --- a/include/net/util.h +++ b/include/net/util.h @@ -53,6 +53,17 @@ namespace ylib bool is_ipv6(const std::string& value); // 是否为域名 bool is_domain(const std::string& value); + + + /// + /// 解析 multipart/form 数据 + /// + /// + /// + /// + /// + /// + bool parse_multipart_form_data(const ylib::buffer& data, const std::string& boundary, std::vector& parts); } } #endif diff --git a/src/net/http_agent.cpp b/src/net/http_agent.cpp index 1b1bea0..9e7e0ea 100644 --- a/src/net/http_agent.cpp +++ b/src/net/http_agent.cpp @@ -1,650 +1,650 @@ -/*Software License - -Copyright(C) 2024[liuyingjie] -License Terms -Usage Rights - -Any individual or entity is free to use, copy, and distribute the binary form of this software without modification to the source code, without the need to disclose the source code. -If the source code is modified, the modifications must be open - sourced under the same license.This means that the modifications must be disclosed and accompanied by a copy of this license. -Future Versions Updates -From this version onwards, all future releases will be governed by the terms of the latest version of the license.This license will automatically be nullified and replaced by the new version. -Users must comply with the terms of the new license issued in future releases. -Liability and Disclaimer -This software is provided “as is”, without any express or implied warranties, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non - infringement.In no event shall the author or copyright holder be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. -Contact Information -If you have any questions, please contact us: 1585346868@qq.com Or visit our website fwlua.com. -*/ - -#include "net/http_agent.h" -#if USE_NET_HTTP_WEBSITE -#include -#include -#include -#include -#include - -#include "HPSocket/HPSocket.h" -#include "HPSocket/HPSocket-SSL.h" - -#include "util/system.h" -#include "util/time.h" -#include "util/map.hpp" - -#include "util/file.h" -#include "util/strutils.h" -#include "net/http_website.h" -#include "net/http_server.h" -#include "net/http_request.h" -#include "net/util.h" -#include "net/http_cache.h" -#include "net/http_reqpack.h" -#include "net/http_define.h" -/*附加数据*/ -class http_agent_extra -{ -public: - // 请求体 - struct request - { - request() - { - } - ~request() - { - } - // 请求头 - std::vector> request_headers; - std::vector> response_headers; - // 请求路径 - std::string path; - // 请求类型 - std::string method; - // 请求数据 - ylib::buffer data; - // HOST:PORT - std::string url_host; - }; - // 接收 - struct receive { - receive() { - transfer_encoding_length = -1; - } - // 回复数据 - ylib::buffer data; - // check 类型数据头内容 默认=-1 即非该类型回复。 - int32 transfer_encoding_length; - }; - http_agent_extra() - { - status_code = 0; - connid = 0; - server = nullptr; - agent = nullptr; - } - - void clear() - { - connid = 0; - server = nullptr; - agent = nullptr; - cache.close(); - status_code = 0; - status_desc.clear(); - } - // server 客户连接ID - uint64 connid; - // 绑定server - network::http::server* server; - // 请求 - request req; - // 接收 - receive recv; - // 代理 - IHttpAgent* agent; - // 缓存文件 - ylib::file_io cache; - // 状态码 - uint32 status_code; - // 状态描述 - std::string status_desc; -}; -// 获取附加数据指针 -inline http_agent_extra* __get_extra_to__(ITcpAgent* client, CONNID dwConnID){ - PVOID extra = 0; - client->GetConnectionExtra(dwConnID, &extra); - return (http_agent_extra*)extra; -} -#define GET_EXTRA __get_extra_to__(pSender,dwConnID) -#define SACONNID std::string("(S:"+std::to_string(GET_EXTRA->connid)+"|A["+std::to_string((uint64)pSender)+"]:"+std::to_string((uint64)dwConnID)+")") -class http_agent_listener :public IHttpAgentListener -{ - public: - http_agent_listener() - { - } - // 通过 IHttpAgentListener 继承 - virtual EnHttpParseResult OnMessageBegin(IHttpAgent* pSender, CONNID dwConnID) override - { - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnMessageBegin "+SACONNID,"http_agent "); - #endif - auto extra = GET_EXTRA; - extra->recv.transfer_encoding_length = -1; - extra->recv.data.clear(); - return HPR_OK; - } - virtual EnHttpParseResult OnRequestLine(IHttpAgent* pSender, CONNID dwConnID, LPCSTR lpszMethod, LPCSTR lpszUrl) override - { - +///*Software License +// +//Copyright(C) 2024[liuyingjie] +//License Terms +//Usage Rights +// +//Any individual or entity is free to use, copy, and distribute the binary form of this software without modification to the source code, without the need to disclose the source code. +//If the source code is modified, the modifications must be open - sourced under the same license.This means that the modifications must be disclosed and accompanied by a copy of this license. +//Future Versions Updates +//From this version onwards, all future releases will be governed by the terms of the latest version of the license.This license will automatically be nullified and replaced by the new version. +//Users must comply with the terms of the new license issued in future releases. +//Liability and Disclaimer +//This software is provided “as is”, without any express or implied warranties, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non - infringement.In no event shall the author or copyright holder be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. +//Contact Information +//If you have any questions, please contact us: 1585346868@qq.com Or visit our website fwlua.com. +//*/ +// +//#include "net/http_agent.h" +//#if USE_NET_HTTP_WEBSITE +//#include +//#include +//#include +//#include +//#include +// +//#include "HPSocket/HPSocket.h" +//#include "HPSocket/HPSocket-SSL.h" +// +//#include "util/system.h" +//#include "util/time.h" +//#include "util/map.hpp" +// +//#include "util/file.h" +//#include "util/strutils.h" +//#include "net/http_website.h" +//#include "net/http_server.h" +//#include "net/http_request.h" +//#include "net/util.h" +//#include "net/http_cache.h" +//#include "net/http_reqpack.h" +//#include "net/http_define.h" +///*附加数据*/ +//class http_agent_extra +//{ +//public: +// // 请求体 +// struct request +// { +// request() +// { +// } +// ~request() +// { +// } +// // 请求头 +// std::vector> request_headers; +// std::vector> response_headers; +// // 请求路径 +// std::string path; +// // 请求类型 +// std::string method; +// // 请求数据 +// ylib::buffer data; +// // HOST:PORT +// std::string url_host; +// }; +// // 接收 +// struct receive { +// receive() { +// transfer_encoding_length = -1; +// } +// // 回复数据 +// ylib::buffer data; +// // check 类型数据头内容 默认=-1 即非该类型回复。 +// int32 transfer_encoding_length; +// }; +// http_agent_extra() +// { +// status_code = 0; +// connid = 0; +// server = nullptr; +// agent = nullptr; +// } +// +// void clear() +// { +// connid = 0; +// server = nullptr; +// agent = nullptr; +// cache.close(); +// status_code = 0; +// status_desc.clear(); +// } +// // server 客户连接ID +// uint64 connid; +// // 绑定server +// network::http::server* server; +// // 请求 +// request req; +// // 接收 +// receive recv; +// // 代理 +// IHttpAgent* agent; +// // 缓存文件 +// ylib::file_io cache; +// // 状态码 +// uint32 status_code; +// // 状态描述 +// std::string status_desc; +//}; +//// 获取附加数据指针 +//inline http_agent_extra* __get_extra_to__(ITcpAgent* client, CONNID dwConnID){ +// PVOID extra = 0; +// client->GetConnectionExtra(dwConnID, &extra); +// return (http_agent_extra*)extra; +//} +//#define GET_EXTRA __get_extra_to__(pSender,dwConnID) +//#define SACONNID std::string("(S:"+std::to_string(GET_EXTRA->connid)+"|A["+std::to_string((uint64)pSender)+"]:"+std::to_string((uint64)dwConnID)+")") +//class http_agent_listener :public IHttpAgentListener +//{ +// public: +// http_agent_listener() +// { +// } +// // 通过 IHttpAgentListener 继承 +// virtual EnHttpParseResult OnMessageBegin(IHttpAgent* pSender, CONNID dwConnID) override +// { // #if HTTP_AGENT_DEBUG_PRINT == 1 -// ylib::log->info("OnRequestLine "+SACONNID,"http_agent "); +// ylib::log->info("OnMessageBegin "+SACONNID,"http_agent "); // #endif - - return HPR_OK; - } - virtual EnHttpParseResult OnStatusLine(IHttpAgent* pSender, CONNID dwConnID, USHORT usStatusCode, LPCSTR lpszDesc) override - { +// auto extra = GET_EXTRA; +// extra->recv.transfer_encoding_length = -1; +// extra->recv.data.clear(); +// return HPR_OK; +// } +// virtual EnHttpParseResult OnRequestLine(IHttpAgent* pSender, CONNID dwConnID, LPCSTR lpszMethod, LPCSTR lpszUrl) override +// { +// +//// #if HTTP_AGENT_DEBUG_PRINT == 1 +//// ylib::log->info("OnRequestLine "+SACONNID,"http_agent "); +//// #endif +// +// return HPR_OK; +// } +// virtual EnHttpParseResult OnStatusLine(IHttpAgent* pSender, CONNID dwConnID, USHORT usStatusCode, LPCSTR lpszDesc) override +// { +//// #if HTTP_AGENT_DEBUG_PRINT == 1 +//// ylib::log->info("OnStatusLine "+SACONNID,"http_agent "); +//// #endif +// http_agent_extra* extra = GET_EXTRA; +// extra->status_code = usStatusCode; +// extra->status_desc = lpszDesc; +// return HPR_OK; +// } +// virtual EnHttpParseResult OnHeader(IHttpAgent* pSender, CONNID dwConnID, LPCSTR lpszName, LPCSTR lpszValue) override +// { +//// #if HTTP_AGENT_DEBUG_PRINT == 1 +//// ylib::log->info("OnHeader "+SACONNID,"http_agent "); +//// #endif +// +// return HPR_OK; +// } +// virtual EnHttpParseResult OnHeadersComplete(IHttpAgent* pSender, CONNID dwConnID) override +// { // #if HTTP_AGENT_DEBUG_PRINT == 1 -// ylib::log->info("OnStatusLine "+SACONNID,"http_agent "); +// ylib::log->info("OnHeadersComplete "+SACONNID,"http_agent "); // #endif - http_agent_extra* extra = GET_EXTRA; - extra->status_code = usStatusCode; - extra->status_desc = lpszDesc; - return HPR_OK; - } - virtual EnHttpParseResult OnHeader(IHttpAgent* pSender, CONNID dwConnID, LPCSTR lpszName, LPCSTR lpszValue) override - { +// http_agent_extra* extra = GET_EXTRA; +// IHttpServer* server = (IHttpServer*)extra->server->hpserver(); +// THeader* local_header = nullptr; +// DWORD local_hsize = 0; +// // 取所有协议头 +// pSender->GetAllHeaders(dwConnID, local_header, local_hsize); +// if (local_hsize == 0) +// return HPR_OK; +// +// // MEM Header Length +// size_t mem_header_length = local_hsize + extra->req.response_headers.size(); +// local_header = new THeader[mem_header_length]; +// pSender->GetAllHeaders(dwConnID, local_header, local_hsize); +// +// size_t push_index = local_hsize; +// for (size_t i = 0; i < extra->req.response_headers.size(); i++) +// { +// std::string response_key = strutils::change_case(extra->req.response_headers[i].name, false); +// bool find = false; +// for (size_t f = 0; f < local_hsize; f++) +// { +// if (response_key == strutils::change_case(local_header[f].name, false)) +// { +// local_header[f].value = extra->req.response_headers[i].value.c_str(); +// find = true; +// break; +// } +// } +// if (find == false) +// { +// local_header[push_index].name = extra->req.response_headers[i].name.c_str(); +// local_header[push_index].value = extra->req.response_headers[i].value.c_str(); +// push_index++; +// } +// } +// +// +// +// // 取请求方式 +// server->SendResponse( +// (CONNID)extra->connid, +// extra->status_code, +// extra->status_desc.c_str(), +// local_header, +// (int)push_index); +// // 缓存 +// { +// if(extra->cache.is_open() && extra->status_code == 200) +// { +// ylib::file_io header_file; +// header_file.open(extra->cache.filepath()+".header"); +// for(size_t i=0;i< push_index;i++) +// { +// header_file.write(local_header[i].name,strlen(local_header[i].name)); +// header_file.write("\r\n",2); +// header_file.write(local_header[i].value,strlen(local_header[i].value)); +// header_file.write("\r\n",2); +// } +// header_file.close(); +// } +// } +// delete[] local_header; +// return HPR_OK; +// } +// std::string dec2hex(int i) //将int转成16进制字符串 +// { +// std::stringstream ioss; //定义字符串流 +// std::string s_temp; //存放转化后字符 +// ioss << std::setiosflags(std::ios::uppercase) << std::hex << i; //以十六制(大写)形式输出 +// //ioss << resetiosflags(ios::uppercase) << hex << i; //以十六制(小写)形式输出//取消大写的设置 +// ioss >> s_temp; +// return s_temp; +// } +// virtual EnHttpParseResult OnBody(IHttpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override +// { // #if HTTP_AGENT_DEBUG_PRINT == 1 -// ylib::log->info("OnHeader "+SACONNID,"http_agent "); +// ylib::log->info("OnBody "+SACONNID,"http_agent "); // #endif - - return HPR_OK; - } - virtual EnHttpParseResult OnHeadersComplete(IHttpAgent* pSender, CONNID dwConnID) override - { - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnHeadersComplete "+SACONNID,"http_agent "); - #endif - http_agent_extra* extra = GET_EXTRA; - IHttpServer* server = (IHttpServer*)extra->server->hpserver(); - THeader* local_header = nullptr; - DWORD local_hsize = 0; - // 取所有协议头 - pSender->GetAllHeaders(dwConnID, local_header, local_hsize); - if (local_hsize == 0) - return HPR_OK; - - // MEM Header Length - size_t mem_header_length = local_hsize + extra->req.response_headers.size(); - local_header = new THeader[mem_header_length]; - pSender->GetAllHeaders(dwConnID, local_header, local_hsize); - - size_t push_index = local_hsize; - for (size_t i = 0; i < extra->req.response_headers.size(); i++) - { - std::string response_key = strutils::change_case(extra->req.response_headers[i].name, false); - bool find = false; - for (size_t f = 0; f < local_hsize; f++) - { - if (response_key == strutils::change_case(local_header[f].name, false)) - { - local_header[f].value = extra->req.response_headers[i].value.c_str(); - find = true; - break; - } - } - if (find == false) - { - local_header[push_index].name = extra->req.response_headers[i].name.c_str(); - local_header[push_index].value = extra->req.response_headers[i].value.c_str(); - push_index++; - } - } - - - - // 取请求方式 - server->SendResponse( - (CONNID)extra->connid, - extra->status_code, - extra->status_desc.c_str(), - local_header, - (int)push_index); - // 缓存 - { - if(extra->cache.is_open() && extra->status_code == 200) - { - ylib::file_io header_file; - header_file.open(extra->cache.filepath()+".header"); - for(size_t i=0;i< push_index;i++) - { - header_file.write(local_header[i].name,strlen(local_header[i].name)); - header_file.write("\r\n",2); - header_file.write(local_header[i].value,strlen(local_header[i].value)); - header_file.write("\r\n",2); - } - header_file.close(); - } - } - delete[] local_header; - return HPR_OK; - } - std::string dec2hex(int i) //将int转成16进制字符串 - { - std::stringstream ioss; //定义字符串流 - std::string s_temp; //存放转化后字符 - ioss << std::setiosflags(std::ios::uppercase) << std::hex << i; //以十六制(大写)形式输出 - //ioss << resetiosflags(ios::uppercase) << hex << i; //以十六制(小写)形式输出//取消大写的设置 - ioss >> s_temp; - return s_temp; - } - virtual EnHttpParseResult OnBody(IHttpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override - { - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnBody "+SACONNID,"http_agent "); - #endif - http_agent_extra* extra = GET_EXTRA; - IHttpServer* server = (IHttpServer*)extra->server->hpserver(); - - - // Chunk 数据 - if(extra->recv.transfer_encoding_length != -1){ - extra->recv.data.append((const char*)pData,iLength); - }else{ - if(extra->cache.is_open() && extra->status_code == 200) - extra->cache.write((const char*)pData,iLength); - server->Send( - (CONNID)extra->connid, - pData, - iLength); - } - - return HPR_OK; - } - virtual EnHttpParseResult OnChunkHeader(IHttpAgent* pSender, CONNID dwConnID, int iLength) override - { - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnChunkHeader "+to_string(iLength)+SACONNID,"http_agent "); - #endif - http_agent_extra* extra = GET_EXTRA; - extra->recv.transfer_encoding_length += iLength; - return HPR_OK; - } - virtual EnHttpParseResult OnChunkComplete(IHttpAgent* pSender, CONNID dwConnID) override - { - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnChunkComplete:"+SACONNID,"http_agent "); - #endif - return HPR_OK; - } - virtual EnHttpParseResult OnMessageComplete(IHttpAgent* pSender, CONNID dwConnID) override - { - - - - http_agent_extra* extra = GET_EXTRA; - - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnMessageComplete:"+SACONNID,"http_agent "); - #endif - - - - if(extra->recv.transfer_encoding_length >= 0){ - IHttpServer* server = (IHttpServer*)extra->server->hpserver(); - - - std::string length = dec2hex(extra->recv.transfer_encoding_length+1)+"\r\n"; - // 分块长度 - server->Send( - (CONNID)extra->connid, - (const BYTE*)length.c_str(), - (int)length.length()); - // 数据包 - server->Send( - (CONNID)extra->connid, - (const BYTE*)extra->recv.data.data(), - (int)extra->recv.data.length() - ); - // 结尾 - server->Send( - (CONNID)extra->connid, - (const BYTE*)"\r\n0\r\n\r\n", - 7); - if(extra->cache.is_open() && extra->status_code == 200) - { - extra->cache.write(length.c_str(),length.length()); - extra->cache.write((const char*)extra->recv.data.data(),extra->recv.data.length()); - extra->cache.write("\r\n0\r\n\r\n",7); - } - - } - - if(extra->cache.is_open()) - { - if(extra->status_code == 200){ - ylib::file::write(extra->cache.filepath()+".conf",std::to_string(time::now_sec())+"\r\nNone"); - } - extra->cache.close(); - } - return HPR_OK; - } - virtual EnHttpParseResult OnUpgrade(IHttpAgent* pSender, CONNID dwConnID, EnHttpUpgradeType enUpgradeType) override - { - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnUpgrade:"+SACONNID,"http_agent "); - #endif - - return HPR_OK; - } - virtual EnHttpParseResult OnParseError(IHttpAgent* pSender, CONNID dwConnID, int iErrorCode, LPCSTR lpszErrorDesc) override - { -#if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnParsrError:"+SACONNID,"http_agent "); -#endif - - return HPR_OK; - } - virtual EnHandleResult OnWSMessageHeader(IHttpAgent* pSender, CONNID dwConnID, BOOL bFinal, BYTE iReserved, BYTE iOperationCode, const BYTE lpszMask[4], ULONGLONG ullBodyLen) override - { - return HR_OK; - } - virtual EnHandleResult OnWSMessageBody(IHttpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override - { - return HR_OK; - } - virtual EnHandleResult OnWSMessageComplete(IHttpAgent* pSender, CONNID dwConnID) override - { - return HR_OK; - } - virtual EnHandleResult OnHandShake(ITcpAgent* pSender, CONNID dwConnID) override - { -#if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnHandShake:"+SACONNID,"http_agent "); -#endif - - http_agent_extra* extra = GET_EXTRA; - // 发送请求 - THeader* local_header = new THeader[extra->req.request_headers.size()]; - size_t i= 0; - for_iter(iter,extra->req.request_headers){ - local_header[i].name = iter->name.c_str(); - local_header[i].value = iter->value.c_str(); - i++; - } - bool result = extra->agent->SendRequest( - dwConnID, - extra->req.method.c_str(), - extra->req.path.c_str(), - local_header, - (int)extra->req.request_headers.size(), - (const BYTE*)extra->req.data.data(), - (int)extra->req.data.length()); - delete[] local_header; - return HR_OK; - } - virtual EnHandleResult OnSend(ITcpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override - { -#if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnSend:"+SACONNID,"http_agent "); -#endif - - return HR_OK; - } - virtual EnHandleResult OnReceive(ITcpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override - { -#if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnReceive:"+SACONNID,"http_agent "); -#endif - - //ylib::log->info("OnReceive", "agent"); - return HR_OK; - } - virtual EnHandleResult OnReceive(ITcpAgent* pSender, CONNID dwConnID, int iLength) override - { - return HR_OK; - } - virtual EnHandleResult OnClose(ITcpAgent* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode) override - { - #if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnClose "+SACONNID,"http_agent "); - #endif - - http_agent_extra* extra = GET_EXTRA; - //IHttpServer* server = (IHttpServer*)extra->server->hpserver(); - //server->Disconnect(extra->connid); - delete extra; - return HR_OK; - } - virtual EnHandleResult OnShutdown(ITcpAgent* pSender) override - { - return HR_OK; - } - virtual EnHandleResult OnPrepareConnect(ITcpAgent* pSender, CONNID dwConnID, SOCKET socket) override - { - return HR_OK; - } - virtual EnHandleResult OnConnect(ITcpAgent* pSender, CONNID dwConnID) override - { -#if HTTP_AGENT_DEBUG_PRINT == 1 - ylib::log->info("OnConnect:"+SACONNID,"http_agent "); -#endif - - return HR_OK; - } -public: - network::http::agent* m_agent; - -}; -bool ylib::network::http::agent::request(int32 wait_msec,reqpack* rp, network::http::proxy* proxy) -{ - - http_agent_extra* extra = new http_agent_extra; - - extra->connid = rp->connid(); - extra->server = rp->server(); - - IHttpAgent* agent = nullptr; - if(proxy->ssl) - agent = (IHttpAgent*)m_agent_ssl; - else - agent = (IHttpAgent*)m_agent; - - extra->agent = agent; - // 拼接地址 - { - try - { - - size_t right_length = rp->url().length() - ylib::file::parent_dir(proxy->src_str).length(); - std::string pjp; - pjp.append(rp->url().c_str() + rp->url().length() - right_length, right_length); - extra->req.path.append(proxy->dst); - - if ( - (proxy->dst.empty() || proxy->dst[proxy->dst.length()-1] != '/') - && pjp[0] != '/') { - extra->req.path +='/'; - } - extra->req.path.append(pjp); - } - catch (const std::exception& e) - { - ylib::log->fatal(e.what()); - } - - } - extra->req.data = rp->data(); - { - extra->req.url_host.append(proxy->remote_ipaddress); - extra->req.url_host.append(":"); - extra->req.url_host.append(std::to_string(proxy->remote_port)); - extra->req.url_host.append(extra->req.path); - } - // 构造请求内容 - { - THeader* header = nullptr; - DWORD header_size = 0; - ((IHttpServer*)rp->server()->hpserver())->GetAllHeaders((CONNID)rp->connid(), header,header_size); - if (header_size == 0){ -#if HTTP_AGENT_PRINT == 1 - ylib::log->error("not found header,"+extra->req.path,"http_agent "); -#endif - delete extra; - return false; - } - header = new THeader[header_size]; - ((IHttpServer*)rp->server()->hpserver())->GetAllHeaders((CONNID)rp->connid(), header,header_size); - // 浏览器真实IP - std::string ipaddress; - ushort port = 0; - rp->server()->remote(rp->connid(),ipaddress,port); - // 请求协议头 - { - for (size_t i = 0; i < header_size; i++) { - ylib::KeyValue kv; - kv.name = header[i].name; - kv.value = header[i].value; - // 要求协议头 - for_iter(iter, proxy->request_headers) { - if (kv.name == iter->first) { - kv.value = iter->second; - break; - } - } - extra->req.request_headers.push_back(kv); - } - for_iter(iter, extra->req.request_headers) { - if (iter->name == "X-Real-IP") { - if (iter->value == "{client_ipaddress}") { - iter->value = ipaddress; - } - } - else if (iter->name == "Host") { - if (iter->value == "{host}") { - iter->value = proxy->remote_ipaddress; - } - } - } - } - // 回复协议头 - { - for_iter(iter, proxy->response_headers) { - ylib::KeyValue kv; - kv.name = iter->first; - kv.value = iter->second; - extra->req.response_headers.push_back(kv); - } - } - - delete[] header; - // 取请求方式 - extra->req.method = ((IHttpServer*)rp->server()->hpserver())->GetMethod((CONNID)rp->connid()); - } - // 符合缓存 - { - auto cache = rp->website()->cache(); - if(cache->enable()) - { - if(cache->find_ext(rp->filepath())){ - std::string cache_filepath = cache->make_cache_filepath(rp->filepath()); - extra->cache.close(); - if(extra->cache.open(cache_filepath) == false){ - ylib::log->error("create open cache file failed! path:"+cache_filepath,"http_agent "); - }else{ - extra->cache.clear(); - ylib::file::remove(cache_filepath+".header"); - ylib::file::remove(cache_filepath+".conf"); - } - } - } - - } - -#if 0 - std::cout<<"======================HEADER=========================="<req.headers.size();i++){ - std::cout<req.headers[i].name.c_str()<<":\t"<req.headers[i].value.c_str()<agent->Connect(proxy->remote_ipaddress.c_str(), proxy->remote_port, &hpcid, (PVOID)extra) == false) - { -#if HTTP_AGENT_PRINT == 1 - ylib::log->error("connect failed.\t"+extra->req.path,"http_agent "); -#endif - delete extra; - return false; - } - // 临时附加数据 - { - PVOID exts = 0; - if (((IHttpServer*)rp->server()->hpserver())->GetConnectionExtra((CONNID)rp->connid(), &exts) == false){ - agent->Disconnect((CONNID)hpcid); -#if HTTP_AGENT_PRINT == 1 - ylib::log->error("get server extra failed,"+extra->req.path,"http_agent "); -#endif - return false; - } - ((temp_recv*)exts)->agent_connid = hpcid; - ((temp_recv*)exts)->agent_ssl = proxy->ssl; - } - return true; -} -void* ylib::network::http::agent::get() -{ - return m_agent; -} -ylib::network::http::agent::agent() -{ - m_agent = nullptr; - m_agent_ssl = nullptr; - m_listener = new http_agent_listener; - m_listener->m_agent = this; - m_agent_ssl = HP_Create_HttpsAgent(m_listener); - m_agent = HP_Create_HttpAgent(m_listener); -} -ylib::network::http::agent::~agent() -{ - stop(); - HP_Destroy_HttpAgent((IHttpAgent*)m_agent); - HP_Destroy_HttpsAgent((IHttpAgent*)m_agent_ssl); -} -void ylib::network::http::agent::stop() -{ - ((IHttpAgent*)m_agent)->Stop(); - ((IHttpAgent*)m_agent_ssl)->Stop(); - ((IHttpAgent*)m_agent_ssl)->Wait(); - ((IHttpAgent*)m_agent_ssl)->Wait(); -} -bool ylib::network::http::agent::start() -{ - //return true; - ((IHttpAgent*)m_agent_ssl)->CleanupSSLContext(); - if (((IHttpAgent*)m_agent_ssl)->SetupSSLContext() == false) - { - m_lastErrorDesc = "SetupSSLContextFailed, " + std::to_string((uint32)SYS_GetLastError()); - return false; - } - if(((IHttpAgent*)m_agent_ssl)->Start() == false){ - m_lastErrorDesc = "SSLHttpAgent start failed."; - return false; - } - if(((IHttpAgent*)m_agent)->Start() == false){ - m_lastErrorDesc = "HttpAgent start failed."; - ((IHttpAgent*)m_agent_ssl)->Stop(); - ((IHttpAgent*)m_agent_ssl)->Wait(); - return false; - - } - return true; - -} -void ylib::network::http::agent::disconnect(bool ssl,uint64 connid) -{ - if(ssl) - ((IHttpAgent*)m_agent_ssl)->Disconnect((CONNID)connid,TRUE); - else - ((IHttpAgent*)m_agent)->Disconnect((CONNID)connid,TRUE); -} -#endif +// http_agent_extra* extra = GET_EXTRA; +// IHttpServer* server = (IHttpServer*)extra->server->hpserver(); +// +// +// // Chunk 数据 +// if(extra->recv.transfer_encoding_length != -1){ +// extra->recv.data.append((const char*)pData,iLength); +// }else{ +// if(extra->cache.is_open() && extra->status_code == 200) +// extra->cache.write((const char*)pData,iLength); +// server->Send( +// (CONNID)extra->connid, +// pData, +// iLength); +// } +// +// return HPR_OK; +// } +// virtual EnHttpParseResult OnChunkHeader(IHttpAgent* pSender, CONNID dwConnID, int iLength) override +// { +// #if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnChunkHeader "+to_string(iLength)+SACONNID,"http_agent "); +// #endif +// http_agent_extra* extra = GET_EXTRA; +// extra->recv.transfer_encoding_length += iLength; +// return HPR_OK; +// } +// virtual EnHttpParseResult OnChunkComplete(IHttpAgent* pSender, CONNID dwConnID) override +// { +// #if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnChunkComplete:"+SACONNID,"http_agent "); +// #endif +// return HPR_OK; +// } +// virtual EnHttpParseResult OnMessageComplete(IHttpAgent* pSender, CONNID dwConnID) override +// { +// +// +// +// http_agent_extra* extra = GET_EXTRA; +// +// #if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnMessageComplete:"+SACONNID,"http_agent "); +// #endif +// +// +// +// if(extra->recv.transfer_encoding_length >= 0){ +// IHttpServer* server = (IHttpServer*)extra->server->hpserver(); +// +// +// std::string length = dec2hex(extra->recv.transfer_encoding_length+1)+"\r\n"; +// // 分块长度 +// server->Send( +// (CONNID)extra->connid, +// (const BYTE*)length.c_str(), +// (int)length.length()); +// // 数据包 +// server->Send( +// (CONNID)extra->connid, +// (const BYTE*)extra->recv.data.data(), +// (int)extra->recv.data.length() +// ); +// // 结尾 +// server->Send( +// (CONNID)extra->connid, +// (const BYTE*)"\r\n0\r\n\r\n", +// 7); +// if(extra->cache.is_open() && extra->status_code == 200) +// { +// extra->cache.write(length.c_str(),length.length()); +// extra->cache.write((const char*)extra->recv.data.data(),extra->recv.data.length()); +// extra->cache.write("\r\n0\r\n\r\n",7); +// } +// +// } +// +// if(extra->cache.is_open()) +// { +// if(extra->status_code == 200){ +// ylib::file::write(extra->cache.filepath()+".conf",std::to_string(time::now_sec())+"\r\nNone"); +// } +// extra->cache.close(); +// } +// return HPR_OK; +// } +// virtual EnHttpParseResult OnUpgrade(IHttpAgent* pSender, CONNID dwConnID, EnHttpUpgradeType enUpgradeType) override +// { +// #if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnUpgrade:"+SACONNID,"http_agent "); +// #endif +// +// return HPR_OK; +// } +// virtual EnHttpParseResult OnParseError(IHttpAgent* pSender, CONNID dwConnID, int iErrorCode, LPCSTR lpszErrorDesc) override +// { +//#if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnParsrError:"+SACONNID,"http_agent "); +//#endif +// +// return HPR_OK; +// } +// virtual EnHandleResult OnWSMessageHeader(IHttpAgent* pSender, CONNID dwConnID, BOOL bFinal, BYTE iReserved, BYTE iOperationCode, const BYTE lpszMask[4], ULONGLONG ullBodyLen) override +// { +// return HR_OK; +// } +// virtual EnHandleResult OnWSMessageBody(IHttpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override +// { +// return HR_OK; +// } +// virtual EnHandleResult OnWSMessageComplete(IHttpAgent* pSender, CONNID dwConnID) override +// { +// return HR_OK; +// } +// virtual EnHandleResult OnHandShake(ITcpAgent* pSender, CONNID dwConnID) override +// { +//#if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnHandShake:"+SACONNID,"http_agent "); +//#endif +// +// http_agent_extra* extra = GET_EXTRA; +// // 发送请求 +// THeader* local_header = new THeader[extra->req.request_headers.size()]; +// size_t i= 0; +// for_iter(iter,extra->req.request_headers){ +// local_header[i].name = iter->name.c_str(); +// local_header[i].value = iter->value.c_str(); +// i++; +// } +// bool result = extra->agent->SendRequest( +// dwConnID, +// extra->req.method.c_str(), +// extra->req.path.c_str(), +// local_header, +// (int)extra->req.request_headers.size(), +// (const BYTE*)extra->req.data.data(), +// (int)extra->req.data.length()); +// delete[] local_header; +// return HR_OK; +// } +// virtual EnHandleResult OnSend(ITcpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override +// { +//#if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnSend:"+SACONNID,"http_agent "); +//#endif +// +// return HR_OK; +// } +// virtual EnHandleResult OnReceive(ITcpAgent* pSender, CONNID dwConnID, const BYTE* pData, int iLength) override +// { +//#if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnReceive:"+SACONNID,"http_agent "); +//#endif +// +// //ylib::log->info("OnReceive", "agent"); +// return HR_OK; +// } +// virtual EnHandleResult OnReceive(ITcpAgent* pSender, CONNID dwConnID, int iLength) override +// { +// return HR_OK; +// } +// virtual EnHandleResult OnClose(ITcpAgent* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode) override +// { +// #if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnClose "+SACONNID,"http_agent "); +// #endif +// +// http_agent_extra* extra = GET_EXTRA; +// //IHttpServer* server = (IHttpServer*)extra->server->hpserver(); +// //server->Disconnect(extra->connid); +// delete extra; +// return HR_OK; +// } +// virtual EnHandleResult OnShutdown(ITcpAgent* pSender) override +// { +// return HR_OK; +// } +// virtual EnHandleResult OnPrepareConnect(ITcpAgent* pSender, CONNID dwConnID, SOCKET socket) override +// { +// return HR_OK; +// } +// virtual EnHandleResult OnConnect(ITcpAgent* pSender, CONNID dwConnID) override +// { +//#if HTTP_AGENT_DEBUG_PRINT == 1 +// ylib::log->info("OnConnect:"+SACONNID,"http_agent "); +//#endif +// +// return HR_OK; +// } +//public: +// network::http::agent* m_agent; +// +//}; +//bool ylib::network::http::agent::request(int32 wait_msec,reqpack* rp, network::http::proxy* proxy) +//{ +// +// http_agent_extra* extra = new http_agent_extra; +// +// extra->connid = rp->connid(); +// extra->server = rp->server(); +// +// IHttpAgent* agent = nullptr; +// if(proxy->ssl) +// agent = (IHttpAgent*)m_agent_ssl; +// else +// agent = (IHttpAgent*)m_agent; +// +// extra->agent = agent; +// // 拼接地址 +// { +// try +// { +// +// size_t right_length = rp->url().length() - ylib::file::parent_dir(proxy->src_str).length(); +// std::string pjp; +// pjp.append(rp->url().c_str() + rp->url().length() - right_length, right_length); +// extra->req.path.append(proxy->dst); +// +// if ( +// (proxy->dst.empty() || proxy->dst[proxy->dst.length()-1] != '/') +// && pjp[0] != '/') { +// extra->req.path +='/'; +// } +// extra->req.path.append(pjp); +// } +// catch (const std::exception& e) +// { +// ylib::log->fatal(e.what()); +// } +// +// } +// extra->req.data = rp->data(); +// { +// extra->req.url_host.append(proxy->remote_ipaddress); +// extra->req.url_host.append(":"); +// extra->req.url_host.append(std::to_string(proxy->remote_port)); +// extra->req.url_host.append(extra->req.path); +// } +// // 构造请求内容 +// { +// THeader* header = nullptr; +// DWORD header_size = 0; +// ((IHttpServer*)rp->server()->hpserver())->GetAllHeaders((CONNID)rp->connid(), header,header_size); +// if (header_size == 0){ +//#if HTTP_AGENT_PRINT == 1 +// ylib::log->error("not found header,"+extra->req.path,"http_agent "); +//#endif +// delete extra; +// return false; +// } +// header = new THeader[header_size]; +// ((IHttpServer*)rp->server()->hpserver())->GetAllHeaders((CONNID)rp->connid(), header,header_size); +// // 浏览器真实IP +// std::string ipaddress; +// ushort port = 0; +// rp->server()->remote(rp->connid(),ipaddress,port); +// // 请求协议头 +// { +// for (size_t i = 0; i < header_size; i++) { +// ylib::KeyValue kv; +// kv.name = header[i].name; +// kv.value = header[i].value; +// // 要求协议头 +// for_iter(iter, proxy->request_headers) { +// if (kv.name == iter->first) { +// kv.value = iter->second; +// break; +// } +// } +// extra->req.request_headers.push_back(kv); +// } +// for_iter(iter, extra->req.request_headers) { +// if (iter->name == "X-Real-IP") { +// if (iter->value == "{client_ipaddress}") { +// iter->value = ipaddress; +// } +// } +// else if (iter->name == "Host") { +// if (iter->value == "{host}") { +// iter->value = proxy->remote_ipaddress; +// } +// } +// } +// } +// // 回复协议头 +// { +// for_iter(iter, proxy->response_headers) { +// ylib::KeyValue kv; +// kv.name = iter->first; +// kv.value = iter->second; +// extra->req.response_headers.push_back(kv); +// } +// } +// +// delete[] header; +// // 取请求方式 +// extra->req.method = ((IHttpServer*)rp->server()->hpserver())->GetMethod((CONNID)rp->connid()); +// } +// // 符合缓存 +// { +// auto cache = rp->website()->cache(); +// if(cache->enable()) +// { +// if(cache->find_ext(rp->filepath())){ +// std::string cache_filepath = cache->make_cache_filepath(rp->filepath()); +// extra->cache.close(); +// if(extra->cache.open(cache_filepath) == false){ +// ylib::log->error("create open cache file failed! path:"+cache_filepath,"http_agent "); +// }else{ +// extra->cache.clear(); +// ylib::file::remove(cache_filepath+".header"); +// ylib::file::remove(cache_filepath+".conf"); +// } +// } +// } +// +// } +// +//#if 0 +// std::cout<<"======================HEADER=========================="<req.headers.size();i++){ +// std::cout<req.headers[i].name.c_str()<<":\t"<req.headers[i].value.c_str()<agent->Connect(proxy->remote_ipaddress.c_str(), proxy->remote_port, &hpcid, (PVOID)extra) == false) +// { +//#if HTTP_AGENT_PRINT == 1 +// ylib::log->error("connect failed.\t"+extra->req.path,"http_agent "); +//#endif +// delete extra; +// return false; +// } +// // 临时附加数据 +// { +// PVOID exts = 0; +// if (((IHttpServer*)rp->server()->hpserver())->GetConnectionExtra((CONNID)rp->connid(), &exts) == false){ +// agent->Disconnect((CONNID)hpcid); +//#if HTTP_AGENT_PRINT == 1 +// ylib::log->error("get server extra failed,"+extra->req.path,"http_agent "); +//#endif +// return false; +// } +// ((temp_recv*)exts)->agent_connid = hpcid; +// ((temp_recv*)exts)->agent_ssl = proxy->ssl; +// } +// return true; +//} +//void* ylib::network::http::agent::get() +//{ +// return m_agent; +//} +//ylib::network::http::agent::agent() +//{ +// m_agent = nullptr; +// m_agent_ssl = nullptr; +// m_listener = new http_agent_listener; +// m_listener->m_agent = this; +// m_agent_ssl = HP_Create_HttpsAgent(m_listener); +// m_agent = HP_Create_HttpAgent(m_listener); +//} +//ylib::network::http::agent::~agent() +//{ +// stop(); +// HP_Destroy_HttpAgent((IHttpAgent*)m_agent); +// HP_Destroy_HttpsAgent((IHttpAgent*)m_agent_ssl); +//} +//void ylib::network::http::agent::stop() +//{ +// ((IHttpAgent*)m_agent)->Stop(); +// ((IHttpAgent*)m_agent_ssl)->Stop(); +// ((IHttpAgent*)m_agent_ssl)->Wait(); +// ((IHttpAgent*)m_agent_ssl)->Wait(); +//} +//bool ylib::network::http::agent::start() +//{ +// //return true; +// ((IHttpAgent*)m_agent_ssl)->CleanupSSLContext(); +// if (((IHttpAgent*)m_agent_ssl)->SetupSSLContext() == false) +// { +// m_lastErrorDesc = "SetupSSLContextFailed, " + std::to_string((uint32)SYS_GetLastError()); +// return false; +// } +// if(((IHttpAgent*)m_agent_ssl)->Start() == false){ +// m_lastErrorDesc = "SSLHttpAgent start failed."; +// return false; +// } +// if(((IHttpAgent*)m_agent)->Start() == false){ +// m_lastErrorDesc = "HttpAgent start failed."; +// ((IHttpAgent*)m_agent_ssl)->Stop(); +// ((IHttpAgent*)m_agent_ssl)->Wait(); +// return false; +// +// } +// return true; +// +//} +//void ylib::network::http::agent::disconnect(bool ssl,uint64 connid) +//{ +// if(ssl) +// ((IHttpAgent*)m_agent_ssl)->Disconnect((CONNID)connid,TRUE); +// else +// ((IHttpAgent*)m_agent)->Disconnect((CONNID)connid,TRUE); +//} +//#endif diff --git a/src/net/http_client_plus.cpp b/src/net/http_client_plus.cpp index eca24e0..b8c8a23 100644 --- a/src/net/http_client_plus.cpp +++ b/src/net/http_client_plus.cpp @@ -327,7 +327,7 @@ void ylib::network::http::client_plus::set_timeout(uint32 connect_msec, uint32 r } bool ylib::network::http::client_plus::del(const std::string& url, const std::map& value) { - m_method = network::http::DEL; + m_method = "DELETE"; std::string param_str; for_iter(iter, value) param_str += (param_str.length() == 0 ? "" : "&") + iter->first + "=" + iter->second; @@ -343,7 +343,7 @@ bool ylib::network::http::client_plus::del(const std::string& url, const std::ma bool ylib::network::http::client_plus::get(const std::string& url, const std::map& value,bool wait) { m_request_wait = wait; - m_method = network::http::GET; + m_method = "GET"; std::string param_str; for_iter(iter, value) @@ -391,16 +391,16 @@ bool ylib::network::http::client_plus::post(const std::string& url, const ylib:: m_request_body = value; return post(url); } -bool ylib::network::http::client_plus::post(const std::string& url, const http::make_form& value) -{ - std::string boundary; - value.make(m_request_body, boundary); - m_headers_request.set("Content-Type", "boundary=" + boundary + "; multipart/form-data"); - return post(url); -} +//bool ylib::network::http::client_plus::post(const std::string& url, const http::make_form& value) +//{ +// std::string boundary; +// value.make(m_request_body, boundary); +// m_headers_request.set("Content-Type", "boundary=" + boundary + "; multipart/form-data"); +// return post(url); +//} bool ylib::network::http::client_plus::head(const std::string& url) { - m_method = network::http::HEAD; + m_method = "HEAD"; if (!init()) return false; if (!parseurl(url)) @@ -551,34 +551,14 @@ bool ylib::network::http::client_plus::request() m_listener->m_recv_state = 0; const char* method; - switch (m_method) + + if (m_method == "GET") { - case ylib::network::http::GET: - method = "GET"; + //【缓存】置头 + if (m_cache != nullptr) { - //【缓存】置头 - if (m_cache != nullptr && m_method == GET) - { - m_cache->set_header(this, m_url); - } + m_cache->set_header(this, m_url); } - break; - case ylib::network::http::POST: - method = "POST"; - break; - case ylib::network::http::PUT: - method = "PUT"; - break; - case ylib::network::http::DEL: - method = "DELETE"; - break; - case ylib::network::http::HEAD: - method = "HEAD"; - break; - default: - m_lastErrorDesc = "Unsupported request type"; - return false; - break; } //置Cookie { @@ -653,7 +633,7 @@ bool ylib::network::http::client_plus::request() if(!result) return false; //【缓存】判断缓存 - if (m_cache != nullptr && m_method == GET) + if (m_cache != nullptr && m_method == "GET") { bool cache = false; if (this->status() == 304) @@ -675,7 +655,7 @@ bool ylib::network::http::client_plus::request() bool ylib::network::http::client_plus::post(const std::string& url) { - m_method = network::http::POST; + m_method = "POST"; if(!init()) return false; if(!parseurl(url)) diff --git a/src/net/http_controller.cpp b/src/net/http_controller.cpp index 89d580d..29fc036 100644 --- a/src/net/http_controller.cpp +++ b/src/net/http_controller.cpp @@ -1,220 +1,220 @@ -/*Software License - -Copyright(C) 2024[liuyingjie] -License Terms -Usage Rights - -Any individual or entity is free to use, copy, and distribute the binary form of this software without modification to the source code, without the need to disclose the source code. -If the source code is modified, the modifications must be open - sourced under the same license.This means that the modifications must be disclosed and accompanied by a copy of this license. -Future Versions Updates -From this version onwards, all future releases will be governed by the terms of the latest version of the license.This license will automatically be nullified and replaced by the new version. -Users must comply with the terms of the new license issued in future releases. -Liability and Disclaimer -This software is provided “as is”, without any express or implied warranties, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non - infringement.In no event shall the author or copyright holder be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. -Contact Information -If you have any questions, please contact us: 1585346868@qq.com Or visit our website fwlua.com. -*/ - -#include "net/http_controller.h" -#if USE_NET_HTTP_WEBSITE - -#include "base/exception.h" -ylib::network::http::controller::controller() -{ - m_reqpack = nullptr; -} -ylib::network::http::controller::~controller() -{ - -} - -std::string ylib::network::http::controller::qry_string(const std::string& name, bool exception) -{ - - std::string value; - bool result = request_param(name, value); - - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return ""; - } - return value; -} -int32 ylib::network::http::controller::qry_int32(const std::string& name, bool exception) -{ - std::string _param_value_; - bool result = request_param(name, _param_value_); - int32 value = ylib::stoi(_param_value_); - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return 0; - } - if (!strutils::is_num(_param_value_)) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' not int32 type"); - else - return 0; - - } - return value; -} -uint32 ylib::network::http::controller::qry_uint32(const std::string& name, bool exception) -{ - std::string _param_value_; - bool result = request_param(name, _param_value_); - uint32 value =ylib::stoi(_param_value_); - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return 0; - } - if (!strutils::is_num(_param_value_)) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' not uint32 type"); - else - return 0; - } - return value; -} -int64 ylib::network::http::controller::qry_int64(const std::string& name, bool exception) -{ - std::string _param_value_; - bool result = request_param(name, _param_value_); - int64 value = ylib::stoll(_param_value_); - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return 0; - } - if (!strutils::is_num(_param_value_)) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' not int64 type"); - else - return 0; - - } - return value; -} -uint64 ylib::network::http::controller::qry_uint64(const std::string& name, bool exception) -{ - std::string _param_value_; - bool result = request_param(name, _param_value_); - uint64 value = ylib::stoull(_param_value_); - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return 0; - } - if (!strutils::is_num(_param_value_)) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' not uint64 type"); - else - return 0; - } - return value; -} -double ylib::network::http::controller::qry_double(const std::string& name, bool exception) -{ - std::string _param_value_; - bool result = request_param(name, _param_value_); - double value = ylib::stod(_param_value_); - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return 0.0f; - } - return value; -} -float ylib::network::http::controller::qry_float(const std::string& name, bool exception) -{ - std::string _param_value_; - bool result = request_param(name, _param_value_); - float value = ylib::stof(_param_value_); - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return 0.0f; - } - return value; -} -bool ylib::network::http::controller::qry_empty(const std::string& name, bool exception) -{ - if (request()->parser()->url_param_exist(name) == false && request()->parser()->body_param_exist(name) == false) - return false; - return true; -} -bool ylib::network::http::controller::qry_bool(const std::string& name, bool exception) -{ - std::string _param_value_; - bool result = request_param(name, _param_value_); - if (!result) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + "' was not found"); - else - return false; - } - return _param_value_ == "true"; -} -ylib::buffer ylib::network::http::controller::qry_buffer(const std::string& name, bool exception) -{ - network::http::form_info form_info; - if (request()->parser()->form()->get(name, form_info) == false) - { - if (exception == true) - throw ylib::exception("The request parameter '" + name + " was not found"); - else - return ylib::buffer(); - } - - if (form_info.start != -1 && form_info.length != -1 && form_info.length != 0) - { - return m_reqpack->data().sub(form_info.start,form_info.length); - } - else - { - if (exception == true) - throw ylib::exception("failed to parse buffer, start=" + std::to_string(form_info.start) + ", length=" + std::to_string(form_info.length)); - else - return ylib::buffer(); - } -} -bool ylib::network::http::controller::request_param(const std::string& name, std::string& value) -{ - if (request()->parser()->url_param(name, value) == false) - return request()->parser()->body_param(name, value); - return true; -} -void ylib::network::http::controller::send(const ylib::json& data) -{ - response()->send(data); -} -network::http::request* ylib::network::http::controller::request() -{ - return m_reqpack->request(); -} -network::http::response* ylib::network::http::controller::response() -{ - return m_reqpack->response(); -} -#endif +///*Software License +// +//Copyright(C) 2024[liuyingjie] +//License Terms +//Usage Rights +// +//Any individual or entity is free to use, copy, and distribute the binary form of this software without modification to the source code, without the need to disclose the source code. +//If the source code is modified, the modifications must be open - sourced under the same license.This means that the modifications must be disclosed and accompanied by a copy of this license. +//Future Versions Updates +//From this version onwards, all future releases will be governed by the terms of the latest version of the license.This license will automatically be nullified and replaced by the new version. +//Users must comply with the terms of the new license issued in future releases. +//Liability and Disclaimer +//This software is provided “as is”, without any express or implied warranties, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non - infringement.In no event shall the author or copyright holder be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. +//Contact Information +//If you have any questions, please contact us: 1585346868@qq.com Or visit our website fwlua.com. +//*/ +// +//#include "net/http_controller.h" +//#if USE_NET_HTTP_WEBSITE +// +//#include "base/exception.h" +//ylib::network::http::controller::controller() +//{ +// m_reqpack = nullptr; +//} +//ylib::network::http::controller::~controller() +//{ +// +//} +// +//std::string ylib::network::http::controller::qry_string(const std::string& name, bool exception) +//{ +// +// std::string value; +// bool result = request_param(name, value); +// +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return ""; +// } +// return value; +//} +//int32 ylib::network::http::controller::qry_int32(const std::string& name, bool exception) +//{ +// std::string _param_value_; +// bool result = request_param(name, _param_value_); +// int32 value = ylib::stoi(_param_value_); +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return 0; +// } +// if (!strutils::is_num(_param_value_)) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' not int32 type"); +// else +// return 0; +// +// } +// return value; +//} +//uint32 ylib::network::http::controller::qry_uint32(const std::string& name, bool exception) +//{ +// std::string _param_value_; +// bool result = request_param(name, _param_value_); +// uint32 value =ylib::stoi(_param_value_); +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return 0; +// } +// if (!strutils::is_num(_param_value_)) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' not uint32 type"); +// else +// return 0; +// } +// return value; +//} +//int64 ylib::network::http::controller::qry_int64(const std::string& name, bool exception) +//{ +// std::string _param_value_; +// bool result = request_param(name, _param_value_); +// int64 value = ylib::stoll(_param_value_); +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return 0; +// } +// if (!strutils::is_num(_param_value_)) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' not int64 type"); +// else +// return 0; +// +// } +// return value; +//} +//uint64 ylib::network::http::controller::qry_uint64(const std::string& name, bool exception) +//{ +// std::string _param_value_; +// bool result = request_param(name, _param_value_); +// uint64 value = ylib::stoull(_param_value_); +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return 0; +// } +// if (!strutils::is_num(_param_value_)) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' not uint64 type"); +// else +// return 0; +// } +// return value; +//} +//double ylib::network::http::controller::qry_double(const std::string& name, bool exception) +//{ +// std::string _param_value_; +// bool result = request_param(name, _param_value_); +// double value = ylib::stod(_param_value_); +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return 0.0f; +// } +// return value; +//} +//float ylib::network::http::controller::qry_float(const std::string& name, bool exception) +//{ +// std::string _param_value_; +// bool result = request_param(name, _param_value_); +// float value = ylib::stof(_param_value_); +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return 0.0f; +// } +// return value; +//} +//bool ylib::network::http::controller::qry_empty(const std::string& name, bool exception) +//{ +// if (request()->parser()->url_param_exist(name) == false && request()->parser()->body_param_exist(name) == false) +// return false; +// return true; +//} +//bool ylib::network::http::controller::qry_bool(const std::string& name, bool exception) +//{ +// std::string _param_value_; +// bool result = request_param(name, _param_value_); +// if (!result) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + "' was not found"); +// else +// return false; +// } +// return _param_value_ == "true"; +//} +//ylib::buffer ylib::network::http::controller::qry_buffer(const std::string& name, bool exception) +//{ +// network::http::form_info form_info; +// if (request()->parser()->form()->get(name, form_info) == false) +// { +// if (exception == true) +// throw ylib::exception("The request parameter '" + name + " was not found"); +// else +// return ylib::buffer(); +// } +// +// if (form_info.start != -1 && form_info.length != -1 && form_info.length != 0) +// { +// return m_reqpack->data().sub(form_info.start,form_info.length); +// } +// else +// { +// if (exception == true) +// throw ylib::exception("failed to parse buffer, start=" + std::to_string(form_info.start) + ", length=" + std::to_string(form_info.length)); +// else +// return ylib::buffer(); +// } +//} +//bool ylib::network::http::controller::request_param(const std::string& name, std::string& value) +//{ +// if (request()->parser()->url_param(name, value) == false) +// return request()->parser()->body_param(name, value); +// return true; +//} +//void ylib::network::http::controller::send(const ylib::json& data) +//{ +// response()->send(data); +//} +//network::http::request* ylib::network::http::controller::request() +//{ +// return m_reqpack->request(); +//} +//network::http::response* ylib::network::http::controller::response() +//{ +// return m_reqpack->response(); +//} +//#endif diff --git a/src/net/http_parser.cpp b/src/net/http_parser.cpp deleted file mode 100644 index fb91ffd..0000000 --- a/src/net/http_parser.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/*Software License - -Copyright(C) 2024[liuyingjie] -License Terms -Usage Rights - -Any individual or entity is free to use, copy, and distribute the binary form of this software without modification to the source code, without the need to disclose the source code. -If the source code is modified, the modifications must be open - sourced under the same license.This means that the modifications must be disclosed and accompanied by a copy of this license. -Future Versions Updates -From this version onwards, all future releases will be governed by the terms of the latest version of the license.This license will automatically be nullified and replaced by the new version. -Users must comply with the terms of the new license issued in future releases. -Liability and Disclaimer -This software is provided “as is”, without any express or implied warranties, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non - infringement.In no event shall the author or copyright holder be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. -Contact Information -If you have any questions, please contact us: 1585346868@qq.com Or visit our website fwlua.com. -*/ - -#include "net/http_parser.h" -#if USE_NET_HTTP_WEBSITE -#include "util/file.h" -#include "util/strutils.h" -network::http::parser::parser() -{ - m_method = network::http::ALL; -} - -network::http::parser::~parser() -{ - -} - -const ylib::json& ylib::network::http::parser::json() -{ - return m_json_param; -} - -std::string ylib::network::http::parser::text() -{ - return m_data.to_string(); -} - -bool network::http::parser::init(const std::string &url,const network::http::method& method,const ylib::buffer &data, const std::string &content_type) -{ - m_url = url; - m_data = data; - m_content_type = content_type; - m_method = method; - - - /*解析URL*/ - parse_url(m_url,m_url_param); - switch (m_method) { - case network::http::GET: - break; - case network::http::POST: - { - if(content_type.find("application/x-www-form-urlencoded") != -1) - { - parse_url(m_data.to_string(),m_body_param); - } - else if(content_type.find("application/json") != -1) - { - parse_json(); - } - else if(content_type.find("multipart/form-data") !=-1) - { - parse_form(); - } - } - break; - default: - break; - } - return true; -} - -bool network::http::parser::url_param(const std::string &name, std::string &value) -{ - return read_url_param(m_url_param,name,value); -} - -bool ylib::network::http::parser::url_param_exist(const std::string& name) -{ - return m_url_param.find(name) != m_url_param.end(); -} - -std::vector network::http::parser::url_param_names() -{ - std::vector names; - for_iter(iter,m_url_param) - names.push_back(iter->first); - return names; -} - -bool network::http::parser::body_param(const std::string &name, std::string &value) -{ - if(m_method == POST) - { - if(m_content_type.find("application/x-www-form-urlencoded") != -1) - { - return read_url_param(m_body_param,name,value); - } - else if(m_content_type.find("application/json") != -1) - { - if(!m_json_param.exist(name)) - return false; - if(m_json_param[name].is_number()){ - value = std::to_string(m_json_param[name].to()); - }else{ - value = m_json_param[name].to(); - } - return true; - } - return false; - } - return false; -} - -bool ylib::network::http::parser::body_param_exist(const std::string& name) -{ - if (m_method == POST) - { - if (m_content_type.find("application/x-www-form-urlencoded") != -1) - { - return m_body_param.find(name) != m_body_param.end(); - } - else if (m_content_type.find("application/json") != -1) - { - return m_json_param.exist(name); - } - } - return false; -} - -std::vector network::http::parser::body_param_names() -{ - - std::vector names; - if(m_method == POST) - { - if (m_content_type.find("application/x-www-form-urlencoded") != -1) - { - for_iter(iter,m_body_param) - names.push_back(iter->first); - } - else if (m_content_type.find("application/json") != -1) - { - return m_json_param.keys(); - } - } - return names; -} - -network::http::form_parser *network::http::parser::form() -{ - return &m_form; -} - -void network::http::parser::parse_url(const std::string &url, std::map &map) -{ - map.clear(); - auto ps = strutils::split(url,'&'); - for(size_t i=0;i(pi[0],pi[1])); - } -} -void network::http::parser::parse_json() -{ - m_json_param.parse(m_data.to_string()); -} - -void network::http::parser::parse_form() -{ - m_form.parse(&m_data); -} - -bool network::http::parser::read_url_param(const std::map &map, const std::string &name, std::string &value) -{ - auto iter = map.find(name); - if(iter == map.end()) - return false; - value = iter->second; - return true; -} - -network::http::form_parser::form_parser() -{ - -} - -network::http::form_parser::~form_parser() -{ - -} - -std::vector network::http::form_parser::names() -{ - std::vector result; - for_iter(iter,m_infos) - result.push_back(iter->first); - return result; -} - -bool network::http::form_parser::get(const std::string &name, form_info &info) -{ - auto iter = m_infos.find(name); - if(iter == m_infos.end()) - return false; - info = iter->second; - return true; -} - -bool network::http::form_parser::write_file(const std::string &name, const std::string &filepath) -{ - auto iter = m_infos.find(name); - if(iter == m_infos.end()) - return false; - return ylib::file::write(filepath,(const char*)m_data->data()+iter->second.start,iter->second.length); -} - -bool network::http::form_parser::parse(buffer *data) -{ - this->m_data = data; - - std::vector starts; - std::vector lengths; - parse_count(starts,lengths); - - - for(size_t i=0;i &starts, std::vector &lengths) -{ - - - ylib::buffer cut_flag; - { - int32 curr_idx = 0; - while (char c = getchar(curr_idx++)) - { - if (c == '\r' && getchar(curr_idx) == '\n') - { - curr_idx++; - break; - } - else - cut_flag.append(c); - } - } - - auto idxVct = m_data->find_list(cut_flag); - for (size_t i = 0; i < idxVct.size(); i++) - { - size_t startIdx = idxVct[i] + cut_flag.length() + 2; - if (i + 1 != idxVct.size()) - { - starts.push_back((uint32)startIdx); - lengths.push_back((uint32)(idxVct[i + 1] - idxVct[i] - cut_flag.length() - 2)); - } - } -} - -void network::http::form_parser::parse_form(uint32 start,uint32 length) -{ - auto parse_paraminfo_secondkv=[](const ylib::buffer& buf)->ylib::KeyValue - { - ylib::KeyValue kv; - buffer cutV; - cutV.resize(1); - cutV[0] = '='; - auto cdIdx = buf.find(cutV, 0); - if (cdIdx == -1) - return kv; - kv.name = buf.sub(0, cdIdx).to_string(); - kv.value = buf.sub(cdIdx + 2, buf.length() - 3 - cdIdx).to_string(); - return kv; - }; - - - ylib::buffer form_data(m_data->data()+start,length); - - ylib::buffer fh; - ylib::buffer fh2; - ylib::buffer cs_ln; - fh.resize(2); - fh2.resize(2); - cs_ln.resize(2); - fh[0] = ';'; - fh[1] = ' '; - fh2[0] = ':'; - fh2[1] = ' '; - cs_ln[0] = '\r'; - cs_ln[1] = '\n'; - - auto div = form_data.find_list(cs_ln); - if (div.size() == -1) - return; - - form_info forminfo; - //数据 - if (div.size() == 3) - { - forminfo.start = div[1] + 2+start; - forminfo.length = div[div.size() - 1] - 2 - div[1]; - } - else if (div.size() > 3) - { - forminfo.start = div[2] + 2+start; - forminfo.length = div[div.size() - 1] - 2 - div[2]; - - auto ContentType = form_data.sub(div[0] + 2, div[1] - 2 - div[0]); - // Content-Type - auto cdIdx = ContentType.find(fh2); - if (cdIdx == -1) - return; - forminfo.content_type = ContentType.sub(cdIdx + 2, ContentType.length() - 2 - cdIdx); - } - else - return; - - //配置项 - auto info = form_data.sub(div[0]); - std::string t = info; - auto info_vct = info.find_list(fh); - if (info_vct.size() == 0) - return; - - // Content-Disposition - auto contentDisposition = info.sub(info_vct[0]); - auto cdIdx = contentDisposition.find(fh2); - if (cdIdx == -1) - return; - - forminfo.disposition = contentDisposition.sub(cdIdx + 2, contentDisposition.length() - 2 - cdIdx); - - - - if (info_vct.size() == 1) - { - auto kv = parse_paraminfo_secondkv(info.sub(info_vct[0] + 2, info.length() - info_vct[0] - 2)); - if (kv.name == "name") - forminfo.name = kv.value; - else if (kv.name == "filename") - forminfo.filename = kv.value; - } - else - { - for (size_t i = 0; i < info_vct.size(); i++) - { - ylib::buffer info_sub; - if (info_vct.size() == i + 1) - info_sub = info.sub(info_vct[i] + 2, info.length() - info_vct[i] - 2); - else - info_sub = info.sub(info_vct[i] + 2, info_vct[i + 1] - info_vct[i] - 2); - auto kv = parse_paraminfo_secondkv(info_sub); - if (kv.name == "name") - forminfo.name = kv.value; - else if (kv.name == "filename") - forminfo.filename = kv.value; - } - } - m_infos.insert(std::pair(forminfo.name,forminfo)); -} - -char network::http::form_parser::getchar(size_t index) -{ - if (index + 1 > m_data->length()) - throw 0; - return *(m_data->data() + index); -} -#endif diff --git a/src/net/http_reqpack.cpp b/src/net/http_reqpack.cpp index 3269983..91fab20 100644 --- a/src/net/http_reqpack.cpp +++ b/src/net/http_reqpack.cpp @@ -23,100 +23,40 @@ If you have any questions, please contact us: 1585346868@qq.com Or visit our web #include "net/http_response.h" #include "util/time.h" #define HPSERVER -ylib::network::http::reqpack::reqpack() +ylib::network::http::reqpack::reqpack(const std::string& url, const std::string& host, const ylib::buffer& data, uint64 connid, network::http::server* server, network::http::website* website) + :m_url(url) + ,m_host(host) + ,m_data(data) + ,m_connid(connid) + ,m_server(server) { - -} + this->website(website); + m_filepath = strutils::F(((IHttpServer*)m_server->hpserver())->GetUrlField((CONNID)m_connid, HUF_PATH)); + // 防止访问上级目录 + m_filepath = strutils::remove(m_filepath, ".."); + +} ylib::network::http::reqpack::~reqpack() { - clear(); } - -void ylib::network::http::reqpack::init(const std::string& url,const std::string& host,const ylib::buffer& data, uint64 connid, network::http::server* server) -{ - m_host = host; - m_url = url; - m_method = network::http::ALL; - m_request = nullptr; - m_response = nullptr; - m_data = data; - m_server = server; - m_connid = connid; - m_website = nullptr; - m_begin_msec = time::now_msec(); -} - -void ylib::network::http::reqpack::clear() -{ - this->m_data.clear(); - if (this->m_request != nullptr) - delete this->m_request; - if (this->m_response != nullptr) - delete this->m_response; - - m_host.clear(); - m_method = network::http::OTHER; - m_begin_msec = 0; - m_filepath.clear(); - m_server = nullptr; - m_referrer.clear(); - m_connid = 0; - m_website = nullptr; - m_url.clear(); - m_remote_ipaddress.clear(); - m_request = nullptr; - m_response = nullptr; -} - -network::http::request *network::http::reqpack::request() +const std::shared_ptr& network::http::reqpack::request() { if(m_request == nullptr){ - m_request = new network::http::request; - m_request->m_reqpack = this; + m_request = std::make_shared(this); m_request->center(m_server->center()); - m_request->website(website()); + m_request->website(this->website()); } return m_request; } -network::http::response *network::http::reqpack::response() +const std::shared_ptr& network::http::reqpack::response() { if(m_response == nullptr){ - m_response = new network::http::response; + m_response = std::make_shared(this); m_response->center(m_server->center()); - m_response->website(website()); - m_response->init(this); + m_response->website(this->website()); } return m_response; } -network::http::method network::http::reqpack::method() -{ - if (m_method == network::http::ALL) - { - std::string method = strutils::F(((IHttpServer*)m_server->hpserver())->GetMethod((CONNID)m_connid)); - if (method == "GET") - m_method = network::http::GET; - else if (method == "POST") - m_method = network::http::POST; - else - m_method = network::http::OTHER; - } - return m_method; -} -const std::string& network::http::reqpack::filepath() -{ - if (m_filepath.empty()) - { - - m_filepath = strutils::F(((IHttpServer*)m_server->hpserver())->GetUrlField((CONNID)m_connid, HUF_PATH)); - // 防止访问上级目录 - m_filepath = strutils::remove(m_filepath, ".."); - } - return m_filepath; -} -void network::http::reqpack::filepath(const std::string &path) -{ - m_filepath = path; -} #endif diff --git a/src/net/http_request.cpp b/src/net/http_request.cpp index c8842d2..fe5adc7 100644 --- a/src/net/http_request.cpp +++ b/src/net/http_request.cpp @@ -25,12 +25,13 @@ If you have any questions, please contact us: 1585346868@qq.com Or visit our web #include "net/http_reqpack.h" #include "net/http_center.h" #include "net/http_website.h" +#include "net/util.h" #include "HPSocket/HPSocket.h" #define HPSERVER ((IHttpServer*)m_reqpack->server()->hpserver()) -ylib::network::http::request::request() +ylib::network::http::request::request(network::http::reqpack* reqpack):m_reqpack(reqpack) { - m_reqpack = nullptr; + } ylib::network::http::request::~request() { @@ -46,10 +47,11 @@ bool ylib::network::http::request::header(const std::string &name, std::string & return true; } -ylib::network::http::method ylib::network::http::request::method() +std::string ylib::network::http::request::method() { - - return m_reqpack->method(); + if (m_method.empty()) + m_method = strutils::change_case(strutils::F(HPSERVER->GetMethod((CONNID)m_reqpack->connid())),true); + return m_method; } std::string ylib::network::http::request::filepath() @@ -61,16 +63,6 @@ std::string ylib::network::http::request::host() { return m_reqpack->host(); } -#if 0 -bool ylib::network::http::request::cookie(const std::string &name, std::string &value) -{ - LPCSTR lpszValue = nullptr; - if (HPSERVER->GetCookie((CONNID)m_reqpack->connid(), name.c_str(), &lpszValue) == false) - return false; - value = strutils::F(lpszValue); - return true; -} -#endif network::http::session& ylib::network::http::request::session(const std::string& session_id) { if (session_id.empty()) @@ -78,51 +70,140 @@ network::http::session& ylib::network::http::request::session(const std::string& m_session.init(website(), session_id); return m_session; } -std::string ylib::network::http::request::token() -{ - std::string token; - header("token", token); - return token; -} network::http::reqpack* ylib::network::http::request::reqpack() { return m_reqpack; } -network::http::parser* ylib::network::http::request::parser() +ylib::AddressPort ylib::network::http::request::remote() { - std::string content_type; + ylib::AddressPort ap; + m_reqpack->server()->remote(m_reqpack->connid(), ap.address, ap.port); + return ap; +} +bool ylib::network::http::request::get_url_param(const std::string& name, std::string& value) +{ + if (m_url_param == nullptr) { - header("Content-Type", content_type); - if (content_type == "") + m_url_param = std::make_shared>(); + // 解析URL参数 + std::string url_query = strutils::F(HPSERVER->GetUrlField((CONNID)m_reqpack->connid(), HUF_QUERY)); + auto results = strutils::split(url_query, "&"); + for (size_t i = 0; i < results.size(); i++) { - content_type = "application/x-www-form-urlencoded"; + std::string key; + std::string value; + auto arr = strutils::split(results[i], '='); + if (arr.size() > 0) + key = arr[0]; + if (arr.size() > 1) + value = arr[1]; + m_url_param->emplace(key, value); } } - - m_parser.init(strutils::F(HPSERVER->GetUrlField((CONNID)m_reqpack->connid(), HUF_QUERY)), m_reqpack->method(), m_reqpack->data(), content_type); - return &m_parser; + // 查找 + auto iter = m_url_param->find(name); + if (iter == m_url_param->end()) + return false; + value = iter->second; + return true; } - -std::string ylib::network::http::request::remote_ipaddress(bool find_header,const std::string& inside_ipaddress) +bool ylib::network::http::request::get_body_param(const std::string& name, std::string& value) { - bool is_inside = false; - std::string ipaddress; - ushort port; - reqpack()->server()->remote(reqpack()->connid(),ipaddress,port); + if (m_body_param == nullptr) { - if(strutils::left(ipaddress,2) == "10" || strutils::left(ipaddress,6) == "172.16" || strutils::left(ipaddress,7) == "192.168" || (ipaddress == inside_ipaddress && inside_ipaddress != "")) - is_inside = true; + m_body_param = std::make_shared>(); + if (content_type("application/x-www-form-urlencoded")) + { + auto results = strutils::split(m_reqpack->body(), "&"); + for (size_t i = 0; i < results.size(); i++) + { + std::string key; + std::string value; + auto arr = strutils::split(results[i], '='); + if (arr.size() > 0) + key = arr[0]; + if (arr.size() > 1) + value = arr[1]; + m_body_param->emplace(key, value); + } + } + else if (content_type("application/json")) + { + auto data_json = ylib::json::from(m_reqpack->body()); + auto keys = data_json.keys(); + for (size_t i = 0; i < keys.size(); i++) + { + std::string strvalue = data_json[keys[i]].to(); + double dobvalue = data_json[keys[i]].to(); + + if (strvalue.empty()) + { + if (dobvalue == 0.0) + continue; + else + m_body_param->emplace(keys[i], std::to_string(dobvalue)); + } + else + m_body_param->emplace(keys[i],strvalue); + } + } } - if(find_header && is_inside) - header("X-Real-IP",ipaddress); - return ipaddress; + // 查找 + auto iter = m_body_param->find(name); + if (iter == m_body_param->end()) + return false; + value = iter->second; + return true; } -ushort ylib::network::http::request::remote_port() +const std::shared_ptr>& ylib::network::http::request::multipart() { - std::string ipaddress; - ushort port; - reqpack()->server()->remote(reqpack()->connid(), ipaddress, port); - return port; + if (m_form == nullptr) + { + m_form = std::make_shared>(); + if (content_type("multipart/form-data")) + { + std::string header_value; + if (header("Content-Type", header_value)) + { + auto arr = strutils::split(header_value, ';'); + for (size_t i = 0; i < arr.size(); i++) + { + if (arr[i].find("boundary") != -1) + { + auto kv = strutils::split(strutils::trim(arr[i], { ' ' }), "="); + if (kv.size() == 2) + { + network::parse_multipart_form_data(m_reqpack->body(), kv[1], *m_form.get()); + } + break; + } + } + + } + + } + } + return m_form; } +bool ylib::network::http::request::content_type(std::string type_name) +{ + type_name = strutils::change_case(type_name, false); + std::string header_value; + if (header("Content-Type", header_value)) + { + auto results = strutils::split(header_value, ';'); + for (size_t i = 0; i < results.size(); i++) + { + if (strutils::change_case(results[i], false).find(type_name) != -1) + return true; + } + } + return false; +} +ylib::buffer& ylib::network::http::request::body() +{ + return m_reqpack->body(); +} + #endif diff --git a/src/net/http_response.cpp b/src/net/http_response.cpp index 18d4ad5..eceec2a 100644 --- a/src/net/http_response.cpp +++ b/src/net/http_response.cpp @@ -37,10 +37,8 @@ If you have any questions, please contact us: 1585346868@qq.com Or visit our web #else #define HEADER_SET(NAME,VALUE) m_headers.emplace(NAME,VALUE) #endif -ylib::network::http::response::response() +ylib::network::http::response::response(network::http::reqpack* reqpack):m_reqpack(reqpack) { - m_reqpack = nullptr; - m_response = false; } ylib::network::http::response::~response() @@ -56,11 +54,6 @@ ylib::network::http::response::~response() send((std::string)"The server does not return any data to the browser", 500, "Internal Server Error"); } } - -void ylib::network::http::response::init(reqpack* rp) -{ - this->m_reqpack = rp; -} bool ylib::network::http::response::send(const char* buf, size_t buf_len, ushort stateNum, const std::string& stateDesc) { @@ -327,11 +320,8 @@ bool ylib::network::http::response::forward(const std::string& filepath) if(m_response == true) return false; m_response = true; - network::http::reqpack* reqpack = new network::http::reqpack; - reqpack->init(m_reqpack->url(),m_reqpack->host(), m_reqpack->data(), m_reqpack->connid(), m_reqpack->server()); - reqpack->filepath(filepath); - reqpack->website(this->website()); - reqpack->extra(m_reqpack->extra()); + network::http::reqpack* reqpack = new network::http::reqpack(filepath,m_reqpack->host(),m_reqpack->body(),m_reqpack->connid(), m_reqpack->server(), m_reqpack->website()); + reqpack->extra() = m_reqpack->extra(); m_reqpack->website()->router()->push(reqpack); return true; diff --git a/src/net/http_router.cpp b/src/net/http_router.cpp index 6090094..854d002 100644 --- a/src/net/http_router.cpp +++ b/src/net/http_router.cpp @@ -150,7 +150,7 @@ void ylib::network::http::router::__thread_callback(reqpack* rp) // 其它 if (m_callback_other != nullptr) - m_callback_other(rp->request(), rp->response()); + m_callback_other(rp->request().get(), rp->response().get()); } catch (const std::exception& e) { diff --git a/src/net/http_server_lst.cpp b/src/net/http_server_lst.cpp index 23a6b6e..ed4ff5c 100644 --- a/src/net/http_server_lst.cpp +++ b/src/net/http_server_lst.cpp @@ -270,9 +270,10 @@ EnHttpParseResult ylib::network::http::http_server_lst::OnMessageComplete(IHttpS pSender->SendResponse(dwConnID, 200, "OK", nullptr, 0, (const BYTE*)"ONLY_HP_OK", 3); return HPR_OK; #endif - reqpack* rp = nullptr; + network::http::reqpack* rp = nullptr; + temp_recv* tr = nullptr; { - temp_recv* tr = nullptr; + PVOID extra = 0; if (pSender->GetConnectionExtra((CONNID)dwConnID, &extra)) { @@ -283,84 +284,37 @@ EnHttpParseResult ylib::network::http::http_server_lst::OnMessageComplete(IHttpS } else return HPR_OK; - - m_server->qps()->request(tr->data.length()); + } - rp = new reqpack; - rp->init(tr->url,tr->host,tr->data,(uint64)dwConnID,m_server); - } - //ylib::log->info("OnRecv:"+codec::to_gbk(rp->data()->to_string())); - std::string size_name; - { - double size_ld = 0; - if(!rp->data().empty()){ - size_ld = (double)rp->data().length(); - } - size_name = ylib::network::size_name(size_ld,2); - /*if(nstring(pSender->GetMethod(dwConnID)) == "GET" && rp->data()->length() != 0){ - ylib::log->warn("GET have body:"+rp->data()->to_string(),"http_server"); - }*/ - } -#if HTTP_SERVER_PRINT == 1 - // LOG - std::string logstr; - { - logstr.append("[recv ]\t"); - logstr.append(rp->remote()); - logstr.append("\t("); - logstr.append(std::to_string(rp->connid())); - logstr.append(")\t\t"); - logstr.append(pSender->GetMethod(dwConnID)); - logstr.append("\t"); - logstr.append(size_name); - logstr.append("\t"); - logstr.append(rp->host()); - logstr.append(rp->url()); - } -#endif - auto website = m_server->center()->website(rp->host()); + // QPS记录 + m_server->qps()->request(tr->data.length()); + // 查找所属网站 + auto website = m_server->center()->website(tr->host); if (website == nullptr) { - pSender->SendResponse(dwConnID, 404, "Not Found", nullptr, 0, (const BYTE*)"No fount site",12); -#if HTTP_SERVER_PRINT == 1 - logstr.append(" not website("+rp->host()+"):"); - ylib::log->error(logstr,"http_server"); -#endif + pSender->SendResponse(dwConnID, 404, "Not Found", nullptr, 0, (const BYTE*)"No fount site", 12); delete rp; return HPR_OK; } -#if HTTP_SERVER_PRINT == 1 - ylib::log->info(logstr,"http_server"); -#endif - rp->website(website); -#if 0 - rp->request(); - rp->response(); - reqpack::destory(rp); - pSender->SendResponse(dwConnID, 200, "OK", nullptr, 0, (const BYTE*)"V24", 3); - return HPR_OK; + // 创建请求包 + rp = new network::http::reqpack(tr->url, tr->host, tr->data, (uint64)dwConnID, m_server, website); -#endif - auto recvd_callback = website->router()->m_callback_recved; - ylib::buffer end_data; - if (recvd_callback != nullptr) + // 开始前处理请求包 { - recvd_callback(rp->data(), &end_data); - if (end_data.length() != 0) - rp->data() = end_data; + auto recvd_callback = website->router()->m_callback_recved; + ylib::buffer end_data; + if (recvd_callback != nullptr) + { + recvd_callback(rp->body(), &end_data); + if (end_data.length() != 0) + rp->body() = end_data; + } } + - + // 追加置路由 website->router()->push(rp); -#if 0 - std::string filepath = pSender->GetUrlField((CONNID)dwConnID, EnHttpUrlField::HUF_PATH); - - filepath = "/home/nianhua/project/mysql_demo/www"+filepath; - pSender->SendLocalFile(dwConnID,filepath.c_str(),HSC_OK); -#endif - - return HPR_OK; } diff --git a/src/net/http_subscribe.cpp b/src/net/http_subscribe.cpp index a3029ad..abc536d 100644 --- a/src/net/http_subscribe.cpp +++ b/src/net/http_subscribe.cpp @@ -81,7 +81,7 @@ bool network::http::subscribe::trigger(const std::string& url, network::http::re for (size_t i = 0; i < m_list.size(); i++) { if (std::regex_match(url.c_str(), m_list[i].regex)) { - m_list[i].callback(rp->request(),rp->response(), m_list[i].pattern,m_list[i].extra); + m_list[i].callback(rp->request().get(), rp->response().get(), m_list[i].pattern, m_list[i].extra); return true; } } diff --git a/src/net/util.cpp b/src/net/util.cpp index ebb0379..5073f77 100644 --- a/src/net/util.cpp +++ b/src/net/util.cpp @@ -328,6 +328,61 @@ bool ylib::network::is_domain(const std::string& value) { return !is_ipv4(value) && !is_ipv6(value); } +bool ylib::network::parse_multipart_form_data(const ylib::buffer& data, const std::string& boundary, std::vector& parts) +{ + ylib::buffer bbd; + bbd.append("--"+boundary+"\r\n"); + auto bbd_start_list = data.find_list(bbd); + if (bbd_start_list.size() == 0) + return true; + ylib::buffer bbd2; + bbd2.append("--" + boundary + "--\r\n"); + auto bbda_end = data.find(bbd2,bbd_start_list[bbd_start_list.size()-1]); + for (size_t i = 0; i < bbd_start_list.size(); i++) + { + size_t bbd_end = bbd_start_list[i] + bbd.length(); + + auto body_start = data.find("\r\n\r\n",4, bbd_start_list[i] + bbd.length()); + network::http::multipart mult; + // 头部 + std::string header = data.sub(bbd_end, body_start - bbd_end); + { + header = strutils::replace(header,"\r\n",";"); + auto parr = strutils::split(header,";"); + for (size_t f = 0; f < parr.size(); f++) + { + auto aarr = strutils::split(parr[f], ": "); + if (aarr.size() == 1) + aarr = strutils::split(parr[f], '='); + + std::string key, value; + if (aarr.size() > 0) + key = strutils::trim(aarr[0], { ' ' }); + if (aarr.size() > 1) + value = strutils::trim(aarr[1], { ' ' }); + if (key == "name" || key == "filename") + value = strutils::trim(value, {'\"'}); + mult.param.emplace(key, value); + } + } + body_start += 4; + + mult.offset = body_start; + if (i + 1 == bbd_start_list.size()) + { + mult.length = bbda_end - mult.offset - 2; + } + else + { + mult.length = bbd_start_list[i + 1] - mult.offset - 2; + } + body_start += mult.length; + parts.push_back(mult); + } + + + return true; +} #endif