Verify custom HTTP headers, fix off by one error

This commit is contained in:
Max Hilbrunner 2022-01-14 03:22:23 +01:00
parent 3a83872d26
commit 3ef5a97505
5 changed files with 25 additions and 3 deletions

View file

@ -96,6 +96,17 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
return query.substr(1); return query.substr(1);
} }
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();
ERR_FAIL_COND_V_MSG(sanitized.is_empty(), ERR_INVALID_PARAMETER, "Invalid HTTP header at index " + itos(i) + ": empty.");
ERR_FAIL_COND_V_MSG(sanitized.find(":") < 1, ERR_INVALID_PARAMETER,
"Invalid HTTP header at index " + itos(i) + ": String must contain header-value pair, delimited by ':', but was: " + p_headers[i]);
}
return OK;
}
Dictionary HTTPClient::_get_response_headers_as_dictionary() { Dictionary HTTPClient::_get_response_headers_as_dictionary() {
List<String> rh; List<String> rh;
get_response_headers(&rh); get_response_headers(&rh);

View file

@ -165,6 +165,7 @@ public:
static HTTPClient *create(); static HTTPClient *create();
String query_string_from_dict(const Dictionary &p_dict); String query_string_from_dict(const Dictionary &p_dict);
Error verify_headers(const Vector<String> &p_headers);
virtual Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) = 0; virtual Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) = 0;
virtual Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true) = 0; virtual Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true) = 0;

View file

@ -146,6 +146,11 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA); ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA);
Error err = verify_headers(p_headers);
if (err) {
return err;
}
String uri = p_url; String uri = p_url;
if (!ssl && http_proxy_port != -1) { if (!ssl && http_proxy_port != -1) {
uri = vformat("http://%s:%d%s", conn_host, conn_port, p_url); uri = vformat("http://%s:%d%s", conn_host, conn_port, p_url);

View file

@ -87,6 +87,11 @@ Error HTTPClientJavaScript::request(Method p_method, const String &p_url, const
ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED); ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
Error err = verify_headers(p_headers);
if (err) {
return err;
}
String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url; String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url;
Vector<CharString> keeper; Vector<CharString> keeper;
Vector<const char *> c_strings; Vector<const char *> c_strings;

View file

@ -86,9 +86,9 @@ String HTTPRequest::get_header_value(const PackedStringArray &p_headers, const S
String lowwer_case_header_name = p_header_name.to_lower(); String lowwer_case_header_name = p_header_name.to_lower();
for (int i = 0; i < p_headers.size(); i++) { for (int i = 0; i < p_headers.size(); i++) {
if (p_headers[i].find(":", 0) >= 0) { if (p_headers[i].find(":") > 0) {
Vector<String> parts = p_headers[i].split(":", false, 1); Vector<String> parts = p_headers[i].split(":", false, 1);
if (parts[0].strip_edges().to_lower() == lowwer_case_header_name) { if (parts.size() > 1 && parts[0].strip_edges().to_lower() == lowwer_case_header_name) {
value = parts[1].strip_edges(); value = parts[1].strip_edges();
break; break;
} }
@ -134,7 +134,7 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_cust
headers = p_custom_headers; headers = p_custom_headers;
if (accept_gzip) { if (accept_gzip) {
// If the user has specified a Accept-Encoding header, don't overwrite it. // If the user has specified an Accept-Encoding header, don't overwrite it.
if (!has_header(headers, "Accept-Encoding")) { if (!has_header(headers, "Accept-Encoding")) {
headers.push_back("Accept-Encoding: gzip, deflate"); headers.push_back("Accept-Encoding: gzip, deflate");
} }