Skip to content

Commit fe3ad38

Browse files
committed
feat: add virtual handler
1 parent cdfd9de commit fe3ad38

File tree

17 files changed

+296
-218
lines changed

17 files changed

+296
-218
lines changed

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ SRCS = $(addprefix $(SRC_DIR)/, \
1919
core/server.hpp \
2020
core/signals.cpp \
2121
core/signals.hpp \
22-
http/http_request.hpp \
22+
handler/handler.cpp \
23+
handler/handler.hpp \
24+
handler/get_handler.cpp \
25+
handler/get_handler.hpp \
26+
http/http_request.hpp \
2327
http/http_response.cpp \
2428
http/http_response.hpp \
2529
router/router.cpp \

src/core/client.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@
55
#include <fcntl.h>
66
#include <unistd.h>
77

8+
#include <iostream>
9+
810
Client::Client(int fd, const sockaddr_in& addr)
911
: fd_(fd),
1012
addr_(addr),
1113
prev_(NULL),
12-
next_(NULL)
14+
next_(NULL),
15+
handler_(NULL)
16+
1317
{
1418
set_nonblocking();
19+
std::cout << "Client constructor called" << std::endl;
1520
}
1621

1722
Client::~Client()
1823
{
1924
if (fd_ != -1) {
2025
close(fd_);
2126
}
27+
if (handler_) {
28+
delete (handler_);
29+
}
30+
std::cout << "Client destructor called" << std::endl;
2231
}
2332

2433
void Client::set_nonblocking()

src/core/client.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CORE_CLIENT_HPP_
22
#define CORE_CLIENT_HPP_
33

4+
#include "handler/handler.hpp"
45
#include "http/http_request.hpp"
56
#include "http/http_response.hpp"
67

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

17+
// setters
18+
void set_handler(Handler* handler) { handler_ = handler; }
1619
void set_nonblocking();
1720
void set_request(const HttpRequest& req) { req_ = req; }
1821
void set_response(const HttpResponse& res) { res_ = res; }
1922
void set_next(Client* conn) { next_ = conn; }
2023
void set_prev(Client* conn) { prev_ = conn; }
2124

25+
// getters
26+
Handler* handler() const { return handler_; }
2227
int fd() const { return fd_; }
2328
const sockaddr_in& addr() const { return addr_; }
24-
2529
const HttpRequest& req() const { return req_; }
2630
HttpResponse& res() { return res_; }
2731
std::string& recv_buffer() { return recv_buffer_; }
2832
std::string& send_buffer() { return send_buffer_; }
29-
3033
Client* next() { return next_; }
3134
Client* prev() { return prev_; }
3235

@@ -39,11 +42,12 @@ class Client {
3942
int fd_;
4043
sockaddr_in addr_;
4144
HttpRequest req_;
42-
HttpResponse res_;
45+
HttpResponse res_; // TODO: remove
4346
std::string recv_buffer_;
4447
std::string send_buffer_;
4548
Client* prev_;
4649
Client* next_;
50+
Handler* handler_;
4751
};
4852

4953
#endif // CORE_CLIENT_HPP_

src/core/server.cpp

Lines changed: 66 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
#include "core/server.hpp"
22

33
#include "core/signals.hpp"
4-
#include "handler/get_handler.hpp"
54
#include "http/http_request.hpp"
6-
#include "http/http_response.hpp"
75
#include "router/router.hpp"
86
#include "util/syscall_error.hpp"
97

@@ -12,6 +10,7 @@
1210
#include <netinet/in.h>
1311
#include <stdlib.h>
1412
#include <string.h>
13+
#include <sys/epoll.h>
1514
#include <sys/socket.h>
1615
#include <sys/stat.h>
1716
#include <unistd.h>
@@ -125,28 +124,6 @@ void Server::accept_connection()
125124
add_connection(client);
126125
}
127126

