hku server continue

This commit is contained in:
fasiondog 2021-03-07 18:14:04 +08:00
parent fc9221e29f
commit e2422b25df
8 changed files with 149 additions and 21 deletions

View File

@ -25,24 +25,31 @@ void HttpHandle::operator()() {
m_nng_req = (nng_http_req*)nng_aio_get_input(m_http_aio, 0);
m_nng_conn = (nng_http_conn*)nng_aio_get_input(m_http_aio, 2);
before_run();
run();
// after_run();
nng_aio_set_output(m_http_aio, 0, m_nng_res);
nng_aio_finish(m_http_aio, 0);
} catch (HttpHandleRunException& e) {
error(e.errcode());
nng_aio_set_output(m_http_aio, 0, m_nng_res);
nng_aio_finish(m_http_aio, 0);
} catch (std::exception& e) {
std::string errmsg(e.what());
CLS_ERROR(errmsg);
error(errmsg);
unknown_error(errmsg);
} catch (...) {
std::string errmsg("Unknown error!");
CLS_ERROR(errmsg);
error(errmsg);
unknown_error(errmsg);
}
}
void HttpHandle::error(const std::string& errmsg) {
void HttpHandle::unknown_error(const std::string& errmsg) {
try {
int errcode = NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR;
const char* info = "Internal server error!";
@ -69,10 +76,11 @@ void HttpHandle::error(const std::string& errmsg) {
nng_aio_set_output(m_http_aio, 0, m_nng_res);
nng_aio_finish(m_http_aio, 0);
} catch (...) {
CLS_FATAL("unknown error in finished!");
}
}
std::string HttpHandle::getRequestData() {
std::string HttpHandle::getReqData() {
void* data = nullptr;
size_t len = 0;
nng_http_req_get_data(m_nng_req, &data, &len);

View File

@ -8,6 +8,7 @@
#pragma once
#include <string>
#include <string_view>
#include <nng/nng.h>
#include <nng/supplemental/http/http.h>
@ -15,6 +16,31 @@
namespace hku {
/**
*
*/
class HttpHandleRunException : public std::exception {
public:
explicit HttpHandleRunException(int errcode) : std::exception(), m_errcode(errcode) {}
int errcode() const {
return m_errcode;
}
private:
int m_errcode = 0;
};
#define HANDLE_ERROR(errcode) throw HttpHandleRunException(errcode)
#define HANDLE_CHECK(expr, errcode) \
do { \
if (!expr) { \
throw HttpHandleRunException(errcode); \
} \
} while (0)
// 仅内部使用
#define NNG_CHECK(rv) \
{ \
if (rv != 0) { \
@ -22,6 +48,7 @@ namespace hku {
} \
}
// 仅内部使用
#define NNG_CHECK_M(rv, msg) \
{ \
if (rv != 0) { \
@ -36,28 +63,52 @@ public:
HttpHandle() = delete;
HttpHandle(nng_aio *aio);
virtual void run() {
logger()->warn("Not implemented HttpHandle run method!");
/** 前处理 */
virtual void before_run() {}
/** 响应处理 */
virtual void run() = 0;
// virtual void after_run() {}
/** 统一处理响应错误 */
virtual void error(int errcode) {
unknown_error(fmt::format("error: {}", errcode));
}
void getRequestData(void **data, size_t *len) {
/**
*
* @param name
* @return NULL
*/
const char *getReqHeader(const char *name) {
return nng_http_req_get_header(m_nng_req, name);
}
std::string getReqHeader(const std::string &name) {
const char *head = nng_http_req_get_header(m_nng_req, name.c_str());
return head ? std::string(head) : std::string();
}
void getReqData(void **data, size_t *len) {
nng_http_req_get_data(m_nng_req, data, len);
}
std::string getRequestData();
std::string getReqData();
void setResponseStatus(uint16_t status) {
void setResStatus(uint16_t status) {
NNG_CHECK(nng_http_res_set_status(m_nng_res, status));
}
void setResponseData(const std::string &content) {
NNG_CHECK(nng_http_res_copy_data(m_nng_res, content.c_str(), content.size()));
void setResData(const std::string_view &content) {
NNG_CHECK(nng_http_res_copy_data(m_nng_res, content.data(), content.size()));
}
void operator()();
private:
void error(const std::string &errmsg);
// error未捕获的信息统一返回500页面
void unknown_error(const std::string &errmsg);
protected:
nng_aio *m_http_aio{nullptr};

View File

@ -0,0 +1,41 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-07
* Author: fasiondog
*/
#include <unordered_map>
#include "HKUHandle.h"
namespace hku {
enum hku_handle_errno {
HKU_HANDLE_INVALID_CONTENT = 1,
};
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")"},
// clang-format on
};
void HKUHandle::before_run() {
const char *content_type = getReqHeader("Content-Type");
HANDLE_CHECK(content_type, HKU_HANDLE_INVALID_CONTENT);
// application/json
}
void HKUHandle::error(int errcode) {
auto iter = g_hku_handle_errmsg.find(errcode);
if (iter == g_hku_handle_errmsg.end()) {
private_error(errcode);
return;
}
// http 响应状态设为 400
setResStatus(NNG_HTTP_STATUS_BAD_REQUEST);
setResData(fmt::format(R"({{"error": "{}", "msg": "{}"}})", errcode, iter->second));
}
} // namespace hku

View File

@ -0,0 +1,27 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-07
* Author: fasiondog
*/
#pragma once
#include "../http/HttpHandle.h"
namespace hku {
class HKUHandle : public HttpHandle {
CLASS_LOGGER(HKUHandle)
public:
HKUHandle(nng_aio *aio) : HttpHandle(aio) {}
virtual void before_run() override;
void error(int errcode) override;
virtual void private_error(int errcode) {}
};
} // namespace hku

View File

@ -7,16 +7,16 @@
#pragma once
#include "../http/HttpHandle.h"
#include "HKUHandle.h"
namespace hku {
class HelloHandle : public HttpHandle {
class HelloHandle : public HKUHandle {
public:
HelloHandle(nng_aio *aio) : HttpHandle(aio) {}
HelloHandle(nng_aio *aio) : HKUHandle(aio) {}
virtual void run() override {
setResponseData("hello");
setResData("hello");
}
};

View File

@ -16,12 +16,12 @@ public:
LoginHandle(nng_aio *aio) : HttpHandle(aio) {}
virtual void run() override {
std::string content = getRequestData();
std::string content = getReqData();
if (content.empty()) {
setResponseStatus(NNG_HTTP_STATUS_NO_CONTENT);
setResStatus(NNG_HTTP_STATUS_BAD_REQUEST);
return;
}
setResponseData(content);
setResData(content);
}
};

View File

@ -1,8 +1,8 @@
target("hikyuu_server")
target("hkuserver")
set_kind("binary")
add_packages("fmt", "spdlog", "flatbuffers", "nng")
add_packages("fmt", "spdlog", "flatbuffers", "nng", "yyjson")
add_deps("hikyuu")
add_includedirs("..")

View File

@ -40,6 +40,7 @@ add_requires("fmt", {system=false, configs = {header_only = true, vs_runtime = "
add_requires("spdlog", {system=false, configs = {header_only = true, fmt_external=true, vs_runtime = "MD"}})
add_requires("flatbuffers", {system=false, configs = {vs_runtime="MD"}})
add_requires("nng", {system=false, configs = {vs_runtime="MD"}})
add_requires("yyjson", {system=false, configs = {vs_runtime="MD"}})
add_defines("SPDLOG_DISABLE_DEFAULT_LOGGER") -- 禁用 spdlog 默认 logger