From 0899b51ca952591444b9707047d4fde2eb6efc48 Mon Sep 17 00:00:00 2001 From: Luke Peterson Date: Tue, 18 Oct 2022 21:57:54 +0900 Subject: [PATCH] Implementing mechanism to specify server port in InstalledFlowReturnMethod. Issue #160 --- src/installed.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/installed.rs b/src/installed.rs index 31f97af..bba20b2 100644 --- a/src/installed.rs +++ b/src/installed.rs @@ -75,6 +75,9 @@ pub enum InstalledFlowReturnMethod { /// Involves spinning up a local HTTP server and Google redirecting the browser to /// the server with a URL containing the code (preferred, but not as reliable). HTTPRedirect, + /// Identical to [Self::HTTPRedirect], but allows a port to be specified for the + /// server, instead of choosing a port randomly. + HTTPPortRedirect(u16), } /// InstalledFlowImpl provides tokens for services that follow the "Installed" OAuth flow. (See @@ -119,7 +122,11 @@ impl InstalledFlow { { match self.method { InstalledFlowReturnMethod::HTTPRedirect => { - self.ask_auth_code_via_http(hyper_client, &self.app_secret, scopes) + self.ask_auth_code_via_http(hyper_client, None, &self.app_secret, scopes) + .await + } + InstalledFlowReturnMethod::HTTPPortRedirect(port) => { + self.ask_auth_code_via_http(hyper_client, Some(port), &self.app_secret, scopes) .await } InstalledFlowReturnMethod::Interactive => { @@ -162,6 +169,7 @@ impl InstalledFlow { async fn ask_auth_code_via_http( &self, hyper_client: &hyper::Client, + port: Option, app_secret: &ApplicationSecret, scopes: &[T], ) -> Result @@ -173,7 +181,7 @@ impl InstalledFlow { S::Error: Into>, { use std::borrow::Cow; - let server = InstalledFlowServer::run()?; + let server = InstalledFlowServer::run(port)?; let server_addr = server.local_addr(); // Present url to user. @@ -260,7 +268,7 @@ struct InstalledFlowServer { } impl InstalledFlowServer { - fn run() -> Result { + fn run(port: Option) -> Result { use hyper::service::{make_service_fn, service_fn}; let (auth_code_tx, auth_code_rx) = oneshot::channel::(); let (trigger_shutdown_tx, trigger_shutdown_rx) = oneshot::channel::<()>(); @@ -275,7 +283,10 @@ impl InstalledFlowServer { })) } }); - let addr: std::net::SocketAddr = ([127, 0, 0, 1], 0).into(); + let addr: std::net::SocketAddr = match port { + Some(port) => ([127, 0, 0, 1], port).into(), + None => ([127, 0, 0, 1], 0).into() + }; let server = hyper::server::Server::try_bind(&addr)?; let server = server.http1_only(true).serve(service); let addr = server.local_addr(); @@ -419,8 +430,8 @@ mod tests { #[tokio::test] async fn test_server_random_local_port() { - let addr1 = InstalledFlowServer::run().unwrap().local_addr(); - let addr2 = InstalledFlowServer::run().unwrap().local_addr(); + let addr1 = InstalledFlowServer::run(None).unwrap().local_addr(); + let addr2 = InstalledFlowServer::run(None).unwrap().local_addr(); assert_ne!(addr1.port(), addr2.port()); } @@ -442,7 +453,7 @@ mod tests { async fn test_server() { let client: hyper::Client = hyper::Client::builder().build_http(); - let server = InstalledFlowServer::run().unwrap(); + let server = InstalledFlowServer::run(None).unwrap(); let response = client .get(format!("http://{}/", server.local_addr()).parse().unwrap())