summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibProtocol
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2022-02-02 19:21:55 +0330
committerAndreas Kling <kling@serenityos.org>2022-02-06 13:10:10 +0100
commitaafc451016b342886f7f1d0d51794f064f313e04 (patch)
treedb1d8931ea335c87b508149e0f46c916bc6dbb3c /Userland/Libraries/LibProtocol
parent7a95c451a3bc4eb379e12c8243b878f73a3dd03d (diff)
downloadserenity-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.cpp83
-rw-r--r--Userland/Libraries/LibProtocol/Request.h17
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;