forked from LeenkxTeam/LNXRNT
Here comes he RunT!
This commit is contained in:
235
Sources/httprequest.h
Normal file
235
Sources/httprequest.h
Normal file
@ -0,0 +1,235 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef WITH_NETWORKING
|
||||
|
||||
#include <v8.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WITH_SSL
|
||||
#ifndef _WIN32
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/crypto.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace HttpRequestWrapper {
|
||||
|
||||
enum ReadyState {
|
||||
UNSENT = 0,
|
||||
OPENED = 1,
|
||||
HEADERS_RECEIVED = 2,
|
||||
LOADING = 3,
|
||||
DONE = 4
|
||||
};
|
||||
|
||||
enum ResponseType {
|
||||
DEFAULT = 0,
|
||||
ARRAY_BUFFER = 1,
|
||||
BLOB = 2,
|
||||
DOCUMENT = 3,
|
||||
JSON = 4,
|
||||
TEXT = 5
|
||||
};
|
||||
|
||||
struct HttpResponse {
|
||||
int status;
|
||||
std::string statusText;
|
||||
std::map<std::string, std::string> headers;
|
||||
std::string responseText;
|
||||
std::string error;
|
||||
|
||||
HttpResponse() : status(0), statusText("") {}
|
||||
};
|
||||
|
||||
class HttpRequestClient {
|
||||
public:
|
||||
HttpRequestClient(v8::Isolate* isolate, v8::Global<v8::Context>* global_context);
|
||||
~HttpRequestClient();
|
||||
|
||||
void open(const std::string& method, const std::string& url, bool async = true);
|
||||
void setRequestHeader(const std::string& header, const std::string& value);
|
||||
void send(const std::string& data = "");
|
||||
void abort();
|
||||
std::string getAllResponseHeaders();
|
||||
std::string getResponseHeader(const std::string& header);
|
||||
|
||||
ReadyState getReadyState() const { return ready_state_; }
|
||||
int getStatus() const { return response_.status; }
|
||||
std::string getStatusText() const { return response_.statusText; }
|
||||
std::string getResponseText() const { return response_.responseText; }
|
||||
std::string getResponseURL() const { return url_; }
|
||||
ResponseType getResponseType() const { return response_type_; }
|
||||
int getTimeout() const { return timeout_; }
|
||||
bool getWithCredentials() const { return with_credentials_; }
|
||||
|
||||
void setTimeout(int timeout) { timeout_ = timeout; }
|
||||
void setResponseType(ResponseType type) { response_type_ = type; }
|
||||
void setWithCredentials(bool withCredentials) { with_credentials_ = withCredentials; }
|
||||
|
||||
void setOnReadyStateChange(v8::Local<v8::Function> callback);
|
||||
void setOnLoad(v8::Local<v8::Function> callback);
|
||||
void setOnError(v8::Local<v8::Function> callback);
|
||||
void setOnTimeout(v8::Local<v8::Function> callback);
|
||||
void setOnAbort(v8::Local<v8::Function> callback);
|
||||
void setOnProgress(v8::Local<v8::Function> callback);
|
||||
void setOnLoadStart(v8::Local<v8::Function> callback);
|
||||
void setOnLoadEnd(v8::Local<v8::Function> callback);
|
||||
|
||||
// from main thread
|
||||
void processEvents();
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
v8::Global<v8::Context>* global_context_;
|
||||
std::string method_;
|
||||
std::string url_;
|
||||
std::map<std::string, std::string> request_headers_;
|
||||
std::string request_data_;
|
||||
HttpResponse response_;
|
||||
ReadyState ready_state_;
|
||||
ResponseType response_type_;
|
||||
int timeout_;
|
||||
bool with_credentials_;
|
||||
bool async_;
|
||||
std::thread request_thread_;
|
||||
std::atomic<bool> should_abort_;
|
||||
|
||||
v8::Global<v8::Function> on_ready_state_change_;
|
||||
v8::Global<v8::Function> on_load_;
|
||||
v8::Global<v8::Function> on_error_;
|
||||
v8::Global<v8::Function> on_timeout_;
|
||||
v8::Global<v8::Function> on_abort_;
|
||||
v8::Global<v8::Function> on_progress_;
|
||||
v8::Global<v8::Function> on_load_start_;
|
||||
v8::Global<v8::Function> on_load_end_;
|
||||
|
||||
std::mutex state_mutex_;
|
||||
|
||||
public:
|
||||
std::atomic<bool> active_operation_{false};
|
||||
|
||||
private:
|
||||
// TODO: find real solution for duplicate done
|
||||
bool done_event_fired_{false};
|
||||
|
||||
#ifdef WITH_SSL
|
||||
#ifdef _WIN32
|
||||
void* ssl_cred_handle_;
|
||||
void* ssl_context_handle_;
|
||||
bool ssl_context_initialized_;
|
||||
int ssl_socket_;
|
||||
std::vector<char> ssl_buffer_;
|
||||
#else
|
||||
SSL_CTX* ssl_ctx_;
|
||||
SSL* ssl_;
|
||||
bool ssl_initialized_;
|
||||
#endif
|
||||
bool initSSL();
|
||||
void cleanupSSL();
|
||||
bool performSSLHandshake(int socket, const std::string& host);
|
||||
int sslRead(char* buffer, int length);
|
||||
int sslWrite(const char* buffer, int length);
|
||||
#endif
|
||||
|
||||
enum EventType {
|
||||
HTTP_READY_STATE_CHANGE = 100,
|
||||
HTTP_LOAD = 101,
|
||||
HTTP_ERROR = 102,
|
||||
HTTP_TIMEOUT = 103,
|
||||
HTTP_ABORT = 104,
|
||||
HTTP_PROGRESS = 105,
|
||||
HTTP_LOAD_START = 106,
|
||||
HTTP_LOAD_END = 107
|
||||
};
|
||||
|
||||
struct Event {
|
||||
EventType type;
|
||||
std::string data;
|
||||
int code;
|
||||
|
||||
Event(EventType t, const std::string& d = "", int c = 0)
|
||||
: type(t), data(d), code(c) {}
|
||||
};
|
||||
|
||||
std::queue<Event> event_queue_;
|
||||
std::mutex event_queue_mutex_;
|
||||
|
||||
// handle* called from background thread
|
||||
void handleReadyStateChange();
|
||||
void handleLoad();
|
||||
void handleError(const std::string& error);
|
||||
void handleTimeout();
|
||||
void handleAbort();
|
||||
void handleProgress();
|
||||
void handleLoadStart();
|
||||
void handleLoadEnd();
|
||||
|
||||
// process* called from main thread
|
||||
void processReadyStateChangeEvent();
|
||||
void processLoadEvent();
|
||||
void processErrorEvent(const std::string& error);
|
||||
void processTimeoutEvent();
|
||||
void processAbortEvent();
|
||||
void processProgressEvent();
|
||||
void processLoadStartEvent();
|
||||
void processLoadEndEvent();
|
||||
|
||||
void performRequest();
|
||||
void loadLocalFile(const std::string& path);
|
||||
void setReadyState(ReadyState state);
|
||||
void callReadyStateChangeCallback();
|
||||
void callCallback(v8::Global<v8::Function>& callback, int argc, v8::Local<v8::Value> argv[]);
|
||||
|
||||
bool parseUrl(const std::string& url, std::string& host, int& port, std::string& path, bool& is_https);
|
||||
std::string formatHttpRequest(const std::string& method, const std::string& path, const std::string& host, const std::string& data);
|
||||
void parseHttpResponse(const std::string& response);
|
||||
};
|
||||
|
||||
void initialize();
|
||||
void cleanup();
|
||||
|
||||
// process events from main thread
|
||||
void processEvents();
|
||||
|
||||
int createHttpRequest(v8::Isolate* isolate);
|
||||
|
||||
v8::Global<v8::Context>* getGlobalContext();
|
||||
}
|
||||
|
||||
// V8 binding functions called from main.cpp
|
||||
void runt_httprequest_create(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_open(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_send(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_abort(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_request_header(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_get_all_response_headers(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_get_response_header(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_get_ready_state(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_get_status(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_get_status_text(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_get_response_text(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_get_response_url(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_timeout(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_response_type(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_with_credentials(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_onreadystatechange(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_onload(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_onerror(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_ontimeout(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_onabort(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_onprogress(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_onloadstart(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void runt_httprequest_set_onloadend(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
void createXMLHttpRequestClass(v8::Isolate* isolate, v8::Local<v8::ObjectTemplate>& global);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user