1
0

accept_header.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include "httplib.h"
  2. #include <iostream>
  3. int main() {
  4. using namespace httplib;
  5. // Example usage of parse_accept_header function
  6. std::cout << "=== Accept Header Parser Example ===" << std::endl;
  7. // Example 1: Simple Accept header
  8. std::string accept1 = "text/html,application/json,text/plain";
  9. std::vector<std::string> result1;
  10. if (detail::parse_accept_header(accept1, result1)) {
  11. std::cout << "\nExample 1: " << accept1 << std::endl;
  12. std::cout << "Parsed order:" << std::endl;
  13. for (size_t i = 0; i < result1.size(); ++i) {
  14. std::cout << " " << (i + 1) << ". " << result1[i] << std::endl;
  15. }
  16. } else {
  17. std::cout << "\nExample 1: Failed to parse Accept header" << std::endl;
  18. }
  19. // Example 2: Accept header with quality values
  20. std::string accept2 =
  21. "text/html;q=0.9,application/json;q=1.0,text/plain;q=0.8";
  22. std::vector<std::string> result2;
  23. if (detail::parse_accept_header(accept2, result2)) {
  24. std::cout << "\nExample 2: " << accept2 << std::endl;
  25. std::cout << "Parsed order (sorted by priority):" << std::endl;
  26. for (size_t i = 0; i < result2.size(); ++i) {
  27. std::cout << " " << (i + 1) << ". " << result2[i] << std::endl;
  28. }
  29. } else {
  30. std::cout << "\nExample 2: Failed to parse Accept header" << std::endl;
  31. }
  32. // Example 3: Browser-like Accept header
  33. std::string accept3 = "text/html,application/xhtml+xml,application/"
  34. "xml;q=0.9,image/webp,*/*;q=0.8";
  35. std::vector<std::string> result3;
  36. if (detail::parse_accept_header(accept3, result3)) {
  37. std::cout << "\nExample 3: " << accept3 << std::endl;
  38. std::cout << "Parsed order:" << std::endl;
  39. for (size_t i = 0; i < result3.size(); ++i) {
  40. std::cout << " " << (i + 1) << ". " << result3[i] << std::endl;
  41. }
  42. } else {
  43. std::cout << "\nExample 3: Failed to parse Accept header" << std::endl;
  44. }
  45. // Example 4: Invalid Accept header examples
  46. std::cout << "\n=== Invalid Accept Header Examples ===" << std::endl;
  47. std::vector<std::string> invalid_examples = {
  48. "text/html;q=1.5,application/json", // q > 1.0
  49. "text/html;q=-0.1,application/json", // q < 0.0
  50. "text/html;q=invalid,application/json", // invalid q value
  51. "invalidtype,application/json", // invalid media type
  52. ",application/json" // empty entry
  53. };
  54. for (const auto &invalid_accept : invalid_examples) {
  55. std::vector<std::string> temp_result;
  56. std::cout << "\nTesting invalid: " << invalid_accept << std::endl;
  57. if (detail::parse_accept_header(invalid_accept, temp_result)) {
  58. std::cout << " Unexpectedly succeeded!" << std::endl;
  59. } else {
  60. std::cout << " Correctly rejected as invalid" << std::endl;
  61. }
  62. }
  63. // Example 4: Server usage example
  64. std::cout << "\n=== Server Usage Example ===" << std::endl;
  65. Server svr;
  66. svr.Get("/api/data", [](const Request &req, Response &res) {
  67. // Get Accept header
  68. auto accept_header = req.get_header_value("Accept");
  69. if (accept_header.empty()) {
  70. accept_header = "*/*"; // Default if no Accept header
  71. }
  72. // Parse accept header to get preferred content types
  73. std::vector<std::string> preferred_types;
  74. if (!detail::parse_accept_header(accept_header, preferred_types)) {
  75. // Invalid Accept header
  76. res.status = 400; // Bad Request
  77. res.set_content("Invalid Accept header", "text/plain");
  78. return;
  79. }
  80. std::cout << "Client Accept header: " << accept_header << std::endl;
  81. std::cout << "Preferred types in order:" << std::endl;
  82. for (size_t i = 0; i < preferred_types.size(); ++i) {
  83. std::cout << " " << (i + 1) << ". " << preferred_types[i] << std::endl;
  84. }
  85. // Choose response format based on client preference
  86. std::string response_content;
  87. std::string content_type;
  88. for (const auto &type : preferred_types) {
  89. if (type == "application/json" || type == "application/*" ||
  90. type == "*/*") {
  91. response_content =
  92. "{\"message\": \"Hello, World!\", \"data\": [1, 2, 3]}";
  93. content_type = "application/json";
  94. break;
  95. } else if (type == "text/html" || type == "text/*") {
  96. response_content = "<html><body><h1>Hello, World!</h1><p>Data: 1, 2, "
  97. "3</p></body></html>";
  98. content_type = "text/html";
  99. break;
  100. } else if (type == "text/plain") {
  101. response_content = "Hello, World!\nData: 1, 2, 3";
  102. content_type = "text/plain";
  103. break;
  104. }
  105. }
  106. if (response_content.empty()) {
  107. // No supported content type found
  108. res.status = 406; // Not Acceptable
  109. res.set_content("No acceptable content type found", "text/plain");
  110. return;
  111. }
  112. res.set_content(response_content, content_type);
  113. std::cout << "Responding with: " << content_type << std::endl;
  114. });
  115. std::cout << "Server configured. You can test it with:" << std::endl;
  116. std::cout
  117. << " curl -H \"Accept: application/json\" http://localhost:8080/api/data"
  118. << std::endl;
  119. std::cout << " curl -H \"Accept: text/html\" http://localhost:8080/api/data"
  120. << std::endl;
  121. std::cout << " curl -H \"Accept: text/plain\" http://localhost:8080/api/data"
  122. << std::endl;
  123. std::cout << " curl -H \"Accept: text/html;q=0.9,application/json;q=1.0\" "
  124. "http://localhost:8080/api/data"
  125. << std::endl;
  126. return 0;
  127. }