|
| 1 | +#include "fastmcpp/server/http_server.hpp" |
| 2 | +#include "fastmcpp/server/server.hpp" |
| 3 | +#include "fastmcpp/util/json.hpp" |
| 4 | + |
| 5 | +#include <httplib.h> |
| 6 | +#include <iostream> |
| 7 | +#include <string> |
| 8 | + |
| 9 | +using fastmcpp::Json; |
| 10 | +using fastmcpp::server::HttpServerWrapper; |
| 11 | +using fastmcpp::server::Server; |
| 12 | + |
| 13 | +int main() |
| 14 | +{ |
| 15 | + std::cout << "Running security limits tests...\n"; |
| 16 | + |
| 17 | + // Create a simple echo server |
| 18 | + auto srv = std::make_shared<Server>(); |
| 19 | + srv->route( |
| 20 | + "tools/list", |
| 21 | + [](const Json&) |
| 22 | + { |
| 23 | + return Json{{"tools", Json::array()}}; |
| 24 | + }); |
| 25 | + |
| 26 | + // Start HTTP server on unique port |
| 27 | + int port = 18199; |
| 28 | + HttpServerWrapper http_server(srv, "127.0.0.1", port); |
| 29 | + |
| 30 | + if (!http_server.start()) |
| 31 | + { |
| 32 | + std::cerr << "Failed to start HTTP server\n"; |
| 33 | + return 1; |
| 34 | + } |
| 35 | + |
| 36 | + // Wait for server to be ready |
| 37 | + std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
| 38 | + |
| 39 | + // Test 1: Normal request within limits should succeed |
| 40 | + { |
| 41 | + std::cout << "Test: normal request within payload limits...\n"; |
| 42 | + httplib::Client client("127.0.0.1", port); |
| 43 | + client.set_connection_timeout(std::chrono::seconds(5)); |
| 44 | + |
| 45 | + Json request = {{"jsonrpc", "2.0"}, {"id", 1}, {"method", "tools/list"}}; |
| 46 | + |
| 47 | + auto res = client.Post("/tools/list", request.dump(), "application/json"); |
| 48 | + |
| 49 | + if (!res || res->status != 200) |
| 50 | + { |
| 51 | + std::cerr << "Normal request failed\n"; |
| 52 | + http_server.stop(); |
| 53 | + return 1; |
| 54 | + } |
| 55 | + std::cout << " [PASS] normal request succeeded\n"; |
| 56 | + } |
| 57 | + |
| 58 | + // Test 2: Oversized payload should be rejected |
| 59 | + { |
| 60 | + std::cout << "Test: oversized payload (>10MB) is rejected...\n"; |
| 61 | + httplib::Client client("127.0.0.1", port); |
| 62 | + client.set_connection_timeout(std::chrono::seconds(5)); |
| 63 | + |
| 64 | + // Create >10MB payload (10MB + 1KB) |
| 65 | + std::string huge_payload(10 * 1024 * 1024 + 1024, 'A'); |
| 66 | + Json request = {{"jsonrpc", "2.0"}, |
| 67 | + {"id", 1}, |
| 68 | + {"method", "tools/list"}, |
| 69 | + {"params", {{"data", huge_payload}}}}; |
| 70 | + |
| 71 | + auto res = client.Post("/tools/list", request.dump(), "application/json"); |
| 72 | + |
| 73 | + // Server should reject with 413 (Payload Too Large) or connection error |
| 74 | + if (!res) |
| 75 | + { |
| 76 | + std::cout << " [PASS] oversized payload rejected (connection error)\n"; |
| 77 | + } |
| 78 | + else if (res->status == 413) |
| 79 | + { |
| 80 | + std::cout << " [PASS] oversized payload rejected with 413\n"; |
| 81 | + } |
| 82 | + else if (res->status >= 400) |
| 83 | + { |
| 84 | + std::cout << " [PASS] oversized payload rejected with status " << res->status |
| 85 | + << "\n"; |
| 86 | + } |
| 87 | + else |
| 88 | + { |
| 89 | + std::cerr << " [FAIL] oversized payload was accepted (status " << res->status |
| 90 | + << ")\n"; |
| 91 | + http_server.stop(); |
| 92 | + return 1; |
| 93 | + } |
| 94 | + } |
| 95 | + |
| 96 | + http_server.stop(); |
| 97 | + |
| 98 | + std::cout << "\n[OK] All security limits tests passed!\n"; |
| 99 | + return 0; |
| 100 | +} |
0 commit comments