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

📄 util.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ==================================================================== * 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.***  - various utilities, repository-independent*/#include "apr_strings.h"#include "apr_lib.h"#define APR_WANT_STRFUNC#include "apr_want.h"#include "mod_dav.h"#include "http_request.h"#include "http_config.h"#include "http_vhost.h"#include "http_log.h"#include "http_protocol.h"DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status,                                       int error_id, const char *desc){    int save_errno = errno;    dav_error *err = apr_pcalloc(p, sizeof(*err));    /* DBG3("dav_new_error: %d %d %s", status, error_id, desc ? desc : "(no desc)"); */    err->status = status;    err->error_id = error_id;    err->desc = desc;    err->save_errno = save_errno;    return err;}DAV_DECLARE(dav_error*) dav_push_error(apr_pool_t *p, int status,                                        int error_id, const char *desc,                                        dav_error *prev){    dav_error *err = apr_pcalloc(p, sizeof(*err));    err->status = status;    err->error_id = error_id;    err->desc = desc;    err->prev = prev;    return err;}DAV_DECLARE(void) dav_check_bufsize(apr_pool_t * p, dav_buffer *pbuf,                                     apr_size_t extra_needed){    /* grow the buffer if necessary */    if (pbuf->cur_len + extra_needed > pbuf->alloc_len) {	char *newbuf;	pbuf->alloc_len += extra_needed + DAV_BUFFER_PAD;	newbuf = apr_palloc(p, pbuf->alloc_len);	memcpy(newbuf, pbuf->buf, pbuf->cur_len);	pbuf->buf = newbuf;    }}DAV_DECLARE(void) dav_set_bufsize(apr_pool_t * p, dav_buffer *pbuf,                                   apr_size_t size){    /* NOTE: this does not retain prior contents */    /* NOTE: this function is used to init the first pointer, too, since       the PAD will be larger than alloc_len (0) for zeroed structures */    /* grow if we don't have enough for the requested size plus padding */    if (size + DAV_BUFFER_PAD > pbuf->alloc_len) {	/* set the new length; min of MINSIZE */	pbuf->alloc_len = size + DAV_BUFFER_PAD;	if (pbuf->alloc_len < DAV_BUFFER_MINSIZE)	    pbuf->alloc_len = DAV_BUFFER_MINSIZE;	pbuf->buf = apr_palloc(p, pbuf->alloc_len);    }    pbuf->cur_len = size;}/* initialize a buffer and copy the specified (null-term'd) string into it */DAV_DECLARE(void) dav_buffer_init(apr_pool_t *p, dav_buffer *pbuf,                                   const char *str){    dav_set_bufsize(p, pbuf, strlen(str));    memcpy(pbuf->buf, str, pbuf->cur_len + 1);}/* append a string to the end of the buffer, adjust length */DAV_DECLARE(void) dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf,                                     const char *str){    size_t len = strlen(str);    dav_check_bufsize(p, pbuf, len + 1);    memcpy(pbuf->buf + pbuf->cur_len, str, len + 1);    pbuf->cur_len += len;}/* place a string on the end of the buffer, do NOT adjust length */DAV_DECLARE(void) dav_buffer_place(apr_pool_t *p, dav_buffer *pbuf,                                    const char *str){    size_t len = strlen(str);    dav_check_bufsize(p, pbuf, len + 1);    memcpy(pbuf->buf + pbuf->cur_len, str, len + 1);}/* place some memory on the end of a buffer; do NOT adjust length */DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf,                                        const void *mem, apr_size_t amt,                                        apr_size_t pad){    dav_check_bufsize(p, pbuf, amt + pad);    memcpy(pbuf->buf + pbuf->cur_len, mem, amt);}/*** dav_lookup_uri()**** Extension for ap_sub_req_lookup_uri() which can't handle absolute** URIs properly.**** If NULL is returned, then an error occurred with parsing the URI or** the URI does not match the current server.*/dav_lookup_result dav_lookup_uri(const char *uri, request_rec * r){    dav_lookup_result result = { 0 };    const char *scheme;    apr_port_t port;    uri_components comp;    char *new_file;    const char *domain;    /* first thing to do is parse the URI into various components */    if (ap_parse_uri_components(r->pool, uri, &comp) != HTTP_OK) {	result.err.status = HTTP_BAD_REQUEST;	result.err.desc = "Invalid syntax in Destination URI.";	return result;    }    /* the URI must be an absoluteURI (WEBDAV S9.3) */    if (comp.scheme == NULL) {	result.err.status = HTTP_BAD_REQUEST;	result.err.desc = "Destination URI must be an absolute URI.";	return result;    }    /* ### not sure this works if the current request came in via https: */    scheme = r->parsed_uri.scheme;    if (scheme == NULL)	scheme = ap_http_method(r);    /* insert a port if the URI did not contain one */    if (comp.port == 0)	comp.port = ap_default_port_for_scheme(comp.scheme);    /* now, verify that the URI uses the same scheme as the current request.       the port, must match our port.       the URI must not have a query (args) or a fragment     */    apr_sockaddr_port_get(&port, r->connection->local_addr);    if (strcasecmp(comp.scheme, scheme) != 0 ||	comp.port != port) {	result.err.status = HTTP_BAD_GATEWAY;	result.err.desc = apr_psprintf(r->pool,				      "Destination URI refers to different "				      "scheme or port (%s://hostname:%d)"                                       APR_EOL_STR "(want: %s://hostname:%d)",				      comp.scheme ? comp.scheme : scheme,				      comp.port ? comp.port : port,				      scheme, port);	return result;    }    if (comp.query != NULL || comp.fragment != NULL) {	result.err.status = HTTP_BAD_REQUEST;	result.err.desc =	    "Destination URI contains invalid components "	    "(a query or a fragment).";	return result;    }    /* we have verified the scheme, port, and general structure */    /*    ** Hrm.  IE5 will pass unqualified hostnames for both the     ** Host: and Destination: headers.  This breaks the    ** http_vhost.c::matches_aliases function.    **    ** For now, qualify unqualified comp.hostnames with    ** r->server->server_hostname.    **    ** ### this is a big hack. Apache should provide a better way.    ** ### maybe the admin should list the unqualified hosts in a    ** ### <ServerAlias> block?    */    if (strrchr(comp.hostname, '.') == NULL &&	(domain = strchr(r->server->server_hostname, '.')) != NULL) {	comp.hostname = apr_pstrcat(r->pool, comp.hostname, domain, NULL);    }    /* now, if a hostname was provided, then verify that it represents the       same server as the current connection. note that we just use our       port, since we've verified the URI matches ours */    if (comp.hostname != NULL &&	!ap_matches_request_vhost(r, comp.hostname, port)) {	result.err.status = HTTP_BAD_GATEWAY;	result.err.desc = "Destination URI refers to a different server.";	return result;    }    /* we have verified that the requested URI denotes the same server as       the current request. Therefore, we can use ap_sub_req_lookup_uri() */    /* reconstruct a URI as just the path */    new_file = ap_unparse_uri_components(r->pool, &comp, UNP_OMITSITEPART);    /*     * Lookup the URI and return the sub-request. Note that we use the     * same HTTP method on the destination. This allows the destination     * to apply appropriate restrictions (e.g. readonly).     */    result.rnew = ap_sub_req_method_uri(r->method, new_file, r, NULL);    return result;}/* ---------------------------------------------------------------**** XML UTILITY FUNCTIONS*//* validate that the root element uses a given DAV: tagname (TRUE==valid) */int dav_validate_root(const ap_xml_doc *doc, const char *tagname){    return doc->root &&	doc->root->ns == AP_XML_NS_DAV_ID &&	strcmp(doc->root->name, tagname) == 0;}/* find and return the (unique) child with a given DAV: tagname */ap_xml_elem *dav_find_child(const ap_xml_elem *elem, const char *tagname){    ap_xml_elem *child = elem->first_child;    for (; child; child = child->next)	if (child->ns == AP_XML_NS_DAV_ID && !strcmp(child->name, tagname))	    return child;    return NULL;}/* gather up all the CDATA into a single string */const char *dav_xml_get_cdata(const ap_xml_elem *elem, apr_pool_t *pool,                              int strip_white){    apr_size_t len = 0;    ap_text *scan;    const ap_xml_elem *child;    char *cdata;    char *s;    apr_size_t tlen;    for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next)        len += strlen(scan->text);    for (child = elem->first_child; child != NULL; child = child->next) {        for (scan = child->following_cdata.first;             scan != NULL;             scan = scan->next)            len += strlen(scan->text);    }    cdata = s = apr_palloc(pool, len + 1);    for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next) {        tlen = strlen(scan->text);        memcpy(s, scan->text, tlen);        s += tlen;    }    for (child = elem->first_child; child != NULL; child = child->next) {        for (scan = child->following_cdata.first;             scan != NULL;             scan = scan->next) {            tlen = strlen(scan->text);            memcpy(s, scan->text, tlen);            s += tlen;        }    }    *s = '\0';    if (strip_white && len > 0) {        /* trim leading whitespace */        while (apr_isspace(*cdata))     /* assume: return false for '\0' */            ++cdata;        /* trim trailing whitespace */        while (len-- > 0 && apr_isspace(cdata[len]))            continue;        cdata[len + 1] = '\0';    }    return cdata;}/* ---------------------------------------------------------------**** Timeout header processing***//* dav_get_timeout:  If the Timeout: header exists, return a time_t *    when this lock is expected to expire.  Otherwise, return *    a time_t of DAV_TIMEOUT_INFINITE. * *    It's unclear if DAV clients are required to understand *    Seconds-xxx and Infinity time values.  We assume that they do. *    In addition, for now, that's all we understand, too. */time_t dav_get_timeout(request_rec *r){    time_t now, expires = DAV_TIMEOUT_INFINITE;    const char *timeout_const = apr_table_get(r->headers_in, "Timeout");    const char *timeout = apr_pstrdup(r->pool, timeout_const), *val;    if (timeout == NULL)	return DAV_TIMEOUT_INFINITE;    /* Use the first thing we understand, or infinity if     * we don't understand anything.     */    while ((val = ap_getword_white(r->pool, &timeout)) && strlen(val)) {	if (!strncmp(val, "Infinite", 8)) {	    return DAV_TIMEOUT_INFINITE;	}	if (!strncmp(val, "Second-", 7)) {	    val += 7;	    /* ### We need to handle overflow better:	     * ### timeout will be <= 2^32 - 1	     */	    expires = atol(val);	    now     = time(NULL);	    return now + expires;	}    }    return DAV_TIMEOUT_INFINITE;}/* ---------------------------------------------------------------**** If Header processing***//* add_if_resource returns a new if_header, linking it to next_ih. */static dav_if_header *dav_add_if_resource(apr_pool_t *p, dav_if_header *next_ih,					  const char *uri, size_t uri_len){    dav_if_header *ih;    if ((ih = apr_pcalloc(p, sizeof(*ih))) == NULL)	return NULL;    ih->uri = uri;    ih->uri_len = uri_len;    ih->next = next_ih;    return ih;}/* add_if_state adds a condition to an if_header. */static dav_error * dav_add_if_state(apr_pool_t *p, dav_if_header *ih,				    const char *state_token,				    dav_if_state_type t, int condition,				    const dav_hooks_locks *locks_hooks){    dav_if_state_list *new_sl;    new_sl = apr_pcalloc(p, sizeof(*new_sl));    new_sl->condition = condition;

⌨️ 快捷键说明

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