Skip to content

Commit cb9122a

Browse files
committed
vsgi: Write the response head on disposal
The router cannot initialize with 'chunked' encoding, because it would break empty responses. It must therefore be an explicit choice from the end-user knowingly that something will be produced. There's no need for the post-condition since we can be assured that the head will be written on disposal. Update the documentation to to include that behaviour.
1 parent e5470cc commit cb9122a

File tree

4 files changed

+20
-26
lines changed

4 files changed

+20
-26
lines changed

docs/vsgi/index.rst

+2-17
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,8 @@ line and headers synchronously in the connection stream before returning an
4242

4343
.. _GLib.OutputStream: http://valadoc.org/#!api=gio-2.0/GLib.OutputStream
4444

45-
.. warning::
46-
47-
The :doc:`response` body must be accessed at least once during the
48-
processing to ensure that the headers are written and filters applied.
49-
50-
Some VSGI implementations rely on stream filtering to produce proper responses
51-
(chunked or gzipped ones) and these are applied when the body is accessed for
52-
the first time.
53-
54-
.. code:: vala
55-
56-
new Server ("org.vsgi.App", (req, res) => {
57-
res.status = 200;
58-
res.headers.append ("Transfer-Encoding", "chunked");
59-
// chunked encoding will be applied
60-
res.body.write_all ("Hello world!".data, null);
61-
});
45+
In case the body is not accessed, the head is written synchronously on disposal
46+
of the :doc:`response` object.
6247

6348
Asynchronous processing
6449
-----------------------

src/valum-router.vala

-7
Original file line numberDiff line numberDiff line change
@@ -421,16 +421,9 @@ namespace Valum {
421421
* raise a {@link Valum.Status.ClientError.METHOD_NOT_ALLOWED}, otherwise
422422
* raise a {@link Valum.Status.ClientError.NOT_FOUND} exception.
423423
*
424-
* The response is initialized with 'chunked' transfer encoding since
425-
* most processing are generally based on stream.
426-
*
427424
* @since 0.1
428425
*/
429426
public void handle (Request req, Response res) {
430-
// sane initialization
431-
if (req.http_version == Soup.HTTPVersion.@1_1)
432-
res.headers.set_encoding (Soup.Encoding.CHUNKED);
433-
434427
// initial invocation
435428
this.invoke (req, res, () => {
436429
var stack = new Queue<Value?> ();

src/vsgi-response.vala

+17-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace VSGI {
8787
this.write_head (out bytes_written);
8888
}
8989
} catch (IOError err) {
90-
warning ("could not write the head in the connection stream");
90+
warning ("could not write the head in the connection stream: %s", err.message);
9191
}
9292

9393
return this.request.connection.output_stream;
@@ -183,5 +183,21 @@ namespace VSGI {
183183
return this.head_written;
184184
}
185185
#endif
186+
187+
/**
188+
* Write the head before disposing references to other objects.
189+
*/
190+
public override void dispose () {
191+
try {
192+
if (!head_written) {
193+
size_t bytes_written;
194+
write_head (out bytes_written);
195+
}
196+
} catch (IOError err) {
197+
warning ("could not write the head in the connection stream: %s", err.message);
198+
} finally {
199+
base.dispose ();
200+
}
201+
}
186202
}
187203
}

src/vsgi-server.vala

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ namespace VSGI {
7373
* Once dispatched, the {@link Response.head_written} property is
7474
* expected to be true unless its reference still held somewhere else.
7575
*/
76-
protected void dispatch (Request req, Response res) ensures (res.ref_count > 1 || res.head_written) {
76+
protected void dispatch (Request req, Response res) {
7777
_application (req, res);
7878
}
7979
}

0 commit comments

Comments
 (0)