httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ruediger Pluem <rpl...@apache.org>
Subject Re: idempotent http methods (svn commit: r617822)
Date Sat, 02 Feb 2008 20:14:35 GMT


On 02/02/2008 07:08 PM, Nick Kew wrote:
> On Sat, 02 Feb 2008 16:35:40 -0000
> rpluem@apache.org wrote:
> 
> 
>> +static int is_idempotent(request_rec *r)
>> +{
>> +    /*
>> +     * If the request has arguments it might not be idempotent as it
>> might have
>> +     * side-effects.
>> +     */
>> +    if (r->args) {
>> +        return 0;
>> +    }
> 
> That breaks RFC compliance, as soon as someone uses it to test
> idempotence.

Thats the question: On one side you are correct that the RFC clearly states
in 9.1.2 that GET / HEAD is idempotent. OTOH in 13.9 the RFC says that GET / HEAD
requests with arguments can have significant side effects and therefore responses
to these queries should be only cached if the response contains an expiration time.
I may chose a bad name with is_idempotent as the purpose is to determine if we
can retry this request again once it has been sent to a backend (partially)  and
the real main argument for retrying or not retrying seems to me if the already
sent request can cause side-effects that prohibit to sent it again.
Non idempotent methods are said to have these, so we cannot sent them again.

> 
>> +    /*
>> +     * RFC2616 (9.1.2): GET, HEAD, PUT, DELETE, OPTIONS, TRACE are
>> considered
>> +     * idempotent. Hint: HEAD requests use M_GET as method number as
>> well.
>> +     */
>> +    switch (r->method_number) {
>> +        case M_GET:
>> +        case M_DELETE:
>> +        case M_PUT:
>> +        case M_OPTIONS:
>> +        case M_TRACE:
>> +            return 1;
>> +        /* Everything else is not considered idempotent. */
>> +        default:
>> +            return 0;
>> +    }
>> +}
> 
> Suggested solution: an enum, with a third value for an idempotent
> method with arguments.  The caller then determines how to use it.

So you think of something like this (ok, no enum, but similar):

#define METHOD_NON_IDEMPOTENT       0
#define METHOD_IDEMPOTENT           1
#define METHOD_IDEMPOTENT_WITH_ARGS 2

static int is_idempotent(request_rec *r)
{
    /*
     * RFC2616 (9.1.2): GET, HEAD, PUT, DELETE, OPTIONS, TRACE are considered
     * idempotent. Hint: HEAD requests use M_GET as method number as well.
     */
    switch (r->method_number) {
        case M_GET:
        case M_DELETE:
        case M_PUT:
        case M_OPTIONS:
        case M_TRACE:
            /*
             * If the request has arguments it might have side-effects and thus
             * it might be undesirable to resent it to a backend again·
             * automatically.
             */
            if (r->args) {
                return METHOD_IDEMPOTENT_WITH_ARGS;
            }
            return METHOD_IDEMPOTENT;
        /* Everything else is not considered idempotent. */
        default:
            return METHOD_NON_IDEMPOTENT;
    }
}

> 
> That's in response to your post to dev@.  OTTOMH it seems to me
> to work as a core function.  How many existing handlers apply
> an equivalent test?
> 

I know of none currently, but I assume that at least in mod_proxy(_http) the
need for this test will rise, once we try to finally solve the race problem in
mod_proxy_http when it sends a request over a connection that is closed just
at this moment.

Regards

Rüdiger

Mime
View raw message