full QUIC support
This commit is contained in:
parent
45479a46ff
commit
28fab2509b
18 changed files with 1334 additions and 645 deletions
|
|
@ -22,63 +22,98 @@ export module Crafter.Network:HTTP;
|
|||
import std;
|
||||
|
||||
namespace Crafter {
|
||||
// HTTP/3 request as carried over a QUIC bidirectional stream. The four
|
||||
// pseudo-headers (method/scheme/authority/path) are split out as named
|
||||
// fields rather than living in the headers map, because RFC 9114 forbids
|
||||
// them from appearing in the regular header section and this shape makes
|
||||
// route dispatch and request construction cleaner. `headers` keys are
|
||||
// expected lowercase; HTTP/3 forbids uppercase characters in field names.
|
||||
export struct HTTPRequest {
|
||||
std::string method;
|
||||
std::string scheme = "https";
|
||||
std::string authority;
|
||||
std::string path = "/";
|
||||
std::unordered_map<std::string, std::string> headers;
|
||||
std::string body;
|
||||
};
|
||||
|
||||
// HTTP/3 response. `status` is the numeric three-digit code as a string
|
||||
// (e.g. "200") — HTTP/3 has no reason phrase. `headers` keys are expected
|
||||
// lowercase.
|
||||
export struct HTTPResponse {
|
||||
std::string status;
|
||||
std::string status = "200";
|
||||
std::unordered_map<std::string, std::string> headers;
|
||||
std::string body;
|
||||
};
|
||||
|
||||
export constexpr std::string CreateResponseHTTP(std::string status) {
|
||||
return std::format("HTTP/1.1 {}\r\nConnection: keep-alive\r\nContent-Length: 0\r\n\r\n", status);
|
||||
}
|
||||
|
||||
export constexpr std::string CreateResponseHTTP(std::string status, std::unordered_map<std::string, std::string> headers) {
|
||||
std::string headersString;
|
||||
for (auto const& [key, val] : headers) {
|
||||
headersString+=std::format("{}: {}\r\n", key, val);
|
||||
}
|
||||
return std::format("HTTP/1.1 {}\r\nConnection: keep-alive\r\nContent-Length: 0\r\n{}\r\n", status, headersString);
|
||||
}
|
||||
|
||||
export constexpr std::string CreateResponseHTTP(std::string status, std::string body) {
|
||||
return std::format("HTTP/1.1 {}\r\nContent-Length: {}\r\nConnection: keep-alive\r\n\r\n{}", status, body.size(), body);
|
||||
}
|
||||
|
||||
export constexpr std::string CreateResponseHTTP(std::string status, std::unordered_map<std::string, std::string> headers, std::string body) {
|
||||
std::string headersString;
|
||||
for (auto const& [key, val] : headers) {
|
||||
headersString+=std::format("{}: {}\r\n", key, val);
|
||||
}
|
||||
return std::format("HTTP/1.1 {}\r\nConnection: keep-alive\r\nContent-Length: {}\r\n{}\r\n{}", status, body.size(), headersString, body);
|
||||
export inline HTTPRequest CreateRequestHTTP(std::string method, std::string path, std::string authority) {
|
||||
HTTPRequest r;
|
||||
r.method = std::move(method);
|
||||
r.path = std::move(path);
|
||||
r.authority = std::move(authority);
|
||||
return r;
|
||||
}
|
||||
|
||||
export constexpr std::string CreateRequestHTTP(std::string method, std::string route, std::string host) {
|
||||
return std::format("{} {} HTTP/1.1\r\nConnection: keep-alive\r\nAccept-Encoding: identity\r\nContent-Length: 0\r\nHost: {}\r\n\r\n", method, route, host);
|
||||
}
|
||||
export inline HTTPRequest CreateRequestHTTP(std::string method, std::string path, std::string authority,
|
||||
std::unordered_map<std::string, std::string> headers) {
|
||||
HTTPRequest r;
|
||||
r.method = std::move(method);
|
||||
r.path = std::move(path);
|
||||
r.authority = std::move(authority);
|
||||
r.headers = std::move(headers);
|
||||
return r;
|
||||
}
|
||||
|
||||
export constexpr std::string CreateRequestHTTP(std::string method, std::string route, std::string host, std::unordered_map<std::string, std::string> headers) {
|
||||
std::string headersString;
|
||||
for (auto const& [key, val] : headers) {
|
||||
headersString+=std::format("{}: {}\r\n", key, val);
|
||||
}
|
||||
return std::format("{} {} HTTP/1.1\r\nConnection: keep-alive\r\nContent-Length: 0\r\nAccept-Encoding: identity\r\nHost: {}\r\n{}\r\n", method, route, host, headersString);
|
||||
}
|
||||
export inline HTTPRequest CreateRequestHTTP(std::string method, std::string path, std::string authority,
|
||||
std::string body) {
|
||||
HTTPRequest r;
|
||||
r.method = std::move(method);
|
||||
r.path = std::move(path);
|
||||
r.authority = std::move(authority);
|
||||
r.body = std::move(body);
|
||||
return r;
|
||||
}
|
||||
|
||||
export constexpr std::string CreateRequestHTTP(std::string method, std::string route, std::string host, std::string body) {
|
||||
return std::format("{} {} HTTP/1.1\r\nContent-Length: {}\r\nConnection: keep-alive\r\nAccept-Encoding: identity\r\nHost: {}\r\n\r\n{}", method, route, body.size(), host, body);
|
||||
}
|
||||
export inline HTTPRequest CreateRequestHTTP(std::string method, std::string path, std::string authority,
|
||||
std::unordered_map<std::string, std::string> headers,
|
||||
std::string body) {
|
||||
HTTPRequest r;
|
||||
r.method = std::move(method);
|
||||
r.path = std::move(path);
|
||||
r.authority = std::move(authority);
|
||||
r.headers = std::move(headers);
|
||||
r.body = std::move(body);
|
||||
return r;
|
||||
}
|
||||
|
||||
export constexpr std::string CreateRequestHTTP(std::string method, std::string route, std::string host, std::unordered_map<std::string, std::string> headers, std::string body) {
|
||||
std::string headersString;
|
||||
for (auto const& [key, val] : headers) {
|
||||
headersString+=std::format("{}: {}\r\n", key, val);
|
||||
}
|
||||
return std::format("{} {} HTTP/1.1\r\nConnection: keep-alive\r\nContent-Length: {}\r\nHost: {}\r\nAccept-Encoding: identity\r\n{}\r\n{}", method, route, body.size(), host, headersString, body);
|
||||
}
|
||||
}
|
||||
export inline HTTPResponse CreateResponseHTTP(std::string status) {
|
||||
HTTPResponse r;
|
||||
r.status = std::move(status);
|
||||
return r;
|
||||
}
|
||||
|
||||
export inline HTTPResponse CreateResponseHTTP(std::string status,
|
||||
std::unordered_map<std::string, std::string> headers) {
|
||||
HTTPResponse r;
|
||||
r.status = std::move(status);
|
||||
r.headers = std::move(headers);
|
||||
return r;
|
||||
}
|
||||
|
||||
export inline HTTPResponse CreateResponseHTTP(std::string status, std::string body) {
|
||||
HTTPResponse r;
|
||||
r.status = std::move(status);
|
||||
r.body = std::move(body);
|
||||
return r;
|
||||
}
|
||||
|
||||
export inline HTTPResponse CreateResponseHTTP(std::string status,
|
||||
std::unordered_map<std::string, std::string> headers,
|
||||
std::string body) {
|
||||
HTTPResponse r;
|
||||
r.status = std::move(status);
|
||||
r.headers = std::move(headers);
|
||||
r.body = std::move(body);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue