diff --git a/examples/app/app.vala b/examples/app/app.vala index 58e23d5dc..22562f4f0 100644 --- a/examples/app/app.vala +++ b/examples/app/app.vala @@ -30,6 +30,14 @@ app.get ("", (req, res, next) => { template.to_stream (res.body); }); +app.get ("buffered", (req, res, next) => { + res.headers.set_content_length (resources_lookup_data ("/templates/home.html", ResourceLookupFlags.NONE).length); + next (req, new VSGI.BufferedResponse (res)); +}).then((req, res) => { + var template = new View.from_resources ("/templates/home.html"); + template.to_stream (res.body); +}); + app.get ("gzip", (req, res, next) => { res.headers.replace ("Content-Encoding", "gzip"); next (req, new VSGI.ConvertedResponse (res, new ZlibCompressor (ZlibCompressorFormat.GZIP))); diff --git a/src/vsgi-buffered-response.vala b/src/vsgi-buffered-response.vala new file mode 100644 index 000000000..1e75693e4 --- /dev/null +++ b/src/vsgi-buffered-response.vala @@ -0,0 +1,50 @@ +using GLib; +using Soup; + +namespace VSGI { + + /** + * Buffers the body of a response. + + * Unlike the traditional {@link VSGI.Response}, the head is not written + * when the body is accessed, but instead flushed. Modifications to the + * status line and headers can still occur even if content has been written + * to the body stream. + + * The default size of the buffer is set to the value of the 'Content-Length' + * header or defaults to 4 kilobytes if it hasn't been set. + * + * If the 'Content-Length' header is set in the response + * The default size of the buffer is + * + * @since 0.3 + */ + public class BufferedResponse : FilteredResponse { + + public BufferedOutputStream buffer { construct; get; } + + public override OutputStream body { + get { + return this.buffer; + } + } + + /** + * + * + * @since 0.3 + */ + public BufferedResponse (Response base_response) { + base_response.head_written = true; // trick the response into + var buffer = base_response.headers.get_encoding () == Encoding.CONTENT_LENGTH ? + new BufferedOutputStream.sized (base_response.body, (size_t) base_response.headers.get_content_length ()) : + new BufferedOutputStream (base_response.body); + Object (base_response: base_response, buffer: buffer); + } + + public BufferedResponse.sized (Response base_response, uint buffer_size) { + base_response.head_written = true; // trick the response into + Object (base_response: base_response, buffer: new BufferedOutputStream.sized (base_response.body, buffer_size)); + } + } +} diff --git a/src/vsgi-response.vala b/src/vsgi-response.vala index 2ed9d405c..ef69cb521 100644 --- a/src/vsgi-response.vala +++ b/src/vsgi-response.vala @@ -53,7 +53,7 @@ namespace VSGI { * * @since 0.2 */ - public bool head_written { get; protected set; default = false; } + public bool head_written { get; protected construct set; default = false; } /** * Response body.