Re: [spr26435] sending headers
John Foderaro <[email protected]> Wed, 24 Jul 2002 08:47:00 -0700
| Newsgroups | gmane.lisp.open-source.franz |
|---|---|
| Message-ID | <[email protected]> |
In an http response the headers must be sent before the body of the response.
If you want to compute the headers after the body has been computed
you must store the whole response in a local buffer, then compute
and send the header and then send the body from the buffer.
There are a few problems with this approach however:
1. It's inefficient in time and space to write the response first
to the buffer and the from the buffer to the socket stream.
Java programmers generally don't care much about efficiency so
they may accept this kind of overhead.
2. If the response body takes a while to compute you're better off sending
parts of the body as you compute them since most web browsers will
start to display as soon as they get something back from the web
server. The user is happier with a slowing changing screen
showing some progress than a totally blank screen which make it
appear that the web site is down.
AllegroServe tries to offer the most efficient user-friendly
experience thus prefers to send the headers first, and then send
parts of the body as they are computed. This is not always possible
however. If the browser supports only HTTP/1.0 (e.g. Netscape 4.x and
older) then the web server can't send a chunked response. If
the HTTP/1.0 browser wants to keep the connection alive for another
request then the web server has to send a Content-Length header
which means that the web server must compute the length of the body
before the headers can be sent.
In AllegroServe, the with-http-response macro examines the headers
of the request and computes the best stategy for responding
to this request. It stores this strategy in the a slot
of the request object accessed via the request-reply-strategy
function. The with-http-body macro then implements this strategy.
Your code between with-http-response and with-http-body is
free to examine the strategy chosen and change it, as long
as you change it to something that makes sense for the given
request. I don't have a document describing how the
strategy works. The generic function compute-strategy in publish.cl
would be useful to examine. If you want to delay sending
the headers until the body is computed then you want to
have :post-headers in the strategy and make sure that
:use-socket-stream is not present.
Another solution to your problem is for you call
with-http-response and then build the body of your response
into a string-output stream and then do with-http-body and
print the contents of the string-output-stream to the *html-stream*.
This is effectively what AllegroServe will be doing for you
if you change the strategy but if you make the saving
of the body into a string output stream explicit in your code
it may be simpler for you to write.