mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 06:31:03 +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() {
|
||||
state = REQUEST_STATE_NONE;
|
||||
state = REQUEST_STATE_NOT_STARTED;
|
||||
cancel_request = false;
|
||||
req_type = REQUEST_TYPE_NONE;
|
||||
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_WRITEDATA, &response_data);
|
||||
|
||||
mres = curl_multi_add_handle(manager, connection);
|
||||
curl_multi_add_handle(manager, connection);
|
||||
|
||||
int still_running = 0;
|
||||
int repeats = 0;
|
||||
mres = curl_multi_perform(manager, &still_running);
|
||||
curl_multi_perform(manager, &still_running);
|
||||
|
||||
do {
|
||||
// Number of file descriptors. If this is zero, nothing happened to
|
||||
// the active connection.
|
||||
int numfds;
|
||||
|
||||
// Set the timeout to 1sec.
|
||||
if (curl_multi_wait(manager, NULL, 0, 1000, &numfds) != CURLM_OK)
|
||||
break;
|
||||
|
||||
if (numfds == 0) {
|
||||
// We allow one repeat try--after which, we start to sleep the
|
||||
// thread until the timeout runs out.
|
||||
if (repeats++ > 1)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(25));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
} else {
|
||||
// While the file descriptor is responding, there's no need to check for repeats.
|
||||
repeats = 0;
|
||||
}
|
||||
|
||||
@ -103,7 +107,7 @@ void MakeRequest(HttpContext* context) {
|
||||
break;
|
||||
}
|
||||
|
||||
mres = curl_multi_perform(manager, &still_running);
|
||||
curl_multi_perform(manager, &still_running);
|
||||
} 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) {
|
||||
// TODO: header value is empty
|
||||
std::string header = Common::StringFromFormat("%s: %s", name.c_str(), value.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).
|
||||
enum RequestState : u32 {
|
||||
REQUEST_STATE_NONE = 0, // TODO: Verify
|
||||
REQUEST_STATE_NOT_STARTED = 1,
|
||||
REQUEST_STATE_IN_PROGRESS = 5,
|
||||
REQUEST_STATE_READY = 8,
|
||||
REQUEST_STATE_TIMEOUT = 10,
|
||||
};
|
||||
|
||||
/** 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]);
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ static void CancelConnection(Service::Interface* self) {
|
||||
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
map_it->second->cancel_request = true;
|
||||
@ -82,7 +82,7 @@ static void GetRequestState(Service::Interface* self) {
|
||||
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -99,15 +99,13 @@ static void GetDownloadSizeState(Service::Interface* self) {
|
||||
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
|
||||
HttpContext* response = map_it->second.get();
|
||||
std::lock_guard<std::mutex> lock(response->mutex);
|
||||
|
||||
// TODO: Request not done yet
|
||||
|
||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||
cmd_buff[2] = (u32) response->downloaded_size;
|
||||
// TODO: invalid content-length?
|
||||
@ -121,12 +119,13 @@ static void BeginRequest(Service::Interface* self) {
|
||||
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
|
||||
HttpContext* context = map_it->second.get();
|
||||
std::lock_guard<std::mutex> lock(context->mutex);
|
||||
|
||||
context->req_thread = Common::make_unique<std::thread>(MakeRequest, context);
|
||||
context->state = REQUEST_STATE_IN_PROGRESS;
|
||||
|
||||
@ -142,14 +141,14 @@ static void ReceiveData(Service::Interface* self) {
|
||||
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
||||
const std::vector<u8>& data = map_it->second->response_data;
|
||||
if (buf_size < data.size()) {
|
||||
cmd_buff[1] = 0xd840a02b;
|
||||
cmd_buff[1] = 0xD840A02B;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -164,21 +163,25 @@ static void AddRequestHeader(Service::Interface* self) {
|
||||
u32 hdr_name_len = cmd_buff[2];
|
||||
u32 hdr_val_len = cmd_buff[3];
|
||||
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
|
||||
// TODO: header value is empty
|
||||
// TODO: header name is empty
|
||||
std::string hdr_name = std::string(hdr_name_buf, hdr_name_len);
|
||||
std::string hdr_val = std::string(hdr_val_buf, hdr_val_len);
|
||||
|
||||
if (hdr_name.empty()) {
|
||||
cmd_buff[1] = 0xD8E0A002;
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(map_it->second->mutex);
|
||||
AddRequestHeader(std::string(hdr_name_buf, hdr_name_len).c_str(),
|
||||
std::string(hdr_val_buf, hdr_val_len).c_str(),
|
||||
AddRequestHeader(hdr_name.c_str(),
|
||||
hdr_val.c_str(),
|
||||
&map_it->second->request_hdrs);
|
||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||
}
|
||||
@ -190,7 +193,7 @@ static void GetResponseStatusCode(Service::Interface* self) {
|
||||
|
||||
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
|
||||
cmd_buff[1] = 0xD8E007F7;
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user