From 70e69796950417215d3c38fd3f7ff28a1476700d Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 21 Jul 2018 19:30:40 -0500 Subject: [PATCH] Services/HTTP: Implemented the CreateContext function handler. --- src/core/hle/service/http_c.cpp | 37 ++++++++++++++++++++++++++++++++- src/core/hle/service/http_c.h | 13 ++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index f2e77f2a7..e4eab02de 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -13,6 +13,7 @@ namespace Service { namespace HTTP { enum class RequestMethod : u8 { + None = 0x0, Get = 0x1, Post = 0x2, Head = 0x3, @@ -22,6 +23,9 @@ enum class RequestMethod : u8 { PutEmpty = 0x7, }; +/// The number of request methods, any valid method must be less than this. +constexpr u32 TotalRequestMethods = 8; + enum class RequestState : u8 { NotStarted = 0x1, // Request has not started yet. InProgress = 0x5, // Request in progress, sending request over the network. @@ -112,10 +116,41 @@ void HTTP_C::Initialize(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_HTTP, "(STUBBED) called, shared memory size: {}", shmem_size); } +void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x2, 2, 2); + const u32 url_size = rp.Pop(); + std::string url(url_size, '\0'); + RequestMethod method = rp.PopEnum(); + + Kernel::MappedBuffer& buffer = rp.PopMappedBuffer(); + buffer.Read(&url[0], 0, url_size - 1); + + LOG_DEBUG(Service_HTTP, "called, url_size={}, url={}, method={}", url_size, url, + static_cast(method)); + + // TODO(Subv): Find the right error code for this case. + ASSERT_MSG(method == RequestMethod::None && static_cast(method) < TotalRequestMethods, + "Invalid request method {}", static_cast(method)); + + Context context{}; + context.url = std::move(url); + context.method = method; + context.state = RequestState::NotStarted; + // TODO(Subv): Find a correct default value for this field. + context.socket_buffer_size = 0; + context.handle = ++context_counter; + contexts[context_counter] = std::move(context); + + IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); + rb.Push(RESULT_SUCCESS); + rb.Push(context_counter); + rb.PushMappedBuffer(buffer); +} + HTTP_C::HTTP_C() : ServiceFramework("http:C", 32) { static const FunctionInfo functions[] = { {0x00010044, &HTTP_C::Initialize, "Initialize"}, - {0x00020082, nullptr, "CreateContext"}, + {0x00020082, &HTTP_C::CreateContext, "CreateContext"}, {0x00030040, nullptr, "CloseContext"}, {0x00040040, nullptr, "CancelConnection"}, {0x00050040, nullptr, "GetRequestState"}, diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index 14d869336..bf9d1f865 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -32,6 +32,19 @@ private: */ void Initialize(Kernel::HLERequestContext& ctx); + /** + * HTTP_C::CreateContext service function + * Inputs: + * 1 : URL buffer size, including null-terminator + * 2 : RequestMethod + * 3 : (URLSize << 4) | 10 + * 4 : URL data pointer + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : HTTP context handle + */ + void CreateContext(Kernel::HLERequestContext& ctx); + Kernel::SharedPtr shared_memory = nullptr; std::unordered_map contexts;