Etan Wexler wrote:
>
> I (Etan Wexler) wrote:
>
> > > Maybe my premise is wrong and cookies are not a mechanism for
> > > associating requests with a session maintained on an origin
> > > server. Maybe cookies pass arbitrary information from origin
> > > server to user agent and back. If that is so, then the use of
> > > cookies still violates the constraint of self-descriptive
> > > messages, because cookies are not self-descriptive at all.
>
> Aristotle Pagaltzis responded (in
> <http://tech.groups.yahoo.com/group/rest-discuss/message/10925>):
>
> > So cookies violate they constraint because they violate the
> > constraint? You have begged the question but not actually given
> > any reason for your claim.
>
> If cookies are vehicles for passing arbitrary information, as you tell
> me that they are, then it is the arbitrary nature that prevents
> self-description. User agents and intermediaries are unable to
> determine whether a cookie carries authentication credentials, a
> reference to session state, a directive to override the method, or
> something else. In terms of desirable properties, the effect is to
> reduce visibility, thus reducing cacheability, thus reducing network
> performance.
>
> I truly struggle to explain my point because, to me, it seems
> extremely obvious. Yeah, if an application fails to conform to a
> constraint, then it has violated the constraint. I don't see
> self-descriptiveness as a default for data. On the contrary, I see
> that it takes nontrivial effort on the part of designers to craft
> self-descriptive data. If you agree that self-descriptiveness is not
> a default for data, then the onus is on the people who find cookies
> in harmony with REST to show how cookies are self-descriptive. If you
> disagree and posit that self-descriptiveness is the default for data,
> then I would ask that you provide some evidence for your claim.
>
The thing with cookies is, they're out there, man... so all anyone,
even Dr. Fielding, can argue against are existing uses of cookies.
Like for authentication. But once again, absolute law isn't the order
of the day around here, we prefer the jury system (or as some would say,
REST is the Pirate Code). In that spirit, we recognize that basing
opposition to cookies in general, based on shortcomings in the realm of
authentication (i.e. security and privacy) or any other singular
evidence, would be to commit a logical fallacy by stating that any use
of cookies is a risk to security and privacy. Or, as the case may be
in section 6.3.4.2, that any use for cookies will ever be devised which
doesn't break the 'back' button.
REST does provide architectural guidelines a Web system may be compared
against, for the purposes of identifying and avoiding scaling issues
through judicious use of caching, avoiding stateful connections, and the
late binding of representations to resources (Content Negotiation). But
here's the flaw in conneg... this is my local IE 6 install's User-Agent
header -- this week, bound to change every time Windows Update runs:
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; formsPlayer
1.5; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET
CLR 3.0.04506.648)
Every Web cache I'm familiar with, when encountering Vary: User-Agent,
will create separate entries for every User-Agent string it encounters,
for IE alone the possibilities are almost endless. But the only reason
I'm sniffing the User-Agent string in the first place, is to detect
IE. Beyond that I don't particularly care about version, or extensions,
or the user's .NET version (if any, but caching is flawed without it).
So, in terms of REST my application's negotiated content is already
limited to HTTP 1.1 caches, with this "cache alias" problem I've
described... not good! But there is a solution, using cookies...
By storing the coarse-grained result of content negotiation in a
cookie, and responding to requests with this cookie by sending 'Vary:
Cookie' instead of 'Vary: User-Agent', the cache alias problem is
cleaned up and the application benefits exponentially in terms of
scale -- because all visitors' IE installations are assigned the same
cookie, and cache-control is Public. This is storing the results of
conneg, which is not application state. All variant representations
reflect the same application state, regardless of cookie values.
Once a user-agent has obtained a cookie (which expires after a time
interval), it knows how to directly request its desired variant,
bypassing content negotiation (less CPU cycles on the server) -- if
the request even *gets* to the origin server. Intermediaries, unless
cookied content is configured as uncacheable, know which variant to
serve, without needing to know the conneg algorithm. Less CPU, less
bandwidth, a fraction of the usual penalties for implementing very
RESTful Content Negotiation, with none of the downsides Roy talks about
in 6.3.4.2...
Yet I should shun this contraption for purely stigmatic reasons? ;-)
You'll have to do better than that! Your point about self-descriptive
messages is a good one, and in fact all the arguments against cookies
cite examples where cookies are used to maintain state. However, my
overloading (hijacking?) of cookie headers to function as cache-
control headers violates nothing in section 5.2.2, specifically:
"All REST interactions are stateless. That is, each request contains
all of the information necessary for a connector to understand the
request, independent of any requests that may have preceded it. This
restriction accomplishes four functions: 1) it removes any need for the
connectors to retain application state between requests, thus reducing
consumption of physical resources and improving scalability; 2) it
allows interactions to be processed in parallel without requiring that
the processing mechanism understand the interaction semantics; 3) it
allows an intermediary to view and understand a request in isolation,
which may be necessary when services are dynamically rearranged; and,
4) it forces all of the information that might factor into the
reusability of a cached response to be present in each request."
The point is, stateless uses of cookies (and I've seen a few) shouldn't
be shunned for using cookies, when the reason cookies aren't normally
thought of as RESTful comes with the assumption that all uses of
cookies result in stateful connections. My method has no cookie-
derived security concerns, as they are stateless, nor does it have
privacy concerns, as 'view=html' is opaque and at most reflects what
sort of browser a visitor is using.
What if cookies are disabled on the client? Well, since the response
is public and cacheable anyway, such a client will always have to hit
the origin server to renegotiate, even when actual content is delivered
by an intermediary (with a far lower probability for a match based on
Vary: User-Agent). So the worst-case scenario in my case, is the
status quo scenario for using conneg to do browser detection.
If cookies are disallowed on an intermediary, that intermediary won't
be caching my negotiated content based on the cookie header. It should
function exactly as it would if no cookies were involved, i.e. cache
based on User-Agent string, which is far less efficient as time goes on
due to the proliferation of little differences between installations in
certain products. Again, the worst-case scenario is the status quo.
Oh, and it took some tinkering with cache-control settings, but the
'back' button now functions properly in my setup and pulls content
direct from browser cache without 'pinging' the origin server (the user
can always reload the cached page). Before, there was considerable
latency involved with the 'back' button, which I considered broken.
Sorry, the example links I've posted previously aren't working, there
were several regression errors in the final update of the alpha. At
some point there will be a beta, until then we don't have the resources
to bother fixing the somewhat-broken alpha, or the /date web service.
Etan Wexler wrote:
>
> Peter Keane wrote (in
> <http://tech.groups.yahoo.com/group/rest-discuss/message/10935>):
>
> > There is
> > no significant distinction (in this specific case) between the
> > server giving the client a form or a uri template or a cookie that
> > the client can then use to create a request.
>
> I'll presume that you mean that the form or the URI template would be
> in a representation with a media type that identifies the form or URI
> template as such. And therein is the significant distinction. A
> REST-conformant user agent would process the form or URI template and
> present it decently to the user only because the media type dictates a
> set of shared conventions. (For example, HTML documents in the World
> Wide Web are HTML documents because their media-type label is
> "text/html". If one changes the label to "text/plain", the entity body
> has lost most of its meaning and is no longer HTML.) The cookie is
> opaque to the user agent (and to connectors and to intermediary
> components).
>
I'm not sure what you're saying, here. The URI is opaque to all of the
above, just like cookies. In REST, the server delivers algorithms to
user-agents, which derive state changes (links, form submissions) which
are presented to the user, from said algorithm. Header fields are not
off-limits. If a response header has no meaning to the user-agent,
fine, but this doesn't mean a script can't refer to it to build a URI.
"The important bit is that the algorithm is defined by the server
and the resource remains accessible regardless of how the URI
was calculated (i.e., the result of the algorithm is bookmarkable)."
http://tech.groups.yahoo.com/group/rest-discuss/message/10027
In my system, the cookie expires quickly, but any page bookmarked after
the cookie was assigned will be valid long after the cookie has
expired, the only consequence is that the client must re-negotiate with
the origin server. I don't understand why the natural behavior of
cookies is a bad thing to exploit for RESTful purposes, IOW there's no
reason I can see why cookies being opaque to the client is a Bad Thing.
My cookie headers would normally be ignored by intermediaries, except
by sending 'Vary: Cookie', which explicitly makes them cache headers.
Just like sending 'Vary: User-Agent', which is also normally ignored by
intermediaries, makes it a cache header. So this is typical behavior in
a RESTful system, even if my choice of headers to Vary is atypical...
unless it breaks an actual REST constraint, implementing anything in
HTTP goes, IMHO.
-Eric