Subject: Re: Server-side roles in the HTTP

From: Mark Nottingham <[email-masked]>
Date: Wed, 1 Sep 1999 16:03:09 +1000 (EST)

Julien,

Thanks for taking the time to comment.

> Of the "Content-generation" mechanisms you cite above, some offer
> lower-level access to the HTTP reply than others, and it's not necessarily feasible or
> desirable to implement all your suggestions in all cases. For example, CGI
> is, if limited, a high-level interface, and it's easy for the daemon to
> intercept and process their responses. Then you have servlets (which you don't
> mention in your paper), at a slightly lower-level. The servlet classes expose some
> HTTP features so the complexity of intercepting and correcting content is
> greater.

Good point; I'm fairly ignorant of the inner workings of servlets as well as their newer cousins like JSP. They very well may fall out of scope for this 
proposal. However, I think that would be a shame; even people with the knowledge to use these facilities rarely implement anything beyond the very 
basics of the protocol.

There's nothing in the draft (although this isn't articulated well) that says mechanisms can't be established to override these server-level responsiblities. 

What I'm trying to do is give the people I called 'publishers' the assurance that, if they use a server and generator compliant with this draft, they won't 
need to worry about details of protocol implementation -- not that they do (that's the root of the problem). 

Whether the server or the 'content generators' is the best place to do that is an interesting question; my feeling is that it's simpler and more reliable to do 
it in the server.

> Then you have server plug-ins which expose many low-level server internal
> features and are more difficult to intercept in the daemon, as there are so
> many server helper functions that can be called in many orders. Plug-ins can
> also be more than content-generators - they may handle tasks like redirection and
> authentication, which are also more difficult to correct on the fly in the
> daemon.
> 
> For those applications that are strictly generating content, I think your
> suggestions make sense. We came largely to the same conclusions recently

It does become a nightmare if it is applied to everything that can be tied into a server. It may be prudent to draw a line at APIs, or perhaps there needs to 
be a further distinction in the draft - 
* content generators (CGI, PHP, ASP, etc) - have a 'shallow', high-level view into the server, server is required to handle all protocol features (as in current 
draft)
* APIs et al (Servlets, ISAPI, NSAPI, etc) - low-level 'deep' view, api user has library of protocol feature calls available

Would this be more practical?

> before I got a chance to see your draft, and we have even implemented some
> solutions to
> these problems already; though you aren't likely to see the results until
> we have a fully compliant HTTP/1.1 server.

Can't wait!

> As far as your draft, I think there should be fewer "MUST" requirements.

It depends on how you place the draft. If you think of it as a peer document to 2616 (you must be compliant with this draft to be considered HTTP 
compliant), you're right - it's far too strict. However, if you consider it as an additional, higher level of compliance, the MUSTS are important. 

I do think that some of the SHOULDs (especially to do with buffering and *perhaps* synthetic validation) might be better as MAYs.

> For instance, the partial content requirement won't necessarily fly with all
> type of content generators. According to RFC2616 section 14.5, a server is not
> required to serve ranges for all resources - it can send "Accept-range: None". That
> doesn't preclude it from supporting ranges on other resources, such as
> static files. I like this flexibility.

But from a protocol/network/user perspective, does it make any sense that a feature is available for one resource but not another, based on the 
underlying technology? If you have a PDF file that happens to be generated by a CGI script, it's a huge pain to get it to support ranges, validation and 
other facilities in the script itself. I've done it, and it was not pleasant. 

A lot of the feedback that I've gotten has been in this vein - that not every object is going to take advantage of all of these 'extra' services. But, if they 
aren't available by default, chances are they'll never be thought of, much less handled.

The other way that I'm working on attacking this problem is creating a series of wrapper scripts / libraries that will take care of as much of this stuff as 
possible automatically. Unfortunately, it's very much an uphill battle (for instance, if I include a content-length in Netscape or Apache CGI, it will make the 
connection persistent; no such luck with other servers), so this would only be a temporary measure. 

Cheers,

--
Mark Nottingham, Melbourne Australia
http://www.mnot.net/

---

From: [email-masked] (Julien Pierre)
Date: Wed, 01 Sep 1999 15:38:59 -0700

Hi,

