Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ SRCS = $(addprefix $(SRC_DIR)/, \
core/server.hpp \
core/signals.cpp \
core/signals.hpp \
http/http_request.hpp \
handler/handler.cpp \
handler/handler.hpp \
handler/get_handler.cpp \
handler/get_handler.hpp \
http/http_request.hpp \
http/http_response.cpp \
http/http_response.hpp \
router/router.cpp \
Expand Down
11 changes: 10 additions & 1 deletion src/core/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,29 @@
#include <fcntl.h>
#include <unistd.h>

#include <iostream>

Client::Client(int fd, const sockaddr_in& addr)
: fd_(fd),
addr_(addr),
prev_(NULL),
next_(NULL)
next_(NULL),
handler_(NULL)

{
set_nonblocking();
std::cout << "Client constructor called" << std::endl;
}

Client::~Client()
{
if (fd_ != -1) {
close(fd_);
}
if (handler_) {
delete (handler_);
}
std::cout << "Client destructor called" << std::endl;
}

void Client::set_nonblocking()
Expand Down
10 changes: 7 additions & 3 deletions src/core/client.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef CORE_CLIENT_HPP_
#define CORE_CLIENT_HPP_

#include "handler/handler.hpp"
#include "http/http_request.hpp"
#include "http/http_response.hpp"

Expand All @@ -13,20 +14,22 @@ class Client {
Client(int fd, const sockaddr_in& addr);
~Client();

// setters
void set_handler(Handler* handler) { handler_ = handler; }
void set_nonblocking();
void set_request(const HttpRequest& req) { req_ = req; }
void set_response(const HttpResponse& res) { res_ = res; }
void set_next(Client* conn) { next_ = conn; }
void set_prev(Client* conn) { prev_ = conn; }

// getters
Handler* handler() const { return handler_; }
int fd() const { return fd_; }
const sockaddr_in& addr() const { return addr_; }

const HttpRequest& req() const { return req_; }
HttpResponse& res() { return res_; }
std::string& recv_buffer() { return recv_buffer_; }
std::string& send_buffer() { return send_buffer_; }

Client* next() { return next_; }
Client* prev() { return prev_; }

Expand All @@ -39,11 +42,12 @@ class Client {
int fd_;
sockaddr_in addr_;
HttpRequest req_;
HttpResponse res_;
HttpResponse res_; // TODO: remove
std::string recv_buffer_;
std::string send_buffer_;
Client* prev_;
Client* next_;
Handler* handler_;
};

#endif // CORE_CLIENT_HPP_
135 changes: 66 additions & 69 deletions src/core/server.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#include "core/server.hpp"

#include "core/signals.hpp"
#include "handler/get_handler.hpp"
#include "http/http_request.hpp"
#include "http/http_response.hpp"
#include "router/router.hpp"
#include "util/syscall_error.hpp"

Expand All @@ -12,6 +10,7 @@
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
Expand Down Expand Up @@ -125,28 +124,6 @@ void Server::accept_connection()
add_connection(client);
}

static void print_http_request(const std::string& s)
{
std::cout << "< ";

for (size_t i = 0; i < s.size(); ++i) {
char c = s[i];
if (c == '\r') {
std::cout << "\\r";
}
else if (c == '\n') {
std::cout << "\\n\n";
if (i < s.size() - 1) {
std::cout << "< ";
}
}
else {
std::cout.put(c);
}
}
std::cout.flush();
}

void Server::run()
{
while (!g_sigint_received) {
Expand Down Expand Up @@ -178,64 +155,84 @@ void Server::run()
}
}

void Server::handle_events(Client* conn, uint32_t events)
// Dirty hack
static void print_raw_data(const std::string& s)
{
if (events & EPOLLIN) {
receive_request(conn);
}
if (events & EPOLLOUT) {
send_response(conn);
std::cout << "< ";

for (size_t i = 0; i < s.size(); ++i) {
char c = s[i];
if (c == '\r') {
std::cout << "\\r";
}
else if (c == '\n') {
std::cout << "\\n\n";
if (i < s.size() - 1) {
std::cout << "< ";
}
}
else {
std::cout.put(c);
}
}
std::cout.flush();
}

// also chunked requests will need to be handled
void Server::receive_request(Client* conn)
void Server::handle_events(Client* conn, uint32_t events)
{
int client_fd = conn->fd();
char buf[4096];
char tmp[4096];

int n_bytes = recv(client_fd, buf, sizeof(buf), 0);
conn->recv_buffer().append(buf, n_bytes);
// No handler yet, assume it's a new request (hardcoded for now)
if (!conn->handler()) {
HttpRequest req;
req.method = "GET";
req.path = "/files/42.txt";
conn->set_request(req);

std::cout << "* Request received\n";
Handler* h = router_.handle_request(conn->req());
conn->set_handler(h);
}

print_http_request(conn->recv_buffer());
// Can read from socket
if (events & EPOLLIN) {
int n = recv(client_fd, tmp, sizeof(tmp), 0);
if (n == 0) {
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, client_fd, NULL);
remove_connection(conn);
return;
}
if (n > 0) {
conn->recv_buffer().append(tmp, n);

epoll_event ev;
ev.events = EPOLLOUT;
ev.data.ptr = conn;
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, client_fd, &ev);

// reading from socket and storing request in Client (TO DO : IBOUKHSS)
// for dev, mimic a http request and call the routing function
HttpRequest req;
req.method = "GET";
req.path = "/files/42.txt";

conn->set_request(req);

// DHE: adding full_path variable to run make lint. The router_.handle_request() call needs to
// be moved out
std::string full_path;
if (!router_.handle_request(conn, req, full_path))
return; // bad request
if (req.method == "GET") {
// add handler to conn
// conn.handler = New GetHandler(full_path);
std::cout << "* Received from socket\n";
print_raw_data(conn->recv_buffer());

epoll_event ev;
ev.events = EPOLLOUT;
ev.data.ptr = conn;
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, client_fd, &ev);
}
}
}

void Server::send_response(Client* conn)
{
int client_fd = conn->fd();
HttpResponse res = conn->res();
std::string raw = res.to_string();
// Can write to socket
if (events & EPOLLOUT) {
if (conn->handler()->is_readable()) {
int n = conn->handler()->read_data(tmp, sizeof(tmp));
if (n > 0)
conn->send_buffer().append(tmp, n);
}

send(client_fd, raw.data(), raw.size(), 0);
if (!conn->send_buffer().empty()) {
int n = send(client_fd, conn->send_buffer().data(), conn->send_buffer().size(), 0);
if (n > 0)
conn->send_buffer().erase(0, n);
}

if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, client_fd, NULL) == -1) {
throw UnrecoverableError("epoll_ctl", errno);
if (conn->handler()->is_done() && conn->send_buffer().empty()) {
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, client_fd, NULL);
remove_connection(conn);
return;
}
}

remove_connection(conn);
}
1 change: 0 additions & 1 deletion src/core/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class Server {
void run();

void handle_events(Client* conn, uint32_t events);
void handle_request(Client* conn, const HttpRequest& request);

void accept_connection();
void add_connection(Client* conn);
Expand Down
Loading