From 64a114a994e7f1a5766de22c03723bd437c6a864 Mon Sep 17 00:00:00 2001 From: Miguel Piedrafita Date: Wed, 16 Aug 2023 21:30:26 +0200 Subject: [PATCH] Implement Bridge Spec (v1) --- Cargo.lock | 620 +++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 25 +- Dockerfile | 9 +- README.md | 3 +- build.rs | 29 ++ src/main.rs | 60 +--- src/routes/mod.rs | 12 + src/routes/request.rs | 78 ++++++ src/routes/response.rs | 57 ++++ src/routes/system.rs | 32 +++ src/server.rs | 16 ++ 11 files changed, 858 insertions(+), 83 deletions(-) create mode 100644 build.rs create mode 100644 src/routes/mod.rs create mode 100644 src/routes/request.rs create mode 100644 src/routes/response.rs create mode 100644 src/routes/system.rs create mode 100644 src/server.rs diff --git a/Cargo.lock b/Cargo.lock index 0abbd7d..7582276 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,64 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "arc-swap" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.68" @@ -25,17 +77,142 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "aws_lambda_events" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65991dbc3bfb586939ba1527eefdc99bc21157b6ec891f180fb1e16e2dddc7a9" +dependencies = [ + "base64", + "bytes", + "http", + "http-body", + "http-serde", + "query_map", + "serde", + "serde_json", +] + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-aws-lambda" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44dbc4a3315ff4e5aeddf2d3ee0372d282dfb3fc2b6d5f6c8b9b983e8880c48b" +dependencies = [ + "axum", + "bytes", + "http", + "hyper", + "lambda_http", + "tower", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + [[package]] name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -43,6 +220,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "time", + "wasm-bindgen", + "winapi", +] + [[package]] name = "combine" version = "4.6.6" @@ -57,12 +249,27 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "dotenvy" version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + [[package]] name = "fnv" version = "1.0.7" @@ -167,6 +374,12 @@ dependencies = [ "slab", ] +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "hermit-abi" version = "0.2.6" @@ -198,6 +411,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "http-serde" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e272971f774ba29341db2f686255ff8a979365a26fb9e4277f6b6d9ec0cdd5e" +dependencies = [ + "http", + "serde", +] + [[package]] name = "httparse" version = "1.8.0" @@ -226,13 +455,36 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.3.0" @@ -249,6 +501,71 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lambda_http" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b15e8ab48a5d8eab3110567008caad4d191924d1470b74c5c8b802b904b5a34" +dependencies = [ + "aws_lambda_events", + "base64", + "bytes", + "encoding_rs", + "futures", + "http", + "http-body", + "hyper", + "lambda_runtime", + "mime", + "percent-encoding", + "serde", + "serde_json", + "serde_urlencoded", + "url", +] + +[[package]] +name = "lambda_runtime" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db262b5e9548a371d9e1dd54ba094b75e3e46b345c11458ea2b4d4c54fbffa9" +dependencies = [ + "async-stream", + "bytes", + "futures", + "http", + "hyper", + "lambda_runtime_api_client", + "serde", + "serde_json", + "serde_path_to_error", + "tokio", + "tokio-stream", + "tower", + "tracing", +] + +[[package]] +name = "lambda_runtime_api_client" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "690c5ae01f3acac8c9c3348b556fc443054e9b7f1deaf53e9ebab716282bf0ed" +dependencies = [ + "http", + "hyper", + "tokio", + "tower-service", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -257,9 +574,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.144" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "lock_api" @@ -280,12 +597,33 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "matchit" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" + [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.6" @@ -294,10 +632,19 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.45.0", ] +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.15.0" @@ -308,6 +655,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -343,11 +699,31 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -357,18 +733,29 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] +[[package]] +name = "query_map" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4465aacac3bebc9484cf7a56dc8b2d7feacb657da6002a9198b4f7af4247a204" +dependencies = [ + "form_urlencoded", + "serde", + "serde_derive", +] + [[package]] name = "quote" -version = "1.0.27" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -401,9 +788,21 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.13" @@ -416,6 +815,59 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "serde" +version = "1.0.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "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_smol" version = "1.0.0" @@ -465,17 +917,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "syn" -version = "2.0.16" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "thread_local" version = "1.1.7" @@ -486,6 +954,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -503,11 +982,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.1" +version = "1.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -515,7 +994,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.3", "tokio-macros", "windows-sys 0.48.0", ] @@ -531,6 +1010,17 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.8" @@ -551,7 +1041,9 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ + "futures-core", "futures-util", + "pin-project", "pin-project-lite", "tokio", "tower-layer", @@ -559,6 +1051,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +dependencies = [ + "bitflags 2.4.0", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.2" @@ -663,12 +1173,72 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + [[package]] name = "winapi" version = "0.3.9" @@ -691,6 +1261,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -827,11 +1406,16 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" name = "world-id-bridge" version = "0.1.0" dependencies = [ + "axum", + "axum-aws-lambda", + "chrono", "dotenvy", - "hyper", + "lambda_http", "redis", + "serde", "tokio", "tower", + "tower-http", "tracing", "tracing-subscriber", ] diff --git a/Cargo.toml b/Cargo.toml index 633b223..c9b2050 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,26 @@ [package] -name = "world-id-bridge" -version = "0.1.0" +license = "MIT" edition = "2021" +version = "0.1.0" +name = "world-id-bridge" +authors = ["Miguel Piedrafita "] +repository = "https://github.com/worldcoin/wallet-bridge" +description = "A bridge between the World ID SDK and the World App" [dependencies] +axum = "0.6.20" +tower = "0.4.13" +serde = "1.0.183" dotenvy = "0.15.7" -tokio = { version = "1", features = ["full"] } +lambda_http = "0.8.1" +axum-aws-lambda = "0.5.0" tracing = { version = "0.1", features = ["log"] } -tower = { version = "0.4.13", features = ["make"] } -hyper = { version = "0.14.26", features = ["http1", "server", "tcp"] } +tokio = { version = "1.31.0", features = ["full"] } +tower-http = { version = "0.4.3", features = ["cors"] } redis = { version = "0.23.0", features = ["tokio-comp", "connection-manager"] } -tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] } +tracing-subscriber = { version = "0.3", default-features = false, features = [ + "fmt", +] } + +[build-dependencies] +chrono = "0.4.26" diff --git a/Dockerfile b/Dockerfile index 8124847..8148c97 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM rust:latest AS builder RUN update-ca-certificates -WORKDIR /world-id-bridge +WORKDIR /app COPY ./Cargo.toml . COPY ./Cargo.lock . @@ -25,9 +25,8 @@ RUN cargo build --release #################################################################################################### FROM gcr.io/distroless/cc -WORKDIR /world-id-bridge +WORKDIR /app -# Copy our build -COPY --from=builder /world-id-bridge/target/release/world-id-bridge /world-id-bridge/world-id-bridge +COPY --from=builder /app/target/release/world-id-bridge /app/world-id-bridge -CMD ["/world-id-bridge/world-id-bridge"] +CMD ["/app/world-id-bridge"] diff --git a/README.md b/README.md index e10ee2a..7d0a79b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ -# wallet-bridge -Establishes a very simple zero-knowledge bridge to pass World ID ZKPs from wallets to verifying apps. +# A bridge between the World ID SDK and the World App diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..7e41343 --- /dev/null +++ b/build.rs @@ -0,0 +1,29 @@ +use chrono::prelude::{DateTime, Utc}; +use std::process::Command; + +fn get_git_rev() -> Option { + let output = Command::new("git") + .args(["rev-parse", "--short", "HEAD"]) + .output() + .ok()?; + + if output.status.success() { + String::from_utf8(output.stdout).ok() + } else { + None + } +} + +fn get_compile_date() -> String { + let system_time = std::time::SystemTime::now(); + let date_time: DateTime = system_time.into(); + format!("{}", date_time.format("%+")) +} + +fn main() { + println!("cargo:rustc-env=STATIC_BUILD_DATE={}", get_compile_date()); + + if let Some(rev) = get_git_rev() { + println!("cargo:rustc-env=GIT_REV={}", rev); + } +} diff --git a/src/main.rs b/src/main.rs index 5f0c0c3..17ae487 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,48 +1,13 @@ -use dotenvy::dotenv; -use hyper::Method; -use hyper::{service::service_fn, Body, Request, Response, Server}; -use redis::{aio::ConnectionManager, AsyncCommands, Client}; -use std::convert::Infallible; -use std::{env, net::SocketAddr}; -use tower::make::Shared; - -async fn handle_request( - mut conn: ConnectionManager, - req: Request, -) -> Result, Infallible> { - let path = req.uri().path(); - let id = &path[1..].to_string(); - - if id.is_empty() { - return Ok(Response::builder().status(404).body(Body::empty()).unwrap()); - } +#![warn(clippy::all, clippy::pedantic, clippy::nursery)] - match *req.method() { - Method::GET => { - let Ok(value) = conn.get::<_, String>(id).await else { - return Ok(Response::builder().status(404).body(Body::empty()).unwrap()); - }; +use dotenvy::dotenv; +use redis::{aio::ConnectionManager, Client}; +use std::env; - Ok(Response::builder().status(200).body(value.into()).unwrap()) - } - Method::PUT => { - let Ok(value) = hyper::body::to_bytes(&mut req.into_body()).await else { - return Ok(Response::builder().status(400).body(Body::empty()).unwrap()); - }; +mod routes; +mod server; - if conn - .set_ex::<_, _, ()>(id, value.to_vec(), 600) - .await - .is_err() - { - return Ok(Response::builder().status(500).body(Body::empty()).unwrap()); - } - - Ok(Response::builder().status(201).body(Body::empty()).unwrap()) - } - _ => Ok(Response::builder().status(404).body(Body::empty()).unwrap()), - } -} +const EXPIRE_AFTER_SECONDS: usize = 60; #[tokio::main] async fn main() { @@ -60,14 +25,5 @@ async fn main() { .await .expect("Failed to create redis connection manager"); - let make_service = Shared::new(service_fn(move |req| handle_request(redis.clone(), req))); - - let addr: SocketAddr = SocketAddr::from(([0, 0, 0, 0], 3000)); - - let server = Server::bind(&addr).serve(make_service); - println!("Listening on http://{}", addr); - - if let Err(e) = server.await { - eprintln!("server error: {}", e); - } + server::start(redis).await; } diff --git a/src/routes/mod.rs b/src/routes/mod.rs new file mode 100644 index 0000000..0fdd6a7 --- /dev/null +++ b/src/routes/mod.rs @@ -0,0 +1,12 @@ +use axum::Router; + +mod request; +mod response; +mod system; + +pub fn handler() -> Router { + Router::new() + .merge(system::handler()) + .merge(request::handler()) + .merge(response::handler()) +} diff --git a/src/routes/request.rs b/src/routes/request.rs new file mode 100644 index 0000000..b95b448 --- /dev/null +++ b/src/routes/request.rs @@ -0,0 +1,78 @@ +use axum::{ + body::Bytes, + extract::Path, + http::{Method, StatusCode}, + routing::head, + Extension, Router, +}; +use redis::{aio::ConnectionManager, AsyncCommands}; +use tower_http::cors::{Any, CorsLayer}; + +use crate::EXPIRE_AFTER_SECONDS; + +const REQ_PREFIX: &str = "req:"; + +pub fn handler() -> Router { + let cors = CorsLayer::new() + .allow_methods([Method::PUT, Method::HEAD]) + .allow_origin(Any); + + Router::new().route( + "/request/:request_id", + head(has_request) + .get(get_request) + .put(insert_request) + .route_layer(cors), + ) +} + +async fn has_request( + Path(request_id): Path, + Extension(mut redis): Extension, +) -> StatusCode { + let Ok(exists) = redis + .exists::<_, bool>(format!("{REQ_PREFIX}{request_id}")) + .await + else { + return StatusCode::INTERNAL_SERVER_ERROR; + }; + + if exists { + StatusCode::OK + } else { + StatusCode::NOT_FOUND + } +} + +async fn get_request( + Path(request_id): Path, + Extension(mut redis): Extension, +) -> Result, StatusCode> { + let value = redis + .get_del::<_, Option>>(format!("{REQ_PREFIX}{request_id}")) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + value.ok_or(StatusCode::NOT_FOUND) +} + +async fn insert_request( + Path(request_id): Path, + Extension(mut redis): Extension, + body: Bytes, +) -> Result { + if !redis + .set_nx::<_, _, bool>(format!("{REQ_PREFIX}{request_id}"), body.to_vec()) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? + { + return Ok(StatusCode::CONFLICT); + } + + redis + .expire::<_, ()>(format!("{REQ_PREFIX}{request_id}"), EXPIRE_AFTER_SECONDS) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + Ok(StatusCode::CREATED) +} diff --git a/src/routes/response.rs b/src/routes/response.rs new file mode 100644 index 0000000..299a7ae --- /dev/null +++ b/src/routes/response.rs @@ -0,0 +1,57 @@ +use axum::{ + body::Bytes, + extract::Path, + http::{Method, StatusCode}, + routing::get, + Extension, Router, +}; +use redis::{aio::ConnectionManager, AsyncCommands}; +use tower_http::cors::{Any, CorsLayer}; + +use crate::EXPIRE_AFTER_SECONDS; + +const RES_PREFIX: &str = "res:"; + +pub fn handler() -> Router { + let cors = CorsLayer::new() + .allow_methods([Method::GET]) + .allow_origin(Any); + + Router::new().route( + "/response/:request_id", + get(get_response).put(insert_response).route_layer(cors), + ) +} + +async fn get_response( + Path(request_id): Path, + Extension(mut redis): Extension, +) -> Result, StatusCode> { + let value = redis + .get_del::<_, Option>>(format!("{RES_PREFIX}{request_id}")) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + value.ok_or(StatusCode::NOT_FOUND) +} + +async fn insert_response( + Path(request_id): Path, + Extension(mut redis): Extension, + body: Bytes, +) -> Result { + if !redis + .set_nx::<_, _, bool>(format!("{RES_PREFIX}{request_id}"), body.to_vec()) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? + { + return Ok(StatusCode::CONFLICT); + } + + redis + .expire::<_, ()>(&request_id, EXPIRE_AFTER_SECONDS) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + Ok(StatusCode::CREATED) +} diff --git a/src/routes/system.rs b/src/routes/system.rs new file mode 100644 index 0000000..023af56 --- /dev/null +++ b/src/routes/system.rs @@ -0,0 +1,32 @@ +use axum::{routing::get, Json, Router}; + +pub fn handler() -> Router { + Router::new().route("/", get(get_info)) +} + +#[derive(Debug, serde::Serialize)] +pub struct AppVersion { + semver: String, + rev: Option, + compile_time: String, +} + +#[derive(Debug, serde::Serialize)] +pub struct RootResponse { + /// Repository URL + pub repo_url: String, + /// Application version + pub version: AppVersion, +} + +#[allow(clippy::unused_async)] +async fn get_info() -> Json { + Json(RootResponse { + repo_url: "https://github.com/worldcoin/wallet-bridge".to_string(), + version: AppVersion { + semver: env!("CARGO_PKG_VERSION").to_string(), + compile_time: env!("STATIC_BUILD_DATE").to_string(), + rev: option_env!("GIT_REV").map(ToString::to_string), + }, + }) +} diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..ab52f31 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,16 @@ +use axum::Extension; +use axum_aws_lambda::LambdaLayer; +use redis::aio::ConnectionManager; +use tower::ServiceBuilder; + +use crate::routes; + +pub async fn start(redis: ConnectionManager) { + let router = routes::handler().layer(Extension(redis)); + + let app = ServiceBuilder::new() + .layer(LambdaLayer::default()) + .service(router); + + lambda_http::run(app).await.unwrap(); +}