win32 support

This commit is contained in:
BENEDEK László 2024-05-31 21:42:16 +02:00
parent f77c95e99e
commit bacb6d2fb3
9 changed files with 80 additions and 10 deletions

View File

@ -7,11 +7,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS true) set(CMAKE_EXPORT_COMPILE_COMMANDS true)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable -Wno-unused-private-field") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable -Wno-unused-private-field -Wno-missing-field-initializers -Wno-c99-designator")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable -Wno-unused-private-field") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable -Wno-unused-private-field -Wno-missing-field-initializers -Wno-c99-designator")
file(GLOB_RECURSE SOURCES "${CMAKE_SOURCE_DIR}/src/rum/*.cpp") file(GLOB_RECURSE SOURCES "${CMAKE_SOURCE_DIR}/src/rum/*.cpp")
set(HEADERS "${CMAKE_SOURCE_DIR}/inc/rum") set(HEADERS "${CMAKE_SOURCE_DIR}/inc/rum")
include_directories("/usr/local/include")
add_library(rum OBJECT ${SOURCES}) add_library(rum OBJECT ${SOURCES})
set_target_properties(rum PROPERTIES POSITION_INDEPENDENT_CODE 1) set_target_properties(rum PROPERTIES POSITION_INDEPENDENT_CODE 1)
target_include_directories(rum PUBLIC "${CMAKE_SOURCE_DIR}/inc") target_include_directories(rum PUBLIC "${CMAKE_SOURCE_DIR}/inc")
@ -24,10 +27,18 @@ add_library(rum-shared SHARED $<TARGET_OBJECTS:rum>)
set_target_properties(rum-shared PROPERTIES OUTPUT_NAME rum) set_target_properties(rum-shared PROPERTIES OUTPUT_NAME rum)
target_include_directories(rum-shared PUBLIC "${CMAKE_SOURCE_DIR}/inc") target_include_directories(rum-shared PUBLIC "${CMAKE_SOURCE_DIR}/inc")
if(WIN32)
target_link_libraries(rum-shared ws2_32)
target_link_libraries(rum-static ws2_32)
endif()
add_executable(example "${CMAKE_SOURCE_DIR}/src/server.cpp") add_executable(example "${CMAKE_SOURCE_DIR}/src/server.cpp")
target_link_libraries(example rum-shared) target_link_libraries(example rum-shared)
option(USE_FLAGS "Use flags in example" OFF)
if(USE_FLAGS) if(USE_FLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_FLAGS") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_FLAGS")
target_link_directories(example PUBLIC "/usr/local/lib")
target_link_libraries(example flags-cpp) target_link_libraries(example flags-cpp)
endif() endif()

View File

