httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r1560081 - in /httpd/httpd/branches/2.4.x: ./ docs/manual/ docs/manual/howto/ docs/manual/mod/ docs/manual/rewrite/ include/ modules/proxy/
Date Tue, 21 Jan 2014 16:44:05 GMT
Author: jim
Date: Tue Jan 21 16:44:04 2014
New Revision: 1560081

URL: http://svn.apache.org/r1560081
Log:
Merge r1451633, r1451905, r1451921, r1452259, r1453981, r1501913, r1513508, r1531340, r1531370,
r1531962, r1533065, r1540052 from trunk:

Add in rough uds support (Bugx 54101) from Blaise Tarr <blaise.tarr@gmail.com>

Make AF_UNIX aware... fix Windows/Netware??

Follow-up to r1451905 to fix NetWare/Windows compilation.


apr trunk-able


message tag for dom sock

Note about new UDS support

UDS subsequent request on a connection fix

Reformat the UDS support inline with a new naming structure.
Use a flag for speed for testing.

syntax sugar... if the worker is associated w/ a UDS,
then make sure the log reporting has a visual clue.

Ensure that userland format of UDS is the same as how it is
configured, no matter how we store and use it internally.

Eclipse code analysis warning

UDS urls need to be desockified when configuring...
Submitted by: jim, fuankg, jim, jim, druggeri, druggeri, jim, jim, jim, jim, jim
Reviewed/backported by: jim

Modified:
    httpd/httpd/branches/2.4.x/   (props changed)
    httpd/httpd/branches/2.4.x/CHANGES
    httpd/httpd/branches/2.4.x/STATUS
    httpd/httpd/branches/2.4.x/docs/manual/   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/howto/   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/mod/   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/mod/mod_macro.xml   (props changed)
    httpd/httpd/branches/2.4.x/docs/manual/mod/mod_proxy.xml
    httpd/httpd/branches/2.4.x/docs/manual/rewrite/   (props changed)
    httpd/httpd/branches/2.4.x/include/ap_mmn.h
    httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.c
    httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h
    httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c
    httpd/httpd/branches/2.4.x/modules/proxy/proxy_util.c

Propchange: httpd/httpd/branches/2.4.x/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk:r1451633,1451905,1451921,1452259,1453981,1501913,1513508,1531340,1531370,1531962,1540052

Modified: httpd/httpd/branches/2.4.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/CHANGES?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.4.x/CHANGES [utf-8] Tue Jan 21 16:44:04 2014
@@ -66,6 +66,10 @@ Changes with Apache 2.4.7
      keys, and unconditionally disable aNULL, eNULL and EXP ciphers
      (not overridable via SSLCipherSuite). [Kaspar Brand]
 
+  *) mod_proxy: Added support for unix domain sockets as the
+     backend server endpoint [Jim Jagielski, Blaise Tarr
+     <blaise tarr gmail com>]
+
   *) Add experimental cmake-based build system for Windows.  [Jeff Trawick,
      Tom Donovan]
 

Modified: httpd/httpd/branches/2.4.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/STATUS?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/STATUS (original)
+++ httpd/httpd/branches/2.4.x/STATUS Tue Jan 21 16:44:04 2014
@@ -98,22 +98,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  * mod_proxy: support Unix domain sockets
-    trunk patch: https://svn.apache.org/viewvc?view=revision&revision=1451633
-                 https://svn.apache.org/viewvc?view=revision&revision=1451905
-                 https://svn.apache.org/viewvc?view=revision&revision=1451921
-                 https://svn.apache.org/viewvc?view=revision&revision=1452259
-                 https://svn.apache.org/viewvc?view=revision&revision=1453981
-                 https://svn.apache.org/viewvc?view=revision&revision=1501913
-                 https://svn.apache.org/viewvc?view=revision&revision=1513508
-                 https://svn.apache.org/viewvc?view=revision&revision=1531340
-                 https://svn.apache.org/viewvc?view=revision&revision=1531370
-                 https://svn.apache.org/viewvc?view=revision&revision=1531962
-                 https://svn.apache.org/viewvc?view=revision&revision=1533065
-                 https://svn.apache.org/viewvc?view=revision&revision=1540052
-    2.4.x patch: http://people.apache.org/~jim/patches/uds-2.4.patch
-    +1: jim, druggeri, humbedooh
-
   * mod_ssl: address the "init functions should return status code rather
     than ssl_die()" todo from 2002 (avoid orphan IPC objects after startup
     or reload failures, see also the "ssl_die() and pool cleanup" thread

Propchange: httpd/httpd/branches/2.4.x/docs/manual/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual:r1451633,1451905,1451921,1452259,1453981,1501913,1513508,1531340,1531370,1531962,1533065,1540052

