wrangler/commands/dev/
mod.rs

1mod edge;
2mod gcs;
3mod server_config;
4mod socket;
5mod tls;
6mod utils;
7
8use hyper::client::HttpConnector;
9use hyper::Body;
10use hyper_rustls::HttpsConnector;
11pub use server_config::Protocol;
12pub use server_config::ServerConfig;
13
14use crate::build::build_target;
15use crate::deploy::{DeployTarget, DeploymentSet};
16use crate::settings::global_user::GlobalUser;
17use crate::settings::toml::Target;
18use crate::terminal::message::{Message, StdOut};
19use crate::terminal::styles;
20
21use anyhow::Result;
22
23fn client() -> hyper::Client<HttpsConnector<HttpConnector>> {
24    let builder = hyper_rustls::HttpsConnectorBuilder::new()
25        .with_native_roots()
26        .https_or_http();
27    // Cloudflare doesn't currently support websockets with HTTP/2.
28    // Allow using HTTP/1.1 for websocket connections.
29    let https = builder.enable_http1().build();
30    hyper::Client::builder().build::<_, Body>(https)
31}
32
33/// `wrangler dev` starts a server on a dev machine that routes incoming HTTP requests
34/// to a Cloudflare Workers runtime and returns HTTP responses
35#[allow(clippy::too_many_arguments)]
36pub fn dev(
37    target: Target,
38    deployments: DeploymentSet,
39    user: Option<GlobalUser>,
40    server_config: ServerConfig,
41    local_protocol: Protocol,
42    upstream_protocol: Protocol,
43    verbose: bool,
44    inspect: bool,
45    unauthenticated: bool,
46) -> Result<()> {
47    // before serving requests we must first build the Worker
48    build_target(&target)?;
49
50    let deploy_target = {
51        let valid_targets = deployments
52            .into_iter()
53            .filter(|t| matches!(t, DeployTarget::Zoned(_) | DeployTarget::Zoneless(_)))
54            .collect::<Vec<_>>();
55
56        let valid_target = valid_targets
57            .iter()
58            .find(|&t| matches!(t, DeployTarget::Zoned(_)))
59            .or_else(|| {
60                valid_targets
61                    .iter()
62                    .find(|&t| matches!(t, DeployTarget::Zoneless(_)))
63            });
64
65        if let Some(target) = valid_target {
66            target.clone()
67        } else {
68            anyhow::bail!("No valid deployment targets: `wrangler dev` can only be used to develop zoned and zoneless deployments")
69        }
70    };
71
72    let host_str = styles::highlight("--host");
73    let local_str = styles::highlight("--local-protocol");
74    let upstream_str = styles::highlight("--upstream-protocol");
75
76    if server_config.host.is_https() != upstream_protocol.is_https() {
77        anyhow::bail!(
78            "Protocol mismatch: protocol in {} and protocol in {} must match",
79            host_str,
80            upstream_str
81        )
82    } else if local_protocol.is_https() && upstream_protocol.is_http() {
83        anyhow::bail!("{} cannot be https if {} is http", local_str, upstream_str)
84    }
85
86    if let Some(user) = user {
87        if !unauthenticated {
88            return edge::dev(
89                target,
90                user,
91                server_config,
92                deploy_target,
93                local_protocol,
94                upstream_protocol,
95                verbose,
96                inspect,
97            );
98        }
99    } else {
100        let wrangler_config_msg = styles::highlight("`wrangler config`");
101        let wrangler_login_msg = styles::highlight("`wrangler login`");
102        let docs_url_msg = styles::url("https://developers.cloudflare.com/workers/tooling/wrangler/configuration/#using-environment-variables");
103        StdOut::billboard(
104        &format!("You have not provided your Cloudflare credentials.\n\nPlease run {}, {}, or visit\n{}\nfor info on authenticating with environment variables.", wrangler_login_msg, wrangler_config_msg, docs_url_msg)
105        );
106    }
107
108    if target.durable_objects.is_some() {
109        anyhow::bail!("wrangler dev does not yet support unauthenticated sessions when using Durable Objects. Please run wrangler login or wrangler config first.")
110    }
111
112    gcs::dev(target, server_config, local_protocol, verbose, inspect)
113}