From 27470ef934065441051030d69bd052a57967b4a5 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Thu, 9 Mar 2023 10:45:22 -0700 Subject: [PATCH] fix http -> https redirect --- backend/src/net/vhost.rs | 25 ++++++++++++++++--------- backend/src/util/io.rs | 16 ++++++++++++++-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/backend/src/net/vhost.rs b/backend/src/net/vhost.rs index 473325909..23f1d84f0 100644 --- a/backend/src/net/vhost.rs +++ b/backend/src/net/vhost.rs @@ -1,11 +1,12 @@ use std::collections::BTreeMap; use std::convert::Infallible; use std::net::{IpAddr, SocketAddr}; +use std::str::FromStr; use std::sync::{Arc, Weak}; use color_eyre::eyre::eyre; use helpers::NonDetachingJoinHandle; -use http::Response; +use http::{Response, Uri}; use hyper::service::{make_service_fn, service_fn}; use hyper::Body; use models::ResultExt; @@ -110,26 +111,32 @@ impl VHostServer { .await { Ok(a) => a, - Err(e) => { + Err(_) => { stream.rewind(); return hyper::server::Server::builder( SingleAccept::new(stream), ) .serve(make_service_fn(|_| async { Ok::<_, Infallible>(service_fn(|req| async move { + let host = req + .headers() + .get(http::header::HOST) + .and_then(|host| host.to_str().ok()); + let uri = Uri::from_parts({ + let mut parts = + req.uri().to_owned().into_parts(); + parts.authority = host + .map(FromStr::from_str) + .transpose()?; + parts + })?; Response::builder() .status( http::StatusCode::TEMPORARY_REDIRECT, ) .header( http::header::LOCATION, - req.headers() - .get(http::header::HOST) - .and_then(|host| host.to_str().ok()) - .map(|host| { - format!("https://{host}") - }) - .unwrap_or_default(), + uri.to_string(), ) .body(Body::default()) })) diff --git a/backend/src/util/io.rs b/backend/src/util/io.rs index 827c6ce7e..de24dc24f 100644 --- a/backend/src/util/io.rs +++ b/backend/src/util/io.rs @@ -304,7 +304,7 @@ pub trait CursorExt { impl> CursorExt for Cursor { fn pure_read(&mut self, buf: &mut ReadBuf<'_>) { let end = self.position() as usize - + std::cmp::max( + + std::cmp::min( buf.remaining(), self.get_ref().as_ref().len() - self.position() as usize, ); @@ -314,6 +314,7 @@ impl> CursorExt for Cursor { } #[pin_project::pin_project] +#[derive(Debug)] pub struct BackTrackingReader { #[pin] reader: T, @@ -361,11 +362,22 @@ impl AsyncRead for BackTrackingReader { .extend_from_slice(&buf.filled()[filled..]); res } else { + let mut ready = false; if (this.buffer.position() as usize) < this.buffer.get_ref().len() { this.buffer.pure_read(buf); + ready = true; } if buf.remaining() > 0 { - this.reader.poll_read(cx, buf) + match this.reader.poll_read(cx, buf) { + Poll::Pending => { + if ready { + Poll::Ready(Ok(())) + } else { + Poll::Pending + } + } + a => a, + } } else { Poll::Ready(Ok(())) }