Propchange: httpd/httpd/branches/2.4.x/docs/manual/howto/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual/howto:r1451633,1451905,1451921,1452259,1453981,1501913,1513508,1531340,1531370,1531962,1533065,1540052

Propchange: httpd/httpd/branches/2.4.x/docs/manual/mod/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual/mod:r1451633,1451905,1451921,1452259,1453981,1501913,1513508,1531340,1531370,1531962,1533065,1540052

Propchange: httpd/httpd/branches/2.4.x/docs/manual/mod/mod_macro.xml
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual/mod/mod_macro.xml:r1451633,1451905,1451921,1452259,1453981,1501913,1513508,1531340,1531370,1531962,1533065,1540052

Modified: httpd/httpd/branches/2.4.x/docs/manual/mod/mod_proxy.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/docs/manual/mod/mod_proxy.xml?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/docs/manual/mod/mod_proxy.xml (original)
+++ httpd/httpd/branches/2.4.x/docs/manual/mod/mod_proxy.xml Tue Jan 21 16:44:04 2014
@@ -837,6 +837,14 @@ expressions</description>
     usually be set <strong>off</strong> when using
     <directive>ProxyPass</directive>.</note>
 
+    <p>Support for using a Unix Domain Socket is available by using a target
+    which prepends <code>unix:/path/lis.sock|</code>. For example, to proxy
+    HTTP and target the UDS at /home/www/socket you would use
+    <code>unix:/home/www.socket|http://localhost/whatever/</code>.</p>
+
+    <note><strong>Note:</strong> The path associated with the <code>unix:</code>
+    URL is <directive>DefaultRuntimeDir</directive> aware.</note>
+
     <p>Suppose the local server has address <code>http://example.com/</code>;
     then</p>
 

Propchange: httpd/httpd/branches/2.4.x/docs/manual/rewrite/
------------------------------------------------------------------------------
  Merged /httpd/httpd/trunk/docs/manual/rewrite:r1451633,1451905,1451921,1452259,1453981,1501913,1513508,1531340,1531370,1531962,1533065,1540052

Modified: httpd/httpd/branches/2.4.x/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/include/ap_mmn.h?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.4.x/include/ap_mmn.h Tue Jan 21 16:44:04 2014
@@ -423,6 +423,7 @@
  * 20120211.26 (2.4.7-dev) Add util_fcgi.h, FastCGI protocol support
  * 20120211.27 (2.4.7-dev) Add ap_podx_restart_t and ap_mpm_podx_*
  * 20120211.28 (2.4.7-dev) Add ap_regname
+ * 20120211.29 (2.4.7-dev) Add uds_path to proxy_conn_rec
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -430,7 +431,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20120211
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 28                   /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 29                   /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.c?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.c (original)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.c Tue Jan 21 16:44:04 2014
@@ -1370,7 +1370,6 @@ static void *merge_proxy_dir_config(apr_
     return new;
 }
 
-
 static const char *
     add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex)
 {
@@ -1445,6 +1444,36 @@ static const char *
     return add_proxy(cmd, dummy, f1, r1, 1);
 }
 
+static char *de_socketfy(apr_pool_t *p, char *url)
+{
+    char *ptr;
+    /*
+     * We could be passed a URL during the config stage that contains
+     * the UDS path... ignore it
+     */
+    if (!strncasecmp(url, "unix:", 5) &&
+        ((ptr = ap_strchr(url, '|')) != NULL)) {
+        /* move past the 'unix:...|' UDS path info */
+        char *ret, *c;
+
+        ret = ptr + 1;
+        /* special case: "unix:....|scheme:" is OK, expand
+         * to "unix:....|scheme://localhost"
+         * */
+        c = ap_strchr(ret, ':');
+        if (c == NULL) {
+            return NULL;
+        }
+        if (c[1] == '\0') {
+            return apr_pstrcat(p, ret, "//localhost", NULL);
+        }
+        else {
+            return ret;
+        }
+    }
+    return url;
+}
+
 static const char *
     add_pass(cmd_parms *cmd, void *dummy, const char *arg, int is_regex)
 {
@@ -1536,7 +1565,7 @@ static const char *
     }
 
     new->fake = apr_pstrdup(cmd->pool, f);
-    new->real = apr_pstrdup(cmd->pool, r);
+    new->real = apr_pstrdup(cmd->pool, de_socketfy(cmd->pool, r));
     new->flags = flags;
     if (use_regex) {
         new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED);
