This repository has been archived by the owner on Aug 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 335
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
231 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use super::preview_request; | ||
use crate::commands::dev::server_config::ServerConfig; | ||
use crate::commands::dev::tls; | ||
use crate::commands::dev::utils::get_path_as_str; | ||
use crate::terminal::{emoji, message}; | ||
|
||
use std::sync::{Arc, Mutex}; | ||
|
||
use chrono::prelude::*; | ||
use futures_util::{ | ||
future::TryFutureExt, | ||
stream::{StreamExt, TryStreamExt}, | ||
}; | ||
use hyper::service::{make_service_fn, service_fn}; | ||
use hyper::{Body, Client as HyperClient, Request, Server}; | ||
use hyper_rustls::HttpsConnector; | ||
use tokio::net::TcpListener; | ||
|
||
pub async fn https( | ||
server_config: ServerConfig, | ||
preview_token: Arc<Mutex<String>>, | ||
host: String, | ||
) -> Result<(), failure::Error> { | ||
tls::generate_cert()?; | ||
|
||
// set up https client to connect to the preview service | ||
let https = HttpsConnector::new(); | ||
let client = HyperClient::builder().build::<_, Body>(https); | ||
|
||
// create a closure that hyper will use later to handle HTTP requests | ||
let service = make_service_fn(move |_| { | ||
let client = client.to_owned(); | ||
let preview_token = preview_token.to_owned(); | ||
let host = host.to_owned(); | ||
|
||
async move { | ||
Ok::<_, failure::Error>(service_fn(move |req| { | ||
let client = client.to_owned(); | ||
let preview_token = preview_token.lock().unwrap().to_owned(); | ||
let host = host.to_owned(); | ||
let version = req.version(); | ||
let (parts, body) = req.into_parts(); | ||
let req_method = parts.method.to_string(); | ||
let now: DateTime<Local> = Local::now(); | ||
let path = get_path_as_str(&parts.uri); | ||
async move { | ||
let resp = preview_request( | ||
Request::from_parts(parts, body), | ||
client, | ||
preview_token.to_owned(), | ||
host.clone(), | ||
false, | ||
) | ||
.await?; | ||
|
||
println!( | ||
"[{}] {} {}{} {:?} {}", | ||
now.format("%Y-%m-%d %H:%M:%S"), | ||
req_method, | ||
host, | ||
path, | ||
version, | ||
resp.status() | ||
); | ||
Ok::<_, failure::Error>(resp) | ||
} | ||
})) | ||
} | ||
}); | ||
|
||
let listening_address = server_config.listening_address; | ||
|
||
let mut tcp = TcpListener::bind(&listening_address).await?; | ||
let tls_acceptor = tls::get_tls_acceptor()?; | ||
let incoming_tls_stream = tcp | ||
.incoming() | ||
.map_err(|e| tls::io_error(format!("Incoming connection failed: {:?}", e))) | ||
.and_then(move |s| { | ||
tls_acceptor | ||
.accept(s) | ||
.map_err(|e| tls::io_error(format!("Incoming connection failed: {:?}", e))) | ||
}) | ||
.boxed(); | ||
|
||
let server = Server::builder(tls::HyperAcceptor { | ||
acceptor: incoming_tls_stream, | ||
}) | ||
.serve(service); | ||
|
||
println!("{} Listening on https://{}", emoji::EAR, listening_address); | ||
message::info("Generated certifiacte is not verified, browsers will give a warning and curl will require `--inscure`"); | ||
|
||
if let Err(e) = server.await { | ||
eprintln!("{}", e); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
mod http; | ||
mod https; | ||
|
||
pub use self::http::http; | ||
pub use self::https::https; | ||
|
||
use crate::commands::dev::utils::get_path_as_str; | ||
|
||
use hyper::client::{HttpConnector, ResponseFuture}; | ||
use hyper::header::{HeaderName, HeaderValue}; | ||
use hyper::{Body, Client as HyperClient, Request}; | ||
use hyper_rustls::HttpsConnector; | ||
|
||
fn preview_request( | ||
req: Request<Body>, | ||
client: HyperClient<HttpsConnector<HttpConnector>>, | ||
preview_token: String, | ||
host: String, | ||
http: bool, | ||
) -> ResponseFuture { | ||
let (mut parts, body) = req.into_parts(); | ||
|
||
let path = get_path_as_str(&parts.uri); | ||
|
||
parts.headers.insert( | ||
HeaderName::from_static("host"), | ||
HeaderValue::from_str(&host).expect("Could not create host header"), | ||
); | ||
|
||
parts.headers.insert( | ||
HeaderName::from_static("cf-workers-preview-token"), | ||
HeaderValue::from_str(&preview_token).expect("Could not create token header"), | ||
); | ||
|
||
parts.uri = if http { | ||
format!("http://{}{}", host, path) | ||
} else { | ||
format!("https://{}{}", host, path) | ||
} | ||
.parse() | ||
.expect("Could not construct preview url"); | ||
|
||
let req = Request::from_parts(parts, body); | ||
|
||
client.request(req) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.