From bfd580db1fcf0312c07f76a8b6454d4578b9a207 Mon Sep 17 00:00:00 2001 From: yaojianpin Date: Wed, 27 Sep 2023 14:29:30 +0800 Subject: [PATCH] add file routing support --- Cargo.lock | 419 ++++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 4 +- src/app.rs | 26 ++- src/db.rs | 26 +++ src/service.rs | 44 +++++ static/db.json | 10 +- static/image1.jpg | Bin 0 -> 15772 bytes static/json1.json | 3 + static/text1.txt | 1 + 9 files changed, 479 insertions(+), 54 deletions(-) create mode 100644 static/image1.jpg create mode 100644 static/json1.json create mode 100644 static/text1.txt diff --git a/Cargo.lock b/Cargo.lock index 73c955c..161a9bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "0.7.18" @@ -22,13 +37,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.56" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] @@ -55,7 +70,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b9496f0c1d1afb7a2af4338bbe1d969cddfead41d87a9fb3aaa6d0bbc7af648" dependencies = [ "async-trait", - "axum-core", + "axum-core 0.2.7", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit 0.5.0", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fb79c228270dcf2426e74864cabc94babb5dbab01a4314e702d2f16540e1591" +dependencies = [ + "async-trait", + "axum-core 0.3.4", "bitflags", "bytes", "futures-util", @@ -63,13 +109,15 @@ dependencies = [ "http-body", "hyper", "itoa", - "matchit", + "matchit 0.7.3", "memchr", "mime", "percent-encoding", "pin-project-lite", + "rustversion", "serde", "serde_json", + "serde_path_to_error", "serde_urlencoded", "sync_wrapper", "tokio", @@ -93,6 +141,56 @@ dependencies = [ "mime", ] +[[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 = "axum-streams" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3e367d27d8c1ce16fbd0d96ddf05105fd1147f5d35ffc55e254dab914e72e8" +dependencies = [ + "axum 0.6.7", + "bytes", + "cargo-husky", + "futures", + "futures-util", + "http", + "mime", + "tokio", + "tokio-stream", + "tokio-util", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -105,6 +203,21 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +[[package]] +name = "cargo-husky" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -138,7 +251,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -166,6 +279,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.21" @@ -173,6 +301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -181,6 +310,34 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.98", +] + [[package]] name = "futures-sink" version = "0.3.21" @@ -199,10 +356,16 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -216,6 +379,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "hashbrown" version = "0.12.3" @@ -293,7 +462,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.4", "tokio", "tower-service", "tracing", @@ -324,9 +493,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "lock_api" @@ -359,6 +528,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.5.0" @@ -381,23 +556,32 @@ dependencies = [ "unicase", ] +[[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.4" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "mock-server" -version = "1.1.0" +version = "1.2.0" dependencies = [ - "axum", + "axum 0.5.13", + "axum-streams", "clap", "once_cell", "rand", @@ -405,6 +589,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "tokio-util", "tower", "tower-http", "tracing", @@ -422,6 +607,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.13.0" @@ -454,7 +648,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -480,14 +674,14 @@ checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -510,7 +704,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.98", "version_check", ] @@ -527,18 +721,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.42" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -599,6 +793,18 @@ version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +[[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.10" @@ -613,22 +819,22 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.141" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7af873f2c95b99fcb0bd0fe622a43e29514658873c8ceba88c4cb88833a22500" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.141" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75743a150d003dd863b51dc809bcad0d73f2102c53632f1e954e738192a3413f" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] @@ -642,6 +848,16 @@ dependencies = [ "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" @@ -672,6 +888,15 @@ dependencies = [ "libc", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.9.0" @@ -688,6 +913,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "strsim" version = "0.10.0" @@ -705,6 +940,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sync_wrapper" version = "0.1.1" @@ -737,41 +983,50 @@ dependencies = [ [[package]] name = "tokio" -version = "1.20.1" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", "num_cpus", - "once_cell", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.4", "tokio-macros", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", +] + +[[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.3" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -824,9 +1079,9 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" [[package]] name = "tower-service" @@ -855,7 +1110,7 @@ checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -988,39 +1243,105 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index 17488f1..44a2598 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,10 +2,11 @@ authors = ["yao "] edition = "2021" name = "mock-server" -version = "1.1.0" +version = "1.2.0" [dependencies] axum = "0.5.13" +axum-streams = "0.9.1" clap = {version = "3.2.17", features = ["derive"]} once_cell = "1.13.0" rand = "0.8.5" @@ -13,6 +14,7 @@ regex = "1.6.0" serde = {version = "1.0.141", features = ["derive"]} serde_json = "1.0.82" tokio = {version = "1.20.1", features = ["full"]} +tokio-util = "0.7.9" tower = "0.4.13" tower-http = {version = "0.3.4", features = ["fs", "trace", "cors"]} tracing = "0.1.36" diff --git a/src/app.rs b/src/app.rs index cf3e545..7f919c3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -17,6 +17,7 @@ use tower_http::services::ServeDir; const DATA_QUERY_TPL: &str = "/api/([^/]*)$"; const DATA_ID_TPL: &str = "/api/([^/]*)/([^/]*)$"; +const FILE_ID_TPL: &str = "/file/([^/]*)$"; pub fn create(_: &Database) -> Router { let app = Router::new() @@ -28,6 +29,7 @@ pub fn create(_: &Database) -> Router { .put(put_data) .delete(delete_data), ) + .route("/file/:id", get(get_file).post(get_file)) .fallback(get_service(ServeDir::new("static")).handle_error(handle_error)); app @@ -101,8 +103,10 @@ pub fn proxy(db: &Database) -> Router { return Ok(res); } - let re = regex::Regex::new(DATA_ID_TPL).unwrap(); - if let Some(cap) = re.captures(&routing_value.to) { + if let Some(cap) = regex::Regex::new(DATA_ID_TPL) + .unwrap() + .captures(&routing_value.to) + { let data = cap.get(1).unwrap().as_str(); let id = cap.get(2).unwrap().as_str(); if !data.starts_with(":") { @@ -124,6 +128,24 @@ pub fn proxy(db: &Database) -> Router { return Ok(res); } + if let Some(cap) = regex::Regex::new(FILE_ID_TPL) + .unwrap() + .captures(&routing_value.to) + { + let id = cap.get(1).unwrap().as_str(); + if !id.starts_with(":") { + path.insert("id".to_string(), id.to_string()); + } + let res = match method { + &Method::GET => get_file(path, db).await.into_response(), + &Method::POST => get_file(path, db).await.into_response(), + _ => (StatusCode::METHOD_NOT_ALLOWED, "method not support") + .into_response(), + }; + + return Ok(res); + } + let res = (StatusCode::BAD_REQUEST, "bad request").into_response(); Ok(res) }), diff --git a/src/db.rs b/src/db.rs index cda0fad..e0abea2 100644 --- a/src/db.rs +++ b/src/db.rs @@ -8,10 +8,12 @@ use serde_json::Value; use std::collections::HashMap; use std::sync::Arc; use std::sync::RwLock; +use tracing::error; #[derive(Clone)] pub struct Database { collections: Arc>>, + files: HashMap, config: Arc, } @@ -27,6 +29,7 @@ impl<'a> Database { Database { config: Arc::new(DataConfig::default()), collections: Arc::new(RwLock::new(HashMap::new())), + files: HashMap::new(), } } @@ -47,6 +50,18 @@ impl<'a> Database { collections.insert(name, data); } + if let Some(file) = json.get("file") { + if let Some(file_list) = file.as_object() { + for (key, value) in file_list { + if let Some(path) = value.as_str() { + self.files.insert(key.to_string(), path.to_string()); + } else { + error!("file.{} must be string type", key); + } + } + } + } + self.config = Arc::new(DataConfig::new(&config)); DATA_CONFIG.set(self.config.clone()).unwrap(); } @@ -237,4 +252,15 @@ impl<'a> Database { Ok(Value::Bool(true)) } + + pub fn get_file( + &mut self, + path_map: &HashMap, + ) -> Result { + let file_id = path_map.get("id").unwrap(); + match self.files.get(file_id) { + Some(v) => Ok(v.clone()), + None => Err(format!("not found item by id {}", file_id)), + } + } } diff --git a/src/service.rs b/src/service.rs index 53bb38c..c186afb 100644 --- a/src/service.rs +++ b/src/service.rs @@ -1,12 +1,17 @@ use crate::models::Wrapper; use crate::Database; use crate::HashMap; +use axum::body::StreamBody; use axum::extract::Path; use axum::extract::Query; +use axum::http::header; +use axum::http::StatusCode; use axum::response::IntoResponse; use axum::Extension; use axum::Json; +use regex::Regex; use serde_json::Value; +use tokio_util::io::ReaderStream; macro_rules! wrapping { ($result: expr) => { @@ -59,3 +64,42 @@ pub async fn delete_data( ) -> impl IntoResponse { wrapping!(db.delete_data(&query), wrap) } + +pub async fn get_file( + Path(query): Path>, + Extension(mut db): Extension, +) -> impl IntoResponse { + match db.get_file(&query) { + Ok(ref path) => { + let file = match tokio::fs::File::open(path).await { + Ok(file) => file, + Err(err) => { + return Err((StatusCode::NOT_FOUND, format!("File not found: {}", err))) + } + }; + let stream = ReaderStream::new(file); + let body = StreamBody::new(stream); + + let mut content_type = "application/octet-stream".to_string(); + let file_path = std::path::Path::new(path); + if let Some(ext) = file_path.extension().and_then(|s| s.to_str()) { + if Regex::new("jpg|png|gif|jpeg").unwrap().is_match(ext) { + content_type = format!("image/{}; charset=utf-8", ext); + } + + if Regex::new("json").unwrap().is_match(ext) { + content_type = format!("application/{}; charset=utf-8", ext); + } + + if Regex::new("txt").unwrap().is_match(ext) { + content_type = format!("text/plain; charset=utf-8"); + } + } + + let headers = [(header::CONTENT_TYPE, content_type)]; + Ok((headers, body)) + } + + Err(err) => return Err((StatusCode::NOT_FOUND, err)), + } +} diff --git a/static/db.json b/static/db.json index e9091be..2d2edc4 100644 --- a/static/db.json +++ b/static/db.json @@ -3,8 +3,8 @@ "config": { "routing": { - "/fbpm_demo/api/expense/listByPageTask": { - "to": "/api/data2" + "/my_image/:id": { + "to": "/file/:id" }, "/a/b/c/:id": { "to": "/api/data/:id" @@ -96,5 +96,11 @@ "age|1-100": 20, "id|+1": 1 }] + }, + + "file": { + "image1": "./static/image1.jpg", + "text1": "./static/text1.txt", + "json1": "./static/json1.json" } } \ No newline at end of file diff --git a/static/image1.jpg b/static/image1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..41309b0ef2f5daa422ef395b3e41cf6b9c7faa23 GIT binary patch literal 15772 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 IO8;j5FClZt_5c6? literal 0 HcmV?d00001 diff --git a/static/json1.json b/static/json1.json new file mode 100644 index 0000000..ad7c4a2 --- /dev/null +++ b/static/json1.json @@ -0,0 +1,3 @@ +{ + "name": "Yao" +} \ No newline at end of file diff --git a/static/text1.txt b/static/text1.txt new file mode 100644 index 0000000..95d09f2 --- /dev/null +++ b/static/text1.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file