Skip to content

Commit

Permalink
feature: added support for IPv6 addresses in the "postgres_server" di…
Browse files Browse the repository at this point in the history
…rective. thanks Ingo Struck for the original patch in #29.
  • Loading branch information
agentzh committed Sep 17, 2014
1 parent f9479fb commit 3efa6b7
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 10 deletions.
5 changes: 0 additions & 5 deletions src/ngx_postgres_keepalive.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,13 @@ ngx_postgres_keepalive_get_peer_single(ngx_peer_connection_t *pc,
pgp->name.data = item->name.data;
pgp->name.len = item->name.len;

pgp->sockaddr = item->sockaddr;

pgp->pgconn = item->pgconn;

pc->connection = c;
pc->cached = 1;

pc->name = &pgp->name;

pc->sockaddr = &pgp->sockaddr;
pc->socklen = item->socklen;

dd("returning NGX_DONE");

return NGX_DONE;
Expand Down
2 changes: 1 addition & 1 deletion src/ngx_postgres_keepalive.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ typedef struct {
ngx_postgres_upstream_srv_conf_t *srv_conf;
ngx_connection_t *connection;
PGconn *pgconn;
struct sockaddr sockaddr;
u_char sockaddr[NGX_SOCKADDRLEN];
socklen_t socklen;
ngx_str_t name;
} ngx_postgres_keepalive_cache_t;
Expand Down
11 changes: 11 additions & 0 deletions src/ngx_postgres_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,17 @@ ngx_postgres_conf_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}

#if defined(nginx_version) && (nginx_version <= 1003000)
if (u.naddrs == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"postgres: IPv6 addresses not supported in "
"this version of nginx");

This comment has been minimized.

Copy link
@PiotrSikora

PiotrSikora Apr 4, 2015

Contributor

Could you change this to:

        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: IPv6 literals require nginx-1.3.1+");

otherwise it's hard for users to figure out which version they need to upgrade to in order to fix the error.

return NGX_CONF_ERROR;
}
#endif

dd("naddrs: %d", (int) u.naddrs);

This comment has been minimized.

Copy link
@PiotrSikora

PiotrSikora Apr 4, 2015

Contributor

I'm not sure whether there is value in keeping this around, but if you want to keep it, then I'd prefer if this was before the check, not after.


pgs->addrs = u.addrs;
pgs->naddrs = u.naddrs;
pgs->port = u.port;
Expand Down
4 changes: 1 addition & 3 deletions src/ngx_postgres_upstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,8 @@ ngx_postgres_upstream_get_peer(ngx_peer_connection_t *pc, void *data)
pgdt->name.len = peer->name.len;
pgdt->name.data = peer->name.data;

pgdt->sockaddr = *peer->sockaddr;

pc->name = &pgdt->name;
pc->sockaddr = &pgdt->sockaddr;
pc->sockaddr = peer->sockaddr;
pc->socklen = peer->socklen;
pc->cached = 0;

Expand Down
1 change: 0 additions & 1 deletion src/ngx_postgres_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ typedef struct {
ngx_postgres_state_t state;
ngx_str_t query;
ngx_str_t name;
struct sockaddr sockaddr;
unsigned failed;
} ngx_postgres_upstream_peer_data_t;

Expand Down
197 changes: 197 additions & 0 deletions t/ipv6.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# vi:filetype=

use lib 'lib';
use Test::Nginx::Socket;

repeat_each(2);

plan tests => repeat_each() * (blocks() * 5);

$ENV{TEST_NGINX_POSTGRESQL_HOST_IPV6} ||= '[::1]';

This comment has been minimized.

Copy link
@PiotrSikora

PiotrSikora Apr 4, 2015

Contributor

I don't think _IPV6 in the name is needed here, it's still a host variable and whether it's IPv6 or not, depends on the value.

$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432;