@@ -1572,7 +1601,7 @@ static const char *
         new->balancer = balancer;
     }
     else {
-        proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, r);
+        proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, de_socketfy(cmd->pool,
r));
         int reuse = 0;
         if (!worker) {
             const char *err = ap_proxy_define_worker(cmd->pool, &worker, NULL, conf,
r, 0);
@@ -1584,14 +1613,14 @@ static const char *
             reuse = 1;
             ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01145)
                          "Sharing worker '%s' instead of creating new worker '%s'",
-                         worker->s->name, new->real);
+                         ap_proxy_worker_name(cmd->pool, worker), new->real);
         }
 
         for (i = 0; i < arr->nelts; i++) {
             if (reuse) {
                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01146)
                              "Ignoring parameter '%s=%s' for worker '%s' because of worker
sharing",
-                             elts[i].key, elts[i].val, worker->s->name);
+                             elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool,
worker));
             } else {
                 const char *err = set_worker_param(cmd->pool, worker, elts[i].key,
                                                    elts[i].val);
@@ -2048,7 +2077,7 @@ static const char *add_member(cmd_parms 
     }
 
     /* Try to find existing worker */
-    worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, name);
+    worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, de_socketfy(cmd->temp_pool,
name));
     if (!worker) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147)
                      "Defining worker '%s' for balancer '%s'",
@@ -2057,13 +2086,13 @@ static const char *add_member(cmd_parms 
             return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01148)
                      "Defined worker '%s' for balancer '%s'",
-                     worker->s->name, balancer->s->name);
+                     ap_proxy_worker_name(cmd->pool, worker), balancer->s->name);
         PROXY_COPY_CONF_PARAMS(worker, conf);
     } else {
         reuse = 1;
         ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01149)
                      "Sharing worker '%s' instead of creating new worker '%s'",
-                     worker->s->name, name);
+                     ap_proxy_worker_name(cmd->pool, worker), name);
     }
 
     arr = apr_table_elts(params);
@@ -2072,7 +2101,7 @@ static const char *add_member(cmd_parms 
         if (reuse) {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01150)
                          "Ignoring parameter '%s=%s' for worker '%s' because of worker sharing",
-                         elts[i].key, elts[i].val, worker->s->name);
+                         elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool, worker));
         } else {
             err = set_worker_param(cmd->pool, worker, elts[i].key,
                                                elts[i].val);
@@ -2134,7 +2163,7 @@ static const char *
         }
     }
     else {
-        worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, name);
+        worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, de_socketfy(cmd->temp_pool,
name));
         if (!worker) {
             if (in_proxy_section) {
                 err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
@@ -2274,7 +2303,7 @@ static const char *proxysection(cmd_parm
         }
         else {
             worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
-                                         conf->p);
+                                         de_socketfy(cmd->temp_pool, (char*)conf->p));
             if (!worker) {
                 err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
                                           sconf, conf->p, 0);

Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h Tue Jan 21 16:44:04 2014
@@ -253,6 +253,7 @@ typedef struct {
     unsigned int need_flush:1; /* Flag to decide whether we need to flush the
                                 * filter chain or not */
     unsigned int inreslist:1;  /* connection in apr_reslist? */
+    const char   *uds_path;    /* Unix domain socket path */
 } proxy_conn_rec;
 
 typedef struct {
@@ -345,6 +346,7 @@ typedef struct {
     char      route[PROXY_WORKER_MAX_ROUTE_SIZE];     /* balancing route */
     char      redirect[PROXY_WORKER_MAX_ROUTE_SIZE];  /* temporary balancing redirection
route */
     char      flusher[PROXY_WORKER_MAX_SCHEME_SIZE];  /* flush provider used by mod_proxy_fdpass
*/
+    char      uds_path[PROXY_WORKER_MAX_NAME_SIZE];   /* path to worker's unix domain socket
if applicable */
     int             lbset;      /* load balancer cluster set */
     int             retries;    /* number of retries on this worker */
     int             lbstatus;   /* Current lbstatus */
@@ -590,6 +592,16 @@ typedef __declspec(dllimport) const char
 
 /* Connection pool API */
 /**
+ * Return the user-land, UDS aware worker name
+ * @param p        memory pool used for displaying worker name
+ * @param worker   the worker
+ * @return         name
+ */
+
+PROXY_DECLARE(char *) ap_proxy_worker_name(apr_pool_t *p,
+                                           proxy_worker *worker);
+
+/**
  * Get the worker from proxy configuration
  * @param p        memory pool used for finding worker
  * @param balancer the balancer that the worker belongs to

Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c (original)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c Tue Jan 21 16:44:04 2014
@@ -118,7 +118,8 @@ static void init_balancer_members(apr_po
         int worker_is_initialized;
         proxy_worker *worker = *workers;
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01158)
-                     "Looking at %s -> %s initialized?", balancer->s->name, worker->s->name);
+                     "Looking at %s -> %s initialized?", balancer->s->name,
+                     ap_proxy_worker_name(p, worker));
         worker_is_initialized = PROXY_WORKER_IS_INITIALIZED(worker);
         if (!worker_is_initialized) {
             ap_proxy_initialize_worker(worker, s, p);
@@ -638,10 +639,11 @@ static int proxy_balancer_post_request(p
             int val = ((int *)balancer->errstatuses->elts)[i];
             if (r->status == val) {
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01174)
-                              "%s: Forcing worker (%s) into error state " 
+                              "%s: Forcing worker (%s) into error state "
                               "due to status code %d matching 'failonstatus' "
                               "balancer parameter",
-                              balancer->s->name, worker->s->name, val);
+                              balancer->s->name, ap_proxy_worker_name(r->pool, worker),
+                              val);
                 worker->s->status |= PROXY_WORKER_IN_ERROR;
                 worker->s->error_time = apr_time_now();
                 break;
@@ -654,7 +656,7 @@ static int proxy_balancer_post_request(p
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02460)
                       "%s: Forcing worker (%s) into error state "
                       "due to timeout and 'failonstatus' parameter being set",
-                       balancer->s->name, worker->s->name);
+                       balancer->s->name, ap_proxy_worker_name(r->pool, worker));
         worker->s->status |= PROXY_WORKER_IN_ERROR;
         worker->s->error_time = apr_time_now();
 
@@ -1282,7 +1284,7 @@ static int balancer_handler(request_rec 
                 worker = *workers;
                 /* Start proxy_worker */
                 ap_rputs("        <httpd:worker>\n", r);
-                ap_rvputs(r, "          <httpd:name>", worker->s->name,
+                ap_rvputs(r, "          <httpd:name>", ap_proxy_worker_name(r->pool,
worker),
                           "</httpd:name>\n", NULL);
                 ap_rvputs(r, "          <httpd:scheme>", worker->s->scheme,
                           "</httpd:scheme>\n", NULL);
@@ -1531,7 +1533,8 @@ static int balancer_handler(request_rec 
                           ap_escape_uri(r->pool, worker->s->name),
                           "&nonce=", balancer->s->nonce,
                           "\">", NULL);
-                ap_rvputs(r, worker->s->name, "</a></td>", NULL);
+                ap_rvputs(r, (*worker->s->uds_path ? "<i>" : ""), ap_proxy_worker_name(r->pool,
worker),
+                          (*worker->s->uds_path ? "</i>" : ""), "</a></td>",
NULL);
                 ap_rvputs(r, "<td>", ap_escape_html(r->pool, worker->s->route),
                           NULL);
                 ap_rvputs(r, "</td><td>",
@@ -1556,7 +1559,7 @@ static int balancer_handler(request_rec 
         ap_rputs("<hr />\n", r);
         if (wsel && bsel) {
             ap_rputs("<h3>Edit worker settings for ", r);
-            ap_rvputs(r, wsel->s->name, "</h3>\n", NULL);
+            ap_rvputs(r, (*wsel->s->uds_path?"<i>":""), ap_proxy_worker_name(r->pool,
wsel), (*wsel->s->uds_path?"</i>":""), "</h3>\n", NULL);
             ap_rputs("<form method=\"POST\" enctype=\"application/x-www-form-urlencoded\"
action=\"", r);
             ap_rvputs(r, ap_escape_uri(r->pool, action), "\">\n", NULL);
             ap_rputs("<dl>\n<table><tr><td>Load factor:</td><td><input
name='w_lf' id='w_lf' type=text ", r);

Modified: httpd/httpd/branches/2.4.x/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/proxy/proxy_util.c?rev=1560081&r1=1560080&r2=1560081&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/branches/2.4.x/modules/proxy/proxy_util.c Tue Jan 21 16:44:04 2014
@@ -31,6 +31,13 @@
 #define apr_socket_create apr_socket_create_ex
 #endif
 
+#if APR_HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if (APR_MAJOR_VERSION < 2)
+#include "apr_support.h"        /* for apr_wait_for_io_or_timeout() */
+#endif
+
 APLOG_USE_MODULE(proxy);
 
 /*
@@ -86,14 +93,20 @@ PROXY_DECLARE(apr_status_t) ap_proxy_str
     char *thenil;
     apr_size_t thelen;
 
+    /* special case handling */
+    if (!dlen) {
+        /* XXX: APR_ENOSPACE would be better */
+        return APR_EGENERAL;
+    }
+    if (!src) {
+        *dst = '\0';
+        return APR_SUCCESS;
+    }
     thenil = apr_cpystrn(dst, src, dlen);
     thelen = thenil - dst;
-    /* Assume the typical case is smaller copying into bigger
-       so we have a fast return */
-    if ((thelen < dlen-1) || ((strlen(src)) == thelen)) {
+    if (src[thelen] == '\0') {
         return APR_SUCCESS;
     }
-    /* XXX: APR_ENOSPACE would be better */
     return APR_EGENERAL;
 }
 
@@ -1218,11 +1231,11 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sha
     } else {
         action = "re-using";
     }
+    balancer->s = shm;
+    balancer->s->index = i;
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02337)
                  "%s shm[%d] (0x%pp) for %s", action, i, (void *)shm,
                  balancer->s->name);
-    balancer->s = shm;
-    balancer->s->index = i;
     /* the below should always succeed */
     lbmethod = ap_lookup_provider(PROXY_LBMETHOD, balancer->s->lbpname, "0");
     if (lbmethod) {
@@ -1356,7 +1369,7 @@ static apr_status_t connection_cleanup(v
         ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool, APLOGNO(00923)
                       "Pooled connection 0x%pp for worker %s has been"
                       " already returned to the connection pool.", conn,
-                      worker->s->name);
+                      ap_proxy_worker_name(conn->pool, worker));
         return APR_SUCCESS;
     }
 
@@ -1480,6 +1493,16 @@ static apr_status_t connection_destructo
  * WORKER related...
  */
 
+PROXY_DECLARE(char *) ap_proxy_worker_name(apr_pool_t *p,
+                                           proxy_worker *worker)
+{
+    if (!(*worker->s->uds_path) || !p) {
+        /* just in case */
+        return worker->s->name;
+    }
+    return apr_pstrcat(p, "unix:", worker->s->uds_path, "|", worker->s->name,
NULL);
+}
+
 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
                                                   proxy_balancer *balancer,
                                                   proxy_server_conf *conf,
@@ -1495,6 +1518,10 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_g
     char *url_copy;
     int i;
 
+    if (!url) {
+        return NULL;
+    }
+
     c = ap_strchr_c(url, ':');
     if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') {
         return NULL;
@@ -1573,20 +1600,47 @@ PROXY_DECLARE(char *) ap_proxy_define_wo
                                              int do_malloc)
 {
     int rv;
-    apr_uri_t uri;
+    apr_uri_t uri, urisock;
     proxy_worker_shared *wshared;
-    char *ptr;
+    char *ptr, *sockpath = NULL;
 
+    /*
+     * Look to see if we are using UDS:
+     * require format: unix:/path/foo/bar.sock|http://ignored/path2/
+     * This results in talking http to the socket at /path/foo/bar.sock
+     */
+    ptr = ap_strchr((char *)url, '|');
+    if (ptr) {
+        *ptr = '\0';
+        rv = apr_uri_parse(p, url, &urisock);
+        if (rv == APR_SUCCESS && !strcasecmp(urisock.scheme, "unix")) {
+            sockpath = ap_runtime_dir_relative(p, urisock.path);;
+            url = ptr+1;    /* so we get the scheme for the uds */
+        }
+        else {
+            *ptr = '|';
+        }
+    }
     rv = apr_uri_parse(p, url, &uri);
 
     if (rv != APR_SUCCESS) {
-        return "Unable to parse URL";
+        return apr_pstrcat(p, "Unable to parse URL: ", url, NULL);
     }
-    if (!uri.hostname || !uri.scheme) {
-        return "URL must be absolute!";
+    if (!uri.scheme) {
+        return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
+    }
+    /* allow for unix:/path|http: */
+    if (!uri.hostname) {
+        if (sockpath) {
+            uri.hostname = "localhost";
+        }
+        else {
+            return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
+        }
+    }
+    else {
+        ap_str_tolower(uri.hostname);
     }
-
-    ap_str_tolower(uri.hostname);
     ap_str_tolower(uri.scheme);
     /*
      * Workers can be associated w/ balancers or on their
@@ -1642,6 +1696,15 @@ PROXY_DECLARE(char *) ap_proxy_define_wo
     wshared->hash.def = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_DEFAULT);
     wshared->hash.fnv = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_FNV);
     wshared->was_malloced = (do_malloc != 0);
+    if (sockpath) {
+        if (PROXY_STRNCPY(wshared->uds_path, sockpath) != APR_SUCCESS) {
+            return apr_psprintf(p, "worker uds path (%s) too long", sockpath);
+        }
+
+    }
+    else {
+        *wshared->uds_path = '\0';
+    }
 
     (*worker)->hash = wshared->hash;
     (*worker)->context = NULL;
@@ -1670,12 +1733,18 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sha
     } else {
         action = "re-using";
     }
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02338)
-                 "%s shm[%d] (0x%pp) for worker: %s", action, i, (void *)shm,
-                 worker->s->name);
-
     worker->s = shm;
     worker->s->index = i;
+    {
+        apr_pool_t *pool;
+        apr_pool_create(&pool, ap_server_conf->process->pool);
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02338)
+                     "%s shm[%d] (0x%pp) for worker: %s", action, i, (void *)shm,
+                     ap_proxy_worker_name(pool, worker));
+        if (pool) {
+            apr_pool_destroy(pool);
+        }
+    }
     return APR_SUCCESS;
 }
 
@@ -1687,11 +1756,13 @@ PROXY_DECLARE(apr_status_t) ap_proxy_ini
     if (worker->s->status & PROXY_WORKER_INITIALIZED) {
         /* The worker is already initialized */
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00924)
-                     "worker %s shared already initialized", worker->s->name);
+                     "worker %s shared already initialized",
+                     ap_proxy_worker_name(p, worker));
     }
     else {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00925)
-                     "initializing worker %s shared", worker->s->name);
+                     "initializing worker %s shared",
+                     ap_proxy_worker_name(p, worker));
         /* Set default parameters */
         if (!worker->s->retry_set) {
             worker->s->retry = apr_time_from_sec(PROXY_WORKER_DEFAULT_RETRY);
@@ -1727,11 +1798,13 @@ PROXY_DECLARE(apr_status_t) ap_proxy_ini
     /* What if local is init'ed and shm isn't?? Even possible? */
     if (worker->local_status & PROXY_WORKER_INITIALIZED) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00926)
-                     "worker %s local already initialized", worker->s->name);
+                     "worker %s local already initialized",
+                     ap_proxy_worker_name(p, worker));
     }
     else {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
-                     "initializing worker %s local", worker->s->name);
+                     "initializing worker %s local",
+                     ap_proxy_worker_name(p, worker));
         apr_global_mutex_lock(proxy_mutex);
         /* Now init local worker data */
         if (worker->tmutex == NULL) {
@@ -2023,6 +2096,29 @@ PROXY_DECLARE(int) ap_proxy_acquire_conn
     (*conn)->close  = 0;
     (*conn)->inreslist = 0;
 
+    if (*worker->s->uds_path) {
+        if ((*conn)->uds_path == NULL) {
+            /* use (*conn)->pool instead of worker->cp->pool to match lifetime */
+            (*conn)->uds_path = apr_pstrdup((*conn)->pool, worker->s->uds_path);
+        }
+        if ((*conn)->uds_path) {
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02545)
+                         "%s: has determined UDS as %s",
+                         proxy_function, (*conn)->uds_path);
+        }
+        else {
+            /* should never happen */
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02546)
+                         "%s: cannot determine UDS (%s)",
+                         proxy_function, worker->s->uds_path);
+
+        }
+    }
+    else {
+        (*conn)->uds_path = NULL;
+    }
+
+
     return OK;
 }
 
