1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 10:27:36 +00:00

Services: Rename ProtocolServer to RequestServer

The current ProtocolServer was really only used for requests, and with
the recent introduction of the WebSocket service, long-lasting
connections with another server are not part of it. To better reflect
this, this commit renames it to RequestServer.

This commit also changes the existing 'protocol' portal to 'request',
the existing 'protocol' user and group to 'request', and most mentions
of the 'download' aspect of the request to 'request' when relevant, to
make everything consistent across the system.

Note that LibProtocol still exists as-is, but the more generic Client
class and the more specific Download class have both been renamed to a
more accurate RequestClient and Request to match the new names.

This commit only change names, not behaviors.
This commit is contained in:
DexesTTP 2021-04-23 22:45:52 +02:00 committed by Linus Groh
parent 22413ef729
commit 71d27abb97
58 changed files with 786 additions and 788 deletions

View file

@ -9,7 +9,7 @@ add_subdirectory(ImageDecoder)
add_subdirectory(LaunchServer)
add_subdirectory(LookupServer)
add_subdirectory(NotificationServer)
add_subdirectory(ProtocolServer)
add_subdirectory(RequestServer)
add_subdirectory(SymbolServer)
add_subdirectory(SystemServer)
add_subdirectory(Taskbar)

View file

@ -1,20 +0,0 @@
compile_ipc(ProtocolServer.ipc ProtocolServerEndpoint.h)
compile_ipc(ProtocolClient.ipc ProtocolClientEndpoint.h)
set(SOURCES
ClientConnection.cpp
Download.cpp
GeminiDownload.cpp
GeminiProtocol.cpp
HttpDownload.cpp
HttpProtocol.cpp
HttpsDownload.cpp
HttpsProtocol.cpp
main.cpp
Protocol.cpp
ProtocolServerEndpoint.h
ProtocolClientEndpoint.h
)
serenity_bin(ProtocolServer)
target_link_libraries(ProtocolServer LibCore LibIPC LibGemini LibHTTP)

View file

@ -1,119 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
#include <ProtocolServer/Protocol.h>
#include <ProtocolServer/ProtocolClientEndpoint.h>
namespace ProtocolServer {
static HashMap<int, RefPtr<ClientConnection>> s_connections;
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id)
: IPC::ClientConnection<ProtocolClientEndpoint, ProtocolServerEndpoint>(*this, move(socket), client_id)
{
s_connections.set(client_id, *this);
}
ClientConnection::~ClientConnection()
{
}
void ClientConnection::die()
{
s_connections.remove(client_id());
if (s_connections.is_empty())
Core::EventLoop::current().quit(0);
}
OwnPtr<Messages::ProtocolServer::IsSupportedProtocolResponse> ClientConnection::handle(const Messages::ProtocolServer::IsSupportedProtocol& message)
{
bool supported = Protocol::find_by_name(message.protocol().to_lowercase());
return make<Messages::ProtocolServer::IsSupportedProtocolResponse>(supported);
}
OwnPtr<Messages::ProtocolServer::StartDownloadResponse> ClientConnection::handle(const Messages::ProtocolServer::StartDownload& message)
{
const auto& url = message.url();
if (!url.is_valid()) {
dbgln("StartDownload: Invalid URL requested: '{}'", url);
return make<Messages::ProtocolServer::StartDownloadResponse>(-1, Optional<IPC::File> {});
}
auto* protocol = Protocol::find_by_name(url.protocol());
if (!protocol) {
dbgln("StartDownload: No protocol handler for URL: '{}'", url);
return make<Messages::ProtocolServer::StartDownloadResponse>(-1, Optional<IPC::File> {});
}
auto download = protocol->start_download(*this, message.method(), url, message.request_headers().entries(), message.request_body());
if (!download) {
dbgln("StartDownload: Protocol handler failed to start download: '{}'", url);
return make<Messages::ProtocolServer::StartDownloadResponse>(-1, Optional<IPC::File> {});
}
auto id = download->id();
auto fd = download->download_fd();
m_downloads.set(id, move(download));
return make<Messages::ProtocolServer::StartDownloadResponse>(id, IPC::File(fd, IPC::File::CloseAfterSending));
}
OwnPtr<Messages::ProtocolServer::StopDownloadResponse> ClientConnection::handle(const Messages::ProtocolServer::StopDownload& message)
{
auto* download = const_cast<Download*>(m_downloads.get(message.download_id()).value_or(nullptr));
bool success = false;
if (download) {
download->stop();
m_downloads.remove(message.download_id());
success = true;
}
return make<Messages::ProtocolServer::StopDownloadResponse>(success);
}
void ClientConnection::did_receive_headers(Badge<Download>, Download& download)
{
IPC::Dictionary response_headers;
for (auto& it : download.response_headers())
response_headers.add(it.key, it.value);
post_message(Messages::ProtocolClient::HeadersBecameAvailable(download.id(), move(response_headers), download.status_code()));
}
void ClientConnection::did_finish_download(Badge<Download>, Download& download, bool success)
{
VERIFY(download.total_size().has_value());
post_message(Messages::ProtocolClient::DownloadFinished(download.id(), success, download.total_size().value()));
m_downloads.remove(download.id());
}
void ClientConnection::did_progress_download(Badge<Download>, Download& download)
{
post_message(Messages::ProtocolClient::DownloadProgress(download.id(), download.total_size(), download.downloaded_size()));
}
void ClientConnection::did_request_certificates(Badge<Download>, Download& download)
{
post_message(Messages::ProtocolClient::CertificateRequested(download.id()));
}
OwnPtr<Messages::ProtocolServer::GreetResponse> ClientConnection::handle(const Messages::ProtocolServer::Greet&)
{
return make<Messages::ProtocolServer::GreetResponse>();
}
OwnPtr<Messages::ProtocolServer::SetCertificateResponse> ClientConnection::handle(const Messages::ProtocolServer::SetCertificate& message)
{
auto* download = const_cast<Download*>(m_downloads.get(message.download_id()).value_or(nullptr));
bool success = false;
if (download) {
download->set_certificate(message.certificate(), message.key());
success = true;
}
return make<Messages::ProtocolServer::SetCertificateResponse>(success);
}
}

