I'm assuming chunked Transfer-Encoding, which is IIRC what the Racket web
server uses for unknown-length payloads. If the server hasn't committed to
chunked encoding (by sending the header), then it probably hasn't sent the
status code either. So truncation is definitely detectable.

RFC 7230 Section 6.3.1 and 6.3.2 give more specific guidance than "do the
right thing", as I read it. I would summarize it as: Only automatically
retry if you know that the operation is idempotent (6.3.1) or hadn't been
processed yet (6.3.2), and only automatically retry once; otherwise, kick
the error up a level and let them decide.

RFC 7230 Section 9.6 (Message Integrity) mentions using "length or
chunk-delimited framing to detect completeness", so I think using a chunk
framing violation to signal incompleteness is fair game.

Re semantics: I haven't read that RFC yet, but generally, *semantics* only
apply to *syntactically* well-formed things. So introducing a syntax error
(the chunk framing violation) is a good way of saying "nevermind, don't
even *try* to interpret this payload", given that there are no other
options.

Re TCP: It's not a TCP error, and the client shouldn't assume it was.
Section 6.3.1 starts with "Connections can be closed at any time, with or
without intention." And the idea generalizes to any connection-oriented
transport layer. (Hanging up the phone isn't a phone error, and if you're,
say, a telemarketer, you probably wouldn't even consider the possibility
that it was a network failure.)

So I still think closing the connection after making the response
syntactically valid is a good default for the Racket web server.

BTW, if you control the client, you could also use "trailing headers" (see
Section 4.1), but the internet tells me that browsers don't support them.

Ryan


On Mon, May 25, 2020 at 9:48 PM Norman Gray <norman.g...@glasgow.ac.uk>
wrote:

>
> Ryan and Matthew, hello.
>
> On 25 May 2020, at 19:43, Ryan Culpepper wrote:
>
> > As I understand the HTTP protocol (that is, some but not lots), the
> > most
> > reasonable thing for the server to do if it discovers an error after
> > the
> > status code has been sent seems to be to just hang up and let the
> > client
> > realize that *something* went wrong. I don't mean just truncate the
> > output;
> > I mean the server should say "here comes another chunk" and then close
> > the
> > TCP connection, so it cannot be mistaken for a valid response. (The
> > servlet
> > should probably make a note so the next request doesn't just fail in
> > exactly the same way.)
>
> I have spent a fair amount of quality time with the HTTP RFCs, and I'm
> surprised I can't think of an answer to this off the top of my head.
>
> Looking through RFC 7230, however (RFCs 7230--5 replace RFC 2616), we
> find in Sect.3.3.3 'Message Body Length',
>
>     Since there is no way to distinguish a successfully completed,
>     close-delimited message from a partially received message
> interrupted
>     by network failure, a server SHOULD generate encoding or
>     length-delimited messages whenever possible.  The close-delimiting
>     feature exists primarily for backwards compatibility with HTTP/1.0.
>
> If a response includes a Content-Length header, then truncation would be
> detectable, if not, not.
>
> This passage is talking about network failure, but I think the
> server-failure we're talking about here is morally similar.  RFC 7230
> Sect 6.3.2, though it's talking about a slightly different thing, also
> conceives of the notion of 'partial failure conditions' whilst being
> vague about what these are or what a client should do (the implication
> is that the client should... do the right thing).
>
> HTTP is generally deliberately rather vague about the payload -- the
> representation of the named resource -- and RFC 7231 Sect.3.3 'Payload
> Semantics' is a mere four paragraphs long.  It includes text
>
>     For example, the payload of a
>     200 (OK) response to GET (Section 4.3.1) represents the current
> state
>     of the target resource, as observed at the time of the message
>     origination date
>
> There's quite a lot that doesn't say, -- it's even prefaced by 'for
> example'.  It doesn't even say that the payload _accurately_ represents
> the state of the resource.  That sounds like quibbling, but it fits in
> with a general idea of 'the client gets what it's given, and it'll like
> it'.
>
> However vague this is, I think this would not be consistent with a
> server deliberately causing a TCP error, in a protocol at a lower layer
> than HTTP.  Apart from anything else (a) the HTTP transaction might not,
> in principle, be running over TCP, and (b) it would be a lie, since the
> problem wasn't a TCP problem.
>
> In other words, truncating the output isn't desirable, obviously, but
> the alternatives of a deliberate lower-layer error, or stalling, seem
> both to be against the spirit of the spec.
>
> Matthew said:
>
> > AFAICT this is the intended behavior. To me it is consistent with the
> > usual policy: an uncaught error stops the program. If you want the
> > program to keep running, then you have to catch the error and make
> > other arrangements.
>
> But what happens in this case (the my-app/error case in my example) is
> that the (server) program keeps going but the client stalls.  The
> unexpected error in the response-output procedure is caught, and (as far
> as I can see) handled by killing the producer thread _without_ closing
> the connection.  To be clear, I think that the handler should do both.
>
> > All my servlet routes are surrounded by a top-level `with-handlers`
> > block that catches `exn:fail?`. If I get an error, I usually a) log it
> > to the remote system, b) send an email to myself, and c) send a status
> > 400 response to the browser with the error string. But the web server
> > keeps running as usual.
>
> I'm not positive where you mean by 'servlet routes'.  If you mean
> creating a handler to wrap my-app/foo in my example, then yes, that's
> what I do, too, and/or create a handler within my-app/foo before I
> create the response object.  But it looks as if I must _additionally_
> create a handler inside the response-output procedure (on the occasions
> when I do that 'by hand'), to cope with any exceptions thrown in there.
>
> Of course, I should design that response-output procedure so that it
> won't throw exceptions, but... never say never.
>
> Best wishes,
>
> Norman
>
>
> --
> Norman Gray  :  http://www.astro.gla.ac.uk/users/norman/it/
> Research IT Coordinator  :  School of Physics and Astronomy
> // My current template week for IT tasks is: Monday, Tuesday, and Friday
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CANy33qnzoHb6Y4PEBCi6oVgHpOZG%3D62O8Hy8dvhOCMk-oXybMA%40mail.gmail.com.

Reply via email to