piped-input-stream, chunked encoding, errors, trailer

53 views
Skip to first unread message

Brian Craft

unread,
May 6, 2017, 7:26:09 PM5/6/17
to Ring
Now that I have piped-input-stream working, server errors are being swallowed. I'm guessing this is because ring has already sent the status 200 when an error occurs, and there's no default error handling. I'm not sure about correct behavior, but it looks like I should be generating a Trailer to the chunked encoding to indicate the server errors status to the client.

I'm not sure how to do that from piped-input-stream.

James Reeves

unread,
May 6, 2017, 8:44:05 PM5/6/17
to Ring
The status code has to be set before the body starts streaming. In HTTP/1.1 and below this is mandated by the protocol, because the status must be sent before the body. If you need an accurate status code, you need to buffer the body, or add a custom marker onto the end of the body stream to denote failure.

In HTTP/2 I believe it's possible to send the status code after the body, because in HTTP/2 the status code is a psuedo-header, and header frames can either precede or succeed the response body data. However, Ring has currently no support for this behaviour, and in any case it's likely we need to support HTTP/1.1 for some time to come.

- James

On 7 May 2017 at 00:26, Brian Craft <craft...@gmail.com> wrote:
Now that I have piped-input-stream working, server errors are being swallowed. I'm guessing this is because ring has already sent the status 200 when an error occurs, and there's no default error handling. I'm not sure about correct behavior, but it looks like I should be generating a Trailer to the chunked encoding to indicate the server errors status to the client.

I'm not sure how to do that from piped-input-stream.

--
You received this message because you are subscribed to the Google Groups "Ring" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ring-clojure+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brian Craft

unread,
May 6, 2017, 11:43:04 PM5/6/17
to Ring, ja...@booleanknot.com
This is what I'm asking about:


http/1.1 trailer, instead of custom end marker.
To unsubscribe from this group and stop receiving emails from it, send an email to ring-clojure...@googlegroups.com.

James Reeves

unread,
May 7, 2017, 12:25:50 AM5/7/17
to Brian Craft, Ring
Ah, I see what you mean. Unfortunately Ring doesn't currently support HTTP trailers, and neither does the latest Servlet spec, so we can't fall back to that.

I don't think you'll be able to add trailers through the OutputStream either, because they need to come after the final chunk. You might be able to do it if you can set a content-length header, but the HTTP server behind the adapter might stop those sort of shenanigans.

You could create a custom Ring adapter with support for a :trailers key, perhaps using a delay that would be forced when after the output stream is closed. This would tie you to a specific adapter (such as Jetty), but I don't think it would be too onerous to adapt ring.adapter.jetty to that purpose.

Alternatively, you could encode the error in the output you're producing. For example, if you're streaming a JSON array, you could wrap it in an object:

  {
    "results": [
      ...streaming...
    ],
    "status": {"type": "error"}
  }

That's the most straightforward solution I can think of.

- James

Brian Craft

unread,
May 7, 2017, 12:31:17 AM5/7/17
to Ring, craft...@gmail.com, ja...@booleanknot.com
Looks like it doesn't really matter, because none of the UAs support it. Apparently a custom marker is the only thing that works today.
Reply all
Reply to author
Forward
0 new messages