View file

@ -1,43 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/HashMap.h>
#include <LibIPC/ClientConnection.h>
#include <ProtocolServer/Forward.h>
#include <ProtocolServer/ProtocolClientEndpoint.h>
#include <ProtocolServer/ProtocolServerEndpoint.h>
namespace ProtocolServer {
class ClientConnection final
: public IPC::ClientConnection<ProtocolClientEndpoint, ProtocolServerEndpoint>
, public ProtocolServerEndpoint {
C_OBJECT(ClientConnection);
public:
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
~ClientConnection() override;
virtual void die() override;
void did_receive_headers(Badge<Download>, Download&);
void did_finish_download(Badge<Download>, Download&, bool success);
void did_progress_download(Badge<Download>, Download&);
void did_request_certificates(Badge<Download>, Download&);
private:
virtual OwnPtr<Messages::ProtocolServer::GreetResponse> handle(const Messages::ProtocolServer::Greet&) override;
virtual OwnPtr<Messages::ProtocolServer::IsSupportedProtocolResponse> handle(const Messages::ProtocolServer::IsSupportedProtocol&) override;
virtual OwnPtr<Messages::ProtocolServer::StartDownloadResponse> handle(const Messages::ProtocolServer::StartDownload&) override;
virtual OwnPtr<Messages::ProtocolServer::StopDownloadResponse> handle(const Messages::ProtocolServer::StopDownload&) override;
virtual OwnPtr<Messages::ProtocolServer::SetCertificateResponse> handle(const Messages::ProtocolServer::SetCertificate&) override;
HashMap<i32, OwnPtr<Download>> m_downloads;
};
}

View file

@ -1,59 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
namespace ProtocolServer {
// FIXME: What about rollover?
static i32 s_next_id = 1;
Download::Download(ClientConnection& client, NonnullOwnPtr<OutputFileStream>&& output_stream)
: m_client(client)
, m_id(s_next_id++)
, m_output_stream(move(output_stream))
{
}
Download::~Download()
{
}
void Download::stop()
{
m_client.did_finish_download({}, *this, false);
}
void Download::set_response_headers(const HashMap<String, String, CaseInsensitiveStringTraits>& response_headers)
{
m_response_headers = response_headers;
m_client.did_receive_headers({}, *this);
}
void Download::set_certificate(String, String)
{
}
void Download::did_finish(bool success)
{
m_client.did_finish_download({}, *this, success);
}
void Download::did_progress(Optional<u32> total_size, u32 downloaded_size)
{
m_total_size = total_size;
m_downloaded_size = downloaded_size;
m_client.did_progress_download({}, *this);
}
void Download::did_request_certificates()
{
m_client.did_request_certificates({}, *this);
}
}

View file

