diff options
author | William A. Rowe Jr <wrowe@apache.org> | 2016-02-11 22:58:45 +0100 |
---|---|---|
committer | William A. Rowe Jr <wrowe@apache.org> | 2016-02-11 22:58:45 +0100 |
commit | 1dd2be03ad7ec020f249e7b244a29a8b5e5e563a (patch) | |
tree | 206a49357b87948f0e47e91b0f309956d8ccaedd /server/core.c | |
parent | Revert r1729897, 1729898, my copy of core.c was polluted by a different patch (diff) | |
download | apache2-1dd2be03ad7ec020f249e7b244a29a8b5e5e563a.tar.xz apache2-1dd2be03ad7ec020f249e7b244a29a8b5e5e563a.zip |
Introduce an ap_get_useragent_host() accessor to replace the old
ap_get_remote_host() in most applications, but preserve the original
behavior for all ap_get_remote_host() consumers (mostly, because we
don't have the request_rec in the first place, and also to avoid any
unintended consequences).
This accessor continues to store the remote_host of connection based
uesr agents within the conn_rec for optimization. Only where some
other module modifies the useragent_addr will we perform a per-request
query of the remote_host.
(Committed previously, but backed out due to unrelated core.c changes)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1729901 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | server/core.c | 99 |
1 files changed, 89 insertions, 10 deletions
diff --git a/server/core.c b/server/core.c index 6de6474624..6b540296de 100644 --- a/server/core.c +++ b/server/core.c @@ -887,27 +887,30 @@ char *ap_response_code_string(request_rec *r, int error_index) /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */ -static APR_INLINE void do_double_reverse (conn_rec *conn) +static APR_INLINE void do_double_reverse (int *double_reverse, + const char *remote_host, + apr_sockaddr_t *client_addr, + apr_pool_t *pool) { apr_sockaddr_t *sa; apr_status_t rv; - if (conn->double_reverse) { + if (*double_reverse) { /* already done */ return; } - if (conn->remote_host == NULL || conn->remote_host[0] == '\0') { + if (remote_host == NULL || remote_host[0] == '\0') { /* single reverse failed, so don't bother */ - conn->double_reverse = -1; + *double_reverse = -1; return; } - rv = apr_sockaddr_info_get(&sa, conn->remote_host, APR_UNSPEC, 0, 0, conn->pool); + rv = apr_sockaddr_info_get(&sa, remote_host, APR_UNSPEC, 0, 0, pool); if (rv == APR_SUCCESS) { while (sa) { - if (apr_sockaddr_equal(sa, conn->client_addr)) { - conn->double_reverse = 1; + if (apr_sockaddr_equal(sa, client_addr)) { + *double_reverse = 1; return; } @@ -915,7 +918,7 @@ static APR_INLINE void do_double_reverse (conn_rec *conn) } } - conn->double_reverse = -1; + *double_reverse = -1; } AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, @@ -953,7 +956,8 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, ap_str_tolower(conn->remote_host); if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) { - do_double_reverse(conn); + do_double_reverse(&conn->double_reverse, conn->remote_host, + conn->client_addr, conn->pool) if (conn->double_reverse != 1) { conn->remote_host = NULL; } @@ -967,7 +971,8 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, } if (type == REMOTE_DOUBLE_REV) { - do_double_reverse(conn); + do_double_reverse(&conn->double_reverse, conn->remote_host, + conn->client_addr, conn->pool) if (conn->double_reverse == -1) { return NULL; } @@ -992,6 +997,80 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, } } +AP_DECLARE(const char *) ap_get_useragent_host(request_rec *r, + int type, int *str_is_ip) +{ + conn_rec *conn = r->connection; + int hostname_lookups; + int ignored_str_is_ip; + + if (req->useragent_addr == conn->client_addr) { + return ap_get_remote_host(conn, r->per_dir_config, type, str_is_ip); + } + + if (!str_is_ip) { /* caller doesn't want to know */ + str_is_ip = &ignored_str_is_ip; + } + *str_is_ip = 0; + + hostname_lookups = ((core_dir_config *) + ap_get_core_module_config(r->per_dir_config)) + ->hostname_lookups; + if (hostname_lookups == HOSTNAME_LOOKUP_UNSET) { + hostname_lookups = HOSTNAME_LOOKUP_OFF; + } + + if (type != REMOTE_NOLOOKUP + && r->useragent_host == NULL + && (type == REMOTE_DOUBLE_REV + || hostname_lookups != HOSTNAME_LOOKUP_OFF)) { + + if (apr_getnameinfo(&r->useragent_host, r->useragent_addr, 0) + == APR_SUCCESS) { + ap_str_tolower(r->useragent_host); + + if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) { + do_double_reverse(&r->double_reverse, r->useragent_host, + r->useragent_addr, r->pool) + if (r->double_reverse != 1) { + r->useragent_host = NULL; + } + } + } + + /* if failed, set it to the NULL string to indicate error */ + if (r->useragent_host == NULL) { + r->useragent_host = ""; + } + } + + if (type == REMOTE_DOUBLE_REV) { + do_double_reverse(&r->double_reverse, r->useragent_host, + r->useragent_addr, r->pool) + if (r->double_reverse == -1) { + return NULL; + } + } + + /* + * Return the desired information; either the remote DNS name, if found, + * or either NULL (if the hostname was requested) or the IP address + * (if any identifier was requested). + */ + if (r->useragent_host != NULL && r->useragent_host[0] != '\0') { + return r->useragent_host; + } + else { + if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) { + return NULL; + } + else { + *str_is_ip = 1; + return r->useragent_ip; + } + } +} + /* * Optional function coming from mod_ident, used for looking up ident user */ |