重构请求解析部分

This commit is contained in:
xx
2024-06-20 01:39:32 +08:00
parent b6689cd478
commit 29afc289bb
22 changed files with 1412 additions and 1968 deletions

View File

@@ -26,7 +26,7 @@ namespace ylib
bool post(const std::string& url, const std::map<std::string, std::string>& 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);
/// <summary>
/// 连接代理服务器
@@ -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] 请求

View File

@@ -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
/**********************************************************
* ClassHttp控制器接口
*********************************************************/
//#define check_qry_json(NAME) request()->parser()->json()[NAME].is_empty()
#define qry_json_string(NAME) request()->parser()->json()[NAME].to<std::string>(true)
#define qry_json_uint32(NAME) request()->parser()->json()[NAME].to<uint32>(true)
#define qry_json_uint64(NAME) request()->parser()->json()[NAME].to<uint64>(true)
#define qry_json_int32(NAME) request()->parser()->json()[NAME].to<int32>(true)
#define qry_json_double(NAME) request()->parser()->json()[NAME].to<double>(true)
#define qry_json_short(NAME) request()->parser()->json()[NAME].to<short>(true)
#define qry_json_bool(NAME) request()->parser()->json()[NAME].to<bool>(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
///**********************************************************
// * ClassHttp控制器接口
// *********************************************************/
////#define check_qry_json(NAME) request()->parser()->json()[NAME].is_empty()
//#define qry_json_string(NAME) request()->parser()->json()[NAME].to<std::string>(true)
//#define qry_json_uint32(NAME) request()->parser()->json()[NAME].to<uint32>(true)
//#define qry_json_uint64(NAME) request()->parser()->json()[NAME].to<uint64>(true)
//#define qry_json_int32(NAME) request()->parser()->json()[NAME].to<int32>(true)
//#define qry_json_double(NAME) request()->parser()->json()[NAME].to<double>(true)
//#define qry_json_short(NAME) request()->parser()->json()[NAME].to<short>(true)
//#define qry_json_bool(NAME) request()->parser()->json()[NAME].to<bool>(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

View File

@@ -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<std::string,std::string> 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)();
}
}
}

View File

@@ -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;
};
}
}

View File

@@ -1,130 +0,0 @@
#pragma once
#include "http_define.h"
#if USE_NET_HTTP_WEBSITE
#include <map>
namespace ylib
{
namespace network
{
namespace http
{
class parser;
/*************************************************************************
* classFORM表单解析器
*************************************************************************/
class form_parser {
public:
form_parser();
~form_parser();
std::vector<std::string> 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<uint32>& starts, std::vector<uint32>& lengths);
void parse_form(uint32 start, uint32 length);
char getchar(size_t index);
private:
ylib::buffer* m_data;
std::map<std::string, form_info> 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<std::string> 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<std::string> body_param_names();
/******************************************************************
* function取BODY请求参数名列表
******************************************************************/
form_parser* form();
const std::map<std::string, std::string>& url_param() { return m_url_param; }
const std::map<std::string, std::string>& body_param() { return m_body_param; }
private:
/******************************************************************
* function解析URL
******************************************************************/
void parse_url(const std::string& url, std::map<std::string, std::string>& map);
/******************************************************************
* function解析JSON
******************************************************************/
void parse_json();
/******************************************************************
* function解析FORM表单
******************************************************************/
void parse_form();
/******************************************************************
* function解析URL格式数据
******************************************************************/
bool read_url_param(const std::map<std::string, std::string>& map, const std::string& name, std::string& value);
private:
// URL参数
std::map<std::string, std::string> m_url_param;
// BODY参数
std::map<std::string, std::string> 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

View File

@@ -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
/// <summary>
/// 请求包
/// </summary>
class reqpack:public network::http::interface_
{
public:
reqpack();
/// <summary>
/// 构造函数
/// </summary>
/// <param name="url"></param>
/// <param name="host"></param>
/// <param name="data"></param>
/// <param name="connid"></param>
/// <param name="server"></param>
/// <param name="website"></param>
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;
}
/// <summary>
/// 请求对象
/// </summary>
/// <returns></returns>
const std::shared_ptr<network::http::request>& request();
/// <summary>
/// 回复对象
/// </summary>
/// <returns></returns>
const std::shared_ptr<network::http::response>& response();
/// <summary>
/// httpserver
/// </summary>
/// <returns></returns>
network::http::server* server() { return m_server; }
/// <summary>
/// 连接ID
/// </summary>
/// <returns></returns>
uint64 connid() { return m_connid; }
/// <summary>
/// 请求完整URL
/// </summary>
/// <returns></returns>
std::string url() { return m_url; }
/// <summary>
/// 请求路径
/// </summary>
/// <returns></returns>
std::string filepath() { return m_filepath; }
/// <summary>
/// 请求主机
/// </summary>
/// <returns></returns>
std::string host() { return m_host; }
/// <summary>
/// 请求数据
/// </summary>
/// <returns></returns>
ylib::buffer& body() { return m_data; }
/// <summary>
/// 附加数据
/// </summary>
/// <returns></returns>
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<network::http::request> m_request;
// 回复
std::shared_ptr<network::http::response> 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;
};
}
}