@ -2,6 +2,10 @@
#include <string> #include <string>
#ifdef _WIN32
#undef DELETE
#endif
namespace Rum::HTTP { namespace Rum::HTTP {
enum Method { GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE }; enum Method { GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE };

View File

@ -1,6 +1,11 @@
#pragma once #pragma once
#ifdef _WIN32
#include <winsock2.h>
#else
#include <netinet/in.h> #include <netinet/in.h>
#endif
#include <condition_variable> #include <condition_variable>
#include <map> #include <map>
#include <mutex> #include <mutex>

View File

@ -1,6 +1,11 @@
#pragma once #pragma once
#ifdef _WIN32
#include <winsock2.h>
#else
#include <netinet/in.h> #include <netinet/in.h>
#endif
#include <unistd.h> #include <unistd.h>
#include <functional> #include <functional>
@ -9,7 +14,7 @@
namespace Rum::TCP { namespace Rum::TCP {
class Server { class Server {
private: private:
const int sock; int sock;
unsigned short port; unsigned short port;
bool stop; bool stop;
@ -22,7 +27,12 @@ class Server {
void listen(const std::function<void(int, sockaddr_in)>& handler) const; void listen(const std::function<void(int, sockaddr_in)>& handler) const;
virtual void end() { virtual void end() {
stop = true; stop = true;
#ifdef _WIN32
shutdown(sock, SD_BOTH);
closesocket(sock);
#else
close(sock); close(sock);
#endif
} }
}; };
} // namespace Rum::TCP } // namespace Rum::TCP

View File

@ -1,6 +1,11 @@
#pragma once #pragma once
#ifdef _WIN32
#include <winsock2.h>
#else
#include <netinet/in.h> #include <netinet/in.h>
#endif
#include <string> #include <string>
namespace Rum::TCP { namespace Rum::TCP {

View File

@ -1,5 +1,4 @@
#include <rum/http/cookie.h> #include <rum/http/cookie.h>
#include <sys/select.h>
#include <chrono> #include <chrono>
#include <ctime> #include <ctime>

View File

@ -1,6 +1,10 @@
#include <rum/http/response.h> #include <rum/http/response.h>
#include <rum/tcp/error.h> #include <rum/tcp/error.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h> #include <sys/socket.h>
#endif
#if __cplusplus >= 202302L #if __cplusplus >= 202302L
#include <format> #include <format>
#endif #endif

View File

@ -8,6 +8,7 @@
#include <regex> #include <regex>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <thread>
namespace Rum::HTTP { namespace Rum::HTTP {
Server::Server(unsigned int port, size_t worker_count, size_t buffer_size) : Rum::TCP::Server(port), buffer_size(buffer_size), stop(false) { Server::Server(unsigned int port, size_t worker_count, size_t buffer_size) : Rum::TCP::Server(port), buffer_size(buffer_size), stop(false) {
@ -37,9 +38,19 @@ Server::Server(unsigned int port, size_t worker_count, size_t buffer_size) : Rum
(void)i; (void)i;
#endif #endif
handler(task.client_sock, task.sockaddr, buffer); handler(task.client_sock, task.sockaddr, buffer);
if (int status = close(task.client_sock); status == TCP::Error::UNKNOWN) {
#ifdef _WIN32
int err = shutdown(task.client_sock, SD_BOTH);
if (err == SOCKET_ERROR)
std::cerr << "shutdown: " << TCP::to_string(task.sockaddr) << ": " << WSAGetLastError() << std::endl;
if (int status = closesocket(task.client_sock); status != 0)
std::cerr << "closesocket: " << TCP::to_string(task.sockaddr) << ": " << status << " -> " << WSAGetLastError() << std::endl;
#else
if (int status = close(task.client_sock); status == TCP::Error::UNKNOWN)
std::cerr << TCP::to_string(task.sockaddr) << ": " << TCP::Error((TCP::Error::Type)status).what() << std::endl; std::cerr << TCP::to_string(task.sockaddr) << ": " << TCP::Error((TCP::Error::Type)status).what() << std::endl;
} #endif
} }
}); });
workers.emplace_back(std::move(worker)); workers.emplace_back(std::move(worker));

View File

@ -1,7 +1,14 @@
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <signal.h>
#else
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/socket.h>
#endif
#include <rum/tcp/error.h> #include <rum/tcp/error.h>
#include <rum/tcp/server.h> #include <rum/tcp/server.h>
#include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <csignal> #include <csignal>
#include <functional> #include <functional>
@ -13,13 +20,23 @@ std::string to_string(const sockaddr_in& address) {
return std::string(inet_ntoa(address.sin_addr)) + ":" + std::to_string(ntohs(address.sin_port)); return std::string(inet_ntoa(address.sin_addr)) + ":" + std::to_string(ntohs(address.sin_port));
} }
Server::Server(unsigned short port) : sock(socket(AF_INET, SOCK_STREAM, 0)), port(port), stop(false) { Server::Server(unsigned short port) : port(port), stop(false) {
#ifdef _WIN32
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2,2), &wsaData);
if (result != 0)
throw Error(Error::UNKNOWN);
#endif
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) if (sock == -1)
throw Error(Error::UNKNOWN); throw Error(Error::UNKNOWN);
#ifndef _WIN32
std::signal(SIGPIPE, SIG_IGN); std::signal(SIGPIPE, SIG_IGN);
#endif
sockaddr_in address = {.sin_family = AF_INET, .sin_port = htons(port), .sin_addr = {.s_addr = INADDR_ANY}, .sin_zero="0000000"};
sockaddr_in address = {.sin_family = AF_INET, .sin_port = htons(port), .sin_addr = {.s_addr = INADDR_ANY}};
if (bind(sock, (struct sockaddr*)&address, sizeof(address)) == -1) if (bind(sock, (struct sockaddr*)&address, sizeof(address)) == -1)
throw Error(Error::UNKNOWN); throw Error(Error::UNKNOWN);
@ -27,6 +44,10 @@ Server::Server(unsigned short port) : sock(socket(AF_INET, SOCK_STREAM, 0)), por
Server::~Server() { Server::~Server() {
end(); end();
#ifdef _WIN32
WSACleanup();
#endif
} }
void Server::listen(const std::function<void(int, sockaddr_in)>& handler) const { void Server::listen(const std::function<void(int, sockaddr_in)>& handler) const {