parent
9a7eece05e
commit
a697e0db12
4 changed files with 217 additions and 0 deletions
@ -0,0 +1,80 @@ |
||||
#include "http_packet.h" |
||||
namespace Bk::Net { |
||||
HttpRequest::HttpRequest(std::string method, |
||||
std::string url, |
||||
std::string version, |
||||
HttpParams params, |
||||
std::string body)
|
||||
: method(method), url(url), version(version), params(params), body(body) {} |
||||
|
||||
HttpRequest::HttpRequest(std::string data) |
||||
{ |
||||
auto lines = Tools::string_split(data, "\n"); |
||||
auto first_line = std::string(lines->at(0)); |
||||
auto req_data = Tools::string_split(first_line, " "); |
||||
method = req_data->at(0); |
||||
url = req_data->at(1); |
||||
version = req_data->at(2); |
||||
body = std::string(lines->at(lines->size() - 1)); |
||||
|
||||
lines->erase(lines->begin()); |
||||
lines->erase(lines->end()); |
||||
|
||||
for (auto line : *lines) |
||||
{ |
||||
auto param = Tools::string_split(line, ":", 1); |
||||
if (param->size() >= 2)
|
||||
{ |
||||
Tools::string_trim(param->at(1)); |
||||
params.insert({param->at(0), param->at(1)}); |
||||
} |
||||
} |
||||
} |
||||
|
||||
std::string HttpRequest::to_string() |
||||
{ |
||||
std::string request = ""; |
||||
request += method + " " + url + " " + version + "\r\n"; |
||||
std::string param_order[] =
|
||||
{ |
||||
"Host", |
||||
"User-Agent", |
||||
"Accept", |
||||
"Accept-Language", |
||||
"Accept-Encoding", |
||||
"Connection", |
||||
"Upgrade-Insecure-Requests", |
||||
"Sec-Fetch-Dest", |
||||
"Sec-Fetch-Mode", |
||||
"Sec-Fetch-Site" |
||||
}; |
||||
if (params.size()) for ( const auto& param : param_order) if (params[param].length()) request += param + ": " + params[param] + "\r\n"; |
||||
request += "\r\n"; |
||||
if (body.length()) request += body; |
||||
return request; |
||||
} |
||||
|
||||
HttpReponse::HttpReponse(std::string status, |
||||
std::string version, |
||||
HttpParams params, |
||||
std::string body) |
||||
: status(status), version(version), params(params), body(body) {} |
||||
|
||||
HttpReponse::HttpReponse(std::string data) |
||||
{ |
||||
status = ""; |
||||
version = ""; |
||||
params = HttpParams(0); |
||||
body = ""; |
||||
} |
||||
|
||||
std::string HttpReponse::to_string() |
||||
{ |
||||
std::string reponse = ""; |
||||
reponse = version + " " + status + " \r\n"; |
||||
if (params.size()) for ( const auto& pair : params) reponse += pair.first + ": " + pair.second + " \r\n"; |
||||
reponse += "\r\n"; |
||||
if (body.length()) reponse += body; |
||||
return reponse; |
||||
} |
||||
} |
@ -0,0 +1,59 @@ |
||||
#pragma once |
||||
|
||||
#include <bakanetpch.h> |
||||
#include <bakanet/tools/string_tools.h> |
||||
|
||||
#define HTTP_RES_200 "200 OK" |
||||
|
||||
#define HTTP_RES_303 "303 See Other" |
||||
|
||||
#define HTTP_RES_400 "400 Bad Request" |
||||
#define HTTP_RES_401 "401 Unauthorized" |
||||
#define HTTP_RES_402 "402 Payment Required" |
||||
#define HTTP_RES_403 "403 Forbidden" |
||||
#define HTTP_RES_404 "404 Not Found" |
||||
#define HTTP_RES_405 "405 Method Not Allowed" |
||||
#define HTTP_RES_406 "406 Not Acceptable" |
||||
#define HTTP_RES_408 "408 Request Timeout" |
||||
|
||||
namespace Bk::Net { |
||||
using HttpParams = std::unordered_map<std::string, std::string>; |
||||
|
||||
class HttpRequest
|
||||
{ |
||||
public: |
||||
HttpRequest(std::string method,
|
||||
std::string url, |
||||
std::string version, |
||||
HttpParams params = HttpParams(0), |
||||
std::string body = ""); |
||||
|
||||
HttpRequest(std::string data); |
||||
|
||||
std::string to_string(); |
||||
|
||||
std::string method; |
||||
std::string url; |
||||
std::string version; |
||||
HttpParams params; |
||||
std::string body; |
||||
}; |
||||
|
||||
class HttpReponse |
||||
{ |
||||
public: |
||||
HttpReponse(std::string status, |
||||
std::string version, |
||||
HttpParams params = HttpParams(0), |
||||
std::string body = ""); |
||||
|
||||
HttpReponse(std::string data); |
||||
|
||||
std::string to_string(); |
||||
|
||||
std::string status; |
||||
std::string version; |
||||
HttpParams params; |
||||
std::string body; |
||||
}; |
||||
} |
@ -0,0 +1,52 @@ |
||||
#include "http_server.h" |
||||
namespace Bk::Net { |
||||
HttpServer::HttpServer(IpAddress ip, int port)
|
||||
{ |
||||
socket = Socket::create(ip, port, IpProtocol::TCP); |
||||
} |
||||
|
||||
void HttpServer::start() |
||||
{ |
||||
bool running = socket->init() && socket->start(5); |
||||
while (running) |
||||
{ |
||||
log("BEFORE") |
||||
Connection conn = socket->ack(); |
||||
if(conn >= 0) |
||||
{ |
||||
log("AFTER") |
||||
route_request(conn, recv_request(conn)); |
||||
close(conn); |
||||
} |
||||
|
||||
}
|
||||
} |
||||
|
||||
HttpRequest HttpServer::recv_request(Connection conn) |
||||
{ |
||||
Packet req; |
||||
bool reading = true; |
||||
while(reading) |
||||
{ |
||||
auto data = socket->obtain(conn, 4); |
||||
log("SIZE " << data.size()) |
||||
reading = req.append_data(data); |
||||
} |
||||
int req_size = req.size(); |
||||
if (req_size) return HttpRequest(std::string(req.pull<char>(req_size).release(), req_size)); |
||||
return HttpRequest("", "", ""); |
||||
} |
||||
|
||||
void HttpServer::send_reponse(Connection conn, HttpReponse res) |
||||
{ |
||||
Packet res_packet; |
||||
std::string str_res = res.to_string(); |
||||
res_packet.push<char>(str_res.c_str(), str_res.length()); |
||||
socket->emit(conn, res_packet.payload); |
||||
} |
||||
|
||||
void HttpServer::route_request(Connection conn, HttpRequest req) |
||||
{ |
||||
if(req_mapper[req.url]) send_reponse(conn, req_mapper[req.url](req)); |
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
#pragma once |
||||
|
||||
#include <bakanetpch.h> |
||||
#include <bakanet/sock_layer/ip_address.h> |
||||
#include <bakanet/sock_layer/packet.h> |
||||
#include <bakanet/sock_layer/socket.h> |
||||
#include "http_packet.h" |
||||
|
||||
namespace Bk::Net { |
||||
class HttpServer
|
||||
{ |
||||
using RequestHandler = std::function<HttpReponse(HttpRequest& req)>; |
||||
public: |
||||
HttpServer(IpAddress ip, int port); |
||||
~HttpServer() = default; |
||||
void start(); |
||||
void get(std::string url, RequestHandler req_handler) { req_mapper.insert({ url, req_handler }); } |
||||
private: |
||||
std::unique_ptr<Socket> socket; |
||||
std::unordered_map<std::string, RequestHandler> req_mapper; |
||||
|
||||
HttpRequest recv_request(Connection conn); |
||||
void send_reponse(Connection conn, HttpReponse res); |
||||
void route_request(Connection conn, HttpRequest req); |
||||
}; |
||||
} |
Loading…
Reference in New Issue