From 63bc63d839b5b588c026e16598ace0e8d4ff2a32 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 25 Aug 2023 13:23:22 +0300 Subject: [PATCH 1/2] libsql/core: Add auth token parameter to open_remote() in V2 --- crates/core/src/v2/mod.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/crates/core/src/v2/mod.rs b/crates/core/src/v2/mod.rs index 9b77d0bacc..8605266c35 100644 --- a/crates/core/src/v2/mod.rs +++ b/crates/core/src/v2/mod.rs @@ -21,7 +21,7 @@ enum DbType { Memory, File { path: String }, Sync { db: crate::Database }, - Remote { url: String }, + Remote { url: String, auth_token: String }, } pub struct Database { @@ -43,7 +43,11 @@ impl Database { }) } - pub async fn open_with_sync(db_path: impl Into, url: impl Into, token: impl Into) -> Result { + pub async fn open_with_sync( + db_path: impl Into, + url: impl Into, + token: impl Into, + ) -> Result { let opts = crate::Opts::with_http_sync(url, token); let db = crate::Database::open_with_opts(db_path, opts).await?; Ok(Database { @@ -51,9 +55,12 @@ impl Database { }) } - pub fn open_remote(url: impl Into) -> Result { + pub fn open_remote(url: impl Into, auth_token: impl Into) -> Result { Ok(Database { - db_type: DbType::Remote { url: url.into() }, + db_type: DbType::Remote { + url: url.into(), + auth_token: auth_token.into(), + }, }) } @@ -85,8 +92,8 @@ impl Database { Ok(Connection { conn }) } - DbType::Remote { url } => { - let conn = Arc::new(hrana::Client::new(url, "")); + DbType::Remote { url, auth_token } => { + let conn = Arc::new(hrana::Client::new(url, auth_token)); Ok(Connection { conn }) } From 8a191bde86604bd76d0ec2dbbf045731996dcc4d Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Fri, 25 Aug 2023 11:06:13 -0400 Subject: [PATCH 2/2] libsql/hrana: Add auth and error handling --- crates/core/examples/example_v2.rs | 7 ++++++- crates/core/src/v2/hrana.rs | 12 ++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/crates/core/examples/example_v2.rs b/crates/core/examples/example_v2.rs index f190261075..62aaa1a865 100644 --- a/crates/core/examples/example_v2.rs +++ b/crates/core/examples/example_v2.rs @@ -3,7 +3,12 @@ use libsql::v2::Database; #[tokio::main] async fn main() { let db = if let Ok(url) = std::env::var("LIBSQL_HRANA_URL") { - Database::open_remote(url).unwrap() + let token = std::env::var("TURSO_AUTH_TOKEN").unwrap_or_else(|_| { + println!("TURSO_AUTH_TOKEN not set, using empty token..."); + "".to_string() + }); + + Database::open_remote(url, token).unwrap() } else { Database::open_in_memory().unwrap() }; diff --git a/crates/core/src/v2/hrana.rs b/crates/core/src/v2/hrana.rs index 3f14fb1521..517700365f 100644 --- a/crates/core/src/v2/hrana.rs +++ b/crates/core/src/v2/hrana.rs @@ -1,6 +1,7 @@ mod pipeline; mod proto; +use hyper::header::AUTHORIZATION; use pipeline::{ ClientMsg, Response, ServerMsg, StreamBatchReq, StreamExecuteReq, StreamRequest, StreamResponse, StreamResponseError, StreamResponseOk, @@ -56,15 +57,20 @@ impl InnerClient { Self { inner } } - async fn send(&self, url: String, _auth: String, body: String) -> Result { + async fn send(&self, url: String, auth: String, body: String) -> Result { let req = hyper::Request::post(url) + .header(AUTHORIZATION, auth) .body(hyper::Body::from(body)) .unwrap(); let res = self.inner.request(req).await.map_err(HranaError::from)?; if res.status() != StatusCode::OK { - // TODO(lucio): Error branch! + let body = hyper::body::to_bytes(res.into_body()) + .await + .map_err(HranaError::from)?; + let body = String::from_utf8(body.into()).unwrap(); + return Err(HranaError::Api(body).into()); } let body = hyper::body::to_bytes(res.into_body()) @@ -91,6 +97,8 @@ pub enum HranaError { Json(#[from] serde_json::Error), #[error("http error: `{0}`")] Http(#[from] hyper::Error), + #[error("api error: `{0}`")] + Api(String), } impl Client {