vapor / postgres-kit

šŸ˜ Non-blocking, event-driven Swift client for PostgreSQL.
MIT License
188 stars 70 forks source link

SQLPostgresConfiguration does not allow the postgresql:// URL scheme #250

Closed vzsg closed 1 year ago

vzsg commented 1 year ago

Describe the bug

When using a connection string managed by a hosted database, the provider might use either postgres:// or postgresql:// as the scheme identifier in the URL. DigitalOcean for example uses the latter with their managed databases.

This is explicitly allowed in other clients like libpq:

The URI scheme designator can be either postgresql:// or postgres://.

However, the SQLPostgresConfiguration struct only accepts the shorter version, causing an URLError to be thrown.

To Reproduce

  1. Clone a template project that has postgres set up.

    git clone git@github.com:vapor/template-fluent-postgres-leaf.git postgres-url-test
    cd postgres-url-test
    xed Package.swift
  2. Change the database configuration in configure.swift to take a postgresql:// URL instead of separate fields.

    // Typically: Environment.get("DATABASE_URL")
    let config = try SQLPostgresConfiguration(url: "postgresql://db:xyz@digitalocean.com:123/db?sslmode=require")
    app.databases.use(.postgres(configuration: config), as: .psql)
  3. Run the project and observe the crash.

    Error Domain=NSURLErrorDomain Code=-1000 "(null)" UserInfo={NSErrorFailingURLStringKey=postgresql://db:xyz@digitalocean.com:123/db?sslmode=require, NSErrorFailingURLKey=postgresql://db:xyz@digitalocean.com:123/db?sslmode=require}

Expected behavior

The URL should be parsed successfully.

Environment

Workaround

Manually replacing postgresql:// in the URL with postgres:// works around the issue ā€“ either by changing the connection string by hand, or replacing the URL scheme in code. The latter approach works best if the service provider rotates the credentials automatically.

.replacingOccurrences(of: "postgresql://", with: "postgres://")