summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-02-11 20:25:15 +0100
committerAndreas Kling <kling@serenityos.org>2022-02-11 20:25:15 +0100
commit5f5fe103eb905880e178b005a5482231280efd95 (patch)
tree37f9b26006f029326413b99839a8b9250932b372
parentba5bbde7ee9aaa8667e54c220efce54eb4e833ec (diff)
downloadserenity-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.cpp12
-rw-r--r--Userland/Libraries/LibHTTP/Job.h19
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;