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

Added URL support for preview command #1001

Merged
merged 14 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ indicatif = "0.13.0"
[dev-dependencies]
assert_cmd = "0.11.1"
fs_extra = "1.1.0"
predicates = "1.0.2"

[features]
vendored-openssl = ['openssl/vendored']
114 changes: 67 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;
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, &headless);

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(None);

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, &headless);
}

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

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

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 !*headless {
"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::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::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 +170,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, &headless);
}
}

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
)
}
}
Loading