Vinayak Ambigapathy ago%!(EXTRA string=2 months)
parent 66483a3838
commit 0570a7ce7b
  1. 2
      premake5.lua
  2. 7
      src/bakanet/core/socket.h
  3. 26
      src/bakanet/http/server.cpp
  4. 14
      src/bakanet/http/server.h
  5. 4
      src/bakanetpch.h
  6. 40
      src/platform/windows/windows_dns_lookup.cpp
  7. 3
      src/platform/windows/windows_ip_adress.cpp
  8. 18
      src/platform/windows/windows_socket.cpp
  9. 3
      src/platform/windows/windows_socket.h

@ -28,7 +28,7 @@ project "bakanet"
} }
filter "system:windows" filter "system:windows"
buildoptions "/MDd" buildoptions { "/MT", "/utf-8" }
defines defines
{ {
"BK_PLATFORM_WINDOWS" "BK_PLATFORM_WINDOWS"

@ -16,8 +16,9 @@ namespace Bk::Net {
virtual bool init() = 0; virtual bool init() = 0;
virtual bool start(int cpt_conn) = 0; virtual bool start(int cpt_conn) = 0;
virtual std::unique_ptr<Socket> ack() = 0; virtual Socket* ack() = 0;
virtual bool conn() = 0; virtual bool conn() = 0;
virtual bool hasConnection(int seconds = 0, int microseconds = 0) = 0;
virtual int get_raw_socket() = 0; virtual int get_raw_socket() = 0;
@ -29,8 +30,8 @@ namespace Bk::Net {
template<typename T> template<typename T>
static bool set_option(Socket& socket, OptionLayer level, SocketOption option_name, const T* option_value) { return setsockopt(socket.get_raw_socket(), (int)level, (int)option_name, (void*)option_value, sizeof(T)) == 0 ? true : false; } static bool set_option(Socket& socket, OptionLayer level, SocketOption option_name, const T* option_value) { return setsockopt(socket.get_raw_socket(), (int)level, (int)option_name, (void*)option_value, sizeof(T)) == 0 ? true : false; }
static std::unique_ptr<Socket> create(IpAddress ip, int port, IpProtocol proto); static Socket* create(IpAddress ip, int port, IpProtocol proto);
protected: protected:
static std::unique_ptr<Socket> create(int id, IpVersion ver, IpProtocol proto); static Socket* create(int id, IpVersion ver, IpProtocol proto);
}; };
} }

