Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e9751cb

Browse files
author
Commitfest Bot
committed
[CF 5387] v7 - Allow PGSERVICEFILE to be specified as part of the connection string
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5387 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CANOn0Exac-L2nzsvukNBszm8kssdy0KT2LWEhzoBjN1qtOMfbQ@mail.gmail.com Author(s): Torsten Foertsch
2 parents e050af2 + d9c01b6 commit e9751cb

File tree

3 files changed

+103
-5
lines changed

3 files changed

+103
-5
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2320,6 +2320,19 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
23202320
</listitem>
23212321
</varlistentry>
23222322

2323+
<varlistentry id="libpq-connect-servicefile" xreflabel="servicefile">
2324+
<term><literal>servicefile</literal></term>
2325+
<listitem>
2326+
<para>
2327+
This option specifies the name of the per-user connection service file
2328+
(see <xref linkend="libpq-pgservice"/>).
2329+
Defaults to <filename>~/.pg_service.conf</filename>, or
2330+
<filename>%APPDATA%\postgresql\.pg_service.conf</filename> on
2331+
Microsoft Windows.
2332+
</para>
2333+
</listitem>
2334+
</varlistentry>
2335+
23232336
<varlistentry id="libpq-connect-target-session-attrs" xreflabel="target_session_attrs">
23242337
<term><literal>target_session_attrs</literal></term>
23252338
<listitem>
@@ -9596,7 +9609,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
95969609
On Microsoft Windows, it is named
95979610
<filename>%APPDATA%\postgresql\.pg_service.conf</filename> (where
95989611
<filename>%APPDATA%</filename> refers to the Application Data subdirectory
9599-
in the user's profile). A different file name can be specified by
9612+
in the user's profile). A different file name can be specified using the
9613+
<literal>servicefile</literal> key word in a libpq connection string or by
96009614
setting the environment variable <envar>PGSERVICEFILE</envar>.
96019615
The system-wide file is named <filename>pg_service.conf</filename>.
96029616
By default it is sought in the <filename>etc</filename> directory

src/interfaces/libpq/fe-connect.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
201201
"Database-Service", "", 20,
202202
offsetof(struct pg_conn, pgservice)},
203203

204+
{"servicefile", "PGSERVICEFILE", NULL, NULL,
205+
"Database-Service-File", "", 64, -1},
206+
204207
{"user", "PGUSER", NULL, NULL,
205208
"Database-User", "", 20,
206209
offsetof(struct pg_conn, pguser)},
@@ -5914,6 +5917,7 @@ static int
59145917
parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
59155918
{
59165919
const char *service = conninfo_getval(options, "service");
5920+
const char *service_fname = conninfo_getval(options, "servicefile");
59175921
char serviceFile[MAXPGPATH];
59185922
char *env;
59195923
bool group_found = false;
@@ -5933,11 +5937,18 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
59335937
return 0;
59345938

59355939
/*
5936-
* Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
5937-
* exists).
5940+
* First, check servicefile option on connection string. Second, check
5941+
* PGSERVICEFILE environment variable. Finally, check ~/.pg_service.conf
5942+
* (if that exists).
59385943
*/
5939-
if ((env = getenv("PGSERVICEFILE")) != NULL)
5944+
if (service_fname != NULL)
5945+
{
5946+
strlcpy(serviceFile, service_fname, sizeof(serviceFile));
5947+
}
5948+
else if ((env = getenv("PGSERVICEFILE")) != NULL)
5949+
{
59405950
strlcpy(serviceFile, env, sizeof(serviceFile));
5951+
}
59415952
else
59425953
{
59435954
char homedir[MAXPGPATH];
@@ -6099,6 +6110,16 @@ parseServiceFile(const char *serviceFile,
60996110
goto exit;
61006111
}
61016112

6113+
if (strcmp(key, "servicefile") == 0)
6114+
{
6115+
libpq_append_error(errorMessage,
6116+
"nested servicefile specifications not supported in service file \"%s\", line %d",
6117+
serviceFile,
6118+
linenr);
6119+
result = 3;
6120+
goto exit;
6121+
}
6122+
61026123
/*
61036124
* Set the parameter --- but don't override any previous
61046125
* explicit setting.

src/interfaces/libpq/t/006_service.pl

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Test::More;
88

99
# This tests scenarios related to the service name and the service file,
10-
# for the connection options and their environment variables.
10+
# for the connection options, servicefile options and their environment variables.
1111

1212
my $node = PostgreSQL::Test::Cluster->new('node');
1313
$node->init;
@@ -146,6 +146,69 @@
146146
unlink($srvfile_default);
147147
}
148148

149+
# Backslashes escaped path string for getting collect result at concatenation
150+
# for Windows environment
151+
my $srvfile_win_cared = $srvfile_valid;
152+
$srvfile_win_cared =~ s/\\/\\\\/g;
153+
154+
# Check that servicefile option works as expected
155+
{
156+
$dummy_node->connect_ok(
157+
q{service=my_srv servicefile='} . $srvfile_win_cared . q{'},
158+
'service=my_srv servicefile=...',
159+
sql => "SELECT 'connect3'",
160+
expected_stdout => qr/connect3/
161+
);
162+
163+
# Encode slashes and backslash
164+
my $encoded_srvfile = $srvfile_valid =~ s{([\\/])}{
165+
$1 eq '/' ? '%2F' : '%5C'
166+
}ger;
167+
168+
# Additionaly encode a colon in servicefile path of Windows
169+
$encoded_srvfile =~ s/:/%3A/g;
170+
171+
$dummy_node->connect_ok(
172+
'postgresql:///?service=my_srv&servicefile=' . $encoded_srvfile,
173+
'postgresql:///?service=my_srv&servicefile=...',
174+
sql => "SELECT 'connect4'",
175+
expected_stdout => qr/connect4/
176+
);
177+
178+
local $ENV{PGSERVICE} = 'my_srv';
179+
$dummy_node->connect_ok(
180+
q{servicefile='} . $srvfile_win_cared . q{'},
181+
'envvar: PGSERVICE=my_srv + servicefile=...',
182+
sql => "SELECT 'connect5'",
183+
expected_stdout => qr/connect5/
184+
);
185+
186+
$dummy_node->connect_ok(
187+
'postgresql://?servicefile=' . $encoded_srvfile,
188+
'envvar: PGSERVICE=my_srv + postgresql://?servicefile=...',
189+
sql => "SELECT 'connect6'",
190+
expected_stdout => qr/connect6/
191+
);
192+
}
193+
194+
# Check that servicefile option takes precedence over PGSERVICEFILE environment variable
195+
{
196+
local $ENV{PGSERVICEFILE} = 'non-existent-file.conf';
197+
198+
$dummy_node->connect_fails(
199+
'service=my_srv',
200+
'service=... fails with wrong PGSERVICEFILE',
201+
expected_stderr => qr/service file "non-existent-file\.conf" not found/
202+
);
203+
204+
$dummy_node->connect_ok(
205+
q{service=my_srv servicefile='} . $srvfile_win_cared . q{'},
206+
'servicefile= takes precedence over PGSERVICEFILE',
207+
sql => "SELECT 'connect7'",
208+
expected_stdout => qr/connect7/
209+
);
210+
}
211+
149212
$node->teardown_node;
150213

151214
done_testing();

0 commit comments

Comments
 (0)