Initial setup

This commit is contained in:
Blue 2023-11-21 19:19:08 -03:00
parent 3a0fa57a06
commit 68e795f0e6
Signed by: blue
GPG key ID: 9B203B252A63EE38
17 changed files with 466 additions and 8 deletions

9
server/CMakeLists.txt Normal file
View file

@ -0,0 +1,9 @@
set(HEADERS
server.h
)
set(SOURCES
server.cpp
)
target_sources(pica PRIVATE ${SOURCES})

78
server/server.cpp Normal file
View file

@ -0,0 +1,78 @@
#include "server.h"
constexpr static const char* REQUEST_URI("REQUEST_URI");
constexpr static const char* DOCUMENT_URI("DOCUMENT_URI");
constexpr static const char* DOCUMENT_ROOT("DOCUMENT_ROOT");
constexpr static const char* SCRIPT_NAME("SCRIPT_NAME");
constexpr static const char* SCRIPT_FILENAME("SCRIPT_FILENAME");
constexpr std::string_view info("info");
constexpr std::string_view env("env");
Server::Server():
terminating(false),
requestCount(0),
serverName(std::nullopt)
{}
Server::~Server() {}
void Server::run(int socketDescriptor) {
while (!terminating) {
std::unique_ptr<Request> request = std::make_unique<Request>();
bool result = request->wait(socketDescriptor);
if (!result) {
std::cerr << "Error accepting a request" << std::endl;
return;
}
handleRequest(std::move(request));
}
}
void Server::handleRequest(std::unique_ptr<Request> request) {
++requestCount;
if (!serverName) {
try {
serverName = request->getServerName();
std::cout << "received server name " << serverName.value() << std::endl;
} catch (...) {
std::cerr << "failed to read server name" << std::endl;
Response error(Response::Status::internalError);
error.replyTo(*request.get());
return;
}
}
if (!request->isGet()) {
static const Response methodNotAllowed(Response::Status::methodNotAllowed);
methodNotAllowed.replyTo(*request.get());
return;
}
try {
std::string_view sPath = request->getPath(serverName.value());
if (sPath == info) {
Response res;
res.setBody("Pica<br>\nVersion: 1.0.0<br>\nRequestsHandled: " + std::to_string(requestCount));
res.replyTo(*request.get());
} else if (sPath == env) {
std::ostringstream ss;
request->printEnvironment(ss);
Response res;
res.setBody(ss.str());
res.replyTo(*request.get());
} else {
Response notFound(Response::Status::notFound);
notFound.setBody(std::string("Path ") + sPath.data() + " was not found");
notFound.replyTo(*request.get());
std::cerr << "Not found: " << sPath.data() << std::endl;
}
} catch (const std::exception e) {
Response error(Response::Status::internalError);
error.setBody(e.what());
error.replyTo(*request.get());
}
}

35
server/server.h Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#include <iostream>
#include <string>
#include <sstream>
#include <optional>
#include <string_view>
#include <vector>
#include <memory>
#include <fcgiapp.h>
#include <fcgio.h>
#include <stdint.h>
#include "request/request.h"
#include "response/response.h"
class Server {
public:
Server();
~Server();
void run(int socketDescriptor);
private:
void handleRequest(std::unique_ptr<Request> request);
void router(const std::vector<std::string_view>& path);
void printEnv(std::ostream& out, FCGX_Request& request);
std::string_view getPath(const FCGX_Request& request);
private:
bool terminating;
uint64_t requestCount;
std::optional<std::string> serverName;
};