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