Fixes based on verification of behavior on hardware

This commit is contained in:
archshift 2015-05-13 01:00:00 -07:00
parent b550a4e4dc
commit eb2dd8bf5d
3 changed files with 32 additions and 23 deletions

View File

@ -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());
} }

View File

@ -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.

View File

@ -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;
} }