✨ Route and forward for http(s)
This commit is contained in:
		
							
								
								
									
										443
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										443
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -158,6 +158,12 @@ version = "3.14.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" | ||||
|  | ||||
| [[package]] | ||||
| name = "byteorder" | ||||
| version = "1.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" | ||||
|  | ||||
| [[package]] | ||||
| name = "bytes" | ||||
| version = "1.5.0" | ||||
| @@ -244,6 +250,16 @@ dependencies = [ | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "core-foundation" | ||||
| version = "0.9.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" | ||||
| dependencies = [ | ||||
|  "core-foundation-sys", | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "core-foundation-sys" | ||||
| version = "0.8.6" | ||||
| @@ -314,6 +330,12 @@ dependencies = [ | ||||
|  "syn 2.0.48", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "data-encoding" | ||||
| version = "2.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" | ||||
|  | ||||
| [[package]] | ||||
| name = "deranged" | ||||
| version = "0.3.11" | ||||
| @@ -390,6 +412,21 @@ version = "1.0.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" | ||||
|  | ||||
| [[package]] | ||||
| name = "foreign-types" | ||||
| version = "0.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" | ||||
| dependencies = [ | ||||
|  "foreign-types-shared", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "foreign-types-shared" | ||||
| version = "0.1.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" | ||||
|  | ||||
| [[package]] | ||||
| name = "form_urlencoded" | ||||
| version = "1.2.1" | ||||
| @@ -634,6 +671,23 @@ dependencies = [ | ||||
|  "itoa", | ||||
|  "pin-project-lite", | ||||
|  "tokio", | ||||
|  "want", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "hyper-tls" | ||||
| version = "0.6.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" | ||||
| dependencies = [ | ||||
|  "bytes", | ||||
|  "http-body-util", | ||||
|  "hyper", | ||||
|  "hyper-util", | ||||
|  "native-tls", | ||||
|  "tokio", | ||||
|  "tokio-native-tls", | ||||
|  "tower-service", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -651,6 +705,8 @@ dependencies = [ | ||||
|  "pin-project-lite", | ||||
|  "socket2", | ||||
|  "tokio", | ||||
|  "tower", | ||||
|  "tower-service", | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| @@ -683,6 +739,16 @@ version = "1.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" | ||||
|  | ||||
| [[package]] | ||||
| name = "idna" | ||||
| version = "0.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" | ||||
| dependencies = [ | ||||
|  "unicode-bidi", | ||||
|  "unicode-normalization", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "indexmap" | ||||
| version = "2.1.0" | ||||
| @@ -702,6 +768,12 @@ dependencies = [ | ||||
|  "generic-array", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "ipnet" | ||||
| version = "2.9.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" | ||||
|  | ||||
| [[package]] | ||||
| name = "itoa" | ||||
| version = "1.0.10" | ||||
| @@ -825,6 +897,24 @@ dependencies = [ | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "native-tls" | ||||
| version = "0.2.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" | ||||
| dependencies = [ | ||||
|  "lazy_static", | ||||
|  "libc", | ||||
|  "log", | ||||
|  "openssl", | ||||
|  "openssl-probe", | ||||
|  "openssl-sys", | ||||
|  "schannel", | ||||
|  "security-framework", | ||||
|  "security-framework-sys", | ||||
|  "tempfile", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "nix" | ||||
| version = "0.27.1" | ||||
| @@ -896,6 +986,50 @@ version = "0.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" | ||||
|  | ||||
| [[package]] | ||||
| name = "openssl" | ||||
| version = "0.10.62" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" | ||||
| dependencies = [ | ||||
|  "bitflags 2.4.1", | ||||
|  "cfg-if", | ||||
|  "foreign-types", | ||||
|  "libc", | ||||
|  "once_cell", | ||||
|  "openssl-macros", | ||||
|  "openssl-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "openssl-macros" | ||||
| version = "0.1.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn 2.0.48", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "openssl-probe" | ||||
| version = "0.1.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" | ||||
|  | ||||
| [[package]] | ||||
| name = "openssl-sys" | ||||
| version = "0.9.98" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" | ||||
| dependencies = [ | ||||
|  "cc", | ||||
|  "libc", | ||||
|  "pkg-config", | ||||
|  "vcpkg", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "ordered-multimap" | ||||
| version = "0.4.3" | ||||
| @@ -992,6 +1126,26 @@ dependencies = [ | ||||
|  "sha2", | ||||
| ] | ||||
|  | ||||
| [[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 2.0.48", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "pin-project-lite" | ||||
| version = "0.2.13" | ||||
| @@ -1004,6 +1158,12 @@ version = "0.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" | ||||
|  | ||||
| [[package]] | ||||
| name = "pkg-config" | ||||
| version = "0.3.28" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" | ||||
|  | ||||
| [[package]] | ||||
| name = "poem" | ||||
| version = "2.0.0" | ||||
| @@ -1011,6 +1171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "38a712ff53e257d60d3d22936c51cafa606552129d55539c8a400de44eff676d" | ||||
| dependencies = [ | ||||
|  "async-trait", | ||||
|  "base64 0.21.7", | ||||
|  "bytes", | ||||
|  "chrono", | ||||
|  "cookie", | ||||
| @@ -1042,6 +1203,7 @@ dependencies = [ | ||||
|  "tokio", | ||||
|  "tokio-metrics", | ||||
|  "tokio-stream", | ||||
|  "tokio-tungstenite", | ||||
|  "tokio-util", | ||||
|  "tracing", | ||||
|  "wildmatch", | ||||
| @@ -1231,6 +1393,45 @@ version = "0.8.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" | ||||
|  | ||||
| [[package]] | ||||
| name = "reqwest" | ||||
| version = "0.11.23" | ||||
| source = "git+https://github.com/seanmonstar/reqwest.git?branch=hyper-v1#7f4bfcbaaa8d332464709262c645893702b1ae84" | ||||
| dependencies = [ | ||||
|  "base64 0.21.7", | ||||
|  "bytes", | ||||
|  "encoding_rs", | ||||
|  "futures-core", | ||||
|  "futures-util", | ||||
|  "h2", | ||||
|  "http", | ||||
|  "http-body", | ||||
|  "http-body-util", | ||||
|  "hyper", | ||||
|  "hyper-tls", | ||||
|  "hyper-util", | ||||
|  "ipnet", | ||||
|  "js-sys", | ||||
|  "log", | ||||
|  "mime", | ||||
|  "native-tls", | ||||
|  "once_cell", | ||||
|  "percent-encoding", | ||||
|  "pin-project-lite", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "serde_urlencoded", | ||||
|  "system-configuration", | ||||
|  "tokio", | ||||
|  "tokio-native-tls", | ||||
|  "tower-service", | ||||
|  "url", | ||||
|  "wasm-bindgen", | ||||
|  "wasm-bindgen-futures", | ||||
|  "web-sys", | ||||
|  "winreg", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "rfc7239" | ||||
| version = "0.1.0" | ||||
| @@ -1245,15 +1446,23 @@ name = "roadsign" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "config", | ||||
|  "futures-util", | ||||
|  "http", | ||||
|  "hyper-util", | ||||
|  "lazy_static", | ||||
|  "poem", | ||||
|  "poem-openapi", | ||||
|  "rand", | ||||
|  "regex", | ||||
|  "reqwest", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "tokio", | ||||
|  "tokio-tungstenite", | ||||
|  "toml 0.8.8", | ||||
|  "tracing", | ||||
|  "tracing-subscriber", | ||||
|  "wildmatch", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -1311,12 +1520,44 @@ version = "1.0.16" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" | ||||
|  | ||||
| [[package]] | ||||
| name = "schannel" | ||||
| version = "0.1.23" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" | ||||
| dependencies = [ | ||||
|  "windows-sys 0.52.0", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "scopeguard" | ||||
| version = "1.2.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" | ||||
|  | ||||
| [[package]] | ||||
| name = "security-framework" | ||||
| version = "2.9.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" | ||||
| dependencies = [ | ||||
|  "bitflags 1.3.2", | ||||
|  "core-foundation", | ||||
|  "core-foundation-sys", | ||||
|  "libc", | ||||
|  "security-framework-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "security-framework-sys" | ||||
| version = "2.9.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" | ||||
| dependencies = [ | ||||
|  "core-foundation-sys", | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "semver" | ||||
| version = "1.0.21" | ||||
| @@ -1419,6 +1660,15 @@ dependencies = [ | ||||
|  "lazy_static", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "signal-hook-registry" | ||||
| version = "1.4.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "slab" | ||||
| version = "0.4.9" | ||||
| @@ -1493,6 +1743,27 @@ dependencies = [ | ||||
|  "futures-core", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "system-configuration" | ||||
| version = "0.5.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" | ||||
| dependencies = [ | ||||
|  "bitflags 1.3.2", | ||||
|  "core-foundation", | ||||
|  "system-configuration-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "system-configuration-sys" | ||||
| version = "0.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" | ||||
| dependencies = [ | ||||
|  "core-foundation-sys", | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tempfile" | ||||
| version = "3.9.0" | ||||
| @@ -1565,6 +1836,21 @@ dependencies = [ | ||||
|  "time-core", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tinyvec" | ||||
| version = "1.6.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" | ||||
| dependencies = [ | ||||
|  "tinyvec_macros", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tinyvec_macros" | ||||
| version = "0.1.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio" | ||||
| version = "1.35.1" | ||||
| @@ -1576,7 +1862,9 @@ dependencies = [ | ||||
|  "libc", | ||||
|  "mio", | ||||
|  "num_cpus", | ||||
|  "parking_lot", | ||||
|  "pin-project-lite", | ||||
|  "signal-hook-registry", | ||||
|  "socket2", | ||||
|  "tokio-macros", | ||||
|  "windows-sys 0.48.0", | ||||
| @@ -1605,6 +1893,16 @@ dependencies = [ | ||||
|  "tokio-stream", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-native-tls" | ||||
| version = "0.3.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" | ||||
| dependencies = [ | ||||
|  "native-tls", | ||||
|  "tokio", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-stream" | ||||
| version = "0.1.14" | ||||
| @@ -1616,6 +1914,18 @@ dependencies = [ | ||||
|  "tokio", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-tungstenite" | ||||
| version = "0.21.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" | ||||
| dependencies = [ | ||||
|  "futures-util", | ||||
|  "log", | ||||
|  "tokio", | ||||
|  "tungstenite", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-util" | ||||
| version = "0.7.10" | ||||
| @@ -1684,12 +1994,41 @@ dependencies = [ | ||||
|  "winnow", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tower" | ||||
| 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", | ||||
|  "tower-service", | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tower-layer" | ||||
| version = "0.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" | ||||
|  | ||||
| [[package]] | ||||
| name = "tower-service" | ||||
| version = "0.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" | ||||
|  | ||||
| [[package]] | ||||
| name = "tracing" | ||||
| version = "0.1.40" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" | ||||
| dependencies = [ | ||||
|  "log", | ||||
|  "pin-project-lite", | ||||
|  "tracing-attributes", | ||||
|  "tracing-core", | ||||
| @@ -1741,6 +2080,31 @@ dependencies = [ | ||||
|  "tracing-log", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "try-lock" | ||||
| version = "0.2.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" | ||||
|  | ||||
| [[package]] | ||||
| name = "tungstenite" | ||||
| version = "0.21.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" | ||||
| dependencies = [ | ||||
|  "byteorder", | ||||
|  "bytes", | ||||
|  "data-encoding", | ||||
|  "http", | ||||
|  "httparse", | ||||
|  "log", | ||||
|  "rand", | ||||
|  "sha1", | ||||
|  "thiserror", | ||||
|  "url", | ||||
|  "utf-8", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "typenum" | ||||
| version = "1.17.0" | ||||
| @@ -1762,12 +2126,27 @@ dependencies = [ | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "unicode-bidi" | ||||
| version = "0.3.14" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" | ||||
|  | ||||
| [[package]] | ||||
| name = "unicode-ident" | ||||
| version = "1.0.12" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" | ||||
|  | ||||
| [[package]] | ||||
| name = "unicode-normalization" | ||||
| version = "0.1.22" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" | ||||
| dependencies = [ | ||||
|  "tinyvec", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "universal-hash" | ||||
| version = "0.5.1" | ||||
| @@ -1784,18 +2163,50 @@ version = "0.2.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" | ||||
|  | ||||
| [[package]] | ||||
| name = "url" | ||||
| version = "2.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" | ||||
| dependencies = [ | ||||
|  "form_urlencoded", | ||||
|  "idna", | ||||
|  "percent-encoding", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "utf-8" | ||||
| version = "0.7.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" | ||||
|  | ||||
| [[package]] | ||||
| name = "valuable" | ||||
| version = "0.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" | ||||
|  | ||||
| [[package]] | ||||
| name = "vcpkg" | ||||
| version = "0.2.15" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" | ||||
|  | ||||
| [[package]] | ||||
| name = "version_check" | ||||
| version = "0.9.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" | ||||
|  | ||||
| [[package]] | ||||
| name = "want" | ||||
| version = "0.3.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" | ||||
| dependencies = [ | ||||
|  "try-lock", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasi" | ||||
| version = "0.11.0+wasi-snapshot-preview1" | ||||
| @@ -1827,6 +2238,18 @@ dependencies = [ | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasm-bindgen-futures" | ||||
| version = "0.4.40" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "js-sys", | ||||
|  "wasm-bindgen", | ||||
|  "web-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasm-bindgen-macro" | ||||
| version = "0.2.90" | ||||
| @@ -1856,6 +2279,16 @@ version = "0.2.90" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" | ||||
|  | ||||
| [[package]] | ||||
| name = "web-sys" | ||||
| version = "0.3.67" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" | ||||
| dependencies = [ | ||||
|  "js-sys", | ||||
|  "wasm-bindgen", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wildmatch" | ||||
| version = "2.3.0" | ||||
| @@ -2034,6 +2467,16 @@ dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "winreg" | ||||
| version = "0.50.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "windows-sys 0.48.0", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "yaml-rust" | ||||
| version = "0.4.5" | ||||
|   | ||||
							
								
								
									
										14
									
								
								Cargo.toml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Cargo.toml
									
									
									
									
									
								
							| @@ -7,12 +7,20 @@ edition = "2021" | ||||
|  | ||||
| [dependencies] | ||||
| config = { version = "0.13.4", features = ["toml"] } | ||||
| futures-util = "0.3.30" | ||||
| http = "1.0.0" | ||||
| hyper-util = { version = "0.1.2", features = ["full"] } | ||||
| lazy_static = "1.4.0" | ||||
| poem = { version = "2.0.0", features = ["tokio-metrics"] } | ||||
| poem-openapi = "4.0.0" | ||||
| poem = { version = "2.0.0", features = ["tokio-metrics", "websocket"] } | ||||
| poem-openapi = { version = "4.0.0", features = ["swagger-ui"] } | ||||
| rand = "0.8.5" | ||||
| regex = "1.10.2" | ||||
| reqwest = { git = "https://github.com/seanmonstar/reqwest.git", branch = "hyper-v1", version = "0.11.23" } | ||||
| serde = "1.0.195" | ||||
| serde_json = "1.0.111" | ||||
| tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "time"] } | ||||
| tokio = { version = "1.35.1", features = ["rt-multi-thread", "macros", "time", "full"] } | ||||
| tokio-tungstenite = "0.21.0" | ||||
| toml = "0.8.8" | ||||
| tracing = "0.1.40" | ||||
| tracing-subscriber = "0.3.18" | ||||
| wildmatch = "2.3.0" | ||||
|   | ||||
| @@ -5,5 +5,5 @@ id = "root" | ||||
| hosts = ["localhost"] | ||||
| paths = ["/"] | ||||
| [[locations.destinations]] | ||||
| id = "example" | ||||
| uri = "https://example.com" | ||||
| id = "echo" | ||||
| uri = "https://postman-echo.com/get" | ||||
|   | ||||
							
								
								
									
										23
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -2,10 +2,12 @@ mod config; | ||||
| mod proxies; | ||||
| mod sideload; | ||||
|  | ||||
| use poem::{listener::TcpListener, Route, Server}; | ||||
| use poem::{listener::TcpListener, Endpoint, EndpointExt, Route, Server}; | ||||
| use poem_openapi::OpenApiService; | ||||
| use tracing::{error, info, Level}; | ||||
|  | ||||
| use crate::proxies::route; | ||||
|  | ||||
| #[tokio::main] | ||||
| async fn main() -> Result<(), std::io::Error> { | ||||
|     // Setting up logging | ||||
| @@ -35,10 +37,19 @@ async fn main() -> Result<(), std::io::Error> { | ||||
|     }; | ||||
|  | ||||
|     // Proxies | ||||
|     let proxies_server = Server::new(TcpListener::bind( | ||||
|         config::C | ||||
|             .read() | ||||
|             .unwrap() | ||||
|             .get_string("listen.proxies") | ||||
|             .unwrap_or("0.0.0.0:80".to_string()), | ||||
|     )) | ||||
|     .run(route::handle.data(instance)); | ||||
|  | ||||
|     // Sideload | ||||
|     let sideload = OpenApiService::new(sideload::SideloadApi, "Sideload API", "1.0") | ||||
|         .server("http://localhost:3000/cgi"); | ||||
|     let sideload_ui = sideload.swagger_ui(); | ||||
|  | ||||
|     let sideload_server = Server::new(TcpListener::bind( | ||||
|         config::C | ||||
| @@ -47,11 +58,13 @@ async fn main() -> Result<(), std::io::Error> { | ||||
|             .get_string("listen.sideload") | ||||
|             .unwrap_or("0.0.0.0:81".to_string()), | ||||
|     )) | ||||
|     .run(Route::new().nest("/cgi", sideload)); | ||||
|     .run( | ||||
|         Route::new() | ||||
|             .nest("/cgi", sideload) | ||||
|             .nest("/swagger", sideload_ui), | ||||
|     ); | ||||
|  | ||||
|     tokio::try_join!(sideload_server)?; | ||||
|     tokio::try_join!(proxies_server, sideload_server)?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,23 +4,70 @@ use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Region { | ||||
|     id: String, | ||||
|     locations: Vec<Location>, | ||||
|     pub id: String, | ||||
|     pub locations: Vec<Location>, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Location { | ||||
|     id: String, | ||||
|     hosts: Vec<String>, | ||||
|     paths: Vec<String>, | ||||
|     headers: Option<Vec<HashMap<String, String>>>, | ||||
|     query_strings: Option<Vec<HashMap<String, String>>>, | ||||
|     destinations: Vec<Destination>, | ||||
|     pub id: String, | ||||
|     pub hosts: Vec<String>, | ||||
|     pub paths: Vec<String>, | ||||
|     pub headers: Option<HashMap<String, String>>, | ||||
|     pub queries: Option<Vec<String>>, | ||||
|     pub destinations: Vec<Destination>, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Destination { | ||||
|     id: String, | ||||
|     uri: String, | ||||
|     timeout: Option<u32>, | ||||
|     pub id: String, | ||||
|     pub uri: String, | ||||
|     pub timeout: Option<u32>, | ||||
|     pub weight: Option<u32>, | ||||
| } | ||||
|  | ||||
| pub enum DestinationType { | ||||
|     Hypertext, | ||||
|     StaticFiles, | ||||
|     Unknown, | ||||
| } | ||||
|  | ||||
| impl Destination { | ||||
|     pub fn get_type(&self) -> DestinationType { | ||||
|         match self.get_protocol() { | ||||
|             "http" | "https" => DestinationType::Hypertext, | ||||
|             "file" | "files" => DestinationType::StaticFiles, | ||||
|             _ => DestinationType::Unknown, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn get_protocol(&self) -> &str { | ||||
|         self.uri.as_str().splitn(2, "://").collect::<Vec<_>>()[0] | ||||
|     } | ||||
|  | ||||
|     pub fn get_queries(&self) -> &str { | ||||
|         self.uri.as_str().splitn(2, "?").collect::<Vec<_>>()[1] | ||||
|     } | ||||
|  | ||||
|     pub fn get_host(&self) -> &str { | ||||
|         (self.uri.as_str().splitn(2, "://").collect::<Vec<_>>()[1]) | ||||
|             .splitn(2, "?") | ||||
|             .collect::<Vec<_>>()[0] | ||||
|     } | ||||
|  | ||||
|     pub fn get_hypertext_uri(&self) -> Result<String, ()> { | ||||
|         match self.get_protocol() { | ||||
|             "http" => Ok("http://".to_string() + self.get_host()), | ||||
|             "https" => Ok("https://".to_string() + self.get_host()), | ||||
|             _ => Err(()), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn get_websocket_uri(&self) -> Result<String, ()> { | ||||
|         let url = self.uri.as_str().splitn(2, "://").collect::<Vec<_>>()[1]; | ||||
|         match self.get_protocol() { | ||||
|             "http" | "https" => Ok(url.replace("http", "ws")), | ||||
|             _ => Err(()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,13 @@ | ||||
| use poem::http::{HeaderMap, Uri}; | ||||
| use regex::Regex; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use wildmatch::WildMatch; | ||||
|  | ||||
| use self::config::Region; | ||||
| use self::config::{Location, Region}; | ||||
|  | ||||
| pub mod config; | ||||
| pub mod loader; | ||||
| pub mod route; | ||||
|  | ||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | ||||
| pub struct Instance { | ||||
| @@ -14,4 +18,44 @@ impl Instance { | ||||
|     pub fn new() -> Instance { | ||||
|         Instance { regions: vec![] } | ||||
|     } | ||||
|  | ||||
|     pub fn filter(&self, uri: &Uri, headers: &HeaderMap) -> Option<&Location> { | ||||
|         self.regions.iter().find_map(|region| { | ||||
|             region.locations.iter().find(|location| { | ||||
|                 let mut hosts = location.hosts.iter(); | ||||
|                 if !hosts.any(|item| { | ||||
|                     WildMatch::new(item.as_str()).matches(uri.host().unwrap_or("localhost")) | ||||
|                 }) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 let mut paths = location.paths.iter(); | ||||
|                 if !paths.any(|item| { | ||||
|                     uri.path().starts_with(item) | ||||
|                         || Regex::new(item.as_str()).unwrap().is_match(uri.path()) | ||||
|                 }) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 if let Some(val) = location.headers.clone() { | ||||
|                     match !val.keys().all(|item| { | ||||
|                         headers.get(item).unwrap() | ||||
|                             == location.headers.clone().unwrap().get(item).unwrap() | ||||
|                     }) { | ||||
|                         true => return false, | ||||
|                         false => (), | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 if let Some(val) = location.queries.clone() { | ||||
|                     let queries: Vec<&str> = uri.query().unwrap_or("").split('&').collect(); | ||||
|                     if !val.iter().all(|item| queries.contains(&item.as_str())) { | ||||
|                         return false; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 true | ||||
|             }) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										155
									
								
								src/proxies/route.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/proxies/route.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| use futures_util::{SinkExt, StreamExt}; | ||||
| use poem::{ | ||||
|     handler, | ||||
|     http::{HeaderMap, StatusCode, Uri}, | ||||
|     web::{websocket::WebSocket, Data}, | ||||
|     Body, Error, FromRequest, IntoResponse, Request, Response, Result, | ||||
| }; | ||||
| use rand::seq::SliceRandom; | ||||
| use reqwest::Method; | ||||
|  | ||||
| use lazy_static::lazy_static; | ||||
| use std::sync::Arc; | ||||
| use tokio::sync::RwLock; | ||||
| use tokio_tungstenite::connect_async; | ||||
|  | ||||
| use crate::proxies::config::{Destination, DestinationType}; | ||||
|  | ||||
| lazy_static! { | ||||
|     pub static ref CLIENT: reqwest::Client = reqwest::Client::new(); | ||||
| } | ||||
|  | ||||
| #[handler] | ||||
| pub async fn handle( | ||||
|     app: Data<&super::Instance>, | ||||
|     req: &Request, | ||||
|     uri: &Uri, | ||||
|     headers: &HeaderMap, | ||||
|     method: Method, | ||||
|     body: Body, | ||||
| ) -> Result<impl IntoResponse, Error> { | ||||
|     let location = match app.filter(uri, headers) { | ||||
|         Some(val) => val, | ||||
|         None => { | ||||
|             return Err(Error::from_string( | ||||
|                 "There are no region be able to respone this request.", | ||||
|                 StatusCode::NOT_FOUND, | ||||
|             )) | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let destination = location | ||||
|         .destinations | ||||
|         .choose_weighted(&mut rand::thread_rng(), |item| item.weight.unwrap_or(1)) | ||||
|         .unwrap(); | ||||
|  | ||||
|     async fn forward( | ||||
|         end: &Destination, | ||||
|         req: &Request, | ||||
|         ori: &Uri, | ||||
|         headers: &HeaderMap, | ||||
|         method: Method, | ||||
|         body: Body, | ||||
|     ) -> Result<impl IntoResponse, Error> { | ||||
|         // Handle websocket | ||||
|         if let Ok(ws) = WebSocket::from_request_without_body(req).await { | ||||
|             // Get uri | ||||
|             let Ok(uri) = end.get_websocket_uri() else { | ||||
|                 return Err(Error::from_string( | ||||
|                     "Proxy endpoint not configured to support websockets!", | ||||
|                     StatusCode::NOT_IMPLEMENTED, | ||||
|                 )); | ||||
|             }; | ||||
|  | ||||
|             // Build request | ||||
|             let mut ws_req = http::Request::builder().uri(&uri); | ||||
|             for (key, value) in headers.iter() { | ||||
|                 ws_req = ws_req.header(key, value); | ||||
|             } | ||||
|  | ||||
|             // Start the websocket connection | ||||
|             return Ok(ws | ||||
|                 .on_upgrade(move |socket| async move { | ||||
|                     let (mut clientsink, mut clientstream) = socket.split(); | ||||
|  | ||||
|                     // Start connection to server | ||||
|                     let (serversocket, _) = connect_async(ws_req.body(()).unwrap()).await.unwrap(); | ||||
|                     let (mut serversink, mut serverstream) = serversocket.split(); | ||||
|  | ||||
|                     let client_live = Arc::new(RwLock::new(true)); | ||||
|                     let server_live = client_live.clone(); | ||||
|  | ||||
|                     tokio::spawn(async move { | ||||
|                         while let Some(Ok(msg)) = clientstream.next().await { | ||||
|                             match serversink.send(msg.into()).await { | ||||
|                                 Err(_) => break, | ||||
|                                 _ => {} | ||||
|                             }; | ||||
|                             if !*client_live.read().await { | ||||
|                                 break; | ||||
|                             }; | ||||
|                         } | ||||
|  | ||||
|                         *client_live.write().await = false; | ||||
|                     }); | ||||
|  | ||||
|                     // Relay server messages to the client | ||||
|                     tokio::spawn(async move { | ||||
|                         while let Some(Ok(msg)) = serverstream.next().await { | ||||
|                             match clientsink.send(msg.into()).await { | ||||
|                                 Err(_) => break, | ||||
|                                 _ => {} | ||||
|                             }; | ||||
|                             if !*server_live.read().await { | ||||
|                                 break; | ||||
|                             }; | ||||
|                         } | ||||
|  | ||||
|                         *server_live.write().await = false; | ||||
|                     }); | ||||
|                 }) | ||||
|                 .into_response()); | ||||
|         } | ||||
|  | ||||
|         // Handle normal web request | ||||
|         match end.get_type() { | ||||
|             DestinationType::Hypertext => { | ||||
|                 let Ok(uri) = end.get_hypertext_uri() else { | ||||
|                     return Err(Error::from_string( | ||||
|                         "Proxy endpoint not configured to support web requests!", | ||||
|                         StatusCode::NOT_IMPLEMENTED, | ||||
|                     )); | ||||
|                 }; | ||||
|  | ||||
|                 let res = CLIENT | ||||
|                     .request(method, uri + ori.path() + ori.query().unwrap_or("")) | ||||
|                     .headers(headers.clone()) | ||||
|                     .body(body.into_bytes().await.unwrap()) | ||||
|                     .send() | ||||
|                     .await; | ||||
|  | ||||
|                 match res { | ||||
|                     Ok(result) => { | ||||
|                         let mut res = Response::default(); | ||||
|                         res.extensions().clone_from(&result.extensions()); | ||||
|                         result.headers().iter().for_each(|(key, val)| { | ||||
|                             res.headers_mut().insert(key, val.to_owned()); | ||||
|                         }); | ||||
|                         res.set_status(result.status()); | ||||
|                         res.set_version(result.version()); | ||||
|                         res.set_body(result.bytes().await.unwrap()); | ||||
|                         Ok(res) | ||||
|                     } | ||||
|  | ||||
|                     Err(error) => Err(Error::from_string( | ||||
|                         error.to_string(), | ||||
|                         error.status().unwrap_or(StatusCode::BAD_GATEWAY), | ||||
|                     )), | ||||
|                 } | ||||
|             } | ||||
|             _ => Err(Error::from_status(StatusCode::NOT_IMPLEMENTED)), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     forward(destination, req, uri, headers, method, body).await | ||||
| } | ||||
		Reference in New Issue
	
	Block a user