Added additional documentation

This commit is contained in:
archshift 2015-05-12 20:17:18 -07:00
parent 5d11d2bcbb
commit 5b12f23365
3 changed files with 34 additions and 20 deletions

View File

@ -39,8 +39,7 @@ static CURLcode SetConnectionType(CURL* connection, RequestType type) {
case REQUEST_TYPE_PUT_: case REQUEST_TYPE_PUT_:
return curl_easy_setopt(connection, CURLOPT_UPLOAD, 1); return curl_easy_setopt(connection, CURLOPT_UPLOAD, 1);
case REQUEST_TYPE_DELETE: case REQUEST_TYPE_DELETE:
// TODO break; // TODO
break;
case REQUEST_TYPE_HEAD: case REQUEST_TYPE_HEAD:
return curl_easy_setopt(connection, CURLOPT_NOBODY, 1); return curl_easy_setopt(connection, CURLOPT_NOBODY, 1);
} }
@ -90,7 +89,7 @@ void MakeRequest(HttpContext* context) {
{ {
std::lock_guard<std::mutex> lock(context->mutex); std::lock_guard<std::mutex> lock(context->mutex);
if (context->should_quit) if (context->cancel_request)
break; break;
} }
@ -127,7 +126,7 @@ void Init() {
void ClearInstance() { void ClearInstance() {
for (auto& pair : context_map) { for (auto& pair : context_map) {
pair.second->should_quit = true; pair.second->cancel_request = true;
if (pair.second->req_thread != nullptr) if (pair.second->req_thread != nullptr)
pair.second->req_thread->join(); pair.second->req_thread->join();
} }

View File

@ -8,6 +8,7 @@
#include <mutex> #include <mutex>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <string>
#include <unordered_map> #include <unordered_map>
#include "core/hle/result.h" #include "core/hle/result.h"
@ -19,6 +20,7 @@ namespace HTTP {
typedef u32 ContextHandle; typedef u32 ContextHandle;
/// HTTP operation that will be performed by the request (API-exposed).
enum RequestType : u32 { enum RequestType : u32 {
REQUEST_TYPE_NONE = 0, REQUEST_TYPE_NONE = 0,
REQUEST_TYPE_GET = 1, REQUEST_TYPE_GET = 1,
@ -30,28 +32,36 @@ enum RequestType : u32 {
REQUEST_TYPE_PUT_ = 7 REQUEST_TYPE_PUT_ = 7
}; };
/// Current state of the HTTP request (API-exposed).
enum RequestState : u32 { enum RequestState : u32 {
REQUEST_STATE_DEFAULT, // TODO
REQUEST_STATE_IN_PROGRESS = 5, REQUEST_STATE_IN_PROGRESS = 5,
REQUEST_STATE_READY = 8, REQUEST_STATE_READY = 8,
}; };
/** A helper struct that contains all the required information for a HTTP request.
* This struct, as it can be accessed by multiple threads, contains a mutex that
* must be locked whenever any of the struct's members are being accessed. This is
* to prevent any possible race conditions.
*/
struct HttpContext { struct HttpContext {
std::mutex mutex; std::mutex mutex;
bool should_quit;
RequestState state; //--- Ongoing request management
RequestState state; //< API-exposed current state of the HTTP request
std::unique_ptr<std::thread> req_thread; std::unique_ptr<std::thread> req_thread;
bool cancel_request; //< True if the request's thread should be canceled ASAP
std::string url; //--- Request data
RequestType req_type; std::string url; //< URL to the target server.
curl_slist* request_hdrs; RequestType req_type; //< Type of request that will be performed
curl_slist* request_hdrs; //< Buffer for request headers to be sent to the server.
std::vector<u8> response_hdrs; //--- Response data
std::vector<u8> response_data; std::vector<u8> response_hdrs; //< Buffer for response headers returned by the server.
long response_code; std::vector<u8> response_data; //< Buffer for response body returned by the server.
double content_length; long response_code; //< The three-digit HTTP response code returned by the server.
double downloaded_size; double content_length; //< The total size in bytes that will be downloaded this request.
double downloaded_size; //< The amount in bytes that has been downloaded so far.
~HttpContext(); ~HttpContext();
}; };
@ -59,7 +69,14 @@ struct HttpContext {
extern std::unordered_map<ContextHandle, std::unique_ptr<HttpContext>> context_map; extern std::unordered_map<ContextHandle, std::unique_ptr<HttpContext>> context_map;
extern ContextHandle next_handle; extern ContextHandle next_handle;
/** Makes an HTTP request using libcurl. Ideally called as part of a new thread.
* @param context A pointer to the HttpContext that will be used by this request. This pointer must remain valid.
*/
void MakeRequest(HttpContext* context); void MakeRequest(HttpContext* context);
/** Appends a name-value pair to a curl_slist*
* @param hdr_list A reference to the curl_slist*
*/
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);
/// Initialize the HTTP service /// Initialize the HTTP service

View File

@ -29,9 +29,7 @@ static void CreateContext(Service::Interface* self) {
char* url_ptr = reinterpret_cast<char*>(Memory::GetPointer(cmd_buff[4])); char* url_ptr = reinterpret_cast<char*>(Memory::GetPointer(cmd_buff[4]));
LOG_DEBUG(Service, "request url=%s req_type=%u", url_ptr, req_type); LOG_DEBUG(Service, "request url=%s req_type=%u", url_ptr, req_type);
auto context = Common::make_unique<HttpContext>();
// TODO: give HttpContext a proper constructor
std::unique_ptr<HttpContext> context(new HttpContext{});
context->req_type = req_type; context->req_type = req_type;
context->url = std::string(url_ptr, url_len); context->url = std::string(url_ptr, url_len);
@ -53,7 +51,7 @@ static void CloseContext(Service::Interface* self) {
return; return;
} }
map_it->second->should_quit = true; map_it->second->cancel_request = true;
if (map_it->second->req_thread != nullptr) if (map_it->second->req_thread != nullptr)
map_it->second->req_thread->join(); map_it->second->req_thread->join();
@ -72,7 +70,7 @@ static void CancelConnection(Service::Interface* self) {
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;
} }
map_it->second->should_quit = true; map_it->second->cancel_request = true;
cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[1] = RESULT_SUCCESS.raw;
} }