> There's nothing in the draft (although this isn't articulated well) that says mechanisms can't be established to override these server-level responsiblities.

When you have MUST requirements it seems to somewhat preclude them.

> Whether the server or the 'content generators' is the best place to do that is an interesting question; my feeling is that it's simpler and more reliable to do

It's true that most applications that generate content don't deal with those 1.1 features like range requests.
It makes sense to have a server mechanism for dealing with them transparently.

But it should still be possible to defer the responsability to handle these features to the application, if only to maintain compatibility with current
applications. Sometimes it's actually the intended effect - you may want the application to actually respond differently to byteranges or other types of ranges, for
instance, than what the server implementor might expect.

> Would this be more practical?

Yes, I think it makes sense to make this distinction.

> compliant), you're right - it's far too strict. However, if you consider it as an additional, higher level of compliance, the MUSTS are important.

Only if they truly apply to all resources in a generic way and I don't think there was any in your draft that did.

> I do think that some of the SHOULDs (especially to do with buffering and *perhaps* synthetic validation) might be better as MAYs.

Actually, the buffering is one of the main advantages of 1.1 and I believe it should be a SHOULD. But I agree about the synthetic validation being a MAY.

> underlying technology?

The problem is that the underlying server technology is not monolithic. There isn't a clear line between the daemon and what you call content generators.
If you look at the way that large web sites are implemented today, it can be pretty complex. You always have an HTTP daemon on the front-end, then possibly a
plug-in running in the daemon process, which in turn may communicate with an application server on a remote machine, itself accessing corporate data on other
servers.

In such a case, I would argue that the content generator is the application server. But the HTTP daemon cannot handle all aspects of the protocol related to such a
complex environment ; instead the plug-in would have to deal with some of them.

>If you have a PDF file that happens to be generated by a CGI script, it's a huge pain to get it to support ranges, validation and

What you suggest when requesting the server implementor to do this job is that  the server has to regenerate the whole dynamic page just to get a few bytes. This
may involve rerunning the application. Even if your CGI sends exactly the same-content with the same last-modified date, so that the client still thinks it's the
same content between HTTP requests, the PDF plug-in might make 10 different HTTP requests in a row with various ranges. The server executes the script 10 times,
gets the full PDF content from the script, and then only sends the requested bytes. Technically, it works, but it's extremely inefficient.
On the other hand, if you let the CGI itself handle the range request, then it's not so bad : the CGI will try to generate those requested bytes itself and won't
waste memory or CPU trying to generate and send the entire thing.

Ranges work best with direct access content (eg: static files) or with cacheable content ; with dynamic content, the server typically only has sequential access to
the content and does not cache it.

That's not to say the HTTP server shouldn't do anything. I think it makes sense for it to transparently do chunking on CGI and plug-ins output, and the way we are
doing it now works very nicely (though I wish we could use our own browser to test this feature :)).

> aren't available by default, chances are they'll never be thought of, much less handled.

Some features are the responsibility of the application, not all are the server's.

> connection persistent; no such luck with other servers), so this would only be a temporary measure.

This won't be an issue in the long term at least for NES servers; with our post-4.0 release, you won't need to do any of this to get the full benefits of persistent
connections and chunking.

--
for a good time, try kill -9 -1

---

From: "Mark Nottingham" <[email-masked]>
Date: Fri, 17 Sep 1999 01:45:50 +1000

I was just paging through previous e-mail to prepare draft-01, and came
across this, which I don't think I responded to.

[me]
> >If you have a PDF file that happens to be generated by a CGI script, it's
a huge pain to get it to support ranges, validation and
> >other facilities in the script itself. I've done it, and it was not
pleasant.

[JP]
> What you suggest when requesting the server implementor to do this job is
that  the server has to regenerate the whole dynamic page just to get a few
bytes. This
> may involve rerunning the application. Even if your CGI sends exactly the
same-content with the same last-modified date, so that the client still
thinks it's the
> same content between HTTP requests, the PDF plug-in might make 10
different HTTP requests in a row with various ranges. The server executes
the script 10 times,
> gets the full PDF content from the script, and then only sends the
requested bytes. Technically, it works, but it's extremely inefficient.
> On the other hand, if you let the CGI itself handle the range request,
then it's not so bad : the CGI will try to generate those requested bytes
itself and won't
> waste memory or CPU trying to generate and send the entire thing.

