mirror of
https://github.com/matrix-construct/construct
synced 2024-09-27 11:18:51 +02:00
ircd::resource: Internalize the buffering boilerplate used with json::stack.
This commit is contained in:
parent
d4a3b3c91d
commit
2140f42cd7
2 changed files with 56 additions and 17 deletions
|
@ -163,11 +163,17 @@ struct ircd::resource::response
|
|||
struct ircd::resource::response::chunked
|
||||
:resource::response
|
||||
{
|
||||
static conf::item<size_t> default_buffer_size;
|
||||
|
||||
client *c {nullptr};
|
||||
unique_buffer<mutable_buffer> buf;
|
||||
|
||||
size_t write(const const_buffer &chunk);
|
||||
const_buffer flush(const const_buffer &);
|
||||
bool finish();
|
||||
|
||||
std::function<const_buffer (const const_buffer &)> flusher();
|
||||
|
||||
chunked(client &, const http::code &, const string_view &content_type, const string_view &headers = {});
|
||||
chunked(client &, const http::code &, const string_view &content_type, const vector_view<const http::header> &);
|
||||
chunked(client &, const http::code &, const vector_view<const http::header> &);
|
||||
|
|
|
@ -658,33 +658,49 @@ ircd::resource::response::chunked::chunked(client &client,
|
|||
const http::code &code,
|
||||
const string_view &content_type,
|
||||
const vector_view<const http::header> &headers)
|
||||
:c{&client}
|
||||
:chunked
|
||||
{
|
||||
assert(!empty(content_type));
|
||||
|
||||
thread_local char buffer[4_KiB];
|
||||
window_buffer sb{buffer};
|
||||
client, code, content_type, [&headers]
|
||||
{
|
||||
const critical_assertion ca;
|
||||
// Note that the headers which are composed into this buffer are
|
||||
// copied again before the response goes out from resource::response.
|
||||
// There must not be any context switch between now and that copy so
|
||||
// we can return a string_view of this TLS buffer.
|
||||
|
||||
thread_local char buffer[4_KiB];
|
||||
window_buffer sb{buffer};
|
||||
http::write(sb, headers);
|
||||
}
|
||||
|
||||
response
|
||||
{
|
||||
client, code, content_type, size_t(-1), string_view{sb.completed()}
|
||||
};
|
||||
return string_view{sb.completed()};
|
||||
}()
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
decltype(ircd::resource::response::chunked::default_buffer_size)
|
||||
ircd::resource::response::chunked::default_buffer_size
|
||||
{
|
||||
{ "name", "ircd.resource.response.chunked.buffer_size" },
|
||||
{ "default", long(96_KiB) },
|
||||
};
|
||||
|
||||
ircd::resource::response::chunked::chunked(client &client,
|
||||
const http::code &code,
|
||||
const string_view &content_type,
|
||||
const string_view &headers)
|
||||
:c{&client}
|
||||
:response
|
||||
{
|
||||
response
|
||||
{
|
||||
client, code, content_type, size_t(-1), headers
|
||||
};
|
||||
client, code, content_type, size_t(-1), headers
|
||||
}
|
||||
,c
|
||||
{
|
||||
&client
|
||||
}
|
||||
,buf
|
||||
{
|
||||
size_t(default_buffer_size)
|
||||
}
|
||||
{
|
||||
assert(!empty(content_type));
|
||||
}
|
||||
|
||||
ircd::resource::response::chunked::~chunked()
|
||||
|
@ -703,6 +719,12 @@ catch(...)
|
|||
return;
|
||||
}
|
||||
|
||||
std::function<ircd::const_buffer (const ircd::const_buffer &)>
|
||||
ircd::resource::response::chunked::flusher()
|
||||
{
|
||||
return std::bind(&chunked::flush, this, ph::_1);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::resource::response::chunked::finish()
|
||||
{
|
||||
|
@ -714,6 +736,17 @@ ircd::resource::response::chunked::finish()
|
|||
return true;
|
||||
}
|
||||
|
||||
ircd::const_buffer
|
||||
ircd::resource::response::chunked::flush(const const_buffer &buf)
|
||||
{
|
||||
const const_buffer wrote
|
||||
{
|
||||
data(buf), write(buf)
|
||||
};
|
||||
|
||||
return wrote;
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::resource::response::chunked::write(const const_buffer &chunk)
|
||||
try
|
||||
|
|
Loading…
Reference in a new issue