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

📄 util.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//*** 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_new_error_tag(apr_pool_t *p, int status,                                          int error_id, const char *desc,                                          const char *namespace,                                          const char *tagname){    dav_error *err = dav_new_error(p, status, error_id, desc);    err->tagname = tagname;    err->namespace = namespace;    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){    apr_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){    apr_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_DECLARE(dav_lookup_result) dav_lookup_uri(const char *uri,                                              request_rec * r,                                              int must_be_absolute){    dav_lookup_result result = { 0 };    const char *scheme;    apr_port_t port;    apr_uri_t comp;    char *new_file;    const char *domain;    /* first thing to do is parse the URI into various components */    if (apr_uri_parse(r->pool, uri, &comp) != APR_SUCCESS) {        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 && must_be_absolute) {        result.err.status = HTTP_BAD_REQUEST;        result.err.desc = "Destination URI must be an absolute URI.";        return result;    }    /* the URI must not have a query (args) or a fragment */    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;    }    /* If the scheme or port was provided, then make sure that it matches       the scheme/port of this request. If the request must be absolute,       then require the (explicit/implicit) scheme/port be matching.       ### hmm. if a port wasn't provided (does the parse return port==0?),       ### but we're on a non-standard port, then we won't detect that the       ### URI's port implies the wrong one.    */    if (comp.scheme != NULL || comp.port != 0 || must_be_absolute)    {        /* ### not sure this works if the current request came in via https: */        scheme = r->parsed_uri.scheme;        if (scheme == NULL)            scheme = ap_http_scheme(r);        /* insert a port if the URI did not contain one */        if (comp.port == 0)            comp.port = apr_uri_port_of_scheme(comp.scheme);        /* now, verify that the URI uses the same scheme as the current.           request. the port must match our port.        */        port = r->connection->local_addr->port;        if (strcasecmp(comp.scheme, scheme) != 0#ifdef APACHE_PORT_HANDLING_IS_BUSTED            || comp.port != port#endif            ) {            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;        }    }    /* 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 (comp.hostname != NULL        && 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 */#ifdef APACHE_PORT_HANDLING_IS_BUSTED    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;    }#endif    /* 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 = apr_uri_unparse(r->pool, &comp, APR_URI_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) */DAV_DECLARE(int) dav_validate_root(const apr_xml_doc *doc,                                   const char *tagname){    return doc->root &&        doc->root->ns == APR_XML_NS_DAV_ID &&        strcmp(doc->root->name, tagname) == 0;}/* find and return the (unique) child with a given DAV: tagname */DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem,                                           const char *tagname){    apr_xml_elem *child = elem->first_child;    for (; child; child = child->next)        if (child->ns == APR_XML_NS_DAV_ID && !strcmp(child->name, tagname))            return child;    return NULL;}/* gather up all the CDATA into a single string */DAV_DECLARE(const char *) dav_xml_get_cdata(const apr_xml_elem *elem, apr_pool_t *pool,                              int strip_white){    apr_size_t len = 0;    apr_text *scan;    const apr_xml_elem *child;    char *cdata;    char *s;    apr_size_t tlen;    const char *found_text = NULL; /* initialize to avoid gcc warning */    int found_count = 0;    for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next) {        found_text = scan->text;        ++found_count;        len += strlen(found_text);    }    for (child = elem->first_child; child != NULL; child = child->next) {        for (scan = child->following_cdata.first;             scan != NULL;             scan = scan->next) {            found_text = scan->text;            ++found_count;            len += strlen(found_text);        }    }    /* some fast-path cases:     * 1) zero-length cdata     * 2) a single piece of cdata with no whitespace to strip     */    if (len == 0)        return "";    if (found_count == 1) {        if (!strip_white            || (!apr_isspace(*found_text)                && !apr_isspace(found_text[len - 1])))            return found_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) {

⌨️ 快捷键说明

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