128-
static void print_http_request(const std::string& s)
129-
{
130-
std::cout << "< ";
131-
132-
for (size_t i = 0; i < s.size(); ++i) {
133-
char c = s[i];
134-
if (c == '\r') {
135-
std::cout << "\\r";
136-
}
137-
else if (c == '\n') {
138-
std::cout << "\\n\n";
139-
if (i < s.size() - 1) {
140-
std::cout << "< ";
141-
}
142-
}
143-
else {
144-
std::cout.put(c);
145-
}
146-
}
147-
std::cout.flush();
148-
}
149-
150127
void Server::run()
151128
{
152129
while (!g_sigint_received) {
@@ -178,64 +155,84 @@ void Server::run()
178155
}
179156
}
180157

181-
void Server::handle_events(Client* conn, uint32_t events)
158+
// Dirty hack
159+
static void print_raw_data(const std::string& s)
182160
{
183-
if (events & EPOLLIN) {
184-
receive_request(conn);
185-
}
186-
if (events & EPOLLOUT) {
187-
send_response(conn);
161+
std::cout << "< ";
162+
163+
for (size_t i = 0; i < s.size(); ++i) {
164+
char c = s[i];
165+
if (c == '\r') {
166+
std::cout << "\\r";
167+
}
168+
else if (c == '\n') {
169+
std::cout << "\\n\n";
170+
if (i < s.size() - 1) {
171+
std::cout << "< ";
172+
}
173+
}
174+
else {
175+
std::cout.put(c);
176+
}
188177
}
178+
std::cout.flush();
189179
}
190180

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

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

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

202-
print_http_request(conn->recv_buffer());
197+
// Can read from socket
198+
if (events & EPOLLIN) {
199+
int n = recv(client_fd, tmp, sizeof(tmp), 0);
200+
if (n == 0) {
201+
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, client_fd, NULL);
202+
remove_connection(conn);
203+
return;
204+
}
205+
if (n > 0) {
206+
conn->recv_buffer().append(tmp, n);
203207

204-
epoll_event ev;
205-
ev.events = EPOLLOUT;
206-
ev.data.ptr = conn;
207-
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, client_fd, &ev);
208-
209-
// reading from socket and storing request in Client (TO DO : IBOUKHSS)
210-
// for dev, mimic a http request and call the routing function
211-
HttpRequest req;
212-
req.method = "GET";
213-
req.path = "/files/42.txt";
214-
215-
conn->set_request(req);
216-
217-
// DHE: adding full_path variable to run make lint. The router_.handle_request() call needs to
218-
// be moved out
219-
std::string full_path;
220-
if (!router_.handle_request(conn, req, full_path))
221-
return; // bad request
222-
if (req.method == "GET") {
223-
// add handler to conn
224-
// conn.handler = New GetHandler(full_path);
208+
std::cout << "* Received from socket\n";
209+
print_raw_data(conn->recv_buffer());
210+
211+
epoll_event ev;
212+
ev.events = EPOLLOUT;
213+
ev.data.ptr = conn;
214+
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, client_fd, &ev);
215+
}
225216
}
226-
}
227217

228-
void Server::send_response(Client* conn)
229-
{
230-
int client_fd = conn->fd();
231-
HttpResponse res = conn->res();
232-
std::string raw = res.to_string();
218+
// Can write to socket
219+
if (events & EPOLLOUT) {
220+
if (conn->handler()->is_readable()) {
221+
int n = conn->handler()->read_data(tmp, sizeof(tmp));
222+
if (n > 0)
223+
conn->send_buffer().append(tmp, n);
224+
}
233225

234-
send(client_fd, raw.data(), raw.size(), 0);
226+
if (!conn->send_buffer().empty()) {
227+
int n = send(client_fd, conn->send_buffer().data(), conn->send_buffer().size(), 0);
228+
if (n > 0)
229+
conn->send_buffer().erase(0, n);
230+
}
235231

236-
if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, client_fd, NULL) == -1) {
237-
throw UnrecoverableError("epoll_ctl", errno);
232+
if (conn->handler()->is_done() && conn->send_buffer().empty()) {
233+
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, client_fd, NULL);
234+
remove_connection(conn);
235+
return;
236+
}
238237
}
239-
240-
remove_connection(conn);
241238
}

src/core/server.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class Server {
2020
void run();
2121

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

2524
void accept_connection();
2625
void add_connection(Client* conn);

0 commit comments

Comments
 (0)