@@ -2094,7 +2190,7 @@ ap_proxy_determine_connection(apr_pool_t
      *      spilling the cached addr from the worker.
      */
     if (!conn->hostname || !worker->s->is_address_reusable ||
-        worker->s->disablereuse) {
+        worker->s->disablereuse || *worker->s->uds_path) {
         if (proxyname) {
             conn->hostname = apr_pstrdup(conn->pool, proxyname);
             conn->port = proxyport;
@@ -2132,7 +2228,8 @@ ap_proxy_determine_connection(apr_pool_t
             conn->port = uri->port;
         }
         socket_cleanup(conn);
-        if (!worker->s->is_address_reusable || worker->s->disablereuse) {
+        if (!(*worker->s->uds_path) &&
+            (!worker->s->is_address_reusable || worker->s->disablereuse)) {
             /*
              * Only do a lookup if we should not reuse the backend address.
              * Otherwise we will look it up once for the worker.
@@ -2143,7 +2240,7 @@ ap_proxy_determine_connection(apr_pool_t
                                         conn->pool);
         }
     }
-    if (worker->s->is_address_reusable && !worker->s->disablereuse) {
+    if (!(*worker->s->uds_path) && worker->s->is_address_reusable &&
!worker->s->disablereuse) {
         /*
          * Looking up the backend address for the worker only makes sense if
          * we can reuse the address.
@@ -2372,6 +2469,52 @@ static apr_status_t send_http_connect(pr
 }
 
 
+#if APR_HAVE_SYS_UN_H
+/* lifted from mod_proxy_fdpass.c; tweaked addrlen in connect() call */
+static apr_status_t socket_connect_un(apr_socket_t *sock,
+                                      struct sockaddr_un *sa)
+{
+    apr_status_t rv;
+    apr_os_sock_t rawsock;
+    apr_interval_time_t t;
+
+    rv = apr_os_sock_get(&rawsock, sock);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
+
+    rv = apr_socket_timeout_get(sock, &t);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
+
+    do {
+        const socklen_t addrlen = APR_OFFSETOF(struct sockaddr_un, sun_path)
+                                  + strlen(sa->sun_path) + 1;
+        rv = connect(rawsock, (struct sockaddr*)sa, addrlen);
+    } while (rv == -1 && errno == EINTR);
+
+    if ((rv == -1) && (errno == EINPROGRESS || errno == EALREADY)
+        && (t > 0)) {
+#if APR_MAJOR_VERSION < 2
+        rv = apr_wait_for_io_or_timeout(NULL, sock, 0);
+#else
+        rv = apr_socket_wait(sock, APR_WAIT_WRITE);
+#endif
+
+        if (rv != APR_SUCCESS) {
+            return rv;
+        }
+    }
+
+    if (rv == -1 && errno != EISCONN) {
+        return errno;
+    }
+
+    return APR_SUCCESS;
+}
+#endif
+
 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
                                             proxy_conn_rec *conn,
                                             proxy_worker *worker,
@@ -2396,93 +2539,131 @@ PROXY_DECLARE(int) ap_proxy_connect_back
                          proxy_function);
         }
     }
-    while (backend_addr && !connected) {
-        if ((rv = apr_socket_create(&newsock, backend_addr->family,
-                                SOCK_STREAM, APR_PROTO_TCP,
-                                conn->scpool)) != APR_SUCCESS) {
-            loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
-            ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00952)
-                         "%s: error creating fam %d socket for target %s",
-                         proxy_function,
-                         backend_addr->family,
-                         worker->s->hostname);
-            /*
-             * this could be an IPv6 address from the DNS but the
-             * local machine won't give us an IPv6 socket; hopefully the
-             * DNS returned an additional address to try
-             */
-            backend_addr = backend_addr->next;
-            continue;
-        }
-        conn->connection = NULL;
+    while ((backend_addr || conn->uds_path) && !connected) {
+#if APR_HAVE_SYS_UN_H
+        if (conn->uds_path)
+        {
+            struct sockaddr_un sa;
 
-        if (worker->s->recv_buffer_size > 0 &&
-            (rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF,
-                                     worker->s->recv_buffer_size))) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00953)
-                         "apr_socket_opt_set(SO_RCVBUF): Failed to set "
-                         "ProxyReceiveBufferSize, using default");
-        }
+            rv = apr_socket_create(&newsock, AF_UNIX, SOCK_STREAM, 0,
+                                   conn->scpool);
+            if (rv != APR_SUCCESS) {
+                loglevel = APLOG_ERR;
+                ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(02453)
+                             "%s: error creating Unix domain socket for "
+                             "target %s",
+                             proxy_function,
+                             worker->s->hostname);
+                break;
+            }
+            conn->connection = NULL;
 
