Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
http2_request.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
7#include "hpack.h"
8
9#include <algorithm>
10#include <cctype>
11#include <cstdint>
12#include <optional>
13#include <string>
14#include <string_view>
15#include <vector>
16
18{
33 {
34 std::string method;
35 std::string path;
36 std::string authority;
37 std::string scheme;
38 std::vector<http_header> headers;
39 std::vector<uint8_t> body;
40
46 [[nodiscard]] auto get_header(std::string_view name) const
47 -> std::optional<std::string>
48 {
49 auto it = std::find_if(headers.begin(), headers.end(),
50 [&name](const http_header& h) {
51 if (h.name.size() != name.size()) return false;
52 for (size_t i = 0; i < h.name.size(); ++i) {
53 if (std::tolower(static_cast<unsigned char>(h.name[i])) !=
54 std::tolower(static_cast<unsigned char>(name[i]))) {
55 return false;
56 }
57 }
58 return true;
59 });
60 if (it != headers.end()) {
61 return it->value;
62 }
63 return std::nullopt;
64 }
65
70 [[nodiscard]] auto content_type() const -> std::optional<std::string>
71 {
72 return get_header("content-type");
73 }
74
79 [[nodiscard]] auto content_length() const -> std::optional<size_t>
80 {
81 auto value = get_header("content-length");
82 if (!value) {
83 return std::nullopt;
84 }
85 try {
86 return static_cast<size_t>(std::stoull(*value));
87 } catch (...) {
88 return std::nullopt;
89 }
90 }
91
96 [[nodiscard]] auto get_body_string() const -> std::string
97 {
98 return std::string(body.begin(), body.end());
99 }
100
110 [[nodiscard]] auto is_valid() const -> bool
111 {
112 if (method.empty()) {
113 return false;
114 }
115 // CONNECT requests have special rules
116 if (method == "CONNECT") {
117 return !authority.empty();
118 }
119 // Normal requests require :method, :scheme, and :path
120 return !scheme.empty() && !path.empty();
121 }
122
131 static auto from_headers(const std::vector<http_header>& parsed_headers)
133 {
134 http2_request request;
135 for (const auto& header : parsed_headers) {
136 if (header.name.empty()) {
137 continue;
138 }
139 if (header.name[0] == ':') {
140 // Pseudo-header
141 if (header.name == ":method") {
142 request.method = header.value;
143 } else if (header.name == ":path") {
144 request.path = header.value;
145 } else if (header.name == ":scheme") {
146 request.scheme = header.value;
147 } else if (header.name == ":authority") {
148 request.authority = header.value;
149 }
150 // Ignore unknown pseudo-headers
151 } else {
152 // Regular header
153 request.headers.push_back(header);
154 }
155 }
156 return request;
157 }
158 };
159
160} // namespace kcenon::network::protocols::http2
auto content_type() const -> std::optional< std::string >
Get Content-Type header value.
std::vector< uint8_t > body
Request body from DATA frames.
static auto from_headers(const std::vector< http_header > &parsed_headers) -> http2_request
Create http2_request from parsed headers.
auto get_body_string() const -> std::string
Get request body as UTF-8 string.
std::string path
Request path (:path pseudo-header)
std::string authority
Authority (:authority pseudo-header)
auto is_valid() const -> bool
Check if this is a valid HTTP/2 request.
std::vector< http_header > headers
Regular headers (non-pseudo)
auto content_length() const -> std::optional< size_t >
Get Content-Length header value as size_t.
auto get_header(std::string_view name) const -> std::optional< std::string >
Get header value by name (case-insensitive)
std::string scheme
Scheme (:scheme pseudo-header)
std::string method
HTTP method (:method pseudo-header)
HTTP header name-value pair.
Definition hpack.h:24