diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2022-02-02 19:21:55 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-06 13:10:10 +0100 |
commit | aafc451016b342886f7f1d0d51794f064f313e04 (patch) | |
tree | db1d8931ea335c87b508149e0f46c916bc6dbb3c /Userland/Libraries/LibProtocol | |
parent | 7a95c451a3bc4eb379e12c8243b878f73a3dd03d (diff) | |
download | serenity-aafc451016b342886f7f1d0d51794f064f313e04.zip |
Userland: Convert TLS::TLSv12 to a Core::Stream::Socket
This commit converts TLS::TLSv12 to a Core::Stream object, and in the
process allows TLS to now wrap other Core::Stream::Socket objects.
As a large part of LibHTTP and LibGemini depend on LibTLS's interface,
this also converts those to support Core::Stream, which leads to a
simplification of LibHTTP (as there's no need to care about the
underlying socket type anymore).
Note that RequestServer now controls the TLS socket options, which is a
better place anyway, as RS is the first receiver of the user-requested
options (though this is currently not particularly useful).
Diffstat (limited to 'Userland/Libraries/LibProtocol')
-rw-r--r-- | Userland/Libraries/LibProtocol/Request.cpp | 83 | ||||
-rw-r--r-- | Userland/Libraries/LibProtocol/Request.h | 17 |
2 files changed, 44 insertions, 56 deletions
diff --git a/Userland/Libraries/LibProtocol/Request.cpp b/Userland/Libraries/LibProtocol/Request.cpp index 741ff6956b..35b7cbb2c7 100644 --- a/Userland/Libraries/LibProtocol/Request.cpp +++ b/Userland/Libraries/LibProtocol/Request.cpp @@ -20,72 +20,61 @@ bool Request::stop() return m_client->stop_request({}, *this); } -void Request::stream_into(OutputStream& stream) +template<typename T> +void Request::stream_into_impl(T& stream) { VERIFY(!m_internal_stream_data); - auto notifier = Core::Notifier::construct(fd(), Core::Notifier::Read); - - m_internal_stream_data = make<InternalStreamData>(fd()); - m_internal_stream_data->read_notifier = notifier; + m_internal_stream_data = make<InternalStreamData>(MUST(Core::Stream::File::adopt_fd(fd(), Core::Stream::OpenMode::Read))); + m_internal_stream_data->read_notifier = Core::Notifier::construct(fd(), Core::Notifier::Read); auto user_on_finish = move(on_finish); on_finish = [this](auto success, auto total_size) { m_internal_stream_data->success = success; m_internal_stream_data->total_size = total_size; m_internal_stream_data->request_done = true; + m_internal_stream_data->on_finish(); }; - notifier->on_ready_to_read = [this, &stream, user_on_finish = move(user_on_finish)] { - constexpr size_t buffer_size = 4096; - static char buf[buffer_size]; - auto nread = m_internal_stream_data->read_stream.read({ buf, buffer_size }); - if (!stream.write_or_error({ buf, nread })) { - // FIXME: What do we do here? - TODO(); + m_internal_stream_data->on_finish = [this, user_on_finish = move(user_on_finish)] { + if (!m_internal_stream_data->user_finish_called && m_internal_stream_data->read_stream->is_eof()) { + m_internal_stream_data->user_finish_called = true; + user_on_finish(m_internal_stream_data->success, m_internal_stream_data->total_size); } - - if (m_internal_stream_data->read_stream.eof() && m_internal_stream_data->request_done) { + }; + m_internal_stream_data->read_notifier->on_ready_to_read = [this, &stream] { + constexpr size_t buffer_size = 16 * KiB; + static char buf[buffer_size]; + do { + auto result = m_internal_stream_data->read_stream->read({ buf, buffer_size }); + if (result.is_error() && (!result.error().is_errno() || (result.error().is_errno() && result.error().code() != EINTR))) + break; + if (result.is_error()) + continue; + auto nread = result.value(); + if (!stream.write_or_error({ buf, nread })) { + // FIXME: What do we do here? + TODO(); + } + if (nread == 0) + break; + } while (true); + + if (m_internal_stream_data->read_stream->is_eof() && m_internal_stream_data->request_done) { m_internal_stream_data->read_notifier->close(); - user_on_finish(m_internal_stream_data->success, m_internal_stream_data->total_size); - } else { - m_internal_stream_data->read_stream.handle_any_error(); + m_internal_stream_data->on_finish(); } }; } void Request::stream_into(Core::Stream::Stream& stream) { - VERIFY(!m_internal_stream_data); - - auto notifier = Core::Notifier::construct(fd(), Core::Notifier::Read); - - m_internal_stream_data = make<InternalStreamData>(fd()); - m_internal_stream_data->read_notifier = notifier; - - auto user_on_finish = move(on_finish); - on_finish = [this](auto success, auto total_size) { - m_internal_stream_data->success = success; - m_internal_stream_data->total_size = total_size; - m_internal_stream_data->request_done = true; - }; - - notifier->on_ready_to_read = [this, &stream, user_on_finish = move(user_on_finish)] { - constexpr size_t buffer_size = 4096; - static char buf[buffer_size]; - auto nread = m_internal_stream_data->read_stream.read({ buf, buffer_size }); - if (!stream.write_or_error({ buf, nread })) { - // FIXME: What do we do here? - TODO(); - } + stream_into_impl(stream); +} - if (m_internal_stream_data->read_stream.eof() && m_internal_stream_data->request_done) { - m_internal_stream_data->read_notifier->close(); - user_on_finish(m_internal_stream_data->success, m_internal_stream_data->total_size); - } else { - m_internal_stream_data->read_stream.handle_any_error(); - } - }; +void Request::stream_into(OutputStream& stream) +{ + stream_into_impl(stream); } void Request::set_should_buffer_all_input(bool value) @@ -102,7 +91,7 @@ void Request::set_should_buffer_all_input(bool value) VERIFY(!m_internal_stream_data); VERIFY(!m_internal_buffered_data); VERIFY(on_buffered_request_finish); // Not having this set makes no sense. - m_internal_buffered_data = make<InternalBufferedData>(fd()); + m_internal_buffered_data = make<InternalBufferedData>(); m_should_buffer_all_input = true; on_headers_received = [this](auto& headers, auto response_code) { diff --git a/Userland/Libraries/LibProtocol/Request.h b/Userland/Libraries/LibProtocol/Request.h index cf5cf51262..b649a208ae 100644 --- a/Userland/Libraries/LibProtocol/Request.h +++ b/Userland/Libraries/LibProtocol/Request.h @@ -62,6 +62,9 @@ public: private: explicit Request(RequestClient&, i32 request_id); + template<typename T> + void stream_into_impl(T&); + WeakPtr<RequestClient> m_client; int m_request_id { -1 }; RefPtr<Core::Notifier> m_write_notifier; @@ -69,28 +72,24 @@ private: bool m_should_buffer_all_input { false }; struct InternalBufferedData { - InternalBufferedData(int fd) - : read_stream(fd) - { - } - - InputFileStream read_stream; DuplexMemoryStream payload_stream; HashMap<String, String, CaseInsensitiveStringTraits> response_headers; Optional<u32> response_code; }; struct InternalStreamData { - InternalStreamData(int fd) - : read_stream(fd) + InternalStreamData(NonnullOwnPtr<Core::Stream::Stream> stream) + : read_stream(move(stream)) { } - InputFileStream read_stream; + NonnullOwnPtr<Core::Stream::Stream> read_stream; RefPtr<Core::Notifier> read_notifier; bool success; u32 total_size { 0 }; bool request_done { false }; + Function<void()> on_finish {}; + bool user_finish_called { false }; }; OwnPtr<InternalBufferedData> m_internal_buffered_data; |