httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject svn commit: r1729897 - in /httpd/httpd/trunk: include/ap_mmn.h include/http_core.h include/httpd.h server/core.c
Date Thu, 11 Feb 2016 21:43:32 GMT
Author: wrowe
Date: Thu Feb 11 21:43:32 2016
New Revision: 1729897

URL: http://svn.apache.org/viewvc?rev=1729897&view=rev
Log:
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.


Modified:
    httpd/httpd/trunk/include/ap_mmn.h
    httpd/httpd/trunk/include/http_core.h
    httpd/httpd/trunk/include/httpd.h
    httpd/httpd/trunk/server/core.c

Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1729897&r1=1729896&r2=1729897&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Thu Feb 11 21:43:32 2016
@@ -500,6 +500,8 @@
  * 20150222.9 (2.5.0-dev)  Add epxr_hander to core_dir_config.
  * 20150222.10 (2.5.0-dev) Add new ap_update_child_status...() methods,
  *                         add protocol to worker_score in scoreboard.h
+ * 20150222.11 (2.5.0-dev) Split useragent_host from the conn_rec into
+ *                         the request_rec, with ap_get_useragent_host()
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
@@ -507,7 +509,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20150222
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 10                 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 11                 /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/trunk/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_core.h?rev=1729897&r1=1729896&r2=1729897&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_core.h (original)
+++ httpd/httpd/trunk/include/http_core.h Thu Feb 11 21:43:32 2016
@@ -159,6 +159,32 @@ AP_DECLARE(int) ap_allow_overrides(reque
 AP_DECLARE(const char *) ap_document_root(request_rec *r);
 
 /**
+ * Lookup the remote user agent's DNS name or IP address
+ * @ingroup get_remote_hostname
+ * @param req The current request
+ * @param type The type of lookup to perform.  One of:
+ * <pre>
+ *     REMOTE_HOST returns the hostname, or NULL if the hostname
+ *                 lookup fails.  It will force a DNS lookup according to the
+ *                 HostnameLookups setting.
+ *     REMOTE_NAME returns the hostname, or the dotted quad if the
+ *                 hostname lookup fails.  It will force a DNS lookup according
+ *                 to the HostnameLookups setting.
+ *     REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
+ *                     never forced.
+ *     REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
+ *                   a double reverse lookup, regardless of the HostnameLookups
+ *                   setting.  The result is the (double reverse checked)
+ *                   hostname, or NULL if any of the lookups fail.
+ * </pre>
+ * @param str_is_ip unless NULL is passed, this will be set to non-zero on
+ *        output when an IP address string is returned
+ * @return The remote hostname (based on the request useragent_ip)
+ */
+AP_DECLARE(const char *) ap_get_useragent_host(request_rec *req, int type,
+                                               int *str_is_ip);
+
+/**
  * Lookup the remote client's DNS name or IP address
  * @ingroup get_remote_host
  * @param conn The current connection
@@ -180,7 +206,7 @@ AP_DECLARE(const char *) ap_document_roo
  * </pre>
  * @param str_is_ip unless NULL is passed, this will be set to non-zero on output when an
IP address
  *        string is returned
- * @return The remote hostname
+ * @return The remote hostname (based on the connection client_ip)
  */
 AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int
*str_is_ip);
 

Modified: httpd/httpd/trunk/include/httpd.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/httpd.h?rev=1729897&r1=1729896&r2=1729897&view=diff
==============================================================================
--- httpd/httpd/trunk/include/httpd.h (original)
+++ httpd/httpd/trunk/include/httpd.h Thu Feb 11 21:43:32 2016
@@ -1056,6 +1056,16 @@ struct request_rec {
     apr_table_t *trailers_in;
     /** MIME trailer environment from the response */
     apr_table_t *trailers_out;
+
+    /** Originator's DNS name, if known.  NULL if DNS hasn't been checked,
+     *  "" if it has and no address was found.  N.B. Only access this though
+     *  ap_get_useragent_host() */
+    char *useragent_host;
+    /** have we done double-reverse DNS? -1 yes/failure, 0 not yet,
+     *  1 yes/success
+     *  TODO: 2 bit signed bitfield when this structure is compacted
+     */
+    int double_reverse;
 };
 
 /**

Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1729897&r1=1729896&r2=1729897&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Thu Feb 11 21:43:32 2016
@@ -887,27 +887,30 @@ char *ap_response_code_string(request_re
 
 
 /* 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->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_h
             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_h
     }
 
     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_h
     }
 }
 
+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
  */
@@ -1015,6 +1094,7 @@ AP_DECLARE(const char *) ap_get_remote_l
  * name" as supplied by a possible Host: header or full URI.
  *
  * The DNS option to UseCanonicalName causes this routine to do a
