📄 util.c
字号:
*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], "<", 4); j += 3; } else if (s[i] == '>') { memcpy(&x[j], ">", 4); j += 3; } else if (s[i] == '&') { memcpy(&x[j], "&", 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 + -