Skip to content
Closed
9 changes: 2 additions & 7 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 Expand Up @@ -135,7 +130,7 @@ ngx_postgres_keepalive_get_peer_multi(ngx_peer_connection_t *pc,
item = ngx_queue_data(q, ngx_postgres_keepalive_cache_t, queue);
c = item->connection;

if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
if (ngx_memn2cmp((u_char *) item->sockaddr, (u_char *) pc->sockaddr,
item->socklen, pc->socklen) == 0)
{
ngx_queue_remove(q);
Expand Down Expand Up @@ -248,7 +243,7 @@ ngx_postgres_keepalive_free_peer(ngx_peer_connection_t *pc,
c->write->log = ngx_cycle->log;

item->socklen = pc->socklen;
ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen);
ngx_memcpy(item->sockaddr, pc->sockaddr, pc->socklen);

item->pgconn = pgp->pgconn;

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");
return NGX_CONF_ERROR;
}
#endif

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

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 @@ -290,10 +290,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]';
$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;
}
--- 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]



=== 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;
}
--- 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]