View File

@@ -4,7 +4,6 @@
#include <string>
#include <vector>
#include "http_session.h"
#include "http_parser.h"
#include "http_interface.h"
namespace ylib
{
@@ -14,64 +13,93 @@ namespace ylib
{
class reqpack;
class server;
/********************************************************************
* classHttp请求解析类
********************************************************************/
/// <summary>
/// HTTP请求
/// </summary>
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);
/// <summary>
/// 取TOKEN
/// 取请求头
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
bool header(const std::string& name, std::string& value);
/// <summary>
/// 请求动作
/// </summary>
/// <returns></returns>
std::string token();
/***************************************************************************
* function取reqpack
***************************************************************************/
std::string method();
/// <summary>
/// 取请求路径
/// </summary>
/// <returns></returns>
std::string filepath();
/// <summary>
/// 取请求主机
/// </summary>
/// <returns></returns>
std::string host();
/// <summary>
/// session
/// </summary>
/// <param name="session_id"></param>
/// <returns></returns>
network::http::session& session(const std::string& session_id);
network::http::reqpack* reqpack();
/***************************************************************************
* function解析器
***************************************************************************/
network::http::parser* parser();
/***************************************************************************
* functionGet Browserr Remote Ipaddress
***************************************************************************/
std::string remote_ipaddress(bool find_header = false, const std::string& inside_ipaddress = "");
ushort remote_port();
friend class reqpack;
/// <summary>
/// 远程信息
/// </summary>
/// <returns></returns>
ylib::AddressPort remote();
/// <summary>
/// 取请求参数
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
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<std::map<std::string, std::string>>& url_param() { return m_url_param; }
std::shared_ptr<std::map<std::string, std::string>>& body_param() { return m_body_param; }
/// <summary>
/// 表单数据
/// </summary>
/// <returns></returns>
const std::shared_ptr<std::vector<network::http::multipart>>& multipart();
/// <summary>
/// 是否为请求类型
/// </summary>
/// <returns></returns>
bool content_type(std::string type_name);
/// <summary>
/// Body
/// </summary>
/// <returns></returns>
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<std::map<std::string, std::string>> m_url_param;
// 请求参数[BODY]
std::shared_ptr<std::map<std::string, std::string>> m_body_param;
// FORM数据
std::shared_ptr<std::vector<network::http::multipart>> m_form;
};
}
}

View File

@@ -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<std::string, std::string> m_headers;
bool m_response;
network::http::reqpack* m_reqpack;
bool m_response = false;
network::http::reqpack* m_reqpack = nullptr;
};
}

View File

@@ -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<form_info*> 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<form_info*> m_list;
// ylib::buffer m_data;
// };
// }
// }
//}
//#endif

View File

@@ -53,6 +53,17 @@ namespace ylib
bool is_ipv6(const std::string& value);
// 是否为域名
bool is_domain(const std::string& value);
/// <summary>
/// 解析 multipart/form 数据
/// </summary>
/// <param name="body"></param>
/// <param name="body_length"></param>
/// <param name="boundary"></param>
/// <param name="parts"></param>
/// <returns></returns>
bool parse_multipart_form_data(const ylib::buffer& data, const std::string& boundary, std::vector<network::http::multipart>& parts);
}
}
#endif