mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:37:45 +00:00
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.
This commit is contained in:
parent
ba5bbde7ee
commit
5f5fe103eb
2 changed files with 24 additions and 7 deletions
|
@ -110,7 +110,7 @@ void Job::flush_received_buffers()
|
||||||
return;
|
return;
|
||||||
dbgln_if(JOB_DEBUG, "Job: Flushing received buffers: have {} bytes in {} buffers for {}", m_buffered_size, m_received_buffers.size(), m_request.url());
|
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) {
|
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);
|
auto result = do_write(payload);
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
if (!result.error().is_errno()) {
|
if (!result.error().is_errno()) {
|
||||||
|
@ -127,7 +127,7 @@ void Job::flush_received_buffers()
|
||||||
m_buffered_size -= written;
|
m_buffered_size -= written;
|
||||||
if (written == payload.size()) {
|
if (written == payload.size()) {
|
||||||
// FIXME: Make this a take-first-friendly object?
|
// FIXME: Make this a take-first-friendly object?
|
||||||
m_received_buffers.take_first();
|
(void)m_received_buffers.take_first();
|
||||||
--i;
|
--i;
|
||||||
continue;
|
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_buffered_size += payload.size();
|
||||||
m_received_size += payload.size();
|
m_received_size += payload.size();
|
||||||
flush_received_buffers();
|
flush_received_buffers();
|
||||||
|
@ -579,8 +579,8 @@ void Job::finish_up()
|
||||||
|
|
||||||
u8* flat_ptr = flattened_buffer.data();
|
u8* flat_ptr = flattened_buffer.data();
|
||||||
for (auto& received_buffer : m_received_buffers) {
|
for (auto& received_buffer : m_received_buffers) {
|
||||||
memcpy(flat_ptr, received_buffer.data(), received_buffer.size());
|
memcpy(flat_ptr, received_buffer.pending_flush.data(), received_buffer.pending_flush.size());
|
||||||
flat_ptr += received_buffer.size();
|
flat_ptr += received_buffer.pending_flush.size();
|
||||||
}
|
}
|
||||||
m_received_buffers.clear();
|
m_received_buffers.clear();
|
||||||
|
|
||||||
|
@ -595,7 +595,7 @@ void Job::finish_up()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_buffered_size = flattened_buffer.size();
|
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;
|
m_can_stream_response = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/FileStream.h>
|
#include <AK/FileStream.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
|
#include <AK/NonnullOwnPtrVector.h>
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
#include <LibCore/NetworkJob.h>
|
#include <LibCore/NetworkJob.h>
|
||||||
#include <LibHTTP/HttpRequest.h>
|
#include <LibHTTP/HttpRequest.h>
|
||||||
|
@ -54,7 +55,23 @@ protected:
|
||||||
int m_code { -1 };
|
int m_code { -1 };
|
||||||
HashMap<String, String, CaseInsensitiveStringTraits> m_headers;
|
HashMap<String, String, CaseInsensitiveStringTraits> m_headers;
|
||||||
Vector<String> m_set_cookie_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_buffered_size { 0 };
|
||||||
size_t m_received_size { 0 };
|
size_t m_received_size { 0 };
|
||||||
Optional<u32> m_content_length;
|
Optional<u32> m_content_length;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue