mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 08:21:04 +00:00
Fixes based on verification of behavior on hardware
This commit is contained in:
parent
b550a4e4dc
commit
eb2dd8bf5d
@ -25,7 +25,7 @@ static int BufWriter(u8 *data, size_t size, size_t nmemb, std::vector<u8>* out_b
|
|||||||
}
|
}
|
||||||
|
|
||||||
HttpContext::HttpContext() {
|
HttpContext::HttpContext() {
|
||||||
state = REQUEST_STATE_NONE;
|
state = REQUEST_STATE_NOT_STARTED;
|
||||||
cancel_request = false;
|
cancel_request = false;
|
||||||
req_type = REQUEST_TYPE_NONE;
|
req_type = REQUEST_TYPE_NONE;
|
||||||
request_hdrs = nullptr;
|
request_hdrs = nullptr;
|
||||||
@ -76,24 +76,28 @@ void MakeRequest(HttpContext* context) {
|
|||||||
res = curl_easy_setopt(connection, CURLOPT_HEADERDATA, &response_hdrs);
|
res = curl_easy_setopt(connection, CURLOPT_HEADERDATA, &response_hdrs);
|
||||||
res = curl_easy_setopt(connection, CURLOPT_WRITEDATA, &response_data);
|
res = curl_easy_setopt(connection, CURLOPT_WRITEDATA, &response_data);
|
||||||
|
|
||||||
mres = curl_multi_add_handle(manager, connection);
|
curl_multi_add_handle(manager, connection);
|
||||||
|
|
||||||
int still_running = 0;
|
int still_running = 0;
|
||||||
int repeats = 0;
|
int repeats = 0;
|
||||||
mres = curl_multi_perform(manager, &still_running);
|
curl_multi_perform(manager, &still_running);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Number of file descriptors. If this is zero, nothing happened to
|
// Number of file descriptors. If this is zero, nothing happened to
|
||||||
// the active connection.
|
// the active connection.
|
||||||
int numfds;
|
int numfds;
|
||||||
|
|
||||||
|
// Set the timeout to 1sec.
|
||||||
if (curl_multi_wait(manager, NULL, 0, 1000, &numfds) != CURLM_OK)
|
if (curl_multi_wait(manager, NULL, 0, 1000, &numfds) != CURLM_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (numfds == 0) {
|
if (numfds == 0) {
|
||||||
|
// We allow one repeat try--after which, we start to sleep the
|
||||||
|
// thread until the timeout runs out.
|
||||||
if (repeats++ > 1)
|
if (repeats++ > 1)
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(25));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
} else {
|
} else {
|
||||||
|
// While the file descriptor is responding, there's no need to check for repeats.
|
||||||
repeats = 0;
|
repeats = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +107,7 @@ void MakeRequest(HttpContext* context) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mres = curl_multi_perform(manager, &still_running);
|
curl_multi_perform(manager, &still_running);
|
||||||
} while (still_running != 0);
|
} while (still_running != 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -124,6 +128,7 @@ void MakeRequest(HttpContext* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AddRequestHeader(const std::string& name, const std::string& value, curl_slist** hdr_list) {
|
void AddRequestHeader(const std::string& name, const std::string& value, curl_slist** hdr_list) {
|
||||||
|
// TODO: header value is empty
|
||||||
std::string header = Common::StringFromFormat("%s: %s", name.c_str(), value.c_str());
|
std::string header = Common::StringFromFormat("%s: %s", name.c_str(), value.c_str());
|
||||||
*hdr_list = curl_slist_append(*hdr_list, header.c_str());
|
*hdr_list = curl_slist_append(*hdr_list, header.c_str());
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,10 @@ enum RequestType : u32 {
|
|||||||
|
|
||||||
/// Current state of the HTTP request (API-exposed).
|
/// Current state of the HTTP request (API-exposed).
|
||||||
enum RequestState : u32 {
|
enum RequestState : u32 {
|
||||||
REQUEST_STATE_NONE = 0, // TODO: Verify
|
REQUEST_STATE_NOT_STARTED = 1,
|
||||||
REQUEST_STATE_IN_PROGRESS = 5,
|
REQUEST_STATE_IN_PROGRESS = 5,
|
||||||
REQUEST_STATE_READY = 8,
|
REQUEST_STATE_READY = 8,
|
||||||
|
REQUEST_STATE_TIMEOUT = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A helper struct that contains all the required information for a HTTP request.
|
/** A helper struct that contains all the required information for a HTTP request.
|
||||||
|
@ -47,7 +47,7 @@ static void CloseContext(Service::Interface* self) {
|
|||||||
ContextHandle handle = static_cast<ContextHandle>(cmd_buff[1]);
|
ContextHandle handle = static_cast<ContextHandle>(cmd_buff[1]);
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ static void CancelConnection(Service::Interface* self) {
|
|||||||
|
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
map_it->second->cancel_request = true;
|
map_it->second->cancel_request = true;
|
||||||
@ -82,7 +82,7 @@ static void GetRequestState(Service::Interface* self) {
|
|||||||
|
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,15 +99,13 @@ static void GetDownloadSizeState(Service::Interface* self) {
|
|||||||
|
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpContext* response = map_it->second.get();
|
HttpContext* response = map_it->second.get();
|
||||||
std::lock_guard<std::mutex> lock(response->mutex);
|
std::lock_guard<std::mutex> lock(response->mutex);
|
||||||
|
|
||||||
// TODO: Request not done yet
|
|
||||||
|
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
cmd_buff[2] = (u32) response->downloaded_size;
|
cmd_buff[2] = (u32) response->downloaded_size;
|
||||||
// TODO: invalid content-length?
|
// TODO: invalid content-length?
|
||||||
@ -121,12 +119,13 @@ static void BeginRequest(Service::Interface* self) {
|
|||||||
|
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpContext* context = map_it->second.get();
|
HttpContext* context = map_it->second.get();
|
||||||
std::lock_guard<std::mutex> lock(context->mutex);
|
std::lock_guard<std::mutex> lock(context->mutex);
|
||||||
|
|
||||||
context->req_thread = Common::make_unique<std::thread>(MakeRequest, context);
|
context->req_thread = Common::make_unique<std::thread>(MakeRequest, context);
|
||||||
context->state = REQUEST_STATE_IN_PROGRESS;
|
context->state = REQUEST_STATE_IN_PROGRESS;
|
||||||
|
|
||||||
@ -142,14 +141,14 @@ static void ReceiveData(Service::Interface* self) {
|
|||||||
|
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
||||||
const std::vector<u8>& data = map_it->second->response_data;
|
const std::vector<u8>& data = map_it->second->response_data;
|
||||||
if (buf_size < data.size()) {
|
if (buf_size < data.size()) {
|
||||||
cmd_buff[1] = 0xd840a02b;
|
cmd_buff[1] = 0xD840A02B;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,21 +163,25 @@ static void AddRequestHeader(Service::Interface* self) {
|
|||||||
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];
|
||||||
char* hdr_name_buf = reinterpret_cast<char*>(Memory::GetPointer(cmd_buff[5]));
|
char* hdr_name_buf = reinterpret_cast<char*>(Memory::GetPointer(cmd_buff[5]));
|
||||||
char* hdr_val_buf = reinterpret_cast<char*>(Memory::GetPointer(cmd_buff[7]));
|
char* hdr_val_buf = reinterpret_cast<char*>(Memory::GetPointer(cmd_buff[7]));
|
||||||
|
|
||||||
// TODO: something is NULL
|
std::string hdr_name = std::string(hdr_name_buf, hdr_name_len);
|
||||||
// TODO: header value is empty
|
std::string hdr_val = std::string(hdr_val_buf, hdr_val_len);
|
||||||
// TODO: header name is empty
|
|
||||||
|
if (hdr_name.empty()) {
|
||||||
|
cmd_buff[1] = 0xD8E0A002;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
||||||
AddRequestHeader(std::string(hdr_name_buf, hdr_name_len).c_str(),
|
AddRequestHeader(hdr_name.c_str(),
|
||||||
std::string(hdr_val_buf, hdr_val_len).c_str(),
|
hdr_val.c_str(),
|
||||||
&map_it->second->request_hdrs);
|
&map_it->second->request_hdrs);
|
||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
}
|
}
|
||||||
@ -190,7 +193,7 @@ static void GetResponseStatusCode(Service::Interface* self) {
|
|||||||
|
|
||||||
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()) {
|
||||||
cmd_buff[1] = -1; // TODO: Find proper result code for invalid handle
|
cmd_buff[1] = 0xD8E007F7;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user