| 307 | SC_TEST_EXPECT(eventLoop.create()); |
| 308 | |
| 309 | //! [HttpAsyncServerSnippet] |
| 310 | constexpr int MAX_CONNECTIONS = 3; // Max number of concurrent http connections |
| 311 | constexpr int REQUEST_SLICES = 2; // Number of slices of the request buffer for each connection |
| 312 | constexpr int REQUEST_SIZE = 1 * 1024; // How many bytes are allocated to stream data for each connection |
| 313 | constexpr int HEADER_SIZE = 8 * 1024; // How many bytes are dedicated to hold request and response headers |
| 314 | |
| 315 | // The size of the header and request memory, and length of read/write queues are fixed here, but user can |
| 316 | // set any arbitrary size for such queues doing the same being done in HttpAsyncConnection constructor. |
| 317 | using HttpConnectionType = HttpAsyncConnection<REQUEST_SLICES, REQUEST_SLICES, HEADER_SIZE, REQUEST_SIZE>; |
| 318 | |
| 319 | // 1. Memory to hold all http connections (single array for simplicity). |
| 320 | // WebServerExample (SCExample) shows how to leverage virtual memory, to handle dynamic number of clients |
| 321 | HttpConnectionType connections[MAX_CONNECTIONS]; |
| 322 | |
| 323 | // Initialize and start the http server |
| 324 | HttpAsyncServer httpServer; |
| 325 | const uint16_t serverPort = report.mapPort(6152); |
| 326 | SC_TEST_EXPECT(httpServer.init(Span<HttpConnectionType>(connections))); |
| 327 | SC_TEST_EXPECT(httpServer.start(eventLoop, "127.0.0.1", serverPort)); |
| 328 | |
| 329 | struct ServerContext |
| 330 | { |
| 331 | int numRequests; |
| 332 | } serverContext = {0}; |
| 333 | |
| 334 | // Handle the request and answer accordingly |
| 335 | httpServer.onRequest = [this, &serverContext](HttpConnection& client) |
| 336 | { |
| 337 | HttpRequest& request = client.request; |
| 338 | HttpResponse& response = client.response; |
| 339 | if (request.getParser().method != HttpParser::Method::HttpGET) |
| 340 | { |
| 341 | SC_TEST_EXPECT(response.startResponse(405)); |
| 342 | SC_TEST_EXPECT(response.addHeader("Allow", "GET")); |
| 343 | SC_TEST_EXPECT(response.sendHeaders()); |
| 344 | SC_TEST_EXPECT(response.end()); |
| 345 | return; |
| 346 | } |
| 347 | if (request.getRequestTarget() != "/index.html" and request.getRequestTarget() != "/") |
| 348 | { |
| 349 | SC_TEST_EXPECT(response.startResponse(404)); |
| 350 | SC_TEST_EXPECT(response.sendHeaders()); |
| 351 | SC_TEST_EXPECT(response.end()); |
| 352 | return; |
| 353 | } |
| 354 | serverContext.numRequests++; |
| 355 | SC_TEST_EXPECT(response.startResponse(200)); |
| 356 | SC_TEST_EXPECT(response.addHeader("Connection", "Closed")); |
| 357 | SC_TEST_EXPECT(response.addHeader("Content-Type", "text/html")); |
| 358 | SC_TEST_EXPECT(response.addHeader("Server", "SC")); |
| 359 | SC_TEST_EXPECT(response.addHeader("Date", "Mon, 27 Aug 2023 16:37:00 GMT")); |
| 360 | SC_TEST_EXPECT(response.addHeader("Last-Modified", "Wed, 27 Aug 2023 16:37:00 GMT")); |
| 361 | const char sampleHtml[] = "<html>\r\n" |
| 362 | "<body bgcolor=\"#000000\" text=\"#ffffff\">\r\n" |
| 363 | "<h1>This is a title {}!</h1>\r\n" |
| 364 | "We must start from somewhere\r\n" |
| 365 | "</body>\r\n" |
| 366 | "</html>\r\n"; |
nothing calls this directly
no test coverage detected