I agree to some extent. I need to make it more clear that the draft is about
defaults; in this case, if you have a more efficient way of handling range
requests in the CGI, have it generate a 'Accept-Ranges: bytes' header, and
the server should know that the application is capable of dealing with
partial content. Best of both worlds.

Even if this isn't taken advantage of, IMHO it's much easier to scale a
server (hardware) than the complete network between any possible user and
the server. Regenerating the entire object to send a few bytes is
inefficient on the server, but it's better than leaving it in the
publisher's hands; as in most cases it won't be done at all.

I'd very much like a survey to be done of Webmasters, CGI scripters, etc.,
to ask them where they think the responsibilty for handling these features
currently lies.

> Ranges work best with direct access content (eg: static files) or with
cacheable content ; with dynamic content, the server typically only has
sequential access to
> the content and does not cache it.

I know what you're getting at, but I really want to redefine what people
think of as dynamic content, as well as cacheability.

Dynamic content to me is defined by dependence on either the identity
(however derived) of the current user, or some other external source of
content entropy that causes two hits to the same request at the same time to
generate different content. That's it; it has nothing to do with the
presence of the string cgi-bin, a query or anything else.

In my mind cachability is two very separate properties; assigned TTL
(through Expires, Cache-Control or assumed through LM) and ability to
validate through conditional request. In the future, it may expand to
include such methods as ability to delta encode.

> That's not to say the HTTP server shouldn't do anything. I think it makes
sense for it to transparently do chunking on CGI and plug-ins output, and
the way we are
> doing it now works very nicely (though I wish we could use our own browser
to test this feature :)).

*grin* know that feeling...

--
Mark Nottingham

---

From: [email-masked] (Koen Holtman)
Date: Mon, 20 Sep 1999 11:59:54 +0200 (MET DST)

Mark Nottingham:
>
>As you may be aware, I have submitted an Internet-Draft,
>draft-nottingham-http-roles-00.txt.
>
>I'd very much appreciate comments from the http-wg, as I see it as primarily
>in that domain (with some overlap to wrec and the cgi efforts).

I read the draft; I won't give specific comments, just some high level
observations.

With my http-wg background, it looks like the draft mixes two things
that I would rather see covered separately.  On the one hand, there
are a lot of efficiency requirements, which, if not followed, won't
affect protocol-level correctness as such.  I'll stay silent on these
as there has been a lot of discussion about them already.

On the other hand, there are a few things that do have an impact on
the ability of a CGI author to produce correct HTTP/1.1 responses.  An
example is the requirement in section 6.2 that validators must be
passed through without modification.

Some time ago I updated the Apache mod_negotiation to HTTP/1.1 and TCN
compliance.  While doing this I encountered several cases where the
current CGI specification does not define server behavior, and where
having a defined behavior would greatly help CGI authors in being more
HTTP/1.1 friendly/compliant.  I'm saying CGI specification here but
this observation really extends to all CGI-like interfaces where
application code supplies headers and and a response body to the
server.

It occured to me that the CGI specification would benefit from a few
HTTP/1.1 targeted extensions and updates.  These extensions have
little to do with performance directly, but more with protocol and
cache correctness, which of course does affect performance on a higher
level.  Updating the CGI specification for HTTP/1.1 is _way_ down on
my todo list however, so I doubt I'll ever get around to doing it.  Of
course, with sufficient encouragement and offers to share the
workload, this item may move higher on my todo list.

