[Web-SIG] Request and Response objects
David Fraser
davidf at sjsoft.com
Wed Nov 5 16:23:28 EST 2003
Ian Bicking wrote:
> On Nov 5, 2003, at 10:34 AM, Gregory (Grisha) Trubetskoy wrote:
>
>> On Wed, 5 Nov 2003, Stuart Bishop wrote:
>>
>>> The "response"-type class is the interesting bit - the API for setting
>>> status codes, headers, cookies etc. And you do want multiples, of
>>> which only one is sent to the client. In particular, if you catch an
>>> exception and are preparing an error message you will want a clean
>>> response to work with rather than, for example, accidently sending
>>> your error message with the wrong content-type. The alternative would
>>> be a reset() method on the response buffer, although this isn't as
>>> flexible.
>>>
>>> def handler(request):
>>> try:
>>> response = Reponse(request)
>>> filename = response.request.getFirst('filename')
>>> response.headers['Content-Type'] = 'image/jpeg'
>>> response.cookies['latest'] = filename
>>> response.write(open(filename,'rb').read()) # A filelike object
>>> except IOError:
>>> response = Response(request)
>>> response.status = 404
>>> print >> response, 'File not found'
>>> response.close() # No more data - compute content-length header
>>> response.send() # Send to client.
>>
>>
>>
>> The functional equivalent of the above would look like this in
>> mod_python.
>>
>> def handler(req):
>>
>> req.content_type = 'image/jpeg'
>>
>> try:
>> req.sendfile(req.filename)
>> except IOError:
>> return apache.HTTP_NOT_FOUND
>>
>> return apache.OK
>>
>>
>> 1. This is a pretty good example of the fact that dual objects don't do
>> much other than introduce extra typing.
>
>
> Dual objects avoid something like "req.content_type = 'image/jpeg'",
> which is not just a misnomer, but confusing and ambiguous, because
> both request and response have a content type.
>
>> 2. This is too low level of an example:
>>
>> The specifics of how an HTTP error is handled are going to vary from
>> server to server - e.g. Apache httpd will furnish it's own error text.
>> (BTW, HTTP errors shouldn't happen if your application is written well.)
>
>
> Of course applications should return errors. 404 is common, 401 and
> 403 are entirely reasonable, and 400 is a reasonable way to respond to
> unexpected input; 30x errors are obviously okay, and fit into an
> overall framework of exceptions. And WebDAV servers have to set the
> error response very specifically, including the body of the response.
>
> A boilerplate message is fine when nothing else is specified, but
> there should exist the possibility of setting the message in your
> application.
>
>> Response.close() and response.send() also assume too much control
>> over the
>> server. Unless we abstract completely by providing our own buffering
>> (which would do little other than introduce inefficiency), the buffering
>> is handled by the server, and whether and when content-length is set
>> depends on encoding used (chunked doesn't need content-length), which is
>> something also best left for the server to decide.
>
>
> Some sort of buffering is probably necessary if we want to be able to
> add headers after some of the body has been created. This is a common
> practice. Raising an exception in the middle of creating the body
> should also be handled gracefully. I think it's okay to make an
> exception when someone explicitly says they want to stream the
> response, but for most pages it doesn't matter.
This sounds more application-level specifics to me. We're designing an
API that will have to work with multiple servers
>
>> Whatever we come up with needs to be at a higher level.
>>
>> having flush() would be appropriate I think.
>>
>> sendfile() is another nice thing to have - if the environment has a
>> native implementation (e.g. mod_python), then it could be used,
>> otherwise
>> it'd just be req.write(open(file)read())
>
>
> Yes, that's a good idea to have.
More information about the Web-SIG
mailing list