[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

apache 2.0's mod_dav.c:dav_handler() out of sync?

From: <kfogel_at_collab.net>
Date: 2001-08-30 23:35:14 CEST

Ryan and Bill,

Greg Stein recommended we ask you about a problem we're having with
Subversion. The "svn update" command is bombing out on us because
dav_handler() on the server side is apparently declining to handle the
request. We think this might be due to mod_dav.c not tracking some
httpd-2.0 changes...

Here is the spot in dav_handler() where the request gets
declined:

    /*
     * NOTE: When Apache moves creates defines for the add'l DAV methods,
     * then it will no longer use M_INVALID. This code must be
     * updated each time Apache adds method defines.
     */
    if (r->method_number != M_INVALID) {
        return DECLINED;
    }

GDB tells us that ((request_rec *) r)->method_number == 16. I had
thought these numbers were to be interpreted as bit-shifty masks, not
raw numbers, but the code in dav_handler() compares r->method_number
as a plain number, for whatever reason.

Anyway, do you know anything about recent changes in Apache that would
imply mod_dav.c needs to be adjusted? Thanks in advance for any
help. Below is the full code to dav_handler(), and we can be reached
at (312) 922-2784 if you want to use voice.

static int dav_handler(request_rec *r)
{
    dav_dir_conf *conf;

    if (strcmp(r->handler, "dav-handler")) {
        return DECLINED;
    }

    /* quickly ignore any HTTP/0.9 requests */
    if (r->assbackwards) {
        return DECLINED;
    }

    /* ### do we need to do anything with r->proxyreq ?? */

    conf = (dav_dir_conf *) ap_get_module_config(r->per_dir_config,
                                                 &dav_module);

    /*
     * Set up the methods mask, since that's one of the reasons this handler
     * gets called, and lower-level things may need the info.
     *
     * First, set the mask to the methods we handle directly. Since by
     * definition we own our managed space, we unconditionally set
     * the r->allowed field rather than ORing our values with anything
     * any other module may have put in there.
     *
     * These are the HTTP-defined methods that we handle directly.
     */
    r->allowed = 0
        | (AP_METHOD_BIT << M_GET)
        | (AP_METHOD_BIT << M_PUT)
        | (AP_METHOD_BIT << M_DELETE)
        | (AP_METHOD_BIT << M_OPTIONS)
        | (AP_METHOD_BIT << M_INVALID);
    /*
     * These are the DAV methods we handle.
     */
    r->allowed |= 0
        | (AP_METHOD_BIT << M_COPY)
        | (AP_METHOD_BIT << M_LOCK)
        | (AP_METHOD_BIT << M_UNLOCK)
        | (AP_METHOD_BIT << M_MKCOL)
        | (AP_METHOD_BIT << M_MOVE)
        | (AP_METHOD_BIT << M_PROPFIND)
        | (AP_METHOD_BIT << M_PROPPATCH);
    /*
     * These are methods that we don't handle directly, but let the
     * server's default handler do for us as our agent.
     */
    r->allowed |= 0
        | (AP_METHOD_BIT << M_POST);
 
    /* ### hrm. if we return HTTP_METHOD_NOT_ALLOWED, then an Allow header
     * ### is sent; it will need the other allowed states; since the default
     * ### handler is not called on error, then it doesn't add the other
     * ### allowed states, so we must */
    /* ### we might need to refine this for just where we return the error.
     * ### also, there is the issue with other methods (see ISSUES) */
    /* ### more work necessary, now that we have M_foo for DAV methods */

    /* dispatch the appropriate method handler */
    if (r->method_number == M_GET) {
        return dav_method_get(r);
    }

    if (r->method_number == M_PUT) {
        return dav_method_put(r);
    }

    if (r->method_number == M_POST) {
        return dav_method_post(r);
    }

    if (r->method_number == M_DELETE) {
        return dav_method_delete(r);
    }

    if (r->method_number == M_OPTIONS) {
        return dav_method_options(r);
    }

    if (r->method_number == M_PROPFIND) {
        return dav_method_propfind(r);
    }

    if (r->method_number == M_PROPPATCH) {
        return dav_method_proppatch(r);
    }

    if (r->method_number == M_MKCOL) {
        return dav_method_mkcol(r);
    }

    if (r->method_number == M_COPY) {
        return dav_method_copymove(r, DAV_DO_COPY);
    }

    if (r->method_number == M_MOVE) {
        return dav_method_copymove(r, DAV_DO_MOVE);
    }

    if (r->method_number == M_LOCK) {
        return dav_method_lock(r);
    }

    if (r->method_number == M_UNLOCK) {
        return dav_method_unlock(r);
    }

    /*
     * NOTE: When Apache moves creates defines for the add'l DAV methods,
     * then it will no longer use M_INVALID. This code must be
     * updated each time Apache adds method defines.
     */
    if (r->method_number != M_INVALID) {
        return DECLINED;
    }

    if (!strcmp(r->method, "VERSION-CONTROL")) {
        return dav_method_vsn_control(r);
    }

    if (!strcmp(r->method, "CHECKOUT")) {
        return dav_method_checkout(r);
    }

    if (!strcmp(r->method, "UNCHECKOUT")) {
        return dav_method_uncheckout(r);
    }

    if (!strcmp(r->method, "CHECKIN")) {
        return dav_method_checkin(r);
    }

    if (!strcmp(r->method, "UPDATE")) {
        return dav_method_update(r);
    }

    if (!strcmp(r->method, "LABEL")) {
        return dav_method_label(r);
    }

    if (!strcmp(r->method, "REPORT")) {
        return dav_method_report(r);
    }

    if (!strcmp(r->method, "MKWORKSPACE")) {
        return dav_method_make_workspace(r);
    }

    if (!strcmp(r->method, "MKACTIVITY")) {
        return dav_method_make_activity(r);
    }

    if (!strcmp(r->method, "BASELINE-CONTROL")) {
        return dav_method_baseline_control(r);
    }

    if (!strcmp(r->method, "MERGE")) {
        return dav_method_merge(r);
    }

    if (!strcmp(r->method, "BIND")) {
        return dav_method_bind(r);
    }

    /* ### add'l methods for Advanced Collections, ACLs, DASL */

    return DECLINED;
}

Thanks,
-Karl

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:37 2006

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.