Currently hgweb is not streaming its output -- it accumulates the
entire response before sending it. This patch restores streaming
behaviour. To avoid having to synchronously write many tiny fragments,
this patch also adds buffering to the template generator. Local
testing of a fetch of a 100,000 line file with wget produces a slight
slowdown overall (up from 6.5 seconds to 7.2 seconds), but instead of
waiting 6 seconds for headers to arrive, output begins immediately.
Thanks to Mads Kiilerich with noticing this. The hg client can only read data
after all the sent data has been read, so we have to read all the request data
even if we're not going to do anything with it (in error conditions). This
is not easy to fix in the client, because we're using Python's httplib, which
is strictly stateful. Abstracted the draining into a separate method.
This is a new version of b6b16fec2a60 (which was backed out in faf83e1e40f5),
with an extra line removed to fix problems with hg serve. hg's internal web
server contains checking if the app isn't trying to write more bytes than
specified by the Content-Length header. The first try still contained an old
line that wrote the response, so the response was sent twice.
Deleting tmpl just before the return statement should have no effect
since tmpl goes out of scope anyway. But it confuses pyflakes who
thinks tmpl is undefined when it is used in the except blocks below.
Using the write() callable supplied by the start_response() call is
frowned upon by the WSGI spec, returning an iterable over the content chunks
is the recommended way. Be aware, though: returning many small chunks will
slow down responses, because the server has to flush each chunk separately.
Consistently enforces authorization checks set up in hgrc up front, so that
the actual commands don't have to worry about them and implementers of
hgweb alternatives can easily implement their own permission checks.
Up to changeset 6713db859c82, HTTP headers were expected to be embedded
in the "headers" template. Since that changeset, the content-type is
supposed to be defined as the "mimetype" template in the map file.
This changeset makes sure the old templates still work.
The protocol functions are already pretty careful about not raising
exceptions to the caller, and have their own error handling. We can formalize
this a little bit to make it clearer (before, the exception handlers for
a limited number of exceptions coming from the interface bits would blow up
because some variables aren't instantiated for the protocol calls).