@ -1,29 +0,0 @@
/*
* Copyright (c) 2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Badge.h>
#include <LibCore/Forward.h>
#include <LibGemini/Forward.h>
#include <ProtocolServer/Download.h>
namespace ProtocolServer {
class GeminiDownload final : public Download {
public:
virtual ~GeminiDownload() override;
static NonnullOwnPtr<GeminiDownload> create_with_job(Badge<GeminiProtocol>, ClientConnection&, NonnullRefPtr<Gemini::GeminiJob>, NonnullOwnPtr<OutputFileStream>&&);
private:
explicit GeminiDownload(ClientConnection&, NonnullRefPtr<Gemini::GeminiJob>, NonnullOwnPtr<OutputFileStream>&&);
virtual void set_certificate(String certificate, String key) override;
NonnullRefPtr<Gemini::GeminiJob> m_job;
};
}

View file

@ -1,33 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibHTTP/HttpJob.h>
#include <ProtocolServer/HttpCommon.h>
#include <ProtocolServer/HttpDownload.h>
#include <ProtocolServer/HttpProtocol.h>
namespace ProtocolServer {
HttpDownload::HttpDownload(ClientConnection& client, NonnullRefPtr<HTTP::HttpJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
: Download(client, move(output_stream))
, m_job(job)
{
Detail::init(this, job);
}
HttpDownload::~HttpDownload()
{
m_job->on_finish = nullptr;
m_job->on_progress = nullptr;
m_job->shutdown();
}
NonnullOwnPtr<HttpDownload> HttpDownload::create_with_job(Badge<HttpProtocol>&&, ClientConnection& client, NonnullRefPtr<HTTP::HttpJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
{
return adopt_own(*new HttpDownload(client, move(job), move(output_stream)));
}
}

View file

@ -1,30 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Badge.h>
#include <AK/NonnullOwnPtr.h>
#include <LibCore/Forward.h>
#include <LibHTTP/Forward.h>
#include <ProtocolServer/Download.h>
namespace ProtocolServer {
class HttpDownload final : public Download {
public:
virtual ~HttpDownload() override;
static NonnullOwnPtr<HttpDownload> create_with_job(Badge<HttpProtocol>&&, ClientConnection&, NonnullRefPtr<HTTP::HttpJob>, NonnullOwnPtr<OutputFileStream>&&);
HTTP::HttpJob& job() { return m_job; }
private:
explicit HttpDownload(ClientConnection&, NonnullRefPtr<HTTP::HttpJob>, NonnullOwnPtr<OutputFileStream>&&);
NonnullRefPtr<HTTP::HttpJob> m_job;
};
}

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <AK/ByteBuffer.h>
#include <AK/HashMap.h>
#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/URL.h>
#include <LibHTTP/HttpJob.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
#include <ProtocolServer/HttpCommon.h>
#include <ProtocolServer/HttpDownload.h>
#include <ProtocolServer/HttpProtocol.h>
namespace ProtocolServer {
HttpProtocol::HttpProtocol()
: Protocol("http")
{
}
OwnPtr<Download> HttpProtocol::start_download(ClientConnection& client, const String& method, const URL& url, const HashMap<String, String>& headers, ReadonlyBytes body)
{
return Detail::start_download(Badge<HttpProtocol> {}, client, method, url, headers, body, get_pipe_for_download());
}
}

View file

@ -1,38 +0,0 @@
/*
* Copyright (c) 2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibHTTP/HttpsJob.h>
#include <ProtocolServer/HttpCommon.h>
#include <ProtocolServer/HttpsDownload.h>
#include <ProtocolServer/HttpsProtocol.h>
namespace ProtocolServer {
HttpsDownload::HttpsDownload(ClientConnection& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
: Download(client, move(output_stream))
, m_job(job)
{
Detail::init(this, job);
}
void HttpsDownload::set_certificate(String certificate, String key)
{
m_job->set_certificate(move(certificate), move(key));
}
HttpsDownload::~HttpsDownload()
{
m_job->on_finish = nullptr;
m_job->on_progress = nullptr;
m_job->shutdown();
}
NonnullOwnPtr<HttpsDownload> HttpsDownload::create_with_job(Badge<HttpsProtocol>&&, ClientConnection& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
{
return adopt_own(*new HttpsDownload(client, move(job), move(output_stream)));
}
}

View file

@ -1,31 +0,0 @@
/*
* Copyright (c) 2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Badge.h>
#include <LibCore/Forward.h>
#include <LibHTTP/HttpsJob.h>
#include <ProtocolServer/Download.h>
namespace ProtocolServer {
class HttpsDownload final : public Download {
public:
virtual ~HttpsDownload() override;
static NonnullOwnPtr<HttpsDownload> create_with_job(Badge<HttpsProtocol>&&, ClientConnection&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<OutputFileStream>&&);
HTTP::HttpsJob& job() { return m_job; }
private:
explicit HttpsDownload(ClientConnection&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<OutputFileStream>&&);
virtual void set_certificate(String certificate, String key) override;
NonnullRefPtr<HTTP::HttpsJob> m_job;
};
}

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2018-2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <AK/ByteBuffer.h>
#include <AK/HashMap.h>
#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/URL.h>
#include <LibHTTP/HttpsJob.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
#include <ProtocolServer/HttpCommon.h>
#include <ProtocolServer/HttpsDownload.h>
#include <ProtocolServer/HttpsProtocol.h>
namespace ProtocolServer {
HttpsProtocol::HttpsProtocol()
: Protocol("https")
{
}
OwnPtr<Download> HttpsProtocol::start_download(ClientConnection& client, const String& method, const URL& url, const HashMap<String, String>& headers, ReadonlyBytes body)
{
return Detail::start_download(Badge<HttpsProtocol> {}, client, method, url, headers, body, get_pipe_for_download());
}
}

View file

@ -1,10 +0,0 @@
endpoint ProtocolClient
{
// Download notifications
DownloadProgress(i32 download_id, Optional<u32> total_size, u32 downloaded_size) =|
DownloadFinished(i32 download_id, bool success, u32 total_size) =|
HeadersBecameAvailable(i32 download_id, IPC::Dictionary response_headers, Optional<u32> status_code) =|
// Certificate requests
CertificateRequested(i32 download_id) => ()
}

View file

@ -1,13 +0,0 @@
endpoint ProtocolServer
{
// Basic protocol
Greet() => ()
// Test if a specific protocol is supported, e.g "http"
IsSupportedProtocol(String protocol) => (bool supported)
// Download API
StartDownload(String method, URL url, IPC::Dictionary request_headers, ByteBuffer request_body) => (i32 download_id, Optional<IPC::File> response_fd)
StopDownload(i32 download_id) => (bool success)
SetCertificate(i32 download_id, String certificate, String key) => (bool success)
}

View file

@ -0,0 +1,20 @@
compile_ipc(RequestServer.ipc RequestServerEndpoint.h)
compile_ipc(RequestClient.ipc RequestClientEndpoint.h)
set(SOURCES
ClientConnection.cpp
Request.cpp
RequestClientEndpoint.h
RequestServerEndpoint.h
GeminiRequest.cpp
GeminiProtocol.cpp
HttpRequest.cpp
HttpProtocol.cpp
HttpsRequest.cpp
HttpsProtocol.cpp
main.cpp
Protocol.cpp
)
serenity_bin(RequestServer)
target_link_libraries(RequestServer LibCore LibIPC LibGemini LibHTTP)

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/Protocol.h>
#include <RequestServer/Request.h>
#include <RequestServer/RequestClientEndpoint.h>
namespace RequestServer {
static HashMap<int, RefPtr<ClientConnection>> s_connections;
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id)
: IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), client_id)
{
s_connections.set(client_id, *this);
}
ClientConnection::~ClientConnection()
{
}
void ClientConnection::die()
{
s_connections.remove(client_id());
if (s_connections.is_empty())
Core::EventLoop::current().quit(0);
}
OwnPtr<Messages::RequestServer::IsSupportedProtocolResponse> ClientConnection::handle(const Messages::RequestServer::IsSupportedProtocol& message)
{
bool supported = Protocol::find_by_name(message.protocol().to_lowercase());
return make<Messages::RequestServer::IsSupportedProtocolResponse>(supported);
}
OwnPtr<Messages::RequestServer::StartRequestResponse> ClientConnection::handle(const Messages::RequestServer::StartRequest& message)
{
const auto& url = message.url();
if (!url.is_valid()) {
dbgln("StartRequest: Invalid URL requested: '{}'", url);
return make<Messages::RequestServer::StartRequestResponse>(-1, Optional<IPC::File> {});
}
auto* protocol = Protocol::find_by_name(url.protocol());
if (!protocol) {
dbgln("StartRequest: No protocol handler for URL: '{}'", url);
return make<Messages::RequestServer::StartRequestResponse>(-1, Optional<IPC::File> {});
}
auto request = protocol->start_request(*this, message.method(), url, message.request_headers().entries(), message.request_body());
if (!request) {
dbgln("StartRequest: Protocol handler failed to start request: '{}'", url);
return make<Messages::RequestServer::StartRequestResponse>(-1, Optional<IPC::File> {});
}
auto id = request->id();
auto fd = request->request_fd();
m_requests.set(id, move(request));
return make<Messages::RequestServer::StartRequestResponse>(id, IPC::File(fd, IPC::File::CloseAfterSending));
}
OwnPtr<Messages::RequestServer::StopRequestResponse> ClientConnection::handle(const Messages::RequestServer::StopRequest& message)
{
auto* request = const_cast<Request*>(m_requests.get(message.request_id()).value_or(nullptr));
bool success = false;
if (request) {
request->stop();
m_requests.remove(message.request_id());
success = true;
}
return make<Messages::RequestServer::StopRequestResponse>(success);
}
void ClientConnection::did_receive_headers(Badge<Request>, Request& request)
{
IPC::Dictionary response_headers;
for (auto& it : request.response_headers())
response_headers.add(it.key, it.value);
post_message(Messages::RequestClient::HeadersBecameAvailable(request.id(), move(response_headers), request.status_code()));
}
void ClientConnection::did_finish_request(Badge<Request>, Request& request, bool success)
{
VERIFY(request.total_size().has_value());
post_message(Messages::RequestClient::RequestFinished(request.id(), success, request.total_size().value()));
m_requests.remove(request.id());
}
void ClientConnection::did_progress_request(Badge<Request>, Request& request)
{
post_message(Messages::RequestClient::RequestProgress(request.id(), request.total_size(), request.downloaded_size()));
}
void ClientConnection::did_request_certificates(Badge<Request>, Request& request)
{
post_message(Messages::RequestClient::CertificateRequested(request.id()));
}
OwnPtr<Messages::RequestServer::GreetResponse> ClientConnection::handle(const Messages::RequestServer::Greet&)
{
return make<Messages::RequestServer::GreetResponse>();
}
OwnPtr<Messages::RequestServer::SetCertificateResponse> ClientConnection::handle(const Messages::RequestServer::SetCertificate& message)
{
auto* request = const_cast<Request*>(m_requests.get(message.request_id()).value_or(nullptr));
bool success = false;
if (request) {
request->set_certificate(message.certificate(), message.key());
success = true;
}
return make<Messages::RequestServer::SetCertificateResponse>(success);
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/HashMap.h>
#include <LibIPC/ClientConnection.h>
#include <RequestServer/Forward.h>
#include <RequestServer/RequestClientEndpoint.h>
#include <RequestServer/RequestServerEndpoint.h>
namespace RequestServer {
class ClientConnection final
: public IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>
, public RequestServerEndpoint {
C_OBJECT(ClientConnection);
public:
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
~ClientConnection() override;
virtual void die() override;
void did_receive_headers(Badge<Request>, Request&);
void did_finish_request(Badge<Request>, Request&, bool success);
void did_progress_request(Badge<Request>, Request&);
void did_request_certificates(Badge<Request>, Request&);
private:
virtual OwnPtr<Messages::RequestServer::GreetResponse> handle(const Messages::RequestServer::Greet&) override;
virtual OwnPtr<Messages::RequestServer::IsSupportedProtocolResponse> handle(const Messages::RequestServer::IsSupportedProtocol&) override;
virtual OwnPtr<Messages::RequestServer::StartRequestResponse> handle(const Messages::RequestServer::StartRequest&) override;
virtual OwnPtr<Messages::RequestServer::StopRequestResponse> handle(const Messages::RequestServer::StopRequest&) override;
virtual OwnPtr<Messages::RequestServer::SetCertificateResponse> handle(const Messages::RequestServer::SetCertificate&) override;
HashMap<i32, OwnPtr<Request>> m_requests;
};
}

View file

@ -6,14 +6,14 @@
#pragma once
namespace ProtocolServer {
namespace RequestServer {
class ClientConnection;
class Download;
class Request;
class GeminiProtocol;
class HttpDownload;
class HttpRequest;
class HttpProtocol;
class HttpsDownload;
class HttpsRequest;
class HttpsProtocol;
class Protocol;

View file

@ -6,11 +6,11 @@
#include <LibGemini/GeminiJob.h>
#include <LibGemini/GeminiRequest.h>
#include <ProtocolServer/GeminiDownload.h>
#include <ProtocolServer/GeminiProtocol.h>
#include <RequestServer/GeminiProtocol.h>
#include <RequestServer/GeminiRequest.h>
#include <fcntl.h>
namespace ProtocolServer {
namespace RequestServer {
GeminiProtocol::GeminiProtocol()
: Protocol("gemini")
@ -21,22 +21,22 @@ GeminiProtocol::~GeminiProtocol()
{
}
OwnPtr<Download> GeminiProtocol::start_download(ClientConnection& client, const String&, const URL& url, const HashMap<String, String>&, ReadonlyBytes)
OwnPtr<Request> GeminiProtocol::start_request(ClientConnection& client, const String&, const URL& url, const HashMap<String, String>&, ReadonlyBytes)
{
Gemini::GeminiRequest request;
request.set_url(url);
auto pipe_result = get_pipe_for_download();
auto pipe_result = get_pipe_for_request();
if (pipe_result.is_error())
return {};
auto output_stream = make<OutputFileStream>(pipe_result.value().write_fd);
output_stream->make_unbuffered();
auto job = Gemini::GeminiJob::construct(request, *output_stream);
auto download = GeminiDownload::create_with_job({}, client, (Gemini::GeminiJob&)*job, move(output_stream));
download->set_download_fd(pipe_result.value().read_fd);
auto protocol_request = GeminiRequest::create_with_job({}, client, (Gemini::GeminiJob&)*job, move(output_stream));
protocol_request->set_request_fd(pipe_result.value().read_fd);
job->start();
return download;
return protocol_request;
}
}

View file

@ -6,16 +6,16 @@
#pragma once
#include <ProtocolServer/Protocol.h>
#include <RequestServer/Protocol.h>
namespace ProtocolServer {
namespace RequestServer {
class GeminiProtocol final : public Protocol {
public:
GeminiProtocol();
virtual ~GeminiProtocol() override;
virtual OwnPtr<Download> start_download(ClientConnection&, const String& method, const URL&, const HashMap<String, String>&, ReadonlyBytes body) override;
virtual OwnPtr<Request> start_request(ClientConnection&, const String& method, const URL&, const HashMap<String, String>&, ReadonlyBytes body) override;
};
}

View file

@ -6,12 +6,12 @@
#include <LibGemini/GeminiJob.h>
#include <LibGemini/GeminiResponse.h>
#include <ProtocolServer/GeminiDownload.h>
#include <RequestServer/GeminiRequest.h>
namespace ProtocolServer {
namespace RequestServer {
GeminiDownload::GeminiDownload(ClientConnection& client, NonnullRefPtr<Gemini::GeminiJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
: Download(client, move(output_stream))
GeminiRequest::GeminiRequest(ClientConnection& client, NonnullRefPtr<Gemini::GeminiJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
: Request(client, move(output_stream))
, m_job(job)
{
m_job->on_finish = [this](bool success) {
@ -30,7 +30,7 @@ GeminiDownload::GeminiDownload(ClientConnection& client, NonnullRefPtr<Gemini::G
}
}
// signal 100% download progress so any listeners can react
// signal 100% request progress so any listeners can react
// appropriately
did_progress(downloaded_size(), downloaded_size());
@ -44,21 +44,21 @@ GeminiDownload::GeminiDownload(ClientConnection& client, NonnullRefPtr<Gemini::G
};
}
void GeminiDownload::set_certificate(String certificate, String key)
void GeminiRequest::set_certificate(String certificate, String key)
{
m_job->set_certificate(move(certificate), move(key));
}
GeminiDownload::~GeminiDownload()
GeminiRequest::~GeminiRequest()
{
m_job->on_finish = nullptr;
m_job->on_progress = nullptr;
m_job->shutdown();
}
NonnullOwnPtr<GeminiDownload> GeminiDownload::create_with_job(Badge<GeminiProtocol>, ClientConnection& client, NonnullRefPtr<Gemini::GeminiJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
NonnullOwnPtr<GeminiRequest> GeminiRequest::create_with_job(Badge<GeminiProtocol>, ClientConnection& client, NonnullRefPtr<Gemini::GeminiJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
{
return adopt_own(*new GeminiDownload(client, move(job), move(output_stream)));
return adopt_own(*new GeminiRequest(client, move(job), move(output_stream)));
}
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Badge.h>
#include <LibCore/Forward.h>
#include <LibGemini/Forward.h>
#include <RequestServer/Request.h>
namespace RequestServer {
class GeminiRequest final : public Request {
public:
virtual ~GeminiRequest() override;
static NonnullOwnPtr<GeminiRequest> create_with_job(Badge<GeminiProtocol>, ClientConnection&, NonnullRefPtr<Gemini::GeminiJob>, NonnullOwnPtr<OutputFileStream>&&);
private:
explicit GeminiRequest(ClientConnection&, NonnullRefPtr<Gemini::GeminiJob>, NonnullOwnPtr<OutputFileStream>&&);
virtual void set_certificate(String certificate, String key) override;
NonnullRefPtr<Gemini::GeminiJob> m_job;
};
}

View file

@ -14,10 +14,10 @@
#include <AK/String.h>
#include <AK/Types.h>
#include <LibHTTP/HttpRequest.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/Request.h>
namespace ProtocolServer::Detail {
namespace RequestServer::Detail {
template<typename TSelf, typename TJob>
void init(TSelf* self, TJob job)
@ -35,7 +35,7 @@ void init(TSelf* self, TJob job)
self->set_downloaded_size(self->output_stream().size());
}
// if we didn't know the total size, pretend that the download finished successfully
// if we didn't know the total size, pretend that the request finished successfully
// and set the total size to the downloaded size
if (!self->total_size().has_value())
self->did_progress(self->downloaded_size(), self->downloaded_size());
@ -53,10 +53,10 @@ void init(TSelf* self, TJob job)
}
template<typename TBadgedProtocol, typename TPipeResult>
OwnPtr<Download> start_download(TBadgedProtocol&& protocol, ClientConnection& client, const String& method, const URL& url, const HashMap<String, String>& headers, ReadonlyBytes body, TPipeResult&& pipe_result)
OwnPtr<Request> start_request(TBadgedProtocol&& protocol, ClientConnection& client, const String& method, const URL& url, const HashMap<String, String>& headers, ReadonlyBytes body, TPipeResult&& pipe_result)
{
using TJob = TBadgedProtocol::Type::JobType;
using TDownload = TBadgedProtocol::Type::DownloadType;
using TRequest = TBadgedProtocol::Type::RequestType;
if (pipe_result.is_error()) {
return {};
@ -74,10 +74,10 @@ OwnPtr<Download> start_download(TBadgedProtocol&& protocol, ClientConnection& cl
auto output_stream = make<OutputFileStream>(pipe_result.value().write_fd);
output_stream->make_unbuffered();
auto job = TJob::construct(request, *output_stream);
auto download = TDownload::create_with_job(forward<TBadgedProtocol>(protocol), client, (TJob&)*job, move(output_stream));
download->set_download_fd(pipe_result.value().read_fd);
auto protocol_request = TRequest::create_with_job(forward<TBadgedProtocol>(protocol), client, (TJob&)*job, move(output_stream));
protocol_request->set_request_fd(pipe_result.value().read_fd);
job->start();
return download;
return protocol_request;
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <AK/ByteBuffer.h>
#include <AK/HashMap.h>
#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/URL.h>
#include <LibHTTP/HttpJob.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/HttpCommon.h>
#include <RequestServer/HttpProtocol.h>
#include <RequestServer/HttpRequest.h>
#include <RequestServer/Request.h>
namespace RequestServer {
HttpProtocol::HttpProtocol()
: Protocol("http")
{
}
OwnPtr<Request> HttpProtocol::start_request(ClientConnection& client, const String& method, const URL& url, const HashMap<String, String>& headers, ReadonlyBytes body)
{
return Detail::start_request(Badge<HttpProtocol> {}, client, method, url, headers, body, get_pipe_for_request());
}
}

View file

@ -12,22 +12,22 @@
#include <AK/String.h>
#include <AK/URL.h>
#include <LibHTTP/HttpJob.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
#include <ProtocolServer/HttpDownload.h>
#include <ProtocolServer/Protocol.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/HttpRequest.h>
#include <RequestServer/Protocol.h>
#include <RequestServer/Request.h>
namespace ProtocolServer {
namespace RequestServer {
class HttpProtocol final : public Protocol {
public:
using JobType = HTTP::HttpJob;
using DownloadType = HttpDownload;
using RequestType = HttpRequest;
HttpProtocol();
~HttpProtocol() override = default;
virtual OwnPtr<Download> start_download(ClientConnection&, const String& method, const URL&, const HashMap<String, String>& headers, ReadonlyBytes body) override;
virtual OwnPtr<Request> start_request(ClientConnection&, const String& method, const URL&, const HashMap<String, String>& headers, ReadonlyBytes body) override;
};
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibHTTP/HttpJob.h>
#include <RequestServer/HttpCommon.h>
#include <RequestServer/HttpProtocol.h>
#include <RequestServer/HttpRequest.h>
namespace RequestServer {
HttpRequest::HttpRequest(ClientConnection& client, NonnullRefPtr<HTTP::HttpJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
: Request(client, move(output_stream))
, m_job(job)
{
Detail::init(this, job);
}
HttpRequest::~HttpRequest()
{
m_job->on_finish = nullptr;
m_job->on_progress = nullptr;
m_job->shutdown();
}
NonnullOwnPtr<HttpRequest> HttpRequest::create_with_job(Badge<HttpProtocol>&&, ClientConnection& client, NonnullRefPtr<HTTP::HttpJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
{
return adopt_own(*new HttpRequest(client, move(job), move(output_stream)));
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Badge.h>
#include <AK/NonnullOwnPtr.h>
#include <LibCore/Forward.h>
#include <LibHTTP/Forward.h>
#include <RequestServer/Request.h>
namespace RequestServer {
class HttpRequest final : public Request {
public:
virtual ~HttpRequest() override;
static NonnullOwnPtr<HttpRequest> create_with_job(Badge<HttpProtocol>&&, ClientConnection&, NonnullRefPtr<HTTP::HttpJob>, NonnullOwnPtr<OutputFileStream>&&);
HTTP::HttpJob& job() { return m_job; }
private:
explicit HttpRequest(ClientConnection&, NonnullRefPtr<HTTP::HttpJob>, NonnullOwnPtr<OutputFileStream>&&);
NonnullRefPtr<HTTP::HttpJob> m_job;
};
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2018-2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <AK/ByteBuffer.h>
#include <AK/HashMap.h>
#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/URL.h>
#include <LibHTTP/HttpsJob.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/HttpCommon.h>
#include <RequestServer/HttpsProtocol.h>
#include <RequestServer/HttpsRequest.h>
#include <RequestServer/Request.h>
namespace RequestServer {
HttpsProtocol::HttpsProtocol()
: Protocol("https")
{
}
OwnPtr<Request> HttpsProtocol::start_request(ClientConnection& client, const String& method, const URL& url, const HashMap<String, String>& headers, ReadonlyBytes body)
{
return Detail::start_request(Badge<HttpsProtocol> {}, client, method, url, headers, body, get_pipe_for_request());
}
}

View file

@ -12,22 +12,22 @@
#include <AK/String.h>
#include <AK/URL.h>
#include <LibHTTP/HttpsJob.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
#include <ProtocolServer/HttpsDownload.h>
#include <ProtocolServer/Protocol.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/HttpsRequest.h>
#include <RequestServer/Protocol.h>
#include <RequestServer/Request.h>
namespace ProtocolServer {
namespace RequestServer {
class HttpsProtocol final : public Protocol {
public:
using JobType = HTTP::HttpsJob;
using DownloadType = HttpsDownload;
using RequestType = HttpsRequest;
HttpsProtocol();
~HttpsProtocol() override = default;
virtual OwnPtr<Download> start_download(ClientConnection&, const String& method, const URL&, const HashMap<String, String>& headers, ReadonlyBytes body) override;
virtual OwnPtr<Request> start_request(ClientConnection&, const String& method, const URL&, const HashMap<String, String>& headers, ReadonlyBytes body) override;
};
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibHTTP/HttpsJob.h>
#include <RequestServer/HttpCommon.h>
#include <RequestServer/HttpsProtocol.h>
#include <RequestServer/HttpsRequest.h>
namespace RequestServer {
HttpsRequest::HttpsRequest(ClientConnection& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
: Request(client, move(output_stream))
, m_job(job)
{
Detail::init(this, job);
}
void HttpsRequest::set_certificate(String certificate, String key)
{
m_job->set_certificate(move(certificate), move(key));
}
HttpsRequest::~HttpsRequest()
{
m_job->on_finish = nullptr;
m_job->on_progress = nullptr;
m_job->shutdown();
}
NonnullOwnPtr<HttpsRequest> HttpsRequest::create_with_job(Badge<HttpsProtocol>&&, ClientConnection& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<OutputFileStream>&& output_stream)
{
return adopt_own(*new HttpsRequest(client, move(job), move(output_stream)));
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2020, The SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Badge.h>
#include <LibCore/Forward.h>
#include <LibHTTP/HttpsJob.h>
#include <RequestServer/Request.h>
namespace RequestServer {
class HttpsRequest final : public Request {
public:
virtual ~HttpsRequest() override;
static NonnullOwnPtr<HttpsRequest> create_with_job(Badge<HttpsProtocol>&&, ClientConnection&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<OutputFileStream>&&);
HTTP::HttpsJob& job() { return m_job; }
private:
explicit HttpsRequest(ClientConnection&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<OutputFileStream>&&);
virtual void set_certificate(String certificate, String key) override;
NonnullRefPtr<HTTP::HttpsJob> m_job;
};
}

View file

@ -5,13 +5,13 @@
*/
#include <AK/HashMap.h>
#include <ProtocolServer/Protocol.h>
#include <RequestServer/Protocol.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
namespace ProtocolServer {
namespace RequestServer {
static HashMap<String, Protocol*>& all_protocols()
{
@ -34,7 +34,7 @@ Protocol::~Protocol()
VERIFY_NOT_REACHED();
}
Result<Protocol::Pipe, String> Protocol::get_pipe_for_download()
Result<Protocol::Pipe, String> Protocol::get_pipe_for_request()
{
int fd_pair[2] { 0 };
if (pipe(fd_pair) != 0) {

View file

@ -9,16 +9,16 @@
#include <AK/RefPtr.h>
#include <AK/Result.h>
#include <AK/URL.h>
#include <ProtocolServer/Forward.h>
#include <RequestServer/Forward.h>
namespace ProtocolServer {
namespace RequestServer {
class Protocol {
public:
virtual ~Protocol();
const String& name() const { return m_name; }
virtual OwnPtr<Download> start_download(ClientConnection&, const String& method, const URL&, const HashMap<String, String>& headers, ReadonlyBytes body) = 0;
virtual OwnPtr<Request> start_request(ClientConnection&, const String& method, const URL&, const HashMap<String, String>& headers, ReadonlyBytes body) = 0;
static Protocol* find_by_name(const String&);
@ -28,7 +28,7 @@ protected:
int read_fd { -1 };
int write_fd { -1 };
};
static Result<Pipe, String> get_pipe_for_download();
static Result<Pipe, String> get_pipe_for_request();
private:
String m_name;

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Badge.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/Request.h>
namespace RequestServer {
// FIXME: What about rollover?
static i32 s_next_id = 1;
Request::Request(ClientConnection& client, NonnullOwnPtr<OutputFileStream>&& output_stream)
: m_client(client)
, m_id(s_next_id++)
, m_output_stream(move(output_stream))
{
}
Request::~Request()
{
}
void Request::stop()
{
m_client.did_finish_request({}, *this, false);
}
void Request::set_response_headers(const HashMap<String, String, CaseInsensitiveStringTraits>& response_headers)
{
m_response_headers = response_headers;
m_client.did_receive_headers({}, *this);
}
void Request::set_certificate(String, String)
{
}
void Request::did_finish(bool success)
{
m_client.did_finish_request({}, *this, success);
}
void Request::did_progress(Optional<u32> total_size, u32 downloaded_size)
{
m_total_size = total_size;
m_downloaded_size = downloaded_size;
m_client.did_progress_request({}, *this);
}
void Request::did_request_certificates()
{
m_client.did_request_certificates({}, *this);
}
}

View file

@ -12,13 +12,13 @@
#include <AK/Optional.h>
#include <AK/RefCounted.h>
#include <AK/URL.h>
#include <ProtocolServer/Forward.h>
#include <RequestServer/Forward.h>
namespace ProtocolServer {
namespace RequestServer {
class Download {
class Request {
public:
virtual ~Download();
virtual ~Request();
i32 id() const { return m_id; }
URL url() const { return m_url; }
@ -32,8 +32,8 @@ public:
virtual void set_certificate(String, String);
// FIXME: Want Badge<Protocol>, but can't make one from HttpProtocol, etc.
void set_download_fd(int fd) { m_download_fd = fd; }
int download_fd() const { return m_download_fd; }
void set_request_fd(int fd) { m_request_fd = fd; }
int request_fd() const { return m_request_fd; }
void did_finish(bool success);
void did_progress(Optional<u32> total_size, u32 downloaded_size);
@ -44,12 +44,12 @@ public:
const OutputFileStream& output_stream() const { return *m_output_stream; }
protected:
explicit Download(ClientConnection&, NonnullOwnPtr<OutputFileStream>&&);
explicit Request(ClientConnection&, NonnullOwnPtr<OutputFileStream>&&);
private:
ClientConnection& m_client;
i32 m_id { 0 };
int m_download_fd { -1 }; // Passed to client.
int m_request_fd { -1 }; // Passed to client.
URL m_url;
Optional<u32> m_status_code;
Optional<u32> m_total_size {};

View file

@ -0,0 +1,9 @@
endpoint RequestClient
{
RequestProgress(i32 request_id, Optional<u32> total_size, u32 downloaded_size) =|
RequestFinished(i32 request_id, bool success, u32 total_size) =|
HeadersBecameAvailable(i32 request_id, IPC::Dictionary response_headers, Optional<u32> status_code) =|
// Certificate requests
CertificateRequested(i32 request_id) => ()
}

View file

@ -0,0 +1,12 @@
endpoint RequestServer
{
// Basic protocol
Greet() => ()
// Test if a specific protocol is supported, e.g "http"
IsSupportedProtocol(String protocol) => (bool supported)
StartRequest(String method, URL url, IPC::Dictionary request_headers, ByteBuffer request_body) => (i32 request_id, Optional<IPC::File> response_fd)
StopRequest(i32 request_id) => (bool success)
SetCertificate(i32 request_id, String certificate, String key) => (bool success)
}

View file

@ -8,10 +8,10 @@
#include <LibCore/LocalServer.h>
#include <LibIPC/ClientConnection.h>
#include <LibTLS/Certificate.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/GeminiProtocol.h>
#include <ProtocolServer/HttpProtocol.h>
#include <ProtocolServer/HttpsProtocol.h>
#include <RequestServer/ClientConnection.h>
#include <RequestServer/GeminiProtocol.h>
#include <RequestServer/HttpProtocol.h>
#include <RequestServer/HttpsProtocol.h>
int main(int, char**)
{
@ -38,12 +38,12 @@ int main(int, char**)
return 1;
}
[[maybe_unused]] auto gemini = new ProtocolServer::GeminiProtocol;
[[maybe_unused]] auto http = new ProtocolServer::HttpProtocol;
[[maybe_unused]] auto https = new ProtocolServer::HttpsProtocol;
[[maybe_unused]] auto gemini = new RequestServer::GeminiProtocol;
[[maybe_unused]] auto http = new RequestServer::HttpProtocol;
[[maybe_unused]] auto https = new RequestServer::HttpsProtocol;
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server();
VERIFY(socket);
IPC::new_client_connection<ProtocolServer::ClientConnection>(socket.release_nonnull(), 1);
IPC::new_client_connection<RequestServer::ClientConnection>(socket.release_nonnull(), 1);
return event_loop.exec();
}

View file

@ -20,7 +20,7 @@ int main(int, char**)
perror("unveil");
return 1;
}
if (unveil("/tmp/portal/protocol", "rw") < 0) {
if (unveil("/tmp/portal/request", "rw") < 0) {
perror("unveil");
return 1;
}