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

Commit

Permalink
Merge pull request #1001 from larkin-nz/master
Browse files Browse the repository at this point in the history
Added URL support for preview command
  • Loading branch information
EverlastingBugstopper authored Apr 10, 2020
2 parents 779092f + 20466eb commit bb8f458
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 52 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ ws = "0.9.0"
[dev-dependencies]
assert_cmd = "0.11.1"
fs_extra = "1.1.0"
predicates = "1.0.2"

[features]
vendored-openssl = ['openssl/vendored']
117 changes: 70 additions & 47 deletions src/commands/preview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ use fiddle_messenger::*;
mod http_method;
pub use http_method::HTTPMethod;

mod request_payload;
pub use request_payload::RequestPayload;

mod upload;
pub use upload::upload;

use crate::commands;

use uuid::Uuid;

use log::info;

use crate::http;
Expand All @@ -24,13 +25,13 @@ use std::sync::mpsc::channel;
use std::thread;
use ws::{Sender, WebSocket};

// Using this instead of just `https://cloudflareworkers.com` returns just the worker response to the CLI
const PREVIEW_ADDRESS: &str = "https://00000000000000000000000000000000.cloudflareworkers.com";
use url::Url;

pub fn preview(
mut target: Target,
user: Option<GlobalUser>,
method: HTTPMethod,
url: Url,
body: Option<String>,
livereload: bool,
verbose: bool,
Expand All @@ -42,10 +43,10 @@ pub fn preview(

let script_id = upload(&mut target, user.as_ref(), sites_preview, verbose)?;

let session = Uuid::new_v4().to_simple();
let preview_host = "example.com";
let https = true;
let https_str = if https { "https://" } else { "http://" };
let request_payload = RequestPayload::create(method, url, body);

let session = &request_payload.session;
let browser_url = &request_payload.browser_url;

if livereload {
// explicitly use 127.0.0.1, since localhost can resolve to 2 addresses
Expand All @@ -57,47 +58,33 @@ pub fn preview(

if !headless {
open_browser(&format!(
"https://cloudflareworkers.com/?wrangler_session_id={0}&wrangler_ws_port={1}&hide_editor#{2}:{3}{4}",
&session.to_string(), ws_port, script_id, https_str, preview_host,
))?;
"https://cloudflareworkers.com/?wrangler_session_id={0}&wrangler_ws_port={1}&hide_editor#{2}:{3}",
session, ws_port, script_id, browser_url
))?;
}

// don't do initial GET + POST with livereload as the expected behavior is unclear.
// Make a the initial request to the URL
client_request(&request_payload, &script_id, &sites_preview);

let broadcaster = server.broadcaster();
thread::spawn(move || server.run());
watch_for_changes(
target,
user.as_ref(),
session.to_string(),
broadcaster,
verbose,
headless,
request_payload,
)?;
} else {
if !headless {
open_browser(&format!(
"https://cloudflareworkers.com/?hide_editor#{0}:{1}{2}",
script_id, https_str, preview_host
"https://cloudflareworkers.com/?hide_editor#{0}:{1}",
script_id, browser_url
))?;
}

let cookie = format!(
"__ew_fiddle_preview={}{}{}{}",
script_id, session, https as u8, preview_host
);

let client = http::client();

let worker_res = match method {
HTTPMethod::Get => get(cookie, &client)?,
HTTPMethod::Post => post(cookie, &client, body)?,
};
let msg = if sites_preview {
"Your Worker is a Workers Site, please preview it in browser window.".to_string()
} else {
format!("Your Worker responded with: {}", worker_res)
};
message::preview(&msg);
client_request(&request_payload, &script_id, &sites_preview);
}

Ok(())
Expand All @@ -119,35 +106,63 @@ fn open_browser(url: &str) -> Result<(), failure::Error> {
Ok(())
}

fn get(cookie: String, client: &reqwest::blocking::Client) -> Result<String, failure::Error> {
let res = client.get(PREVIEW_ADDRESS).header("Cookie", cookie).send();
fn client_request(payload: &RequestPayload, script_id: &String, sites_preview: &bool) {
let client = http::client();

let method = &payload.method;
let url = &payload.service_url;
let body = &payload.body;

let cookie = payload.cookie(script_id);

let worker_res = match method {
HTTPMethod::Get => get(&url, &cookie, &client).unwrap(),
HTTPMethod::Post => post(&url, &cookie, &body, &client).unwrap(),
};

let msg = if *sites_preview {
"Your Worker is a Workers Site, please preview it in browser window.".to_string()
} else {
format!("Your Worker responded with: {}", worker_res)
};
message::preview(&msg);
}

fn get(
url: &String,
cookie: &String,
client: &reqwest::blocking::Client,
) -> Result<String, failure::Error> {
let res = client.get(url).header("Cookie", cookie).send();
Ok(res?.text()?)
}

fn post(
cookie: String,
url: &String,
cookie: &String,
body: &Option<String>,
client: &reqwest::blocking::Client,
body: Option<String>,
) -> Result<String, failure::Error> {
let res = match body {
Some(s) => client
.post(PREVIEW_ADDRESS)
.post(url)
.header("Cookie", cookie)
.body(s)
.body(format!("{}", s))
.send(),
None => client.post(PREVIEW_ADDRESS).header("Cookie", cookie).send(),
None => client.post(url).header("Cookie", cookie).send(),
};
let msg = format!("POST {}", PREVIEW_ADDRESS);
let msg = format!("POST {}", url);
message::preview(&msg);
Ok(res?.text()?)
}

fn watch_for_changes(
mut target: Target,
user: Option<&GlobalUser>,
session_id: String,
broadcaster: Sender,
verbose: bool,
headless: bool,
request_payload: RequestPayload,
) -> Result<(), failure::Error> {
let sites_preview: bool = target.site.is_some();

Expand All @@ -158,17 +173,25 @@ fn watch_for_changes(
commands::build(&target)?;

if let Ok(new_id) = upload(&mut target, user, sites_preview, verbose) {
let script_id = format!("{}", new_id);

let msg = FiddleMessage {
session_id: session_id.clone(),
data: FiddleMessageData::LiveReload { new_id },
session_id: request_payload.session.clone(),
data: FiddleMessageData::LiveReload {
new_id: new_id.clone(),
},
};

match broadcaster.send(serde_json::to_string(&msg)?) {
Ok(_) => {
message::preview("Updated preview with changes");
if !headless {
match broadcaster.send(serde_json::to_string(&msg)?) {
Ok(_) => {
message::preview("Updated preview with changes");
}
Err(_e) => message::user_error("communication with preview failed"),
}
Err(_e) => message::user_error("communication with preview failed"),
}

client_request(&request_payload, &script_id, &sites_preview);
}
}

Expand Down
60 changes: 60 additions & 0 deletions src/commands/preview/request_payload.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use url::Url;
use uuid::Uuid;

use super::http_method::HTTPMethod;

pub struct RequestPayload {
pub method: HTTPMethod,
pub https: u8,
pub session: String,
pub protocol: String,
pub domain: String,
pub path: String,
pub query: String,
pub browser_url: String,
pub service_url: String,
pub body: Option<String>,
}

impl RequestPayload {
pub fn create(method: HTTPMethod, url: Url, body: Option<String>) -> RequestPayload {
let session = Uuid::new_v4().to_simple().to_string();

let https = if url.scheme() == "https" { 1 } else { 0 };
let protocol = format!("{}://", url.scheme());

let domain = url.domain().unwrap().to_string();
let path = url.path().to_string();

let query = match url.query() {
Some(query) => format!("?{}", query),
None => "".to_string(),
};

let browser_url = format!("{}{}{}{}", protocol, domain, path, query);
let service_url = format!(
"{}{}{}",
"https://00000000000000000000000000000000.cloudflareworkers.com", path, query
);

RequestPayload {
method,
https,
session,
protocol,
domain,
path,
query,
browser_url,
service_url,
body,
}
}

pub fn cookie(&self, script_id: &String) -> String {
format!(
"__ew_fiddle_preview={}{}{}{}",
script_id, self.session, self.https, self.domain
)
}
}
29 changes: 25 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use commands::HTTPMethod;
use console::style;
use exitfailure::ExitFailure;

use url::Url;

use wrangler::commands;
use wrangler::commands::kv::key::KVMetaData;
use wrangler::installer;
Expand Down Expand Up @@ -383,24 +385,31 @@ fn run() -> Result<(), failure::Error> {
.help("Body string to post to your preview worker request")
.index(2),
)
.arg(
Arg::with_name("url")
.help("URL to open in the worker preview")
.short("u")
.long("url")
.takes_value(true)
)
.arg(
Arg::with_name("env")
.help("environment to preview")
.help("Environment to preview")
.short("e")
.long("env")
.takes_value(true)
)
.arg(
Arg::with_name("watch")
.help("watch your project for changes and update the preview automagically")
.help("Watch your project for changes and update the preview automagically")
.long("watch")
.takes_value(false),
)
.arg(
Arg::with_name("verbose")
.long("verbose")
.takes_value(false)
.help("toggle verbose output"),
.help("Toggle verbose output"),
),
)
.subcommand(
Expand Down Expand Up @@ -605,6 +614,18 @@ fn run() -> Result<(), failure::Error> {

let method = HTTPMethod::from_str(matches.value_of("method").unwrap_or("get"))?;

let url = Url::parse(matches.value_of("url").unwrap_or("https://example.com"))?;

// Validate the URL scheme
failure::ensure!(
match url.scheme() {
"http" => true,
"https" => true,
_ => false,
},
"Invalid URL scheme (use either \"https\" or \"http\")"
);

let body = match matches.value_of("body") {
Some(s) => Some(s.to_string()),
None => None,
Expand All @@ -614,7 +635,7 @@ fn run() -> Result<(), failure::Error> {
let verbose = matches.is_present("verbose");
let headless = matches.is_present("headless");

commands::preview(target, user, method, body, watch, verbose, headless)?;
commands::preview(target, user, method, url, body, watch, verbose, headless)?;
} else if let Some(matches) = matches.subcommand_matches("dev") {
log::info!("Starting dev server");
let port = matches.value_of("port");
Expand Down
Loading

0 comments on commit bb8f458

Please sign in to comment.