Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
HttpRequest.h
Go to the documentation of this file.
1
14#ifndef HTTPREQUEST_H
15#define HTTPREQUEST_H
16#pragma once
17
18#include <string>
19#include <map>
20#include <iostream>
21#include "network/Tcp.h"
22#include "utility/utility.h"
23#include "http/HttpResponse.h"
24
25class Router;
26
32{
33public:
34 // ─────────────────────────────────────────────────────────────────────────────
35 // Constructors
36 // ─────────────────────────────────────────────────────────────────────────────
37
44 HttpRequest(const char *rawHeaders, const std::string &reqMethod, const std::string &reqPath);
45
46 // used by fluent builder - client side
47 HttpRequest(const std::string &raw, const std::string &method, const std::string &path)
48 : method(method), uri(path), path(path) {}
49
50 // Server-side use — accepts Tcp* and parsed info
51 HttpRequest(Tcp *connection, const std::string rawHeaders, const std::string &method, const std::string &path)
52 : tcp(connection), method(method), uri(path), path(path)
53 {
54 parseHeaders(rawHeaders.c_str());
55 }
56
57 HttpRequest() = default;
58 HttpRequest(const HttpRequest &) = default;
59
60 // ─────────────────────────────────────────────────────────────────────────────
61 // Store a CA Root Certificate
62 // ─────────────────────────────────────────────────────────────────────────────
63
69 HttpRequest &setRootCACertificate(const std::string &certData);
70
71#if defined(PICO_HTTP_ENABLE_STORAGE)
78 bool setRootCACertificateFromFile(const char *path);
79#endif
80
81 // ─────────────────────────────────────────────────────────────────────────────
82 // Easy access methods for sending requests
83 // ─────────────────────────────────────────────────────────────────────────────
84
90
97 HttpResponse get(const std::string &url);
99 HttpResponse post(const std::string &url, const std::string &body);
101 HttpResponse put(const std::string &url, const std::string &body);
103 HttpResponse del(const std::string &url);
104
105 // ─────────────────────────────────────────────────────────────────────────────
106 // Header Accessors
107 // ─────────────────────────────────────────────────────────────────────────────
108
114 std::string getHeader(const std::string &field) const
115 {
116 auto it = headers.find(toLower(field));
117 return (it != headers.end()) ? it->second : "";
118 }
119
124 const std::map<std::string, std::string> &getHeaders() const
125 {
126 return headers;
127 }
128
132 void printHeaders() const
133 {
134 for (const auto &header : headers)
135 {
136 std::cout << header.first << ": " << header.second << std::endl;
137 }
138 }
139
144 void setHeaderEnd(size_t end)
145 {
146 headerEnd = end;
147 }
148
154 {
155 return headerEnd;
156 }
157
161 const std::string &getHost() const
162 {
163 return host;
164 }
165
166 const std::string &getProtocol() const
167 {
168 return protocol;
169 }
170
171 // ─────────────────────────────────────────────────────────────────────────────
172 // Content Type / Body Type Checkers
173 // ─────────────────────────────────────────────────────────────────────────────
174
178 bool isFormUrlEncoded() const
179 {
180 auto it = headers.find("content-type");
181 return it != headers.end() && it->second.find("application/x-www-form-urlencoded") != std::string::npos;
182 }
183
187 bool isJson() const
188 {
189 auto it = headers.find("content-type");
190 return it != headers.end() && it->second.find("application/json") != std::string::npos;
191 }
192
196 const std::string getContentType() const
197 {
198 return getHeader("content-type");
199 }
200
205 const std::string getBoundary() const
206 {
207 auto contentType = getContentType();
208 auto boundaryPos = contentType.find("boundary=");
209 if (boundaryPos != std::string::npos)
210 {
211 return contentType.substr(boundaryPos + 9);
212 }
213 return "";
214 }
215
219 bool isMultipart() const
220 {
221 auto contentType = getHeader("content-type");
222 return contentType.find("multipart/form-data") != std::string::npos;
223 }
224
225 // ─────────────────────────────────────────────────────────────────────────────
226 // Body Accessors
227 // ─────────────────────────────────────────────────────────────────────────────
228
232 const std::string &getBody() const
233 {
234 return body;
235 }
236
238 bool isBodyTruncated() const { return bodyTruncated; }
240
245 HttpRequest &setBody(const std::string &body); // Enables chaining
246
251 HttpRequest& setJson(const nlohmann::json &json);
252
257 HttpRequest& setJson(const std::string &json);
258
264 {
265 std::string content_length_str = getHeader("content-length");
266 int contentLength = 0;
267 if (!content_length_str.empty())
268 {
269 contentLength = std::stoi(content_length_str);
270 }
271 return contentLength;
272 }
273
281 inline nlohmann::json json() const
282 {
283 return nlohmann::json::parse(getBody(), nullptr, false);
284 }
285
286 // ─────────────────────────────────────────────────────────────────────────────
287 // Method / URL / Path Accessors
288 // ─────────────────────────────────────────────────────────────────────────────
289
293 HttpRequest &setMethod(const std::string &method)
294 {
295 this->method = method;
296 return *this;
297 }
298
302 HttpRequest &setPath(const std::string &path)
303 {
304 this->path = path;
305 return *this;
306 }
307
311 const std::string &getMethod() const
312 {
313 return method;
314 }
315
319 const std::string &getPath() const
320 {
321 return path;
322 }
323
327 const std::string &getUri() const
328 {
329 return uri;
330 }
331
335 const std::string &getQuery() const
336 {
337 return query;
338 }
339
340 // ─────────────────────────────────────────────────────────────────────────────
341 // Tcp accessors
342 // ─────────────────────────────────────────────────────────────────────────────
343
344 Tcp *getTcp() const
345 {
346 return tcp;
347 }
348
349 // ─────────────────────────────────────────────────────────────────────────────
350 // Cookie and Parameter Access
351 // ─────────────────────────────────────────────────────────────────────────────
352
357 const std::unordered_map<std::string, std::string> getCookies() const;
358
364 const std::string getCookie(const std::string &name) const;
365
369 const std::unordered_multimap<std::string, std::string> getQueryParams();
370
374 const std::unordered_multimap<std::string, std::string> getFormParams();
375
376 // ─────────────────────────────────────────────────────────────────────────────
377 // Socket-Based Helpers (Static)
378 // ─────────────────────────────────────────────────────────────────────────────
379
385 static HttpRequest receive(Tcp *tcp);
386
387
388
389 static std::optional<std::pair<std::string, std::string>> receiveUntilHeadersComplete(Tcp* conn);
390 bool appendRemainingBody(int expectedLength);
391
392
393
394
395
403 static bool getMethodAndPath(const std::string& data, std::string& method, std::string& path);
404
405 // ─────────────────────────────────────────────────────────────────────────────
406 // Multipart Upload Handling
407 // ─────────────────────────────────────────────────────────────────────────────
408
415 // ─────────────────────────────────────────────────────────────────────────────
416 // Fluent Builder Methods (Client Usage)
417 // ─────────────────────────────────────────────────────────────────────────────
418
419 static HttpRequest create(); // static builder factory
420 HttpRequest &setUri(const std::string &uri);
421 HttpRequest &setHost(const std::string &host);
422 HttpRequest &setProtocol(const std::string &protocol);
423 HttpRequest &setHeaders(const std::map<std::string, std::string> &headers);
424 HttpRequest &setHeader(const std::string &key, const std::string &value);
425 HttpRequest &setUserAgent(const std::string &userAgent);
426 HttpRequest &setAcceptEncoding(const std::string &encoding);
427
428 // ─────────────────────────────────────────────────────────────────────────────
429 // toFile: Save the request body to a file
430 // ─────────────────────────────────────────────────────────────────────────────
431
432 HttpRequest &toFile(const std::string &path);
433 std::string getOutputFilePath() const;
434 bool wantsToFile() const;
435
436 // ─────────────────────────────────────────────────────────────────────────────
437 // Root CA Certificate Access
438 // ─────────────────────────────────────────────────────────────────────────────
444 const std::string &getRootCACertificate() const
445 {
446 return rootCACertificate;
447 }
448
449#if defined(PICO_HTTP_ENABLE_STORAGE)
450 HttpRequest &setBodyFromFile(const std::string &path);
451#endif
452
453private:
454 void parseHeaders(const char *raw);
455 void appendToBody(const char *data, size_t len);
456
457 void setQueryString(const std::string &query)
458 {
459 this->query = query;
460 }
461
462 Tcp *tcp = nullptr;
463
464 std::string clientIp;
465 std::string method;
466 std::string uri;
467 std::string path;
468 std::string query;
469 std::string host;
470 std::string protocol;
471 std::map<std::string, std::string> headers; // optional
472 std::string body;
473 std::string rootCACertificate;
474 size_t headerEnd = 0;
475 bool bodyTruncated = false;
476 std::string outputFilePath;
477};
478
479#endif // HTTPREQUEST_H
HTTP HttpResponse class for managing status, headers, body, and streaming support.
nlohmann::json json
General-purpose TCP socket abstraction with optional TLS support for both client and server use.
Forward declaration for potential routing needs.
Definition HttpRequest.h:32
HttpResponse get()
Send a GETPOST/PUT/DEL request.
const std::string & getBody() const
Get the request body (copy).
const std::map< std::string, std::string > & getHeaders() const
Get all request headers.
bool isFormUrlEncoded() const
Check if content-type is application/x-www-form-urlencoded.
HttpRequest & setUserAgent(const std::string &userAgent)
std::string getOutputFilePath() const
void setQueryString(const std::string &query)
std::string protocol
HttpRequest & setUri(const std::string &uri)
Set the URI for the request.
HttpRequest()=default
HttpResponse put()
void appendToBody(const char *data, size_t len)
HttpRequest(const std::string &raw, const std::string &method, const std::string &path)
Definition HttpRequest.h:47
std::string uri
const std::string & getMethod() const
Get the HTTP method.
static bool getMethodAndPath(const std::string &data, std::string &method, std::string &path)
Parse the HTTP method and path from the first request line.
std::string host
std::string clientIp
std::string outputFilePath
bool bodyTruncated
HttpRequest & setRootCACertificate(const std::string &certData)
Set the root CA certificate to use for TLS.
HttpRequest & setHost(const std::string &host)
HttpRequest & setMethod(const std::string &method)
Set the HTTP method (e.g., GET, POST).
bool wantsToFile() const
HttpRequest & setPath(const std::string &path)
Set the request path.
void printHeaders() const
Print all headers to the standard output.
const std::string & getRootCACertificate() const
Get the root CA certificate string, if set.
void parseHeaders(const char *raw)
std::string body
HttpRequest & toFile(const std::string &path)
std::string query
const std::string & getHost() const
Get the Host header value.
const std::unordered_multimap< std::string, std::string > getFormParams()
Get parsed form fields (application/x-www-form-urlencoded).
const std::unordered_multimap< std::string, std::string > getQueryParams()
Get parsed query string parameters.
static HttpRequest receive(Tcp *tcp)
Receive and parse an HTTP request from a socket.
std::string method
std::string path
int handle_multipart(HttpResponse &res)
Handle multipart/form-data uploads.
HttpRequest(const HttpRequest &)=default
const std::unordered_map< std::string, std::string > getCookies() const
Get all parsed cookies.
size_t getHeaderEnd()
Get the header end offset (used for body parsing).
static std::optional< std::pair< std::string, std::string > > receiveUntilHeadersComplete(Tcp *conn)
const std::string & getPath() const
Get the parsed request path (without query string).
const std::string getContentType() const
Get the raw Content-Type string.
HttpRequest & setProtocol(const std::string &protocol)
const std::string & getQuery() const
Get the parsed query string from the URL.
std::map< std::string, std::string > headers
nlohmann::json json() const
Safely parse the request body as JSON (non-throwing).
bool isJson() const
Check if content-type is application/json.
const std::string getCookie(const std::string &name) const
Get a specific cookie value.
int getContentLength() const
Get the Content-Length header as integer.
HttpResponse send()
Send the request and return the response.
size_t headerEnd
void setHeaderEnd(size_t end)
Set the position marking the end of headers.
HttpRequest & setHeaders(const std::map< std::string, std::string > &headers)
const std::string getBoundary() const
Get the boundary string (for multipart/form-data).
bool isMultipart() const
Check whether the request is multipart/form-data.
std::string rootCACertificate
HttpRequest & setAcceptEncoding(const std::string &encoding)
std::string getHeader(const std::string &field) const
Get a specific header field (case-insensitive).
HttpResponse del()
HttpRequest & setJson(const nlohmann::json &json)
Set the body of the request as JSON.
HttpRequest(Tcp *connection, const std::string rawHeaders, const std::string &method, const std::string &path)
Definition HttpRequest.h:51
static HttpRequest create()
void markBodyTruncated()
HttpRequest & setHeader(const std::string &key, const std::string &value)
HttpResponse post()
Tcp * getTcp() const
const std::string & getUri() const
Get the original URL from the request line.
bool appendRemainingBody(int expectedLength)
bool isBodyTruncated() const
Check if the request body was truncated due to memory limits.
const std::string & getProtocol() const
HttpRequest & setBody(const std::string &body)
Set the body of the request.
Represents an HTTP response object.
The central router for handling HTTP requests and middleware.
Definition Router.h:60
General-purpose TCP socket wrapper with optional TLS support via mbedTLS (altcp).
Definition Tcp.h:39
std::string toLower(std::string str)
Definition utility.cpp:93
System utilities for diagnostics, memory, stack usage, and tracing.