Format example/accept_header.cc

The file predates the clang-format hook, so any edit to it drags the
whole file into the diff. Reformat it on its own first.
This commit is contained in:
yhirose
2026-08-26 22:52:04 -04:00
parent 794a997d8c
commit efe709c45f

View File

@@ -2,133 +2,144 @@
#include <iostream> #include <iostream>
int main() { int main() {
using namespace httplib; using namespace httplib;
// Example usage of parse_accept_header function // Example usage of parse_accept_header function
std::cout << "=== Accept Header Parser Example ===" << std::endl; std::cout << "=== Accept Header Parser Example ===" << std::endl;
// Example 1: Simple Accept header // Example 1: Simple Accept header
std::string accept1 = "text/html,application/json,text/plain"; std::string accept1 = "text/html,application/json,text/plain";
std::vector<std::string> result1; std::vector<std::string> result1;
if (detail::parse_accept_header(accept1, result1)) { if (detail::parse_accept_header(accept1, result1)) {
std::cout << "\nExample 1: " << accept1 << std::endl; std::cout << "\nExample 1: " << accept1 << std::endl;
std::cout << "Parsed order:" << std::endl; std::cout << "Parsed order:" << std::endl;
for (size_t i = 0; i < result1.size(); ++i) { for (size_t i = 0; i < result1.size(); ++i) {
std::cout << " " << (i + 1) << ". " << result1[i] << std::endl; std::cout << " " << (i + 1) << ". " << result1[i] << std::endl;
} }
} else {
std::cout << "\nExample 1: Failed to parse Accept header" << std::endl;
}
// Example 2: Accept header with quality values
std::string accept2 =
"text/html;q=0.9,application/json;q=1.0,text/plain;q=0.8";
std::vector<std::string> result2;
if (detail::parse_accept_header(accept2, result2)) {
std::cout << "\nExample 2: " << accept2 << std::endl;
std::cout << "Parsed order (sorted by priority):" << std::endl;
for (size_t i = 0; i < result2.size(); ++i) {
std::cout << " " << (i + 1) << ". " << result2[i] << std::endl;
}
} else {
std::cout << "\nExample 2: Failed to parse Accept header" << std::endl;
}
// Example 3: Browser-like Accept header
std::string accept3 = "text/html,application/xhtml+xml,application/"
"xml;q=0.9,image/webp,*/*;q=0.8";
std::vector<std::string> result3;
if (detail::parse_accept_header(accept3, result3)) {
std::cout << "\nExample 3: " << accept3 << std::endl;
std::cout << "Parsed order:" << std::endl;
for (size_t i = 0; i < result3.size(); ++i) {
std::cout << " " << (i + 1) << ". " << result3[i] << std::endl;
}
} else {
std::cout << "\nExample 3: Failed to parse Accept header" << std::endl;
}
// Example 4: Invalid Accept header examples
std::cout << "\n=== Invalid Accept Header Examples ===" << std::endl;
std::vector<std::string> invalid_examples = {
"text/html;q=1.5,application/json", // q > 1.0
"text/html;q=-0.1,application/json", // q < 0.0
"text/html;q=invalid,application/json", // invalid q value
"invalidtype,application/json", // invalid media type
",application/json" // empty entry
};
for (const auto &invalid_accept : invalid_examples) {
std::vector<std::string> temp_result;
std::cout << "\nTesting invalid: " << invalid_accept << std::endl;
if (detail::parse_accept_header(invalid_accept, temp_result)) {
std::cout << " Unexpectedly succeeded!" << std::endl;
} else { } else {
std::cout << "\nExample 1: Failed to parse Accept header" << std::endl; std::cout << " Correctly rejected as invalid" << std::endl;
} }
}
// Example 2: Accept header with quality values
std::string accept2 = "text/html;q=0.9,application/json;q=1.0,text/plain;q=0.8"; // Example 4: Server usage example
std::vector<std::string> result2; std::cout << "\n=== Server Usage Example ===" << std::endl;
if (detail::parse_accept_header(accept2, result2)) { Server svr;
std::cout << "\nExample 2: " << accept2 << std::endl;
std::cout << "Parsed order (sorted by priority):" << std::endl; svr.Get("/api/data", [](const Request &req, Response &res) {
for (size_t i = 0; i < result2.size(); ++i) { // Get Accept header
std::cout << " " << (i + 1) << ". " << result2[i] << std::endl; auto accept_header = req.get_header_value("Accept");
} if (accept_header.empty()) {
} else { accept_header = "*/*"; // Default if no Accept header
std::cout << "\nExample 2: Failed to parse Accept header" << std::endl;
} }
// Example 3: Browser-like Accept header // Parse accept header to get preferred content types
std::string accept3 = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; std::vector<std::string> preferred_types;
std::vector<std::string> result3; if (!detail::parse_accept_header(accept_header, preferred_types)) {
if (detail::parse_accept_header(accept3, result3)) { // Invalid Accept header
std::cout << "\nExample 3: " << accept3 << std::endl; res.status = 400; // Bad Request
std::cout << "Parsed order:" << std::endl; res.set_content("Invalid Accept header", "text/plain");
for (size_t i = 0; i < result3.size(); ++i) { return;
std::cout << " " << (i + 1) << ". " << result3[i] << std::endl;
}
} else {
std::cout << "\nExample 3: Failed to parse Accept header" << std::endl;
} }
// Example 4: Invalid Accept header examples std::cout << "Client Accept header: " << accept_header << std::endl;
std::cout << "\n=== Invalid Accept Header Examples ===" << std::endl; std::cout << "Preferred types in order:" << std::endl;
for (size_t i = 0; i < preferred_types.size(); ++i) {
std::vector<std::string> invalid_examples = { std::cout << " " << (i + 1) << ". " << preferred_types[i] << std::endl;
"text/html;q=1.5,application/json", // q > 1.0
"text/html;q=-0.1,application/json", // q < 0.0
"text/html;q=invalid,application/json", // invalid q value
"invalidtype,application/json", // invalid media type
",application/json" // empty entry
};
for (const auto& invalid_accept : invalid_examples) {
std::vector<std::string> temp_result;
std::cout << "\nTesting invalid: " << invalid_accept << std::endl;
if (detail::parse_accept_header(invalid_accept, temp_result)) {
std::cout << " Unexpectedly succeeded!" << std::endl;
} else {
std::cout << " Correctly rejected as invalid" << std::endl;
}
} }
// Example 4: Server usage example // Choose response format based on client preference
std::cout << "\n=== Server Usage Example ===" << std::endl; std::string response_content;
Server svr; std::string content_type;
svr.Get("/api/data", [](const Request& req, Response& res) { for (const auto &type : preferred_types) {
// Get Accept header if (type == "application/json" || type == "application/*" ||
auto accept_header = req.get_header_value("Accept"); type == "*/*") {
if (accept_header.empty()) { response_content =
accept_header = "*/*"; // Default if no Accept header "{\"message\": \"Hello, World!\", \"data\": [1, 2, 3]}";
} content_type = "application/json";
break;
// Parse accept header to get preferred content types } else if (type == "text/html" || type == "text/*") {
std::vector<std::string> preferred_types; response_content = "<html><body><h1>Hello, World!</h1><p>Data: 1, 2, "
if (!detail::parse_accept_header(accept_header, preferred_types)) { "3</p></body></html>";
// Invalid Accept header content_type = "text/html";
res.status = 400; // Bad Request break;
res.set_content("Invalid Accept header", "text/plain"); } else if (type == "text/plain") {
return; response_content = "Hello, World!\nData: 1, 2, 3";
} content_type = "text/plain";
break;
std::cout << "Client Accept header: " << accept_header << std::endl; }
std::cout << "Preferred types in order:" << std::endl; }
for (size_t i = 0; i < preferred_types.size(); ++i) {
std::cout << " " << (i + 1) << ". " << preferred_types[i] << std::endl; if (response_content.empty()) {
} // No supported content type found
res.status = 406; // Not Acceptable
// Choose response format based on client preference res.set_content("No acceptable content type found", "text/plain");
std::string response_content; return;
std::string content_type; }
for (const auto& type : preferred_types) { res.set_content(response_content, content_type);
if (type == "application/json" || type == "application/*" || type == "*/*") { std::cout << "Responding with: " << content_type << std::endl;
response_content = "{\"message\": \"Hello, World!\", \"data\": [1, 2, 3]}"; });
content_type = "application/json";
break; std::cout << "Server configured. You can test it with:" << std::endl;
} else if (type == "text/html" || type == "text/*") { std::cout
response_content = "<html><body><h1>Hello, World!</h1><p>Data: 1, 2, 3</p></body></html>"; << " curl -H \"Accept: application/json\" http://localhost:8080/api/data"
content_type = "text/html"; << std::endl;
break; std::cout << " curl -H \"Accept: text/html\" http://localhost:8080/api/data"
} else if (type == "text/plain") { << std::endl;
response_content = "Hello, World!\nData: 1, 2, 3"; std::cout << " curl -H \"Accept: text/plain\" http://localhost:8080/api/data"
content_type = "text/plain"; << std::endl;
break; std::cout << " curl -H \"Accept: text/html;q=0.9,application/json;q=1.0\" "
} "http://localhost:8080/api/data"
} << std::endl;
if (response_content.empty()) { return 0;
// No supported content type found
res.status = 406; // Not Acceptable
res.set_content("No acceptable content type found", "text/plain");
return;
}
res.set_content(response_content, content_type);
std::cout << "Responding with: " << content_type << std::endl;
});
std::cout << "Server configured. You can test it with:" << std::endl;
std::cout << " curl -H \"Accept: application/json\" http://localhost:8080/api/data" << std::endl;
std::cout << " curl -H \"Accept: text/html\" http://localhost:8080/api/data" << std::endl;
std::cout << " curl -H \"Accept: text/plain\" http://localhost:8080/api/data" << std::endl;
std::cout << " curl -H \"Accept: text/html;q=0.9,application/json;q=1.0\" http://localhost:8080/api/data" << std::endl;
return 0;
} }