diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ClientConnection.cpp | 23 | ||||
| -rw-r--r-- | src/ServerConnection.cpp | 26 | ||||
| -rw-r--r-- | src/main.cpp | 18 | 
3 files changed, 56 insertions, 11 deletions
| diff --git a/src/ClientConnection.cpp b/src/ClientConnection.cpp index c434212..e8e6692 100644 --- a/src/ClientConnection.cpp +++ b/src/ClientConnection.cpp @@ -3,7 +3,13 @@  #include <cstring>  #include <iostream>  #include <sstream> -#include <unistd.h> + +#ifdef _WIN32 +	#include <winsock2.h> +	#pragma comment(lib, "ws2_32.lib") +#else +	#include <unistd.h> +#endif  ClientConnection::ClientConnection(int socket)  	: m_socket_fd(socket) @@ -19,7 +25,12 @@ HttpRequest ClientConnection::read_request() const  	int n = 0;  	memset(buffer, 0, BUFFER_SIZE); -	while ((n = read(m_socket_fd, buffer, BUFFER_SIZE - 1)) > 0) { +#ifdef _WIN32 +	n = recv(m_socket_fd, buffer, BUFFER_SIZE - 1, 0); +#else +	n = read(m_socket_fd, buffer, BUFFER_SIZE - 1); +#endif +	while (n > 0) {  		if (buffer[n - 1] == '\n')  			break; @@ -35,7 +46,11 @@ bool ClientConnection::send(const HttpResponse& response) const  		return false;  	std::string result = response.to_string(); +#ifdef _WIN32 +	::send(m_socket_fd, result.c_str(), result.length(), 0); +#else  	write(m_socket_fd, result.c_str(), result.length()); +#endif  	return true;  } @@ -43,5 +58,9 @@ bool ClientConnection::send(const HttpResponse& response) const  void ClientConnection::close_connection()  {  	m_is_open = false; +#ifdef _WIN32 +	closesocket(m_socket_fd); +#else  	close(m_socket_fd); +#endif  } diff --git a/src/ServerConnection.cpp b/src/ServerConnection.cpp index 64692b6..0a47dc3 100644 --- a/src/ServerConnection.cpp +++ b/src/ServerConnection.cpp @@ -1,13 +1,17 @@  #include "ServerConnection.h" -#include <arpa/inet.h> -#include <csignal> -#include <netdb.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/time.h>  #include <sys/types.h> -#include <unistd.h> + +#ifdef _WIN32 +	#include <winsock2.h> +	#pragma comment(lib, "ws2_32.lib") +#else +	#include <arpa/inet.h> +	#include <sys/ioctl.h> +	#include <sys/socket.h> +	#include <sys/time.h> +	#include <unistd.h> +#endif  #include "ClientConnection.h" @@ -19,14 +23,22 @@ static void error_and_die(const char* message)  ServerConnection::ServerConnection(int port)  { +#ifdef _WIN32 +	WSADATA wsaData; +	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) +		error_and_die("Failed to initialize Winsock"); +#endif +  	sockaddr_in address {};  	int socket_options = 1;  	if ((m_socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  		error_and_die("Failed to create socket"); +#ifndef _WIN32  	if (setsockopt(m_socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &socket_options, sizeof(socket_options)) != 0)  		error_and_die("setsockopt"); +#endif  	address.sin_family = AF_INET;  	address.sin_addr.s_addr = htonl(INADDR_ANY); diff --git a/src/main.cpp b/src/main.cpp index c0c9bb3..4937f0d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,15 @@ +#ifndef _WIN32  #include <getopt.h> +#endif  #include <filesystem>  #include <fstream>  #include <iostream>  #include <sstream> +#ifndef _WIN32  #include "CGIScript.h" +#endif  #include "ClientConnection.h"  #include "HttpRequest.h"  #include "HttpResponse.h" @@ -66,6 +70,7 @@ static HttpResponse serve_from_filesystem(const HttpRequest& request)  	return response;  } +#ifndef _WIN32  static HttpResponse serve_from_cgi(const std::string& script_path, const HttpRequest& request)  {  	HttpResponse response; @@ -99,11 +104,14 @@ static HttpResponse serve_from_cgi(const std::string& script_path, const HttpReq  	response.add_headers_and_content(script.read_output());  	return response;  } +#endif +#ifndef _WIN32  static option long_options[] = {  	{ "cgi", required_argument, nullptr, 'c' },  	{ "port", required_argument, nullptr, 'p' },  }; +#endif  int main(int argc, char** argv)  { @@ -111,6 +119,8 @@ int main(int argc, char** argv)  	bool in_cgi_mode = false;  	std::string cgi_program_name; +	// TODO: getopt.h is not available on Windows, so this part needs to be rewritten. +#ifndef _WIN32  	int c = 0;  	int option_index = 0;  	while ((c = getopt_long(argc, argv, "c:p:", long_options, &option_index)) != -1) { @@ -135,6 +145,7 @@ int main(int argc, char** argv)  	// script before attempting to start the server.  	if (in_cgi_mode)  		CGIScript::validate_path(cgi_program_name); +#endif  	ServerConnection server(port);  	std::cout << "Serving a " << (in_cgi_mode ? "CGI script" : "directory") << " on port " << port << std::endl; @@ -144,11 +155,14 @@ int main(int argc, char** argv)  		HttpRequest request = client.read_request();  		HttpResponse response; +		// TODO: Support running CGI executables on Windows +#ifndef _WIN32  		if (in_cgi_mode) {  			response = serve_from_cgi(cgi_program_name, request); -		} else { +		} else +#endif  			response = serve_from_filesystem(request); -		} +  		client.send(response);  		client.close_connection(); | 