-        rv = apr_socket_opt_set(newsock, APR_TCP_NODELAY, 1);
-        if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
-             ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00954)
-                          "apr_socket_opt_set(APR_TCP_NODELAY): "
-                          "Failed to set");
-        }
+            sa.sun_family = AF_UNIX;
+            apr_cpystrn(sa.sun_path, conn->uds_path, sizeof(sa.sun_path));
 
-        /* Set a timeout for connecting to the backend on the socket */
-        if (worker->s->conn_timeout_set) {
-            apr_socket_timeout_set(newsock, worker->s->conn_timeout);
-        }
-        else if (worker->s->timeout_set) {
-            apr_socket_timeout_set(newsock, worker->s->timeout);
-        }
-        else if (conf->timeout_set) {
-            apr_socket_timeout_set(newsock, conf->timeout);
-        }
-        else {
-             apr_socket_timeout_set(newsock, s->timeout);
-        }
-        /* Set a keepalive option */
-        if (worker->s->keepalive) {
-            if ((rv = apr_socket_opt_set(newsock,
-                            APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00955)
-                             "apr_socket_opt_set(SO_KEEPALIVE): Failed to set"
-                             " Keepalive");
-            }
-        }
-        ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
-                     "%s: fam %d socket created to connect to %s",
-                     proxy_function, backend_addr->family, worker->s->hostname);
-
-        if (conf->source_address_set) {
-            local_addr = apr_pmemdup(conn->pool, conf->source_address,
-                                     sizeof(apr_sockaddr_t));
-            local_addr->pool = conn->pool;
-            rv = apr_socket_bind(newsock, local_addr);
+            rv = socket_connect_un(newsock, &sa);
             if (rv != APR_SUCCESS) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00956)
