mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-23 04:16:50 +01:00
Implemented custom response headers for WebServerRequest.
This commit is contained in:
parent
3244eab5c5
commit
b68bbd3bfb
@ -139,12 +139,19 @@ void HTTPServerConnection::update() {
|
|||||||
void HTTPServerConnection::send_redirect(Ref<WebServerRequest> request, const String &location, const HTTPServerEnums::HTTPStatusCode status_code) {
|
void HTTPServerConnection::send_redirect(Ref<WebServerRequest> request, const String &location, const HTTPServerEnums::HTTPStatusCode status_code) {
|
||||||
//String s = "HTTP/1.1 " + itos(static_cast<int>(status_code)) + " Found\r\n";
|
//String s = "HTTP/1.1 " + itos(static_cast<int>(status_code)) + " Found\r\n";
|
||||||
String s = "HTTP/1.1 " + HTTPServerEnums::get_status_code_header_string(status_code) + "\r\n";
|
String s = "HTTP/1.1 " + HTTPServerEnums::get_status_code_header_string(status_code) + "\r\n";
|
||||||
s += "Location: " + location + "\r\n";
|
|
||||||
|
|
||||||
if (has_more_messages()) {
|
HashMap<StringName, String> custom_headers = request->custom_response_headers_get();
|
||||||
s += "Connection: keep-alive\r\n";
|
|
||||||
} else {
|
if (!custom_headers.has("Location")) {
|
||||||
s += "Connection: close\r\n";
|
s += "Location: " + location + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!custom_headers.has("Connection")) {
|
||||||
|
if (has_more_messages()) {
|
||||||
|
s += "Connection: keep-alive\r\n";
|
||||||
|
} else {
|
||||||
|
s += "Connection: close\r\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
||||||
@ -159,6 +166,10 @@ void HTTPServerConnection::send_redirect(Ref<WebServerRequest> request, const St
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (HashMap<StringName, String>::Element *E = custom_headers.front(); E; E = E->next) {
|
||||||
|
s += String(E->key()) + ": " + E->value() + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
s += "\r\n";
|
s += "\r\n";
|
||||||
|
|
||||||
#if CONNECTION_RESPOSE_DEBUG
|
#if CONNECTION_RESPOSE_DEBUG
|
||||||
@ -172,14 +183,24 @@ void HTTPServerConnection::send_redirect(Ref<WebServerRequest> request, const St
|
|||||||
void HTTPServerConnection::send(Ref<WebServerRequest> request) {
|
void HTTPServerConnection::send(Ref<WebServerRequest> request) {
|
||||||
String body = request->get_compiled_body();
|
String body = request->get_compiled_body();
|
||||||
|
|
||||||
String s = "HTTP/1.1 " + HTTPServerEnums::get_status_code_header_string(request->get_status_code()) + "\r\n";
|
HashMap<StringName, String> custom_headers = request->custom_response_headers_get();
|
||||||
s += "Content-Length: " + itos(body.utf8_byte_length()) + "\r\n";
|
|
||||||
s += "Content-type: text/html\r\n";
|
|
||||||
|
|
||||||
if (has_more_messages()) {
|
String s = "HTTP/1.1 " + HTTPServerEnums::get_status_code_header_string(request->get_status_code()) + "\r\n";
|
||||||
s += "Connection: keep-alive\r\n";
|
|
||||||
} else {
|
if (!custom_headers.has("Content-Length")) {
|
||||||
s += "Connection: close\r\n";
|
s += "Content-Length: " + itos(body.utf8_byte_length()) + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!custom_headers.has("Content-type")) {
|
||||||
|
s += "Content-type: text/html\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!custom_headers.has("Connection")) {
|
||||||
|
if (has_more_messages()) {
|
||||||
|
s += "Connection: keep-alive\r\n";
|
||||||
|
} else {
|
||||||
|
s += "Connection: close\r\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
||||||
@ -194,6 +215,10 @@ void HTTPServerConnection::send(Ref<WebServerRequest> request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (HashMap<StringName, String>::Element *E = custom_headers.front(); E; E = E->next) {
|
||||||
|
s += String(E->key()) + ": " + E->value() + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
s += "\r\n";
|
s += "\r\n";
|
||||||
s += body;
|
s += body;
|
||||||
|
|
||||||
@ -205,13 +230,17 @@ void HTTPServerConnection::send(Ref<WebServerRequest> request) {
|
|||||||
peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1);
|
peer->put_data((const uint8_t *)cs.get_data(), cs.size() - 1);
|
||||||
}
|
}
|
||||||
void HTTPServerConnection::send_file(Ref<WebServerRequest> request, const String &p_file_path) {
|
void HTTPServerConnection::send_file(Ref<WebServerRequest> request, const String &p_file_path) {
|
||||||
|
HashMap<StringName, String> custom_headers = request->custom_response_headers_get();
|
||||||
|
|
||||||
if (!FileAccess::exists(p_file_path)) {
|
if (!FileAccess::exists(p_file_path)) {
|
||||||
String s = "HTTP/1.1 404 Not Found\r\n";
|
String s = "HTTP/1.1 404 Not Found\r\n";
|
||||||
|
|
||||||
if (has_more_messages()) {
|
if (!custom_headers.has("Connection")) {
|
||||||
s += "Connection: keep-alive\r\n";
|
if (has_more_messages()) {
|
||||||
} else {
|
s += "Connection: keep-alive\r\n";
|
||||||
s += "Connection: close\r\n";
|
} else {
|
||||||
|
s += "Connection: close\r\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
||||||
@ -226,6 +255,10 @@ void HTTPServerConnection::send_file(Ref<WebServerRequest> request, const String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (HashMap<StringName, String>::Element *E = custom_headers.front(); E; E = E->next) {
|
||||||
|
s += String(E->key()) + ": " + E->value() + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
s += "\r\n";
|
s += "\r\n";
|
||||||
|
|
||||||
#if CONNECTION_RESPOSE_DEBUG
|
#if CONNECTION_RESPOSE_DEBUG
|
||||||
@ -237,26 +270,30 @@ void HTTPServerConnection::send_file(Ref<WebServerRequest> request, const String
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ctype;
|
|
||||||
String req_ext = p_file_path.get_extension();
|
|
||||||
|
|
||||||
if (_http_server->mimes.has(req_ext)) {
|
|
||||||
ctype = _http_server->mimes[req_ext];
|
|
||||||
} else {
|
|
||||||
ctype = "text/plain";
|
|
||||||
}
|
|
||||||
|
|
||||||
FileAccess *f = FileAccess::open(p_file_path, FileAccess::READ);
|
FileAccess *f = FileAccess::open(p_file_path, FileAccess::READ);
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
String s = "HTTP/1.1 200 OK\r\n";
|
String s = "HTTP/1.1 200 OK\r\n";
|
||||||
|
|
||||||
if (has_more_messages()) {
|
if (!custom_headers.has("Connection")) {
|
||||||
s += "Connection: keep-alive\r\n";
|
if (has_more_messages()) {
|
||||||
} else {
|
s += "Connection: keep-alive\r\n";
|
||||||
s += "Connection: close\r\n";
|
} else {
|
||||||
|
s += "Connection: close\r\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s += "Content-Type: " + ctype + "\r\n";
|
if (!custom_headers.has("Content-Type")) {
|
||||||
|
String ctype;
|
||||||
|
String req_ext = p_file_path.get_extension();
|
||||||
|
|
||||||
|
if (_http_server->mimes.has(req_ext)) {
|
||||||
|
ctype = _http_server->mimes[req_ext];
|
||||||
|
} else {
|
||||||
|
ctype = "text/plain";
|
||||||
|
}
|
||||||
|
|
||||||
|
s += "Content-Type: " + ctype + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
for (int i = 0; i < request->response_get_cookie_count(); ++i) {
|
||||||
Ref<WebServerCookie> cookie = request->response_get_cookie(i);
|
Ref<WebServerCookie> cookie = request->response_get_cookie(i);
|
||||||
@ -270,10 +307,10 @@ void HTTPServerConnection::send_file(Ref<WebServerRequest> request, const String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s += "Access-Control-Allow-Origin: *\r\n";
|
for (HashMap<StringName, String>::Element *E = custom_headers.front(); E; E = E->next) {
|
||||||
s += "Cross-Origin-Opener-Policy: same-origin\r\n";
|
s += String(E->key()) + ": " + E->value() + "\r\n";
|
||||||
s += "Cross-Origin-Embedder-Policy: require-corp\r\n";
|
}
|
||||||
s += "Cache-Control: no-store, max-age=0\r\n";
|
|
||||||
s += "\r\n";
|
s += "\r\n";
|
||||||
|
|
||||||
#if CONNECTION_RESPOSE_DEBUG
|
#if CONNECTION_RESPOSE_DEBUG
|
||||||
|
@ -48,6 +48,34 @@
|
|||||||
Takes the head, body and footer properties, and merges them into the [code]compiled_body[/code] property. It adds an html5 type declaration, then the opening [code]html[/code] tag, then the contents of the [code]head[/code] property to the [code]head[/code] section of the response, and then the contents of the [code]body[/code] then footer property into the [code]body[/code] section of the response, then it closes the main [code]html[/code] tag.
|
Takes the head, body and footer properties, and merges them into the [code]compiled_body[/code] property. It adds an html5 type declaration, then the opening [code]html[/code] tag, then the contents of the [code]head[/code] property to the [code]head[/code] section of the response, and then the contents of the [code]body[/code] then footer property into the [code]body[/code] section of the response, then it closes the main [code]html[/code] tag.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="custom_response_header_get">
|
||||||
|
<return type="String" />
|
||||||
|
<argument index="0" name="key" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Returns a custom HTTP response header or an empty String if it's not set.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="custom_response_header_has">
|
||||||
|
<return type="bool" />
|
||||||
|
<argument index="0" name="key" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Returns whether a custom HTTP response header is set.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="custom_response_header_set">
|
||||||
|
<return type="void" />
|
||||||
|
<argument index="0" name="key" type="StringName" />
|
||||||
|
<argument index="1" name="value" type="String" />
|
||||||
|
<description>
|
||||||
|
Set a custom HTTP response header that will be sent to the client.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="custom_response_headers_get">
|
||||||
|
<return type="Dictionary" />
|
||||||
|
<description>
|
||||||
|
Returns all the custom response headers that were previously set.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="get_cookie">
|
<method name="get_cookie">
|
||||||
<return type="String" />
|
<return type="String" />
|
||||||
<argument index="0" name="key" type="String" />
|
<argument index="0" name="key" type="String" />
|
||||||
@ -394,6 +422,10 @@
|
|||||||
<member name="connection_closed" type="bool" setter="set_connection_closed" getter="get_connection_closed" default="false">
|
<member name="connection_closed" type="bool" setter="set_connection_closed" getter="get_connection_closed" default="false">
|
||||||
The server might set this to true if the connection got closed while handling the request. It's not yet used.
|
The server might set this to true if the connection got closed while handling the request. It's not yet used.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="content_type" type="String" setter="set_content_type" getter="get_content_type" default="""">
|
||||||
|
A shorthand property to set the Content-Type HTTP header.
|
||||||
|
Equivalent to [code]custom_response_header_set("Content-Type", content_type)[/code] and [code]custom_response_header_get("Content-Type")[/code].
|
||||||
|
</member>
|
||||||
<member name="footer" type="String" setter="set_footer" getter="get_footer" default="""">
|
<member name="footer" type="String" setter="set_footer" getter="get_footer" default="""">
|
||||||
When you call [code]compile_body()[/code] or [code]compile_and_send_body()[/code], the contents of this property will end up in the bottom of the [code]body[/code] portion of the resulting HTML.
|
When you call [code]compile_body()[/code] or [code]compile_and_send_body()[/code], the contents of this property will end up in the bottom of the [code]body[/code] portion of the resulting HTML.
|
||||||
</member>
|
</member>
|
||||||
|
@ -176,6 +176,41 @@ void WebServerRequest::response_remove_cookie_simple(const String &key) {
|
|||||||
_cookies.push_back(cookie);
|
_cookies.push_back(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebServerRequest::custom_response_header_set(const StringName &key, const String &value) {
|
||||||
|
_custom_response_headers[key] = value;
|
||||||
|
}
|
||||||
|
String WebServerRequest::custom_response_header_get(const StringName &key) {
|
||||||
|
String *e = _custom_response_headers.getptr(key);
|
||||||
|
|
||||||
|
if (!e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return *e;
|
||||||
|
}
|
||||||
|
bool WebServerRequest::custom_response_header_has(const StringName &key) {
|
||||||
|
return _custom_response_headers.has(key);
|
||||||
|
}
|
||||||
|
HashMap<StringName, String> WebServerRequest::custom_response_headers_get() {
|
||||||
|
return _custom_response_headers;
|
||||||
|
}
|
||||||
|
Dictionary WebServerRequest::custom_response_headers_get_bind() {
|
||||||
|
Dictionary ret;
|
||||||
|
|
||||||
|
for (HashMap<StringName, String>::Element *E = _custom_response_headers.front(); E; E = E->next) {
|
||||||
|
ret[E->key()] = E->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
String WebServerRequest::get_content_type() {
|
||||||
|
return custom_response_header_get("Content-Type");
|
||||||
|
}
|
||||||
|
void WebServerRequest::set_content_type(const String &content_type) {
|
||||||
|
custom_response_header_set("Content-Type", content_type);
|
||||||
|
}
|
||||||
|
|
||||||
HTTPServerEnums::HTTPMethod WebServerRequest::get_method() const {
|
HTTPServerEnums::HTTPMethod WebServerRequest::get_method() const {
|
||||||
return HTTPServerEnums::HTTP_METHOD_GET;
|
return HTTPServerEnums::HTTP_METHOD_GET;
|
||||||
}
|
}
|
||||||
@ -550,6 +585,15 @@ void WebServerRequest::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("response_remove_cookie", "index"), &WebServerRequest::response_remove_cookie);
|
ClassDB::bind_method(D_METHOD("response_remove_cookie", "index"), &WebServerRequest::response_remove_cookie);
|
||||||
ClassDB::bind_method(D_METHOD("response_remove_cookie_simple", "key"), &WebServerRequest::response_remove_cookie_simple);
|
ClassDB::bind_method(D_METHOD("response_remove_cookie_simple", "key"), &WebServerRequest::response_remove_cookie_simple);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("custom_response_header_set", "key", "value"), &WebServerRequest::custom_response_header_set);
|
||||||
|
ClassDB::bind_method(D_METHOD("custom_response_header_get", "key"), &WebServerRequest::custom_response_header_get);
|
||||||
|
ClassDB::bind_method(D_METHOD("custom_response_header_has", "key"), &WebServerRequest::custom_response_header_has);
|
||||||
|
ClassDB::bind_method(D_METHOD("custom_response_headers_get"), &WebServerRequest::custom_response_headers_get_bind);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_content_type"), &WebServerRequest::get_content_type);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_content_type", "content_type"), &WebServerRequest::set_content_type);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::STRING, "content_type"), "set_content_type", "get_content_type");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_method"), &WebServerRequest::get_method);
|
ClassDB::bind_method(D_METHOD("get_method"), &WebServerRequest::get_method);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("parse_files"), &WebServerRequest::parse_files);
|
ClassDB::bind_method(D_METHOD("parse_files"), &WebServerRequest::parse_files);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "core/variant/dictionary.h"
|
#include "core/variant/dictionary.h"
|
||||||
#include "core/string/ustring.h"
|
#include "core/string/ustring.h"
|
||||||
#include "core/containers/vector.h"
|
#include "core/containers/vector.h"
|
||||||
|
#include "core/containers/hash_map.h"
|
||||||
|
|
||||||
#include "core/object/object.h"
|
#include "core/object/object.h"
|
||||||
#include "core/object/reference.h"
|
#include "core/object/reference.h"
|
||||||
@ -67,6 +68,15 @@ public:
|
|||||||
void response_remove_cookie(const int index);
|
void response_remove_cookie(const int index);
|
||||||
void response_remove_cookie_simple(const String &key);
|
void response_remove_cookie_simple(const String &key);
|
||||||
|
|
||||||
|
void custom_response_header_set(const StringName &key, const String& value);
|
||||||
|
String custom_response_header_get(const StringName &key);
|
||||||
|
bool custom_response_header_has(const StringName &key);
|
||||||
|
HashMap<StringName, String> custom_response_headers_get();
|
||||||
|
Dictionary custom_response_headers_get_bind();
|
||||||
|
|
||||||
|
String get_content_type();
|
||||||
|
void set_content_type(const String &content_type);
|
||||||
|
|
||||||
virtual HTTPServerEnums::HTTPMethod get_method() const;
|
virtual HTTPServerEnums::HTTPMethod get_method() const;
|
||||||
|
|
||||||
virtual void parse_files();
|
virtual void parse_files();
|
||||||
@ -143,6 +153,8 @@ protected:
|
|||||||
int _path_stack_pointer;
|
int _path_stack_pointer;
|
||||||
Vector<Ref<WebServerCookie>> _cookies;
|
Vector<Ref<WebServerCookie>> _cookies;
|
||||||
|
|
||||||
|
HashMap<StringName, String> _custom_response_headers;
|
||||||
|
|
||||||
Ref<WebPermission> _active_permission;
|
Ref<WebPermission> _active_permission;
|
||||||
int _permissions;
|
int _permissions;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user