On Tue, 04 Oct 2011 08:30:47 -0600, Alex Rousskov wrote:
On 10/03/2011 08:49 PM, Amos Jeffries wrote:

We got a malformed max-stale value. We have only
two options when it comes to that value interpretation, I think:

   A1. Treat it as valueless max-stale.
   A2. Ignore it completely.

BTW, we have three options when it comes to forwarding the malformed
directive:

   B1. Forward our own valid directive.
   B2. Forward nothing.
   B3. Forward the malformed directive.


The new updated RFC texts from HTTPbis are now stating:

"
   A proxy, whether or not it implements a cache, MUST pass cache
   directives through in forwarded messages, regardless of their
   significance to that application, since the directives might be
applicable to all recipients along the request/response chain. It is
   not possible to target a directive to a specific cache.
"

So we do not have B2 as a compliant option. If we receive it, it MUST be
relayed.

I disagree. The above HTTPbis text does not talk about malformed
directives, which are the only subject of the current discussion. B2 is acceptable for malformed directives, IMO, even though B3 would match the
spirit of the above spec better.


Erasing it could be an option, but not a compliant one. Striping the
unknown-value to make it less strict than we received would be more
likely to add problems in downstream software which might understand it.

Squid can either drop the malformed directive completely (B2) or forward
the original malformed directive (B3). B2 is easy to implement. B3 is
not so easy and is probably not very useful in practice so I would not
spend cycles on it, but it is Kinkie's call.

Forwarding something other than the original is a bad idea, IMO, because it may result in more stale objects than the client wants to accept (B1).


That said, the spec clearly outlines it as delta-seconds so if its not parseable as delta-seconds its clearly malformed and B1 probably should
not pass "max-stale".

Exactly. Although, technically, it is easy to construct a well-formed
max-stale value that Squid would consider malformed:

  max-stale=9999999999999999999999999999999999999999999999999999

The same is true for virtually all integer-based values in HTTP. We can
hope such values will never be found in real requests until we meet
aliens that write software which can cache objects for eternity.


Or the science and archival communities. They have particular accuracy requirements on the meaning of "forever".


Which leaves us in a mess because;
 A1->B1 seems intuitively the right thing, but has bad side effects.

Neither A1 nor B1 are the right things, IMO, because they may lead to
responses that are more stale than what the client is willing to accept.


A1->B3 seems like a reasonable alternative to avoid the effects, but
gambles on delta-seconds never changing.

A1 has a side effect of serving a possibly "too stale" object to the
client. You may be confused by the old source code comments (now fixed
by Kinkie) that valueless max-stale means "always stale". It actually
means "never stale". Thus, A1 and B1 convert "possibly stale at some
unknown point in time" to "never stale" which feels like a bad idea.

I was going by the RFC 2616 section 14.9.3 clause on max-stale:
"If no value is assigned to max-stale, then the client is willing to accept a stale response of any age."

Treating it compliantly as valueless when a value was sent (but not understood or malformed) means the client will get incorrect overly-stale objects.

If we want the client _never_ to get stale objects then it must be treated as max-stale=0 to override both the local max_stale directives and the RFC "anything" behaviour of valueless field.


I think we might have to get around this by using the max_stale
directive (or refresh_pattern override value) to limit the max-stale
value relayed upstream from the current Squid. If we consider this to be
an administrative override determining that this Squid will not emit
objects older than max_stale its reasonable to shrink the requested
staleness range from the valueless "anything" and ensure we get an
object as current as we want, within the wider range of what the client
wants.

When max-stale=value is malformed, we do not know whether we shrink or extend it by supplying our own value. That is why I think A2 is the only
acceptable option for Squid internal interpretation and B2 and B3 are
the only acceptable options for forwarding.


If we do A2, ignoring the header text entirely results in using the max_stale directives local values.

If we do A1, the RFC requires "anything" and our max_stale directives will always be smaller or equal to that. Usually smaller (1 week) so a slight gain in worst-case freshness over a bare assumption of "anything".

Amos

Reply via email to