Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/networking/advanced-networking.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ server.use(custom_cors);
server.get("/test-cors", [](const glz::request& req, glz::response& res) {
res.json({
{"message", "CORS test endpoint"},
{"origin", req.headers.count("Origin") ? req.headers.at("Origin") : "none"},
{"origin", std::string{req.headers.first_value("Origin").value_or("none")}},
{"method", glz::to_string(req.method)},
{"timestamp", std::time(nullptr)}
});
Expand Down Expand Up @@ -207,12 +207,12 @@ secure_ws->on_validate([](const glz::request& req) -> bool {
return false;
}

return validate_jwt_token(auth_header->second);
return validate_jwt_token(auth_header->value);
});

secure_ws->on_open([](auto conn, const glz::request& req) {
// Store user info from validated token
auto user_data = extract_user_from_token(req.headers.at("Authorization"));
auto user_data = extract_user_from_token(*req.headers.first_value("Authorization"));
conn->set_user_data(std::make_shared<UserData>(user_data));

conn->send_text("Authenticated successfully");
Expand Down Expand Up @@ -384,7 +384,7 @@ User new_user{0, "John Doe", "john@example.com"};
auto create_response = client.post_json("https://api.example.com/users", new_user);

// POST with custom headers
std::unordered_map<std::string, std::string> headers = {
glz::http_headers headers = {
{"Authorization", "Bearer " + token},
{"Content-Type", "application/json"}
};
Expand Down Expand Up @@ -444,7 +444,7 @@ auto timing_middleware = [](const glz::request& req, glz::response& res) {
auto response_time_middleware = [](const glz::request& req, glz::response& res) {
auto start_header = res.response_headers.find("X-Request-Start");
if (start_header != res.response_headers.end()) {
auto start_ms = std::stoll(start_header->second);
auto start_ms = std::stoll(start_header->value);
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch()).count();

Expand Down
26 changes: 13 additions & 13 deletions docs/networking/http-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Notes:
```cpp
std::expected<response, std::error_code> get(
std::string_view url,
const std::unordered_map<std::string, std::string>& headers = {}
const glz::http_headers& headers = {}
);
```

Expand All @@ -93,7 +93,7 @@ std::expected<response, std::error_code> get(
std::expected<response, std::error_code> post(
std::string_view url,
std::string_view body,
const std::unordered_map<std::string, std::string>& headers = {}
const glz::http_headers& headers = {}
);
```

Expand All @@ -103,7 +103,7 @@ template<class T>
std::expected<response, std::error_code> post_json(
std::string_view url,
const T& data,
const std::unordered_map<std::string, std::string>& headers = {}
const glz::http_headers& headers = {}
);
```

Expand All @@ -120,7 +120,7 @@ All asynchronous methods come in two variants:
```cpp
std::future<std::expected<response, std::error_code>> get_async(
std::string_view url,
const std::unordered_map<std::string, std::string>& headers = {}
const glz::http_headers& headers = {}
);
```

Expand All @@ -129,7 +129,7 @@ std::future<std::expected<response, std::error_code>> get_async(
template<typename CompletionHandler>
void get_async(
std::string_view url,
const std::unordered_map<std::string, std::string>& headers,
const glz::http_headers& headers,
CompletionHandler&& handler
);
```
Expand All @@ -141,7 +141,7 @@ void get_async(
std::future<std::expected<response, std::error_code>> post_async(
std::string_view url,
std::string_view body,
const std::unordered_map<std::string, std::string>& headers = {}
const glz::http_headers& headers = {}
);
```

Expand All @@ -151,7 +151,7 @@ template<typename CompletionHandler>
void post_async(
std::string_view url,
std::string_view body,
const std::unordered_map<std::string, std::string>& headers,
const glz::http_headers& headers,
CompletionHandler&& handler
);
```
Expand All @@ -164,7 +164,7 @@ template<class T>
std::future<std::expected<response, std::error_code>> post_json_async(
std::string_view url,
const T& data,
const std::unordered_map<std::string, std::string>& headers = {}
const glz::http_headers& headers = {}
);
```

Expand All @@ -174,7 +174,7 @@ template<class T, typename CompletionHandler>
void post_json_async(
std::string_view url,
const T& data,
const std::unordered_map<std::string, std::string>& headers,
const glz::http_headers& headers,
CompletionHandler&& handler
);
```
Expand All @@ -197,7 +197,7 @@ struct stream_request_params_v2 {
stream_read_strategy strategy{stream_read_strategy::bulk_transfer};
size_t max_buffer_size{1024 * 1024};
std::string body;
std::unordered_map<std::string, std::string> headers;
glz::http_headers headers;
http_connect_handler on_connect;
http_disconnect_handler on_disconnect;
http_data_handler on_data;
Expand Down Expand Up @@ -257,7 +257,7 @@ The `response` object contains:
```cpp
struct response {
uint16_t status_code; // HTTP status code
std::unordered_map<std::string, std::string> response_headers; // Response headers
glz::http_headers response_headers; // Response headers
std::string response_body; // Response body
};
```
Expand Down Expand Up @@ -294,7 +294,7 @@ int main() {

if (response) {
std::cout << "Status: " << response->status_code << std::endl;
std::cout << "Content-Type: " << response->response_headers["Content-Type"] << std::endl;
std::cout << "Content-Type: " << response->response_headers.first_value("Content-Type").value_or("") << std::endl;
std::cout << "Body: " << response->response_body << std::endl;
} else {
std::cerr << "Error: " << response.error().message() << std::endl;
Expand All @@ -312,7 +312,7 @@ int main() {
int main() {
glz::http_client client;

std::unordered_map<std::string, std::string> headers = {
glz::http_headers headers = {
{"Content-Type", "text/plain"},
{"Authorization", "Bearer your-token"}
};
Expand Down
13 changes: 6 additions & 7 deletions docs/networking/http-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,9 +590,8 @@ int main() {
std::string username = "User" + std::to_string(std::rand() % 1000);

// In a real app, you'd extract this from authentication
auto auth_header = req.headers.find("x-username");
if (auth_header != req.headers.end()) {
username = auth_header->second;
if (auto name = req.headers.first_value("x-username")) {
username = *name;
}

std::cout << "WebSocket connection from " << conn->remote_address() << " (username: " << username << ")" << std::endl;
Expand Down Expand Up @@ -815,7 +814,7 @@ auto create_simple_auth_middleware(SimpleAuthService& auth_service) {
return;
}

std::string auth_value = auth_header->second;
std::string auth_value{auth_header->value};
if (!auth_value.starts_with("Bearer ")) {
res.status(401).json({{"error", "Bearer token required"}});
return;
Expand Down Expand Up @@ -871,8 +870,8 @@ int main() {
// Protected endpoints
server.get("/api/profile", [](const glz::request& req, glz::response& res) {
// User info is available from auth middleware
std::string username = res.response_headers["X-Username"];
std::string role = res.response_headers["X-User-Role"];
std::string username{res.response_headers.first_value("X-Username").value_or("")};
std::string role{res.response_headers.first_value("X-User-Role").value_or("")};

res.json({
{"username", username},
Expand All @@ -882,7 +881,7 @@ int main() {
});

server.get("/api/admin", [](const glz::request& req, glz::response& res) {
std::string role = res.response_headers["X-User-Role"];
std::string role{res.response_headers.first_value("X-User-Role").value_or("")};

if (role != "admin") {
res.status(403).json({{"error", "Admin access required"}});
Expand Down
7 changes: 4 additions & 3 deletions docs/networking/http-rest-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ struct request {
http_method method; // GET, POST, etc.
std::string target; // "/users/123"
std::unordered_map<std::string, std::string> params; // Route parameters
std::unordered_map<std::string, std::string> headers; // HTTP headers
glz::http_headers headers; // HTTP headers
std::string body; // Request body
std::string remote_ip; // Client IP
uint16_t remote_port; // Client port
Expand All @@ -119,12 +119,13 @@ struct request {
```cpp
struct response {
int status_code = 200;
std::unordered_map<std::string, std::string> response_headers;
glz::http_headers response_headers;
std::string response_body;

// Fluent interface
response& status(int code);
response& header(std::string_view name, std::string_view value);
response& header(std::string_view name, std::string_view value); // replaces any existing field
response& add_header(std::string_view name, std::string_view value); // appends, for Set-Cookie and friends
response& body(std::string_view content);
response& content_type(std::string_view type);

Expand Down
2 changes: 1 addition & 1 deletion docs/networking/http-router.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ router.use([](const glz::request& req, glz::response& res) {
return;
}

if (!validate_token(auth_header->second)) {
if (!validate_token(auth_header->value)) {
res.status(403).json({{"error", "Invalid token"}});
return;
}
Expand Down
6 changes: 3 additions & 3 deletions docs/networking/url.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ For `application/x-www-form-urlencoded` POST requests, use `parse_urlencoded` on
```cpp
server.post("/login", [](const glz::request& req, glz::response& res) {
// Check content type
auto ct = req.headers.find("content-type");
if (ct == req.headers.end() ||
ct->second.find("application/x-www-form-urlencoded") == std::string::npos) {
// A media type can carry parameters like "; charset=utf-8", so match on the prefix.
auto ct = req.headers.first_value("content-type");
if (!ct || !ct->starts_with("application/x-www-form-urlencoded")) {
res.status(415).json({{"error", "Unsupported content type"}});
return;
}
Expand Down
4 changes: 2 additions & 2 deletions include/glaze/net/cors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace glz
std::string origin;
auto origin_it = req.headers.find("origin");
if (origin_it != req.headers.end()) {
origin = origin_it->second;
origin = origin_it->value;
}

// Check if this is a preflight request (OPTIONS method with specific headers)
Expand Down Expand Up @@ -189,7 +189,7 @@ namespace glz
}
else if (auto requested_headers = req.headers.find("access-control-request-headers");
requested_headers != req.headers.end()) {
res.header("Access-Control-Allow-Headers", requested_headers->second);
res.header("Access-Control-Allow-Headers", requested_headers->value);
}

// Add max age
Expand Down
Loading
Loading