parent
							
								
									96d928a83c
								
							
						
					
					
						commit
						8af6cfb3f7
					
				
				 9 changed files with 285 additions and 0 deletions
			
			
		@ -0,0 +1,12 @@ | 
				
			||||
#pragma once | 
				
			||||
 | 
				
			||||
#include <unordered_map> | 
				
			||||
#include <iostream> | 
				
			||||
#include <vector> | 
				
			||||
#include <string> | 
				
			||||
#include <bakanet.h> | 
				
			||||
 | 
				
			||||
#define log(str) std::cout << str << "\n"; | 
				
			||||
#define input(ref) std::cin >> ref; | 
				
			||||
 | 
				
			||||
#define PORT 8080 | 
				
			||||
@ -0,0 +1,41 @@ | 
				
			||||
project "server" | 
				
			||||
    location "./server" | 
				
			||||
    kind "ConsoleApp" | 
				
			||||
    language "C++" | 
				
			||||
    cppdialect "C++17" | 
				
			||||
    systemversion "latest" | 
				
			||||
 | 
				
			||||
    targetdir("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") | 
				
			||||
    objdir("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") | 
				
			||||
 | 
				
			||||
    includedirs  | 
				
			||||
    { | 
				
			||||
        "%{IncludeDirs.bakanet}", | 
				
			||||
        "./" | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    files  | 
				
			||||
    { | 
				
			||||
        "%{prj.location}/**.h", | 
				
			||||
        "%{prj.location}/**.cpp", | 
				
			||||
        "./commun.h" | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    links | 
				
			||||
    { | 
				
			||||
        "bakanet" | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    filter "system:linux" | 
				
			||||
        defines | 
				
			||||
        { | 
				
			||||
            "BK_PLAFORM_LINUX" | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
    filter "system:windows" | 
				
			||||
        defines | 
				
			||||
        { | 
				
			||||
            "BK_PLAFORM_WINDOWS" | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,79 @@ | 
				
			||||
#include "http_packet.h" | 
				
			||||
#include <iomanip> | 
				
			||||
 | 
				
			||||
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 = string_split(data, "\n"); | 
				
			||||
    auto first_line = std::string(lines->at(0)); | 
				
			||||
    auto req_data = 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 = string_split(line, ":", 1); | 
				
			||||
        if (param->size() >= 2) 
 | 
				
			||||
        { | 
				
			||||
            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 = ""; | 
				
			||||
    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,44 @@ | 
				
			||||
#pragma once | 
				
			||||
 | 
				
			||||
#include <commun.h> | 
				
			||||
#include "http_tools.h" | 
				
			||||
 | 
				
			||||
using HttpParams = std::unordered_map<std::string, std::string>; | 
				
			||||
 | 
				
			||||
class HttpRequest 
 | 
				
			||||
{ | 
				
			||||
    public: | 
				
			||||
        HttpRequest(std::string method, | 
				
			||||
        std::string url, | 
				
			||||
        std::string version, | 
				
			||||
        HttpParams params, | 
				
			||||
        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, | 
				
			||||
        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,38 @@ | 
				
			||||
#include "http_server.h" | 
				
			||||
 | 
				
			||||
void http_server() 
 | 
				
			||||
{ | 
				
			||||
    IpAddress ip("127.0.0.1"); | 
				
			||||
    Socket* sock = Socket::Create(ip, PORT, IpProtocol::TCP).release(); | 
				
			||||
    bool running = sock->init() && sock->start(5); | 
				
			||||
    char input = 'n'; | 
				
			||||
    
 | 
				
			||||
    do | 
				
			||||
    { | 
				
			||||
        Connection conn = sock->ack(); | 
				
			||||
        if (conn >= 0) 
 | 
				
			||||
        { | 
				
			||||
            log("New Conn") | 
				
			||||
            std::string http_request(http_handler(sock, conn)); | 
				
			||||
            
 | 
				
			||||
            if (http_request == "") continue; | 
				
			||||
            HttpRequest req(http_request); | 
				
			||||
            log("to string") | 
				
			||||
            log(req.to_string()) | 
				
			||||
            close(conn); | 
				
			||||
        } | 
				
			||||
        log("Close?") | 
				
			||||
        input(input); | 
				
			||||
    } while (input != 'y'); | 
				
			||||
    delete sock; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
std::string http_handler(Socket* sock, Connection conn) 
 | 
				
			||||
{ | 
				
			||||
    Packet req; | 
				
			||||
    while(req.append_data(sock->obtain(conn, 4))); | 
				
			||||
    int req_size = req.size(); | 
				
			||||
    std::unique_ptr<char[]> req_test = req.pull<char>(req_size); | 
				
			||||
    if (req_size) return std::string(req_test.release(), req_size); | 
				
			||||
    return ""; | 
				
			||||
} | 
				
			||||
@ -0,0 +1,8 @@ | 
				
			||||
#pragma once | 
				
			||||
 | 
				
			||||
#include <commun.h> | 
				
			||||
#include "http_packet.h" | 
				
			||||
 | 
				
			||||
using namespace Bk::Net; | 
				
			||||
void http_server(); | 
				
			||||
std::string http_handler(Socket* sock, Connection conn); | 
				
			||||
@ -0,0 +1,43 @@ | 
				
			||||
#include "http_tools.h" | 
				
			||||
 | 
				
			||||
std::string string_to_lower(std::string& str) | 
				
			||||
{ | 
				
			||||
    for (int i = 0; i < str.length(); i++) | 
				
			||||
    { | 
				
			||||
        str[i] = std::tolower(str[i]); | 
				
			||||
    } | 
				
			||||
    return str; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
std::string string_to_upper(std::string& str) | 
				
			||||
{ | 
				
			||||
    for (int i = 0; i < str.length(); i++) | 
				
			||||
    { | 
				
			||||
        str[i] = std::toupper(str[i]); | 
				
			||||
    } | 
				
			||||
    return str; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
std::unique_ptr<std::vector<std::string>> string_split(std::string& str, std::string delimiter, int cpt) | 
				
			||||
{ | 
				
			||||
    std::string s(str); | 
				
			||||
    std::unique_ptr<std::vector<std::string>> splits(new std::vector<std::string>(0)); | 
				
			||||
    size_t pos = 0; | 
				
			||||
    while (((pos = s.find(delimiter)) != std::string::npos) && cpt-- != 0) 
 | 
				
			||||
    { | 
				
			||||
        splits->push_back(s.substr(0, pos)); | 
				
			||||
        s.erase(0, pos + delimiter.length()); | 
				
			||||
    } | 
				
			||||
    if (s.length()) splits->push_back(s); | 
				
			||||
    return splits; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
void string_trim(std::string& str, const std::string& whitespace) | 
				
			||||
{ | 
				
			||||
    const auto strBegin = str.find_first_not_of(whitespace); | 
				
			||||
    const auto strEnd = str.find_last_not_of(whitespace); | 
				
			||||
    if (strBegin != std::string::npos) | 
				
			||||
    { | 
				
			||||
        str.erase(0, strBegin); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,9 @@ | 
				
			||||
#pragma once | 
				
			||||
 | 
				
			||||
#include <cstring> | 
				
			||||
#include <commun.h> | 
				
			||||
 | 
				
			||||
std::string string_to_lower(std::string& str); | 
				
			||||
std::string string_to_upper(std::string& str); | 
				
			||||
std::unique_ptr<std::vector<std::string>> string_split(std::string& str, std::string delimiter, int cpt = -1); | 
				
			||||
void string_trim(std::string& str, const std::string& whitespace = " \b\0"); | 
				
			||||
@ -0,0 +1,11 @@ | 
				
			||||
#include <commun.h> | 
				
			||||
#include "http/http_server.h" | 
				
			||||
 | 
				
			||||
int main() 
 | 
				
			||||
{ | 
				
			||||
    http_server(); | 
				
			||||
    return 0; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
					Loading…
					
					
				
		Reference in New Issue