mod_dav.c revision b0fb330a8581c8bfab5e523084f9f39264a52b12
** repository implementation. ** - within a DAV hierarchy, if an unknown method is used and we default ** to Apache's implementation, it sends back an OPTIONS with the wrong ** set of methods -- there is NO HOOK for us. ** therefore: we need to manually handle the HTTP_METHOD_NOT_ALLOWED ** and HTTP_NOT_IMPLEMENTED responses (not ap_send_error_response). ** - process_mkcol_body() had to dup code from ap_setup_client_block(). ** - it would be nice to get status lines from Apache for arbitrary ** - it would be nice to be able to extend Apache's set of response ** codes so that it doesn't return 500 when an unknown code is placed ** - http_vhost functions should apply "const" to their params ** - For PROPFIND, we batch up the entire response in memory before ** sending it. We may want to reorganize around sending the information ** as we suck it in from the propdb. Alternatively, we should at least ** generate a total Content-Length if we're going to buffer in memory ** so that we can keep the connection open. /* per-dir configuration */ int handle_get;
/* cached from repository hook structure */ /* per-server configuration */ /* LimitXMLRequestBody handling */ /* forward-declare for use in configuration lookup */ /* copy a module's providers into our per-directory configuration state */ /* ### if NULL? need to error out somehow... */ /* Set hooks for any providers in the module */ /* ### how to signal an error? */ /* ### not yet defined */ /* ### not yet defined */ /* ### need to error out somehow... */ /* DBG0("dav_init_handler"); */ /* NOTE: dir==NULL creates the default per-dir config */ /* DBG1("dav_create_dir_config: %08lx", (long)conf); */ ** Locate the appropriate module (NULL == default) and copy the module's ** providers' hooks into our configuration state. /* DBG3("dav_merge_dir_config: new=%08lx base=%08lx overrides=%08lx", (long)newconf, (long)base, (long)overrides); */ /* Call repository hook to resolve resource */ /* ### not yet defined */ /* ### not yet defined */ /* unknown provider type */ * Command handler for the DAV directive, which is FLAG. * Command handler for the DAVDepthInfinity directive, which is FLAG. * Command handler for the DAVLockDB directive, which is TAKE1 * Command handler for DAVMinTimeout directive, which is TAKE1 return "DAVMinTimeout requires a non-negative integer.";
* Command handler for DAVParam directive, which is TAKE2 * Command handler for LimitXMLRequestBody directive, which is TAKE1 return "LimitXMLRequestBody requires a non-negative integer.";
** Send a nice response back to the user. In most cases, Apache doesn't ** allow us to provide details in the body about what happened. This ** function allows us to completely specify the response body. /* since we're returning DONE, ensure the request body is consumed. */ /* begin the response now... */ /* the response has been sent. */ * ### Use of DONE obviates logging..! ** Apache's URI escaping does not replace '&' since that is a valid character ** in a URI (to form a query section). We must explicitly handle it so that ** we can embed the URI into an XML document. /* check the easy case... */ /* more work needed... sigh. */ ** Note: this is a teeny bit of overkill since we know there are no ** '<' or '>' characters, but who cares. /* Set the correct status and Content-Type */ /* Send all of the headers now */ /* Start a timeout for delivering the response. */ /* Send the actual multistatus response now... */ "<D:multistatus xmlns:D=\"DAV:\"", r);
/* ### it would be nice to get a status line from Apache */ "<D:status>HTTP/1.1 %d status text goes here</D:status>" /* assume this includes <propstat> and is quoted properly */ ** We supply the description, so we know it doesn't have to /* Done with sending and the timeout. */ ** Write error information to the log. /* ### should have a directive to log the first or all */ ** Handle the standard error processing. <err> must be non-NULL. ** <response> is set by the following: ** - dav_validate_request() ** - repos_hooks->remove_resource ** - repos_hooks->move_resource ** - repos_hooks->copy_resource /* our error messages are safe; tell Apache this */ /* since we're returning DONE, ensure the request body is consumed. */ /* handy function for return values of methods that (may) create things */ /* did the target resource already exist? */ /* Apache will supply a default message */ /* Per HTTP/1.1, S10.2.2: add a Location header to contain the * URI that was created. */ /* ### rnew->uri does not contain an absoluteURI. S14.30 states that * ### the Location header requires an absoluteURI. where to get it? */ /* ### disable until we get the right value */ /* ### insert an ETag header? see HTTP/1.1 S10.2.2 */ /* Apache doesn't allow us to set a variable body for HTTP_CREATED, so * we must manufacture the entire response. */ /* ### move to dav_util? */ /* The caller will return an HTTP_BAD_REQUEST. This will augment the * default message that Apache provides. */ "An invalid Depth header was specified.");
return 1;
/* default is "T" */ /* The caller will return an HTTP_BAD_REQUEST. This will augment the * default message that Apache provides. */ "An invalid Overwrite header was specified.");
/* resolve a request URI to a resource descriptor */ /* Call repository hook to resolve resource */ /* ### this should happen at startup rather than per-request */ "No %s has been configured.",
/* Apache will supply a default error for this. */ /* open the thing lazily */ /* malformed header. ignore it (per S14.16 of RFC2616) */ /* invalid range. ignore it (per S14.16 of RFC2616) */ /* we now have a valid range */ /* handle the GET method */ /* This method should only be called when the resource is not * visible to Apache. We will fetch the resource from the repository, * then create a subrequest for Apache to handle. /* Apache will supply a default error for this. */ /* Check resource type */ "Cannot GET this type of resource.");
/* Cannot handle GET of a collection from a repository */ "No default response to GET for a " ** We can use two different approaches for a GET. ** 1) get_pathname will return a pathname to a file which should be ** sent to the client. If the repository provides this, then we ** This is the best alternative since it allows us to do a sub- ** request on the file, which gives the Apache framework a chance ** to deal with negotiation, MIME types, or whatever. ** 2) open_stream and read_stream. /* Ask repository for copy of file */ /* Convert to canonical filename, so Apache detects component * separators (on Windows, it only looks for '/', not '\') /* Create a sub-request with the new filename */ /* This may be a HEAD request */ /* ### this enables header generation */ /* Run the sub-request */ /* set up the HTTP headers for the response */ "Unable to set up HTTP headers.",
/* use plain READ mode unless we see a Content-Range */ /* process the Content-Range header (if present) */ /* use a read mode which is seekable */ /* ### assuming FORBIDDEN is probably not quite right... */ "Unable to GET contents for %s.",
"Could not seek to beginning of the " "specified Content-Range.",
err);
/* all set. send the headers now. */ /* start a timeout for delivering the response. */ /* note: range_end - range_start is an ssize_t */ /* ### what to do with this error? */ /* reset the timeout after a successful write */ /* Done with the request; clear its timeout */ ** ### range_start should equal range_end+1. if it doesn't, then ** ### we did not send enough data to the client. the client will ** ### hang (and timeout) waiting for the data. ** ### what to do? abort the connection? /* validate resource on POST, then pass it off to the default handler */ /* Ask repository module to resolve the resource */ /* Note: depth == 0. Implies no need for a multistatus response. */ /* ### add a higher-level description? */ /* handle the PUT method */ /* Ask repository module to resolve the resource */ /* If not a file or collection resource, PUT not allowed */ "Cannot create resource %s with PUT.",
/* Cannot PUT a collection */ "Cannot PUT to a collection.");
** Note: depth == 0 normally requires no multistatus response. However, ** if we pass DAV_VALIDATE_PARENT, then we could get an error on a URI ** other than the Request-URI, thereby requiring a multistatus. ** If the resource does not exist (DAV_RESOURCE_NULL), then we must ** check the resource *and* its parent. If the resource exists or is ** a locknull resource, then we check only the resource. /* ### add a higher-level description? */ /* make sure the resource can be modified (if versioning repository) */ /* ### add a higher-level description? */ /* truncate and rewrite the file unless we see a Content-Range */ /* Create the new file in the repository */ /* ### assuming FORBIDDEN is probably not quite right... */ "Unable to PUT new contents for %s.",
/* a range was provided. seek to the start */ ** Once we start reading the request, then we must read the ** whole darn thing. ap_discard_request_body() won't do anything ** for a partially-read request. /* write whatever we read, until we see an error */ ** ### what happens if we read more/less than the amount ** ### specified in the Content-Range? eek... ** Error reading request body. This has precedence over "An error occurred while reading the " /* no error during the write, but we hit one at close. use it. */ ** Ensure that we think the resource exists now. ** ### eek. if an error occurred during the write and we did not commit, /* restore modifiability of resources back to what they were */ /* check for errors now */ "The PUT was successful, but there " "was a problem reverting the writability of " "the resource or its parent collection.",
/* ### place the Content-Type and Content-Language into the propdb */ /* The file creation was successful, but the locking failed. */ "The file was PUT successfully, but there " "was a problem opening the lock database " "which prevents inheriting locks from the " /* The file creation was successful, but the locking failed. */ "The file was PUT successfully, but there " "was a problem updating its lock " /* NOTE: WebDAV spec, S8.7.1 states properties should be unaffected */ /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */ /* ### move this to dav_util? */ /* just drop some data into an dav_response */ /* handle the DELETE method */ /* We don't use the request body right now, so torch it. */ /* Ask repository module to resolve the resource */ /* Apache will supply a default error for this. */ /* 2518 says that depth must be infinity only for collections. * For non-collections, depth is ignored, unless it is an illegal value (1). /* This supplies additional information for the default message. */ "Depth must be \"infinity\" for DELETE of a collection.");
/* This supplies additional information for the default message. */ "Depth of \"1\" is not allowed for DELETE.");
/* Check for valid resource type */ /* ### allow DAV_RESOURCE_TYPE_REVISION with All-Bindings header */ "Cannot delete resource %s.",
** If any resources fail the lock/If: conditions, then we must fail ** the delete. Each of the failing resources will be listed within ** a DAV:multistatus body, wrapped into a 424 response. ** Note that a failure on the resource itself does not generate a "Could not DELETE %s due to a failed " "precondition (e.g. locks).",
/* ### RFC 2518 s. 8.10.5 says to remove _all_ locks, not just those * locked by the token(s) in the if_header. /* if versioned resource, make sure parent is checked out */ /* ### add a higher-level description? */ /* try to remove the resource */ /* restore writability of parent back to what it was */ /* check for errors now */ "The DELETE was successful, but there " "was a problem reverting the writability of " "its parent collection.",
/* ### HTTP_NO_CONTENT if no body, HTTP_OK if there is a body (some day) */ /* Apache will supply a default error for this. */ /* handle the OPTIONS method */ /* per HTTP/1.1 S9.2, we can discard this body */ /* resolve the resource */ /* determine which providers are available */ ** Iterate through the live property providers; add their URIs to /* this tells MSFT products to skip looking for FrontPage extensions */ ** Three cases: resource is null (3), is lock-null (7.4), or exists. ** All cases support OPTIONS and LOCK. ** (Lock-) null resources also support MKCOL and PUT. ** Lock-null support PROPFIND and UNLOCK. ** Existing resources support lots of stuff. /* ### take into account resource type */ "GET, HEAD, POST, DELETE, TRACE, " "PROPFIND, PROPPATCH, COPY, MOVE",
/* files also support PUT */ "GET, HEAD, POST, DELETE, TRACE, " "PROPFIND, PROPPATCH, COPY, MOVE, PUT",
/* resource is lock-null. */ /* ### internal error! */ /* If there is a versioning provider, add versioning options */ /* ### take into account resource type */ /* ### this will send a Content-Type. the default OPTIONS does not. */ /* ### the default (ap_send_http_options) returns OK, but I believe * ### that is because it is the default handler and nothing else * ### will run after the thing. */ /* we've sent everything necessary to the client. */ /* just return if we built the thing already */ "<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR ** Note: ctx->doc can only be NULL for DAV_PROPFIND_IS_ALLPROP. Since ** dav_get_allprops() does not need to do namespace translation, ** Note: we cast to lose the "const". The propdb won't try to change ** the resource, however, since we are opening readonly. /* ### do something with err! */ /* ### what to do about closing the propdb on server failure? */ /* handle the PROPFIND method */ /* Ask repository module to resolve the resource */ /* Apache will supply a default error for this. */ /* dav_get_depth() supplies additional information for the /* default is to DISALLOW these requests */ "PROPFIND requests with a " "Depth of \"infinity\" are " /* note: doc == NULL if no request body */ /* This supplies additional information for the default message. */ "The \"propfind\" element was not found.");
/* ### validate that only one of these three elements is present */ /* note: no request body implies allprop */ /* "propfind" element must have one of the above three children */ /* This supplies additional information for the default message. */ "The \"propfind\" element does not contain one of " "the required child elements (the specific command).");
/* ### should open read-only */ "The lock database could not be opened, " "preventing access to the various lock " "properties for the PROPFIND.",
/* if we have a lock database, then we can walk locknull resources */ /* ### add a higher-level description? */ /* return a 207 (Multi-Status) response now. */ /* if a 404 was generated for an HREF, then we need to spit out the * doc's namespaces for use by the 404. Note that <response> elements * will override these ns0, ns1, etc, but NOT within the <response> * scope for the badprops. */ /* NOTE: propstat_404 != NULL implies doc != NULL */ /* the response has been sent. */ /* ### might be nice to sort by status code and description */ for ( ; i-- > 0; ++
ctx ) {
/* nothing was assigned here yet, so make it a 424 */ "Attempted DAV:set operation " "could not be completed due " "operation could not be " "completed due to other " /* ### we should use compute_desc if necessary... */ ** ### we probably need to revise the way we assemble the response... ** ### this code assumes everything will return status==200. for ( ; i-- > 0; ++
ctx ) {
"<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR ** Call <func> for each context. This can stop when an error occurs, or ** simply iterate through the whole list. ** Returns 1 if an error occurs (and the iteration is aborted). Returns 0 ** if all elements are processed. ** If <reverse> is true (non-zero), then the list is traversed in /* handle the PROPPATCH method */ /* Ask repository module to resolve the resource */ /* Apache will supply a default error for this. */ /* note: doc == NULL if no request body */ /* This supplies additional information for the default message. */ "The request body does not contain " "a \"propertyupdate\" element.");
/* Check If-Headers and existing locks */ /* Note: depth == 0. Implies no need for a multistatus response. */ /* ### add a higher-level description? */ "Could not open the property " /* ### what to do about closing the propdb on server failure? */ /* ### validate "live" properties */ /* set up an array to hold property operation contexts */ /* do a first pass to ensure that all "remove" properties exist */ /* Ignore children that are not set/remove */ /* make sure that a "prop" child exists for set/remove */ /* This supplies additional information for the default message. */ "A \"prop\" element is missing inside " "the propertyupdate command.");
ctx->r = r;
/* for later use by dav_prop_log_errors() */ /* ### should test that we found at least one set/remove */ /* execute all of the operations */ /* make sure this gets closed! */ /* log any errors that occurred */ /* ### should probably use something new to pass along this text... */ /* the response has been sent. */ /* This is snarfed from ap_setup_client_block(). We could get pretty * close to this behavior by passing REQUEST_NO_BODY, but we need to * return HTTP_UNSUPPORTED_MEDIA_TYPE (while ap_setup_client_block * returns HTTP_REQUEST_ENTITY_TOO_LARGE). */ /* make sure to set the Apache request fields properly. */ /* Use this instead of Apache's default error string */ "Unknown Transfer-Encoding %s",
tenc);
/* This supplies additional information for the default message. */ "Invalid Content-Length %s",
lenp);
/* Apache will supply a default error for this. */ ** Get rid of the body. this will call ap_setup_client_block(), but ** our copy above has already verified its work. /* handle the MKCOL method */ /* handle the request body */ /* ### this may move lower once we start processing bodies */ /* Ask repository module to resolve the resource */ /* oops. something was already there! */ /* Apache will supply a default error for this. */ /* ### we should provide a specific error message! */ ** Check If-Headers and existing locks. ** Note: depth == 0 normally requires no multistatus response. However, ** if we pass DAV_VALIDATE_PARENT, then we could get an error on a URI ** other than the Request-URI, thereby requiring a multistatus. ** If the resource does not exist (DAV_RESOURCE_NULL), then we must ** check the resource *and* its parent. If the resource exists or is ** a locknull resource, then we check only the resource. /* ### add a higher-level description? */ /* if versioned resource, make sure parent is checked out */ /* ### add a higher-level description? */ /* try to create the collection */ /* restore modifiability of parent back to what it was */ /* check for errors now */ "The MKCOL was successful, but there " "was a problem reverting the writability of " "its parent collection.",
/* The directory creation was successful, but the locking failed. */ "The MKCOL was successful, but there " "was a problem opening the lock database " "which prevents inheriting locks from the " /* The dir creation was successful, but the locking failed. */ "The MKCOL was successful, but there " "was a problem updating its lock " /* return an appropriate response (HTTP_CREATED) */ /* handle the COPY and MOVE methods */ /* Ask repository module to resolve the resource */ /* Apache will supply a default error for this. */ /* If not a file or collection resource, COPY/MOVE not allowed */ /* get the destination URI */ /* Look in headers provided by Netscape's Roaming Profiles */ /* This supplies additional information for the default message. */ "The request is missing a Destination header.");
/* This supplies additional information for the default message. */ /* ### this assumes that dav_lookup_uri() only generates a status * ### that Apache can provide a status line for!! */ /* ### how best to report this... */ "Destination URI had an error.");
/* Resolve destination resource */ /* are the two resources handled by the same repository? */ /* ### this message exposes some backend config, but screw it... */ "Destination URI is handled by a " "different repository than the source URI. " "MOVE or COPY between repositories is " /* get and parse the overwrite header value */ /* dav_get_overwrite() supplies additional information for the /* quick failure test: if dest exists and overwrite is false. */ /* Supply some text for the error response body. */ "Destination is not empty and " "Overwrite is not \"T\"");
/* are the source and destination the same? */ /* Supply some text for the error response body. */ "Source and Destination URIs are the same.");
/* get and parse the Depth header value. "0" and "infinity" are legal. */ /* dav_get_depth() supplies additional information for the /* This supplies additional information for the default message. */ "Depth must be \"0\" or \"infinity\" for COPY or MOVE.");
/* This supplies additional information for the default message. */ "Depth must be \"infinity\" when moving a collection.");
** Check If-Headers and existing locks for each resource in the source ** if we are performing a MOVE. We will return a 424 response with a ** DAV:multistatus body. The multistatus responses will contain the ** information about any resource that fails the validation. ** We check the parent resource, too, since this is a MOVE. Moving the ** resource effectively removes it from the parent collection, so we ** must ensure that we have met the appropriate conditions. ** If a problem occurs with the Request-URI itself, then a plain error ** (rather than a multistatus) will be returned. "Could not MOVE %s due to a failed " "precondition on the source " ** Check If-Headers and existing locks for destination. Note that we ** use depth==infinity since the target (hierarchy) will be deleted ** Note that we are overwriting the target, which implies a DELETE, so ** we are subject to the error/response rules as a DELETE. Namely, we ** will return a 424 error if any of the validations fail. ** (see dav_method_delete() for more information) "failed precondition on the " "destination (e.g. locks).",
/* Supply some text for the error response body. */ "Source collection contains the " /* The destination must exist (since it contains the source), and * a condition above implies Overwrite==T. Obviously, we cannot * delete the Destination before the MOVE/COPY, as that would /* Supply some text for the error response body. */ "Destination collection contains the Source " "and Overwrite has been specified.");
/* ### for now, we don't need anything in the body */ /* ### add a higher-level description? */ /* remove any locks from the old resources */ ** ### this is Yet Another Traversal. if we do a rename(), then we ** ### really don't have to do this in some cases since the inode ** ### values will remain constant across the move. but we can't ** ### know that fact from outside the provider :-( ** ### note that we now have a problem atomicity in the move/copy ** ### since a failure after this would have removed locks (technically, ** ### this is okay to do, but really...) /* ### this is wrong! it blasts direct locks on parent resources */ /* remember whether target resource existed */ /* if this is a move, then the source parent collection will be modified */ /* ### add a higher-level description? */ /* prepare the destination collection for modification */ /* could not make destination writable: * if move, restore state of source parent /* ### add a higher-level description? */ /* If source and destination parents are the same, then * use the same object, so status updates to one are reflected /* New resource will be same kind as source */ /* If target exists, remove it first (we know Ovewrite must be TRUE). /* restore parent collection states */ /* check for errors from reverting writability */ "The MOVE/COPY was successful, but there was a " "problem reverting the writability of the " "source parent collection.",
"The MOVE/COPY was successful, but there was a " "problem reverting the writability of the " "destination parent collection.",
/* propagate any indirect locks at the target */ /* The move/copy was successful, but the locking failed. */ "The MOVE/COPY was successful, but there " "was a problem updating the lock " /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */ /* dav_method_lock: Handler to implement the DAV LOCK method ** Returns appropriate HTTP_* response. /* If no locks provider, decline the request */ "Depth must be 0 or \"infinity\" for LOCK.");
/* Ask repository module to resolve the resource */ ** Open writable. Unless an error occurs, we'll be ** writing into the database. /* ### add a higher-level description? */ /* ### add a higher-level description to err? */ ** Check If-Headers and existing locks. ** If this will create a locknull resource, then the LOCK will affect ** the parent collection (much like a PUT/MKCOL). For that case, we must ** validate the parent resource's conditions. "Could not LOCK %s due to a failed " "precondition (e.g. other locks).",
** ### Assumption: We can renew multiple locks on the same resource ** ### at once. First harvest all the positive lock-tokens given in ** ### the If header. Then modify the lock entries for this resource ** ### with the new Timeout val. "The lock refresh for %s failed " "because no lock tokens were " "specified in an \"If:\" " /* ### add a higher-level description to err? */ /* apply lower bound (if any) from DAVMinTimeout directive */ /* ### add a higher-level description to err? */ /* the response has been sent. */ /* dav_method_unlock: Handler to implement the DAV UNLOCK method * Returns appropriate HTTP_* response. /* If no locks provider, decline the request */ "Unlock failed (%s): No Lock-Token specified in header", r->
filename);
/* ### should provide more specifics... */ /* ### should provide more specifics... */ "The UNLOCK on %s failed -- an " "invalid lock token was specified " "in the \"If:\" header.",
/* Ask repository module to resolve the resource */ ** Check If-Headers and existing locks. ** Note: depth == 0 normally requires no multistatus response. However, ** if we pass DAV_VALIDATE_PARENT, then we could get an error on a URI ** other than the Request-URI, thereby requiring a multistatus. ** If the resource is a locknull resource, then the UNLOCK will affect ** the parent collection (much like a delete). For that case, we must ** validate the parent resource's conditions. /* ### add a higher-level description? */ /* ### RFC 2518 s. 8.11: If this resource is locked by locktoken, * _all_ resources locked by locktoken are released. It does not say * resource has to be the root of an infinte lock. Thus, an UNLOCK * on any part of an infinte lock will remove the lock on all resources. * For us, if r->filename represents an indirect lock (part of an infinity lock), * we must actually perform an UNLOCK on the direct lock for this resource. /* handle the SEARCH method from DASL */ /* ### we know this method, but we won't allow it yet */ /* Apache will supply a default error for this. */ /* Do some error checking, like if the querygrammar is * supported by the content type, and then pass the * request on to the appropriate query module. /* handle the CHECKOUT method */ /* If no versioning provider, decline the request */ /* ### eventually check body for DAV:checkin-policy */ /* Ask repository module to resolve the resource */ /* Apache will supply a default error for this. */ /* Check the state of the resource: must be a file or collection, * must be versioned, and must not already be checked out. "Cannot checkout this type of resource.");
"Cannot checkout unversioned resource.");
"The resource is already checked out to the workspace.");
/* ### do lock checks, once behavior is defined */ "Could not CHECKOUT resource %s.",
/* handle the UNCHECKOUT method */ /* If no versioning provider, decline the request */ /* Ask repository module to resolve the resource */ /* Apache will supply a default error for this. */ /* Check the state of the resource: must be a file or collection, * must be versioned, and must be checked out. "Cannot uncheckout this type of resource.");
"Cannot uncheckout unversioned resource.");
"The resource is not checked out to the workspace.");
/* ### do lock checks, once behavior is defined */ "Could not UNCHECKOUT resource %s.",
/* handle the CHECKIN method */ /* If no versioning provider, decline the request */ /* Ask repository module to resolve the resource */ /* Apache will supply a default error for this. */ /* Check the state of the resource: must be a file or collection, * must be versioned, and must be checked out. "Cannot checkin this type of resource.");
"Cannot checkin unversioned resource.");
"The resource is not checked out to the workspace.");
/* ### do lock checks, once behavior is defined */ "Could not CHECKIN resource %s.",
* Response handler for DAV resources /* quickly ignore any HTTP/0.9 requests */ /* ### do we need to do anything with r->proxyreq ?? */ * 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. * These are the DAV methods we handle. * These are methods that we don't handle directly, but let the * server's default handler do for us as our agent. /* ### 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 */ * 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. /* ### add'l methods for Advanced Collections, ACLs, DASL */ /* if DAV is not enabled, then we've got nothing to do */ ** ### need some work to pull Content-Type and Content-Language ** ### from the property database. ** If the repository hasn't indicated that it will handle the ** GET method, then just punt. ** ### this isn't quite right... taking over the response can break ** ### things like mod_negotiation. need to look into this some more. /* ### we should (instead) trap the ones that we DO understand */ /* ### the handler DOES handle POST, so we need to fix one of these */ ** ### anything else to do here? could another module and/or ** ### config option "take over" the handler here? i.e. how do ** ### we lock down this hierarchy so that we are the ultimate ** ### arbiter? (or do we simply depend on the administrator ** ### to avoid conflicting configurations?) ** ### I think the OK stops running type-checkers. need to look. /*--------------------------------------------------------------------------- ** Configuration info for the module "turn DAV on/off for a directory or location" "specify a lock database" "specify minimum allowed timeout" "allow Depth infinity PROPFIND requests" "DAVParam <parameter name> <parameter value>" "Limit (in bytes) on maximum size of an XML-based request body" NULL,
/* filename translation */ NULL,
/* check_user_id */ NULL,
/* header parser */ NULL /* post read-request */