mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #4001 from Subv/http2
Services/HTTP: Corrected some error codes and added a few new ones.
This commit is contained in:
		
						commit
						8ae126eb33
					
				
					 2 changed files with 206 additions and 26 deletions
				
			
		|  | @ -11,30 +11,82 @@ namespace HTTP { | ||||||
| 
 | 
 | ||||||
| namespace ErrCodes { | namespace ErrCodes { | ||||||
| enum { | enum { | ||||||
|  |     InvalidRequestState = 22, | ||||||
|  |     TooManyContexts = 26, | ||||||
|     InvalidRequestMethod = 32, |     InvalidRequestMethod = 32, | ||||||
|     InvalidContext = 102, |     ContextNotFound = 100, | ||||||
|  | 
 | ||||||
|  |     /// This error is returned in multiple situations: when trying to initialize an
 | ||||||
|  |     /// already-initialized session, or when using the wrong context handle in a context-bound
 | ||||||
|  |     /// session
 | ||||||
|  |     SessionStateError = 102, | ||||||
| }; | }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const ResultCode ERROR_CONTEXT_ERROR = // 0xD8A0A066
 | const ResultCode ERROR_STATE_ERROR = // 0xD8A0A066
 | ||||||
|     ResultCode(ErrCodes::InvalidContext, ErrorModule::HTTP, ErrorSummary::InvalidState, |     ResultCode(ErrCodes::SessionStateError, ErrorModule::HTTP, ErrorSummary::InvalidState, | ||||||
|                ErrorLevel::Permanent); |                ErrorLevel::Permanent); | ||||||
| 
 | 
 | ||||||
| void HTTP_C::Initialize(Kernel::HLERequestContext& ctx) { | void HTTP_C::Initialize(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx, 0x1, 1, 4); |     IPC::RequestParser rp(ctx, 0x1, 1, 4); | ||||||
|     const u32 shmem_size = rp.Pop<u32>(); |     const u32 shmem_size = rp.Pop<u32>(); | ||||||
|     rp.PopPID(); |     u32 pid = rp.PopPID(); | ||||||
|     shared_memory = rp.PopObject<Kernel::SharedMemory>(); |     shared_memory = rp.PopObject<Kernel::SharedMemory>(); | ||||||
|     if (shared_memory) { |     if (shared_memory) { | ||||||
|         shared_memory->name = "HTTP_C:shared_memory"; |         shared_memory->name = "HTTP_C:shared_memory"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     LOG_WARNING(Service_HTTP, "(STUBBED) called, shared memory size: {} pid: {}", shmem_size, pid); | ||||||
|  | 
 | ||||||
|  |     auto* session_data = GetSessionData(ctx.Session()); | ||||||
|  |     ASSERT(session_data); | ||||||
|  | 
 | ||||||
|  |     if (session_data->initialized) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Tried to initialize an already initialized session"); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     session_data->initialized = true; | ||||||
|  | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|     // This returns 0xd8a0a046 if no network connection is available.
 |     // This returns 0xd8a0a046 if no network connection is available.
 | ||||||
|     // Just assume we are always connected.
 |     // Just assume we are always connected.
 | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_HTTP, "(STUBBED) called, shared memory size: {}", shmem_size); | void HTTP_C::InitializeConnectionSession(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx, 0x8, 1, 2); | ||||||
|  |     const Context::Handle context_handle = rp.Pop<u32>(); | ||||||
|  |     u32 pid = rp.PopPID(); | ||||||
|  | 
 | ||||||
|  |     auto* session_data = GetSessionData(ctx.Session()); | ||||||
|  |     ASSERT(session_data); | ||||||
|  | 
 | ||||||
|  |     if (session_data->initialized) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Tried to initialize an already initialized session"); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // TODO(Subv): Check that the input PID matches the PID that created the context.
 | ||||||
|  |     auto itr = contexts.find(context_handle); | ||||||
|  |     if (itr == contexts.end()) { | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         rb.Push(ResultCode(ErrCodes::ContextNotFound, ErrorModule::HTTP, ErrorSummary::InvalidState, | ||||||
|  |                            ErrorLevel::Permanent)); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     session_data->initialized = true; | ||||||
|  |     // Bind the context to the current session.
 | ||||||
|  |     session_data->current_http_context = context_handle; | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     LOG_DEBUG(Service_HTTP, "called, context_id={} pid={}", context_handle, pid); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { | void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { | ||||||
|  | @ -50,11 +102,46 @@ void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_DEBUG(Service_HTTP, "called, url_size={}, url={}, method={}", url_size, url, |     LOG_DEBUG(Service_HTTP, "called, url_size={}, url={}, method={}", url_size, url, | ||||||
|               static_cast<u32>(method)); |               static_cast<u32>(method)); | ||||||
| 
 | 
 | ||||||
|  |     auto* session_data = GetSessionData(ctx.Session()); | ||||||
|  |     ASSERT(session_data); | ||||||
|  | 
 | ||||||
|  |     if (!session_data->initialized) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Tried to create a context on an uninitialized session"); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         rb.PushMappedBuffer(buffer); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // This command can only be called without a bound session.
 | ||||||
|  |     if (session_data->current_http_context != boost::none) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Command called with a bound context"); | ||||||
|  | 
 | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, | ||||||
|  |                            ErrorSummary::Internal, ErrorLevel::Permanent)); | ||||||
|  |         rb.PushMappedBuffer(buffer); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static constexpr size_t MaxConcurrentHTTPContexts = 8; | ||||||
|  |     if (session_data->num_http_contexts >= MaxConcurrentHTTPContexts) { | ||||||
|  |         // There can only be 8 HTTP contexts open at the same time for any particular session.
 | ||||||
|  |         LOG_ERROR(Service_HTTP, "Tried to open too many HTTP contexts"); | ||||||
|  | 
 | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |         rb.Push(ResultCode(ErrCodes::TooManyContexts, ErrorModule::HTTP, ErrorSummary::InvalidState, | ||||||
|  |                            ErrorLevel::Permanent)); | ||||||
|  |         rb.PushMappedBuffer(buffer); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (method == RequestMethod::None || static_cast<u32>(method) >= TotalRequestMethods) { |     if (method == RequestMethod::None || static_cast<u32>(method) >= TotalRequestMethods) { | ||||||
|         LOG_ERROR(Service_HTTP, "invalid request method={}", static_cast<u32>(method)); |         LOG_ERROR(Service_HTTP, "invalid request method={}", static_cast<u32>(method)); | ||||||
| 
 | 
 | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|         rb.Push(ERROR_CONTEXT_ERROR); |         rb.Push(ResultCode(ErrCodes::InvalidRequestMethod, ErrorModule::HTTP, | ||||||
|  |                            ErrorSummary::InvalidState, ErrorLevel::Permanent)); | ||||||
|         rb.PushMappedBuffer(buffer); |         rb.PushMappedBuffer(buffer); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -67,6 +154,8 @@ void HTTP_C::CreateContext(Kernel::HLERequestContext& ctx) { | ||||||
|     contexts[context_counter].socket_buffer_size = 0; |     contexts[context_counter].socket_buffer_size = 0; | ||||||
|     contexts[context_counter].handle = context_counter; |     contexts[context_counter].handle = context_counter; | ||||||
| 
 | 
 | ||||||
|  |     session_data->num_http_contexts++; | ||||||
|  | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.Push<u32>(context_counter); |     rb.Push<u32>(context_counter); | ||||||
|  | @ -80,10 +169,24 @@ void HTTP_C::CloseContext(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_HTTP, "(STUBBED) called, handle={}", context_handle); |     LOG_WARNING(Service_HTTP, "(STUBBED) called, handle={}", context_handle); | ||||||
| 
 | 
 | ||||||
|  |     auto* session_data = GetSessionData(ctx.Session()); | ||||||
|  |     ASSERT(session_data); | ||||||
|  | 
 | ||||||
|  |     if (!session_data->initialized) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Tried to close a context on an uninitialized session"); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ASSERT_MSG(session_data->current_http_context == boost::none, | ||||||
|  |                "Unimplemented CloseContext on context-bound session"); | ||||||
|  | 
 | ||||||
|     auto itr = contexts.find(context_handle); |     auto itr = contexts.find(context_handle); | ||||||
|     if (itr == contexts.end()) { |     if (itr == contexts.end()) { | ||||||
|  |         // The real HTTP module just silently fails in this case.
 | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|         rb.Push(ERROR_CONTEXT_ERROR); |         rb.Push(RESULT_SUCCESS); | ||||||
|         LOG_ERROR(Service_HTTP, "called, context {} not found", context_handle); |         LOG_ERROR(Service_HTTP, "called, context {} not found", context_handle); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -91,7 +194,10 @@ void HTTP_C::CloseContext(Kernel::HLERequestContext& ctx) { | ||||||
|     // TODO(Subv): What happens if you try to close a context that's currently being used?
 |     // TODO(Subv): What happens if you try to close a context that's currently being used?
 | ||||||
|     ASSERT(itr->second.state == RequestState::NotStarted); |     ASSERT(itr->second.state == RequestState::NotStarted); | ||||||
| 
 | 
 | ||||||
|  |     // TODO(Subv): Make sure that only the session that created the context can close it.
 | ||||||
|  | 
 | ||||||
|     contexts.erase(itr); |     contexts.erase(itr); | ||||||
|  |     session_data->num_http_contexts--; | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|  | @ -108,19 +214,56 @@ void HTTP_C::AddRequestHeader(Kernel::HLERequestContext& ctx) { | ||||||
|     // Copy the name_buffer into a string without the \0 at the end
 |     // Copy the name_buffer into a string without the \0 at the end
 | ||||||
|     const std::string name(name_buffer.begin(), name_buffer.end() - 1); |     const std::string name(name_buffer.begin(), name_buffer.end() - 1); | ||||||
| 
 | 
 | ||||||
|     // Copy thr value_buffer into a string without the \0 at the end
 |     // Copy the value_buffer into a string without the \0 at the end
 | ||||||
|     std::string value(value_size - 1, '\0'); |     std::string value(value_size - 1, '\0'); | ||||||
|     value_buffer.Read(&value[0], 0, value_size - 1); |     value_buffer.Read(&value[0], 0, value_size - 1); | ||||||
| 
 | 
 | ||||||
|     auto itr = contexts.find(context_handle); |     auto* session_data = GetSessionData(ctx.Session()); | ||||||
|     if (itr == contexts.end()) { |     ASSERT(session_data); | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | 
 | ||||||
|         rb.Push(ERROR_CONTEXT_ERROR); |     if (!session_data->initialized) { | ||||||
|         LOG_ERROR(Service_HTTP, "called, context {} not found", context_handle); |         LOG_ERROR(Service_HTTP, "Tried to add a request header on an uninitialized session"); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         rb.PushMappedBuffer(value_buffer); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // This command can only be called with a bound context
 | ||||||
|  |     if (session_data->current_http_context == boost::none) { | ||||||
|  |         LOG_ERROR(Service_HTTP, "Command called without a bound context"); | ||||||
|  | 
 | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |         rb.Push(ResultCode(ErrorDescription::NotImplemented, ErrorModule::HTTP, | ||||||
|  |                            ErrorSummary::Internal, ErrorLevel::Permanent)); | ||||||
|  |         rb.PushMappedBuffer(value_buffer); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (session_data->current_http_context != context_handle) { | ||||||
|  |         LOG_ERROR(Service_HTTP, | ||||||
|  |                   "Tried to add a request header on a mismatched session input context={} session " | ||||||
|  |                   "context={}", | ||||||
|  |                   context_handle, session_data->current_http_context.get()); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |         rb.Push(ERROR_STATE_ERROR); | ||||||
|  |         rb.PushMappedBuffer(value_buffer); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto itr = contexts.find(context_handle); | ||||||
|  |     ASSERT(itr != contexts.end()); | ||||||
|  | 
 | ||||||
|  |     if (itr->second.state != RequestState::NotStarted) { | ||||||
|  |         LOG_ERROR(Service_HTTP, | ||||||
|  |                   "Tried to add a request header on a context that has already been started."); | ||||||
|  |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |         rb.Push(ResultCode(ErrCodes::InvalidRequestState, ErrorModule::HTTP, | ||||||
|  |                            ErrorSummary::InvalidState, ErrorLevel::Permanent)); | ||||||
|  |         rb.PushMappedBuffer(value_buffer); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ASSERT(itr->second.state == RequestState::NotStarted); |  | ||||||
|     ASSERT(std::find_if(itr->second.headers.begin(), itr->second.headers.end(), |     ASSERT(std::find_if(itr->second.headers.begin(), itr->second.headers.end(), | ||||||
|                         [&name](const Context::RequestHeader& m) -> bool { |                         [&name](const Context::RequestHeader& m) -> bool { | ||||||
|                             return m.name == name; |                             return m.name == name; | ||||||
|  | @ -132,8 +275,8 @@ void HTTP_C::AddRequestHeader(Kernel::HLERequestContext& ctx) { | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.PushMappedBuffer(value_buffer); |     rb.PushMappedBuffer(value_buffer); | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_HTTP, "called, name={}, value={}, context_handle={}", name, value, |     LOG_DEBUG(Service_HTTP, "called, name={}, value={}, context_handle={}", name, value, | ||||||
|                 context_handle); |               context_handle); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HTTP_C::HTTP_C() : ServiceFramework("http:C", 32) { | HTTP_C::HTTP_C() : ServiceFramework("http:C", 32) { | ||||||
|  | @ -145,7 +288,7 @@ HTTP_C::HTTP_C() : ServiceFramework("http:C", 32) { | ||||||
|         {0x00050040, nullptr, "GetRequestState"}, |         {0x00050040, nullptr, "GetRequestState"}, | ||||||
|         {0x00060040, nullptr, "GetDownloadSizeState"}, |         {0x00060040, nullptr, "GetDownloadSizeState"}, | ||||||
|         {0x00070040, nullptr, "GetRequestError"}, |         {0x00070040, nullptr, "GetRequestError"}, | ||||||
|         {0x00080042, nullptr, "InitializeConnectionSession"}, |         {0x00080042, &HTTP_C::InitializeConnectionSession, "InitializeConnectionSession"}, | ||||||
|         {0x00090040, nullptr, "BeginRequest"}, |         {0x00090040, nullptr, "BeginRequest"}, | ||||||
|         {0x000A0040, nullptr, "BeginRequestAsync"}, |         {0x000A0040, nullptr, "BeginRequestAsync"}, | ||||||
|         {0x000B0082, nullptr, "ReceiveData"}, |         {0x000B0082, nullptr, "ReceiveData"}, | ||||||
|  |  | ||||||
|  | @ -41,7 +41,8 @@ enum class RequestState : u8 { | ||||||
| /// There can only be at most one client certificate context attached to an HTTP context at any
 | /// There can only be at most one client certificate context attached to an HTTP context at any
 | ||||||
| /// given time.
 | /// given time.
 | ||||||
| struct ClientCertContext { | struct ClientCertContext { | ||||||
|     u32 handle; |     using Handle = u32; | ||||||
|  |     Handle handle; | ||||||
|     std::vector<u8> certificate; |     std::vector<u8> certificate; | ||||||
|     std::vector<u8> private_key; |     std::vector<u8> private_key; | ||||||
| }; | }; | ||||||
|  | @ -51,17 +52,21 @@ struct ClientCertContext { | ||||||
| /// it, but the chain may contain an arbitrary number of certificates in it.
 | /// it, but the chain may contain an arbitrary number of certificates in it.
 | ||||||
| struct RootCertChain { | struct RootCertChain { | ||||||
|     struct RootCACert { |     struct RootCACert { | ||||||
|         u32 handle; |         using Handle = u32; | ||||||
|  |         Handle handle; | ||||||
|         std::vector<u8> certificate; |         std::vector<u8> certificate; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     u32 handle; |     using Handle = u32; | ||||||
|  |     Handle handle; | ||||||
|     std::vector<RootCACert> certificates; |     std::vector<RootCACert> certificates; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /// Represents an HTTP context.
 | /// Represents an HTTP context.
 | ||||||
| class Context final { | class Context final { | ||||||
| public: | public: | ||||||
|  |     using Handle = u32; | ||||||
|  | 
 | ||||||
|     Context() = default; |     Context() = default; | ||||||
|     Context(const Context&) = delete; |     Context(const Context&) = delete; | ||||||
|     Context& operator=(const Context&) = delete; |     Context& operator=(const Context&) = delete; | ||||||
|  | @ -99,7 +104,7 @@ public: | ||||||
|         std::weak_ptr<RootCertChain> root_ca_chain; |         std::weak_ptr<RootCertChain> root_ca_chain; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     u32 handle; |     Handle handle; | ||||||
|     std::string url; |     std::string url; | ||||||
|     RequestMethod method; |     RequestMethod method; | ||||||
|     RequestState state = RequestState::NotStarted; |     RequestState state = RequestState::NotStarted; | ||||||
|  | @ -111,7 +116,22 @@ public: | ||||||
|     std::vector<PostData> post_data; |     std::vector<PostData> post_data; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class HTTP_C final : public ServiceFramework<HTTP_C> { | struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { | ||||||
|  |     /// The HTTP context that is currently bound to this session, this can be empty if no context
 | ||||||
|  |     /// has been bound. Certain commands can only be called on a session with a bound context.
 | ||||||
|  |     boost::optional<Context::Handle> current_http_context; | ||||||
|  | 
 | ||||||
|  |     /// Number of HTTP contexts that are currently opened in this session.
 | ||||||
|  |     u32 num_http_contexts = 0; | ||||||
|  |     /// Number of ClientCert contexts that are currently opened in this session.
 | ||||||
|  |     u32 num_client_certs = 0; | ||||||
|  | 
 | ||||||
|  |     /// Whether this session has been initialized in some way, be it via Initialize or
 | ||||||
|  |     /// InitializeConnectionSession.
 | ||||||
|  |     bool initialized = false; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class HTTP_C final : public ServiceFramework<HTTP_C, SessionData> { | ||||||
| public: | public: | ||||||
|     HTTP_C(); |     HTTP_C(); | ||||||
| 
 | 
 | ||||||
|  | @ -151,6 +171,17 @@ private: | ||||||
|      */ |      */ | ||||||
|     void CloseContext(Kernel::HLERequestContext& ctx); |     void CloseContext(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * HTTP_C::InitializeConnectionSession service function | ||||||
|  |      *  Inputs: | ||||||
|  |      *      1 : HTTP context handle | ||||||
|  |      *      2 : 0x20, processID translate-header for the ARM11-kernel | ||||||
|  |      *      3 : processID set by the ARM11-kernel | ||||||
|  |      *  Outputs: | ||||||
|  |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |      */ | ||||||
|  |     void InitializeConnectionSession(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * HTTP_C::AddRequestHeader service function |      * HTTP_C::AddRequestHeader service function | ||||||
|      *  Inputs: |      *  Inputs: | ||||||
|  | @ -168,11 +199,17 @@ private: | ||||||
| 
 | 
 | ||||||
|     Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr; |     Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr; | ||||||
| 
 | 
 | ||||||
|     std::unordered_map<u32, Context> contexts; |     /// The next handle number to use when a new HTTP context is created.
 | ||||||
|     u32 context_counter = 0; |     Context::Handle context_counter = 0; | ||||||
| 
 | 
 | ||||||
|     std::unordered_map<u32, ClientCertContext> client_certs; |     /// The next handle number to use when a new ClientCert context is created.
 | ||||||
|     u32 client_certs_counter = 0; |     ClientCertContext::Handle client_certs_counter = 0; | ||||||
|  | 
 | ||||||
|  |     /// Global list of HTTP contexts currently opened.
 | ||||||
|  |     std::unordered_map<Context::Handle, Context> contexts; | ||||||
|  | 
 | ||||||
|  |     /// Global list of  ClientCert contexts currently opened.
 | ||||||
|  |     std::unordered_map<ClientCertContext::Handle, ClientCertContext> client_certs; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void InstallInterfaces(SM::ServiceManager& service_manager); | void InstallInterfaces(SM::ServiceManager& service_manager); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue