Skip to content

Commit

Permalink
Add static method for HTTPClient's query_string_from_dict
Browse files Browse the repository at this point in the history
  • Loading branch information
Mickeon committed Feb 27, 2024
1 parent a586e86 commit dcde01e
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 10 deletions.
7 changes: 6 additions & 1 deletion core/io/http_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Error HTTPClient::_request(Method p_method, const String &p_url, const Vector<St
return request(p_method, p_url, p_headers, size > 0 ? (const uint8_t *)body_utf8.get_data() : nullptr, size);
}

String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
String HTTPClient::query_string_from(const Dictionary &p_dict) {
String query = "";
Array keys = p_dict.keys();
for (int i = 0; i < keys.size(); ++i) {
Expand Down Expand Up @@ -97,6 +97,10 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
return query.substr(1);
}

String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
return HTTPClient::query_string_from(p_dict);
}

Error HTTPClient::verify_headers(const Vector<String> &p_headers) {
for (int i = 0; i < p_headers.size(); i++) {
String sanitized = p_headers[i].strip_edges();
Expand Down Expand Up @@ -166,6 +170,7 @@ void HTTPClient::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPClient::set_https_proxy);

ClassDB::bind_method(D_METHOD("query_string_from_dict", "fields"), &HTTPClient::query_string_from_dict);
ClassDB::bind_static_method("HTTPClient", D_METHOD("query_string_from", "fields"), &HTTPClient::query_string_from);

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_mode_enabled"), "set_blocking_mode", "is_blocking_mode_enabled");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "connection", PROPERTY_HINT_RESOURCE_TYPE, "StreamPeer", PROPERTY_USAGE_NONE), "set_connection", "get_connection");
Expand Down
1 change: 1 addition & 0 deletions core/io/http_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class HTTPClient : public RefCounted {
public:
static HTTPClient *create();

static String query_string_from(const Dictionary &p_dict);
String query_string_from_dict(const Dictionary &p_dict);
Error verify_headers(const Vector<String> &p_headers);

Expand Down
17 changes: 12 additions & 5 deletions doc/classes/HTTPClient.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,28 +93,28 @@
This needs to be called in order to have any request processed. Check results with [method get_status].
</description>
</method>
<method name="query_string_from_dict">
<method name="query_string_from" qualifiers="static">
<return type="String" />
<param index="0" name="fields" type="Dictionary" />
<description>
Generates a GET/POST application/x-www-form-urlencoded style query string from a provided dictionary, e.g.:
[codeblocks]
[gdscript]
var fields = {"username": "user", "password": "pass"}
var query_string = http_client.query_string_from_dict(fields)
var query_string = HTTPClient.query_string_from_dict(fields)
# Returns "username=user&amp;password=pass"
[/gdscript]
[csharp]
var fields = new Godot.Collections.Dictionary { { "username", "user" }, { "password", "pass" } };
string queryString = httpClient.QueryStringFromDict(fields);
string queryString = HTTPClient.QueryStringFromDict(fields);
// Returns "username=user&amp;password=pass"
[/csharp]
[/codeblocks]
Furthermore, if a key has a [code]null[/code] value, only the key itself is added, without equal sign and value. If the value is an array, for each value in it a pair with the same key is added.
[codeblocks]
[gdscript]
var fields = {"single": 123, "not_valued": null, "multiple": [22, 33, 44]}
var query_string = http_client.query_string_from_dict(fields)
var query_string = HTTPClient.query_string_from_dict(fields)
# Returns "single=123&amp;not_valued&amp;multiple=22&amp;multiple=33&amp;multiple=44"
[/gdscript]
[csharp]
Expand All @@ -124,12 +124,19 @@
{ "notValued", default },
{ "multiple", new Godot.Collections.Array { 22, 33, 44 } },
};
string queryString = httpClient.QueryStringFromDict(fields);
string queryString = HTTPClient.QueryStringFromDict(fields);
// Returns "single=123&amp;not_valued&amp;multiple=22&amp;multiple=33&amp;multiple=44"
[/csharp]
[/codeblocks]
</description>
</method>
<method name="query_string_from_dict" deprecated="Use the static method [method query_string_from] instead">
<return type="String" />
<param index="0" name="fields" type="Dictionary" />
<description>
Generates a GET/POST application/x-www-form-urlencoded style query string from a provided dictionary.
</description>
</method>
<method name="read_response_body_chunk">
<return type="PackedByteArray" />
<description>
Expand Down
7 changes: 3 additions & 4 deletions tests/core/io/test_http_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,13 @@ TEST_CASE("[HTTPClient] Instantiation") {
}

TEST_CASE("[HTTPClient] query_string_from_dict") {
Ref<HTTPClient> client = HTTPClient::create();
Dictionary empty_dict;
String empty_query = client->query_string_from_dict(empty_dict);
String empty_query = HTTPClient::query_string_from(empty_dict);
CHECK_MESSAGE(empty_query.is_empty(), "A empty dictionary should return a empty string");

Dictionary dict1;
dict1["key"] = "value";
String single_key = client->query_string_from_dict(dict1);
String single_key = HTTPClient::query_string_from(dict1);
CHECK_MESSAGE(single_key == "key=value", "The query should return key=value for every string in the dictionary");

// Check Dictionary with multiple values of different types.
Expand All @@ -63,7 +62,7 @@ TEST_CASE("[HTTPClient] query_string_from_dict") {
values.push_back(3);
dict2["key3"] = values;
dict2["key4"] = Variant();
String multiple_keys = client->query_string_from_dict(dict2);
String multiple_keys = HTTPClient::query_string_from(dict2);
CHECK_MESSAGE(multiple_keys == "key1=value&key2=123&key3=1&key3=2&key3=3&key4",
"The query should return key=value for every string in the dictionary. Pairs should be separated by &, arrays should be have a query for every element, and variants should have empty values");
}
Expand Down

0 comments on commit dcde01e

Please sign in to comment.