mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:17:34 +00:00
WebServer: Add Content-Length header to HTTP responses
This makes the browser know how much data it should expect.
This commit is contained in:
parent
b6f358689c
commit
c1ca009939
2 changed files with 29 additions and 23 deletions
|
@ -164,11 +164,11 @@ ErrorOr<bool> Client::handle_request(ReadonlyBytes raw_request)
|
||||||
|
|
||||||
Core::InputFileStream stream { file };
|
Core::InputFileStream stream { file };
|
||||||
|
|
||||||
TRY(send_response(stream, request, Core::guess_mime_type_based_on_filename(real_path)));
|
TRY(send_response(stream, request, { .type = Core::guess_mime_type_based_on_filename(real_path), .length = TRY(Core::File::size(real_path)) }));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> Client::send_response(InputStream& response, HTTP::HttpRequest const& request, String const& content_type)
|
ErrorOr<void> Client::send_response(InputStream& response, HTTP::HttpRequest const& request, ContentInfo content_info)
|
||||||
{
|
{
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
builder.append("HTTP/1.0 200 OK\r\n");
|
builder.append("HTTP/1.0 200 OK\r\n");
|
||||||
|
@ -176,9 +176,8 @@ ErrorOr<void> Client::send_response(InputStream& response, HTTP::HttpRequest con
|
||||||
builder.append("X-Frame-Options: SAMEORIGIN\r\n");
|
builder.append("X-Frame-Options: SAMEORIGIN\r\n");
|
||||||
builder.append("X-Content-Type-Options: nosniff\r\n");
|
builder.append("X-Content-Type-Options: nosniff\r\n");
|
||||||
builder.append("Pragma: no-cache\r\n");
|
builder.append("Pragma: no-cache\r\n");
|
||||||
builder.append("Content-Type: ");
|
builder.appendff("Content-Type: {}\r\n", content_info.type);
|
||||||
builder.append(content_type);
|
builder.appendff("Content-Length: {}\r\n", content_info.length);
|
||||||
builder.append("\r\n");
|
|
||||||
builder.append("\r\n");
|
builder.append("\r\n");
|
||||||
|
|
||||||
auto builder_contents = builder.to_byte_buffer();
|
auto builder_contents = builder.to_byte_buffer();
|
||||||
|
@ -326,31 +325,33 @@ ErrorOr<void> Client::handle_directory_listing(String const& requested_path, Str
|
||||||
|
|
||||||
auto response = builder.to_string();
|
auto response = builder.to_string();
|
||||||
InputMemoryStream stream { response.bytes() };
|
InputMemoryStream stream { response.bytes() };
|
||||||
return send_response(stream, request, "text/html");
|
return send_response(stream, request, { .type = "text/html", .length = response.length() });
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> Client::send_error_response(unsigned code, HTTP::HttpRequest const& request, Vector<String> const& headers)
|
ErrorOr<void> Client::send_error_response(unsigned code, HTTP::HttpRequest const& request, Vector<String> const& headers)
|
||||||
{
|
{
|
||||||
auto reason_phrase = HTTP::HttpResponse::reason_phrase_for_code(code);
|
auto reason_phrase = HTTP::HttpResponse::reason_phrase_for_code(code);
|
||||||
StringBuilder builder;
|
|
||||||
builder.appendff("HTTP/1.0 {} ", code);
|
StringBuilder content_builder;
|
||||||
builder.append(reason_phrase);
|
content_builder.append("<!DOCTYPE html><html><body><h1>");
|
||||||
builder.append("\r\n");
|
content_builder.appendff("{} ", code);
|
||||||
|
content_builder.append(reason_phrase);
|
||||||
|
content_builder.append("</h1></body></html>");
|
||||||
|
|
||||||
|
StringBuilder header_builder;
|
||||||
|
header_builder.appendff("HTTP/1.0 {} ", code);
|
||||||
|
header_builder.append(reason_phrase);
|
||||||
|
header_builder.append("\r\n");
|
||||||
|
|
||||||
for (auto& header : headers) {
|
for (auto& header : headers) {
|
||||||
builder.append(header);
|
header_builder.append(header);
|
||||||
builder.append("\r\n");
|
header_builder.append("\r\n");
|
||||||
}
|
}
|
||||||
builder.append("Content-Type: text/html; charset=UTF-8\r\n");
|
header_builder.append("Content-Type: text/html; charset=UTF-8\r\n");
|
||||||
|
header_builder.appendff("Content-Length: {}\r\n", content_builder.length());
|
||||||
builder.append("\r\n");
|
header_builder.append("\r\n");
|
||||||
builder.append("<!DOCTYPE html><html><body><h1>");
|
TRY(m_socket->write(header_builder.to_byte_buffer()));
|
||||||
builder.appendff("{} ", code);
|
TRY(m_socket->write(content_builder.to_byte_buffer()));
|
||||||
builder.append(reason_phrase);
|
|
||||||
builder.append("</h1></body></html>");
|
|
||||||
|
|
||||||
auto builder_contents = builder.to_byte_buffer();
|
|
||||||
TRY(m_socket->write(builder_contents));
|
|
||||||
|
|
||||||
log_response(code, request);
|
log_response(code, request);
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -22,8 +22,13 @@ public:
|
||||||
private:
|
private:
|
||||||
Client(NonnullOwnPtr<Core::Stream::BufferedTCPSocket>, Core::Object* parent);
|
Client(NonnullOwnPtr<Core::Stream::BufferedTCPSocket>, Core::Object* parent);
|
||||||
|
|
||||||
|
struct ContentInfo {
|
||||||
|
String type;
|
||||||
|
size_t length {};
|
||||||
|
};
|
||||||
|
|
||||||
ErrorOr<bool> handle_request(ReadonlyBytes);
|
ErrorOr<bool> handle_request(ReadonlyBytes);
|
||||||
ErrorOr<void> send_response(InputStream&, HTTP::HttpRequest const&, String const& content_type);
|
ErrorOr<void> send_response(InputStream&, HTTP::HttpRequest const&, ContentInfo);
|
||||||
ErrorOr<void> send_redirect(StringView redirect, HTTP::HttpRequest const&);
|
ErrorOr<void> send_redirect(StringView redirect, HTTP::HttpRequest const&);
|
||||||
ErrorOr<void> send_error_response(unsigned code, HTTP::HttpRequest const&, Vector<String> const& headers = {});
|
ErrorOr<void> send_error_response(unsigned code, HTTP::HttpRequest const&, Vector<String> const& headers = {});
|
||||||
void die();
|
void die();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue