weiznich/diesel_async

Add support for Tls enabled postgresql connections

Closed this issue · 1 comments

Setup

Versions

  • Rust: 1.66.0
  • Diesel: 2.0.2
  • Diesel_async: 0.2.0
  • Database: PostgreSQL
  • Operating System Linux

Feature Flags

  • diesel: postgres, time
  • diesel_async: postgres, bb8

Problem Description

When using Diesel's sync Pg implementation, I can connect via TLS, but when using the bb8 pooled connections via diesel-async I cannot. I tracked this down to diesel-async always passing NoTls when creating a tokio-postgres connection.

What are you trying to accomplish?

I want to connect to a PostgreSQL database using TLS

What is the expected output?

I'd expect this to work

What is the actual output?

I cannot connect

Are you seeing any additional errors?

The error I see is that I have to connect over TLS

Steps to reproduce

Simply try to connect to a pgsql service which requires tls using a bb8 pooled diesel-async connection (frankly a non-pooled connection would exhibit the same issue)

If you don't have such a server, you can get a free account on bit.io

Checklist

  • I have already looked over the issue tracker for similar possible closed issues.
  • This issue can be reproduced on Rust's stable channel. (Your issue will be
    closed if this is not the case)
  • This issue can be reproduced without requiring a third party crate

Notes

I'd hope for a postgres-openssl and postgres-nativetls pair of features for diesel-async which enable the relevant TLS implementation for the connections. In the meantime I just have a hacky pile of code I'm not proud of:

Hacky tls connection
pub type Pool = bb8::Pool<AsyncPgConnection>;

fn establish_connection(url: &str) -> BoxFuture<ConnectionResult<AsyncPgConnection>> {
    (async {
        let builder = SslConnector::builder(SslMethod::tls())
            .map_err(|e| ConnectionError::BadConnection(e.to_string()))?;
        let connector = MakeTlsConnector::new(builder.build());
        let (client, connection) = tokio_postgres::connect(url, connector)
            .await
            .map_err(|e| ConnectionError::BadConnection(e.to_string()))?;
        tokio::spawn(async move {
            if let Err(e) = connection.await {
                eprintln!("connection error: {}", e);
            }
        });
        AsyncPgConnection::try_from(client).await
    })
    .boxed()
}

pub async fn create_pool(db_url: &str) -> Result<Pool, PoolError> {
    let config = AsyncDieselConnectionManager::<AsyncPgConnection>::new_with_setup(
        db_url,
        establish_connection,
    );
    bb8::Pool::builder().build(config).await
}

As already discussed in #36 I'm not willing to add these additional dependencies behind feature flags as this makes it much harder to test the crate correctly. Your "hacky" solution is in fact the correct way to build a connection pool with TLS support.
I'm willing to accept a PR adding these information to the documentation.