@ -1,4 +1,5 @@
#include "server.h" #include "server.h"
namespace Bk::Net { namespace Bk::Net {
HttpServer::HttpServer(IpAddress ip, int port) HttpServer::HttpServer(IpAddress ip, int port)
{ {
@ -6,16 +7,23 @@ namespace Bk::Net {
radix = RadixTree(); radix = RadixTree();
} }
HttpServer::~HttpServer()
{
delete socket;
}
void HttpServer::start() void HttpServer::start()
{ {
bool running = socket->init() && socket->start(5); bool running = socket->init() && socket->start(5);
while (running) while (running)
{ {
std::unique_ptr<Socket> conn = socket->ack(); Socket* conn = socket->ack();
threads.push_back(std::thread([this](std::unique_ptr<Socket> conn) pool.queue([this, conn]()
{ {
route_request(*conn, recv_request(*conn)); route_request(conn, recv_request(conn));
}, std::move(conn))); delete conn;
});
pool.stop();
} }
} }
@ -55,13 +63,13 @@ namespace Bk::Net {
else radix.add_nodes(splits->data(), splits->size(), HttpMethodArray({{ "PUT", req_handler }})); else radix.add_nodes(splits->data(), splits->size(), HttpMethodArray({{ "PUT", req_handler }}));
} }
HttpRequest HttpServer::recv_request(Socket& conn) HttpRequest HttpServer::recv_request(Socket* conn)
{ {
Type::DataStream req; Type::DataStream req;
std::vector<char> data; std::vector<char> data;
do do
{ {
data = conn.obtain(1024); data = conn->obtain(1024);
req.append_data(data); req.append_data(data);
} while(data.size() >= 1024); } while(data.size() >= 1024);
int req_size = req.size(); int req_size = req.size();
@ -69,15 +77,15 @@ namespace Bk::Net {
return HttpRequest("", "", ""); return HttpRequest("", "", "");
} }
void HttpServer::send_reponse(Socket& conn, HttpReponse res) void HttpServer::send_reponse(Socket* conn, HttpReponse res)
{ {
Type::DataStream res_packet; Type::DataStream res_packet;
std::string str_res = res.to_string(); std::string str_res = res.to_string();
res_packet.push<char>(str_res.c_str(), str_res.length()); res_packet.push<char>(str_res.c_str(), str_res.length());
conn.emit(res_packet.payload); conn->emit(res_packet.payload);
} }
void HttpServer::route_request(Socket& conn, HttpRequest req) void HttpServer::route_request(Socket* conn, HttpRequest req)
{ {
std::string url = std::string(req.url); std::string url = std::string(req.url);
Tools::string_trim(url, " /"); Tools::string_trim(url, " /");

@ -2,6 +2,7 @@
#include <bakanetpch.h> #include <bakanetpch.h>
#include <bakanet/core/ip_address.h> #include <bakanet/core/ip_address.h>
#include <bakatools/thread/task_pool.h>
#include <bakanet/core/socket.h> #include <bakanet/core/socket.h>
#include "packet.h" #include "packet.h"
@ -9,13 +10,12 @@ namespace Bk::Net {
using RequestHandler = std::function<HttpReponse(HttpRequest& req)>; using RequestHandler = std::function<HttpReponse(HttpRequest& req)>;
using HttpMethodArray = std::unordered_map<std::string, RequestHandler>; using HttpMethodArray = std::unordered_map<std::string, RequestHandler>;
using RadixTree = Type::Trie<std::string, HttpMethodArray>; using RadixTree = Type::Trie<std::string, HttpMethodArray>;
using ThreadPool = std::vector<std::thread>;
class HttpServer class HttpServer
{ {
public: public:
HttpServer(IpAddress ip, int port); HttpServer(IpAddress ip, int port);
~HttpServer() = default; ~HttpServer();
void start(); void start();
void get(std::string url, RequestHandler req_handler); void get(std::string url, RequestHandler req_handler);
void post(std::string url, RequestHandler req_handler); void post(std::string url, RequestHandler req_handler);
@ -23,12 +23,12 @@ namespace Bk::Net {
void put(std::string url, RequestHandler req_handler); void put(std::string url, RequestHandler req_handler);
private: private:
std::unique_ptr<Socket> socket; Socket* socket;
ThreadPool threads; ThreadPool pool;
RadixTree radix; RadixTree radix;
HttpRequest recv_request(Socket& conn); HttpRequest recv_request(Socket* conn);
void send_reponse(Socket& conn, HttpReponse res); void send_reponse(Socket* conn, HttpReponse res);
void route_request(Socket& conn, HttpRequest req); void route_request(Socket* conn, HttpRequest req);
}; };
} }

@ -15,8 +15,8 @@
#include <bakatools.h> #include <bakatools.h>
#if defined(BK_PLATFORM_WINDOWS) #if defined(BK_PLATFORM_WINDOWS)
#include <Ws2tcpip.h> #include <ws2tcpip.h>
#include <WinSock2.h> #include <winsock2.h>
#include <tchar.h> #include <tchar.h>
#pragma comment(lib,"WS2_32.lib") #pragma comment(lib,"WS2_32.lib")
#elif defined(BK_PLATFORM_LINUX) #elif defined(BK_PLATFORM_LINUX)

@ -0,0 +1,40 @@
#include <bakanet/core/dns_lookup.h>
namespace Bk::Net {
std::vector<std::string> dns_lookup(const std::string& host_name, IpVersion ipv)
{
std::vector<std::string> output;
struct addrinfo hints, *res, *p;
char ip_address[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = (int)ipv;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(host_name.c_str(), NULL, &hints, &res) != 0)
{
output.push_back("");
return output;
}
for (p = res;p != NULL; p = p->ai_next)
{
void* addr;
if (p->ai_family == AF_INET)
{
struct sockaddr_in* ipv4 = (struct sockaddr_in*)p->ai_addr;
addr = &(ipv4->sin_addr);
}
else
{
struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)p->ai_addr;
addr = &(ipv6->sin6_addr);
}
inet_ntop(p->ai_family, addr, ip_address, sizeof ip_address);
output.push_back(ip_address);
}
freeaddrinfo(res); // free the linked list
return output;
}
}

@ -9,7 +9,8 @@ namespace Bk::Net {
addr.s_addr = INADDR_ANY; addr.s_addr = INADDR_ANY;
return addr; return addr;
} }
else if (InetPton(AF_INET, (PWSTR)str.c_str(), &addr) <= 0) perror("Bad IP"); int result = InetPtonW(AF_INET, std::wstring(str.begin(), str.end()).c_str(), &addr);
if (result <= 0) BK_CORE_ERROR("Bad IP {0}", result);
return addr; return addr;
} }
} }

