LeftHookRoll
An HTTP/1.0 compliant web server, as specified by RFC1945
Loading...
Searching...
No Matches
Request.hpp
Go to the documentation of this file.
1/**
2 * @file Request.hpp
3 * @brief Parses and stores the entire HTTP request entity (headers, body).
4 * Utilizes a State Machine to handle non-blocking, fragmented data streams.
5 */
6#pragma once
7
8#include <string>
9#include <map>
10#include <sys/types.h>
11#include <netinet/in.h>
12#include "AllowedMethods.hpp"
13#include "DataStore.hpp"
14
15//like a time slice per parse iter, but in bytes 🤯😲
16#define PARSE_BYTE_SLICE 8192
17namespace req_utils
18{
19 std::string trim(const std::string& s);
20 std::string ipv4ToString(const struct ::sockaddr_in& addr);
21}
22/**
23 * @enum ReqState
24 * @brief Represents the current network-reading phase of the HTTP request.
25 */
27{
28 REQ_HEADERS, // Waiting for "\r\n\r\n" and parsing Request-Line & Headers
29 REQ_BODY, // Headers parsed, waiting for Content-Length bytes
30 REQ_CHUNKED, // Headers parsed, accumulating raw chunks until "\r\n\r\n"
31 REQ_DONE, // The entire request has been successfully received from the socket(often times for HTTP/0.9)
32 REQ_ERROR // A parsing error occurred
33};
34
35class Request {
36public:
37 // Canonical Form
38 Request();
39 Request(long long _maxBodySize);
40 Request(const Request& other);
41 Request& operator=(const Request& other);
42 ~Request();
43
44 // Core Parsing Behavior
45
46 /**
47 * @brief Parses the raw buffer containing the HTTP Request-Line and Headers.
48 * Transitions state to REQ_BODY, REQ_CHUNKED, or REQ_DONE upon finding "\r\n\r\n".
49 * @param rawBuffer The string buffer accumulated by the Connection.
50 * @return size_t The index at which the headers end (after "\r\n\r\n").
51 * Useful for slicing leftover body data that recv() accidentally grabbed.
52 */
53 size_t parseHeaders(const std::string& rawBuffer);
54
55 /**
56 * @brief Checks if the incoming chunked data contains the terminal "\r\n\r\n".
57 * Used to transition from REQ_CHUNKED to REQ_DONE.
58 * @param newData The latest chunk of data received from the socket.
59 * @return true if the terminal chunk is found, false otherwise.
60 */
61 bool isChunkedDone(const std::string& newData) const;
62
63 /**
64 * @brief Unified method to prepare the body for the Response/CGI phase.
65 * For Content-Length bodies, this does nothing and returns true immediately.
66 * For Chunked bodies, it decodes PARSE_BYTE_SLICE bytes per call to prevent blocking.
67 * @return true if the body is fully clean and ready, false if it needs more processing loops.
68 */
69 bool processBodySlice();
70
71 // Getters
72
73 long long getContentLength() const;
74 HTTPMethod getMethod() const;
75 const std::string& getURL() const;
76 const std::string& getProtocol() const;
77 const std::string& getQuery() const;
78 const std::map<std::string, std::string>& getHeaders() const;
79 const std::map<std::string, std::string>& getCookies() const;
80 /**
81 * @brief Gets a specific header value.
82 * @return The value, or empty string if not found.
83 */
84 std::string getHeader(const std::string& key) const;
85 /**
86 * @brief Gets a specific cookie value.
87 * @return The value, or empty string if not found.
88 */
89 std::string getCookie(const std::string& key) const;
90 /**
91 * @brief Returns a reference to the DataStore to allow direct writing from recv().
92 */
94
95 // State Management Getters
96
97 ReqState getReqState() const;
98 std::string getStatusCode() const;
99 size_t getMaxBytesToRead() const;
100 size_t getTotalBytesRead() const;
101 bool isComplete() const;
102
103private:
104 // Identity
106 std::string _URL;
107 std::string _protocol;
108 std::string _query;
109 long long _contentLength; // -1 for chunked requests.
110 // Data
113 std::map<std::string, std::string> _headers;
114 std::map<std::string, std::string> _cookies;
115
116 // State Management
118 std::string _statusCode; // e.g., 200, 400, 413
119 size_t _maxBodySize; // filled from server config.
120 size_t _totalBytesRead;// used to track against _contentLength and _maxBodySize
121
122 // Chunk Decoding State (filled per chunk)
125 bool _isBodyProcessed; //set on "\r\n\r\n"
126 std::string _chunkBuffer; // accumulates raw chunked data until we can decode a full chunk.
128
129 // Private Parsing Helpers
130 void _parseRequestLine(const std::string& line);// parses the METHOD URI PROTOCOL line.
131 void _parseHeaderLine(const std::string& line);// parses the key value
132 void _parseCookies(const std::string& cookieHeader);// parses the Cookie header into key-value pairs.
133 void _typeOfReq();// know what type of request is it, chenked or content length
135};
HTTPMethod
Represents the HTTP methods supported by the server as a bitmask.
A DataStore is a flexible data structure, it is either a RAM buffer or a file on disk,...
ReqState
Represents the current network-reading phase of the HTTP request.
Definition Request.hpp:27
@ REQ_BODY
Definition Request.hpp:29
@ REQ_ERROR
Definition Request.hpp:32
@ REQ_CHUNKED
Definition Request.hpp:30
@ REQ_DONE
Definition Request.hpp:31
@ REQ_HEADERS
Definition Request.hpp:28
size_t _chunkSize
Definition Request.hpp:123
size_t _chunkDecodeOffset
Definition Request.hpp:124
size_t _maxBodySize
Definition Request.hpp:119
long long _contentLength
Definition Request.hpp:109
void _typeOfReq()
Definition Request.cpp:227
bool isChunkedDone(const std::string &newData) const
Checks if the incoming chunked data contains the terminal "\r\n\r\n". Used to transition from REQ_CHU...
Definition Request.cpp:359
size_t _totalBytesRead
Definition Request.hpp:120
DataStore & getBodyStore()
Returns a reference to the DataStore to allow direct writing from recv().
Definition Request.cpp:390
const std::string & getQuery() const
Definition Request.cpp:94
void _parseRequestLine(const std::string &line)
Definition Request.cpp:107
bool _isBodyProcessed
Definition Request.hpp:125
void _parseHeaderLine(const std::string &line)
Definition Request.cpp:287
HTTPMethod getMethod() const
Definition Request.cpp:82
std::string getHeader(const std::string &key) const
Gets a specific header value.
Definition Request.cpp:267
ReqState getReqState() const
Definition Request.cpp:367
~Request()
Definition Request.cpp:78
std::string getStatusCode() const
Definition Request.cpp:370
size_t parseHeaders(const std::string &rawBuffer)
Parses the raw buffer containing the HTTP Request-Line and Headers. Transitions state to REQ_BODY,...
Definition Request.cpp:168
void _extractQueryFromURL()
Definition Request.cpp:157
std::string _chunkBuffer
Definition Request.hpp:126
long long getContentLength() const
Definition Request.cpp:379
void _parseCookies(const std::string &cookieHeader)
Definition Request.cpp:205
size_t getMaxBytesToRead() const
Definition Request.cpp:375
const std::string & getURL() const
Definition Request.cpp:86
std::string _URL
Definition Request.hpp:106
DataStore _body
Definition Request.hpp:111
std::map< std::string, std::string > _headers
Definition Request.hpp:113
std::string _statusCode
Definition Request.hpp:118
const std::map< std::string, std::string > & getHeaders() const
Definition Request.cpp:98
Request & operator=(const Request &other)
Definition Request.cpp:52
std::string _protocol
Definition Request.hpp:107
const std::map< std::string, std::string > & getCookies() const
Definition Request.cpp:102
size_t _ramParsePos
Definition Request.hpp:127
std::string getCookie(const std::string &key) const
Gets a specific cookie value.
Definition Request.cpp:279
size_t getTotalBytesRead() const
Definition Request.cpp:383
DataStore _decodedBody
Definition Request.hpp:112
HTTPMethod _methodName
Definition Request.hpp:105
std::string _query
Definition Request.hpp:108
bool processBodySlice()
Unified method to prepare the body for the Response/CGI phase. For Content-Length bodies,...
Definition Request.cpp:302
std::map< std::string, std::string > _cookies
Definition Request.hpp:114
ReqState _reqState
Definition Request.hpp:117
const std::string & getProtocol() const
Definition Request.cpp:90
bool isComplete() const
Definition Request.cpp:386
Request()
Definition Request.cpp:42
std::string ipv4ToString(const struct ::sockaddr_in &addr)
Definition Request.cpp:29
std::string trim(const std::string &s)
Definition Request.cpp:13