redone _read_request(). Should work with any BUFSIZE.
+ WIP in some aspects. Need to adjust parse_request() among others things. + update memo.txt
This commit is contained in:
14
memo.txt
14
memo.txt
@@ -1,6 +1,16 @@
|
|||||||
|
IN 42 SUBJECT, PRIORITY :
|
||||||
- do correct handling of special character in url (/rfc2119_files/errata.js.t%C3%A9l%C3%A9chargement -> /rfc2119_files/errata.js.téléchargement)
|
- 505 HTTP Version Not Supported
|
||||||
|
- CGI
|
||||||
- handle redirection
|
- handle redirection
|
||||||
|
- index and autoindex
|
||||||
|
- gestion memoire en cas de bad_alloc
|
||||||
|
- Ecrire des tests !
|
||||||
|
-----------------------------
|
||||||
|
- replace atoi() with a better function
|
||||||
|
- 408 Request Timeout
|
||||||
|
- gerer le champ "Accept" du client
|
||||||
|
- gerer les ".." dans un URL (verifier que l'on ne sort pas du dossier "root")
|
||||||
|
- do correct handling of special character in url (/rfc2119_files/errata.js.t%C3%A9l%C3%A9chargement -> /rfc2119_files/errata.js.téléchargement)
|
||||||
- maybe add a "last_action_time" in Client for timeout handling
|
- maybe add a "last_action_time" in Client for timeout handling
|
||||||
little global timeout on epoll, like 100ms, then find client that actualy need to timeout
|
little global timeout on epoll, like 100ms, then find client that actualy need to timeout
|
||||||
if (actual_time - client.last_action_time > 10000ms){timeout(client)}
|
if (actual_time - client.last_action_time > 10000ms){timeout(client)}
|
||||||
|
|||||||
@@ -5,7 +5,12 @@
|
|||||||
* COPLIENS
|
* COPLIENS
|
||||||
*********************************************/
|
*********************************************/
|
||||||
|
|
||||||
Client::Client() : fd(0), status(0) {
|
Client::Client()
|
||||||
|
: fd(0),
|
||||||
|
status(0),
|
||||||
|
header_complete(false),
|
||||||
|
read_body_size(0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +57,8 @@ void Client::parse_request()
|
|||||||
void Client::clear()
|
void Client::clear()
|
||||||
{
|
{
|
||||||
clear_request();
|
clear_request();
|
||||||
|
header_complete = false;
|
||||||
|
read_body_size = 0;
|
||||||
raw_request.clear();
|
raw_request.clear();
|
||||||
response.clear();
|
response.clear();
|
||||||
status = 0;
|
status = 0;
|
||||||
@@ -125,6 +132,8 @@ void Client::_parse_request_headers( std::vector<std::string> list )
|
|||||||
|
|
||||||
void Client::_parse_request_body( size_t pos )
|
void Client::_parse_request_body( size_t pos )
|
||||||
{
|
{
|
||||||
|
// TODO : a revoir avec une std::string,
|
||||||
|
// pour ne pas avoir le probleme d'un '0' qui marque la fin des données
|
||||||
std::string body = &raw_request[pos];
|
std::string body = &raw_request[pos];
|
||||||
|
|
||||||
_request.body = body;
|
_request.body = body;
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ class Client
|
|||||||
unsigned int status;
|
unsigned int status;
|
||||||
listen_socket *lsocket;
|
listen_socket *lsocket;
|
||||||
|
|
||||||
|
bool header_complete;
|
||||||
|
size_t read_body_size;
|
||||||
|
|
||||||
// const functions ?
|
// const functions ?
|
||||||
http_method get_method();
|
http_method get_method();
|
||||||
std::string &get_path();
|
std::string &get_path();
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#include "Webserv.hpp"
|
#include "Webserv.hpp"
|
||||||
|
|
||||||
#define BUFSIZE 8192
|
#define BUFSIZE 8192
|
||||||
|
#define MAX_HEADER_SIZE 42000
|
||||||
|
#define MAX_BODY_SIZE 500000 // test macro, replace with server config
|
||||||
|
|
||||||
void Webserv::_request(Client *client)
|
void Webserv::_request(Client *client)
|
||||||
{
|
{
|
||||||
@@ -12,9 +14,10 @@ void Webserv::_request(Client *client)
|
|||||||
|
|
||||||
void Webserv::_read_request(Client *client)
|
void Webserv::_read_request(Client *client)
|
||||||
{
|
{
|
||||||
char buf[BUFSIZE+1];
|
char buf[BUFSIZE];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
|
std::cerr << "call recv()" << "\n" ;
|
||||||
ret = ::recv(client->fd, buf, BUFSIZE, 0);
|
ret = ::recv(client->fd, buf, BUFSIZE, 0);
|
||||||
std::cerr << "recv() on fd(" << client->fd << ") returned = " << ret << "\n" ;
|
std::cerr << "recv() on fd(" << client->fd << ") returned = " << ret << "\n" ;
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
@@ -25,20 +28,57 @@ void Webserv::_read_request(Client *client)
|
|||||||
_close_client(client->fd);
|
_close_client(client->fd);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
if (ret == 0) // Not sure what to do in case of 0. Just close ?
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
_close_client(client->fd);
|
_close_client(client->fd);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (ret == BUFSIZE)
|
|
||||||
// send error like "request too long" to client
|
|
||||||
*/
|
|
||||||
|
|
||||||
buf[ret] = '\0';
|
client->raw_request.append(buf, ret);
|
||||||
client->raw_request.append(buf);
|
if (!client->header_complete)
|
||||||
client->parse_request();
|
{
|
||||||
|
if (client->raw_request.find(CRLF CRLF) != std::string::npos)
|
||||||
|
{
|
||||||
|
client->header_complete = true;
|
||||||
|
client->parse_request(); // TODO : split function to avoid useless parsing ?
|
||||||
|
// TODO : determine server here for body size limit
|
||||||
|
if (!client->get_headers("Content-Length").empty()
|
||||||
|
&& ::atoi(client->get_headers("Content-Length").c_str()) > MAX_BODY_SIZE)
|
||||||
|
{
|
||||||
|
client->status = 413;
|
||||||
|
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (client->raw_request.size() > MAX_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
client->status = 400;
|
||||||
|
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (client->header_complete)
|
||||||
|
{
|
||||||
|
client->read_body_size += ret;
|
||||||
|
if (client->read_body_size > MAX_BODY_SIZE)
|
||||||
|
{
|
||||||
|
client->status = 413;
|
||||||
|
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((int)client->read_body_size > ::atoi(client->get_headers("Content-Length").c_str()))
|
||||||
|
{
|
||||||
|
client->parse_request(); // reparse for the body
|
||||||
|
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
|
||||||
|
if (client->header_complete && client->get_headers("Content-Type").empty() && client->get_headers("Content-Length").empty() )
|
||||||
|
{
|
||||||
|
_epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user