In any case, as an example of the kind of things I would want a
1.1-oriented CGI update to define, here is is the type of facility I
would prefer that a server provides with respect to HTTP/1.1 entity
tags:

  The server should *not* pass from the CGI interface into the
  HTTP/1.1 response unchanged!  Rather, by default, the CGI script
  should be able to return a `content validator' to the server, which
  will be used by the server as _one_ of the components of the
  HTTP/1.1 entity tag.  Another component is a server-generated
  validator for the script file itself.  Thus, if the script is
  updated, correct cache resynchronisation is guaranteed.  If the
  response body output by the script is not used directly as a HTTP
  response body, but in stead embedded in other content before being
  sent to the client, then the entity tag should also act as a
  validator for the other content.  Naturally, the server, not the
  script, is responsible by default for correctly processing HTTP/1.1
  if-none-match and if-match header fields.

Note that Apache, for example, currently does not do much of the above
at all.  Therefore, as a CGI script writer for Apache I would not
currently create scripts that emit entity tags.  Not emitting these
tags is the safest route to HTTP/1.1 compliance.

With respect to draft-nottingham-http-roles-00.txt, I would conclude
that it either needs to separate out the CGI extensions that help CGI
authors in producing correct HTTP/1.1, or drop such extensions
alltogether.

Koen.

---

From: [email-masked] (Julien Pierre)
Date: Mon, 20 Sep 1999 16:59:56 -0700

Hi, Mark!

Sorry for the delay in answering - things can be a bit busy at times.

> partial content. Best of both worlds.

Noted. This adds some extra complexity again, but it should work.

> publisher's hands; as in most cases it won't be done at all.

I'm not sure that it's better to have it done this way as opposed to not having
it done at all.
Partial content was designed to provide faster access to the needed data, thus
improving performance.
These benefits are particularly evident with large objects.

However, with a large dynamic object and the approach you suggest, these
benefits would be effectively negated since the application would have to run
multiple times instead of one. Instead of implementing some relatively complex
code to handle it transparently which would have questionable value and
performance, I would be much more inclined to have the server add an
"accept-ranges: none" by default for CGIs and other applications so that this
situation would not happen.
Of course, this would be done only if the application doesn't insert its own
Accept-ranges to indicate that it can handle it.

> to ask them where they think the responsibilty for handling these features

I don't think we need to do such a poll to know the results :-).
Even though it sounds nice to have ranges for CGIs, my take as a server
implementor is that having it done transparently in the server is at best not
going to help and in most cases will hurt performance both on the server and
client sides.

> (however derived) of the current user,

If it's purely the identity then it is only an authentication scheme.
In the case you described previously, it sounds like your CGI script was not
really generating content but only providing authentication.

To handle such cases, there are much better ways :
- use LDAP ACLs if your users are in an LDAP server . That's the easiest way -
no programming required
- use a server plug-in to do your own authentication for a resource

If on the other hand the bits of the PDF were generated on the fly, let's say
from the user input, then the CGI might make sense.
But I wonder how the PDF plug-in deals with POST when it makes its partial
content requests .. It would have to repost the whole
user input for every range request. You can see how inefficient that is - no
matter if it's the server or the CGI script that handles the range.

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 21 Sep 1999 20:50:21 +1000 (EST)

Quoting Julien Pierre <[email-masked]>:

> benefits would be effectively negated since the application would have to
> run multiple times instead of one. 

This would only be true for PDFs and other non-sequential access methods, not file download resumption, etc. 

> Instead of implementing some relatively complex
> "accept-ranges: none" by default for CGIs and other applications so that
> this situation would not happen.
> Of course, this would be done only if the application doesn't insert its
> own Accept-ranges to indicate that it can handle it.

Well put. I'm not particularly interested in fighting for partial content; it has limited uses and is a pain to implement in caches (which is the prime area of 
interest for me). How about something along the lines of servers MAY handle ranges transparently, but if they don't, they MUST send Accept-Ranges: 
none, unless the content generator has set an Accept-Ranges?

The other way to approach it would be to default to no ranges, allow the generator to communicate that it can handle them, and allow the generator to 
dictate to the server that it should handle them (by regenerating content, if they server implementor has chosen to do this). Hmm, his seems a bit 
unwieldy...

> In the case you described previously, it sounds like your CGI script was
> not really generating content but only providing authentication.
> 
> - use LDAP ACLs if your users are in an LDAP server . That's the easiest
> way - no programming required

In this particular case, I was charged with making a CGI application's output (PDFs) cacheable, without changing it; there was a lot
of logic in determining the authentication criteria, and the implementors did it in CGI, because it seemed natural for them to do so. There's a fair amount 
of this sort of thing going on; people don't really think about the protocol-level implications of what they do.

I'm on holiday right now (in an internet cafe in London), so I won't be reading my mail too often. However, I do plan to submit a revised draft incorporating 
a lot of what's been discussed when I get back, and hopefully this can be discussed in Washington.

--
Mark Nottingham
http://www.mnot.net/