File: accept_header.cc

package info (click to toggle)
cpp-httplib 0.25.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,708 kB
  • sloc: cpp: 19,322; makefile: 176; python: 50; sh: 50
file content (134 lines) | stat: -rw-r--r-- 5,815 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "httplib.h"
#include <iostream>

int main() {
    using namespace httplib;
    
    // Example usage of parse_accept_header function
    std::cout << "=== Accept Header Parser Example ===" << std::endl;
    
    // Example 1: Simple Accept header
    std::string accept1 = "text/html,application/json,text/plain";
    std::vector<std::string> result1;
    if (detail::parse_accept_header(accept1, result1)) {
        std::cout << "\nExample 1: " << accept1 << std::endl;
        std::cout << "Parsed order:" << std::endl;
        for (size_t i = 0; i < result1.size(); ++i) {
            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 {
            std::cout << "  Correctly rejected as invalid" << std::endl;
        }
    }
    
    // Example 4: Server usage example
    std::cout << "\n=== Server Usage Example ===" << std::endl;
    Server svr;
    
    svr.Get("/api/data", [](const Request& req, Response& res) {
        // Get Accept header
        auto accept_header = req.get_header_value("Accept");
        if (accept_header.empty()) {
            accept_header = "*/*";  // Default if no Accept header
        }
        
        // Parse accept header to get preferred content types
        std::vector<std::string> preferred_types;
        if (!detail::parse_accept_header(accept_header, preferred_types)) {
            // Invalid Accept header
            res.status = 400;  // Bad Request
            res.set_content("Invalid Accept header", "text/plain");
            return;
        }
        
        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;
        }
        
        // Choose response format based on client preference
        std::string response_content;
        std::string content_type;
        
        for (const auto& type : preferred_types) {
            if (type == "application/json" || type == "application/*" || type == "*/*") {
                response_content = "{\"message\": \"Hello, World!\", \"data\": [1, 2, 3]}";
                content_type = "application/json";
                break;
            } else if (type == "text/html" || type == "text/*") {
                response_content = "<html><body><h1>Hello, World!</h1><p>Data: 1, 2, 3</p></body></html>";
                content_type = "text/html";
                break;
            } else if (type == "text/plain") {
                response_content = "Hello, World!\nData: 1, 2, 3";
                content_type = "text/plain";
                break;
            }
        }
        
        if (response_content.empty()) {
            // 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;
}