diff --git a/proxy/src/bin/proxy.rs b/proxy/src/bin/proxy.rs index 6b46eaddfad5..6bccdf6e5a36 100644 --- a/proxy/src/bin/proxy.rs +++ b/proxy/src/bin/proxy.rs @@ -1,5 +1,6 @@ use futures::future::Either; use proxy::auth; +use proxy::config::HttpConfig; use proxy::console; use proxy::http; use proxy::metrics; @@ -79,6 +80,9 @@ struct ProxyCliArgs { /// Allow self-signed certificates for compute nodes (for testing) #[clap(long, default_value_t = false, value_parser = clap::builder::BoolishValueParser::new(), action = clap::ArgAction::Set)] allow_self_signed_compute: bool, + /// timeout for http connections + #[clap(long, default_value = "15s", value_parser = humantime::parse_duration)] + sql_over_http_timeout: tokio::time::Duration, } #[tokio::main] @@ -220,12 +224,15 @@ fn build_config(args: &ProxyCliArgs) -> anyhow::Result<&'static ProxyConfig> { auth::BackendType::Link(Cow::Owned(url)) } }; - + let http_config = HttpConfig { + sql_over_http_timeout: args.sql_over_http_timeout, + }; let config = Box::leak(Box::new(ProxyConfig { tls_config, auth_backend, metric_collection, allow_self_signed_compute: args.allow_self_signed_compute, + http_config, })); Ok(config) diff --git a/proxy/src/config.rs b/proxy/src/config.rs index 989027f03f3f..b37c1736bd2e 100644 --- a/proxy/src/config.rs +++ b/proxy/src/config.rs @@ -13,6 +13,7 @@ pub struct ProxyConfig { pub auth_backend: auth::BackendType<'static, ()>, pub metric_collection: Option, pub allow_self_signed_compute: bool, + pub http_config: HttpConfig, } #[derive(Debug)] @@ -26,6 +27,10 @@ pub struct TlsConfig { pub common_names: Option>, } +pub struct HttpConfig { + pub sql_over_http_timeout: tokio::time::Duration, +} + impl TlsConfig { pub fn to_server_config(&self) -> Arc { self.config.clone() diff --git a/proxy/src/http/sql_over_http.rs b/proxy/src/http/sql_over_http.rs index fbf19bcb50b7..63d7d807e980 100644 --- a/proxy/src/http/sql_over_http.rs +++ b/proxy/src/http/sql_over_http.rs @@ -24,6 +24,7 @@ use url::Url; use utils::http::error::ApiError; use utils::http::json::json_response; +use crate::config::HttpConfig; use crate::proxy::{NUM_CONNECTIONS_ACCEPTED_COUNTER, NUM_CONNECTIONS_CLOSED_COUNTER}; use super::conn_pool::ConnInfo; @@ -49,7 +50,6 @@ enum Payload { const MAX_RESPONSE_SIZE: usize = 10 * 1024 * 1024; // 10 MiB const MAX_REQUEST_SIZE: u64 = 10 * 1024 * 1024; // 10 MiB -const HTTP_CONNECTION_TIMEOUT: tokio::time::Duration = tokio::time::Duration::from_secs(15); static RAW_TEXT_OUTPUT: HeaderName = HeaderName::from_static("neon-raw-text-output"); static ARRAY_MODE: HeaderName = HeaderName::from_static("neon-array-mode"); @@ -191,9 +191,10 @@ pub async fn handle( sni_hostname: Option, conn_pool: Arc, session_id: uuid::Uuid, + config: &'static HttpConfig, ) -> Result, ApiError> { let result = tokio::time::timeout( - HTTP_CONNECTION_TIMEOUT, + config.sql_over_http_timeout, handle_inner(request, sni_hostname, conn_pool, session_id), ) .await; @@ -224,7 +225,7 @@ pub async fn handle( Err(_) => { let message = format!( "HTTP-Connection timed out, execution time exeeded {} seconds", - HTTP_CONNECTION_TIMEOUT.as_secs() + config.sql_over_http_timeout.as_secs() ); error!(message); json_response( diff --git a/proxy/src/http/websocket.rs b/proxy/src/http/websocket.rs index ddebbccabc71..656635b2995a 100644 --- a/proxy/src/http/websocket.rs +++ b/proxy/src/http/websocket.rs @@ -205,7 +205,14 @@ async fn ws_handler( // TODO: that deserves a refactor as now this function also handles http json client besides websockets. // Right now I don't want to blow up sql-over-http patch with file renames and do that as a follow up instead. } else if request.uri().path() == "/sql" && request.method() == Method::POST { - sql_over_http::handle(request, sni_hostname, conn_pool, session_id).await + sql_over_http::handle( + request, + sni_hostname, + conn_pool, + session_id, + &config.http_config, + ) + .await } else if request.uri().path() == "/sql" && request.method() == Method::OPTIONS { Response::builder() .header("Allow", "OPTIONS, POST")