| 23 | namespace SC |
| 24 | { |
| 25 | struct ApiServerExample |
| 26 | { |
| 27 | static constexpr size_t MaxConnections = 32; |
| 28 | |
| 29 | using Connection = HttpAsyncConnection<16, 16, 16 * 1024, 512 * 1024>; |
| 30 | |
| 31 | Connection connections[MaxConnections]; |
| 32 | HttpAsyncServer server; |
| 33 | HttpRouter router; |
| 34 | HttpRoute routes[3] = { |
| 35 | {HttpParser::Method::HttpGET, "/health"}, |
| 36 | {HttpParser::Method::HttpGET, "/hello"}, |
| 37 | {HttpParser::Method::HttpPOST, "/echo"}, |
| 38 | }; |
| 39 | |
| 40 | String interface = "127.0.0.1"; |
| 41 | int32_t port = 8091; |
| 42 | |
| 43 | Result start(AsyncEventLoop& loop) |
| 44 | { |
| 45 | SC_TRY(server.init(Span<Connection>(connections))); |
| 46 | SC_TRY(router.init(routes)); |
| 47 | SC_TRY(server.start(loop, interface.view(), static_cast<uint16_t>(port))); |
| 48 | server.onRequest.bind<ApiServerExample, &ApiServerExample::onRequest>(*this); |
| 49 | return Result(true); |
| 50 | } |
| 51 | |
| 52 | void onRequest(HttpConnection& connection) |
| 53 | { |
| 54 | HttpRouteMatch match; |
| 55 | SC_ASSERT_RELEASE( |
| 56 | router.match(connection.request.getParser().method, connection.request.getRequestTarget(), {}, match)); |
| 57 | if (match.status == HttpRouteMatchStatus::NotFound) |
| 58 | { |
| 59 | SC_ASSERT_RELEASE(notFound(connection)); |
| 60 | return; |
| 61 | } |
| 62 | if (match.status == HttpRouteMatchStatus::MethodNotAllowed) |
| 63 | { |
| 64 | char allowStorage[64]; |
| 65 | StringSpan allow; |
| 66 | SC_ASSERT_RELEASE(router.formatAllowHeader(connection.request.getRequestTarget(), allowStorage, allow)); |
| 67 | SC_ASSERT_RELEASE(connection.response.sendMethodNotAllowed(allow)); |
| 68 | return; |
| 69 | } |
| 70 | if (match.status != HttpRouteMatchStatus::Matched) |
| 71 | { |
| 72 | SC_ASSERT_RELEASE(connection.sendTextCopy(500, "route error\n")); |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | if (match.route == &routes[0]) |
| 77 | { |
| 78 | SC_ASSERT_RELEASE(connection.sendJsonCopy(200, "{\"status\":\"ok\"}")); |
| 79 | return; |
| 80 | } |
| 81 | if (match.route == &routes[1]) |
| 82 | { |
nothing calls this directly
no outgoing calls
no test coverage detected