From dc3d3bb5b740dfcaaa6d59ff0802b17e5950c301 Mon Sep 17 00:00:00 2001
From: Andrey Alcheev <buddy@k66.ru>
Date: Sat, 15 Feb 2014 14:43:38 +0600
Subject: [PATCH 1/2] Bring in the support of unix sockets and introduce "port"
 parameter in "postgres_server" directive.

---
 README.md                   |  4 ++--
 src/ngx_postgres_module.c   | 11 ++++++++++-
 src/ngx_postgres_module.h   |  2 ++
 src/ngx_postgres_upstream.c | 20 ++++++++++++++------
 4 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index c7b34eba..63096b87 100644
--- a/README.md
+++ b/README.md
@@ -25,11 +25,11 @@ Configuration directives
 ========================
 postgres_server
 ---------------
-* **syntax**: `postgres_server ip[:port] dbname=dbname user=user password=pass`
+* **syntax**: `postgres_server {ip[:portnum]|unix:/socket/dir} [port=portnum] [dbname=dbname] [user=user] [password=pass]`
 * **default**: `none`
 * **context**: `upstream`
 
-Set details about the database server.
+Set details about the database server. Additional port parameter is offered to connect to unix socket with alternative port numbers.
 
 
 postgres_keepalive
diff --git a/src/ngx_postgres_module.c b/src/ngx_postgres_module.c
index 176d828e..16dda41b 100644
--- a/src/ngx_postgres_module.c
+++ b/src/ngx_postgres_module.c
@@ -442,11 +442,20 @@ ngx_postgres_conf_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     pgs->addrs = u.addrs;
     pgs->naddrs = u.naddrs;
-    pgs->port = u.port;
+    if(u.family != AF_UNIX)
+        pgs->port = u.port;
+    pgs->family = u.family;
 
     /* parse various options */
     for (i = 2; i < cf->args->nelts; i++) {
 
+        if (ngx_strncmp(value[i].data, "port=", sizeof("port=") - 1)
+                == 0)
+        {
+            pgs->port = (in_port_t) ngx_atoi(&value[i].data[sizeof("port=") - 1], value[i].len - (sizeof("port=") - 1));
+            continue;
+        }
+
         if (ngx_strncmp(value[i].data, "dbname=", sizeof("dbname=") - 1)
                 == 0)
         {
diff --git a/src/ngx_postgres_module.h b/src/ngx_postgres_module.h
index 03f49fdb..59a811f2 100644
--- a/src/ngx_postgres_module.h
+++ b/src/ngx_postgres_module.h
@@ -111,6 +111,7 @@ typedef struct {
 #endif
     ngx_uint_t                          naddrs;
     in_port_t                           port;
+    int                                 family;
     ngx_str_t                           dbname;
     ngx_str_t                           user;
     ngx_str_t                           password;
@@ -122,6 +123,7 @@ typedef struct {
     ngx_str_t                           name;
     ngx_str_t                           host;
     in_port_t                           port;
+    int                                 family;
     ngx_str_t                           dbname;
     ngx_str_t                           user;
     ngx_str_t                           password;
diff --git a/src/ngx_postgres_upstream.c b/src/ngx_postgres_upstream.c
index 34583eb9..97cd3221 100644
--- a/src/ngx_postgres_upstream.c
+++ b/src/ngx_postgres_upstream.c
@@ -91,6 +91,7 @@ ngx_postgres_upstream_init(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *uscf)
             peers->peer[n].socklen = server[i].addrs[j].socklen;
             peers->peer[n].name = server[i].addrs[j].name;
             peers->peer[n].port = server[i].port;
+            peers->peer[n].family = server[i].family;
             peers->peer[n].dbname = server[i].dbname;
             peers->peer[n].user = server[i].user;
             peers->peer[n].password = server[i].password;
@@ -329,6 +330,7 @@ ngx_postgres_upstream_get_peer(ngx_peer_connection_t *pc, void *data)
     }
 
     /* sizeof("...") - 1 + 1 (for spaces and '\0' omitted */
+    /* we hope that unix sockets connection string will be always shorter than tcp/ip one (because 'host' is shorter than 'hostaddr') */
     len = sizeof("hostaddr=") + peer->host.len
         + sizeof("port=") + sizeof("65535") - 1
         + sizeof("dbname=") + peer->dbname.len
@@ -346,12 +348,18 @@ ngx_postgres_upstream_get_peer(ngx_peer_connection_t *pc, void *data)
 #endif
     }
 
-    /* TODO add unix sockets */
-    last = ngx_snprintf(connstring, len - 1,
-                        "hostaddr=%V port=%d dbname=%V user=%V password=%V"
-                        " sslmode=disable",
-                        &peer->host, peer->port, &peer->dbname, &peer->user,
-                        &peer->password);
+    if(peer->family != AF_UNIX)
+        last = ngx_snprintf(connstring, len - 1,
+                            "hostaddr=%V port=%d dbname=%V user=%V password=%V"
+                            " sslmode=disable",
+                            &peer->host, peer->port, &peer->dbname, &peer->user,
+                            &peer->password);
+    else
+        last = ngx_snprintf(connstring, len - 1,
+                            "host=%s port=%d dbname=%V user=%V password=%V"
+                            " sslmode=disable",
+                            &peer->host.data[5], peer->port, &peer->dbname, &peer->user,
+                            &peer->password);
     *last = '\0';
 
     dd("PostgreSQL connection string: %s", connstring);

From 026b2c792aba5eb5ec89e668e57ef6563808376b Mon Sep 17 00:00:00 2001
From: Andrey Alcheev <buddy@k66.ru>
Date: Mon, 16 Jun 2014 18:38:56 +0600
Subject: [PATCH 2/2] Port number must be always initialized otherwise it
 becomes zero in case of using unix socket without "port=" parameter

---
 src/ngx_postgres_module.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/ngx_postgres_module.c b/src/ngx_postgres_module.c
index 16dda41b..90818853 100644
--- a/src/ngx_postgres_module.c
+++ b/src/ngx_postgres_module.c
@@ -442,8 +442,7 @@ ngx_postgres_conf_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     pgs->addrs = u.addrs;
     pgs->naddrs = u.naddrs;
-    if(u.family != AF_UNIX)
-        pgs->port = u.port;
+    pgs->port = u.family == AF_UNIX ? u.default_port : u.port;
     pgs->family = u.family;
 
     /* parse various options */