From 07c113a76c655388139c5ced54acfc45f24a876c Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Mon, 4 Nov 2024 16:54:54 -0800 Subject: [PATCH] Cf worker support --- Cargo.lock | 505 ++++++++++++++++++++++- Cargo.toml | 1 + examples/cloudflare-worker/.gitignore | 3 + examples/cloudflare-worker/Cargo.toml | 24 ++ examples/cloudflare-worker/src/lib.rs | 9 + examples/cloudflare-worker/wrangler.toml | 6 + rwf/Cargo.toml | 9 +- rwf/src/controller/mod.rs | 3 + rwf/src/http/cloudflare.rs | 53 +++ rwf/src/http/error.rs | 4 + rwf/src/http/head.rs | 9 + rwf/src/http/mod.rs | 15 +- rwf/src/http/request.rs | 16 + rwf/src/lib.rs | 2 +- 14 files changed, 637 insertions(+), 22 deletions(-) create mode 100644 examples/cloudflare-worker/.gitignore create mode 100644 examples/cloudflare-worker/Cargo.toml create mode 100644 examples/cloudflare-worker/src/lib.rs create mode 100644 examples/cloudflare-worker/wrangler.toml create mode 100644 rwf/src/http/cloudflare.rs diff --git a/Cargo.lock b/Cargo.lock index ea58e912..8d6bf6fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -113,9 +113,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "async-stream" @@ -300,6 +300,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "js-sys", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "cipher" version = "0.4.4" @@ -350,6 +361,17 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +[[package]] +name = "cloudflare-worker" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "http", + "rwf", + "worker", + "worker-macros", +] + [[package]] name = "colorchoice" version = "1.0.3" @@ -405,6 +427,16 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "cpufeatures" version = "0.2.14" @@ -498,6 +530,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "django" version = "0.1.0" @@ -571,6 +614,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -602,6 +654,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + [[package]] name = "futures-macro" version = "0.3.31" @@ -632,9 +690,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -657,8 +717,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -694,9 +756,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hdrhistogram" @@ -807,9 +869,9 @@ dependencies = [ [[package]] name = "hyper-timeout" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ "hyper", "hyper-util", @@ -837,6 +899,145 @@ dependencies = [ "tracing", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -854,7 +1055,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -974,6 +1175,12 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -1638,6 +1845,7 @@ dependencies = [ "base64 0.22.1", "bytes", "colored", + "getrandom", "notify", "once_cell", "parking_lot", @@ -1658,6 +1866,7 @@ dependencies = [ "tracing", "tracing-subscriber", "uuid", + "worker", ] [[package]] @@ -1761,6 +1970,28 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" version = "1.0.214" @@ -1793,6 +2024,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1864,6 +2107,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static-files" version = "0.1.0" @@ -1897,9 +2146,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -1918,6 +2167,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -1936,18 +2196,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", @@ -1995,6 +2255,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -2329,6 +2599,29 @@ dependencies = [ "subtle", ] +[[package]] +name = "url" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -2413,6 +2706,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.95" @@ -2442,6 +2747,19 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.72" @@ -2651,6 +2969,116 @@ dependencies = [ "memchr", ] +[[package]] +name = "worker" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8aca53ec63e508176a89a573c972266f0f98bcc48bd866def7be0d939ef9268" +dependencies = [ + "async-trait", + "bytes", + "chrono", + "futures-channel", + "futures-util", + "http", + "http-body", + "js-sys", + "matchit", + "pin-project", + "serde", + "serde-wasm-bindgen 0.6.5", + "serde_json", + "serde_urlencoded", + "tokio", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "worker-kv", + "worker-macros", + "worker-sys", +] + +[[package]] +name = "worker-kv" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f06d4d1416a9f8346ee9123b0d9a11b3cfa38e6cfb5a139698017d1597c4d41" +dependencies = [ + "js-sys", + "serde", + "serde-wasm-bindgen 0.5.0", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "worker-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1118a0ceb59ddde7fdbaff6c47b6fa6ee47848975ea38b4ae9bb4080f96541cd" +dependencies = [ + "async-trait", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-macro-support", + "worker-sys", +] + +[[package]] +name = "worker-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5643a2ba07df61aa50e37212ffcb0944417db7d3960d4331f36aeb2fa5e2fd7" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -2672,8 +3100,51 @@ dependencies = [ "syn", ] +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index aefe086d..299b65e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,4 +19,5 @@ members = [ "examples/request-tracking", "examples/engine", "rwf-admin", + "examples/cloudflare-worker", ] diff --git a/examples/cloudflare-worker/.gitignore b/examples/cloudflare-worker/.gitignore new file mode 100644 index 00000000..d27315f0 --- /dev/null +++ b/examples/cloudflare-worker/.gitignore @@ -0,0 +1,3 @@ +target +node_modules +.wrangler diff --git a/examples/cloudflare-worker/Cargo.toml b/examples/cloudflare-worker/Cargo.toml new file mode 100644 index 00000000..127d5aaa --- /dev/null +++ b/examples/cloudflare-worker/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "cloudflare-worker" +version = "0.1.0" +edition = "2021" +authors = ["Lev Kokotov "] + +[package.metadata.release] +release = false + +# https://github.com/rustwasm/wasm-pack/issues/1247 +[package.metadata.wasm-pack.profile.release] +wasm-opt = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +worker = { version = "0.4.2", features = ['http'] } +worker-macros = { version = "0.4.2", features = ['http'] } +console_error_panic_hook = { version = "0.1.1" } +http = "1.1" +rwf = { path = "../../rwf", default-features = false, features = [ + "cloudflare", +] } diff --git a/examples/cloudflare-worker/src/lib.rs b/examples/cloudflare-worker/src/lib.rs new file mode 100644 index 00000000..b594dbc8 --- /dev/null +++ b/examples/cloudflare-worker/src/lib.rs @@ -0,0 +1,9 @@ +use worker::*; + +#[event(fetch)] +async fn fetch(req: Request, _env: Env, _ctx: Context) -> Result { + console_error_panic_hook::set_once(); + Ok(Response::builder() + .with_status(200) + .body(ResponseBody::Empty)) +} diff --git a/examples/cloudflare-worker/wrangler.toml b/examples/cloudflare-worker/wrangler.toml new file mode 100644 index 00000000..8087d463 --- /dev/null +++ b/examples/cloudflare-worker/wrangler.toml @@ -0,0 +1,6 @@ +name = "cloudflare-worker" +main = "build/worker/shim.mjs" +compatibility_date = "2024-11-04" + +[build] +command = "cargo install -q worker-build && worker-build --release" \ No newline at end of file diff --git a/rwf/Cargo.toml b/rwf/Cargo.toml index 0d64f9b5..140bd183 100644 --- a/rwf/Cargo.toml +++ b/rwf/Cargo.toml @@ -9,7 +9,8 @@ description = "Framework for building web applications in the Rust programming l [features] wsgi = ["pyo3", "rayon"] -default = [] +cloudflare = ["worker"] +default = ["tokio", "notify"] [dependencies] time = { version = "0.3", features = ["formatting", "serde", "parsing"] } @@ -19,7 +20,7 @@ tokio-postgres = { version = "0.7", features = [ "with-uuid-1", ] } bytes = "1" -tokio = { version = "1", features = ["full"] } +tokio = { version = "1", features = ["full"], optional = true } thiserror = "1" parking_lot = "0.12" once_cell = "1" @@ -34,13 +35,15 @@ base64 = "0.22" aes-gcm-siv = "0.11" aes = "0.8" rand = { version = "0.8", features = ["getrandom"] } +getrandom = { version = "*", features = ["js"] } regex = "1" sha1 = "0.10" toml = "0.8" pyo3 = { version = "0.22", features = ["auto-initialize"], optional = true } rayon = { version = "1", optional = true } uuid = { version = "1", features = ["v4"] } -notify = "7" +notify = { version = "7", optional = true } +worker = { version = "0.4", features = ["http"], optional = true } [dev-dependencies] tempdir = "0.3" diff --git a/rwf/src/controller/mod.rs b/rwf/src/controller/mod.rs index ff38bb8d..9667efd1 100644 --- a/rwf/src/controller/mod.rs +++ b/rwf/src/controller/mod.rs @@ -6,6 +6,7 @@ pub mod error; pub mod middleware; pub mod ser; pub mod static_files; +#[cfg(not(feature = "cloudflare"))] pub mod turbo_stream; pub mod util; @@ -19,6 +20,7 @@ pub use engine::Engine; pub use error::Error; pub use middleware::{Middleware, MiddlewareHandler, MiddlewareSet, Outcome, RateLimiter}; pub use static_files::StaticFiles; +#[cfg(not(feature = "cloudflare"))] pub use turbo_stream::TurboStream; use super::http::{ @@ -407,6 +409,7 @@ pub trait ModelController: Controller { #[async_trait] #[allow(unused_variables)] +#[cfg(not(feature = "cloudflare"))] pub trait WebsocketController: Controller { async fn handle(&self, request: &Request) -> Result { use base64::{engine::general_purpose, Engine as _}; diff --git a/rwf/src/http/cloudflare.rs b/rwf/src/http/cloudflare.rs new file mode 100644 index 00000000..45cd07b0 --- /dev/null +++ b/rwf/src/http/cloudflare.rs @@ -0,0 +1,53 @@ +use crate::http::{self, Head, Headers, Method, Path, Version}; +use worker::{Request, Response}; + +impl From for Method { + fn from(method: worker::Method) -> Method { + match method { + worker::Method::Get => Method::Get, + worker::Method::Post => Method::Post, + worker::Method::Head => Method::Head, + worker::Method::Patch => Method::Patch, + worker::Method::Put => Method::Put, + worker::Method::Delete => Method::Delete, + method => panic!("cf method conversion: {}", method), + } + } +} + +pub struct CfRequest { + request: http::Request, +} + +impl CfRequest { + pub async fn from_request(mut request: worker::Request) -> Result { + let url = request.url()?; + let query = if let Some(query) = url.query() { + format!("?{}", query) + } else { + "".to_string() + }; + let path = format!("{}{}", url.path(), query); + let path = Path::parse(&path)?; + let version = Version::Http1; + + let mut headers = Headers::new(); + + for (key, value) in request.headers() { + headers.insert(key, value); + } + + let head = Head::new(request.method().into(), path, version, headers); + let body = request.bytes().await?; + + Ok(CfRequest { + request: http::Request::new(head, &body)?, + }) + } +} + +impl From for Response { + fn from(request: super::Response) -> Response { + todo!() + } +} diff --git a/rwf/src/http/error.rs b/rwf/src/http/error.rs index ab1b2386..718144b6 100644 --- a/rwf/src/http/error.rs +++ b/rwf/src/http/error.rs @@ -37,6 +37,10 @@ pub enum Error { #[error("forbidden")] Forbidden, + + #[cfg(feature = "cloudflare")] + #[error("cloudflare: {0}")] + Cloudflare(#[from] worker::Error), } impl Error { diff --git a/rwf/src/http/head.rs b/rwf/src/http/head.rs index c61c4ff6..62f46c62 100644 --- a/rwf/src/http/head.rs +++ b/rwf/src/http/head.rs @@ -149,6 +149,15 @@ impl Head { }) } + pub fn new(method: Method, path: Path, version: Version, headers: Headers) -> Self { + Self { + method, + path, + version, + headers, + } + } + pub fn authorization(&self) -> Option { Authorization::parse(match self.header("authorization") { Some(authorization) => authorization, diff --git a/rwf/src/http/mod.rs b/rwf/src/http/mod.rs index 8d3b4bb9..b8de1c90 100644 --- a/rwf/src/http/mod.rs +++ b/rwf/src/http/mod.rs @@ -12,6 +12,7 @@ pub mod path; pub mod request; pub mod response; pub mod router; +#[cfg(not(feature = "cloudflare"))] pub mod server; pub mod url; pub mod websocket; @@ -19,6 +20,11 @@ pub mod websocket; #[cfg(feature = "wsgi")] pub mod wsgi; +#[cfg(feature = "cloudflare")] +pub mod cloudflare; + +use std::marker::PhantomData; + pub use authorization::Authorization; pub use body::Body; pub use cookies::{Cookie, CookieBuilder, Cookies}; @@ -26,13 +32,20 @@ pub use error::Error; pub use form::{Form, FromFormData}; pub use form_data::FormData; pub use handler::Handler; -pub use head::{Head, Method}; +pub use head::{Head, Method, Version}; pub use headers::Headers; pub use path::{Params, Path, Query, ToParameter}; pub use request::Request; pub use response::Response; pub use router::Router; +#[cfg(not(feature = "cloudflare"))] pub use server::{Server, Stream}; + +#[cfg(feature = "cloudflare")] +pub enum Stream<'a> { + Cloudflare { _unused: &'a str }, +} + pub use url::{urldecode, urlencode}; pub use websocket::Message; diff --git a/rwf/src/http/request.rs b/rwf/src/http/request.rs index 9e9afd75..b71a78a7 100644 --- a/rwf/src/http/request.rs +++ b/rwf/src/http/request.rs @@ -75,6 +75,22 @@ impl Request { }) } + pub fn new(head: Head, body: &[u8]) -> Result { + let cookies = head.cookies(); + + Ok(Self { + head, + params: None, + session: cookies.get_session()?, + inner: Arc::new(Inner { + body: body.to_vec(), + peer: None, + cookies, + }), + received_at: OffsetDateTime::now_utc(), + }) + } + /// Get the request's source IP address. pub fn peer(&self) -> &SocketAddr { self.inner diff --git a/rwf/src/lib.rs b/rwf/src/lib.rs index 8b223d9e..e558a36b 100644 --- a/rwf/src/lib.rs +++ b/rwf/src/lib.rs @@ -5,6 +5,7 @@ pub mod config; pub mod controller; pub mod crypto; pub mod error; +#[cfg(not(feature = "cloudflare"))] pub mod hmr; pub mod http; pub mod job; @@ -21,7 +22,6 @@ pub use tokio; pub use tokio_postgres; pub use controller::{Controller, Error, ModelController, RestController}; -pub use http::Server; pub use logging::Logger; use std::net::SocketAddr;