+ /
  * reverse lookup on the local IP address of the connection and use
  * that for the ServerName. This makes its value more reliable while
  * at the same time allowing Demon's magic virtual hosting to work.
@@ -5359,7 +5439,7 @@ static void core_dump_config(apr_pool_t
     }
 }
 
-static int core_upgrade_handler(request_rec *r)
+static int core_upgrade_request(request_rec *r)
 {
     conn_rec *c = r->connection;
     const char *upgrade;
@@ -5387,8 +5467,15 @@ static int core_upgrade_handler(request_
             if (offers && offers->nelts > 0) {
                 const char *protocol = ap_select_protocol(c, r, NULL, offers);
                 if (protocol && strcmp(protocol, ap_get_protocol(c))) {
+                    apr_status_t rv;
                     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02909)
                                   "Upgrade selects '%s'", protocol);
+                    /* RFC7230 6.7: Stupid constraint, detect request body,
+                     * send 100-continue, read it immediately, and set it aside
+                     * for the filters/handler to process after upgrade
+                     * XXX: TODO
+                     */
+
                     /* Let the client know what we are upgrading to. */
                     apr_table_clear(r->headers_out);
                     apr_table_setn(r->headers_out, "Upgrade", protocol);
@@ -5398,20 +5485,25 @@ static int core_upgrade_handler(request_
                     r->status_line = ap_get_status_line(r->status);
                     ap_send_interim_response(r, 1);
 
-                    ap_switch_protocol(c, r, r->server, protocol);
-
-                    /* make sure httpd closes the connection after this */
-                    c->keepalive = AP_CONN_CLOSE;
-                    return DONE;
+                    rv = ap_switch_protocol(c, r, r->server, protocol);
+                    if (rv == APR_EOF)
+                    {
+                        /* make sure httpd closes the connection after this */
+                        c->keepalive = AP_CONN_CLOSE;
+                        return DONE;
+                    }
                 }
             }
         }
     }
-    else if (!c->keepalives) {
-        /* first request on a master connection, if we have protocols other
-         * than the current one enabled here, announce them to the
-         * client. If the client is already talking a protocol with requests
-         * on slave connections, leave it be. */
+    else {
+        /* first request on a master connection, announce our presence
+         * and presume an h2c client will remember the advertisement.
+         */
+        if (!c->keepalives) {
+        /* No upgrade: requested; if we have protocols other than the current
+         * one enabled here, announce them to the client.
+         */
         const apr_array_header_t *upgrades;
         ap_get_protocol_upgrades(c, r, NULL, 0, &upgrades);
         if (upgrades && upgrades->nelts > 0) {
@@ -5420,16 +5512,7 @@ static int core_upgrade_handler(request_
             apr_table_setn(r->headers_out, "Connection", "Upgrade");
         }
     }
-    
-    return DECLINED;
-}
 
-static int core_upgrade_storage(request_rec *r)
-{
-    if ((r->method_number == M_OPTIONS) && r->uri && (r->uri[0]
== '*') &&
-        (r->uri[1] == '\0')) {
-        return core_upgrade_handler(r);
-    }
     return DECLINED;
 }
 
@@ -5455,12 +5538,11 @@ static void register_hooks(apr_pool_t *p
     ap_hook_check_config(core_check_config,NULL,NULL,APR_HOOK_FIRST);
     ap_hook_test_config(core_dump_config,NULL,NULL,APR_HOOK_FIRST);
     ap_hook_translate_name(ap_core_translate,NULL,NULL,APR_HOOK_REALLY_LAST);
-    ap_hook_map_to_storage(core_upgrade_storage,NULL,NULL,APR_HOOK_REALLY_FIRST);
     ap_hook_map_to_storage(core_map_to_storage,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_open_logs(ap_open_logs,NULL,NULL,APR_HOOK_REALLY_FIRST);
     ap_hook_child_init(core_child_init,NULL,NULL,APR_HOOK_REALLY_FIRST);
     ap_hook_child_init(ap_logs_child_init,NULL,NULL,APR_HOOK_MIDDLE);
-    ap_hook_handler(core_upgrade_handler,NULL,NULL,APR_HOOK_REALLY_FIRST);
+    ap_hook_post_read_request(core_upgrade_request,NULL,NULL,APR_HOOK_LAST);
     ap_hook_handler(default_handler,NULL,NULL,APR_HOOK_REALLY_LAST);
     /* FIXME: I suspect we can eliminate the need for these do_nothings - Ben */
     ap_hook_type_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST);



Mime
View raw message