⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_dav.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, *    if any, must include the following acknowledgment: *       "This product includes software developed by the *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowledgment may appear in the software itself, *    if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", *    nor may "Apache" appear in their name, without prior written *    permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. *//*** DAV extension module for Apache 2.0.***** This module is repository-independent. It depends on hooks provided by a** repository implementation.**** APACHE ISSUES:**   - 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**     status codes**   - 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**     into r->status.**   - http_vhost functions should apply "const" to their params**** DESIGN NOTES:**   - 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.*/#include "apr_strings.h"#include "apr_lib.h"            /* for apr_is* */#define APR_WANT_STRFUNC#include "apr_want.h"#include "httpd.h"#include "http_config.h"#include "http_core.h"#include "http_log.h"#include "http_main.h"#include "http_protocol.h"#include "http_request.h"#include "util_script.h"#include "mod_dav.h"/* ### what is the best way to set this? */#define DAV_DEFAULT_PROVIDER    "filesystem"enum {    DAV_ENABLED_UNSET = 0,    DAV_ENABLED_OFF,    DAV_ENABLED_ON};/* per-dir configuration */typedef struct {    const char *provider_name;    const dav_provider *provider;    const char *dir;    int locktimeout;    int allow_depthinfinity;    apr_table_t *d_params;	/* per-directory DAV config parameters */} dav_dir_conf;/* per-server configuration */typedef struct {    int unused;} dav_server_conf;#define DAV_INHERIT_VALUE(parent, child, field) \		((child)->field ? (child)->field : (parent)->field)/* forward-declare for use in configuration lookup */extern module DAV_DECLARE_DATA dav_module;static void dav_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,                             server_rec *s){    /* DBG0("dav_init_handler"); */    ap_add_version_component(p, "DAV/2");}static void *dav_create_server_config(apr_pool_t *p, server_rec *s){    dav_server_conf *newconf;    newconf = (dav_server_conf *) apr_pcalloc(p, sizeof(*newconf));    /* ### this isn't used at the moment... */    return newconf;}static void *dav_merge_server_config(apr_pool_t *p, void *base, void *overrides){#if 0    dav_server_conf *child = overrides;#endif    dav_server_conf *newconf;    newconf = (dav_server_conf *) apr_pcalloc(p, sizeof(*newconf));    /* ### nothing to merge right now... */    return newconf;}static void *dav_create_dir_config(apr_pool_t *p, char *dir){    /* NOTE: dir==NULL creates the default per-dir config */    dav_dir_conf *conf;    conf = (dav_dir_conf *) apr_pcalloc(p, sizeof(*conf));    /* clean up the directory to remove any trailing slash */    if (dir != NULL) {        char *d;        apr_size_t l;        d = apr_pstrdup(p, dir);        l = strlen(d);        if (l > 1 && d[l - 1] == '/')            d[l - 1] = '\0';        conf->dir = d;    }    conf->d_params = apr_table_make(p, 1);    return conf;}static void *dav_merge_dir_config(apr_pool_t *p, void *base, void *overrides){    dav_dir_conf *parent = base;    dav_dir_conf *child = overrides;    dav_dir_conf *newconf = (dav_dir_conf *) apr_pcalloc(p, sizeof(*newconf));    /* DBG3("dav_merge_dir_config: new=%08lx  base=%08lx  overrides=%08lx",       (long)newconf, (long)base, (long)overrides); */    newconf->provider_name = DAV_INHERIT_VALUE(parent, child, provider_name);    newconf->provider = DAV_INHERIT_VALUE(parent, child, provider);    if (parent->provider_name != NULL) {        if (child->provider_name == NULL) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, NULL,                         "\"DAV Off\" cannot be used to turn off a subtree "                         "of a DAV-enabled location.");        }        else if (strcasecmp(child->provider_name,                            parent->provider_name) != 0) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, NULL,                         "A subtree cannot specify a different DAV provider "                         "than its parent.");        }    }    newconf->locktimeout = DAV_INHERIT_VALUE(parent, child, locktimeout);    newconf->dir = DAV_INHERIT_VALUE(parent, child, dir);    newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child,                                                     allow_depthinfinity);    newconf->d_params = apr_table_copy(p, parent->d_params);    apr_table_overlap(newconf->d_params, child->d_params,		      APR_OVERLAP_TABLES_SET);    return newconf;}apr_table_t *dav_get_dir_params(const request_rec *r){    dav_dir_conf *conf;    conf = ap_get_module_config(r->per_dir_config, &dav_module);    return conf->d_params;}static const dav_provider * dav_get_provider(request_rec *r){    dav_dir_conf *conf;    conf = ap_get_module_config(r->per_dir_config, &dav_module);    /* assert: conf->provider_name != NULL       (otherwise, DAV is disabled, and we wouldn't be here) */    /* assert: conf->provider != NULL       (checked when conf->provider_name is set) */    return conf->provider;}const dav_hooks_locks *dav_get_lock_hooks(request_rec *r){    return dav_get_provider(r)->locks;}const dav_hooks_propdb *dav_get_propdb_hooks(request_rec *r){    return dav_get_provider(r)->propdb;}const dav_hooks_vsn *dav_get_vsn_hooks(request_rec *r){    return dav_get_provider(r)->vsn;}const dav_hooks_binding *dav_get_binding_hooks(request_rec *r){    return dav_get_provider(r)->binding;}/* * Command handler for the DAV directive, which is TAKE1. */static const char *dav_cmd_dav(cmd_parms *cmd, void *config, const char *arg1){    dav_dir_conf *conf = (dav_dir_conf *) config;    if (strcasecmp(arg1, "on") == 0) {	conf->provider_name = DAV_DEFAULT_PROVIDER;    }    else if (strcasecmp(arg1, "off") == 0) {	conf->provider_name = NULL;        conf->provider = NULL;    }    else {        conf->provider_name = apr_pstrdup(cmd->pool, arg1);    }    if (conf->provider_name != NULL) {        /* lookup and cache the actual provider now */        conf->provider = dav_lookup_provider(conf->provider_name);        if (conf->provider == NULL) {            /* by the time they use it, the provider should be loaded and               registered with us. */            return apr_psprintf(cmd->pool,                                "Unknown DAV provider: %s",                                conf->provider_name);        }    }    return NULL;}/* * Command handler for the DAVDepthInfinity directive, which is FLAG. */static const char *dav_cmd_davdepthinfinity(cmd_parms *cmd, void *config,                                            int arg){    dav_dir_conf *conf = (dav_dir_conf *) config;    if (arg)	conf->allow_depthinfinity = DAV_ENABLED_ON;    else	conf->allow_depthinfinity = DAV_ENABLED_OFF;    return NULL;}/* * Command handler for DAVMinTimeout directive, which is TAKE1 */static const char *dav_cmd_davmintimeout(cmd_parms *cmd, void *config,                                         const char *arg1){    dav_dir_conf *conf = (dav_dir_conf *) config;    conf->locktimeout = atoi(arg1);    if (conf->locktimeout < 0)        return "DAVMinTimeout requires a non-negative integer.";    return NULL;}/* * Command handler for DAVParam directive, which is TAKE2 */static const char *dav_cmd_davparam(cmd_parms *cmd, void *config,                                    const char *arg1, const char *arg2){    dav_dir_conf *conf = (dav_dir_conf *) config;    apr_table_set(conf->d_params, arg1, arg2);    return NULL;}/*** dav_error_response()**** 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.**** ### this function is not logging any errors! (e.g. the body)*/static int dav_error_response(request_rec *r, int status, const char *body){    r->status = status;    r->status_line = ap_get_status_line(status);    r->content_type = "text/html";    /* since we're returning DONE, ensure the request body is consumed. */    (void) ap_discard_request_body(r);    /* begin the response now... */    ap_rvputs(r,	      DAV_RESPONSE_BODY_1,	      r->status_line,	      DAV_RESPONSE_BODY_2,	      &r->status_line[4],	      DAV_RESPONSE_BODY_3,	      NULL);    ap_rputs(body, r);    ap_rputs(ap_psignature("\n<P><HR>\n", r), r);    ap_rputs(DAV_RESPONSE_BODY_4, r);    /* the response has been sent. */    /*     * ### Use of DONE obviates logging..!     */    return DONE;}/*** 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.*/static const char *dav_xml_escape_uri(apr_pool_t *p, const char *uri){    const char *e_uri = ap_escape_uri(p, uri);    /* check the easy case... */    if (ap_strchr_c(e_uri, '&') == NULL)	return e_uri;    /* more work needed... sigh. */    /*    ** Note: this is a teeny bit of overkill since we know there are no

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -