diff options
-rw-r--r-- | core/io/http_client.cpp | 97 | ||||
-rw-r--r-- | core/io/http_client.h | 6 | ||||
-rw-r--r-- | platform/javascript/http_client.h.inc | 1 | ||||
-rw-r--r-- | platform/javascript/http_client_javascript.cpp | 17 | ||||
-rw-r--r-- | scene/main/http_request.cpp | 3 |
5 files changed, 28 insertions, 96 deletions
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 78f04e57d3..859f1ef8fb 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -133,7 +133,7 @@ static bool _check_request_url(HTTPClient::Method p_method, const String &p_url) } } -Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) { +Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) { ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!_check_request_url(p_method, p_url), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); @@ -141,7 +141,7 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n"; bool add_host = true; - bool add_clen = p_body.size() > 0; + bool add_clen = p_body_size > 0; bool add_uagent = true; bool add_accept = true; for (int i = 0; i < p_headers.size(); i++) { @@ -168,7 +168,7 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector } } if (add_clen) { - request += "Content-Length: " + itos(p_body.size()) + "\r\n"; + request += "Content-Length: " + itos(p_body_size) + "\r\n"; // Should it add utf8 encoding? } if (add_uagent) { @@ -181,80 +181,15 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector CharString cs = request.utf8(); Vector<uint8_t> data; - data.resize(cs.length()); - { - uint8_t *data_write = data.ptrw(); - for (int i = 0; i < cs.length(); i++) { - data_write[i] = cs[i]; - } - } - - data.append_array(p_body); - - const uint8_t *r = data.ptr(); - Error err = connection->put_data(&r[0], data.size()); - - if (err) { - close(); - status = STATUS_CONNECTION_ERROR; - return err; + data.resize(cs.length() + p_body_size); + memcpy(data.ptrw(), cs.get_data(), cs.length()); + if (p_body_size > 0) { + memcpy(data.ptrw() + cs.length(), p_body, p_body_size); } - status = STATUS_REQUESTING; - head_request = p_method == METHOD_HEAD; - - return OK; -} - -Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) { - ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(!_check_request_url(p_method, p_url), ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA); - - String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n"; - bool add_host = true; - bool add_uagent = true; - bool add_accept = true; - bool add_clen = p_body.length() > 0; - for (int i = 0; i < p_headers.size(); i++) { - request += p_headers[i] + "\r\n"; - if (add_host && p_headers[i].findn("Host:") == 0) { - add_host = false; - } - if (add_clen && p_headers[i].findn("Content-Length:") == 0) { - add_clen = false; - } - if (add_uagent && p_headers[i].findn("User-Agent:") == 0) { - add_uagent = false; - } - if (add_accept && p_headers[i].findn("Accept:") == 0) { - add_accept = false; - } - } - if (add_host) { - if ((ssl && conn_port == PORT_HTTPS) || (!ssl && conn_port == PORT_HTTP)) { - // Don't append the standard ports - request += "Host: " + conn_host + "\r\n"; - } else { - request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; - } - } - if (add_clen) { - request += "Content-Length: " + itos(p_body.utf8().length()) + "\r\n"; - // Should it add utf8 encoding? - } - if (add_uagent) { - request += "User-Agent: GodotEngine/" + String(VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n"; - } - if (add_accept) { - request += "Accept: */*\r\n"; - } - request += "\r\n"; - request += p_body; + // TODO Implement non-blocking requests. + Error err = connection->put_data(data.ptr(), data.size()); - CharString cs = request.utf8(); - Error err = connection->put_data((const uint8_t *)cs.ptr(), cs.length()); if (err) { close(); status = STATUS_CONNECTION_ERROR; @@ -737,6 +672,16 @@ HTTPClient::~HTTPClient() {} #endif // #ifndef JAVASCRIPT_ENABLED +Error HTTPClient::_request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) { + int size = p_body.size(); + return request(p_method, p_url, p_headers, size > 0 ? p_body.ptr() : nullptr, size); +} + +Error HTTPClient::_request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) { + int size = p_body.length(); + return request(p_method, p_url, p_headers, size > 0 ? (const uint8_t *)p_body.utf8().get_data() : nullptr, size); +} + String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { String query = ""; Array keys = p_dict.keys(); @@ -802,8 +747,8 @@ void HTTPClient::_bind_methods() { ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port", "use_ssl", "verify_host"), &HTTPClient::connect_to_host, DEFVAL(-1), DEFVAL(false), DEFVAL(true)); ClassDB::bind_method(D_METHOD("set_connection", "connection"), &HTTPClient::set_connection); ClassDB::bind_method(D_METHOD("get_connection"), &HTTPClient::get_connection); - ClassDB::bind_method(D_METHOD("request_raw", "method", "url", "headers", "body"), &HTTPClient::request_raw); - ClassDB::bind_method(D_METHOD("request", "method", "url", "headers", "body"), &HTTPClient::request, DEFVAL(String())); + ClassDB::bind_method(D_METHOD("request_raw", "method", "url", "headers", "body"), &HTTPClient::_request_raw); + ClassDB::bind_method(D_METHOD("request", "method", "url", "headers", "body"), &HTTPClient::_request, DEFVAL(String())); ClassDB::bind_method(D_METHOD("close"), &HTTPClient::close); ClassDB::bind_method(D_METHOD("has_response"), &HTTPClient::has_response); diff --git a/core/io/http_client.h b/core/io/http_client.h index f70999836f..5d44613149 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -192,14 +192,16 @@ private: static void _bind_methods(); + Error _request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body); + Error _request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body = String()); + public: Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true); void set_connection(const Ref<StreamPeer> &p_connection); Ref<StreamPeer> get_connection() const; - Error request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body); - Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body = String()); + Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size); void close(); diff --git a/platform/javascript/http_client.h.inc b/platform/javascript/http_client.h.inc index 6544d41c98..316bab7ea4 100644 --- a/platform/javascript/http_client.h.inc +++ b/platform/javascript/http_client.h.inc @@ -30,7 +30,6 @@ // HTTPClient's additional private members in the javascript platform -Error make_request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len); static void _parse_headers(int p_len, const char **p_headers, void *p_ref); int js_id = 0; diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index a6cf4b0eb8..1443197e33 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -105,7 +105,7 @@ Ref<StreamPeer> HTTPClient::get_connection() const { ERR_FAIL_V_MSG(REF(), "Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform."); } -Error HTTPClient::make_request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len) { +Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len) { ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE, "HTTP methods TRACE and CONNECT are not supported for the HTML5 platform."); ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); @@ -128,21 +128,6 @@ Error HTTPClient::make_request(Method p_method, const String &p_url, const Vecto return OK; } -Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) { - if (p_body.is_empty()) { - return make_request(p_method, p_url, p_headers, nullptr, 0); - } - return make_request(p_method, p_url, p_headers, p_body.ptr(), p_body.size()); -} - -Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) { - if (p_body.is_empty()) { - return make_request(p_method, p_url, p_headers, nullptr, 0); - } - const CharString cs = p_body.utf8(); - return make_request(p_method, p_url, p_headers, (const uint8_t *)cs.get_data(), cs.size() - 1); -} - void HTTPClient::close() { host = ""; port = -1; diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index f3c7d128ba..43d7b7355c 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -322,7 +322,8 @@ bool HTTPRequest::_update_connection() { } else { // Did not request yet, do request - Error err = client->request_raw(method, request_string, headers, request_data); + int size = request_data.size(); + Error err = client->request(method, request_string, headers, size > 0 ? request_data.ptr() : nullptr, size); if (err != OK) { call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray()); return true; |