// Copyright Epic Games, Inc. All Rights Reserved. #include "httptest.h" #include #include #include namespace zen { using namespace std::literals; HttpTestingService::HttpTestingService() { m_Router.RegisterRoute( "hello", [](HttpRouterRequest& Req) { Req.ServerRequest().WriteResponse(HttpResponseCode::OK); }, HttpVerb::kGet); m_Router.RegisterRoute( "hello_slow", [](HttpRouterRequest& Req) { Req.ServerRequest().WriteResponseAsync([](HttpServerRequest& Request) { Stopwatch Timer; Sleep(1000); Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, fmt::format("hello, took me {}", NiceTimeSpanMs(Timer.GetElapsedTimeMs()))); }); }, HttpVerb::kGet); m_Router.RegisterRoute( "hello_veryslow", [](HttpRouterRequest& Req) { Req.ServerRequest().WriteResponseAsync([](HttpServerRequest& Request) { Stopwatch Timer; Sleep(60000); Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, fmt::format("hello, took me {}", NiceTimeSpanMs(Timer.GetElapsedTimeMs()))); }); }, HttpVerb::kGet); m_Router.RegisterRoute( "hello_throw", [](HttpRouterRequest& Req) { Req.ServerRequest().WriteResponseAsync([](HttpServerRequest&) { throw std::runtime_error("intentional error"); }); }, HttpVerb::kGet); m_Router.RegisterRoute( "hello_noresponse", [](HttpRouterRequest& Req) { Req.ServerRequest().WriteResponseAsync([](HttpServerRequest&) {}); }, HttpVerb::kGet); m_Router.RegisterRoute( "metrics", [this](HttpRouterRequest& Req) { metrics::OperationTiming::Scope _(m_TimingStats); Req.ServerRequest().WriteResponse(HttpResponseCode::OK); }, HttpVerb::kGet); m_Router.RegisterRoute( "get_metrics", [this](HttpRouterRequest& Req) { CbObjectWriter Cbo; EmitSnapshot("requests", m_TimingStats, Cbo); Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Cbo.Save()); }, HttpVerb::kGet); m_Router.RegisterRoute( "json", [this](HttpRouterRequest& Req) { CbObjectWriter Obj; Obj.AddBool("ok", true); Obj.AddInteger("counter", ++m_Counter); Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save()); }, HttpVerb::kGet); m_Router.RegisterRoute( "echo", [](HttpRouterRequest& Req) { IoBuffer Body = Req.ServerRequest().ReadPayload(); Req.ServerRequest().WriteResponse(HttpResponseCode::OK, HttpContentType::kBinary, Body); }, HttpVerb::kPost); m_Router.RegisterRoute( "package", [](HttpRouterRequest& Req) { CbPackage Pkg = Req.ServerRequest().ReadPayloadPackage(); Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Pkg); }, HttpVerb::kPost); } HttpTestingService::~HttpTestingService() { } const char* HttpTestingService::BaseUri() const { return "/testing/"; } void HttpTestingService::HandleRequest(HttpServerRequest& Request) { m_Router.HandleRequest(Request); } Ref HttpTestingService::HandlePackageRequest(HttpServerRequest& HttpServiceRequest) { RwLock::ExclusiveLockScope _(m_RwLock); const uint32_t RequestId = HttpServiceRequest.RequestId(); if (auto It = m_HandlerMap.find(RequestId); It != m_HandlerMap.end()) { Ref Handler = std::move(It->second); m_HandlerMap.erase(It); return Handler.Get(); } auto InsertResult = m_HandlerMap.insert({RequestId, nullptr}); _.ReleaseNow(); return (InsertResult.first->second = new PackageHandler(*this, RequestId)).Get(); } void HttpTestingService::RegisterHandlers(WebSocketServer& Server) { Server.RegisterRequestHandler("SayHello"sv, *this); } bool HttpTestingService::HandleRequest(const WebSocketMessage& RequestMsg) { CbObjectView Request = RequestMsg.Body().GetObject(); std::string_view Method = Request["Method"].AsString(); if (Method != "SayHello"sv) { return false; } CbObjectWriter Response; Response.AddString("Result"sv, "Hello Friend!!"); WebSocketMessage ResponseMsg; ResponseMsg.SetMessageType(WebSocketMessageType::kResponse); ResponseMsg.SetCorrelationId(RequestMsg.CorrelationId()); ResponseMsg.SetSocketId(RequestMsg.SocketId()); ResponseMsg.SetBody(Response.Save()); SocketServer().SendResponse(std::move(ResponseMsg)); return true; } ////////////////////////////////////////////////////////////////////////// HttpTestingService::PackageHandler::PackageHandler(HttpTestingService& Svc, uint32_t RequestId) : m_Svc(Svc), m_RequestId(RequestId) { } HttpTestingService::PackageHandler::~PackageHandler() { } void HttpTestingService::PackageHandler::FilterOffer(std::vector& OfferCids) { ZEN_UNUSED(OfferCids); // No-op return; } void HttpTestingService::PackageHandler::OnRequestBegin() { } void HttpTestingService::PackageHandler::OnRequestComplete() { } IoBuffer HttpTestingService::PackageHandler::CreateTarget(const IoHash& Cid, uint64_t StorageSize) { ZEN_UNUSED(Cid); return IoBuffer{StorageSize}; } } // namespace zen