httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gst...@apache.org
Subject cvs commit: httpd-2.0/modules/dav/main mod_dav.c mod_dav.h props.c util.c
Date Wed, 28 Mar 2001 07:37:27 GMT
gstein      01/03/27 23:37:27

  Modified:    modules/dav/main mod_dav.c mod_dav.h props.c util.c
  Log:
  Patch to sync with some changes to mod_dav 1.1:
  
  *) revamp the set_target stuff -- latest draft calls this UPDATE
  *) update the CHECKIN method handling
  *) liveprop providers can catch/define "core" properties before the core
     gets a chance.
  
  Submitted by: John Vasta <jvasta@rational.com>
  Reviewed by: Greg Stein
  
  Revision  Changes    Path
  1.52      +105 -119  httpd-2.0/modules/dav/main/mod_dav.c
  
  Index: mod_dav.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/dav/main/mod_dav.c,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -u -r1.51 -r1.52
  --- mod_dav.c	2001/03/13 02:13:54	1.51
  +++ mod_dav.c	2001/03/28 07:37:25	1.52
  @@ -517,6 +517,7 @@
   **   - repos_hooks->remove_resource
   **   - repos_hooks->move_resource
   **   - repos_hooks->copy_resource
  +**   - vsn_hooks->update
   */
   static int dav_handle_err(request_rec *r, dav_error *err,
   			  dav_response *response)
  @@ -2848,13 +2849,8 @@
   	return HTTP_BAD_REQUEST;
       }
   
  -    /* Ask repository module to resolve the resource.
  -     * DeltaV says result of target selector is undefined,
  -     * so allow it, and let provider reject the lock attempt
  -     * on a version if it wants to.
  -     */
  -    /* ### gjs: I'm not sure we want to allow for locking a version... */
  -    err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */,
  +    /* Ask repository module to resolve the resource */
  +    err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */,
                              &resource);
       if (err != NULL)
           return dav_handle_err(r, err, NULL);
  @@ -3035,13 +3031,8 @@
   	return dav_handle_err(r, err, NULL);
       }
   
  -    /* Ask repository module to resolve the resource.
  -     * DeltaV says result of target selector is undefined,
  -     * so allow it, and let provider reject the unlock attempt
  -     * on a version if it wants to.
  -     */
  -    /* ### gjs: I'm not sure we want to allow for locking a version... */
  -    err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */,
  +    /* Ask repository module to resolve the resource */
  +    err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */,
                              &resource);
       if (err != NULL)
           return dav_handle_err(r, err, NULL);
  @@ -3475,13 +3466,26 @@
       const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r);
       dav_error *err;
       int result;
  +    ap_xml_doc *doc;
  +    int keep_checked_out = 0;
   
       /* If no versioning provider, decline the request */
       if (vsn_hooks == NULL)
           return DECLINED;
   
  -    if ((result = ap_discard_request_body(r)) != OK) {
  +    if ((result = ap_xml_parse_input(r, &doc)) != OK)
   	return result;
  +
  +    if (doc != NULL) {
  +        if (!dav_validate_root(doc, "checkin")) {
  +            /* This supplies additional information for the default msg. */
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
  +                          "The request body, if present, must be a "
  +                          "DAV:checkin element.");
  +            return HTTP_BAD_REQUEST;
  +        }
  +
  +        keep_checked_out = dav_find_child(doc->root, "keep-checked-out") != NULL;
       }
   
       /* Ask repository module to resolve the resource */
  @@ -3509,13 +3513,14 @@
   
       if (!resource->working) {
   	return dav_error_response(r, HTTP_CONFLICT,
  -				  "The resource is not checked out to the workspace.");
  +				  "The resource is not checked out.");
       }
   
       /* ### do lock checks, once behavior is defined */
   
       /* Do the checkin */
  -    if ((err = (*vsn_hooks->checkin)(resource, &new_version)) != NULL) {
  +    if ((err = (*vsn_hooks->checkin)(resource, keep_checked_out, &new_version))
  +        != NULL) {
   	err = dav_push_error(r->pool, HTTP_CONFLICT, 0,
   			     apr_psprintf(r->pool,
   					 "Could not CHECKIN resource %s.",
  @@ -3527,80 +3532,27 @@
       return dav_created(r, new_version->uri, "Version", 0);
   }
   
  -/* context maintained during SET-TARGET treewalk */
  -typedef struct dav_set_target_walker_ctx
  +static int dav_method_update(request_rec *r)
   {
  -    /* input: */
  -    dav_walk_params w;
  -
  -    /* target specifier */
  -    const char *target;
  -
  -    /* flag for whether target is version URI or label */
  -    int is_label;
  -
  -    /* version provider hooks */
  -    const dav_hooks_vsn *vsn_hooks;
  -
  -} dav_set_target_walker_ctx;
  -
  -static dav_error * dav_set_target_walker(dav_walk_resource *wres, int calltype)
  -{
  -    dav_set_target_walker_ctx *ctx = wres->walk_ctx;
  -    dav_error *err = NULL;
  -
  -    /* Check the state of the resource: must be a checked-in version
  -     * or baseline selector
  -     */
  -    /* ### need a general mechanism for reporting precondition violations
  -     * ### (should be returning XML document for 403/409 responses)
  -     */
  -    if (wres->resource->type != DAV_RESOURCE_TYPE_REGULAR
  -        || !wres->resource->versioned || wres->resource->working) {
  -	err = dav_new_error(ctx->w.pool, HTTP_CONFLICT, 0,
  -			    "<DAV:must-be-checked-in-version-selector/>");
  -    }
  -    else {
  -        /* do the set-target operation */
  -        err = (*ctx->vsn_hooks->set_target)(wres->resource, ctx->target, ctx->is_label);
  -    }
  -
  -    if (err != NULL) {
  -        /* ### need utility routine to add response with description? */
  -        dav_add_response(wres, err->status, NULL);
  -        wres->response->desc = err->desc;
  -    }
  -
  -    return NULL;
  -}
  -
  -static int dav_method_set_target(request_rec *r)
  -{
       dav_resource *resource;
  +    dav_resource *version = NULL;
       const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r);
       ap_xml_doc *doc;
       ap_xml_elem *child;
  +    int is_label = 0;
       int depth;
       int result;
  -    apr_size_t tsize;
  +    int tsize;
  +    const char *target;
  +    dav_response *multi_response;
       dav_error *err;
  -    dav_set_target_walker_ctx ctx = { { 0 } };
  -    dav_response *multi_status;
  +    dav_lookup_result lookup;
   
  -    /* If no versioning provider, decline the request */
  -    if (vsn_hooks == NULL)
  +    /* If no versioning provider, or UPDATE not supported,
  +     * decline the request */
  +    if (vsn_hooks == NULL || vsn_hooks->update == NULL)
           return DECLINED;
   
  -    /* Ask repository module to resolve the resource */
  -    err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */,
  -                           &resource);
  -    if (err != NULL)
  -        return dav_handle_err(r, err, NULL);
  -    if (!resource->exists) {
  -        /* Apache will supply a default error for this. */
  -        return HTTP_NOT_FOUND;
  -    }
  -
       if ((depth = dav_get_depth(r, 0)) < 0) {
   	/* dav_get_depth() supplies additional information for the
   	 * default message. */
  @@ -3612,21 +3564,18 @@
   	return result;
       }
   
  -    if (doc == NULL || !dav_validate_root(doc, "set-target")) {
  +    if (doc == NULL || !dav_validate_root(doc, "update")) {
   	/* This supplies additional information for the default message. */
   	ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
   		      "The request body does not contain "
  -		      "a \"set-target\" element.");
  +		      "an \"update\" element.");
   	return HTTP_BAD_REQUEST;
       }
   
  -    /* check for label-name or version element */
  -    if ((child = dav_find_child(doc->root, "label-name")) != NULL) {
  -        ctx.is_label = 1;
  -    }
  +    /* check for label-name or version element, but not both */
  +    if ((child = dav_find_child(doc->root, "label-name")) != NULL)
  +        is_label = 1;
       else if ((child = dav_find_child(doc->root, "version")) != NULL) {
  -        ctx.is_label = 0;
  -
           /* get the href element */
           if ((child = dav_find_child(child, "href")) == NULL) {
   	    ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
  @@ -3637,14 +3586,21 @@
       }
       else {
   	ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
  -		      "The \"set-target\" element does not contain "
  +		      "The \"update\" element does not contain "
   		      "a \"label-name\" or \"version\" element.");
   	return HTTP_BAD_REQUEST;
       }
  +
  +    /* a depth greater than zero is only allowed for a label */
  +    if (!is_label && depth != 0) {
  +	ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
  +		      "Depth must be zero for UPDATE with a version");
  +	return HTTP_BAD_REQUEST;
  +    }
   
  -    /* get the target value (a label or a version URI */
  +    /* get the target value (a label or a version URI) */
       ap_xml_to_text(r->pool, child, AP_XML_X2T_INNER, NULL, NULL,
  -                   &ctx.target, &tsize);
  +                   &target, &tsize);
       if (tsize == 0) {
   	ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
   		      "A \"label-name\" or \"href\" element does not contain "
  @@ -3652,39 +3608,69 @@
   	return HTTP_BAD_REQUEST;
       }
   
  -    /* do the set-target operation walk */
  -    ctx.w.walk_type = DAV_WALKTYPE_NORMAL;
  -    ctx.w.func = dav_set_target_walker;
  -    ctx.w.walk_ctx = &ctx;
  -    ctx.w.pool = r->pool;
  -    ctx.w.root = resource;
  -    ctx.vsn_hooks = vsn_hooks;
  +    /* Ask repository module to resolve the resource */
  +    err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */,
  +                           &resource);
  +    if (err != NULL)
  +        return dav_handle_err(r, err, NULL);
   
  -    err = (*resource->hooks->walk)(&ctx.w, depth, &multi_status);
  +    if (!resource->exists) {
  +        /* Apache will supply a default error for this. */
  +        return HTTP_NOT_FOUND;
  +    }
   
  -    if (err != NULL) {
  -        /* some sort of error occurred which terminated the walk */
  -        err = dav_push_error(r->pool, err->status, 0,
  -                             "The SET-TARGET operation was terminated prematurely.",
  -                             err);
  -        return dav_handle_err(r, err, multi_status);
  +    /* ### need a general mechanism for reporting precondition violations
  +     * ### (should be returning XML document for 403/409 responses)
  +     */
  +    if (resource->type != DAV_RESOURCE_TYPE_REGULAR
  +        || !resource->versioned || resource->working) {
  +	return dav_error_response(r, HTTP_CONFLICT,
  +				  "<DAV:must-be-checked-in-version-controlled-resource>");
       }
   
  -    if (multi_status != NULL) {
  -        /* One or more resources had errors. If depth was zero, convert
  -         * response to simple error, else make sure there is an
  -         * overall error to pass to dav_handle_err()
  -         */
  -        if (depth == 0) {
  -            err = dav_new_error(r->pool, multi_status->status, 0, multi_status->desc);
  -            multi_status = NULL;
  +    /* if target is a version, resolve the version resource */
  +    /* ### dav_lookup_uri only allows absolute URIs; is that OK? */
  +    if (!is_label) {
  +        lookup = dav_lookup_uri(target, r);
  +        if (lookup.rnew == NULL) {
  +	    if (lookup.err.status == HTTP_BAD_REQUEST) {
  +	        /* This supplies additional information for the default message. */
  +	        ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
  +			      lookup.err.desc);
  +	        return HTTP_BAD_REQUEST;
  +	    }
  +
  +	    /* ### this assumes that dav_lookup_uri() only generates a status
  +	     * ### that Apache can provide a status line for!! */
  +
  +	    return dav_error_response(r, lookup.err.status, lookup.err.desc);
           }
  -        else {
  -            err = dav_new_error(r->pool, HTTP_MULTI_STATUS, 0,
  -                                "Errors occurred during the SET-TARGET operation.");
  +        if (lookup.rnew->status != HTTP_OK) {
  +	    /* ### how best to report this... */
  +	    return dav_error_response(r, lookup.rnew->status,
  +				      "Version URI had an error.");
           }
   
  -        return dav_handle_err(r, err, multi_status);
  +        /* resolve version resource */
  +        err = dav_get_resource(lookup.rnew, 0 /* label_allowed */,
  +                               0 /* use_checked_in */, &version);
  +        if (err != NULL)
  +            return dav_handle_err(r, err, NULL);
  +
  +        /* NULL out target, since we're using a version resource */
  +        target = NULL;
  +    }
  +
  +    /* do the UPDATE operation */
  +    err = (*vsn_hooks->update)(resource, version, target, depth, &multi_response);
  +
  +    if (err != NULL) {
  +        err = dav_push_error(r->pool, err->status, 0,
  +			     ap_psprintf(r->pool,
  +					 "Could not UPDATE %s.",
  +					 ap_escape_html(r->pool, r->uri)),
  +                             err);
  +        return dav_handle_err(r, err, multi_response);
       }
   
       /* set the Cache-Control header, per the spec */
  @@ -4402,8 +4388,8 @@
   	return dav_method_checkin(r);
       }
   
  -    if (!strcmp(r->method, "SET-TARGET")) {
  -	return dav_method_set_target(r);
  +    if (!strcmp(r->method, "UPDATE")) {
  +	return dav_method_update(r);
       }
   
       if (!strcmp(r->method, "LABEL")) {
  
  
  
  1.45      +37 -19    httpd-2.0/modules/dav/main/mod_dav.h
  
  Index: mod_dav.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/dav/main/mod_dav.h,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -u -r1.44 -r1.45
  --- mod_dav.h	2001/03/26 10:10:31	1.44
  +++ mod_dav.h	2001/03/28 07:37:25	1.45
  @@ -321,12 +321,12 @@
   **     baselined  = 0
   **     working    = 0
   **
  -** version/baseline selector:
  +** version-controlled resource or configuration:
   **     type       = DAV_RESOURCE_TYPE_REGULAR
   **     exists     = 1
   **     collection = ? (1 if collection)
   **     versioned  = 1
  -**     baselined  = ? (1 if baseline selector)
  +**     baselined  = ? (1 if configuration)
   **     working    = ? (1 if checked out)
   **
   ** version/baseline history:
  @@ -357,9 +357,9 @@
   **     type       = DAV_RESOURCE_TYPE_WORKSPACE
   **     exists     = ? (1 if exists)
   **     collection = 1
  -**     versioned  = * (jvasta: I'm seeking clarification on whether a
  -**     baselined  = *  workspace can be versioned or baselined)
  -**     working    = *
  +**     versioned  = ? (1 if version-controlled)
  +**     baselined  = ? (1 if baseline-controlled)
  +**     working    = ? (1 if checked out)
   **
   ** activity:
   **     type       = DAV_RESOURCE_TYPE_ACTIVITY
  @@ -383,7 +383,7 @@
                            * and is always 1 for VERSION and WORKING */
   
       int baselined;      /* 0 => not baselined; can be 1 for
  -                         * REGULAR and VERSION resources;
  +                         * REGULAR, VERSION, and WORKSPACE resources;
                            * versioned == 1 when baselined == 1 */
   
       int working;	/* 0 => not checked out; can be 1 for
  @@ -1937,31 +1937,26 @@
                               apr_array_header_t *activities,
                               dav_resource **working_resource);
   
  -    /* Uncheckout a resource. If successful, the resource
  +    /* Uncheckout a checked-out resource. If successful, the resource
        * object state is updated appropriately.
        */
       dav_error * (*uncheckout)(dav_resource *resource);
   
  -    /* Checkin a working resource. If successful, the resource
  +    /* Checkin a checked-out resource. If successful, the resource
        * object state is updated appropriately, and the
        * version_resource descriptor will refer to the new version.
        * The version_resource argument can be NULL if the caller
        * is not interested in the new version resource.
  +     *
  +     * If the client has specified DAV:keep-checked-out in the checkin
  +     * request, then the keep_checked_out flag is set. The provider
  +     * should create a new version, but keep the resource in the
  +     * checked-out state.
        */
       dav_error * (*checkin)(dav_resource *resource,
  +                           int keep_checked_out,
                              dav_resource **version_resource);
   
  -    /*
  -    ** Set the default target of a version selector or
  -    ** baseline selector resource.
  -    ** The target argument specifies the new target, which
  -    ** can be a label, if is_label != 0, or a version URI,
  -    ** if is_label == 0.
  -    */
  -    dav_error * (*set_target)(const dav_resource *resource,
  -	                      const char *target,
  -                              int is_label);
  -
       /* Determine whether a non-versioned (or non-existent) resource
        * is versionable. Returns != 0 if resource can be versioned.
        */
  @@ -2014,6 +2009,29 @@
       ** The following hooks are optional; if not defined, then the
       ** corresponding protocol methods will be unsupported.
       */
  +
  +    /*
  +    ** Set the state of a checked-in version-controlled resource.
  +    **
  +    ** If the request specified a version, the version resource
  +    ** represents that version. If the request specified a label,
  +    ** then "version" is NULL, and "label" is the label.
  +    **
  +    ** The depth argument is ignored for a file, and can be 0, 1, or
  +    ** DAV_INFINITY for a collection. The depth argument only applies
  +    ** with a label, not a version.
  +    **
  +    ** If an error occurs in a child resource, then the return value is
  +    ** non-NULL, and *response is set to a multistatus response.
  +    **
  +    ** This hook is optional; if not defined, then the UPDATE method
  +    ** will not be supported.
  +    */
  +    dav_error * (*update)(const dav_resource *resource,
  +                          const dav_resource *version,
  +                          const char *label,
  +                          int depth,
  +                          dav_response **response);
   
       /*
       ** Add a label to a version. The resource is either a specific
  
  
  
  1.27      +10 -10    httpd-2.0/modules/dav/main/props.c
  
  Index: props.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/dav/main/props.c,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -u -r1.26 -r1.27
  --- props.c	2001/02/16 04:26:35	1.26
  +++ props.c	2001/03/28 07:37:25	1.27
  @@ -337,22 +337,22 @@
   	/* policy: liveprop providers cannot define no-namespace properties */
   	return DAV_PROPID_CORE_UNKNOWN;
       }
  -    else if (strcmp(ns_uri, "DAV:") == 0) {
  +
  +    /* check liveprop providers first, so they can define core properties */
  +    propid = dav_run_find_liveprop(propdb->resource, ns_uri, propname,
  +                                   provider);
  +    if (propid != 0) {
  +        return propid;
  +    }
  +
  +    /* check for core property */
  +    if (strcmp(ns_uri, "DAV:") == 0) {
   	const char * const *p = dav_core_props;
   
   	for (propid = DAV_PROPID_CORE; *p != NULL; ++p, ++propid)
   	    if (strcmp(propname, *p) == 0) {
   		return propid;
   	    }
  -
  -	/* didn't find it. fall thru. a provider can define DAV: props */
  -    }
  -
  -    /* is there a liveprop provider for this property? */
  -    propid = dav_run_find_liveprop(propdb->resource, ns_uri, propname,
  -                                   provider);
  -    if (propid != 0) {
  -        return propid;
       }
   
       /* no provider for this property */
  
  
  
  1.24      +4 -2      httpd-2.0/modules/dav/main/util.c
  
  Index: util.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/dav/main/util.c,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -u -r1.23 -r1.24
  --- util.c	2001/03/13 02:13:54	1.23
  +++ util.c	2001/03/28 07:37:25	1.24
  @@ -1739,7 +1739,8 @@
               if (undo)
                   err = (*vsn_hooks->uncheckout)(resource);
               else
  -                err = (*vsn_hooks->checkin)(resource, NULL);
  +                err = (*vsn_hooks->checkin)(resource,
  +                                            0 /*keep_checked_out*/, NULL);
   
               if (err != NULL) {
   	        body = apr_psprintf(r->pool,
  @@ -1774,7 +1775,8 @@
   	if (undo)
   	    err = (*vsn_hooks->uncheckout)(av_info->parent_resource);
   	else
  -	    err = (*vsn_hooks->checkin)(av_info->parent_resource, NULL);
  +	    err = (*vsn_hooks->checkin)(av_info->parent_resource,
  +                                        0 /*keep_checked_out*/, NULL);
   
   	if (err != NULL) {
   	    body = apr_psprintf(r->pool,
  
  
  

Mime
View raw message