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::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())
}))

View File

@@ -304,7 +304,7 @@ pub trait CursorExt {
impl<T: AsRef<[u8]>> CursorExt for Cursor<T> {
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<T: AsRef<[u8]>> CursorExt for Cursor<T> {
}
#[pin_project::pin_project]
#[derive(Debug)]
pub struct BackTrackingReader<T> {
#[pin]
reader: T,
@@ -361,11 +362,22 @@ impl<T: AsyncRead> AsyncRead for BackTrackingReader<T> {
.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(()))
}