Skip to content

Commit

Permalink
Add host type configuration to client options
Browse files Browse the repository at this point in the history
  • Loading branch information
Soremwar committed Jan 12, 2022
1 parent 540aaba commit 78f8845
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 6 deletions.
2 changes: 2 additions & 0 deletions connection/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ export class Connection {
connection: Deno.Conn,
options: { hostname: string; caCerts: string[] },
) {
// TODO
// Remove unstable check on 1.17.0
if ("startTls" in Deno) {
// @ts-ignore This API should be available on unstable
this.#conn = await Deno.startTls(connection, options);
Expand Down
40 changes: 38 additions & 2 deletions connection/connection_params.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { parseDsn } from "../utils/utils.ts";
import { ConnectionParamsError } from "../client/error.ts";
import { fromFileUrl } from "../deps.ts";

/**
* The connection string must match the following URI structure
Expand Down Expand Up @@ -74,6 +75,7 @@ export interface ClientOptions {
connection?: Partial<ConnectionOptions>;
database?: string;
hostname?: string;
host_type?: "tcp" | "socket";
password?: string;
port?: string | number;
tls?: Partial<TLSOptions>;
Expand All @@ -85,6 +87,7 @@ export interface ClientConfiguration {
connection: ConnectionOptions;
database: string;
hostname: string;
host_type: "tcp" | "socket";
password?: string;
port: number;
tls: TLSOptions;
Expand Down Expand Up @@ -169,12 +172,15 @@ function parseOptionsFromDsn(connString: string): ClientOptions {
};
}

// TODO
// Maybe default should be looking for unix socket?
const DEFAULT_OPTIONS: Omit<ClientConfiguration, "database" | "user"> = {
applicationName: "deno_postgres",
connection: {
attempts: 1,
},
hostname: "127.0.0.1",
host_type: "tcp",
port: 5432,
tls: {
enabled: true,
Expand All @@ -187,6 +193,8 @@ export function createParams(
params: string | ClientOptions = {},
): ClientConfiguration {
if (typeof params === "string") {
throw new Error("Host type not handled in connection string yet");
// @ts-ignore
params = parseOptionsFromDsn(params);
}

Expand All @@ -202,6 +210,33 @@ export function createParams(
}
}

const host_type = params.host_type ?? DEFAULT_OPTIONS.host_type;
if (!["tcp", "socket"].includes(host_type)) {
throw new ConnectionParamsError(`"${host_type}" is not a valid host type`);
}

const hostname = params.hostname ??
pgEnv.hostname ??
DEFAULT_OPTIONS.hostname;
let host = hostname;
if (host_type === "socket") {
try {
const parsed_host = new URL(
hostname,
Deno.mainModule,
);

// Resolve relative path
if (parsed_host.protocol === "file:") {
host = fromFileUrl(parsed_host);
}
} catch (_e) {
// TODO
// Add error cause
throw new ConnectionParamsError(`Could not parse host "${hostname}"`);
}
}

let port: number;
if (params.port) {
port = Number(params.port);
Expand Down Expand Up @@ -235,7 +270,8 @@ export function createParams(
DEFAULT_OPTIONS.connection.attempts,
},
database: params.database ?? pgEnv.database,
hostname: params.hostname ?? pgEnv.hostname ?? DEFAULT_OPTIONS.hostname,
hostname: host,
host_type,
password: params.password ?? pgEnv.password,
port,
tls: {
Expand All @@ -248,7 +284,7 @@ export function createParams(

assertRequiredOptions(
connection_options,
["applicationName", "database", "hostname", "port", "user"],
["applicationName", "database", "hostname", "host_type", "port", "user"],
has_env_access,
);

Expand Down
1 change: 1 addition & 0 deletions deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export { Md5 } from "https://deno.land/std@0.120.0/hash/md5.ts";
export { deferred, delay } from "https://deno.land/std@0.114.0/async/mod.ts";
export type { Deferred } from "https://deno.land/std@0.114.0/async/mod.ts";
export { bold, yellow } from "https://deno.land/std@0.114.0/fmt/colors.ts";
export { fromFileUrl } from "https://deno.land/std@0.114.0/path/mod.ts";
4 changes: 4 additions & 0 deletions tests/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export const getMainConfiguration = (): Configuration => {
applicationName: config.postgres_md5.applicationName,
database: config.postgres_md5.database,
hostname: config.postgres_md5.hostname,
host_type: "tcp",
password: config.postgres_md5.password,
port: config.postgres_md5.port,
tls: enabled_tls,
Expand All @@ -95,6 +96,7 @@ export const getMd5Configuration = (tls: boolean): Configuration => {
applicationName: config.postgres_md5.applicationName,
database: config.postgres_md5.database,
hostname: config.postgres_md5.hostname,
host_type: "tcp",
password: config.postgres_md5.password,
port: config.postgres_md5.port,
tls: tls ? enabled_tls : disabled_tls,
Expand All @@ -107,6 +109,7 @@ export const getScramConfiguration = (tls: boolean): Configuration => {
applicationName: config.postgres_scram.applicationName,
database: config.postgres_scram.database,
hostname: config.postgres_scram.hostname,
host_type: "tcp",
password: config.postgres_scram.password,
port: config.postgres_scram.port,
tls: tls ? enabled_tls : disabled_tls,
Expand All @@ -119,6 +122,7 @@ export const getTlsOnlyConfiguration = (): Configuration => {
applicationName: config.postgres_md5.applicationName,
database: config.postgres_md5.database,
hostname: config.postgres_md5.hostname,
host_type: "tcp",
password: config.postgres_md5.password,
port: config.postgres_md5.port,
tls: enabled_tls,
Expand Down
46 changes: 43 additions & 3 deletions tests/connection_params_test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertEquals, assertThrows } from "./test_deps.ts";
import { assertEquals, assertThrows, fromFileUrl } from "./test_deps.ts";
import { createParams } from "../connection/connection_params.ts";
import { ConnectionParamsError } from "../client/error.ts";
import { has_env_access } from "./constants.ts";
Expand Down Expand Up @@ -129,7 +129,7 @@ Deno.test("Throws on connection string with invalid port", function () {
createParams(
"postgres://some_user@some_host:abc/deno_postgres",
),
undefined,
TypeError,
"Invalid URL",
);
});
Expand All @@ -140,7 +140,7 @@ Deno.test("Throws on connection string with invalid ssl mode", function () {
createParams(
"postgres://some_user@some_host:10101/deno_postgres?sslmode=verify-full",
),
undefined,
ConnectionParamsError,
"Supplied DSN has invalid sslmode 'verify-full'. Only 'disable', 'require', and 'prefer' are supported",
);
});
Expand Down Expand Up @@ -283,3 +283,43 @@ Deno.test("Throws when required options are not passed", function () {
);
}
});

Deno.test("Determines host type", () => {
{
const p = createParams({
database: "some_db",
hostname: "127.0.0.1",
user: "some_user",
});

assertEquals(p.host_type, "tcp");
}

{
const abs_path = "/some/absolute/path";

const p = createParams({
database: "some_db",
hostname: abs_path,
host_type: "socket",
user: "some_user",
});

assertEquals(p.hostname, abs_path);
assertEquals(p.host_type, "socket");
}

{
const rel_path = "./some_file";

const p = createParams({
database: "some_db",
hostname: rel_path,
host_type: "socket",
user: "some_user",
});

assertEquals(p.hostname, fromFileUrl(new URL(rel_path, import.meta.url)));
assertEquals(p.host_type, "socket");
}
});
15 changes: 15 additions & 0 deletions tests/connection_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ Deno.test("Clear password authentication (tls)", async () => {
}
});

Deno.test("Clear password authentication (socket)", async () => {
const client = new Client({
...getClearConfiguration(true),
hostname: "/var/run/postgres_clear/.s.PGSQL.5432",
tls: undefined,
});
await client.connect();

try {
assertEquals(client.session.tls, true);
} finally {
await client.end();
}
});

Deno.test("MD5 authentication (unencrypted)", async () => {
const client = new Client(getMd5Configuration(false));
await client.connect();
Expand Down
1 change: 0 additions & 1 deletion tests/test_deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ export {
assertThrows,
assertThrowsAsync,
} from "https://deno.land/std@0.114.0/testing/asserts.ts";
export { fromFileUrl } from "https://deno.land/std@0.114.0/path/mod.ts";
export * as streams from "https://deno.land/std@0.114.0/streams/conversion.ts";

0 comments on commit 78f8845

Please sign in to comment.