[Web-SIG] Defining a standard interface for common web tasks

Greg Stein gstein at lyra.org
Fri Oct 24 17:06:44 EDT 2003


On Fri, Oct 24, 2003 at 10:54:01AM -0500, Ian Bicking wrote:
>...
> > res.content_type = 'text/html'
> 
> res.setHeader('content-type', 'text/html')
> # I don't really see a reason that this header needs special attention

Because it is a header that should almost always be set. Might even be
required (dunno off the top of my head; RFC 2616 would say).

Note that a character set should be set in there, too. Omitting the
character set can cause problems, although I forget the exact nature of
those. A few years ago, Apache httpd went and did a lot of work to add
character sets into the Content-Type header; providing defaults and
directives to make it easier and whatnot. It was done for some security
reason, if I recall correctly.

> > res.set_cookie('name', 'Simon')
> > res['X-Additional-Header'] = 'Another header'
> 
> res.setHeader('X-additional-header', 'Another header')
> # It's not clear what dictionary access to the response object would 
> mean.
> # res.headers['X-additional-header'] = 'Another header' might be okay
> # but it makes it difficult to add multiple headers by the same name -- 
> but
> # I don't know if HTTP ever really calls for that anyway.

HTTP specifically discusses what happens when you see two headers with the
same name:

    Some-Header: foo
    Some-Header: bar

is equivalent to:

    Some-Header: foo, bar

i.e. concatenate with a comma. While it is allowed, there is *generally*
no reason for the API to enable writing separate headers, nor a reason to
expose same-named headers as separate (i.e. just concatenate them
internally).

Note that I say "generally" because I've seen a client that could not deal
properly with a long header value. By separating the tokens in the header
across multiple instances, the client worked. IOW, a single line couldn't
be longer than about 64 characters, but its internal value-concatenation
worked just fine for long logical values.

> > res.send_headers()
> > res.write('<html><h1>Hi there</h1>\n%s' % body)
> 
> # This, but also:
> res.write('<html><h1>Hi there</h1>\n%s' % body)
> res.setHeader('X-Yet-Another-Header', 'Yet another value')
> res.commit()
> # res.flush()?  Sends headers *and* any body, can be called multiple 
> times
> res.setHeader('Content-type', 'text/plain')
> # raises exception

That shouldn't raise an exception *until* you use a method which writes
body-content. If you're talking about a method to send and *end* the
header block, then it needs a better name. i.e. send_headers()  (and yes,
after calling that method, further headers would raise an exception)

Both the client and server libraries should also respect the "Expect"
header around the header/body transition point. See RFC 2616 for more info
about that. Essentially, the client can send the headers, wait for the
server to say "go ahead" (or throw errors back to the client), and *then*
upload that 5 gigabyte body. It provides a way for the server to resolve
authz/authn (or other) problems before you get into the business of
uploading huge bodies.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/



More information about the Web-SIG mailing list