From fc9dbdade390e158420af952e3310d3943d65140 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Thu, 20 Feb 2020 15:21:20 -0600 Subject: [PATCH 01/14] wip: route authenticated dev requests to the edge --- src/commands/dev/edge/mod.rs | 29 ++++++-- src/commands/dev/edge/server.rs | 104 ++++++++++++++++++++++++++++- src/commands/dev/edge/setup.rs | 103 +++++++++++++++++++++++++++- src/commands/dev/gcs/server.rs | 9 +-- src/commands/dev/mod.rs | 6 +- src/commands/dev/utils.rs | 8 +++ src/main.rs | 3 +- src/settings/toml/deploy_config.rs | 12 ++-- 8 files changed, 247 insertions(+), 27 deletions(-) create mode 100644 src/commands/dev/utils.rs diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index 3336f3fb4..493d94daa 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -1,16 +1,33 @@ +mod server; +mod setup; + +use server::serve; + +use crate::commands; use crate::commands::dev::ServerConfig; use crate::settings::global_user::GlobalUser; -use crate::settings::toml::Target; +use crate::settings::toml::{DeployConfig, Target}; + +use tokio::runtime::Runtime as TokioRuntime; pub fn dev( target: Target, + deploy_config: DeployConfig, user: GlobalUser, server_config: ServerConfig, verbose: bool, ) -> Result<(), failure::Error> { - println!( - "{:?}\n{:?}\n{:?}\n{:?}", - target, user, server_config, verbose - ); - Ok(()) + commands::build(&target)?; + let preview_token = setup::get_preview_token(&deploy_config, &user)?; + let host = match deploy_config.clone() { + DeployConfig::Zoned(config) => "theharnishes.com", + DeployConfig::Zoneless(config) => "worker.avery.workers.dev", + } + .to_string(); + let mut target = target.clone(); + // TODO: replace asset manifest parameter + let preview_token = setup::upload(&mut target, None, &deploy_config, &user)?; + let server = serve(server_config, preview_token, host); + let mut runtime = TokioRuntime::new()?; + runtime.block_on(server) } diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index 6a227cea0..cdaf2d64a 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -1,3 +1,101 @@ -pub(super) async fn serve() -> Result<(), failure::Error> { - unimplemented!() -} \ No newline at end of file +use crate::commands::dev::server_config::ServerConfig; +use crate::commands::dev::utils::get_path_as_str; +use crate::terminal::emoji; + +use chrono::prelude::*; +use hyper::client::{HttpConnector, ResponseFuture}; +use hyper::header::{HeaderName, HeaderValue}; +use hyper::service::{make_service_fn, service_fn}; +use hyper::{Body, Client as HyperClient, Request, Server, Uri}; +use hyper_tls::HttpsConnector; + +pub(super) async fn serve( + server_config: ServerConfig, + preview_token: String, + host: 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_token = preview_token.to_owned(); + let server_config = server_config.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.to_owned(); + let server_config = server_config.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::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, + ) + .await?; + + println!( + "[{}] {} {}{} {:?} {}", + now.format("%Y-%m-%d %H:%M:%S"), + req_method, + server_config.host, + path, + version, + resp.status() + ); + 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 preview_request( + req: Request, + client: HyperClient>, + preview_token: String, + host: String, +) -> 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 header for preview id"), + ); + + // TODO: figure out how to http _or_ https + let uri: Uri = format!("https://{}{}", host, path) + .parse() + .expect("Could not construct preview url"); + + let req = Request::from_parts(parts, body); + + client.request(req) +} diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 761c7e88b..52eac44fe 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -1,3 +1,102 @@ -pub(super) fn get_preview_id() -> Result { - unimplemented!() +use crate::commands::kv::bucket::AssetManifest; +use crate::commands::publish; +use crate::http; +use crate::settings::global_user::GlobalUser; +use crate::settings::toml::{DeployConfig, Target}; +use crate::upload; + +use serde::{Deserialize, Serialize}; +use serde_json::json; +use url::Url; + +pub(super) fn upload( + target: &mut Target, + asset_manifest: Option, + deploy_config: &DeployConfig, + user: &GlobalUser, +) -> Result { + let client = http::auth_client(None, &user); + + if let Some(site_config) = target.site.clone() { + publish::bind_static_site_contents(user, target, &site_config, true)?; + } + + let session_config = get_session_config(deploy_config); + let address = get_address(deploy_config); + + let script_upload_form = upload::form::build(target, asset_manifest)?; + + let res = client + .post(&address) + .multipart(script_upload_form) + .send()? + .error_for_status()?; + + let text = &res.text()?; + log::info!("Response from edge preview: {:#?}", text); + + // TODO: use cloudflare-rs for this :) + let response: V4ApiResponse = serde_json::from_str(text)?; + + Ok(response.result.token) +} + +pub(super) fn get_preview_token( + deploy_config: &DeployConfig, + user: &GlobalUser, +) -> Result { + let exchange_url = get_exchange_url(deploy_config, user)?; + let client = http::auth_client(None, &user); + let response = client.get(&exchange_url).send()?.error_for_status()?; + let headers = response.headers(); + let token = headers.get("cf-workers-preview-token"); + match token { + Some(token) => Ok(token.to_str()?.to_string()), + None => failure::bail!("Could not get token to initialize preview session"), + } +} + +fn get_session_config(deploy_config: &DeployConfig) -> serde_json::Value { + match deploy_config { + DeployConfig::Zoned(config) => json!({"route": config.routes}), + DeployConfig::Zoneless(_) => json!({"workers_dev": true}), + } +} + +fn get_address(deploy_config: &DeployConfig) -> String { + match deploy_config { + DeployConfig::Zoned(config) => format!( + "https://api.cloudflare.com/client/v4/zones/{}/workers/realish", + config.zone_id + ), + // TODO: zoneless is probably wrong + DeployConfig::Zoneless(config) => format!( + "https://api.cloudflare.com/client/v4/account/{}/workers/realish/subdomain", + config.account_id + ), + } +} + +fn get_exchange_url( + deploy_config: &DeployConfig, + user: &GlobalUser, +) -> Result { + let client = http::auth_client(None, &user); + let address = get_address(deploy_config); + let url = Url::parse(&address)?; + let response = client.get(url).send()?.error_for_status()?; + let text = &response.text()?; + let response: V4ApiResponse = serde_json::from_str(text)?; + Ok(response.result.exchange_url) +} + +#[derive(Debug, Serialize, Deserialize)] +struct Preview { + pub exchange_url: String, + pub token: String, +} + +#[derive(Debug, Serialize, Deserialize)] +struct V4ApiResponse { + pub result: Preview, } diff --git a/src/commands/dev/gcs/server.rs b/src/commands/dev/gcs/server.rs index 7da4b2388..4df9886f9 100644 --- a/src/commands/dev/gcs/server.rs +++ b/src/commands/dev/gcs/server.rs @@ -1,5 +1,6 @@ use crate::commands::dev::gcs::headers::{destructure_response, structure_request}; use crate::commands::dev::server_config::ServerConfig; +use crate::commands::dev::utils::get_path_as_str; use crate::terminal::emoji; use std::sync::{Arc, Mutex}; @@ -23,6 +24,7 @@ pub(super) async fn serve( 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(); @@ -77,13 +79,6 @@ fn get_preview_url(path_string: &str) -> Result { 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, client: HyperClient>, diff --git a/src/commands/dev/mod.rs b/src/commands/dev/mod.rs index f9aaaef3f..2d69acdfb 100644 --- a/src/commands/dev/mod.rs +++ b/src/commands/dev/mod.rs @@ -2,15 +2,17 @@ mod edge; mod gcs; mod server_config; mod socket; +mod utils; use server_config::ServerConfig; use crate::settings::global_user::GlobalUser; -use crate::settings::toml::Target; +use crate::settings::toml::{DeployConfig, Target}; use crate::terminal::message_box; pub fn dev( target: Target, + deploy_config: DeployConfig, user: Option, host: Option<&str>, port: Option<&str>, @@ -20,7 +22,7 @@ pub fn dev( message_box::dev_alpha_warning(); let server_config = ServerConfig::new(host, ip, port)?; match user { - Some(user) => edge::dev(target, user, server_config, verbose), + Some(user) => edge::dev(target, deploy_config, user, server_config, verbose), None => gcs::dev(target, server_config, verbose), } } diff --git a/src/commands/dev/utils.rs b/src/commands/dev/utils.rs new file mode 100644 index 000000000..840ef950a --- /dev/null +++ b/src/commands/dev/utils.rs @@ -0,0 +1,8 @@ +use hyper::Uri; + +pub(super) fn get_path_as_str(uri: &Uri) -> String { + uri.path_and_query() + .map(|x| x.as_str()) + .unwrap_or("") + .to_string() +} diff --git a/src/main.rs b/src/main.rs index 0cf24ba68..b3ac29be4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -620,9 +620,10 @@ fn run() -> Result<(), failure::Error> { let manifest = settings::toml::Manifest::new(config_path)?; let env = matches.value_of("env"); let target = manifest.get_target(env)?; + let deploy_config = manifest.deploy_config(env)?; let user = settings::global_user::GlobalUser::new().ok(); let verbose = matches.is_present("verbose"); - commands::dev::dev(target, user, host, port, ip, verbose)?; + commands::dev::dev(target, deploy_config, user, host, port, ip, verbose)?; } else if matches.subcommand_matches("whoami").is_some() { log::info!("Getting User settings"); let user = settings::global_user::GlobalUser::new()?; diff --git a/src/settings/toml/deploy_config.rs b/src/settings/toml/deploy_config.rs index 5c98642eb..43d8ee5e3 100644 --- a/src/settings/toml/deploy_config.rs +++ b/src/settings/toml/deploy_config.rs @@ -1,6 +1,12 @@ use crate::settings::toml::Route; use crate::terminal::message; +#[derive(Clone, Debug, PartialEq)] +pub enum DeployConfig { + Zoneless(Zoneless), + Zoned(Zoned), +} + impl DeployConfig { pub fn build( script_name: &str, @@ -89,12 +95,6 @@ impl DeployConfig { } } -#[derive(Clone, Debug, PartialEq)] -pub enum DeployConfig { - Zoneless(Zoneless), - Zoned(Zoned), -} - #[derive(Clone, Debug, PartialEq)] pub struct Zoneless { pub account_id: String, From 78a687cc40bd9e02d17012a6821831b74a38fc61 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Thu, 5 Mar 2020 13:17:00 -0600 Subject: [PATCH 02/14] wip --- src/commands/dev/edge/mod.rs | 2 +- src/commands/dev/edge/server.rs | 2 +- src/commands/dev/edge/setup.rs | 52 +++++++++++++++++++++++---------- src/commands/preview/upload.rs | 6 ++-- src/http.rs | 1 + src/upload/form/mod.rs | 28 +++++++++++++++--- src/upload/mod.rs | 2 +- 7 files changed, 68 insertions(+), 25 deletions(-) diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index 493d94daa..d90bbcee1 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -26,7 +26,7 @@ pub fn dev( .to_string(); let mut target = target.clone(); // TODO: replace asset manifest parameter - let preview_token = setup::upload(&mut target, None, &deploy_config, &user)?; + let preview_token = setup::upload(&mut target, None, &deploy_config, &user, preview_token)?; let server = serve(server_config, preview_token, host); let mut runtime = TokioRuntime::new()?; runtime.block_on(server) diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index cdaf2d64a..cc1c10c09 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -91,7 +91,7 @@ fn preview_request( ); // TODO: figure out how to http _or_ https - let uri: Uri = format!("https://{}{}", host, path) + parts.uri = format!("https://{}{}", host, path) .parse() .expect("Could not construct preview url"); diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 52eac44fe..0bdc44bb8 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -14,31 +14,30 @@ pub(super) fn upload( asset_manifest: Option, deploy_config: &DeployConfig, user: &GlobalUser, + preview_token: String, ) -> Result { let client = http::auth_client(None, &user); - if let Some(site_config) = target.site.clone() { publish::bind_static_site_contents(user, target, &site_config, true)?; } let session_config = get_session_config(deploy_config); - let address = get_address(deploy_config); + let address = get_upload_address(target); - let script_upload_form = upload::form::build(target, asset_manifest)?; + let script_upload_form = upload::form::build(target, asset_manifest, Some(session_config))?; - let res = client + let response = client .post(&address) + .header("cf-workers-preview-token", preview_token) .multipart(script_upload_form) .send()? .error_for_status()?; - let text = &res.text()?; - log::info!("Response from edge preview: {:#?}", text); + let text = &response.text()?; // TODO: use cloudflare-rs for this :) - let response: V4ApiResponse = serde_json::from_str(text)?; - - Ok(response.result.token) + let response: PreviewV4ApiResponse = serde_json::from_str(text)?; + Ok(response.result.preview_token) } pub(super) fn get_preview_token( @@ -58,12 +57,18 @@ pub(super) fn get_preview_token( fn get_session_config(deploy_config: &DeployConfig) -> serde_json::Value { match deploy_config { - DeployConfig::Zoned(config) => json!({"route": config.routes}), + DeployConfig::Zoned(config) => { + let mut routes: Vec = Vec::new(); + for route in &config.routes { + routes.push(route.pattern.clone()); + } + json!({ "routes": routes }) + } DeployConfig::Zoneless(_) => json!({"workers_dev": true}), } } -fn get_address(deploy_config: &DeployConfig) -> String { +fn get_initialize_address(deploy_config: &DeployConfig) -> String { match deploy_config { DeployConfig::Zoned(config) => format!( "https://api.cloudflare.com/client/v4/zones/{}/workers/realish", @@ -77,26 +82,43 @@ fn get_address(deploy_config: &DeployConfig) -> String { } } +fn get_upload_address(target: &mut Target) -> String { + format!( + "https://api.cloudflare.com/client/v4/accounts/{}/workers/scripts/{}/realish", + target.account_id, target.name + ) +} + fn get_exchange_url( deploy_config: &DeployConfig, user: &GlobalUser, ) -> Result { let client = http::auth_client(None, &user); - let address = get_address(deploy_config); + let address = get_initialize_address(deploy_config); let url = Url::parse(&address)?; let response = client.get(url).send()?.error_for_status()?; let text = &response.text()?; - let response: V4ApiResponse = serde_json::from_str(text)?; + let response: InitV4ApiResponse = serde_json::from_str(text)?; Ok(response.result.exchange_url) } #[derive(Debug, Serialize, Deserialize)] -struct Preview { +struct Init { pub exchange_url: String, pub token: String, } #[derive(Debug, Serialize, Deserialize)] -struct V4ApiResponse { +struct InitV4ApiResponse { + pub result: Init, +} + +#[derive(Debug, Serialize, Deserialize)] +struct Preview { + pub preview_token: String, +} + +#[derive(Debug, Serialize, Deserialize)] +struct PreviewV4ApiResponse { pub result: Preview, } diff --git a/src/commands/preview/upload.rs b/src/commands/preview/upload.rs index c79718e78..0060a0704 100644 --- a/src/commands/preview/upload.rs +++ b/src/commands/preview/upload.rs @@ -134,7 +134,7 @@ fn authenticated_upload( ); log::info!("address: {}", create_address); - let script_upload_form = upload::form::build(target, asset_manifest)?; + let script_upload_form = upload::form::build(target, asset_manifest, None)?; let res = client .post(&create_address) @@ -164,9 +164,9 @@ fn unauthenticated_upload(client: &Client, target: &Target) -> Result) -> HeaderMap { let mut headers = HeaderMap::new(); headers.insert(USER_AGENT, HeaderValue::from_str(&user_agent).unwrap()); + headers } diff --git a/src/upload/form/mod.rs b/src/upload/form/mod.rs index dccaf3482..112e4eb79 100644 --- a/src/upload/form/mod.rs +++ b/src/upload/form/mod.rs @@ -25,6 +25,7 @@ use super::{krate, Package}; pub fn build( target: &Target, asset_manifest: Option, + session_config: Option, ) -> Result { let target_type = &target.target_type; let kv_namespaces = target.kv_namespaces(); @@ -60,7 +61,7 @@ pub fn build( plain_texts, )?; - build_form(&assets) + build_form(&assets, session_config) } TargetType::JavaScript => { log::info!("JavaScript project detected. Publishing..."); @@ -77,7 +78,7 @@ pub fn build( plain_texts, )?; - build_form(&assets) + build_form(&assets, session_config) } TargetType::Webpack => { log::info!("webpack project detected. Publishing..."); @@ -110,7 +111,7 @@ pub fn build( plain_texts, )?; - build_form(&assets) + build_form(&assets, session_config) } } } @@ -120,13 +121,19 @@ fn get_asset_manifest_blob(asset_manifest: AssetManifest) -> Result Result { +fn build_form( + assets: &ProjectAssets, + session_config: Option, +) -> Result { let mut form = Form::new(); // The preview service in particular streams the request form, and requires that the // "metadata" part be set first, so this order is important. form = add_metadata(form, assets)?; form = add_files(form, assets)?; + if let Some(session_config) = session_config { + form = add_session_config(form, session_config)? + } log::info!("building form"); log::info!("{:?}", &form); @@ -167,6 +174,19 @@ fn add_metadata(mut form: Form, assets: &ProjectAssets) -> Result Result { + let wrangler_session_config = Part::text((session_config).to_string()) + .file_name("") + .mime_str("application/json")?; + + form = form.part("wrangler-session-config", wrangler_session_config); + + Ok(form) +} + fn filename_from_path(path: &PathBuf) -> Option { path.file_stem()?.to_str().map(|s| s.to_string()) } diff --git a/src/upload/mod.rs b/src/upload/mod.rs index 1b12dcc6f..18f8a68e6 100644 --- a/src/upload/mod.rs +++ b/src/upload/mod.rs @@ -25,7 +25,7 @@ pub fn script( http::auth_client(None, user) }; - let script_upload_form = form::build(target, asset_manifest)?; + let script_upload_form = form::build(target, asset_manifest, None)?; let res = client .put(&worker_addr) From 5fab9d585cf7b54cc57dcec3ddf2dcb9bdc6b4bb Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Wed, 11 Mar 2020 17:25:50 -0500 Subject: [PATCH 03/14] Parse host from exchange url --- src/commands/dev/edge/mod.rs | 7 +------ src/commands/dev/edge/setup.rs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index d90bbcee1..d52457030 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -18,12 +18,7 @@ pub fn dev( verbose: bool, ) -> Result<(), failure::Error> { commands::build(&target)?; - let preview_token = setup::get_preview_token(&deploy_config, &user)?; - let host = match deploy_config.clone() { - DeployConfig::Zoned(config) => "theharnishes.com", - DeployConfig::Zoneless(config) => "worker.avery.workers.dev", - } - .to_string(); + let (preview_token, host) = setup::init(&deploy_config, &user)?; let mut target = target.clone(); // TODO: replace asset manifest parameter let preview_token = setup::upload(&mut target, None, &deploy_config, &user, preview_token)?; diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 0bdc44bb8..32a7858d0 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -5,6 +5,7 @@ use crate::settings::global_user::GlobalUser; use crate::settings::toml::{DeployConfig, Target}; use crate::upload; +use failure::format_err; use serde::{Deserialize, Serialize}; use serde_json::json; use url::Url; @@ -40,17 +41,20 @@ pub(super) fn upload( Ok(response.result.preview_token) } -pub(super) fn get_preview_token( +pub(super) fn init( deploy_config: &DeployConfig, user: &GlobalUser, -) -> Result { +) -> Result<(String, String), failure::Error> { let exchange_url = get_exchange_url(deploy_config, user)?; let client = http::auth_client(None, &user); - let response = client.get(&exchange_url).send()?.error_for_status()?; + let response = client + .get(exchange_url.clone()) + .send()? + .error_for_status()?; let headers = response.headers(); let token = headers.get("cf-workers-preview-token"); match token { - Some(token) => Ok(token.to_str()?.to_string()), + Some(token) => Ok((token.to_str()?.to_string(), exchange_url.host_str().expect("Could not get host string, please file an issue at https://github.com/cloudflare/wrangler").to_string())), None => failure::bail!("Could not get token to initialize preview session"), } } @@ -92,14 +96,14 @@ fn get_upload_address(target: &mut Target) -> String { fn get_exchange_url( deploy_config: &DeployConfig, user: &GlobalUser, -) -> Result { +) -> Result { let client = http::auth_client(None, &user); let address = get_initialize_address(deploy_config); let url = Url::parse(&address)?; let response = client.get(url).send()?.error_for_status()?; let text = &response.text()?; let response: InitV4ApiResponse = serde_json::from_str(text)?; - Ok(response.result.exchange_url) + Url::parse(&response.result.exchange_url).map_err(|e| format_err!("{}", e)) } #[derive(Debug, Serialize, Deserialize)] From 9ef586f2701330551945ed2b2134f60771ffcb63 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Mon, 23 Mar 2020 15:06:14 -0500 Subject: [PATCH 04/14] rename realish to edge-preview --- src/commands/dev/edge/setup.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 9bb9698cc..c01ec98f4 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -75,12 +75,12 @@ fn get_session_config(deploy_config: &DeployConfig) -> serde_json::Value { fn get_initialize_address(deploy_config: &DeployConfig) -> String { match deploy_config { DeployConfig::Zoned(config) => format!( - "https://api.cloudflare.com/client/v4/zones/{}/workers/realish", + "https://api.cloudflare.com/client/v4/zones/{}/workers/edge-preview", config.zone_id ), // TODO: zoneless is probably wrong DeployConfig::Zoneless(config) => format!( - "https://api.cloudflare.com/client/v4/account/{}/workers/realish/subdomain", + "https://api.cloudflare.com/client/v4/account/{}/workers/edge-preview/subdomain", config.account_id ), } @@ -88,7 +88,7 @@ fn get_initialize_address(deploy_config: &DeployConfig) -> String { fn get_upload_address(target: &mut Target) -> String { format!( - "https://api.cloudflare.com/client/v4/accounts/{}/workers/scripts/{}/realish", + "https://api.cloudflare.com/client/v4/accounts/{}/workers/scripts/{}/edge-preview", target.account_id, target.name ) } From 813f749a3b518a7040e807f4afb36d5554f88908 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Mon, 23 Mar 2020 15:52:24 -0500 Subject: [PATCH 05/14] fix endpoint for workers.dev preview --- src/commands/dev/edge/mod.rs | 9 +++++++++ src/commands/dev/edge/server.rs | 6 ++---- src/commands/dev/edge/setup.rs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index c728b9bbe..a347a5a03 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -19,6 +19,15 @@ pub fn dev( commands::build(&target)?; let (preview_token, host) = setup::init(&deploy_config, &user)?; let mut target = target.clone(); + let host = match deploy_config { + DeployConfig::Zoned(_) => host, + DeployConfig::Zoneless(_) => { + let namespaces: Vec<&str> = host.split('.').collect(); + let subdomain = namespaces[1]; + format!("{}.{}.workers.dev", target.name, subdomain) + } + }; + // TODO: replace asset manifest parameter let preview_token = setup::upload(&mut target, None, &deploy_config, &user, preview_token)?; let server = serve(server_config, preview_token, host); diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index f4ed90301..698968d3f 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -24,14 +24,12 @@ pub(super) async fn serve( let make_service = make_service_fn(move |_| { let client = client.to_owned(); let preview_token = preview_token.to_owned(); - let server_config = server_config.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.to_owned(); - let server_config = server_config.to_owned(); let host = host.to_owned(); let version = req.version(); let (parts, body) = req.into_parts(); @@ -43,7 +41,7 @@ pub(super) async fn serve( Request::from_parts(parts, body), client, preview_token.to_owned(), - host, + host.clone(), ) .await?; @@ -51,7 +49,7 @@ pub(super) async fn serve( "[{}] {} {}{} {:?} {}", now.format("%Y-%m-%d %H:%M:%S"), req_method, - server_config.host, + host, path, version, resp.status() diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index c01ec98f4..d3781fb55 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -80,7 +80,7 @@ fn get_initialize_address(deploy_config: &DeployConfig) -> String { ), // TODO: zoneless is probably wrong DeployConfig::Zoneless(config) => format!( - "https://api.cloudflare.com/client/v4/account/{}/workers/edge-preview/subdomain", + "https://api.cloudflare.com/client/v4/accounts/{}/workers/subdomain/edge-preview", config.account_id ), } From 67c8eda7e968e6db994adea17694ea537d7391a1 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Wed, 8 Apr 2020 15:41:50 -0500 Subject: [PATCH 06/14] use new header for auth --- src/commands/dev/edge/setup.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index f471049ae..3b4ed3ea6 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -29,7 +29,7 @@ pub(super) fn upload( let response = client .post(&address) - .header("cf-workers-preview-token", preview_token) + .header("cf-preview-upload-config-token", preview_token) .multipart(script_upload_form) .send()? .error_for_status()?; From d5f1e12225675539765748ded5d70d1b76ffedfd Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Tue, 19 May 2020 15:01:55 -0500 Subject: [PATCH 07/14] parse websocket endpoint from cdn-cgi --- src/commands/dev/edge/mod.rs | 16 +++---- src/commands/dev/edge/server.rs | 2 +- src/commands/dev/edge/setup.rs | 77 +++++++++++++++++++++++---------- src/commands/dev/gcs/mod.rs | 2 + 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index adc83807a..81a0d5604 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -2,6 +2,7 @@ mod server; mod setup; use server::serve; +use setup::Init; use crate::commands::dev::ServerConfig; use crate::settings::global_user::GlobalUser; @@ -15,20 +16,13 @@ pub fn dev( user: GlobalUser, server_config: ServerConfig, ) -> Result<(), failure::Error> { - let (preview_token, host) = setup::init(&deploy_config, &user)?; + let init = Init::new(&target, &deploy_config, &user)?; let mut target = target.clone(); - let host = match deploy_config { - DeployConfig::Zoned(_) => host, - DeployConfig::Zoneless(_) => { - let namespaces: Vec<&str> = host.split('.').collect(); - let subdomain = namespaces[1]; - format!("{}.{}.workers.dev", target.name, subdomain) - } - }; // TODO: replace asset manifest parameter - let preview_token = setup::upload(&mut target, None, &deploy_config, &user, preview_token)?; - let server = serve(server_config, preview_token, host); + let preview_token = + setup::upload(&mut target, None, &deploy_config, &user, init.preview_token)?; + let server = serve(server_config, preview_token, init.host); let mut runtime = TokioRuntime::new()?; runtime.block_on(server) } diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index 698968d3f..a68308c0c 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -60,7 +60,7 @@ pub(super) async fn serve( } }); - let server = Server::bind(&listening_address.address).serve(make_service); + let server = Server::bind(&listening_address).serve(make_service); println!("{} Listening on http://{}", emoji::EAR, listening_address); if let Err(e) = server.await { eprintln!("server error: {}", e) diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 3b4ed3ea6..4faa7a3f6 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -1,14 +1,12 @@ use crate::commands::kv::bucket::AssetManifest; use crate::commands::publish; -use crate::http; use crate::settings::global_user::GlobalUser; use crate::settings::toml::{DeployConfig, Target}; use crate::upload; -use failure::format_err; +use reqwest::Url; use serde::{Deserialize, Serialize}; use serde_json::json; -use url::Url; pub(super) fn upload( target: &mut Target, @@ -17,7 +15,7 @@ pub(super) fn upload( user: &GlobalUser, preview_token: String, ) -> Result { - let client = http::legacy_auth_client(&user); + let client = crate::http::legacy_auth_client(&user); if target.site.is_some() { publish::add_site_namespace(user, target, true)?; } @@ -41,21 +39,47 @@ pub(super) fn upload( Ok(response.result.preview_token) } -pub(super) fn init( - deploy_config: &DeployConfig, - user: &GlobalUser, -) -> Result<(String, String), failure::Error> { - let exchange_url = get_exchange_url(deploy_config, user)?; - let client = http::legacy_auth_client(&user); - let response = client - .get(exchange_url.clone()) - .send()? - .error_for_status()?; - let headers = response.headers(); - let token = headers.get("cf-workers-preview-token"); - match token { - Some(token) => Ok((token.to_str()?.to_string(), exchange_url.host_str().expect("Could not get host string, please file an issue at https://github.com/cloudflare/wrangler").to_string())), - None => failure::bail!("Could not get token to initialize preview session"), +pub struct Init { + pub host: String, + pub websocket_url: Url, + pub preview_token: String, +} + +impl Init { + pub fn new( + target: &Target, + deploy_config: &DeployConfig, + user: &GlobalUser, + ) -> Result { + let exchange_url = get_exchange_url(deploy_config, user)?; + let host = match exchange_url.host_str() { + Some(host) => Ok(host.to_string()), + None => Err(failure::format_err!( + "Could not parse host from exchange url" + )), + }?; + + let host = match deploy_config { + DeployConfig::Zoned(_) => host.to_owned(), + DeployConfig::Zoneless(_) => { + let namespaces: Vec<&str> = host.as_str().split('.').collect(); + let subdomain = namespaces[1]; + format!("{}.{}.workers.dev", target.name, subdomain) + } + }; + + let client = crate::http::legacy_auth_client(&user); + let response = client.get(exchange_url).send()?.error_for_status()?; + let text = &response.text()?; + let response: InspectorV4ApiResponse = serde_json::from_str(text)?; + let websocket_url = Url::parse(&response.inspector_websocket)?; + let preview_token = response.token; + + Ok(Init { + host, + websocket_url, + preview_token, + }) } } @@ -97,24 +121,31 @@ fn get_exchange_url( deploy_config: &DeployConfig, user: &GlobalUser, ) -> Result { - let client = http::legacy_auth_client(&user); + let client = crate::http::legacy_auth_client(&user); let address = get_initialize_address(deploy_config); let url = Url::parse(&address)?; let response = client.get(url).send()?.error_for_status()?; let text = &response.text()?; let response: InitV4ApiResponse = serde_json::from_str(text)?; - Url::parse(&response.result.exchange_url).map_err(|e| format_err!("{}", e)) + let url = Url::parse(&response.result.exchange_url)?; + Ok(url) } #[derive(Debug, Serialize, Deserialize)] -struct Init { +struct InitResponse { pub exchange_url: String, pub token: String, } #[derive(Debug, Serialize, Deserialize)] struct InitV4ApiResponse { - pub result: Init, + pub result: InitResponse, +} + +#[derive(Debug, Serialize, Deserialize)] +struct InspectorV4ApiResponse { + pub inspector_websocket: String, + pub token: String, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/commands/dev/gcs/mod.rs b/src/commands/dev/gcs/mod.rs index 983c19a98..c89fa3500 100644 --- a/src/commands/dev/gcs/mod.rs +++ b/src/commands/dev/gcs/mod.rs @@ -22,6 +22,8 @@ pub fn dev( server_config: ServerConfig, verbose: bool, ) -> Result<(), failure::Error> { + println!("unauthenticated"); + // setup the session let session_id = get_session_id()?; From cd14794b66420ad3d2d4c72f3fffe151a3f277e6 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Tue, 19 May 2020 15:20:25 -0500 Subject: [PATCH 08/14] wip connect to edge websocket --- src/commands/dev/edge/mod.rs | 23 ++++++++++++++++++----- src/commands/dev/edge/setup.rs | 7 ++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index 81a0d5604..2bde1ed42 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -4,7 +4,7 @@ mod setup; use server::serve; use setup::Init; -use crate::commands::dev::ServerConfig; +use crate::commands::dev::{socket, ServerConfig}; use crate::settings::global_user::GlobalUser; use crate::settings::toml::{DeployConfig, Target}; @@ -20,9 +20,22 @@ pub fn dev( let mut target = target.clone(); // TODO: replace asset manifest parameter - let preview_token = - setup::upload(&mut target, None, &deploy_config, &user, init.preview_token)?; - let server = serve(server_config, preview_token, init.host); + let preview_token = setup::upload( + &mut target, + None, + &deploy_config, + &user, + init.preview_token.clone(), + )?; let mut runtime = TokioRuntime::new()?; - runtime.block_on(server) + runtime.block_on(async { + let devtools_listener = tokio::spawn(socket::listen(init.websocket_url)); + let server = tokio::spawn(serve(server_config, preview_token, init.host)); + let res = tokio::try_join!(async { devtools_listener.await? }, async { server.await? }); + + match res { + Ok(_) => Ok(()), + Err(e) => Err(e), + } + }) } diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 4faa7a3f6..6b154cfed 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -39,6 +39,7 @@ pub(super) fn upload( Ok(response.result.preview_token) } +#[derive(Debug, Clone)] pub struct Init { pub host: String, pub websocket_url: Url, @@ -72,7 +73,11 @@ impl Init { let response = client.get(exchange_url).send()?.error_for_status()?; let text = &response.text()?; let response: InspectorV4ApiResponse = serde_json::from_str(text)?; - let websocket_url = Url::parse(&response.inspector_websocket)?; + let full_url = format!( + "{}?{}={}", + &response.inspector_websocket, "cf_workers_preview_token", &response.token + ); + let websocket_url = Url::parse(&full_url)?; let preview_token = response.token; Ok(Init { From 54cd8d51945267cd574643f1300bee795d2f43cf Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Tue, 16 Jun 2020 16:26:13 -0500 Subject: [PATCH 09/14] fixup merge conflicts --- src/commands/dev/edge/setup.rs | 5 ++--- src/preview/upload.rs | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 4faa7a3f6..07d36b222 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -1,7 +1,6 @@ -use crate::commands::kv::bucket::AssetManifest; -use crate::commands::publish; use crate::settings::global_user::GlobalUser; use crate::settings::toml::{DeployConfig, Target}; +use crate::sites::{self, AssetManifest}; use crate::upload; use reqwest::Url; @@ -17,7 +16,7 @@ pub(super) fn upload( ) -> Result { let client = crate::http::legacy_auth_client(&user); if target.site.is_some() { - publish::add_site_namespace(user, target, true)?; + sites::add_namespace(user, target, true)?; } let session_config = get_session_config(deploy_config); diff --git a/src/preview/upload.rs b/src/preview/upload.rs index 366fdac0b..4c9051e28 100644 --- a/src/preview/upload.rs +++ b/src/preview/upload.rs @@ -188,10 +188,10 @@ fn unauthenticated_upload(target: &Target) -> Result { message::warn( "KV Namespaces are not supported in preview without setting API credentials and account_id", ); - + target.kv_namespaces = Vec::new(); } - let script_upload_form = upload::form::build(&target, None)?; + let script_upload_form = upload::form::build(&target, None, None)?; let client = http::client(); let res = client .post(create_address) From ba5be3acbd9fa40d61729d55148cf0541db3187f Mon Sep 17 00:00:00 2001 From: Josh Wheeler Date: Tue, 30 Jun 2020 11:13:41 -0500 Subject: [PATCH 10/14] pass token as get param instead of header for preview requests --- src/commands/dev/edge/server.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index a68308c0c..8236f8026 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -83,15 +83,13 @@ fn preview_request( 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 header for preview id"), - ); - // TODO: figure out how to http _or_ https - parts.uri = format!("https://{}{}", host, path) - .parse() - .expect("Could not construct preview url"); + parts.uri = format!( + "https://{}{}?cf_workers_preview_token={}", + host, path, preview_token + ) + .parse() + .expect("Could not construct preview url"); let req = Request::from_parts(parts, body); From 5d077aae706bc5de2059235f58bb664a547ca275 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Tue, 30 Jun 2020 11:34:31 -0500 Subject: [PATCH 11/14] clippy --- src/commands/dev/edge/mod.rs | 2 +- src/commands/dev/edge/setup.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index 81a0d5604..1eba66017 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -17,7 +17,7 @@ pub fn dev( server_config: ServerConfig, ) -> Result<(), failure::Error> { let init = Init::new(&target, &deploy_config, &user)?; - let mut target = target.clone(); + let mut target = target; // TODO: replace asset manifest parameter let preview_token = diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 07d36b222..8c05f38db 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -59,7 +59,7 @@ impl Init { }?; let host = match deploy_config { - DeployConfig::Zoned(_) => host.to_owned(), + DeployConfig::Zoned(_) => host, DeployConfig::Zoneless(_) => { let namespaces: Vec<&str> = host.as_str().split('.').collect(); let subdomain = namespaces[1]; From e475c33dec14d69065a0a5b3cd7fb19329e1c39a Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Wed, 15 Jul 2020 13:19:59 -0500 Subject: [PATCH 12/14] clippy --- src/commands/dev/edge/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index 8236f8026..9d436ffd7 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -18,7 +18,7 @@ pub(super) async fn serve( let https = HttpsConnector::new(); let client = HyperClient::builder().build::<_, Body>(https); - let listening_address = server_config.listening_address.clone(); + let listening_address = server_config.listening_address; // create a closure that hyper will use later to handle HTTP requests let make_service = make_service_fn(move |_| { From 1f2ad3139a418145dbdcedfec70a8a07d7bfcdec Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Wed, 15 Jul 2020 13:28:42 -0500 Subject: [PATCH 13/14] put token back in header --- src/commands/dev/edge/server.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index 8236f8026..2a064037c 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -83,13 +83,15 @@ fn preview_request( 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"), + ); + // TODO: figure out how to http _or_ https - parts.uri = format!( - "https://{}{}?cf_workers_preview_token={}", - host, path, preview_token - ) - .parse() - .expect("Could not construct preview url"); + parts.uri = format!("https://{}{}", host, path) + .parse() + .expect("Could not construct preview url"); let req = Request::from_parts(parts, body); From 39b56c90aa8e5bbccd0fca8907bad045cda44dc0 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Wed, 15 Jul 2020 13:37:54 -0500 Subject: [PATCH 14/14] [dev] upload workers sites bindings for edge dev (#1451) --- src/commands/dev/edge/mod.rs | 10 +++++++-- src/commands/dev/edge/server.rs | 2 +- src/commands/dev/edge/setup.rs | 37 ++++++++++++++++++++++++++++----- src/commands/dev/mod.rs | 2 +- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/commands/dev/edge/mod.rs b/src/commands/dev/edge/mod.rs index 1eba66017..c9a81dad6 100644 --- a/src/commands/dev/edge/mod.rs +++ b/src/commands/dev/edge/mod.rs @@ -15,13 +15,19 @@ pub fn dev( deploy_config: DeployConfig, user: GlobalUser, server_config: ServerConfig, + verbose: bool, ) -> Result<(), failure::Error> { let init = Init::new(&target, &deploy_config, &user)?; let mut target = target; // TODO: replace asset manifest parameter - let preview_token = - setup::upload(&mut target, None, &deploy_config, &user, init.preview_token)?; + let preview_token = setup::upload( + &mut target, + &deploy_config, + &user, + init.preview_token, + verbose, + )?; let server = serve(server_config, preview_token, init.host); let mut runtime = TokioRuntime::new()?; runtime.block_on(server) diff --git a/src/commands/dev/edge/server.rs b/src/commands/dev/edge/server.rs index 2a064037c..11a4bb4d7 100644 --- a/src/commands/dev/edge/server.rs +++ b/src/commands/dev/edge/server.rs @@ -18,7 +18,7 @@ pub(super) async fn serve( let https = HttpsConnector::new(); let client = HyperClient::builder().build::<_, Body>(https); - let listening_address = server_config.listening_address.clone(); + let listening_address = server_config.listening_address; // create a closure that hyper will use later to handle HTTP requests let make_service = make_service_fn(move |_| { diff --git a/src/commands/dev/edge/setup.rs b/src/commands/dev/edge/setup.rs index 8c05f38db..044b31b11 100644 --- a/src/commands/dev/edge/setup.rs +++ b/src/commands/dev/edge/setup.rs @@ -1,6 +1,10 @@ +use std::path::Path; + +use crate::kv::bulk; use crate::settings::global_user::GlobalUser; use crate::settings::toml::{DeployConfig, Target}; -use crate::sites::{self, AssetManifest}; +use crate::sites::{add_namespace, sync}; +use crate::terminal::message; use crate::upload; use reqwest::Url; @@ -9,15 +13,30 @@ use serde_json::json; pub(super) fn upload( target: &mut Target, - asset_manifest: Option, deploy_config: &DeployConfig, user: &GlobalUser, preview_token: String, + verbose: bool, ) -> Result { let client = crate::http::legacy_auth_client(&user); - if target.site.is_some() { - sites::add_namespace(user, target, true)?; - } + + let (to_delete, asset_manifest, site_namespace_id) = if let Some(site_config) = + target.site.clone() + { + let site_namespace = add_namespace(user, target, true)?; + let path = Path::new(&site_config.bucket); + let (to_upload, to_delete, asset_manifest) = sync(target, user, &site_namespace.id, path)?; + + // First, upload all existing files in given directory + if verbose { + message::info("Uploading updated files..."); + } + + bulk::put(target, user, &site_namespace.id, to_upload, &None)?; + (to_delete, Some(asset_manifest), Some(site_namespace.id)) + } else { + (Vec::new(), None, None) + }; let session_config = get_session_config(deploy_config); let address = get_upload_address(target); @@ -31,6 +50,14 @@ pub(super) fn upload( .send()? .error_for_status()?; + if !to_delete.is_empty() { + if verbose { + message::info("Deleting stale files..."); + } + + bulk::delete(target, user, &site_namespace_id.unwrap(), to_delete, &None)?; + } + let text = &response.text()?; // TODO: use cloudflare-rs for this :) diff --git a/src/commands/dev/mod.rs b/src/commands/dev/mod.rs index e26605d31..7edda2cb9 100644 --- a/src/commands/dev/mod.rs +++ b/src/commands/dev/mod.rs @@ -32,7 +32,7 @@ pub fn dev( match user { // authenticated users connect to the edge - Some(user) => edge::dev(target, deploy_config, user, server_config), + Some(user) => edge::dev(target, deploy_config, user, server_config, verbose), // unauthenticated users connect to gcs None => gcs::dev(target, server_config, verbose),