-                    "%s: failed to bind socket to local address",
-                    proxy_function);
+                apr_socket_close(newsock);
+                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02454)
+                             "%s: attempt to connect to Unix domain socket "
+                             "%s (%s) failed",
+                             proxy_function,
+                             conn->uds_path,
+                             worker->s->hostname);
+                break;
             }
         }
+        else
+#endif
+        {
+            if ((rv = apr_socket_create(&newsock, backend_addr->family,
+                                        SOCK_STREAM, APR_PROTO_TCP,
+                                        conn->scpool)) != APR_SUCCESS) {
+                loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
+                ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00952)
+                             "%s: error creating fam %d socket for "
+                             "target %s",
+                             proxy_function,
+                             backend_addr->family,
+                             worker->s->hostname);
+                /*
+                 * this could be an IPv6 address from the DNS but the
+                 * local machine won't give us an IPv6 socket; hopefully the
+                 * DNS returned an additional address to try
+                 */
+                backend_addr = backend_addr->next;
+                continue;
+            }
+            conn->connection = NULL;
 
-        /* make the connection out of the socket */
-        rv = apr_socket_connect(newsock, backend_addr);
+            if (worker->s->recv_buffer_size > 0 &&
+                (rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF,
+                                         worker->s->recv_buffer_size))) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00953)
+                             "apr_socket_opt_set(SO_RCVBUF): Failed to set "
+                             "ProxyReceiveBufferSize, using default");
+            }
 
-        /* if an error occurred, loop round and try again */
-        if (rv != APR_SUCCESS) {
-            apr_socket_close(newsock);
-            loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
-            ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00957)
-                         "%s: attempt to connect to %pI (%s) failed",
-                         proxy_function,
-                         backend_addr,
-                         worker->s->hostname);
-            backend_addr = backend_addr->next;
-            continue;
+            rv = apr_socket_opt_set(newsock, APR_TCP_NODELAY, 1);
+            if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00954)
+                             "apr_socket_opt_set(APR_TCP_NODELAY): "
+                             "Failed to set");
+            }
+
+            /* Set a timeout for connecting to the backend on the socket */
+            if (worker->s->conn_timeout_set) {
+                apr_socket_timeout_set(newsock, worker->s->conn_timeout);
+            }
+            else if (worker->s->timeout_set) {
+                apr_socket_timeout_set(newsock, worker->s->timeout);
+            }
+            else if (conf->timeout_set) {
+                apr_socket_timeout_set(newsock, conf->timeout);
+            }
+            else {
+                apr_socket_timeout_set(newsock, s->timeout);
+            }
+            /* Set a keepalive option */
+            if (worker->s->keepalive) {
+                if ((rv = apr_socket_opt_set(newsock,
+                                             APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) {
+                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00955)
+                                 "apr_socket_opt_set(SO_KEEPALIVE): Failed to set"
+                                 " Keepalive");
+                }
+            }
+            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
+                         "%s: fam %d socket created to connect to %s",
+                         proxy_function, backend_addr->family, worker->s->hostname);
+
+            if (conf->source_address_set) {
+                local_addr = apr_pmemdup(conn->pool, conf->source_address,
+                                         sizeof(apr_sockaddr_t));
+                local_addr->pool = conn->pool;
+                rv = apr_socket_bind(newsock, local_addr);
+                if (rv != APR_SUCCESS) {
+                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00956)
+                                 "%s: failed to bind socket to local address",
+                                 proxy_function);
+                }
+            }
+
+            /* make the connection out of the socket */
+            rv = apr_socket_connect(newsock, backend_addr);
+
+            /* if an error occurred, loop round and try again */
+            if (rv != APR_SUCCESS) {
+                apr_socket_close(newsock);
+                loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
+                ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00957)
+                             "%s: attempt to connect to %pI (%s) failed",
+                             proxy_function,
+                             backend_addr,
+                             worker->s->hostname);
+                backend_addr = backend_addr->next;
+                continue;
+            }
         }
 
         /* Set a timeout on the socket */
@@ -2498,7 +2679,7 @@ PROXY_DECLARE(int) ap_proxy_connect_back
 
         conn->sock = newsock;
 
-        if (conn->forward) {
+        if (!conn->uds_path && conn->forward) {
             forward_info *forward = (forward_info *)conn->forward;
             /*
              * For HTTP CONNECT we need to prepend CONNECT request before
@@ -2779,7 +2960,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_syn
                 found = 1;
                 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02402)
                              "re-grabbing shm[%d] (0x%pp) for worker: %s", i, (void *)shm,
-                             worker->s->name);
+                             ap_proxy_worker_name(conf->pool, worker));
                 break;
             }
         }



Mime
View raw message