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

📄 mod_dav.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* resource exists */        apr_table_addn(methods, "GET", "");        apr_table_addn(methods, "HEAD", "");        apr_table_addn(methods, "POST", "");        apr_table_addn(methods, "DELETE", "");        apr_table_addn(methods, "TRACE", "");        apr_table_addn(methods, "PROPFIND", "");        apr_table_addn(methods, "PROPPATCH", "");        apr_table_addn(methods, "COPY", "");        apr_table_addn(methods, "MOVE", "");	if (!resource->collection)            apr_table_addn(methods, "PUT", "");        if (locks_hooks != NULL) {            apr_table_addn(methods, "LOCK", "");            apr_table_addn(methods, "UNLOCK", "");        }        break;    case DAV_RESOURCE_LOCK_NULL:	/* resource is lock-null. */        apr_table_addn(methods, "MKCOL", "");        apr_table_addn(methods, "PROPFIND", "");        apr_table_addn(methods, "PUT", "");        if (locks_hooks != NULL) {            apr_table_addn(methods, "LOCK", "");            apr_table_addn(methods, "UNLOCK", "");        }        break;    case DAV_RESOURCE_NULL:	/* resource is null. */        apr_table_addn(methods, "MKCOL", "");        apr_table_addn(methods, "PUT", "");        if (locks_hooks != NULL)            apr_table_addn(methods, "LOCK", "");        break;    default:	/* ### internal error! */	break;    }    /* If there is a versioning provider, add versioning methods */    if (vsn_hooks != NULL) {        if (!resource->exists) {            if ((*vsn_hooks->versionable)(resource))                apr_table_addn(methods, "VERSION-CONTROL", "");            if (vsn_hooks->can_be_workspace != NULL                && (*vsn_hooks->can_be_workspace)(resource))                apr_table_addn(methods, "MKWORKSPACE", "");            if (vsn_hooks->can_be_activity != NULL                && (*vsn_hooks->can_be_activity)(resource))                apr_table_addn(methods, "MKACTIVITY", "");        }        else if (!resource->versioned) {            if ((*vsn_hooks->versionable)(resource))                apr_table_addn(methods, "VERSION-CONTROL", "");        }        else if (resource->working) {            apr_table_addn(methods, "CHECKIN", "");            /* ### we might not support this DeltaV option */            apr_table_addn(methods, "UNCHECKOUT", "");        }        else if (vsn_hooks->add_label != NULL) {            apr_table_addn(methods, "CHECKOUT", "");            apr_table_addn(methods, "LABEL", "");        }        else {            apr_table_addn(methods, "CHECKOUT", "");        }    }    /* If there is a bindings provider, see if resource is bindable */    if (binding_hooks != NULL        && (*binding_hooks->is_bindable)(resource)) {        apr_table_addn(methods, "BIND", "");    }    /* Generate the Allow header */    arr = apr_table_elts(methods);    elts = (apr_table_entry_t *) arr->elts;    text_size = 0;    /* first, compute total length */    for (i = 0; i < arr->nelts; ++i) {        if (elts[i].key == NULL)            continue;        /* add 1 for comma or null */        text_size += strlen(elts[i].key) + 1;    }    s = allow = apr_palloc(r->pool, text_size);    for (i = 0; i < arr->nelts; ++i) {        if (elts[i].key == NULL)            continue;        if (s != allow)            *s++ = ',';        strcpy(s, elts[i].key);        s += strlen(s);    }    apr_table_setn(r->headers_out, "Allow", allow);    /* if there was no request body, then there is no response body */    if (doc == NULL) {        ap_set_content_length(r, 0);        /* ### this sends 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. */        return DONE;    }    /* handle each options request */    for (elem = doc->root->first_child; elem != NULL; elem = elem->next) {        /* check for something we recognize first */        int core_option = 0;        dav_error *err = NULL;        if (elem->ns == AP_XML_NS_DAV_ID) {            if (strcmp(elem->name, "supported-method-set") == 0) {                err = dav_gen_supported_methods(r, elem, methods, &body);                core_option = 1;            }            else if (strcmp(elem->name, "supported-live-property-set") == 0) {                err = dav_gen_supported_live_props(r, resource, elem, &body);                core_option = 1;            }            else if (strcmp(elem->name, "supported-report-set") == 0) {                err = dav_gen_supported_reports(r, resource, elem, vsn_hooks, &body);                core_option = 1;            }        }        if (err != NULL)            return dav_handle_err(r, err, NULL);        /* if unrecognized option, pass to versioning provider */        if (!core_option) {            if ((err = (*vsn_hooks->get_option)(resource, elem, &body))                != NULL) {                return dav_handle_err(r, err, NULL);            }        }    }    /* send the options response */    r->status = HTTP_OK;    r->content_type = DAV_XML_CONTENT_TYPE;    /* send the headers and response body */    ap_rputs(DAV_XML_HEADER DEBUG_CR             "<D:options-response xmlns:D=\"DAV:\">" DEBUG_CR, r);    for (t = body.first; t != NULL; t = t->next)        ap_rputs(t->text, r);    ap_rputs("</D:options-response>" DEBUG_CR, r);    /* we've sent everything necessary to the client. */    return DONE;}static void dav_cache_badprops(dav_walker_ctx *ctx){    const ap_xml_elem *elem;    ap_text_header hdr = { 0 };    /* just return if we built the thing already */    if (ctx->propstat_404 != NULL) {	return;    }    ap_text_append(ctx->w.pool, &hdr,		   "<D:propstat>" DEBUG_CR		   "<D:prop>" DEBUG_CR);    elem = dav_find_child(ctx->doc->root, "prop");    for (elem = elem->first_child; elem; elem = elem->next) {	ap_text_append(ctx->w.pool, &hdr,                       ap_xml_empty_elem(ctx->w.pool, elem));    }    ap_text_append(ctx->w.pool, &hdr,		   "</D:prop>" DEBUG_CR		   "<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR		   "</D:propstat>" DEBUG_CR);    ctx->propstat_404 = hdr.first;}static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype){    dav_walker_ctx *ctx = wres->walk_ctx;    dav_error *err;    dav_propdb *propdb;    dav_get_props_result propstats = { 0 };    /*    ** Note: ctx->doc can only be NULL for DAV_PROPFIND_IS_ALLPROP. Since    ** dav_get_allprops() does not need to do namespace translation,    ** we're okay.    **    ** Note: we cast to lose the "const". The propdb won't try to change    ** the resource, however, since we are opening readonly.    */    err = dav_open_propdb(ctx->r, ctx->w.lockdb, wres->resource, 1,			  ctx->doc ? ctx->doc->namespaces : NULL, &propdb);    if (err != NULL) {	/* ### do something with err! */	if (ctx->propfind_type == DAV_PROPFIND_IS_PROP) {	    dav_get_props_result badprops = { 0 };	    /* some props were expected on this collection/resource */	    dav_cache_badprops(ctx);	    badprops.propstats = ctx->propstat_404;	    dav_add_response(wres, 0, &badprops);	}	else {	    /* no props on this collection/resource */	    dav_add_response(wres, HTTP_OK, NULL);	}	return NULL;    }    /* ### what to do about closing the propdb on server failure? */    if (ctx->propfind_type == DAV_PROPFIND_IS_PROP) {	propstats = dav_get_props(propdb, ctx->doc);    }    else {        dav_prop_insert what = ctx->propfind_type == DAV_PROPFIND_IS_ALLPROP                                 ? DAV_PROP_INSERT_VALUE                                 : DAV_PROP_INSERT_NAME;	propstats = dav_get_allprops(propdb, what);    }    dav_close_propdb(propdb);    dav_add_response(wres, 0, &propstats);    return NULL;}/* handle the PROPFIND method */static int dav_method_propfind(request_rec *r){    dav_resource *resource;    int depth;    dav_error *err;    int result;    ap_xml_doc *doc;    const ap_xml_elem *child;    dav_walker_ctx ctx = { { 0 } };    dav_response *multi_status;    /* Ask repository module to resolve the resource */    err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */,                           &resource);    if (err != NULL)        return dav_handle_err(r, err, NULL);    if (dav_get_resource_state(r, resource) == DAV_RESOURCE_NULL) {	/* Apache will supply a default error for this. */	return HTTP_NOT_FOUND;    }    if ((depth = dav_get_depth(r, DAV_INFINITY)) < 0) {	/* dav_get_depth() supplies additional information for the	 * default message. */	return HTTP_BAD_REQUEST;    }    if (depth == DAV_INFINITY && resource->collection) {	dav_dir_conf *conf;	conf = (dav_dir_conf *) ap_get_module_config(r->per_dir_config,						     &dav_module);        /* default is to DISALLOW these requests */	if (conf->allow_depthinfinity != DAV_ENABLED_ON) {            return dav_error_response(r, HTTP_FORBIDDEN,                                      apr_psprintf(r->pool,                                                  "PROPFIND requests with a "                                                  "Depth of \"infinity\" are "                                                  "not allowed for %s.",                                                  ap_escape_html(r->pool,                                                                 r->uri)));	}    }    if ((result = ap_xml_parse_input(r, &doc)) != OK) {	return result;    }    /* note: doc == NULL if no request body */    if (doc && !dav_validate_root(doc, "propfind")) {	/* This supplies additional information for the default message. */	ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,		      "The \"propfind\" element was not found.");	return HTTP_BAD_REQUEST;    }    /* ### validate that only one of these three elements is present */    if (doc == NULL	|| (child = dav_find_child(doc->root, "allprop")) != NULL) {	/* note: no request body implies allprop */	ctx.propfind_type = DAV_PROPFIND_IS_ALLPROP;    }    else if ((child = dav_find_child(doc->root, "propname")) != NULL) {	ctx.propfind_type = DAV_PROPFIND_IS_PROPNAME;    }    else if ((child = dav_find_child(doc->root, "prop")) != NULL) {	ctx.propfind_type = DAV_PROPFIND_IS_PROP;    }    else {	/* "propfind" element must have one of the above three children */	/* This supplies additional information for the default message. */	ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,		      "The \"propfind\" element does not contain one of "		      "the required child elements (the specific command).");	return HTTP_BAD_REQUEST;    }    ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;    ctx.w.func = dav_propfind_walker;    ctx.w.walk_ctx = &ctx;    ctx.w.pool = r->pool;    ctx.w.root = resource;    ctx.doc = doc;    ctx.r = r;    /* ### should open read-only */    if ((err = dav_open_lockdb(r, 0, &ctx.w.lockdb)) != NULL) {	err = dav_push_error(r->pool, err->status, 0,			     "The lock database could not be opened, "			     "preventing access to the various lock "			     "properties for the PROPFIND.",			     err);	return dav_handle_err(r, err, NULL);    }    if (ctx.w.lockdb != NULL) {	/* if we have a lock database, then we can walk locknull resources */	ctx.w.walk_type |= DAV_WALKTYPE_LOCKNULL;    }    err = (*resource->hooks->walk)(&ctx.w, depth, &multi_status);    if (ctx.w.lockdb != NULL) {	(*ctx.w.lockdb->hooks->close_lockdb)(ctx.w.lockdb);    }    if (err != NULL) {	/* ### add a higher-level description? */	return dav_handle_err(r, err, NULL);    }    /* 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 */    if (ctx.propstat_404 != NULL) {	dav_send_multistatus(r, HTTP_MULTI_STATUS, multi_status,                             doc->namespaces);    }    else {	dav_send_multistatus(r, HTTP_MULTI_STATUS, multi_status, NULL);    }    /* the response has been sent. */    return DONE;}static ap_text * dav_failed_proppatch(apr_pool_t *p,                                       apr_array_header_t *prop_ctx){    ap_text_header hdr = { 0 };    int i = prop_ctx->nelts;    dav_prop_ctx *ctx = (dav_prop_ctx *)prop_ctx->elts;    dav_error *err424_set = NULL;    dav_error *err424_delete = NULL;    const char *s;    /* ### might be nice to sort by status code and description *

⌨️ 快捷键说明

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