httpserver:
包含内容:C++ 、mongoose、http协议
此次只实现了服务端,客户端没有去实现。最终测试成功
主要针对客户端使用POST方式进行应答,GET方式也可以
客户端使用POST方式上传的信息会通过标准输出函数输出在终端上
代码:
main.cpp
#include <memory>
#include "./http/http_server.h"
std::string HttpServer::s_web_dir = ".";
bool HttpServer::compare_flag = true;
mg_serve_http_opts HttpServer::s_server_option;
std::unordered_map<std::string,ReqHandler> HttpServer::s_handler_map;
bool handle_function(std::string Req_message,mg_connection *c,OnRspCallback rsp_callback)
{
std::cout<<Req_message<<"\n"<<std::endl;
rsp_callback(c);
return true;
}
int main(int argc,char *argv[])
{
std::string port;
auto http_server = std::shared_ptr<HttpServer>(new HttpServer);
std::cout<<"please input port number : ";
std::cin>>port;
http_server->Init(port);
http_server->AddHandler("/",handle_function);
http_server->Start();
return 0;
}
http_server.cpp
#include "http_server.h"
void HttpServer::Init(const std::string port)
{
m_port = port;
s_server_option.enable_directory_listing = "yes";
s_server_option.document_root = s_web_dir.c_str();
}
bool HttpServer::Start()
{
mg_mgr_init(&m_mgr,NULL);
mg_connection *connection = mg_bind(&m_mgr,m_port.c_str(),HttpServer::OnHttpEvent);
if(connection == NULL)
return false;
mg_set_protocol_http_websocket(connection);
printf("starting http server at port : %s , ready !!!\n\n",m_port.c_str());
while(HttpServer::compare_flag)
mg_mgr_poll(&m_mgr,500);
std::cout<<"error : respond format error!\n"<<std::endl;
Close();
return true;
}
void HttpServer::OnHttpEvent(mg_connection *connection,int event_type,void *event_data)
{
if(event_type == MG_EV_HTTP_REQUEST) {
http_message *http_req = (http_message *)event_data;
HandleHttpEvent(connection,http_req);
}
}
static bool route_check(const http_message *http_msg,const char *route_prefix)
{
if(mg_vcmp(&http_msg->uri,route_prefix) == 0)
return true;
else
return false;
}
void HttpServer::HandleHttpEvent(mg_connection *connection, http_message *http_req)
{
std::string req_str = std::string(http_req->message.p,http_req->message.len);
std::string url = std::string(http_req->uri.p,http_req->uri.len);
std::string body = std::string(http_req->body.p, http_req->body.len);
if(strncmp(body.c_str(),"vgdecoderesult",sizeof("vgdecoderesult")-1) == 0)
HttpServer::compare_flag = true;
else
HttpServer::compare_flag = false;
auto it = s_handler_map.find(url);
if(it != s_handler_map.end()) {
ReqHandler handler_func = it->second;
handler_func(req_str.c_str(),connection,&HttpServer::SendHttpRsp);
}
if(route_check(http_req,(char*)"/"))
mg_serve_http(connection,http_req,s_server_option);
else {
mg_printf(
connection,
"%s",
"HTTP/1.1 501 Not Implemented",
"Content-Length: 0\r\n\r\n"
);
}
}
void HttpServer::SendHttpRsp(mg_connection *connection)
{
if(HttpServer::compare_flag == true){
mg_printf(connection, "%s",
"HTTP/1.1 200 OK code=0000\r\n"
"Transfer-Encoding: chunked\r\n"
"Content-Type: text/plain; charset=UTF-8\r\n"
"Content-Length: 0\r\n\r\n"
);
mg_printf_http_chunk(connection, "{ \"result\": %s }", "code=0000");
}
else if(HttpServer::compare_flag == false){
mg_printf(connection, "%s",
"HTTP/1.1 200 OK code=1111\r\n"
"Transfer-Encoding: chunked\r\n"
"Content-Type: text/plain; charset=UTF-8\r\n"
"Content-Length: 0\r\n\r\n"
);
mg_printf_http_chunk(connection, "{ \"result\": %s }", "code=1111");
}
mg_send_http_chunk(connection,"",0);
}
bool HttpServer::Close()
{
mg_mgr_free(&m_mgr);
return true;
}
void HttpServer::AddHandler(const std::string &url,ReqHandler req_handler)
{
if(s_handler_map.find(url) != s_handler_map.end())
return;
s_handler_map.insert(std::make_pair(url,req_handler));
}
http_server.h
#pragma once
#include "../mongoose/mongoose.h"
#include <string>
#include <string.h>
#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <iostream>
typedef void OnRspCallback(mg_connection *c);
using ReqHandler = std::function<bool (std::string,mg_connection *c,OnRspCallback)>;
class HttpServer
{
public:
HttpServer(){}
~HttpServer(){}
void Init(const std::string port);
bool Start();
bool Close();
void AddHandler(const std::string &url,ReqHandler req_handler);
static mg_serve_http_opts s_server_option;
static std::string s_web_dir;
static bool compare_flag;
static std::unordered_map<std::string,ReqHandler> s_handler_map;
private:
static void SendHttpRsp(mg_connection *connection);
static void HandleHttpEvent(mg_connection *connection, http_message *http_req);
static void OnHttpEvent(mg_connection *connection,int event_type,void *event_data);
std::string m_port;
mg_mgr m_mgr;
};
|