mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 16:01:05 +00:00
Separate out http_c into multiple files under http/
Also implement safe thread exiting, and closing of contexts.
This commit is contained in:
parent
24cc45c246
commit
779b482ac3
@ -65,7 +65,8 @@ set(SRCS
|
|||||||
hle/service/hid/hid.cpp
|
hle/service/hid/hid.cpp
|
||||||
hle/service/hid/hid_spvr.cpp
|
hle/service/hid/hid_spvr.cpp
|
||||||
hle/service/hid/hid_user.cpp
|
hle/service/hid/hid_user.cpp
|
||||||
hle/service/http_c.cpp
|
hle/service/http/http.cpp
|
||||||
|
hle/service/http/http_c.cpp
|
||||||
hle/service/ir/ir.cpp
|
hle/service/ir/ir.cpp
|
||||||
hle/service/ir/ir_rst.cpp
|
hle/service/ir/ir_rst.cpp
|
||||||
hle/service/ir/ir_u.cpp
|
hle/service/ir/ir_u.cpp
|
||||||
@ -177,7 +178,8 @@ set(HEADERS
|
|||||||
hle/service/hid/hid.h
|
hle/service/hid/hid.h
|
||||||
hle/service/hid/hid_spvr.h
|
hle/service/hid/hid_spvr.h
|
||||||
hle/service/hid/hid_user.h
|
hle/service/hid/hid_user.h
|
||||||
hle/service/http_c.h
|
hle/service/http/http.h
|
||||||
|
hle/service/http/http_c.h
|
||||||
hle/service/ir/ir.h
|
hle/service/ir/ir.h
|
||||||
hle/service/ir/ir_rst.h
|
hle/service/ir/ir_rst.h
|
||||||
hle/service/ir/ir_u.h
|
hle/service/ir/ir_u.h
|
||||||
|
119
src/core/hle/service/http/http.cpp
Normal file
119
src/core/hle/service/http/http.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2015 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "common/string_util.h"
|
||||||
|
|
||||||
|
#include "core/hle/service/http/http.h"
|
||||||
|
#include "core/hle/service/http/http_c.h"
|
||||||
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Service {
|
||||||
|
namespace HTTP {
|
||||||
|
|
||||||
|
std::unordered_map<ContextHandle, std::unique_ptr<HttpContext>> context_map;
|
||||||
|
ContextHandle next_handle;
|
||||||
|
|
||||||
|
static int WriteBuf(u8 *data, size_t size, size_t nmemb, std::mutex *mutex, std::vector<u8> *buffer) {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex);
|
||||||
|
buffer->reserve(buffer->size() + size * nmemb);
|
||||||
|
buffer->insert(buffer->end(), data, data + size * nmemb);
|
||||||
|
return static_cast<int>(size * nmemb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int HdrWriter(u8 *data, size_t size, size_t nmemb, HttpContext *context) {
|
||||||
|
if (context == nullptr || context->should_quit)
|
||||||
|
return -1;
|
||||||
|
return WriteBuf(data, size, nmemb, &context->mutex, &context->response_hdrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DataWriter(u8 *data, size_t size, size_t nmemb, HttpContext *context) {
|
||||||
|
if (context == nullptr || context->should_quit)
|
||||||
|
return -1;
|
||||||
|
return WriteBuf(data, size, nmemb, &context->mutex, &context->response_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpContext::~HttpContext() {
|
||||||
|
curl_slist_free_all(request_hdrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeRequest(HttpContext* context) {
|
||||||
|
CURL* connection = curl_easy_init();
|
||||||
|
CURLcode res;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(context->mutex);
|
||||||
|
|
||||||
|
context->state = REQUEST_STATE_IN_PROGRESS;
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_URL, context->url.c_str());
|
||||||
|
switch (context->req_type) {
|
||||||
|
case REQUEST_TYPE_GET:
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_HTTPGET, 1);
|
||||||
|
break;
|
||||||
|
case REQUEST_TYPE_POST:
|
||||||
|
case REQUEST_TYPE_POST_:
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_POST, 1);
|
||||||
|
break;
|
||||||
|
case REQUEST_TYPE_PUT:
|
||||||
|
case REQUEST_TYPE_PUT_:
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_UPLOAD, 1);
|
||||||
|
break;
|
||||||
|
case REQUEST_TYPE_DELETE:
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case REQUEST_TYPE_HEAD:
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_NOBODY, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_HEADERFUNCTION, HdrWriter);
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_WRITEFUNCTION, DataWriter);
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_HEADERDATA, context);
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_WRITEDATA, context);
|
||||||
|
res = curl_easy_setopt(connection, CURLOPT_HTTPHEADER, context->request_hdrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = curl_easy_perform(connection);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(context->mutex);
|
||||||
|
|
||||||
|
res = curl_easy_getinfo(connection, CURLINFO_RESPONSE_CODE, &context->response_code);
|
||||||
|
res = curl_easy_getinfo(connection, CURLINFO_SIZE_DOWNLOAD, &context->downloaded_size);
|
||||||
|
res = curl_easy_getinfo(connection, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &context->download_size);
|
||||||
|
|
||||||
|
context->state = REQUEST_STATE_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_cleanup(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddRequestHeader(std::string name, std::string value, curl_slist** hdr_list) {
|
||||||
|
std::string header = Common::StringFromFormat("%s: %s", name.c_str(), value.c_str());
|
||||||
|
*hdr_list = curl_slist_append(*hdr_list, header.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init() {
|
||||||
|
AddService(new HTTP_C_Interface);
|
||||||
|
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearInstance() {
|
||||||
|
for (auto& pair : context_map) {
|
||||||
|
pair.second->should_quit = true;
|
||||||
|
if (pair.second->req_thread != nullptr)
|
||||||
|
pair.second->req_thread->join();
|
||||||
|
}
|
||||||
|
|
||||||
|
context_map.clear();
|
||||||
|
next_handle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() {
|
||||||
|
curl_global_cleanup();
|
||||||
|
ClearInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace HTTP
|
||||||
|
} // namespace Service
|
74
src/core/hle/service/http/http.h
Normal file
74
src/core/hle/service/http/http.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Copyright 2015 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
struct curl_slist;
|
||||||
|
|
||||||
|
namespace Service {
|
||||||
|
namespace HTTP {
|
||||||
|
|
||||||
|
typedef u32 ContextHandle;
|
||||||
|
|
||||||
|
enum RequestType : u32 {
|
||||||
|
REQUEST_TYPE_NONE = 0,
|
||||||
|
REQUEST_TYPE_GET = 1,
|
||||||
|
REQUEST_TYPE_POST = 2,
|
||||||
|
REQUEST_TYPE_HEAD = 3,
|
||||||
|
REQUEST_TYPE_PUT = 4,
|
||||||
|
REQUEST_TYPE_DELETE = 5,
|
||||||
|
REQUEST_TYPE_POST_ = 6,
|
||||||
|
REQUEST_TYPE_PUT_ = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RequestState : u32 {
|
||||||
|
REQUEST_STATE_DEFAULT, // TODO
|
||||||
|
REQUEST_STATE_IN_PROGRESS = 5,
|
||||||
|
REQUEST_STATE_READY = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HttpContext {
|
||||||
|
std::mutex mutex;
|
||||||
|
bool should_quit;
|
||||||
|
|
||||||
|
RequestState state;
|
||||||
|
std::unique_ptr<std::thread> req_thread;
|
||||||
|
|
||||||
|
std::string url;
|
||||||
|
RequestType req_type;
|
||||||
|
curl_slist* request_hdrs;
|
||||||
|
|
||||||
|
std::vector<u8> response_hdrs;
|
||||||
|
std::vector<u8> response_data;
|
||||||
|
long response_code;
|
||||||
|
double download_size;
|
||||||
|
double downloaded_size;
|
||||||
|
|
||||||
|
~HttpContext();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::unordered_map<ContextHandle, std::unique_ptr<HttpContext>> context_map;
|
||||||
|
extern ContextHandle next_handle;
|
||||||
|
|
||||||
|
void MakeRequest(HttpContext* context);
|
||||||
|
void AddRequestHeader(std::string name, std::string value, curl_slist** hdr_list);
|
||||||
|
|
||||||
|
/// Initialize the HTTP service
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
void ClearInstance();
|
||||||
|
|
||||||
|
/// Shutdown the HTTP service
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
} // namespace HTTP
|
||||||
|
} // namespace Service
|
@ -4,87 +4,21 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#include "core/hle/hle.h"
|
#include "core/hle/hle.h"
|
||||||
#include "core/hle/service/http_c.h"
|
#include "core/hle/service/http/http.h"
|
||||||
|
#include "core/hle/service/http/http_c.h"
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/make_unique.h"
|
#include "common/make_unique.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
namespace Service {
|
||||||
// Namespace HTTP_C
|
namespace HTTP {
|
||||||
|
|
||||||
namespace HTTP_C {
|
|
||||||
|
|
||||||
typedef u32 ContextHandle;
|
|
||||||
|
|
||||||
enum RequestType : u32 {
|
|
||||||
REQUEST_TYPE_NONE = 0,
|
|
||||||
REQUEST_TYPE_GET = 1,
|
|
||||||
REQUEST_TYPE_POST = 2,
|
|
||||||
REQUEST_TYPE_HEAD = 3,
|
|
||||||
REQUEST_TYPE_PUT = 4,
|
|
||||||
REQUEST_TYPE_DELETE = 5,
|
|
||||||
REQUEST_TYPE_POST_ = 6,
|
|
||||||
REQUEST_TYPE_PUT_ = 7
|
|
||||||
};
|
|
||||||
|
|
||||||
enum RequestState : u32 {
|
|
||||||
REQUEST_STATE_DEFAULT, // TODO
|
|
||||||
REQUEST_STATE_IN_PROGRESS = 5,
|
|
||||||
REQUEST_STATE_READY = 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HttpContext {
|
|
||||||
std::mutex mutex;
|
|
||||||
|
|
||||||
RequestState state;
|
|
||||||
|
|
||||||
std::string url;
|
|
||||||
RequestType req_type;
|
|
||||||
curl_slist* request_hdrs;
|
|
||||||
|
|
||||||
std::vector<u8> response_hdrs;
|
|
||||||
std::vector<u8> response_data;
|
|
||||||
long response_code;
|
|
||||||
double download_size;
|
|
||||||
double downloaded_size;
|
|
||||||
|
|
||||||
~HttpContext() {
|
|
||||||
curl_slist_free_all(request_hdrs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::unordered_map<ContextHandle, std::unique_ptr<HttpContext>> context_map;
|
|
||||||
static ContextHandle next_handle;
|
|
||||||
|
|
||||||
static int writer_hdrs(u8* data, size_t size, size_t nmemb, HttpContext* context) {
|
|
||||||
if (context == nullptr)
|
|
||||||
return 0;
|
|
||||||
std::lock_guard<std::mutex> lock(context->mutex);
|
|
||||||
context->response_hdrs.reserve(context->response_hdrs.size() + size * nmemb);
|
|
||||||
context->response_hdrs.insert(context->response_hdrs.end(), data, data + size * nmemb);
|
|
||||||
return (int)(size * nmemb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int writer_data(u8* data, size_t size, size_t nmemb, HttpContext* context) {
|
|
||||||
if (context == nullptr)
|
|
||||||
return 0;
|
|
||||||
std::lock_guard<std::mutex> lock(context->mutex);
|
|
||||||
context->response_data.reserve(context->response_data.size() + size * nmemb);
|
|
||||||
context->response_data.insert(context->response_data.end(), data, data + size * nmemb);
|
|
||||||
return (int)(size * nmemb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Initialize(Service::Interface* self) {
|
static void Initialize(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +39,6 @@ static void CreateContext(Service::Interface* self) {
|
|||||||
|
|
||||||
context->req_type = req_type;
|
context->req_type = req_type;
|
||||||
context->url = url;
|
context->url = url;
|
||||||
|
|
||||||
context_map.emplace(next_handle, std::move(context));
|
context_map.emplace(next_handle, std::move(context));
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
@ -118,17 +51,36 @@ static void CloseContext(Service::Interface* self) {
|
|||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
ContextHandle handle = static_cast<ContextHandle>(cmd_buff[1]);
|
ContextHandle handle = static_cast<ContextHandle>(cmd_buff[1]);
|
||||||
// auto map_it = request_map.find(handle);
|
auto map_it = context_map.find(handle);
|
||||||
// if (map_it == request_map.end()) {
|
if (map_it == context_map.end()) {
|
||||||
// cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// TODO: wait for thread to finish!
|
|
||||||
|
map_it->second->should_quit = true;
|
||||||
|
if (map_it->second->req_thread != nullptr)
|
||||||
|
map_it->second->req_thread->join();
|
||||||
|
|
||||||
context_map.erase(handle);
|
context_map.erase(handle);
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CancelConnection(Service::Interface* self) {
|
||||||
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
|
ContextHandle handle = static_cast<ContextHandle>(cmd_buff[1]);
|
||||||
|
|
||||||
|
auto map_it = context_map.find(handle);
|
||||||
|
if (map_it == context_map.end()) {
|
||||||
|
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map_it->second->should_quit = true;
|
||||||
|
|
||||||
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
|
}
|
||||||
|
|
||||||
static void GetRequestState(Service::Interface* self) {
|
static void GetRequestState(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
@ -169,56 +121,6 @@ static void GetDownloadSizeState(Service::Interface* self) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MakeRequest(HttpContext* context) {
|
|
||||||
CURL* connection = curl_easy_init();
|
|
||||||
CURLcode res;
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(context->mutex);
|
|
||||||
|
|
||||||
context->state = REQUEST_STATE_IN_PROGRESS;
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_URL, context->url.c_str());
|
|
||||||
switch (context->req_type) {
|
|
||||||
case REQUEST_TYPE_GET:
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_HTTPGET, 1);
|
|
||||||
break;
|
|
||||||
case REQUEST_TYPE_POST:
|
|
||||||
case REQUEST_TYPE_POST_:
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_POST, 1);
|
|
||||||
break;
|
|
||||||
case REQUEST_TYPE_PUT:
|
|
||||||
case REQUEST_TYPE_PUT_:
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_UPLOAD, 1);
|
|
||||||
break;
|
|
||||||
case REQUEST_TYPE_DELETE:
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
case REQUEST_TYPE_HEAD:
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_NOBODY, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_HEADERFUNCTION, writer_hdrs);
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_WRITEFUNCTION, writer_data);
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_HEADERDATA, context);
|
|
||||||
res = curl_easy_setopt(connection, CURLOPT_WRITEDATA, context);
|
|
||||||
|
|
||||||
curl_easy_setopt(connection, CURLOPT_HTTPHEADER, context->request_hdrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
res = curl_easy_perform(connection);
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(context->mutex);
|
|
||||||
|
|
||||||
curl_easy_getinfo(connection, CURLINFO_RESPONSE_CODE, &context->response_code);
|
|
||||||
curl_easy_getinfo(connection, CURLINFO_SIZE_DOWNLOAD, &context->downloaded_size);
|
|
||||||
curl_easy_getinfo(connection, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &context->download_size);
|
|
||||||
|
|
||||||
context->state = REQUEST_STATE_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_cleanup(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BeginRequest(Service::Interface* self) {
|
static void BeginRequest(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
@ -231,9 +133,8 @@ static void BeginRequest(Service::Interface* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HttpContext* context = map_it->second.get();
|
HttpContext* context = map_it->second.get();
|
||||||
|
std::lock_guard<std::mutex> lock(context->mutex);
|
||||||
std::thread req_thread(MakeRequest, context);
|
context->req_thread = Common::make_unique<std::thread>(MakeRequest, context);
|
||||||
req_thread.detach();
|
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
}
|
}
|
||||||
@ -268,15 +169,12 @@ static void AddRequestHeader(Service::Interface* self) {
|
|||||||
ContextHandle handle = static_cast<ContextHandle>(cmd_buff[1]);
|
ContextHandle handle = static_cast<ContextHandle>(cmd_buff[1]);
|
||||||
u32 hdr_name_len = cmd_buff[2];
|
u32 hdr_name_len = cmd_buff[2];
|
||||||
u32 hdr_val_len = cmd_buff[3];
|
u32 hdr_val_len = cmd_buff[3];
|
||||||
u32 hdr_name_buf = cmd_buff[5];
|
const char* hdr_name_buf = reinterpret_cast<const char*>(Memory::GetPointer(cmd_buff[5]));
|
||||||
u32 hdr_val_buf = cmd_buff[7];
|
const char* hdr_val_buf = reinterpret_cast<const char*>(Memory::GetPointer(cmd_buff[7]));
|
||||||
|
|
||||||
// TODO: something is NULL
|
// TODO: something is NULL
|
||||||
// TODO: header value is empty
|
// TODO: header value is empty
|
||||||
// TODO: header name is empty
|
// TODO: header name is empty
|
||||||
std::string header = Common::StringFromFormat("%s: %s",
|
|
||||||
std::string(reinterpret_cast<const char*>(Memory::GetPointer(hdr_name_buf)), hdr_name_len).c_str(),
|
|
||||||
std::string(reinterpret_cast<const char*>(Memory::GetPointer(hdr_val_buf)), hdr_val_len).c_str());
|
|
||||||
|
|
||||||
auto map_it = context_map.find(handle);
|
auto map_it = context_map.find(handle);
|
||||||
if (map_it == context_map.end()) {
|
if (map_it == context_map.end()) {
|
||||||
@ -285,7 +183,9 @@ static void AddRequestHeader(Service::Interface* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
||||||
map_it->second->request_hdrs = curl_slist_append(map_it->second->request_hdrs, header.c_str());
|
AddRequestHeader(std::string(hdr_name_buf, hdr_name_len).c_str(),
|
||||||
|
std::string(hdr_val_buf, hdr_val_len).c_str(),
|
||||||
|
&map_it->second->request_hdrs);
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +200,7 @@ static void GetResponseStatusCode(Service::Interface* self) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Verify behavior
|
||||||
while (true) {
|
while (true) {
|
||||||
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
||||||
if (map_it->second->state == REQUEST_STATE_READY)
|
if (map_it->second->state == REQUEST_STATE_READY)
|
||||||
@ -317,9 +218,7 @@ static void GetResponseStatusCode(Service::Interface* self) {
|
|||||||
static void Finalize(Service::Interface* self) {
|
static void Finalize(Service::Interface* self) {
|
||||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||||
|
|
||||||
context_map.clear();
|
ClearInstance();
|
||||||
next_handle = 0;
|
|
||||||
curl_global_cleanup();
|
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
}
|
}
|
||||||
@ -328,7 +227,7 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x00010044, Initialize, "Initialize"},
|
{0x00010044, Initialize, "Initialize"},
|
||||||
{0x00020082, CreateContext, "CreateContext"},
|
{0x00020082, CreateContext, "CreateContext"},
|
||||||
{0x00030040, CloseContext, "CloseContext"},
|
{0x00030040, CloseContext, "CloseContext"},
|
||||||
{0x00040040, nullptr, "CancelConnection"},
|
{0x00040040, CancelConnection, "CancelConnection"},
|
||||||
{0x00050040, GetRequestState, "GetRequestState"},
|
{0x00050040, GetRequestState, "GetRequestState"},
|
||||||
{0x00060040, GetDownloadSizeState, "GetDownloadSizeState"},
|
{0x00060040, GetDownloadSizeState, "GetDownloadSizeState"},
|
||||||
{0x00070040, nullptr, "GetRequestError"},
|
{0x00070040, nullptr, "GetRequestError"},
|
||||||
@ -370,8 +269,9 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Interface class
|
// Interface class
|
||||||
|
|
||||||
Interface::Interface() {
|
HTTP_C_Interface::HTTP_C_Interface() {
|
||||||
Register(FunctionTable);
|
Register(FunctionTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
@ -6,14 +6,12 @@
|
|||||||
|
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
namespace Service {
|
||||||
// Namespace HTTP_C
|
namespace HTTP {
|
||||||
|
|
||||||
namespace HTTP_C {
|
class HTTP_C_Interface : public Service::Interface {
|
||||||
|
|
||||||
class Interface : public Service::Interface {
|
|
||||||
public:
|
public:
|
||||||
Interface();
|
HTTP_C_Interface();
|
||||||
|
|
||||||
std::string GetPortName() const override {
|
std::string GetPortName() const override {
|
||||||
return "http:C";
|
return "http:C";
|
||||||
@ -21,3 +19,4 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
}
|
@ -23,7 +23,6 @@
|
|||||||
#include "core/hle/service/frd_u.h"
|
#include "core/hle/service/frd_u.h"
|
||||||
#include "core/hle/service/gsp_gpu.h"
|
#include "core/hle/service/gsp_gpu.h"
|
||||||
#include "core/hle/service/gsp_lcd.h"
|
#include "core/hle/service/gsp_lcd.h"
|
||||||
#include "core/hle/service/http_c.h"
|
|
||||||
#include "core/hle/service/ldr_ro.h"
|
#include "core/hle/service/ldr_ro.h"
|
||||||
#include "core/hle/service/mic_u.h"
|
#include "core/hle/service/mic_u.h"
|
||||||
#include "core/hle/service/ndm_u.h"
|
#include "core/hle/service/ndm_u.h"
|
||||||
@ -43,6 +42,7 @@
|
|||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/hle/service/hid/hid.h"
|
#include "core/hle/service/hid/hid.h"
|
||||||
|
#include "core/hle/service/http/http.h"
|
||||||
#include "core/hle/service/ir/ir.h"
|
#include "core/hle/service/ir/ir.h"
|
||||||
#include "core/hle/service/ptm/ptm.h"
|
#include "core/hle/service/ptm/ptm.h"
|
||||||
|
|
||||||
@ -115,6 +115,7 @@ void Init() {
|
|||||||
Service::APT::Init();
|
Service::APT::Init();
|
||||||
Service::PTM::Init();
|
Service::PTM::Init();
|
||||||
Service::HID::Init();
|
Service::HID::Init();
|
||||||
|
Service::HTTP::Init();
|
||||||
Service::IR::Init();
|
Service::IR::Init();
|
||||||
|
|
||||||
AddService(new AC_U::Interface);
|
AddService(new AC_U::Interface);
|
||||||
@ -133,7 +134,6 @@ void Init() {
|
|||||||
AddService(new FRD_U::Interface);
|
AddService(new FRD_U::Interface);
|
||||||
AddService(new GSP_GPU::Interface);
|
AddService(new GSP_GPU::Interface);
|
||||||
AddService(new GSP_LCD::Interface);
|
AddService(new GSP_LCD::Interface);
|
||||||
AddService(new HTTP_C::Interface);
|
|
||||||
AddService(new LDR_RO::Interface);
|
AddService(new LDR_RO::Interface);
|
||||||
AddService(new MIC_U::Interface);
|
AddService(new MIC_U::Interface);
|
||||||
AddService(new NDM_U::Interface);
|
AddService(new NDM_U::Interface);
|
||||||
|
Loading…
Reference in New Issue
Block a user