Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Commit

Permalink
Separate dev into edge and gcs modules
Browse files Browse the repository at this point in the history
  • Loading branch information
EverlastingBugstopper committed Feb 18, 2020
1 parent 6fe586c commit 88691bd
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 189 deletions.
16 changes: 16 additions & 0 deletions src/commands/dev/edge/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::commands::dev::ServerConfig;
use crate::settings::global_user::GlobalUser;
use crate::settings::toml::Target;

pub fn dev(
target: Target,
user: GlobalUser,
server_config: ServerConfig,
verbose: bool,
) -> Result<(), failure::Error> {
println!(
"{:?}\n{:?}\n{:?}\n{:?}",
target, user, server_config, verbose
);
Ok(())
}
File renamed without changes.
63 changes: 63 additions & 0 deletions src/commands/dev/gcs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
mod headers;
mod server;
mod setup;
mod watch;

use server::serve;
use setup::{get_preview_id, get_session_id};
use watch::watch_for_changes;

use crate::commands;
use crate::commands::dev::{socket, ServerConfig};
use crate::settings::toml::Target;

use std::sync::{Arc, Mutex};
use std::thread;

use tokio::runtime::Runtime as TokioRuntime;
use url::Url;

pub fn dev(
target: Target,
server_config: ServerConfig,
verbose: bool,
) -> Result<(), failure::Error> {
commands::build(&target)?;
let session_id = get_session_id()?;
let preview_id = get_preview_id(
target.clone(),
None,
&server_config,
&session_id.clone(),
verbose,
)?;
let preview_id = Arc::new(Mutex::new(preview_id));

{
let session_id = session_id.clone();
let preview_id = preview_id.clone();
let server_config = server_config.clone();
thread::spawn(move || {
watch_for_changes(
target,
None,
&server_config,
Arc::clone(&preview_id),
&session_id,
verbose,
)
});
}
let socket_url = format!("wss://rawhttp.cloudflareworkers.com/inspect/{}", session_id);
let socket_url = Url::parse(&socket_url)?;
let devtools_listener = socket::listen(socket_url);
let server = serve(server_config, Arc::clone(&preview_id));

let runners = futures::future::join(devtools_listener, server);
let mut runtime = TokioRuntime::new()?;
runtime.block_on(async {
let (devtools_listener, server) = runners.await;
devtools_listener?;
server
})
}
106 changes: 106 additions & 0 deletions src/commands/dev/gcs/server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use crate::commands::dev::gcs::headers::{destructure_response, structure_request};
use crate::commands::dev::server_config::ServerConfig;
use crate::terminal::emoji;

use std::sync::{Arc, Mutex};

use chrono::prelude::*;
use hyper::client::{HttpConnector, ResponseFuture};
use hyper::header::{HeaderName, HeaderValue};
use hyper::http::uri::InvalidUri;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Client as HyperClient, Request, Response, Server, Uri};
use hyper_tls::HttpsConnector;

const PREVIEW_HOST: &str = "rawhttp.cloudflareworkers.com";

pub(super) async fn serve(
server_config: ServerConfig,
preview_id: Arc<Mutex<String>>,
) -> Result<(), failure::Error> {
// set up https client to connect to the preview service
let https = HttpsConnector::new();
let client = HyperClient::builder().build::<_, Body>(https);

let listening_address = server_config.listening_address.clone();
// create a closure that hyper will use later to handle HTTP requests
let make_service = make_service_fn(move |_| {
let client = client.to_owned();
let preview_id = preview_id.lock().unwrap().to_owned();
let server_config = server_config.to_owned();
async move {
Ok::<_, failure::Error>(service_fn(move |req| {
let client = client.to_owned();
let preview_id = preview_id.to_owned();
let server_config = server_config.to_owned();
async move {
let resp =
preview_request(req, client, preview_id.to_owned(), server_config).await?;
let (mut parts, body) = resp.into_parts();

destructure_response(&mut parts)?;
let resp = Response::from_parts(parts, body);
Ok::<_, failure::Error>(resp)
}
}))
}
});

let server = Server::bind(&listening_address.address).serve(make_service);
println!("{} Listening on http://{}", emoji::EAR, listening_address);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
Ok(())
}

fn get_preview_url(path_string: &str) -> Result<Uri, InvalidUri> {
format!("https://{}{}", PREVIEW_HOST, path_string).parse()
}

fn get_path_as_str(uri: &Uri) -> String {
uri.path_and_query()
.map(|x| x.as_str())
.unwrap_or("")
.to_string()
}

fn preview_request(
req: Request<Body>,
client: HyperClient<HttpsConnector<HttpConnector>>,
preview_id: String,
server_config: ServerConfig,
) -> ResponseFuture {
let (mut parts, body) = req.into_parts();

let path = get_path_as_str(&parts.uri);
let method = parts.method.to_string();
let now: DateTime<Local> = Local::now();
let preview_id = &preview_id;

structure_request(&mut parts);

parts.headers.insert(
HeaderName::from_static("host"),
HeaderValue::from_static(PREVIEW_HOST),
);

parts.headers.insert(
HeaderName::from_static("cf-ew-preview"),
HeaderValue::from_str(preview_id).expect("Could not create header for preview id"),
);

parts.uri = get_preview_url(&path).expect("Could not get preview url");

let req = Request::from_parts(parts, body);

println!(
"[{}] \"{} {}{} {:?}\"",
now.format("%Y-%m-%d %H:%M:%S"),
method,
server_config.host,
path,
req.version()
);
client.request(req)
}
28 changes: 28 additions & 0 deletions src/commands/dev/gcs/setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use uuid::Uuid;

use crate::commands::dev::ServerConfig;
use crate::commands::preview::upload;
use crate::settings::global_user::GlobalUser;
use crate::settings::toml::Target;

pub(super) fn get_preview_id(
mut target: Target,
user: Option<GlobalUser>,
server_config: &ServerConfig,
session_id: &str,
verbose: bool,
) -> Result<String, failure::Error> {
let sites_preview = false;
let script_id = upload(&mut target, user.as_ref(), sites_preview, verbose)?;
Ok(format!(
"{}{}{}{}",
&script_id,
session_id,
server_config.host.is_https() as u8,
server_config.host
))
}

pub(super) fn get_session_id() -> Result<String, failure::Error> {
Ok(Uuid::new_v4().to_simple().to_string())
}
5 changes: 3 additions & 2 deletions src/commands/dev/watch.rs → src/commands/dev/gcs/watch.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::sync::{mpsc, Arc, Mutex};

use crate::commands;
use crate::commands::dev::get_preview_id;
use crate::commands::dev::gcs::setup::get_preview_id;
use crate::commands::dev::server_config::ServerConfig;
use crate::commands::watch_and_build;

use crate::settings::global_user::GlobalUser;
use crate::settings::toml::Target;
Expand All @@ -16,7 +17,7 @@ pub fn watch_for_changes(
verbose: bool,
) -> Result<(), failure::Error> {
let (sender, receiver) = mpsc::channel();
commands::watch_and_build(&target, Some(sender))?;
watch_and_build(&target, Some(sender))?;

while let Ok(_) = receiver.recv() {
let user = user.clone();
Expand Down
Loading

0 comments on commit 88691bd

Please sign in to comment.