our $http_config = <<'_EOC_';
upstream database {
postgres_server $TEST_NGINX_POSTGRESQL_HOST_IPV6:$TEST_NGINX_POSTGRESQL_PORT
dbname=ngx_test user=ngx_test password=ngx_test;
}
_EOC_
run_tests();
__DATA__
=== TEST 1: no keep-alive
--- http_config
upstream database {
postgres_server $TEST_NGINX_POSTGRESQL_HOST_IPV6:$TEST_NGINX_POSTGRESQL_PORT
dbname=ngx_test user=ngx_test password=ngx_test;
postgres_keepalive off;
}
--- config
location /postgres {
postgres_pass database;
postgres_query "select * from cats";
}
--- request
GET /postgres
--- error_code: 200
--- response_headers
Content-Type: application/x-resty-dbd-stream
--- response_body eval
"\x{00}". # endian
"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
"\x{00}". # result type
"\x{00}\x{00}". # std errcode
"\x{02}\x{00}". # driver errcode
"\x{00}\x{00}". # driver errstr len
"". # driver errstr data
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
"\x{02}\x{00}". # col count
"\x{09}\x{00}". # std col type (integer/int)
"\x{17}\x{00}". # driver col type
"\x{02}\x{00}". # col name len
"id". # col name data
"\x{06}\x{80}". # std col type (varchar/str)
"\x{19}\x{00}". # driver col type
"\x{04}\x{00}". # col name len
"name". # col name data
"\x{01}". # valid row flag
"\x{01}\x{00}\x{00}\x{00}". # field len
"2". # field data
"\x{ff}\x{ff}\x{ff}\x{ff}". # field len
"". # field data
"\x{01}". # valid row flag
"\x{01}\x{00}\x{00}\x{00}". # field len
"3". # field data
"\x{03}\x{00}\x{00}\x{00}". # field len
"bob". # field data
"\x{00}" # row list terminator
--- timeout: 10
--- no_error_log
[alert]
[error]
=== TEST 2: keep-alive (single)
--- http_config
upstream database {
postgres_server $TEST_NGINX_POSTGRESQL_HOST_IPV6:$TEST_NGINX_POSTGRESQL_PORT
dbname=ngx_test user=ngx_test password=ngx_test;
postgres_keepalive max=10 mode=single;

This comment has been minimized.

Copy link
@PiotrSikora

PiotrSikora Apr 4, 2015

Contributor

Style: two spaces before max=, please.

}
--- config
location /postgres {
postgres_pass database;
postgres_query "select * from cats";
}
location /t {
echo_location /postgres;
echo_location /postgres;
echo_location /postgres;
}
--- request
GET /t
--- error_code: 200
--- response_headers
Content-Type: text/plain
--- response_body eval
my $s="\x{00}". # endian
"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
"\x{00}". # result type
"\x{00}\x{00}". # std errcode
"\x{02}\x{00}". # driver errcode
"\x{00}\x{00}". # driver errstr len
"". # driver errstr data
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
"\x{02}\x{00}". # col count
"\x{09}\x{00}". # std col type (integer/int)
"\x{17}\x{00}". # driver col type
"\x{02}\x{00}". # col name len
"id". # col name data
"\x{06}\x{80}". # std col type (varchar/str)
"\x{19}\x{00}". # driver col type
"\x{04}\x{00}". # col name len
"name". # col name data
"\x{01}". # valid row flag
"\x{01}\x{00}\x{00}\x{00}". # field len
"2". # field data
"\x{ff}\x{ff}\x{ff}\x{ff}". # field len
"". # field data
"\x{01}". # valid row flag
"\x{01}\x{00}\x{00}\x{00}". # field len
"3". # field data
"\x{03}\x{00}\x{00}\x{00}". # field len
"bob". # field data
"\x{00}"; # row list terminator

This comment has been minimized.

Copy link
@PiotrSikora

PiotrSikora Apr 4, 2015

Contributor

Style: extra space, not aligned.

$s x 3;
--- timeout: 10
--- no_error_log
[alert]
[error]
=== TEST 3: keep-alive (multi)
--- http_config
upstream database {
postgres_server $TEST_NGINX_POSTGRESQL_HOST_IPV6:$TEST_NGINX_POSTGRESQL_PORT
dbname=ngx_test user=ngx_test password=ngx_test;
postgres_keepalive max=10 mode=multi;

This comment has been minimized.

Copy link
@PiotrSikora

PiotrSikora Apr 4, 2015

Contributor

Style: two spaces before max=, please.

}
--- config
location /postgres {
postgres_pass database;
postgres_query "select * from cats";
}
location /t {
echo_location /postgres;
echo_location /postgres;
echo_location /postgres;
}
--- request
GET /t
--- error_code: 200
--- response_headers
Content-Type: text/plain
--- response_body eval
my $s="\x{00}". # endian
"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
"\x{00}". # result type
"\x{00}\x{00}". # std errcode
"\x{02}\x{00}". # driver errcode
"\x{00}\x{00}". # driver errstr len
"". # driver errstr data
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
"\x{02}\x{00}". # col count
"\x{09}\x{00}". # std col type (integer/int)
"\x{17}\x{00}". # driver col type
"\x{02}\x{00}". # col name len
"id". # col name data
"\x{06}\x{80}". # std col type (varchar/str)
"\x{19}\x{00}". # driver col type
"\x{04}\x{00}". # col name len
"name". # col name data
"\x{01}". # valid row flag
"\x{01}\x{00}\x{00}\x{00}". # field len
"2". # field data
"\x{ff}\x{ff}\x{ff}\x{ff}". # field len
"". # field data
"\x{01}". # valid row flag
"\x{01}\x{00}\x{00}\x{00}". # field len
"3". # field data
"\x{03}\x{00}\x{00}\x{00}". # field len
"bob". # field data
"\x{00}"; # row list terminator
$s x 3;
--- timeout: 10
--- no_error_log
[alert]
[error]

This comment has been minimized.

Copy link
@PiotrSikora

PiotrSikora Apr 4, 2015

Contributor

Style: extra empty line.

0 comments on commit 3efa6b7

Please sign in to comment.