@ -66,7 +66,7 @@ namespace Bk::Net {
return true; return true;
} }
std::unique_ptr<Socket> WindowsSocket::ack() Socket* WindowsSocket::ack()
{ {
socklen_t addrlen = sizeof(addr); socklen_t addrlen = sizeof(addr);
return Socket::create(accept((SOCKET)id, (struct sockaddr*)&addr, &addrlen), ip_addr.version, ip_proto); return Socket::create(accept((SOCKET)id, (struct sockaddr*)&addr, &addrlen), ip_addr.version, ip_proto);
@ -78,6 +78,14 @@ namespace Bk::Net {
return true; return true;
} }
bool WindowsSocket::hasConnection(int seconds, int microseconds) {
struct timeval tv = { seconds, microseconds };
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(id, &rfds);
return select(id + 1, &rfds, (fd_set*)0, (fd_set*)0, &tv) > 0;
};
void WindowsSocket::emit(std::vector<char> packet) void WindowsSocket::emit(std::vector<char> packet)
{ {
send((SOCKET)id, packet.data(), packet.size(), 0); send((SOCKET)id, packet.data(), packet.size(), 0);
@ -92,13 +100,13 @@ namespace Bk::Net {
return buffer; return buffer;
} }
std::unique_ptr<Socket> Socket::create(IpAddress ip, int port, IpProtocol proto) Socket* Socket::create(IpAddress ip, int port, IpProtocol proto)
{ {
return std::unique_ptr<Socket>(new WindowsSocket(ip, port, proto)); return new WindowsSocket(ip, port, proto);
} }
std::unique_ptr<Socket> Socket::create(int id, IpVersion ver, IpProtocol proto) Socket* Socket::create(int id, IpVersion ver, IpProtocol proto)
{ {
return std::unique_ptr<Socket>(new WindowsSocket(id, ver, proto)); return new WindowsSocket(id, ver, proto);
} }
} }

@ -14,8 +14,9 @@ namespace Bk::Net {
bool init() override; bool init() override;
bool start(int cpt_conn) override; bool start(int cpt_conn) override;
std::unique_ptr<Socket> ack() override; Socket* ack() override;
bool conn() override; bool conn() override;
bool hasConnection(int seconds = 0, int microseconds = 0) override;
int get_raw_socket() override { return id; } int get_raw_socket() override { return id; }
const std::string get_ip() override { return ip_addr.str; } const std::string get_ip() override { return ip_addr.str; }

Loading…
Cancel
Save