hku server continue

This commit is contained in:
fasiondog 2021-03-08 00:46:44 +08:00
parent e2422b25df
commit 4c4851eeb6
9 changed files with 193 additions and 16 deletions

View 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

View File

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

View File

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

View File

@ -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!");
}

View 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

View 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

View File

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

View File

@ -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) {

View File

@ -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) {}