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

📄 util.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
                *x = '%';            }            else {                char decoded;                decoded = x2c(y + 1);                if (decoded == '\0') {                    badpath = 1;                }                else {                    *x = decoded;                    y += 2;                }            }        }    }    *x = '\0';    if (badesc) {        return HTTP_BAD_REQUEST;    }    else if (badpath) {        return HTTP_NOT_FOUND;    }    else {        return OK;    }}AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname,                                       apr_port_t port, const request_rec *r){    if (ap_is_default_port(port, r)) {        return apr_pstrdup(p, hostname);    }    else {        return apr_psprintf(p, "%s:%u", hostname, port);    }}/* c2x takes an unsigned, and expects the caller has guaranteed that * 0 <= what < 256... which usually means that you have to cast to * unsigned char first, because (unsigned)(char)(x) first goes through * signed extension to an int before the unsigned cast. * * The reason for this assumption is to assist gcc code generation -- * the unsigned char -> unsigned extension is already done earlier in * both uses of this code, so there's no need to waste time doing it * again. */static const char c2x_table[] = "0123456789abcdef";static APR_INLINE unsigned char *c2x(unsigned what, unsigned char *where){#if APR_CHARSET_EBCDIC    what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what);#endif /*APR_CHARSET_EBCDIC*/    *where++ = '%';    *where++ = c2x_table[what >> 4];    *where++ = c2x_table[what & 0xf];    return where;}/* * escape_path_segment() escapes a path segment, as defined in RFC 1808. This * routine is (should be) OS independent. * * os_escape_path() converts an OS path to a URL, in an OS dependent way. In all * cases if a ':' occurs before the first '/' in the URL, the URL should be * prefixed with "./" (or the ':' escaped). In the case of Unix, this means * leaving '/' alone, but otherwise doing what escape_path_segment() does. For * efficiency reasons, we don't use escape_path_segment(), which is provided for * reference. Again, RFC 1808 is where this stuff is defined. * * If partial is set, os_escape_path() assumes that the path will be appended to * something with a '/' in it (and thus does not prefix "./"). */AP_DECLARE(char *) ap_escape_path_segment(apr_pool_t *p, const char *segment){    char *copy = apr_palloc(p, 3 * strlen(segment) + 1);    const unsigned char *s = (const unsigned char *)segment;    unsigned char *d = (unsigned char *)copy;    unsigned c;    while ((c = *s)) {        if (TEST_CHAR(c, T_ESCAPE_PATH_SEGMENT)) {            d = c2x(c, d);        }        else {            *d++ = c;        }        ++s;    }    *d = '\0';    return copy;}AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partial){    char *copy = apr_palloc(p, 3 * strlen(path) + 3);    const unsigned char *s = (const unsigned char *)path;    unsigned char *d = (unsigned char *)copy;    unsigned c;    if (!partial) {        const char *colon = ap_strchr_c(path, ':');        const char *slash = ap_strchr_c(path, '/');        if (colon && (!slash || colon < slash)) {            *d++ = '.';            *d++ = '/';        }    }    while ((c = *s)) {        if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) {            d = c2x(c, d);        }        else {            *d++ = c;        }        ++s;    }    *d = '\0';    return copy;}/* ap_escape_uri is now a macro for os_escape_path */AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s){    int i, j;    char *x;    /* first, count the number of extra characters */    for (i = 0, j = 0; s[i] != '\0'; i++)        if (s[i] == '<' || s[i] == '>')            j += 3;        else if (s[i] == '&')            j += 4;    if (j == 0)        return apr_pstrmemdup(p, s, i);    x = apr_palloc(p, i + j + 1);    for (i = 0, j = 0; s[i] != '\0'; i++, j++)        if (s[i] == '<') {            memcpy(&x[j], "&lt;", 4);            j += 3;        }        else if (s[i] == '>') {            memcpy(&x[j], "&gt;", 4);            j += 3;        }        else if (s[i] == '&') {            memcpy(&x[j], "&amp;", 5);            j += 4;        }        else            x[j] = s[i];    x[j] = '\0';    return x;}AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str){    char *ret;    unsigned char *d;    const unsigned char *s;    if (!str) {        return NULL;    }    ret = apr_palloc(p, 4 * strlen(str) + 1); /* Be safe */    d = (unsigned char *)ret;    s = (const unsigned char *)str;    for (; *s; ++s) {        if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {            *d++ = '\\';            switch(*s) {            case '\b':                *d++ = 'b';                break;            case '\n':                *d++ = 'n';                break;            case '\r':                *d++ = 'r';                break;            case '\t':                *d++ = 't';                break;            case '\v':                *d++ = 'v';                break;            case '\\':            case '"':                *d++ = *s;                break;            default:                c2x(*s, d);                *d = 'x';                d += 3;            }        }        else {            *d++ = *s;        }    }    *d = '\0';    return ret;}AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source,                                               apr_size_t buflen){    unsigned char *d, *ep;    const unsigned char *s;    if (!source || !buflen) { /* be safe */        return 0;    }    d = (unsigned char *)dest;    s = (const unsigned char *)source;    ep = d + buflen - 1;    for (; d < ep && *s; ++s) {        if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {            *d++ = '\\';            if (d >= ep) {                --d;                break;            }            switch(*s) {            case '\b':                *d++ = 'b';                break;            case '\n':                *d++ = 'n';                break;            case '\r':                *d++ = 'r';                break;            case '\t':                *d++ = 't';                break;            case '\v':                *d++ = 'v';                break;            case '\\':                *d++ = *s;                break;            case '"': /* no need for this in error log */                d[-1] = *s;                break;            default:                if (d >= ep - 2) {                    ep = --d; /* break the for loop as well */                    break;                }                c2x(*s, d);                *d = 'x';                d += 3;            }        }        else {            *d++ = *s;        }    }    *d = '\0';    return (d - (unsigned char *)dest);}AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path){    apr_finfo_t finfo;    if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS)        return 0;                /* in error condition, just return no */    return (finfo.filetype == APR_DIR);}AP_DECLARE(int) ap_is_rdirectory(apr_pool_t *p, const char *path){    apr_finfo_t finfo;    if (apr_lstat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS)        return 0;                /* in error condition, just return no */    return (finfo.filetype == APR_DIR);}AP_DECLARE(char *) ap_make_full_path(apr_pool_t *a, const char *src1,                                  const char *src2){    apr_size_t len1, len2;    char *path;    len1 = strlen(src1);    len2 = strlen(src2);     /* allocate +3 for '/' delimiter, trailing NULL and overallocate      * one extra byte to allow the caller to add a trailing '/'      */    path = (char *)apr_palloc(a, len1 + len2 + 3);    if (len1 == 0) {        *path = '/';        memcpy(path + 1, src2, len2 + 1);    }    else {        char *next;        memcpy(path, src1, len1);        next = path + len1;        if (next[-1] != '/') {            *next++ = '/';        }        memcpy(next, src2, len2 + 1);    }    return path;}/* * Check for an absoluteURI syntax (see section 3.2 in RFC2068). */AP_DECLARE(int) ap_is_url(const char *u){    register int x;    for (x = 0; u[x] != ':'; x++) {        if ((!u[x]) ||            ((!apr_isalpha(u[x])) && (!apr_isdigit(u[x])) &&             (u[x] != '+') && (u[x] != '-') && (u[x] != '.'))) {            return 0;        }    }    return (x ? 1 : 0);                /* If the first character is ':', it's broken, too */}AP_DECLARE(int) ap_ind(const char *s, char c){    const char *p = ap_strchr_c(s, c);    if (p == NULL)        return -1;    return p - s;}AP_DECLARE(int) ap_rind(const char *s, char c){    const char *p = ap_strrchr_c(s, c);    if (p == NULL)        return -1;    return p - s;}AP_DECLARE(void) ap_str_tolower(char *str){    while (*str) {        *str = apr_tolower(*str);        ++str;    }}static char *find_fqdn(apr_pool_t *a, struct hostent *p){    int x;    if (!strchr(p->h_name, '.')) {        if (p->h_aliases) {            for (x = 0; p->h_aliases[x]; ++x) {                if (strchr(p->h_aliases[x], '.') &&                    (!strncasecmp(p->h_aliases[x], p->h_name,                                  strlen(p->h_name))))                    return apr_pstrdup(a, p->h_aliases[x]);            }        }        return NULL;    }    return apr_pstrdup(a, (void *) p->h_name);}char *ap_get_local_host(apr_pool_t *a){#ifndef MAXHOSTNAMELEN#define MAXHOSTNAMELEN 256#endif    char str[MAXHOSTNAMELEN + 1];    char *server_hostname = NULL;    struct hostent *p;#ifdef BEOS_R5    if (gethostname(str, sizeof(str) - 1) == 0)#else    if (gethostname(str, sizeof(str) - 1) != 0)#endif    {        ap_log_perror(APLOG_MARK, APLOG_STARTUP | APLOG_WARNING, 0, a,                     "%s: gethostname() failed to determine ServerName",                     ap_server_argv0);    }    else     {        str[sizeof(str) - 1] = '\0';        /* TODO: Screaming for APR-ization */        if ((!(p = gethostbyname(str)))             || (!(server_hostname = find_fqdn(a, p)))) {            /* Recovery - return the default servername by IP: */            if (p && p->h_addr_list[0]) {                apr_snprintf(str, sizeof(str), "%pA", p->h_addr_list[0]);                server_hostname = apr_pstrdup(a, str);                /* We will drop through to report the IP-named server */            }        }        else {            /* Since we found a fdqn, return it with no logged message. */            return server_hostname;        }    }    if (!server_hostname)         server_hostname = apr_pstrdup(a, "127.0.0.1");    ap_log_perror(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, a,                 "%s: Could not determine the server's fully qualified "                 "domain name, using %s for ServerName",                 ap_server_argv0, server_hostname);                 return server_hostname;}/* simple 'pool' alloc()ing glue to apr_base64.c */AP_DECLARE(char *) ap_pbase64decode(apr_pool_t *p, const char *bufcoded){    char *decoded;    int l;    decoded = (char *) apr_palloc(p, 1 + apr_base64_decode_len(bufcoded));    l = apr_base64_decode(decoded, bufcoded);    decoded[l] = '\0'; /* make binary sequence into string */    return decoded;}AP_DECLARE(char *) ap_pbase64encode(apr_pool_t *p, char *string) {     char *encoded;    int l = strlen(string);    encoded = (char *) apr_palloc(p, 1 + apr_base64_encode_len(l));    l = apr_base64_encode(encoded, string, l);    encoded[l] = '\0'; /* make binary sequence into string */    return encoded;}/* we want to downcase the type/subtype for comparison purposes * but nothing else because ;parameter=foo values are case sensitive. * XXX: in truth we want to downcase parameter names... but really, * apache has never handled parameters and such correctly.  You * also need to compress spaces and such to be able to compare * properly. -djg */AP_DECLARE(void) ap_content_type_tolower(char *str){    char *semi;    semi = strchr(str, ';');    if (semi) {        *semi = '\0';    }    while (*str) {        *str = apr_tolower(*str);        ++str;    }    if (semi) {        *semi = ';';    }}/* * Given a string, replace any bare " with \" . */AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring){    int newlen = 0;    const char *inchr = instring;    char *outchr, *outstring;    /*     * Look through the input string, jogging the length of the output     * string up by an extra byte each time we find an unescaped ".     */    while (*inchr != '\0') {        newlen++;        if (*inchr == '"') {            newlen++;        }        /*         * If we find a slosh, and it's not the last byte in the string,         * it's escaping something - advance past both bytes.         */        if ((*inchr == '\\') && (inchr[1] != '\0')) {            inchr++;            newlen++;        }        inchr++;    }    outstring = apr_palloc(p, newlen + 1);    inchr = instring;    outchr = outstring;    /*     * Now copy the input string to the output string, inserting a slosh     * in front of every " that doesn't already have one.     */    while (*inchr != '\0') {        if ((*inchr == '\\') && (inchr[1] != '\0')) {            *outchr++ = *inchr++;            *outchr++ = *inchr++;        }        if (*inchr == '"') {            *outchr++ = '\\';        }        if (*inchr != '\0') {            *outchr++ = *inchr++;        }    }    *outchr = '\0';    return outstring;}

⌨️ 快捷键说明

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