fix http -> https redirect

This commit is contained in:
Aiden McClelland
2023-03-09 10:45:22 -07:00
parent 8a1da87702
commit 27470ef934
2 changed files with 30 additions and 11 deletions

View File

@@ -1,11 +1,12 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::convert::Infallible; use std::convert::Infallible;
use std::net::{IpAddr, SocketAddr}; use std::net::{IpAddr, SocketAddr};
use std::str::FromStr;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use color_eyre::eyre::eyre; use color_eyre::eyre::eyre;
use helpers::NonDetachingJoinHandle; use helpers::NonDetachingJoinHandle;
use http::Response; use http::{Response, Uri};
use hyper::service::{make_service_fn, service_fn}; use hyper::service::{make_service_fn, service_fn};
use hyper::Body; use hyper::Body;
use models::ResultExt; use models::ResultExt;
@@ -110,26 +111,32 @@ impl VHostServer {
.await .await
{ {
Ok(a) => a, Ok(a) => a,
Err(e) => { Err(_) => {
stream.rewind(); stream.rewind();
return hyper::server::Server::builder( return hyper::server::Server::builder(
SingleAccept::new(stream), SingleAccept::new(stream),
) )
.serve(make_service_fn(|_| async { .serve(make_service_fn(|_| async {
Ok::<_, Infallible>(service_fn(|req| async move { 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() Response::builder()
.status( .status(
http::StatusCode::TEMPORARY_REDIRECT, http::StatusCode::TEMPORARY_REDIRECT,
) )
.header( .header(
http::header::LOCATION, http::header::LOCATION,
req.headers() uri.to_string(),
.get(http::header::HOST)
.and_then(|host| host.to_str().ok())
.map(|host| {
format!("https://{host}")
})
.unwrap_or_default(),
) )
.body(Body::default()) .body(Body::default())
})) }))

View File

@@ -304,7 +304,7 @@ pub trait CursorExt {
impl<T: AsRef<[u8]>> CursorExt for Cursor<T> { impl<T: AsRef<[u8]>> CursorExt for Cursor<T> {
fn pure_read(&mut self, buf: &mut ReadBuf<'_>) { fn pure_read(&mut self, buf: &mut ReadBuf<'_>) {
let end = self.position() as usize let end = self.position() as usize
+ std::cmp::max( + std::cmp::min(
buf.remaining(), buf.remaining(),
self.get_ref().as_ref().len() - self.position() as usize, self.get_ref().as_ref().len() - self.position() as usize,
); );
@@ -314,6 +314,7 @@ impl<T: AsRef<[u8]>> CursorExt for Cursor<T> {
} }
#[pin_project::pin_project] #[pin_project::pin_project]
#[derive(Debug)]
pub struct BackTrackingReader<T> { pub struct BackTrackingReader<T> {
#[pin] #[pin]
reader: T, reader: T,
@@ -361,11 +362,22 @@ impl<T: AsyncRead> AsyncRead for BackTrackingReader<T> {
.extend_from_slice(&buf.filled()[filled..]); .extend_from_slice(&buf.filled()[filled..]);
res res
} else { } else {
let mut ready = false;
if (this.buffer.position() as usize) < this.buffer.get_ref().len() { if (this.buffer.position() as usize) < this.buffer.get_ref().len() {
this.buffer.pure_read(buf); this.buffer.pure_read(buf);
ready = true;
} }
if buf.remaining() > 0 { 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 { } else {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }