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

📄 mod_dav.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 5 页
字号:
    ** '<' or '>' characters, but who cares.    */    return ap_xml_quote_string(p, e_uri, 0);}static void dav_send_multistatus(request_rec *r, int status,                                 dav_response *first,				 apr_array_header_t *namespaces){    /* Set the correct status and Content-Type */    r->status = status;    r->content_type = DAV_XML_CONTENT_TYPE;    /* Send the headers and actual multistatus response now... */    ap_rputs(DAV_XML_HEADER DEBUG_CR	     "<D:multistatus xmlns:D=\"DAV:\"", r);    if (namespaces != NULL) {	int i;	for (i = namespaces->nelts; i--; ) {	    ap_rprintf(r, " xmlns:ns%d=\"%s\"", i,		       AP_XML_GET_URI_ITEM(namespaces, i));	}    }    /* ap_rputc('>', r); */    ap_rputs(">" DEBUG_CR, r);    for (; first != NULL; first = first->next) {	ap_text *t;	if (first->propresult.xmlns == NULL) {	    ap_rputs("<D:response>", r);	}	else {	    ap_rputs("<D:response", r);	    for (t = first->propresult.xmlns; t; t = t->next) {		ap_rputs(t->text, r);	    }	    ap_rputc('>', r);	}	ap_rputs(DEBUG_CR "<D:href>", r);	ap_rputs(dav_xml_escape_uri(r->pool, first->href), r);	ap_rputs("</D:href>" DEBUG_CR, r);	if (first->propresult.propstats == NULL) {	    /* use the Status-Line text from Apache.  Note, this will	     * default to 500 Internal Server Error if first->status	     * is not a known (or valid) status code. */	    ap_rprintf(r,		       "<D:status>HTTP/1.1 %s</D:status>" DEBUG_CR, 		       ap_get_status_line(first->status));	}	else {	    /* assume this includes <propstat> and is quoted properly */	    for (t = first->propresult.propstats; t; t = t->next) {		ap_rputs(t->text, r);	    }	}	if (first->desc != NULL) {	    /*	    ** We supply the description, so we know it doesn't have to	    ** have any escaping/encoding applied to it.	    */	    ap_rputs("<D:responsedescription>", r);	    ap_rputs(first->desc, r);	    ap_rputs("</D:responsedescription>" DEBUG_CR, r);	}	ap_rputs("</D:response>" DEBUG_CR, r);    }    ap_rputs("</D:multistatus>" DEBUG_CR, r);}/*** dav_log_err()**** Write error information to the log.*/static void dav_log_err(request_rec *r, dav_error *err, int level){    dav_error *errscan;    /* Log the errors */    /* ### should have a directive to log the first or all */    for (errscan = err; errscan != NULL; errscan = errscan->prev) {	if (errscan->desc == NULL)	    continue;	if (errscan->save_errno != 0) {	    errno = errscan->save_errno;	    ap_log_rerror(APLOG_MARK, level, errno, r, "%s  [%d, #%d]",			  errscan->desc, errscan->status, errscan->error_id);	}	else {	    ap_log_rerror(APLOG_MARK, level | APLOG_NOERRNO, 0, r,			  "%s  [%d, #%d]",			  errscan->desc, errscan->status, errscan->error_id);	}    }}/*** dav_handle_err()**** Handle the standard error processing. <err> must be non-NULL.**** <response> is set by the following:**   - dav_validate_request()**   - dav_add_lock()**   - repos_hooks->remove_resource**   - repos_hooks->move_resource**   - repos_hooks->copy_resource*/static int dav_handle_err(request_rec *r, dav_error *err,			  dav_response *response){    /* log the errors */    dav_log_err(r, err, APLOG_ERR);    if (response == NULL) {	/* our error messages are safe; tell Apache this */	apr_table_setn(r->notes, "verbose-error-to", "*");	return err->status;    }    /* since we're returning DONE, ensure the request body is consumed. */    (void) ap_discard_request_body(r);    /* send the multistatus and tell Apache the request/response is DONE. */    dav_send_multistatus(r, err->status, response, NULL);    return DONE;}/* handy function for return values of methods that (may) create things */static int dav_created(request_rec *r, const char *locn, const char *what,                       int replaced){    const char *body;    if (locn == NULL) {	locn = r->uri;    }    /* did the target resource already exist? */    if (replaced) {	/* Apache will supply a default message */	return HTTP_NO_CONTENT;    }    /* Per HTTP/1.1, S10.2.2: add a Location header to contain the     * URI that was created. */    /* Convert locn to an absolute URI, and return in Location header */    apr_table_setn(r->headers_out, "Location", ap_construct_url(r->pool, locn, r));    /* ### 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. */    body = apr_psprintf(r->pool, "%s %s has been created.",                        what, ap_escape_html(r->pool, locn));    return dav_error_response(r, HTTP_CREATED, body);}/* ### move to dav_util? */int dav_get_depth(request_rec *r, int def_depth){    const char *depth = apr_table_get(r->headers_in, "Depth");    if (depth == NULL) {	return def_depth;    }    if (strcasecmp(depth, "infinity") == 0) {	return DAV_INFINITY;    }    else if (strcmp(depth, "0") == 0) {	return 0;    }    else if (strcmp(depth, "1") == 0) {	return 1;    }    /* The caller will return an HTTP_BAD_REQUEST. This will augment the     * default message that Apache provides. */    ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,		  "An invalid Depth header was specified.");    return -1;}static int dav_get_overwrite(request_rec *r){    const char *overwrite = apr_table_get(r->headers_in, "Overwrite");    if (overwrite == NULL) {	return 1;		/* default is "T" */    }    if ((*overwrite == 'F' || *overwrite == 'f') && overwrite[1] == '\0') {	return 0;    }    if ((*overwrite == 'T' || *overwrite == 't') && overwrite[1] == '\0') {	return 1;    }    /* The caller will return an HTTP_BAD_REQUEST. This will augment the     * default message that Apache provides. */    ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,		  "An invalid Overwrite header was specified.");    return -1;}/* resolve a request URI to a resource descriptor. * * If label_allowed != 0, then allow the request target to be altered by * a Label: header. * * If use_checked_in is true, then the repository provider should return * the resource identified by the DAV:checked-in property of the resource * identified by the Request-URI. */static dav_error * dav_get_resource(request_rec *r, int label_allowed,                                    int use_checked_in, dav_resource **res_p){    dav_dir_conf *conf;    const char *label = NULL;    dav_error *err;    /* if the request target can be overridden, get any target selector */    if (label_allowed) {        label = apr_table_get(r->headers_in, "label");    }    conf = ap_get_module_config(r->per_dir_config, &dav_module);    /* assert: conf->provider != NULL */    /* resolve the resource */    err = (*conf->provider->repos->get_resource)(r, conf->dir,                                                 label, use_checked_in,                                                 res_p);    if (err != NULL) {        err = dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,                             "Could not fetch resource information.", err);        return err;    }    /* Note: this shouldn't happen, but just be sure... */    if (*res_p == NULL) {        /* ### maybe use HTTP_INTERNAL_SERVER_ERROR */        return dav_new_error(r->pool, HTTP_NOT_FOUND, 0,                             apr_psprintf(r->pool,                                          "The provider did not define a "                                          "resource for %s.",                                          ap_escape_html(r->pool, r->uri)));    }    /* ### hmm. this doesn't feel like the right place or thing to do */    /* if there were any input headers requiring a Vary header in the response,     * add it now */    dav_add_vary_header(r, r, *res_p);    return NULL;}static dav_error * dav_open_lockdb(request_rec *r, int ro, dav_lockdb **lockdb){    const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);    if (hooks == NULL) {	*lockdb = NULL;	return NULL;    }    /* open the thing lazily */    return (*hooks->open_lockdb)(r, ro, 0, lockdb);}static int dav_parse_range(request_rec *r,                           apr_off_t *range_start, apr_off_t *range_end){    const char *range_c;    char *range;    char *dash;    char *slash;    range_c = apr_table_get(r->headers_in, "content-range");    if (range_c == NULL)        return 0;    range = apr_pstrdup(r->pool, range_c);    if (strncasecmp(range, "bytes ", 6) != 0        || (dash = ap_strchr(range, '-')) == NULL        || (slash = ap_strchr(range, '/')) == NULL) {        /* malformed header. ignore it (per S14.16 of RFC2616) */        return 0;    }    *dash = *slash = '\0';    /* ### atol may not be large enough for the apr_off_t */    *range_start = atol(range + 6);    *range_end = atol(dash + 1);    if (*range_end < *range_start        || (slash[1] != '*' && atol(slash + 1) <= *range_end)) {        /* invalid range. ignore it (per S14.16 of RFC2616) */        return 0;    }    /* we now have a valid range */    return 1;}/* handle the GET method */static int dav_method_get(request_rec *r){    dav_resource *resource;    int result;    dav_error *err;    /* 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.     */    err = dav_get_resource(r, 1 /* 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;    }    /* Check resource type */    if (resource->type != DAV_RESOURCE_TYPE_REGULAR &&        resource->type != DAV_RESOURCE_TYPE_VERSION &&        resource->type != DAV_RESOURCE_TYPE_WORKING)    {        return dav_error_response(r, HTTP_CONFLICT,                                  "Cannot GET this type of resource.");    }    /* Cannot handle GET of a collection from a repository */    if (resource->collection) {	return dav_error_response(r, HTTP_CONFLICT,                                   "No default response to GET for a "                                  "collection.");    }    /*    ** 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    **    use it.    **    **    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.    */    if (resource->hooks->get_pathname != NULL) {	const char *pathname;	void *fhandle;	request_rec *new_req;		/* Ask repository for copy of file */	pathname = (*resource->hooks->get_pathname)(resource, &fhandle);	if (pathname == NULL) {	    return HTTP_NOT_FOUND;	}	/* Convert to canonical filename, so Apache detects component	 * separators (on Windows, it only looks for '/', not '\')	 */	pathname = ap_os_case_canonical_filename(r->pool, pathname);	/* Create a sub-request with the new filename */	new_req = ap_sub_req_lookup_file(pathname, r, NULL);	if (new_req == NULL) {	    (*resource->hooks->free_file)(fhandle);	    return HTTP_INTERNAL_SERVER_ERROR;	}	/* This may be a HEAD request */	new_req->header_only = r->header_only;	/* ### this enables header generation */	new_req->assbackwards = 0;	/* Run the sub-request */	result = ap_run_sub_req(new_req);	ap_destroy_sub_req(new_req);	/* Free resources */	(*resource->hooks->free_file)(fhandle);	return result;    }

⌨️ 快捷键说明

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