mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
RequestServer+LibProtocol: Make starting requests fully async
This makes it so the clients don't have to wait for RS to become responsive, potentially allowing them to do other things while RS handles the connections. Fixes #23306.
This commit is contained in:
parent
18d26142f0
commit
5232afa13d
Notes:
sideshowbarker
2024-07-17 01:28:15 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/5232afa13d Pull-request: https://github.com/SerenityOS/serenity/pull/23330 Issue: https://github.com/SerenityOS/serenity/issues/23306 Reviewed-by: https://github.com/awesomekling
@ -20,12 +20,26 @@ bool Request::stop()
|
||||
return m_client->stop_request({}, *this);
|
||||
}
|
||||
|
||||
void Request::set_request_fd(Badge<Protocol::RequestClient>, int fd)
|
||||
{
|
||||
VERIFY(m_fd == -1);
|
||||
m_fd = fd;
|
||||
|
||||
auto notifier = Core::Notifier::construct(fd, Core::Notifier::Type::Read);
|
||||
auto stream = MUST(Core::File::adopt_fd(fd, Core::File::OpenMode::Read));
|
||||
notifier->on_activation = move(m_internal_stream_data->read_notifier->on_activation);
|
||||
m_internal_stream_data->read_notifier = move(notifier);
|
||||
m_internal_stream_data->read_stream = move(stream);
|
||||
}
|
||||
|
||||
void Request::stream_into(Stream& stream)
|
||||
{
|
||||
VERIFY(!m_internal_stream_data);
|
||||
|
||||
m_internal_stream_data = make<InternalStreamData>(MUST(Core::File::adopt_fd(fd(), Core::File::OpenMode::Read)));
|
||||
m_internal_stream_data = make<InternalStreamData>();
|
||||
m_internal_stream_data->read_notifier = Core::Notifier::construct(fd(), Core::Notifier::Type::Read);
|
||||
if (fd() != -1)
|
||||
m_internal_stream_data->read_stream = MUST(Core::File::adopt_fd(fd(), Core::File::OpenMode::Read));
|
||||
|
||||
auto user_on_finish = move(on_finish);
|
||||
on_finish = [this](auto success, auto total_size) {
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
void did_request_certificates(Badge<RequestClient>);
|
||||
|
||||
RefPtr<Core::Notifier>& write_notifier(Badge<RequestClient>) { return m_write_notifier; }
|
||||
void set_request_fd(Badge<RequestClient>, int fd) { m_fd = fd; }
|
||||
void set_request_fd(Badge<RequestClient>, int fd);
|
||||
|
||||
private:
|
||||
explicit Request(RequestClient&, i32 request_id);
|
||||
@ -73,12 +73,9 @@ private:
|
||||
};
|
||||
|
||||
struct InternalStreamData {
|
||||
InternalStreamData(NonnullOwnPtr<Stream> stream)
|
||||
: read_stream(move(stream))
|
||||
{
|
||||
}
|
||||
InternalStreamData() { }
|
||||
|
||||
NonnullOwnPtr<Stream> read_stream;
|
||||
OwnPtr<Stream> read_stream;
|
||||
RefPtr<Core::Notifier> read_notifier;
|
||||
bool success;
|
||||
u32 total_size { 0 };
|
||||
|
@ -29,20 +29,27 @@ RefPtr<Request> RequestClient::start_request(ByteString const& method, URL const
|
||||
if (body_result.is_error())
|
||||
return nullptr;
|
||||
|
||||
auto maybe_response = IPCProxy::try_start_request(method, url, headers_or_error.release_value(), body_result.release_value(), proxy_data);
|
||||
if (maybe_response.is_error())
|
||||
return nullptr;
|
||||
auto response = maybe_response.release_value();
|
||||
auto request_id = response.request_id();
|
||||
if (request_id < 0 || !response.response_fd().has_value())
|
||||
return nullptr;
|
||||
auto response_fd = response.response_fd().value().take_fd();
|
||||
static i32 s_next_request_id = 0;
|
||||
auto request_id = s_next_request_id++;
|
||||
|
||||
IPCProxy::async_start_request(request_id, method, url, headers_or_error.release_value(), body_result.release_value(), proxy_data);
|
||||
auto request = Request::create_from_id({}, *this, request_id);
|
||||
request->set_request_fd({}, response_fd);
|
||||
m_requests.set(request_id, request);
|
||||
return request;
|
||||
}
|
||||
|
||||
void RequestClient::request_started(i32 request_id, IPC::File const& response_file)
|
||||
{
|
||||
auto request = m_requests.get(request_id);
|
||||
if (!request.has_value()) {
|
||||
warnln("Received response for non-existent request {}", request_id);
|
||||
return;
|
||||
}
|
||||
|
||||
auto response_fd = response_file.take_fd();
|
||||
request.value()->set_request_fd({}, response_fd);
|
||||
}
|
||||
|
||||
bool RequestClient::stop_request(Badge<Request>, Request& request)
|
||||
{
|
||||
if (!m_requests.contains(request.id()))
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
bool set_certificate(Badge<Request>, Request&, ByteString, ByteString);
|
||||
|
||||
private:
|
||||
virtual void request_started(i32, IPC::File const&) override;
|
||||
virtual void request_progress(i32, Optional<u64> const&, u64) override;
|
||||
virtual void request_finished(i32, bool, u64) override;
|
||||
virtual void certificate_requested(i32) override;
|
||||
|
@ -71,13 +71,15 @@ void request_did_finish(URL const& url, Core::Socket const* socket)
|
||||
connection->job_data.fail(Core::NetworkJob::Error::ConnectionFailed);
|
||||
return;
|
||||
}
|
||||
Core::deferred_invoke([&, url] {
|
||||
dbgln_if(REQUESTSERVER_DEBUG, "Running next job in queue for connection {} @{}", &connection, connection->socket);
|
||||
connection->timer.start();
|
||||
connection->current_url = url;
|
||||
connection->job_data = connection->request_queue.take_first();
|
||||
connection->socket->set_notifications_enabled(true);
|
||||
connection->job_data.start(*connection->socket);
|
||||
|
||||
connection->has_started = true;
|
||||
Core::deferred_invoke([&connection = *connection, url] {
|
||||
dbgln_if(REQUESTSERVER_DEBUG, "Running next job in queue for connection {}", &connection);
|
||||
connection.timer.start();
|
||||
connection.current_url = url;
|
||||
connection.job_data = connection.request_queue.take_first();
|
||||
connection.socket->set_notifications_enabled(true);
|
||||
connection.job_data.start(*connection.socket);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -248,22 +248,22 @@ decltype(auto) get_or_create_connection(auto& cache, URL const& url, auto job, C
|
||||
|
||||
auto& connection = *sockets_for_url[index];
|
||||
if (!connection.has_started) {
|
||||
if (auto result = recreate_socket_if_needed(connection, url); result.is_error()) {
|
||||
dbgln("ConnectionCache: request failed to start, failed to make a socket: {}", result.error());
|
||||
Core::deferred_invoke([job] {
|
||||
job->fail(Core::NetworkJob::Error::ConnectionFailed);
|
||||
});
|
||||
return ReturnType { nullptr };
|
||||
}
|
||||
dbgln_if(REQUESTSERVER_DEBUG, "Immediately start request for url {} in {} - {}", url, &connection, connection.socket);
|
||||
connection.has_started = true;
|
||||
Core::deferred_invoke([&connection, url, job] {
|
||||
connection.has_started = true;
|
||||
connection.removal_timer->stop();
|
||||
connection.timer.start();
|
||||
connection.current_url = url;
|
||||
connection.job_data = decltype(connection.job_data)::create(job);
|
||||
connection.socket->set_notifications_enabled(true);
|
||||
connection.job_data.start(*connection.socket);
|
||||
if (auto result = recreate_socket_if_needed(connection, url); result.is_error()) {
|
||||
dbgln("ConnectionCache: request failed to start, failed to make a socket: {}", result.error());
|
||||
Core::deferred_invoke([job] {
|
||||
job->fail(Core::NetworkJob::Error::ConnectionFailed);
|
||||
});
|
||||
} else {
|
||||
dbgln_if(REQUESTSERVER_DEBUG, "Immediately start request for url {} in {} - {}", url, &connection, connection.socket);
|
||||
connection.removal_timer->stop();
|
||||
connection.timer.start();
|
||||
connection.current_url = url;
|
||||
connection.job_data = decltype(connection.job_data)::create(job);
|
||||
connection.socket->set_notifications_enabled(true);
|
||||
connection.job_data.start(*connection.socket);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dbgln_if(REQUESTSERVER_DEBUG, "Enqueue request for URL {} in {} - {}", url, &connection, connection.socket);
|
||||
|
@ -39,26 +39,30 @@ Messages::RequestServer::IsSupportedProtocolResponse ConnectionFromClient::is_su
|
||||
return supported;
|
||||
}
|
||||
|
||||
Messages::RequestServer::StartRequestResponse ConnectionFromClient::start_request(ByteString const& method, URL const& url, HashMap<ByteString, ByteString> const& request_headers, ByteBuffer const& request_body, Core::ProxyData const& proxy_data)
|
||||
void ConnectionFromClient::start_request(i32 request_id, ByteString const& method, URL const& url, HashMap<ByteString, ByteString> const& request_headers, ByteBuffer const& request_body, Core::ProxyData const& proxy_data)
|
||||
{
|
||||
if (!url.is_valid()) {
|
||||
dbgln("StartRequest: Invalid URL requested: '{}'", url);
|
||||
return { -1, Optional<IPC::File> {} };
|
||||
(void)post_message(Messages::RequestClient::RequestFinished(request_id, false, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
auto* protocol = Protocol::find_by_name(url.scheme().to_byte_string());
|
||||
if (!protocol) {
|
||||
dbgln("StartRequest: No protocol handler for URL: '{}'", url);
|
||||
return { -1, Optional<IPC::File> {} };
|
||||
(void)post_message(Messages::RequestClient::RequestFinished(request_id, false, 0));
|
||||
return;
|
||||
}
|
||||
auto request = protocol->start_request(*this, method, url, request_headers, request_body, proxy_data);
|
||||
auto request = protocol->start_request(request_id, *this, method, url, request_headers, request_body, proxy_data);
|
||||
if (!request) {
|
||||
dbgln("StartRequest: Protocol handler failed to start request: '{}'", url);
|
||||
return { -1, Optional<IPC::File> {} };
|
||||
(void)post_message(Messages::RequestClient::RequestFinished(request_id, false, 0));
|
||||
return;
|
||||
}
|
||||
auto id = request->id();
|
||||
auto fd = request->request_fd();
|
||||
m_requests.set(id, move(request));
|
||||
return { id, IPC::File(fd, IPC::File::CloseAfterSending) };
|
||||
(void)post_message(Messages::RequestClient::RequestStarted(request_id, IPC::File(fd, IPC::File::CloseAfterSending)));
|
||||
}
|
||||
|
||||
Messages::RequestServer::StopRequestResponse ConnectionFromClient::stop_request(i32 request_id)
|
||||
|
@ -32,7 +32,7 @@ private:
|
||||
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
|
||||
|
||||
virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(ByteString const&) override;
|
||||
virtual Messages::RequestServer::StartRequestResponse start_request(ByteString const&, URL const&, HashMap<ByteString, ByteString> const&, ByteBuffer const&, Core::ProxyData const&) override;
|
||||
virtual void start_request(i32 request_id, ByteString const&, URL const&, HashMap<ByteString, ByteString> const&, ByteBuffer const&, Core::ProxyData const&) override;
|
||||
virtual Messages::RequestServer::StopRequestResponse stop_request(i32) override;
|
||||
virtual Messages::RequestServer::SetCertificateResponse set_certificate(i32, ByteString const&, ByteString const&) override;
|
||||
virtual void ensure_connection(URL const& url, ::RequestServer::CacheLevel const& cache_level) override;
|
||||
|
@ -17,7 +17,7 @@ GeminiProtocol::GeminiProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
OwnPtr<Request> GeminiProtocol::start_request(ConnectionFromClient& client, ByteString const&, const URL& url, HashMap<ByteString, ByteString> const&, ReadonlyBytes, Core::ProxyData proxy_data)
|
||||
OwnPtr<Request> GeminiProtocol::start_request(i32 request_id, ConnectionFromClient& client, ByteString const&, const URL& url, HashMap<ByteString, ByteString> const&, ReadonlyBytes, Core::ProxyData proxy_data)
|
||||
{
|
||||
Gemini::GeminiRequest request;
|
||||
request.set_url(url);
|
||||
@ -28,10 +28,12 @@ OwnPtr<Request> GeminiProtocol::start_request(ConnectionFromClient& client, Byte
|
||||
|
||||
auto output_stream = MUST(Core::File::adopt_fd(pipe_result.value().write_fd, Core::File::OpenMode::Write));
|
||||
auto job = Gemini::Job::construct(request, *output_stream);
|
||||
auto protocol_request = GeminiRequest::create_with_job({}, client, *job, move(output_stream));
|
||||
auto protocol_request = GeminiRequest::create_with_job({}, client, *job, move(output_stream), request_id);
|
||||
protocol_request->set_request_fd(pipe_result.value().read_fd);
|
||||
|
||||
ConnectionCache::get_or_create_connection(ConnectionCache::g_tls_connection_cache, url, job, proxy_data);
|
||||
Core::EventLoop::current().deferred_invoke([=] {
|
||||
ConnectionCache::get_or_create_connection(ConnectionCache::g_tls_connection_cache, url, job, proxy_data);
|
||||
});
|
||||
|
||||
return protocol_request;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ public:
|
||||
GeminiProtocol();
|
||||
virtual ~GeminiProtocol() override = default;
|
||||
|
||||
virtual OwnPtr<Request> start_request(ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const&, ReadonlyBytes body, Core::ProxyData proxy_data = {}) override;
|
||||
virtual OwnPtr<Request> start_request(i32, ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const&, ReadonlyBytes body, Core::ProxyData proxy_data = {}) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
namespace RequestServer {
|
||||
|
||||
GeminiRequest::GeminiRequest(ConnectionFromClient& client, NonnullRefPtr<Gemini::Job> job, NonnullOwnPtr<Core::File>&& output_stream)
|
||||
: Request(client, move(output_stream))
|
||||
GeminiRequest::GeminiRequest(ConnectionFromClient& client, NonnullRefPtr<Gemini::Job> job, NonnullOwnPtr<Core::File>&& output_stream, i32 request_id)
|
||||
: Request(client, move(output_stream), request_id)
|
||||
, m_job(move(job))
|
||||
{
|
||||
m_job->on_finish = [this](bool success) {
|
||||
@ -57,9 +57,9 @@ GeminiRequest::~GeminiRequest()
|
||||
m_job->cancel();
|
||||
}
|
||||
|
||||
NonnullOwnPtr<GeminiRequest> GeminiRequest::create_with_job(Badge<GeminiProtocol>, ConnectionFromClient& client, NonnullRefPtr<Gemini::Job> job, NonnullOwnPtr<Core::File>&& output_stream)
|
||||
NonnullOwnPtr<GeminiRequest> GeminiRequest::create_with_job(Badge<GeminiProtocol>, ConnectionFromClient& client, NonnullRefPtr<Gemini::Job> job, NonnullOwnPtr<Core::File>&& output_stream, i32 request_id)
|
||||
{
|
||||
return adopt_own(*new GeminiRequest(client, move(job), move(output_stream)));
|
||||
return adopt_own(*new GeminiRequest(client, move(job), move(output_stream), request_id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ namespace RequestServer {
|
||||
class GeminiRequest final : public Request {
|
||||
public:
|
||||
virtual ~GeminiRequest() override;
|
||||
static NonnullOwnPtr<GeminiRequest> create_with_job(Badge<GeminiProtocol>, ConnectionFromClient&, NonnullRefPtr<Gemini::Job>, NonnullOwnPtr<Core::File>&&);
|
||||
static NonnullOwnPtr<GeminiRequest> create_with_job(Badge<GeminiProtocol>, ConnectionFromClient&, NonnullRefPtr<Gemini::Job>, NonnullOwnPtr<Core::File>&&, i32 request_id);
|
||||
|
||||
Gemini::Job const& job() const { return *m_job; }
|
||||
|
||||
virtual URL url() const override { return m_job->url(); }
|
||||
|
||||
private:
|
||||
explicit GeminiRequest(ConnectionFromClient&, NonnullRefPtr<Gemini::Job>, NonnullOwnPtr<Core::File>&&);
|
||||
explicit GeminiRequest(ConnectionFromClient&, NonnullRefPtr<Gemini::Job>, NonnullOwnPtr<Core::File>&&, i32 request_id);
|
||||
|
||||
virtual void set_certificate(ByteString certificate, ByteString key) override;
|
||||
|
||||
|
@ -61,7 +61,7 @@ void init(TSelf* self, TJob job)
|
||||
}
|
||||
|
||||
template<typename TBadgedProtocol, typename TPipeResult>
|
||||
OwnPtr<Request> start_request(TBadgedProtocol&& protocol, ConnectionFromClient& client, ByteString const& method, const URL& url, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, TPipeResult&& pipe_result, Core::ProxyData proxy_data = {})
|
||||
OwnPtr<Request> start_request(TBadgedProtocol&& protocol, i32 request_id, ConnectionFromClient& client, ByteString const& method, const URL& url, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, TPipeResult&& pipe_result, Core::ProxyData proxy_data = {})
|
||||
{
|
||||
using TJob = typename TBadgedProtocol::Type::JobType;
|
||||
using TRequest = typename TBadgedProtocol::Type::RequestType;
|
||||
@ -99,13 +99,15 @@ OwnPtr<Request> start_request(TBadgedProtocol&& protocol, ConnectionFromClient&
|
||||
|
||||
auto output_stream = MUST(Core::File::adopt_fd(pipe_result.value().write_fd, Core::File::OpenMode::Write));
|
||||
auto job = TJob::construct(move(request), *output_stream);
|
||||
auto protocol_request = TRequest::create_with_job(forward<TBadgedProtocol>(protocol), client, (TJob&)*job, move(output_stream));
|
||||
auto protocol_request = TRequest::create_with_job(forward<TBadgedProtocol>(protocol), client, (TJob&)*job, move(output_stream), request_id);
|
||||
protocol_request->set_request_fd(pipe_result.value().read_fd);
|
||||
|
||||
if constexpr (IsSame<typename TBadgedProtocol::Type, HttpsProtocol>)
|
||||
ConnectionCache::get_or_create_connection(ConnectionCache::g_tls_connection_cache, url, job, proxy_data);
|
||||
else
|
||||
ConnectionCache::get_or_create_connection(ConnectionCache::g_tcp_connection_cache, url, job, proxy_data);
|
||||
Core::EventLoop::current().deferred_invoke([=] {
|
||||
if constexpr (IsSame<typename TBadgedProtocol::Type, HttpsProtocol>)
|
||||
ConnectionCache::get_or_create_connection(ConnectionCache::g_tls_connection_cache, url, job, proxy_data);
|
||||
else
|
||||
ConnectionCache::get_or_create_connection(ConnectionCache::g_tcp_connection_cache, url, job, proxy_data);
|
||||
});
|
||||
|
||||
return protocol_request;
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ HttpProtocol::HttpProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
OwnPtr<Request> HttpProtocol::start_request(ConnectionFromClient& client, ByteString const& method, const URL& url, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data)
|
||||
OwnPtr<Request> HttpProtocol::start_request(i32 request_id, ConnectionFromClient& client, ByteString const& method, const URL& url, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data)
|
||||
{
|
||||
return Detail::start_request(Badge<HttpProtocol> {}, client, method, url, headers, body, get_pipe_for_request(), proxy_data);
|
||||
return Detail::start_request(Badge<HttpProtocol> {}, request_id, client, method, url, headers, body, get_pipe_for_request(), proxy_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
HttpProtocol();
|
||||
~HttpProtocol() override = default;
|
||||
|
||||
virtual OwnPtr<Request> start_request(ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data = {}) override;
|
||||
virtual OwnPtr<Request> start_request(i32, ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data = {}) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
namespace RequestServer {
|
||||
|
||||
HttpRequest::HttpRequest(ConnectionFromClient& client, NonnullRefPtr<HTTP::Job> job, NonnullOwnPtr<Core::File>&& output_stream)
|
||||
: Request(client, move(output_stream))
|
||||
HttpRequest::HttpRequest(ConnectionFromClient& client, NonnullRefPtr<HTTP::Job> job, NonnullOwnPtr<Core::File>&& output_stream, i32 request_id)
|
||||
: Request(client, move(output_stream), request_id)
|
||||
, m_job(job)
|
||||
{
|
||||
Detail::init(this, job);
|
||||
@ -25,9 +25,9 @@ HttpRequest::~HttpRequest()
|
||||
m_job->cancel();
|
||||
}
|
||||
|
||||
NonnullOwnPtr<HttpRequest> HttpRequest::create_with_job(Badge<HttpProtocol>&&, ConnectionFromClient& client, NonnullRefPtr<HTTP::Job> job, NonnullOwnPtr<Core::File>&& output_stream)
|
||||
NonnullOwnPtr<HttpRequest> HttpRequest::create_with_job(Badge<HttpProtocol>&&, ConnectionFromClient& client, NonnullRefPtr<HTTP::Job> job, NonnullOwnPtr<Core::File>&& output_stream, i32 request_id)
|
||||
{
|
||||
return adopt_own(*new HttpRequest(client, move(job), move(output_stream)));
|
||||
return adopt_own(*new HttpRequest(client, move(job), move(output_stream), request_id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace RequestServer {
|
||||
class HttpRequest final : public Request {
|
||||
public:
|
||||
virtual ~HttpRequest() override;
|
||||
static NonnullOwnPtr<HttpRequest> create_with_job(Badge<HttpProtocol>&&, ConnectionFromClient&, NonnullRefPtr<HTTP::Job>, NonnullOwnPtr<Core::File>&&);
|
||||
static NonnullOwnPtr<HttpRequest> create_with_job(Badge<HttpProtocol>&&, ConnectionFromClient&, NonnullRefPtr<HTTP::Job>, NonnullOwnPtr<Core::File>&&, i32);
|
||||
|
||||
HTTP::Job& job() { return m_job; }
|
||||
HTTP::Job const& job() const { return m_job; }
|
||||
@ -25,7 +25,7 @@ public:
|
||||
virtual URL url() const override { return m_job->url(); }
|
||||
|
||||
private:
|
||||
explicit HttpRequest(ConnectionFromClient&, NonnullRefPtr<HTTP::Job>, NonnullOwnPtr<Core::File>&&);
|
||||
explicit HttpRequest(ConnectionFromClient&, NonnullRefPtr<HTTP::Job>, NonnullOwnPtr<Core::File>&&, i32);
|
||||
|
||||
NonnullRefPtr<HTTP::Job> m_job;
|
||||
};
|
||||
|
@ -22,9 +22,9 @@ HttpsProtocol::HttpsProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
OwnPtr<Request> HttpsProtocol::start_request(ConnectionFromClient& client, ByteString const& method, const URL& url, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data)
|
||||
OwnPtr<Request> HttpsProtocol::start_request(i32 request_id, ConnectionFromClient& client, ByteString const& method, const URL& url, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data)
|
||||
{
|
||||
return Detail::start_request(Badge<HttpsProtocol> {}, client, method, url, headers, body, get_pipe_for_request(), proxy_data);
|
||||
return Detail::start_request(Badge<HttpsProtocol> {}, request_id, client, method, url, headers, body, get_pipe_for_request(), proxy_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
HttpsProtocol();
|
||||
~HttpsProtocol() override = default;
|
||||
|
||||
virtual OwnPtr<Request> start_request(ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data = {}) override;
|
||||
virtual OwnPtr<Request> start_request(i32, ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data = {}) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
namespace RequestServer {
|
||||
|
||||
HttpsRequest::HttpsRequest(ConnectionFromClient& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<Core::File>&& output_stream)
|
||||
: Request(client, move(output_stream))
|
||||
HttpsRequest::HttpsRequest(ConnectionFromClient& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<Core::File>&& output_stream, i32 request_id)
|
||||
: Request(client, move(output_stream), request_id)
|
||||
, m_job(job)
|
||||
{
|
||||
Detail::init(this, job);
|
||||
@ -30,9 +30,9 @@ HttpsRequest::~HttpsRequest()
|
||||
m_job->cancel();
|
||||
}
|
||||
|
||||
NonnullOwnPtr<HttpsRequest> HttpsRequest::create_with_job(Badge<HttpsProtocol>&&, ConnectionFromClient& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<Core::File>&& output_stream)
|
||||
NonnullOwnPtr<HttpsRequest> HttpsRequest::create_with_job(Badge<HttpsProtocol>&&, ConnectionFromClient& client, NonnullRefPtr<HTTP::HttpsJob> job, NonnullOwnPtr<Core::File>&& output_stream, i32 request_id)
|
||||
{
|
||||
return adopt_own(*new HttpsRequest(client, move(job), move(output_stream)));
|
||||
return adopt_own(*new HttpsRequest(client, move(job), move(output_stream), request_id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace RequestServer {
|
||||
class HttpsRequest final : public Request {
|
||||
public:
|
||||
virtual ~HttpsRequest() override;
|
||||
static NonnullOwnPtr<HttpsRequest> create_with_job(Badge<HttpsProtocol>&&, ConnectionFromClient&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<Core::File>&&);
|
||||
static NonnullOwnPtr<HttpsRequest> create_with_job(Badge<HttpsProtocol>&&, ConnectionFromClient&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<Core::File>&&, i32);
|
||||
|
||||
HTTP::HttpsJob& job() { return m_job; }
|
||||
HTTP::HttpsJob const& job() const { return m_job; }
|
||||
@ -24,7 +24,7 @@ public:
|
||||
virtual URL url() const override { return m_job->url(); }
|
||||
|
||||
private:
|
||||
explicit HttpsRequest(ConnectionFromClient&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<Core::File>&&);
|
||||
explicit HttpsRequest(ConnectionFromClient&, NonnullRefPtr<HTTP::HttpsJob>, NonnullOwnPtr<Core::File>&&, i32);
|
||||
|
||||
virtual void set_certificate(ByteString certificate, ByteString key) override;
|
||||
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
virtual ~Protocol();
|
||||
|
||||
ByteString const& name() const { return m_name; }
|
||||
virtual OwnPtr<Request> start_request(ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data = {}) = 0;
|
||||
virtual OwnPtr<Request> start_request(i32, ConnectionFromClient&, ByteString const& method, const URL&, HashMap<ByteString, ByteString> const& headers, ReadonlyBytes body, Core::ProxyData proxy_data = {}) = 0;
|
||||
|
||||
static Protocol* find_by_name(ByteString const&);
|
||||
|
||||
|
@ -9,12 +9,9 @@
|
||||
|
||||
namespace RequestServer {
|
||||
|
||||
// FIXME: What about rollover?
|
||||
static i32 s_next_id = 1;
|
||||
|
||||
Request::Request(ConnectionFromClient& client, NonnullOwnPtr<Core::File>&& output_stream)
|
||||
Request::Request(ConnectionFromClient& client, NonnullOwnPtr<Core::File>&& output_stream, i32 request_id)
|
||||
: m_client(client)
|
||||
, m_id(s_next_id++)
|
||||
, m_id(request_id)
|
||||
, m_output_stream(move(output_stream))
|
||||
{
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
Core::File const& output_stream() const { return *m_output_stream; }
|
||||
|
||||
protected:
|
||||
explicit Request(ConnectionFromClient&, NonnullOwnPtr<Core::File>&&);
|
||||
explicit Request(ConnectionFromClient&, NonnullOwnPtr<Core::File>&&, i32 request_id);
|
||||
|
||||
private:
|
||||
ConnectionFromClient& m_client;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
endpoint RequestClient
|
||||
{
|
||||
request_started(i32 request_id, IPC::File fd) =|
|
||||
request_progress(i32 request_id, Optional<u64> total_size, u64 downloaded_size) =|
|
||||
request_finished(i32 request_id, bool success, u64 total_size) =|
|
||||
headers_became_available(i32 request_id, HashMap<ByteString,ByteString,CaseInsensitiveStringTraits> response_headers, Optional<u32> status_code) =|
|
||||
|
@ -6,7 +6,7 @@ endpoint RequestServer
|
||||
// Test if a specific protocol is supported, e.g "http"
|
||||
is_supported_protocol(ByteString protocol) => (bool supported)
|
||||
|
||||
start_request(ByteString method, URL url, HashMap<ByteString,ByteString> request_headers, ByteBuffer request_body, Core::ProxyData proxy_data) => (i32 request_id, Optional<IPC::File> response_fd)
|
||||
start_request(i32 request_id, ByteString method, URL url, HashMap<ByteString,ByteString> request_headers, ByteBuffer request_body, Core::ProxyData proxy_data) =|
|
||||
stop_request(i32 request_id) => (bool success)
|
||||
set_certificate(i32 request_id, ByteString certificate, ByteString key) => (bool success)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user