mirror of
https://gitee.com/fasiondog/hikyuu.git
synced 2024-11-30 19:08:48 +08:00
hku server continue
This commit is contained in:
parent
e2422b25df
commit
4c4851eeb6
17
hikyuu_cpp/hikyuu_server/http/HttpClient.h
Normal file
17
hikyuu_cpp/hikyuu_server/http/HttpClient.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright(C) 2021 hikyuu.org
|
||||
*
|
||||
* Create on: 2021-03-07
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace hku {
|
||||
|
||||
class HttpClient {
|
||||
public:
|
||||
HttpClient() {}
|
||||
};
|
||||
|
||||
} // namespace hku
|
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "url.h"
|
||||
#include "HttpHandle.h"
|
||||
|
||||
namespace hku {
|
||||
@ -87,4 +88,55 @@ std::string HttpHandle::getReqData() {
|
||||
return data ? std::string((char*)data) : std::string();
|
||||
}
|
||||
|
||||
bool HttpHandle::haveQueryParams() {
|
||||
const char* url = nng_http_req_get_uri(m_nng_req);
|
||||
return !url ? false : strchr(url, '?');
|
||||
}
|
||||
|
||||
bool HttpHandle::getQueryParams(QueryParams& query_params) {
|
||||
const char* url = nng_http_req_get_uri(m_nng_req);
|
||||
CLS_IF_RETURN(!url, false);
|
||||
|
||||
const char* p = strchr(url, '?');
|
||||
CLS_IF_RETURN(!p, false);
|
||||
|
||||
p = p + 1;
|
||||
|
||||
enum {
|
||||
s_key,
|
||||
s_value,
|
||||
} state = s_key;
|
||||
|
||||
const char* key = p;
|
||||
const char* value = NULL;
|
||||
int key_len = 0;
|
||||
int value_len = 0;
|
||||
while (*p != '\0') {
|
||||
if (*p == '&') {
|
||||
if (key_len && value_len) {
|
||||
std::string strkey = std::string(key, key_len);
|
||||
std::string strvalue = std::string(value, value_len);
|
||||
query_params[url_unescape(strkey.c_str())] = url_unescape(strvalue.c_str());
|
||||
key_len = value_len = 0;
|
||||
}
|
||||
state = s_key;
|
||||
key = p + 1;
|
||||
} else if (*p == '=') {
|
||||
state = s_value;
|
||||
value = p + 1;
|
||||
} else {
|
||||
state == s_key ? ++key_len : ++value_len;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
if (key_len && value_len) {
|
||||
std::string strkey = std::string(key, key_len);
|
||||
std::string strvalue = std::string(value, value_len);
|
||||
query_params[url_unescape(strkey.c_str())] = url_unescape(strvalue.c_str());
|
||||
key_len = value_len = 0;
|
||||
}
|
||||
|
||||
return query_params.size() != 0;
|
||||
}
|
||||
|
||||
} // namespace hku
|
@ -96,10 +96,28 @@ public:
|
||||
|
||||
std::string getReqData();
|
||||
|
||||
/**
|
||||
* 请求的 ulr 中是否包含 query 参数
|
||||
*/
|
||||
bool haveQueryParams();
|
||||
|
||||
typedef std::unordered_map<std::string, std::string> QueryParams;
|
||||
|
||||
/**
|
||||
* 获取 query 参数
|
||||
* @param query_params [out] 输出 query 参数
|
||||
* @return true | false 获取或解析失败
|
||||
*/
|
||||
bool getQueryParams(QueryParams &query_params);
|
||||
|
||||
void setResStatus(uint16_t status) {
|
||||
NNG_CHECK(nng_http_res_set_status(m_nng_res, status));
|
||||
}
|
||||
|
||||
void setResHeader(const char *key, const char *val) {
|
||||
NNG_CHECK(nng_http_res_set_header(m_nng_res, key, val));
|
||||
}
|
||||
|
||||
void setResData(const std::string_view &content) {
|
||||
NNG_CHECK(nng_http_res_copy_data(m_nng_res, content.data(), content.size()));
|
||||
}
|
||||
|
@ -8,6 +8,10 @@
|
||||
#include <csignal>
|
||||
#include "HttpServer.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace hku {
|
||||
|
||||
#define HTTP_FATAL_CHECK(rv, msg) \
|
||||
@ -21,9 +25,17 @@ namespace hku {
|
||||
nng_http_server* HttpServer::ms_server = nullptr;
|
||||
MQThreadPool HttpServer::ms_tg(std::thread::hardware_concurrency(), false);
|
||||
|
||||
#if defined(_WIN32)
|
||||
static UINT g_old_cp;
|
||||
#endif
|
||||
|
||||
void HttpServer::http_exit() {
|
||||
CLS_INFO("exit server");
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
|
||||
#if defined(_WIN32)
|
||||
SetConsoleOutputCP(g_old_cp);
|
||||
#endif
|
||||
|
||||
if (ms_server) {
|
||||
nng_http_server_release(ms_server);
|
||||
nng_fini();
|
||||
@ -60,6 +72,13 @@ HttpServer::~HttpServer() {
|
||||
void HttpServer::start() {
|
||||
std::signal(SIGINT, &HttpServer::signal_handler);
|
||||
std::signal(SIGTERM, &HttpServer::signal_handler);
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows 下设置控制台程序输出代码页为 UTF8
|
||||
auto g_old_cp = GetConsoleOutputCP();
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
HTTP_FATAL_CHECK(nng_http_server_start(ms_server), "Failed nng_http_server_start!");
|
||||
}
|
||||
|
||||
|
56
hikyuu_cpp/hikyuu_server/http/url.cpp
Normal file
56
hikyuu_cpp/hikyuu_server/http/url.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright(C) 2021 hikyuu.org
|
||||
*
|
||||
* Create on: 2021-03-07
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#include "url.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
#define IS_ALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
|
||||
#define IS_NUM(c) ((c) >= '0' && (c) <= '9')
|
||||
#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c))
|
||||
#define IS_HEX(c) (IS_NUM(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
|
||||
|
||||
static inline bool is_unambiguous(char c) {
|
||||
return IS_ALPHANUM(c) || c == '-' || c == '_' || c == '.' || c == '~';
|
||||
}
|
||||
|
||||
static inline unsigned char hex2i(char hex) {
|
||||
return hex <= '9' ? hex - '0' : hex <= 'F' ? hex - 'A' + 10 : hex - 'a' + 10;
|
||||
}
|
||||
|
||||
std::string url_escape(const char* istr) {
|
||||
std::string ostr;
|
||||
const char* p = istr;
|
||||
char szHex[4] = {0};
|
||||
while (*p != '\0') {
|
||||
if (is_unambiguous(*p)) {
|
||||
ostr += *p;
|
||||
} else {
|
||||
sprintf(szHex, "%%%02X", *p);
|
||||
ostr += szHex;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
return ostr;
|
||||
}
|
||||
|
||||
std::string url_unescape(const char* istr) {
|
||||
std::string ostr;
|
||||
const char* p = istr;
|
||||
while (*p != '\0') {
|
||||
if (*p == '%' && IS_HEX(p[1]) && IS_HEX(p[2])) {
|
||||
ostr += ((hex2i(p[1]) << 4) | hex2i(p[2]));
|
||||
p += 3;
|
||||
} else {
|
||||
ostr += *p;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
return ostr;
|
||||
}
|
||||
|
||||
} // namespace hku
|
17
hikyuu_cpp/hikyuu_server/http/url.h
Normal file
17
hikyuu_cpp/hikyuu_server/http/url.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright(C) 2021 hikyuu.org
|
||||
*
|
||||
* Create on: 2021-03-07
|
||||
* Author: fasiondog
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hku {
|
||||
|
||||
std::string url_escape(const char* istr);
|
||||
std::string url_unescape(const char* istr);
|
||||
|
||||
} // namespace hku
|
@ -18,12 +18,6 @@
|
||||
using namespace hku;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#if defined(_WIN32)
|
||||
// Windows 下设置控制台程序输出代码页为 UTF8
|
||||
auto old_cp = GetConsoleOutputCP();
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
HKU_INFO("start server ... You can press Ctrl-C stop");
|
||||
|
||||
HttpServer server("http://*", 8080);
|
||||
@ -32,9 +26,5 @@ int main(int argc, char* argv[]) {
|
||||
server.GET<LoginHandle>("/login");
|
||||
|
||||
server.start();
|
||||
|
||||
#if defined(_WIN32)
|
||||
SetConsoleOutputCP(old_cp);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,20 +10,28 @@
|
||||
|
||||
namespace hku {
|
||||
|
||||
enum hku_handle_errno {
|
||||
enum hku_rest_errno {
|
||||
HKU_HANDLE_INVALID_CONTENT = 1,
|
||||
HKU_HANDLE_MISS_TOKEN = 2,
|
||||
HKU_HANDLE_UNAUTHORIZED = 3,
|
||||
};
|
||||
|
||||
static std::unordered_map<int, const char *> g_hku_handle_errmsg{
|
||||
// clang-format off
|
||||
{HKU_HANDLE_INVALID_CONTENT, R"(Invalid Content-Type, Please use "application/json")"},
|
||||
{HKU_HANDLE_INVALID_CONTENT, "Invalid Content-Type, Please use 'application/json'"},
|
||||
{HKU_HANDLE_MISS_TOKEN, "Missing token"},
|
||||
{HKU_HANDLE_UNAUTHORIZED, "Authentication failed"},
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
void HKUHandle::before_run() {
|
||||
setResHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
|
||||
const char *content_type = getReqHeader("Content-Type");
|
||||
HANDLE_CHECK(content_type, HKU_HANDLE_INVALID_CONTENT);
|
||||
// application/json
|
||||
|
||||
const char *token = getReqHeader("token");
|
||||
HANDLE_CHECK(token, HKU_HANDLE_MISS_TOKEN);
|
||||
}
|
||||
|
||||
void HKUHandle::error(int errcode) {
|
||||
|
@ -7,11 +7,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../http/HttpHandle.h"
|
||||
#include "HKUHandle.h"
|
||||
|
||||
namespace hku {
|
||||
|
||||
class LoginHandle : public HttpHandle {
|
||||
class LoginHandle : public HKUHandle {
|
||||
public:
|
||||
LoginHandle(nng_aio *aio) : HttpHandle(aio) {}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user