diff options
author | Andreas Kling <kling@serenityos.org> | 2022-02-11 20:25:15 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-11 20:25:15 +0100 |
commit | 5f5fe103eb905880e178b005a5482231280efd95 (patch) | |
tree | 37f9b26006f029326413b99839a8b9250932b372 | |
parent | ba5bbde7ee9aaa8667e54c220efce54eb4e833ec (diff) | |
download | serenity-5f5fe103eb905880e178b005a5482231280efd95.zip |
LibHTTP: Don't copy payload slices in flush_received_buffers()
Instead of using ByteBuffer::slice() to carve off the remaining part of
the payload every time we flush a part of it, we now keep a sliding
span (ReadonlyBytes) over it.
-rw-r--r-- | Userland/Libraries/LibHTTP/Job.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibHTTP/Job.h | 19 |
2 files changed, 24 insertions, 7 deletions
diff --git a/Userland/Libraries/LibHTTP/Job.cpp b/Userland/Libraries/LibHTTP/Job.cpp index 52004cda26..e07e234d66 100644 --- a/Userland/Libraries/LibHTTP/Job.cpp +++ b/Userland/Libraries/LibHTTP/Job.cpp @@ -110,7 +110,7 @@ void Job::flush_received_buffers() return; dbgln_if(JOB_DEBUG, "Job: Flushing received buffers: have {} bytes in {} buffers for {}", m_buffered_size, m_received_buffers.size(), m_request.url()); for (size_t i = 0; i < m_received_buffers.size(); ++i) { - auto& payload = m_received_buffers[i]; + auto& payload = m_received_buffers[i].pending_flush; auto result = do_write(payload); if (result.is_error()) { if (!result.error().is_errno()) { @@ -127,7 +127,7 @@ void Job::flush_received_buffers() m_buffered_size -= written; if (written == payload.size()) { // FIXME: Make this a take-first-friendly object? - m_received_buffers.take_first(); + (void)m_received_buffers.take_first(); --i; continue; } @@ -506,7 +506,7 @@ void Job::on_socket_connected() } } - m_received_buffers.append(payload); + m_received_buffers.append(make<ReceivedBuffer>(payload)); m_buffered_size += payload.size(); m_received_size += payload.size(); flush_received_buffers(); @@ -579,8 +579,8 @@ void Job::finish_up() u8* flat_ptr = flattened_buffer.data(); for (auto& received_buffer : m_received_buffers) { - memcpy(flat_ptr, received_buffer.data(), received_buffer.size()); - flat_ptr += received_buffer.size(); + memcpy(flat_ptr, received_buffer.pending_flush.data(), received_buffer.pending_flush.size()); + flat_ptr += received_buffer.pending_flush.size(); } m_received_buffers.clear(); @@ -595,7 +595,7 @@ void Job::finish_up() } m_buffered_size = flattened_buffer.size(); - m_received_buffers.append(move(flattened_buffer)); + m_received_buffers.append(make<ReceivedBuffer>(move(flattened_buffer))); m_can_stream_response = true; } diff --git a/Userland/Libraries/LibHTTP/Job.h b/Userland/Libraries/LibHTTP/Job.h index 9a5da1d5ac..91eeac4fce 100644 --- a/Userland/Libraries/LibHTTP/Job.h +++ b/Userland/Libraries/LibHTTP/Job.h @@ -8,6 +8,7 @@ #include <AK/FileStream.h> #include <AK/HashMap.h> +#include <AK/NonnullOwnPtrVector.h> #include <AK/Optional.h> #include <LibCore/NetworkJob.h> #include <LibHTTP/HttpRequest.h> @@ -54,7 +55,23 @@ protected: int m_code { -1 }; HashMap<String, String, CaseInsensitiveStringTraits> m_headers; Vector<String> m_set_cookie_headers; - Vector<ByteBuffer, 2> m_received_buffers; + + struct ReceivedBuffer { + ReceivedBuffer(ByteBuffer d) + : data(move(d)) + , pending_flush(data.bytes()) + { + } + + // The entire received buffer. + ByteBuffer data; + + // The bytes we have yet to flush. (This is a slice of `data`) + ReadonlyBytes pending_flush; + }; + + NonnullOwnPtrVector<ReceivedBuffer> m_received_buffers; + size_t m_buffered_size { 0 }; size_t m_received_size { 0 }; Optional<u32> m_content_length; |