diff --git a/.github/workflows/release_ci.yml b/.github/workflows/release_ci.yml index d8aaeefc1..6d9c1847e 100644 --- a/.github/workflows/release_ci.yml +++ b/.github/workflows/release_ci.yml @@ -119,7 +119,6 @@ jobs: # (cd imageflow_riapi && cargo count --unsafe-statistics) # (cd imageflow_helpers && cargo count --unsafe-statistics) # (cd imageflow_types && cargo count --unsafe-statistics) - # (cd imageflow_server && cargo count --unsafe-statistics) # (cd c_components/lib && cargo count --unsafe-statistics) # - name: Test Release # run: cargo test --all --release @@ -576,7 +575,6 @@ jobs: run: | docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD" ./ci/travis_publish_docker_images.sh docker/imageflow_tool imazen/imageflow_tool - ./ci/travis_publish_docker_images.sh docker/imageflow_server_unsecured imazen/imageflow_server_unsecured env: PUBLISH_DOCKER: True DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} diff --git a/.idea/runConfigurations/demo_server.xml b/.idea/runConfigurations/demo_server.xml index 2b5b8d435..b28cbf227 100644 --- a/.idea/runConfigurations/demo_server.xml +++ b/.idea/runConfigurations/demo_server.xml @@ -1,7 +1,6 @@ - \ No newline at end of file + diff --git a/Cargo.lock b/Cargo.lock index d90177655..4c84e7a85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,13 +30,22 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] +[[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 = "ansi_term" version = "0.12.1" @@ -88,15 +97,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -118,12 +118,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - [[package]] name = "base64" version = "0.9.3" @@ -140,15 +134,6 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -167,9 +152,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] @@ -180,7 +165,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ - "lazy_static 1.4.0", + "lazy_static", "memchr", "regex-automata", "serde", @@ -188,15 +173,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "bytemuck" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5377c8865e74a160d21f29c2d40669f53286db6eab59b88540cbb12ffc8b835" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" [[package]] name = "byteorder" @@ -275,10 +260,11 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6127248204b9aba09a362f6c930ef6a78f2c1b2215f8a7b398c06e1083f17af0" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ + "iana-time-zone", "js-sys", "num-integer", "num-traits", @@ -304,9 +290,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.16" +version = "3.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9" +checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" dependencies = [ "atty", "bitflags", @@ -314,7 +300,7 @@ dependencies = [ "indexmap", "strsim 0.10.0", "termcolor", - "textwrap 0.15.0", + "textwrap 0.15.1", ] [[package]] @@ -326,15 +312,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - [[package]] name = "color_quant" version = "1.1.0" @@ -348,25 +325,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" dependencies = [ "atty", - "lazy_static 1.4.0", + "lazy_static", "winapi", ] -[[package]] -name = "conduit-mime-types" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ca30253581af809925ef68c2641cc140d6183f43e12e0af4992d53768bd7b8" -dependencies = [ - "rustc-serialize", -] - -[[package]] -name = "const_fn" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -391,9 +353,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -419,7 +381,7 @@ dependencies = [ "criterion-plot", "csv", "itertools", - "lazy_static 1.4.0", + "lazy_static", "num-traits", "oorandom", "plotters", @@ -466,26 +428,24 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cfg-if", "crossbeam-utils", "memoffset", - "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -537,25 +497,19 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" [[package]] name = "digest" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ "block-buffer", "crypto-common", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "dssim" -version = "3.2.0" +version = "3.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55fa7149ce6823593fe553fb388c07fb50d33e248e83c9096861c39bcd45f859" +checksum = "98ec20d49a0ab93384aa138604d52d325499638e24d6c7f79b92eec46533ddfc" dependencies = [ "dssim-core", "getopts", @@ -568,9 +522,9 @@ dependencies = [ [[package]] name = "dssim-core" -version = "3.2.3" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d037ca5a40f7f511ed15b7058cc7d4970746c5b4dd9c92b43be7e6ba3a5e126" +checksum = "c0286ae9482caf2cc3fb8ce55c5ff7dc1986425f36fd8423f00e38a83b4169fb" dependencies = [ "imgref", "itertools", @@ -586,9 +540,9 @@ checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" [[package]] name = "either" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "encoding_rs" @@ -604,34 +558,11 @@ name = "enum_derive" version = "0.1.7" source = "git+https://github.com/DanielKeep/rust-custom-derive.git#1252f258cdb9b7c9867f937c52c2f5c0e69a9c03" -[[package]] -name = "env_logger" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime", - "log 0.4.17", - "regex", - "termcolor", -] - -[[package]] -name = "error" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e606f14042bb87cc02ef6a14db6c90ab92ed6f62d87e69377bc759fd7987cc" -dependencies = [ - "traitobject", - "typeable", -] - [[package]] name = "evalchroma" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc56886adabea8a3c8091b7b71521d93dec644c347c0f5c912fe281fed5ea63" +checksum = "750cbea0b946cfa53b12dbc59922526cbefa96d7cb27ccd2bebbdf817271236b" dependencies = [ "imgref", "rgb", @@ -722,12 +653,11 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", - "percent-encoding 2.1.0", + "percent-encoding 2.2.0", ] [[package]] @@ -738,42 +668,42 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-core", "futures-io", @@ -838,9 +768,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -918,9 +848,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -928,15 +858,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error 1.2.3", -] - [[package]] name = "hyper" version = "0.10.16" @@ -1022,6 +943,19 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd911b35d940d2bd0bea0f9100068e5b97b51a1cbe13d13382f132e0365257a0" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "js-sys", + "wasm-bindgen", + "winapi", +] + [[package]] name = "idna" version = "0.1.5" @@ -1035,11 +969,10 @@ dependencies = [ [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -1115,7 +1048,7 @@ dependencies = [ "imgref", "itertools", "jpeg-decoder", - "lazy_static 1.4.0", + "lazy_static", "lcms2", "lcms2-sys", "libc", @@ -1135,9 +1068,9 @@ dependencies = [ "slotmap", "smallvec 1.9.0", "threadpool", - "time 0.3.12", + "time 0.3.14", "twox-hash", - "url 2.2.2", + "url 2.3.1", "uuid", ] @@ -1151,7 +1084,7 @@ dependencies = [ "chrono", "digest", "fnv", - "lazy_static 1.4.0", + "lazy_static", "libc", "mockito", "rand 0.8.5", @@ -1162,7 +1095,7 @@ dependencies = [ "serde_json", "sha2", "smallvec 1.9.0", - "time 0.3.12", + "time 0.3.14", "twox-hash", "unicase 2.6.0", "uuid", @@ -1190,61 +1123,18 @@ dependencies = [ "ieee754", "imageflow_helpers", "imageflow_types", - "lazy_static 1.4.0", + "lazy_static", "macro-attr", "option-filter", - "time 0.3.12", - "url 2.2.2", -] - -[[package]] -name = "imageflow_server" -version = "0.1.0" -dependencies = [ - "base64 0.13.0", - "bincode", - "blake2-rfc", - "chrono", - "clap 2.34.0", - "conduit-mime-types", - "env_logger", - "fnv", - "http", - "hyper 0.14.20", - "hyper-native-tls", - "imageflow_core", - "imageflow_helpers", - "imageflow_http_helpers", - "imageflow_riapi", - "imageflow_types", - "iron", - "lazy_static 1.4.0", - "libc", - "log 0.4.17", - "logger", - "lru-cache", - "mount 0.3.0 (git+https://github.com/iron/mount.git?rev=2c3d719be4c158d4ddbd8cdb402fafccdefec58c)", - "persistent", - "rand 0.6.5", - "regex", - "reqwest", - "router", - "serde", - "serde_derive", - "serde_json", - "staticfile", - "threadpool", - "time 0.2.27", - "twox-hash", - "url 1.7.2", - "wait-timeout", + "time 0.3.14", + "url 2.3.1", ] [[package]] name = "imageflow_tool_lib" version = "0.1.0" dependencies = [ - "clap 3.2.16", + "clap 3.2.22", "imageflow_core", "imageflow_helpers", "imageflow_http_helpers", @@ -1253,7 +1143,7 @@ dependencies = [ "serde", "serde_json", "threadpool", - "time 0.3.12", + "time 0.3.14", ] [[package]] @@ -1263,8 +1153,8 @@ dependencies = [ "chrono", "imageflow_helpers", "imgref", - "lazy_static 1.4.0", - "quick-error 2.0.1", + "lazy_static", + "quick-error", "regex", "rgb", "serde", @@ -1274,12 +1164,13 @@ dependencies = [ [[package]] name = "imagequant" -version = "4.0.1" +version = "4.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9c246b5e902559d1f619b08a08f872cb88b03afe21ca9ec0df146f2fb1d34d" +checksum = "75ee54f35d304758d5625121221ed2bd8258d022ff4b5d26b7b292e1ca0d5fc7" dependencies = [ "arrayvec 0.7.2", "noisy_float", + "num_cpus", "once_cell", "rayon", "rgb", @@ -1288,9 +1179,9 @@ dependencies = [ [[package]] name = "imgref" -version = "1.9.2" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6a8cd48d0dc604999b8beacfbfc2f4eb289a52af175029d4f79fb57b80c7d5" +checksum = "b2cf49df1085dcfb171460e4592597b84abe50d900fb83efb6e41b20fefd6c2c" [[package]] name = "indexmap" @@ -1298,7 +1189,7 @@ version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ - "autocfg 1.1.0", + "autocfg", "hashbrown", ] @@ -1317,29 +1208,11 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" -[[package]] -name = "iron" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2440ae846e7a8c7f9b401db8f6e31b4ea5e7d3688b91761337da7e054520c75b" -dependencies = [ - "conduit-mime-types", - "error", - "hyper 0.10.16", - "lazy_static 0.2.11", - "log 0.3.9", - "modifier", - "num_cpus", - "plugin", - "typemap", - "url 1.7.2", -] - [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -1358,9 +1231,9 @@ checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] @@ -1376,9 +1249,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -1389,12 +1262,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -[[package]] -name = "lazy_static" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" - [[package]] name = "lazy_static" version = "1.4.0" @@ -1413,9 +1280,9 @@ dependencies = [ [[package]] name = "lcms2-sys" -version = "3.1.9" +version = "3.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b74cd3659cc927b9933cd6ee9eab30123048da3b488cb492f9754d245c0714c" +checksum = "a9101fb5ea428c617afec10c309c4b19bd9b719d09f7909a912277f9a79dc2d4" dependencies = [ "cc", "dunce", @@ -1425,15 +1292,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.127" +version = "0.2.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b" +checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" [[package]] name = "libpng-sys" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "939658d8a33e52645ecfdc42500285c8b0fdeb26df10677c32abd13a1fc1d70c" +checksum = "b531eb8c558e697d1fc6a642b260426aa85ba4d054a8f0db66f5866918332674" dependencies = [ "cc", "dunce", @@ -1495,11 +1362,11 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] @@ -1534,25 +1401,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "logger" -version = "0.3.0" -source = "git+https://github.com/iron/logger.git?rev=0daead5fe10c3cd0c4738767c162dc63a59c3fb3#0daead5fe10c3cd0c4738767c162dc63a59c3fb3" -dependencies = [ - "iron", - "log 0.3.9", - "time 0.1.44", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "macro-attr" version = "0.2.1" @@ -1582,7 +1430,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -1602,9 +1450,9 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] @@ -1630,7 +1478,7 @@ dependencies = [ "assert-json-diff", "colored", "httparse", - "lazy_static 1.4.0", + "lazy_static", "log 0.4.17", "rand 0.8.5", "regex", @@ -1639,39 +1487,13 @@ dependencies = [ "similar", ] -[[package]] -name = "modifier" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" - -[[package]] -name = "mount" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32245731923cd096899502fc4c4317cfd09f121e80e73f7f576cf3777a824256" -dependencies = [ - "iron", - "sequence_trie", -] - -[[package]] -name = "mount" -version = "0.3.0" -source = "git+https://github.com/iron/mount.git?rev=2c3d719be4c158d4ddbd8cdb402fafccdefec58c#2c3d719be4c158d4ddbd8cdb402fafccdefec58c" -dependencies = [ - "iron", - "sequence_trie", -] - [[package]] name = "mozjpeg" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ffb6ffccac322edcde024a132d6312a4c3006729e81291123ed34c316eca7e" +checksum = "6c50976021d48f0824d019f68988c91be3b5cd3ef7f0581e2ff8d51251ad1fa2" dependencies = [ "arrayvec 0.7.2", - "fallible_collections", "libc", "mozjpeg-sys", "rgb", @@ -1679,9 +1501,9 @@ dependencies = [ [[package]] name = "mozjpeg-sys" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac69196a2b59950122d25194985c8070f9633ac01414dce0a48925346c70c3de" +checksum = "1cffedd1e63b8799eb112e2bd6c8a748c3c25d012501914f481c972e62ecf98d" dependencies = [ "cc", "dunce", @@ -1704,7 +1526,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" dependencies = [ - "lazy_static 1.4.0", + "lazy_static", "libc", "log 0.4.17", "openssl", @@ -1765,7 +1587,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-integer", "num-traits", ] @@ -1776,7 +1598,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-integer", "num-traits", ] @@ -1805,7 +1627,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-traits", ] @@ -1815,7 +1637,7 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-integer", "num-traits", ] @@ -1826,7 +1648,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-bigint 0.3.3", "num-integer", "num-traits", @@ -1838,7 +1660,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-bigint 0.4.3", "num-integer", "num-traits", @@ -1850,7 +1672,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -1883,9 +1705,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "oorandom" @@ -1895,9 +1717,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "openssl" -version = "0.10.41" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ "bitflags", "cfg-if", @@ -1927,11 +1749,11 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.75" +version = "0.9.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" +checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cc", "libc", "pkg-config", @@ -1952,9 +1774,9 @@ checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" [[package]] name = "os_str_bytes" -version = "6.2.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] name = "owning_ref" @@ -2018,19 +1840,9 @@ checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" [[package]] name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "persistent" -version = "0.4.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8fa0009c4f3d350281309909c618abddf10bb7e3145f28410782f6a5ec74c5" -dependencies = [ - "iron", - "plugin", -] +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "petgraph" @@ -2062,9 +1874,9 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plotters" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9428003b84df1496fb9d6eeee9c5f8145cb41ca375eb0dad204328888832811f" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", @@ -2081,49 +1893,28 @@ checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0918736323d1baff32ee0eade54984f6f201ad7e97d5cfb5d6ab4a358529615" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] -[[package]] -name = "plugin" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" -dependencies = [ - "typemap", -] - [[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quick-error" version = "2.0.1" @@ -2152,25 +1943,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", -] - [[package]] name = "rand" version = "0.8.5" @@ -2178,18 +1950,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", + "rand_chacha", + "rand_core 0.6.4", ] [[package]] @@ -2199,7 +1961,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -2219,82 +1981,20 @@ checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "rayon" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ - "autocfg 1.1.0", + "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -2364,9 +2064,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" +checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" dependencies = [ "base64 0.13.0", "bytes", @@ -2380,11 +2080,11 @@ dependencies = [ "hyper-tls", "ipnet", "js-sys", - "lazy_static 1.4.0", "log 0.4.17", "mime 0.3.16", "native-tls", - "percent-encoding 2.1.0", + "once_cell", + "percent-encoding 2.2.0", "pin-project-lite", "serde", "serde_json", @@ -2392,7 +2092,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tower-service", - "url 2.2.2", + "url 2.3.1", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2410,51 +2110,19 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b221de559e4a29df3b957eec92bc0de6bc8eaf6ca9cfed43e5e1d67ff65a34" +checksum = "3603b7d71ca82644f79b5a06d1220e9a58ede60bd32255f698cb1af8838b8db3" dependencies = [ "bytemuck", ] -[[package]] -name = "route-recognizer" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea509065eb0b3c446acdd0102f0d46567dc30902dc0be91d6552035d92b0f4f8" - -[[package]] -name = "router" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b1797ff166029cb632237bb5542696e54961b4cf75a324c6f05c9cf0584e4e" -dependencies = [ - "iron", - "route-recognizer", - "url 1.7.2", -] - [[package]] name = "rustc-demangle" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "rustface" version = "0.1.7" @@ -2492,7 +2160,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ - "lazy_static 1.4.0", + "lazy_static", "windows-sys", ] @@ -2504,9 +2172,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -2525,32 +2193,11 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "sequence_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c915714ca833b1d4d6b8f6a9d72a3ff632fe45b40a8d184ef79c81bec6327eed" - [[package]] name = "serde" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] @@ -2567,9 +2214,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -2578,9 +2225,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa 1.0.3", "ryu", @@ -2599,15 +2246,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - [[package]] name = "sha1_smol" version = "1.0.0" @@ -2616,9 +2254,9 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", @@ -2637,7 +2275,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -2666,9 +2304,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -2680,82 +2318,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check 0.9.4", -] - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "staticfile" -version = "0.3.1" -source = "git+https://github.com/onur/staticfile?rev=9f2ff7201eda648128c92e3f5597c587f0629f51#9f2ff7201eda648128c92e3f5597c587f0629f51" -dependencies = [ - "iron", - "log 0.3.9", - "mount 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.44", - "url 1.7.2", -] - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "strsim" version = "0.8.0" @@ -2770,9 +2338,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" dependencies = [ "proc-macro2", "quote", @@ -2813,9 +2381,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" [[package]] name = "thread_local" @@ -2848,53 +2416,14 @@ dependencies = [ [[package]] name = "time" -version = "0.2.27" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check 0.9.4", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b7cc93fc23ba97fde84f7eea56c55d1ba183f495c6715defdfc7b9cb8c870f" -dependencies = [ - "js-sys", "libc", "num_threads", ] -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn", -] - [[package]] name = "tinytemplate" version = "1.2.1" @@ -2922,17 +2451,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.20.1" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ - "autocfg 1.1.0", + "autocfg", "bytes", "libc", "memchr", "mio", "num_cpus", - "once_cell", "pin-project-lite", "socket2", "winapi", @@ -2962,9 +2490,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -3043,15 +2571,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -[[package]] -name = "typemap" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" -dependencies = [ - "unsafe-any", -] - [[package]] name = "typenum" version = "1.15.0" @@ -3084,39 +2603,30 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" [[package]] name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "unsafe-any" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" -dependencies = [ - "traitobject", -] +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "url" @@ -3131,14 +2641,13 @@ dependencies = [ [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", - "idna 0.2.3", - "matches", - "percent-encoding 2.1.0", + "idna 0.3.0", + "percent-encoding 2.2.0", ] [[package]] @@ -3175,15 +2684,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - [[package]] name = "walkdir" version = "2.3.2" @@ -3219,9 +2719,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3229,9 +2729,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log 0.4.17", @@ -3244,9 +2744,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -3256,9 +2756,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3266,9 +2766,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -3279,15 +2779,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "web-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index c370e15a9..eb9b51fd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ members = [ "imageflow_abi", "imageflow", "imageflow_tool", - "imageflow_server", "c_components", "c_components/tests", ] diff --git a/README.md b/README.md index a9725ea39..cc552ff88 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![tests](https://github.com/imazen/imageflow/workflows/Test/badge.svg?branch=main)](https://github.com/imazen/imageflow/actions?query=workflow%3ATest) [![state: release candidate](https://img.shields.io/badge/state-release%E2%80%93candidate-yellow.svg)](#flaws) [![Docker Pulls](https://img.shields.io/docker/pulls/imazen/imageflow_tool.svg)](https://hub.docker.com/r/imazen/imageflow_tool/) -[![Docker Pulls](https://img.shields.io/docker/pulls/imazen/imageflow_server_unsecured.svg)](https://hub.docker.com/r/imazen/imageflow_server_unsecured/) [![view releases](https://img.shields.io/badge/-download%20binaries%20for%20windows,%20mac,%20or%20linux-green.svg)](https://github.com/imazen/imageflow/releases) [![license: Choose AGPLv3 or Commercial](https://img.shields.io/badge/license-Choose%20AGPLv3%20or%20Commercial-green.svg)](https://imageresizing.net/pricing) @@ -57,9 +56,9 @@ By default, imageflow_tool prints a JSON response to stdout. You write this to d `--debug-package` will create a .zip file to reproduce problematic behavior with both `v1/build` and `v1/querystring`. Please submit bug reports; we try to make it easy. -## Using imageflow_server for dynamic imaging +## Using Imageflow.Server for dynamic imaging -`imageflow_server start --demo` +NOTE: imageflow_server has been removed as the underlying web framework (iron) is abandoned and no longer secure. For the last few years we have suggested moving to the production-ready [Imageflow.Server product](https://github.com/imazen/imageflow-dotnet-server), which also offers docker deployment (but we suggest your own dockerfile to permit configration) Now you can edit images from HTML... and use srcset without headache. @@ -155,7 +154,6 @@ You can also build using `cargo` directly, although this will place binaries in * `cargo test --all` to test Imageflow in debug (slooow) mode * `cargo build --package imageflow_abi --release` to compile `libimageflow/imageflow.dll` * `cargo build --package imageflow_tool --release` to compile `imageflow_tool(.exe)` - * `cargo build --package imageflow_server --release` to compile `imageflow_server(.exe)` * `cargo build --all --release` to compile everything in release mode * `cargo doc --no-deps --all --release` to generate documentation. diff --git a/build.sh b/build.sh index e3f982c1c..553fa1ec3 100755 --- a/build.sh +++ b/build.sh @@ -108,7 +108,6 @@ if [[ "$IMAGEFLOW_BUILD_OVERRIDE" == 'codestats' ]]; then (cd imageflow_riapi && cargo count --unsafe-statistics) (cd imageflow_helpers && cargo count --unsafe-statistics) (cd imageflow_types && cargo count --unsafe-statistics) - (cd imageflow_server && cargo count --unsafe-statistics) (cd c_components/lib && cargo count --unsafe-statistics) ) exit 0 @@ -290,9 +289,6 @@ export TEST_RELEASE="${TEST_RELEASE:-$BUILD_RELEASE}" # Rebuild final Rust artifacts (not deps) export CLEAN_RUST_TARGETS="${CLEAN_RUST_TARGETS:-False}" -# Ignored -export IMAGEFLOW_SERVER=True - # Chooses values for ARTIFACT_UPLOAD_PATH and DOCS_UPLOAD_DIR if they are empty export UPLOAD_BY_DEFAULT="${UPLOAD_BY_DEFAULT:-False}" diff --git a/ci/cloud/README.md b/ci/cloud/README.md index 09aeac467..ad200cc6f 100644 --- a/ci/cloud/README.md +++ b/ci/cloud/README.md @@ -1,5 +1,9 @@ # Prereq + +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead + + 1. jq and doctl must be installed. 2. `doctl auth init` 3. Put the right SSH fingerprint in use_key.txt @@ -58,4 +62,4 @@ doctl compute size list # m-128gb 131072 16 340 960.00 1.428570 # m-224gb 229376 32 500 1680.00 2.500000 doctl compute droplet list -``` \ No newline at end of file +``` diff --git a/ci/packaging_extras/install.sh b/ci/packaging_extras/install.sh index ffce50095..55da8ac59 100755 --- a/ci/packaging_extras/install.sh +++ b/ci/packaging_extras/install.sh @@ -14,13 +14,12 @@ fi # Set INSTALL_BASE to customize install location export INSTALL_BASE="${INSTALL_BASE:-/usr/local}" -if [[ ! -e "./libimageflow.${DLL_EXT}" || ! -e "./imageflow_tool" || ! -e "./imageflow_server" ]]; then - echo Cannot install - libimageflow, imageflow_tool, or imageflow_server not found +if [[ ! -e "./libimageflow.${DLL_EXT}" || ! -e "./imageflow_tool" " ]]; then + echo Cannot install - libimageflow or imageflow_tool not found exit 1; fi cp "./libimageflow.${DLL_EXT}" "${INSTALL_BASE}/lib/" cp "./imageflow_tool" "${INSTALL_BASE}/bin/" -cp "./imageflow_server" "${INSTALL_BASE}/bin/" cp "./imageflow.h" "${INSTALL_BASE}/include/imageflow.h" -echo "Installed libimageflow, imageflow_tool, and imageflow_server" +echo "Installed libimageflow and imageflow_tool" exit 0; diff --git a/ci/travis_run.sh b/ci/travis_run.sh index 81d01b2cb..e3b439532 100755 --- a/ci/travis_run.sh +++ b/ci/travis_run.sh @@ -45,7 +45,6 @@ printf "travis_run.sh: " # TEST_C_DEBUG_BUILD # TEST_RUST # CLEAN_RUST_TARGETS -# IMAGEFLOW_SERVER # COVERAGE # COVERALLS # COVERALLS_TOKEN diff --git a/docker/imageflow_base_os/README.md b/docker/imageflow_base_os/README.md index 44679c687..b78741eae 100644 --- a/docker/imageflow_base_os/README.md +++ b/docker/imageflow_base_os/README.md @@ -1,10 +1,10 @@ ## imazen/imageflow_base_os -* This image should contain the runtime dependencies needed by imageflow_server and imageflow_tool. +* This image should contain the runtime dependencies needed by imageflow_tool. * It should also contain wget, for use in child dockerfiles * RUST_BACKTRACE=1 It should be rebuilt every commit, master -> latest, (v[0-9].*) -> $1 -ubuntu:bionic with imageflow user account - updated with sudo wget libcurl4-openssl-dev curl libssl-dev ca-certificates libpng-dev \ No newline at end of file +ubuntu:bionic with imageflow user account - updated with sudo wget libcurl4-openssl-dev curl libssl-dev ca-certificates libpng-dev diff --git a/docker/imageflow_server_unsecured/Dockerfile b/docker/imageflow_server_unsecured/Dockerfile index 4d9abceb9..2d27b53b3 100644 --- a/docker/imageflow_server_unsecured/Dockerfile +++ b/docker/imageflow_server_unsecured/Dockerfile @@ -1,5 +1,8 @@ FROM imazen/imageflow_base_os +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead + + MAINTAINER Lilith River ARG IMAGEFLOW_DOWNLOAD_URL_TAR_GZ diff --git a/docker/imageflow_server_unsecured/README.md b/docker/imageflow_server_unsecured/README.md index b79723440..11a3e8203 100644 --- a/docker/imageflow_server_unsecured/README.md +++ b/docker/imageflow_server_unsecured/README.md @@ -1,6 +1,9 @@ ## imageflow_server_unsecured +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead + + No HTTPS support, no TLS, no NGINX proxy. Just imageflow_server, that's it. Compiled for Sandy Bridge and higher architectures Starts the demo server by default on port 39876 @@ -44,4 +47,4 @@ FLAGS: -h, --help Prints help information --show-compilation-info Show all the information stored in this executable about the environment in which it was compiled. -V, --version Prints version information -``` \ No newline at end of file +``` diff --git a/docker/imageflow_server_unsecured/docker-compose.yml b/docker/imageflow_server_unsecured/docker-compose.yml index bc5f9d0ca..faa93e956 100644 --- a/docker/imageflow_server_unsecured/docker-compose.yml +++ b/docker/imageflow_server_unsecured/docker-compose.yml @@ -1,3 +1,6 @@ + +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead + imageflow: entrypoint: '/bin/sh -c "sudo chown -R imageflow /home/imageflow/ && /home/imageflow/imageflow_server start --demo --bind-address 0.0.0.0 --port 3000 --data-dir /home/imageflow/data/"' environment: @@ -6,4 +9,4 @@ imageflow: ports: - '3000:3000' volumes: - - 'imageflow_data:/home/imageflow/data' \ No newline at end of file + - 'imageflow_data:/home/imageflow/data' diff --git a/docker/imageflow_server_unsecured/helm_chart/README.MD b/docker/imageflow_server_unsecured/helm_chart/README.MD index ea20f7ae2..0f179773e 100644 --- a/docker/imageflow_server_unsecured/helm_chart/README.MD +++ b/docker/imageflow_server_unsecured/helm_chart/README.MD @@ -1,5 +1,8 @@ # Imageflow Helm Chart +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead + + This is a heml deployment chart for kubernetes. The chart pulls and deploys the image with the configuration options in Values.yaml diff --git a/docker/imageflow_server_unsecured/helm_chart/values.yaml b/docker/imageflow_server_unsecured/helm_chart/values.yaml index f1ca39358..517e54f5c 100644 --- a/docker/imageflow_server_unsecured/helm_chart/values.yaml +++ b/docker/imageflow_server_unsecured/helm_chart/values.yaml @@ -1,3 +1,7 @@ + +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead + + # Default values for imageflow. # This is a YAML-formatted file. # Declare variables to be passed into your templates. diff --git a/docker/proxied_stack/other.txt b/docker/proxied_stack/other.txt index c02051a6f..fa22f79c8 100644 --- a/docker/proxied_stack/other.txt +++ b/docker/proxied_stack/other.txt @@ -1,3 +1,4 @@ +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead diff --git a/docker/proxied_stack/stackfile.yml b/docker/proxied_stack/stackfile.yml index 76083e290..c328625f3 100644 --- a/docker/proxied_stack/stackfile.yml +++ b/docker/proxied_stack/stackfile.yml @@ -1,3 +1,6 @@ +# Obsolete! Use https://github.com/imazen/imageflow-dotnet-server instead + + volume-config: image: imazen/nginx_template autoredeploy: false diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 78ccdae29..a74ad277f 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -29,4 +29,3 @@ - [Copy Rectangle](json/copy_rect_to_canvas.md) - [Draw Image Exact](json/draw_image_exact.md) - [Using imageflow_tool](imageflow_tool.md) -- [Using imageflow_server](imageflow_server.md) diff --git a/docs/src/introduction.md b/docs/src/introduction.md index 64d294139..2e1bc3014 100644 --- a/docs/src/introduction.md +++ b/docs/src/introduction.md @@ -2,7 +2,7 @@ * Imageflow can be used as a library (libimageflow or [imageflow-dotnet](https://github.com/imazen/imageflow-dotnet)) * Imageflow can be used as a command-line tool for scripting ([imageflow_tool](imageflow_tool.md)) -* Imageflow can be used as an HTTP server ([imageflow_server](imageflow_server.md)) +* Imageflow can be used as an HTTP server ([Imageflow.Server](https://github.com/imazen/imageflow-dotnet-server)) All share support for the querystring API ([RIAPI](querystring/introduction.md)). libimageflow, imageflow-dotnet, and imageflow_tool currently support the [JSON API](json/introduction.md). diff --git a/imageflow_server/.gitignore b/imageflow_server/.gitignore deleted file mode 100644 index e5c5d806c..000000000 --- a/imageflow_server/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/bin/ -/self_tests/ -/server_tests/ -/server_tests_heavy/ -/imageflow_data/ -/Dockerfile -/imageflow_tool -/imageflow_server \ No newline at end of file diff --git a/imageflow_server/Cargo.toml b/imageflow_server/Cargo.toml deleted file mode 100644 index 44d01c510..000000000 --- a/imageflow_server/Cargo.toml +++ /dev/null @@ -1,77 +0,0 @@ -[package] -name = "imageflow_server" -version = "0.1.0" -authors = ["Lilith River "] -workspace = "../" -edition = "2018" - - - -[dependencies] -libc = "0.2" - -# time -time = "0.2" -chrono = "0.4" - -# serialization -serde = "1" -serde_json = "1" -serde_derive = "1" -base64 = "0.13" - -#lazy static -lazy_static = "1" - -# fast hashes, crypto hashs -twox-hash = "1" -fnv = "*" -blake2-rfc = "*" - -## Crate-specific dependencies - - -clap = "2" - -imageflow_core = { path = "../imageflow_core", version = "*" } -imageflow_types = { path = "../imageflow_types", version = "*" } -imageflow_helpers = { path = "../imageflow_helpers", version = "*" } -imageflow_riapi = { path = "../imageflow_riapi", version = "*" } -imageflow_http_helpers = { path = "../imageflow_http_helpers", version = "*" } - - -rand = "0.6" -lru-cache = "0.1" -regex = "1" -log="0.4" -env_logger="0.7" -wait-timeout = "0.2" - -bincode = "1" -staticfile = { git= "https://github.com/onur/staticfile", rev= "9f2ff7201eda648128c92e3f5597c587f0629f51" } -conduit-mime-types = "0.7" -router = "=0.5" -iron = "=0.5.1" -persistent = "=0.4" -hyper = { version = "0.14", default-features = false } -threadpool = "1.8" -url="1" -hyper-native-tls="0.3" -reqwest="0.11" -http="*" - -[[bin]] -name = "imageflow_server" -path = "src/main.rs" -doc = false - -[dependencies.mount] -git = "https://github.com/iron/mount.git" -rev = "2c3d719be4c158d4ddbd8cdb402fafccdefec58c" - -[dependencies.logger] -git = "https://github.com/iron/logger.git" -rev = "0daead5fe10c3cd0c4738767c162dc63a59c3fb3" - -[features] -nightly = ["imageflow_core/nightly", "imageflow_helpers/nightly"] diff --git a/imageflow_server/README.md b/imageflow_server/README.md deleted file mode 100644 index b7ba6e446..000000000 --- a/imageflow_server/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# imageflow_server - -If you're compiling, use `cargo run --bin imageflow_server` instead of `imageflow_server`. - -Currently we have 4 mount providers: -* ir4_http - ImageResizer4 compatible querystring API, pulling originals from a remote server -* ir4_local - ImageResizer4 compatible querystring API, pulling from disk -* static - static file server -* permacache_proxy - static file proxy with permanent caching (no invalidation, ever) - -* `imageflow_server start --demo` -* `imageflow_server start --port 80 --data-dir=./imageflow_data --mount /ir4/local/:ir4_local:./img/ --mount /ir4/remote/:ir4_http:http:://remote.com/img/ --mount` -* `imageflow_server start --port 80 --data-dir=./imageflow_data --mount /js/:static:./js --mount /proxy_asis/:permacache_proxy:http:://remote.com/static/:360` -* `imageflow_server diagnose --show-compilation-info` - -http://localhost:3004/ir4/proxy_unsplash/photo-1422493757035-1e5e03968f95?width=600 \ No newline at end of file diff --git a/imageflow_server/demo/index.html b/imageflow_server/demo/index.html deleted file mode 100644 index dd6784d17..000000000 --- a/imageflow_server/demo/index.html +++ /dev/null @@ -1,205 +0,0 @@ - - - Sample page - - - -

ImageResizer 4 Examples

-

Hover over the images to view the querystrings used. All commands can be combined.

- -
-
-

Resizing using maxwidth and/or maxheight

-

Aspect ratio is always maintained with maxwidth and maxheight. The image is scaled to fit within those bounds.

- - - -
-
-

Resizing using width and height

-

Specifying only one of width or height will behave the same as using maxwidth - or maxheight. The difference is when you specify both.

-

Specifying both width and height will force the image to those exact dimensions, unless the - image is already smaller (see scale). This is done by adding whitespace to the image. To center and crop instead, use - &mode=crop. To lose aspect ratio and fill the specified rectangle, use &mode=stretch.

- - - - - -

Scaling

-

By default, images are not upscaled. If an image is already smaller than width/height/maxwidth/maxheight, it is not resized. - To upscale images, use ?scale=both. ?scale=downscaleonly is the default.

- - - -
- You can control the color by setting &bgcolor=color|hex. - -

Upscaling the canvas is sometimes desired instead of upscaling the image when it is smaller than the requested size. Use ?scale=upscalecanvas to achieve this effect.

- - - -

Cropping

-

To enable cropping, you can use &crop=auto, which minimally crops and centers to preserve aspect ratio, or custom cropping.

-

&crop=(x1,y1,x2,y2) specifies the rectangle to crop on the image. You can still resize and modify the cropped portion - using the other commands as normal. Negative coordinates are relative to the bottom-right corner - - which makes it easy to trim off a 50-pixel border by specifying &crop=(50,50,-50,-50).

- - - - -

Cropping can also be done against arbitrary scales, which is very useful for jQuery jCrop interfaces. - Example to crop 10% off each edge: crop=(.1,.1,.9,.9)&cropxunits=1&cropyunits=1 - Example to crop an image relative to the 'final' coordinates, without knowing the original size. Ex. crop=(20,30,400,350)&cropxunits=500&cropxunits=390

- -

Rotation

-

rotate=90|180|280

- - - - - - -

Flipping

-

You can horizontally or vertically flip an image, as well as both. &flip=h|v|both

- -
- - -

Source flipping

-

Since normal flipping applies after rotation and cropping occur, it can be - difficult to work with if you are just wanting the source image flipped before the other - adjustments are applied. To flip the source prior to work, use &sFlip=h|v|both.

-

Note how the same crop coordinates return different sections of the image. This is because the source image is flipped before *anything* happens.

- - - -

Stretching

-

To stretch an image to width and height, use &stretch=fill.

- - - - -

Output format

-

Jpeg compression levels 0-100 (&quality=0-100)

- - - - - - - - - - - - - -

Transparent GIFs and PNGs

-

Transparency is maintained when resizing PNGs

- - - -

Transparency is maintained when resizing WebP images and converting PNG to WebP

- - -

Jpegs can be converted to webp

- - - -

Whitespace cropping

- - - - -
- - - - - - diff --git a/imageflow_server/dockerize.sh b/imageflow_server/dockerize.sh deleted file mode 100755 index e9a6ed43a..000000000 --- a/imageflow_server/dockerize.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/bash -set -e - -# The purpose of this script is to compile Imageflow locally (or in a CI simulation docker container), then copy it to *another* docker container, and run a basic smoke test. -# This can help detect incompatibilites and missing basics, like glibc. - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export FROM_IMAGE="imazen/imageflow_base_os" -export BUILD_IMAGE_NAME="imazen/imageflow_build_ubuntu16" -export OUTPUT_IMAGE_NAME="local/if_testing" -export DOCKER_DIR="/home/imageflow" - -export SAFE_IMAGE_NAME="$BUILD_IMAGE_NAME" -SAFE_IMAGE_NAME="${SAFE_IMAGE_NAME//\//_}" -SAFE_IMAGE_NAME="${SAFE_IMAGE_NAME//:/_}" - - -echo "./dockerize.sh $1 $2 $3" -echo "help: ./dockerize.sh (debug|quiet[123]|release|clean|valgrind|test|rusttest)+ localbuild|docker server|tool #SMOKE TESTS ONLY" - -export OVERRIDE="$1" -export OVERRIDE="${OVERRIDE:-debugquiet}" -if [[ "$OVERRIDE" == *"debug"* ]]; then - export PROFILE=debug -else - export PROFILE=release -fi - -export CARGO_TARGET="${CARGO_TARGET:-}" - -if [[ -n "$CARGO_TARGET" ]]; then - export TARGET_DIR="target/${CARGO_TARGET}/" -else - export TARGET_DIR="target/" -fi - - -if [[ "$3" == 'tool' ]]; then - export BINARY_NAME=imageflow_tool - export TEST_ENTRYPOINT=(sudo "${DOCKER_DIR}/${BINARY_NAME}" diagnose --self-test) -else - export BINARY_NAME=imageflow_server - export TEST_ENTRYPOINT=(sudo "${DOCKER_DIR}/${BINARY_NAME}" diagnose --smoke-test-core) -fi - -if [[ "$2" == 'docker' ]]; then - - TARGET_CPU="${TARGET_CPU:-x86-64}" - WORKING_DIR="${HOME}/.docker_imageflow_caches/.docker_${SAFE_IMAGE_NAME}_${TARGET_CPU}" - export BINARY_DIR="${WORKING_DIR}_cache/${TARGET_DIR}${PROFILE}" -else - export BINARY_DIR="${SCRIPT_DIR}/../${TARGET_DIR}${PROFILE}" -fi - - -if [[ -d "$BINARY_DIR" ]]; then - export BINARY_DIR - BINARY_DIR="$(readlink -f "$BINARY_DIR")" -else - echo "Cannot find $BINARY_DIR" -fi -export BINARY_OUT="$BINARY_DIR/$BINARY_NAME" -export BINARY_COPY="${SCRIPT_DIR}/bin/$BINARY_NAME" -mkdir -p "${SCRIPT_DIR}/bin/" || true -mkdir -p "${BINARY_DIR}" || true &>/dev/null - -sep_bar(){ - printf "\n=================== %s ======================\n" "$1" -} -print_modified_ago(){ - if [[ -f "$1" ]]; then - printf "(modified %s seconds ago)" "$(( $(date +%s) - $(stat -c%Y "$1") ))" - fi -} - -sep_bar "Compiling" -printf "BINARY_OUT=%s " "$BINARY_OUT" && print_modified_ago "$BINARY_OUT" && printf "\n" - -export BUILD_QUIETER="${BUILD_QUIETER:-True}" -export UPLOAD_BUILD=False -export UPLOAD_DOCS=False -export IMAGEFLOW_BUILD_OVERRIDE="$OVERRIDE" - -if [[ "$2" == 'docker' ]]; then - ( cd "${SCRIPT_DIR}/../ci" && ./simulate_travis.sh "${BUILD_IMAGE_NAME}" ) -else - ( "${SCRIPT_DIR}/../build.sh" "${OVERRIDE}" ) - - #if [[ "$PROFILE" == 'debug' ]]; then - # ( set -vx && cd "${SCRIPT_DIR}/../${CRATE_NAME}" && cargo build --bin "${BINARY_NAME}" ) - #else - # ( set -vx && cd "${SCRIPT_DIR}/../${CRATE_NAME}" && cargo build --bin "${BINARY_NAME}" --release ) - #fide -fi - -# Post-compile build info -"${BINARY_OUT}" --version || ( printf "\nBINARY_OUT=%s " "$BINARY_OUT" && print_modified_ago "$BINARY_OUT" && printf "\n" ) - -# Generate and build Dockerfile -sep_bar "Dockerizing" -( - cd "$SCRIPT_DIR" - cp -p "${BINARY_OUT}" . - printf "\nCreating Dockerfile\n\n" - printf "FROM %s\n\nEXPOSE 39876\n\nADD %s %s/" "$FROM_IMAGE" "$BINARY_NAME" "$DOCKER_DIR" > Dockerfile - docker build -t "$OUTPUT_IMAGE_NAME" . -) -sep_bar "Smoke testing in Docker" -docker run --rm "${OUTPUT_IMAGE_NAME}" "${DOCKER_DIR}/${BINARY_NAME}" --version || printf "Failed to run %s --version!\n" "${BINARY_NAME}" - -set +e - -if docker run --rm "${OUTPUT_IMAGE_NAME}" "${TEST_ENTRYPOINT[@]}"; then - sep_bar "PASSED" -else - sep_bar "FAILED" - export TEST_FAILED=1 -fi -set -e - - - -if [[ "$TEST_FAILED" == '1' ]]; then - echo "Entering interactive" - echo "This creates docker containers and doesn't clean them up. Use this to remove all containers (danger!)" - # shellcheck disable=SC2016 - echo 'docker rm `docker ps -aq`' - - docker run -i -t "${OUTPUT_IMAGE_NAME}" /bin/bash - - exit 1 -fi - -if [[ "$BINARY_NAME" == 'imageflow_server' ]]; then - docker run -i -t -p 3000:3000 "${OUTPUT_IMAGE_NAME}" sudo "${DOCKER_DIR}/${BINARY_NAME}" start --demo --port 3000 --bind-address 0.0.0.0 -fi - - -#docker push "${IMAGE_NAME}" -#docker-cloud stack up --name "$TEST_STACK_NAME" -#docker-cloud stack update "$TEST_STACK_NAME" -#export STACK_UID= $(docker-cloud stack up --name flow3 -f docker-solo.yaml) -#printf "%s" "${STACK_UID}" -#docker-cloud stack redeploy "$TEST_STACK_NAME" - - - diff --git a/imageflow_server/src/assets/identity.p12 b/imageflow_server/src/assets/identity.p12 deleted file mode 100644 index d16abb8c7..000000000 Binary files a/imageflow_server/src/assets/identity.p12 and /dev/null differ diff --git a/imageflow_server/src/assets/root-ca.pem b/imageflow_server/src/assets/root-ca.pem deleted file mode 100644 index 4ec2f5388..000000000 --- a/imageflow_server/src/assets/root-ca.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDXTCCAkWgAwIBAgIJAOIvDiVb18eVMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTYwODE0MTY1NjExWhcNMjYwODEyMTY1NjExWjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEArVHWFn52Lbl1l59exduZntVSZyDYpzDND+S2LUcO6fRBWhV/1Kzox+2G -ZptbuMGmfI3iAnb0CFT4uC3kBkQQlXonGATSVyaFTFR+jq/lc0SP+9Bd7SBXieIV -eIXlY1TvlwIvj3Ntw9zX+scTA4SXxH6M0rKv9gTOub2vCMSHeF16X8DQr4XsZuQr -7Cp7j1I4aqOJyap5JTl5ijmG8cnu0n+8UcRlBzy99dLWJG0AfI3VRJdWpGTNVZ92 -aFff3RpK3F/WI2gp3qV1ynRAKuvmncGC3LDvYfcc2dgsc1N6Ffq8GIrkgRob6eBc -klDHp1d023Lwre+VaVDSo1//Y72UFwIDAQABo1AwTjAdBgNVHQ4EFgQUbNOlA6sN -XyzJjYqciKeId7g3/ZowHwYDVR0jBBgwFoAUbNOlA6sNXyzJjYqciKeId7g3/Zow -DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVVaR5QWLZIRR4Dw6TSBn -BQiLpBSXN6oAxdDw6n4PtwW6CzydaA+creiK6LfwEsiifUfQe9f+T+TBSpdIYtMv -Z2H2tjlFX8VrjUFvPrvn5c28CuLI0foBgY8XGSkR2YMYzWw2jPEq3Th/KM5Catn3 -AFm3bGKWMtGPR4v+90chEN0jzaAmJYRrVUh9vea27bOCn31Nse6XXQPmSI6Gyncy -OAPUsvPClF3IjeL1tmBotWqSGn1cYxLo+Lwjk22A9h6vjcNQRyZF2VLVvtwYrNU3 -mwJ6GCLsLHpwW/yjyvn8iEltnJvByM/eeRnfXV6WDObyiZsE/n6DxIRJodQzFqy9 -GA== ------END CERTIFICATE----- diff --git a/imageflow_server/src/assets/tiny.jpg b/imageflow_server/src/assets/tiny.jpg deleted file mode 100644 index 71911bf48..000000000 Binary files a/imageflow_server/src/assets/tiny.jpg and /dev/null differ diff --git a/imageflow_server/src/config.rs b/imageflow_server/src/config.rs deleted file mode 100644 index 309fa6b90..000000000 --- a/imageflow_server/src/config.rs +++ /dev/null @@ -1,67 +0,0 @@ - -// use serde_toml -// Deserialize from TOML or from inline struct - -// pub struct Hostname -// -// pub struct PerRequestLimits{ -// max_pixels_out: Option, -// max_pixels_in: Option, -// max_cpu_milliseconds: Option, -// max_bitmap_ram_bytes: Option -// } -// -// pub struct ContentTypeRestrictions{ -// allow: Option>, -// deny: Option>, -// allow_extensions: Option>, -// deny_extensions: Option> -// } -// pub struct SecurityPolicy{ -// per_request_limits: Option, -// serve_content_types: Option, -// proxy_content_types: Option, -// force_image_recoding: Option -// } -// -// pub enum BlobSource{ -// Directory(String), -// HttpServer(String), -// //TODO: Azure and S3 blob backend -// } -// -// pub enum InternalCachingStrategy{ -// PubSubAndPermaPyramid, -// TrackStatsAndPermaPyramid, -// OpportunistPermaPyramid, -// PubSubToInvalidate, -// OpportunistPubSubEtagCheck, -// -// } -// pub struct CacheControlPolicy{ -// //How do we set etag/last modified/expires/maxage? -// } -// -// pub struct BaseConfig{ -// //Security defaults -// pub security: Option, -// //May also want to filter by hostnames or ports for heavy multi-tenanting -// pub cache_control: Option -// } -// -// pub enum Frontend{ -// ImageResizer4Compatible, -// Flow0 -// } -// pub struct MountPath { -// //Where we get originals from -// pub source: BlobSource, -// //The virtual path for which we handle sub-requests. -// pub prefix: String, -// //Customize security -// pub security: Option, -// //May also want to filter by hostnames or ports for heavy multi-tenanting -// pub cache_control: Option, -// -// pub api: Frontend -// } \ No newline at end of file diff --git a/imageflow_server/src/diagnose.rs b/imageflow_server/src/diagnose.rs deleted file mode 100644 index 4077503b8..000000000 --- a/imageflow_server/src/diagnose.rs +++ /dev/null @@ -1,46 +0,0 @@ -use imageflow_helpers::preludes::from_std::*; -use imageflow_core::clients::stateless; -use imageflow_core::clients::fluent; -use crate::s; - -const BLUE_PNG32_200X200_B64:&'static str = "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAABiUlEQVR42u3TgRAAQAgAsA/qkaKLK48EIug2h8XP6gesQhAQBAQBQUAQEAQEAUFAEBAEEAQEAUFAEBAEBAFBQBAQBAQRBAQBQUAQEAQEAUFAEBAEBAEEAUFAEBAEBAFBQBAQBAQBQQBBQBAQBAQBQUAQEAQEAUEAQUAQEAQEAUFAEBAEBAFBQBBAEBAEBAFBQBAQBAQBQUAQQBAQBAQBQUAQEAQEAUFAEBAEEAQEAUFAEBAEBAFBQBAQBAQRBAQBQUAQEAQEAUFAEBAEBAEEAUFAEBAEBAFBQBAQBAQBQQQBQUAQEAQEAUFAEBAEBAFBAEFAEBAEBAFBQBAQBAQBQUAQQBAQBAQBQUAQEAQEAUFAEEAQEAQEAUFAEBAEBAFBQBAQBBAEBAFBQBAQBAQBQUAQEAQQBAQBQUAQEAQEAUFAEBAEBAEEAUFAEBAEBAFBQBAQBAQBQQQBQUAQEAQEAUFAEBAEBAFBAEFAEBAEBAFBQBAQBAQBQUAQQUAQEAQEAUFAEBAEBIGLBkZ+sahOjkyUAAAAAElFTkSuQmCC"; - - -fn smoke_jpeg_to_jpeg() { - let framewise = fluent::fluently() - .decode(0) - .constrain_within(Some(40), Some(40), Some(s::ResampleHints::with(None, Some(25f32)))) - .encode(1, s::EncoderPreset::libjpeg_turbo()).builder().to_framewise(); - - let bytes = include_bytes!("assets/tiny.jpg"); - - let req = stateless::BuildRequest{ - export_graphs_to: None, - inputs: vec![stateless::BuildInput{bytes, io_id: 0}], - framewise - }; - let _ = stateless::LibClient{}.build(req).unwrap(); -} - - - -fn smoke_png_to_png() { - let framewise = fluent::fluently() - .decode(0) - .constrain_within(Some(40), Some(40), Some(s::ResampleHints::with(None, Some(25f32)))) - .encode(1, s::EncoderPreset::libpng32()).builder().to_framewise(); - - let bytes = base64::decode(BLUE_PNG32_200X200_B64).unwrap(); - - let req = stateless::BuildRequest{ - export_graphs_to: None, - inputs: vec![stateless::BuildInput{bytes: &bytes, io_id: 0}], - framewise: framewise - }; - let _ = stateless::LibClient{}.build(req).unwrap(); -} - -pub fn smoke_test_core() { - smoke_png_to_png(); - smoke_jpeg_to_jpeg(); -} diff --git a/imageflow_server/src/disk_cache.rs b/imageflow_server/src/disk_cache.rs deleted file mode 100644 index 1c1fbb0cf..000000000 --- a/imageflow_server/src/disk_cache.rs +++ /dev/null @@ -1,301 +0,0 @@ -/// This is a naive local 'caching' implementation of a key/value blob store -/// Each pair gets 1 file -/// Hash collisions are improbable - we use blake2 256, faster than SHA-3. 32-byte hashes -/// Write only -/// Append-only log for transitioning to more complex system -/// Staging folder - files are renamed into final locations -/// soft and hard count and byte limit - NO DELETION -use std::path::*; -use std::io; -use std; -use std::io::prelude::*; -use std::fs::{create_dir_all, File}; -use std::sync::atomic::{AtomicBool, Ordering}; -use self::rand::RngCore; -// TODO: -// Cleanup staging folders automatically (failed renames) -// Implement write-only log -// Implement transactional filesystem 'counters' to track total count/size -// Implement write failure when limits are reached - -// It *is* possible to implement FIFO cache eviction, but is FIFO worth it? (random sampling of the write log, staging folders to drop handles, etc) - -extern crate rand; -extern crate imageflow_helpers; -use self::imageflow_helpers as hlp; - - -fn create_dir_all_helpful>(path: P) -> io::Result<()> { - match create_dir_all(&path) { - Ok(v) => Ok(v), - Err(e) => { - //panic!("Failed to create dir {:?} {:?}", path.as_ref(), e); - Err(e) - } - } -} - - -// -///// Cache of the state of the cache folder - can be invalidated by failure. -//struct CacheCache{ -// -//} - -//Since we have a fixed number of folders, known at creation time, let's deterministically order them -//and use a bitset or something. -//We can use RwLock on a BitVec or a Vec of AtomicBools (64kb vs 8kb, but maybe we just collapse for storage?) - -#[derive(Debug)] -pub struct CacheFolder{ - root: PathBuf, - root_confirmed: AtomicBool, - meta_dir: PathBuf, - staging_dir: PathBuf, - meta_layout_confirmed: AtomicBool, - write_log: PathBuf, - consumption_log: PathBuf, - consumption_summary: PathBuf, - folder_bits: u8, - folders_from_hash: u32, - bits_format: &'static str, - write_layout: FolderLayout -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum FolderLayout { - /// 64 tier 1 folders, each with a 'files' subdirectory. Optimal range 0 to 8,000 entries or so. Suggested max 51k. - Tiny, - /// 64 x 64, each leaf with a 'files' subdirectory. Optimal range ~8,000 to ~500,000 entries. Suggested max 3 million. - Normal, - /// 64 x 64 x 16. Optimal for 500k to 8 million entries. Suggested max 50 million. - Huge -} - -impl CacheFolder{ - pub fn new(root: &Path, write_layout: FolderLayout) -> CacheFolder{ - CacheFolder{ - meta_layout_confirmed: AtomicBool::default(), - root: root.to_owned(), - root_confirmed: AtomicBool::default(), - meta_dir: root.join(Path::new("meta")), - staging_dir: root.join(Path::new("staging")), - write_log: root.join(Path::new("meta")).join(Path::new("write_log")), - consumption_log: root.join(Path::new("meta")).join(Path::new("consumption_log")), - consumption_summary: root.join(Path::new("meta")).join(Path::new("consumption_summary")), - folder_bits: match write_layout{ - FolderLayout::Tiny => 6, - FolderLayout::Normal => 12, - FolderLayout::Huge => 16, - }, - bits_format: match write_layout{ - FolderLayout::Tiny => "{250-256:02x}/files/{0-256:064x}", - FolderLayout::Normal => "{250-256:02x}/{244-250:02x}/files/{0-256:064x}", - FolderLayout::Huge => "{250-256:02x}/{244-250:02x}/{240-244:02x}/{0-256:064x}", - }, - folders_from_hash: match write_layout{ - FolderLayout::Tiny => 64 * 2, - FolderLayout::Normal => 64 * 64 * 2 + 64, - FolderLayout::Huge => 64 * 64 * 16 + 64 * 64 + 64, - }, - write_layout: write_layout - } - } - - pub fn entry(&self, hash: &[u8;32]) -> CacheEntry { - CacheEntry { - path: self.root.join(hlp::hashing::normalize_slashes(hlp::hashing::bits_format(hash, self.bits_format))), - hash: *hash, - parent: self - } - } -// PUT A README IN THE CACHE ROOT! DO IT! - - - fn ensure_root(&self) -> io::Result<()>{ - if !self.root_confirmed.load(Ordering::Relaxed) && - !self.root.as_path().is_dir(){ - create_dir_all_helpful(&self.root)?; - self.root_confirmed.store(true, Ordering::Relaxed); - } - Ok(()) - } - - fn ensure_meta_layout_confirmed(&self) -> io::Result<()>{ - if !self.meta_layout_confirmed.load(Ordering::SeqCst){ - let path = self.meta_dir.join(Path::new(match self.write_layout{ - FolderLayout::Huge => "huge", - FolderLayout::Tiny => "tiny", - FolderLayout::Normal => "normal" - })); - if !self.meta_layout_confirmed.load(Ordering::SeqCst) && !path.exists() { - create_dir_all_helpful(&self.meta_dir)?; - File::create(path)?; - self.meta_layout_confirmed.store(true, Ordering::SeqCst); - } - } - Ok(()) - } - - ///TODO: we could optimize directory existence checks with an 8, 512, or 8kb BitVec, easily persisted. - /// We would need 'fast path' that falls back to 'careful path' when any of those caches get out of sync - fn prepare_for(&self, entry: &CacheEntry) -> io::Result<()> { - self.ensure_root().unwrap(); - self.ensure_meta_layout_confirmed().unwrap(); - let dir = entry.path.as_path().parent().expect("Every cache path should have a parent dir; this did not!"); - if !dir.exists(){ - create_dir_all_helpful(dir)?; - } - Ok(()) - } - - fn acquire_staging_location(&self, hash: &[u8;32]) -> io::Result{ - if !self.staging_dir.as_path().exists(){ - create_dir_all_helpful(self.staging_dir.as_path())?; - } - - let slot_id = hlp::timeywimey::time_bucket(60 * 60 * 2, 6); - - //six slots, each used for 2 hours. - let subdir = self.staging_dir.join(Path::new(&format!("{}", slot_id))); - if !subdir.exists() { - create_dir_all_helpful(subdir.as_path())?; - } - - let staging_path = format!("{:064x}_{:016x}_incoming", hlp::hashing::HexableBytes(hash), rand::thread_rng().next_u64()); - Ok(subdir.join(Path::new(&staging_path))) - } -} - -pub struct CacheEntry<'a>{ - //Path shall always have a valid parent. - hash: [u8;32], - path: PathBuf, - parent: &'a CacheFolder -} - -impl<'a> CacheEntry<'a>{ - pub fn prepare_dir(&self) -> io::Result<()>{ - self.parent.prepare_for(self) - } - pub fn exists(&self) -> bool{ - self.path.as_path().is_file() - } - - // static NEXT_FLUENT_NODE_ID: AtomicU64 = ATOMIC_U64_INIT; - - - // We have to write to a different file, first. Then we fs::rename() to overwrite - // - pub fn write(&self, bytes: &[u8]) -> io::Result<()> { - self.prepare_dir()?; - let temp_path = self.parent.acquire_staging_location(&self.hash)?; - use ::std::fs::OpenOptions; - { - let mut f = OpenOptions::new().write(true).create_new(true).open(&temp_path)?; - f.write_all(bytes)?; - } - std::fs::rename(&temp_path, &self.path)?; - Ok(()) - } - - pub fn read(&self) -> io::Result>{ - hlp::filesystem::read_file_bytes(&self.path) - } - - -} - -// If one migrates from one FolderLayout to another, or is moving off of a old cache directory, then multiple queries make sense -// Check for meta/tiny, meta/normal, meta/huge presence to auto-populate -//struct CacheReader{ -// folders: Vec -//} -// -//impl CacheReader{ -// -//} -// -// -// - - - - - - - - - - - - - - - - - - - - - - - - -//We should log each 32-byte hash saved to a file. This would be far faster than a directory listing later. -//128 entries per block is quite efficient. We could handle 10 million in 320mb. - -//But if we don't require aligning to block boundaries, another 11 to 16 bytes would be quite handy. - -//We could log size for another 8 bytes (or 4 or 5 if we are ok with a 2 or 512GB limit) -//Dimensions are u16xu16 for the formats we care about. at least 1 byte to cover all mime types -//And another 2-3 bytes for useful metadata about the image?? -// I.e, 43-48 bytes per record. - -//We can append to file pretty reliably, but reads will get torn at the end https://stackoverflow.com/questions/1154446/is-file-append-atomic-in-unix - - - - - - -// -//hashes are 32 bytes? -// -//Cache write -//Create 3 parent directories -// -// -// -// -//There is no cleanup -//64 x 64 x 1 nested directories by default. Optional 64x64x16 + 1. with read through -// -// -// -// -// -// -//Allow read-through to -//There is no index -// -// -//Fetch by hash - blake2d 256bit -// -//blake2-rfc = "0.2.17" or https://github.com/RustCrypto/hashes -//base 32? -// -// -//Filesystem -//Disable 8.3 on windows -//Disable all metadata (as much as possible) -//only list unsorted -//https://stackoverflow.com/questions/197162/ntfs-performance-and-large-volumes-of-files-and-directories - - - - - - - - diff --git a/imageflow_server/src/lib.rs b/imageflow_server/src/lib.rs deleted file mode 100644 index 692c2b434..000000000 --- a/imageflow_server/src/lib.rs +++ /dev/null @@ -1,757 +0,0 @@ - -extern crate iron; -extern crate persistent; -extern crate router; -extern crate logger; - -extern crate bincode; -extern crate mount; - -use staticfile::Static; - - -#[macro_use] extern crate serde_derive; - -extern crate staticfile; -extern crate hyper; - -extern crate time; -#[macro_use] extern crate lazy_static; -extern crate regex; - -extern crate hyper_native_tls; - -use hyper_native_tls::NativeTlsServer; - -use std::sync::atomic::AtomicUsize; - - -extern crate conduit_mime_types as mime_types; - -use regex::Regex; - -extern crate imageflow_helpers; -extern crate imageflow_core; -extern crate imageflow_types as s; -extern crate imageflow_riapi; -extern crate reqwest; - -use ::imageflow_helpers as hlp; -use imageflow_http_helpers::FetchConfig; -use imageflow_helpers::preludes::from_std::*; -use imageflow_core::clients::stateless; - - -pub mod disk_cache; -pub mod resizer; -pub mod diagnose; - -mod requested_path; -extern crate url; - -use crate::disk_cache::{CacheFolder, FolderLayout}; -use logger::Logger; - -pub mod preludes { - pub use super::{MountedEngine, MountLocation, StartServerConfig, ServerError}; - pub use super::disk_cache::FolderLayout; -} - - -use iron::mime::*; -use iron::prelude::*; -use iron::status; -use router::Router; - - - - - -use imageflow_helpers::timeywimey::precise_time_ns; - -#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))] -#[allow(unused_imports)] -#[macro_use] extern crate log; -extern crate env_logger; - - -#[derive(Debug)] -struct SharedData { - source_cache: CacheFolder, - output_cache: CacheFolder, - requests_received: AtomicUsize, - //detailed_errors: bool -} - -impl iron::typemap::Key for SharedData { type Value = SharedData; } - - -// Todo: consider lru_cache crate - -#[derive(Debug)] -pub enum ServerError { - HyperError(hyper::Error), - ReqwestError(reqwest::Error), - IoError(std::io::Error), - DiskCacheReadIoError(std::io::Error), - DiskCacheWriteIoError(std::io::Error), - UpstreamResponseError(hyper::StatusCode), - UpstreamResponseErrorWithBytes((hyper::StatusCode, Vec)), - UpstreamHyperError(hyper::Error), - UpstreamReqwestError(reqwest::Error), - UpstreamIoError(std::io::Error), - BuildFailure(stateless::BuildFailure), - LayoutSizingError(::imageflow_riapi::sizing::LayoutError) -} - -impl From for ServerError { - fn from(e: stateless::BuildFailure) -> ServerError { - ServerError::BuildFailure(e) - } -} - -impl From for ServerError { - fn from(e: reqwest::Error) -> ServerError { - ServerError::ReqwestError(e) - } -} -impl From for ServerError { - fn from(e: hyper::Error) -> ServerError { - ServerError::HyperError(e) - } -} -impl From<::imageflow_http_helpers::FetchError> for ServerError { - fn from(e: ::imageflow_http_helpers::FetchError) -> ServerError { - match e{ - ::imageflow_http_helpers::FetchError::HyperError(e) => ServerError::HyperError(e), - ::imageflow_http_helpers::FetchError::IoError(e) => ServerError::IoError(e), - ::imageflow_http_helpers::FetchError::UpstreamResponseError(e) => ServerError::UpstreamResponseError(e), - ::imageflow_http_helpers::FetchError::UpstreamResponseErrorWithResponse{status, ..}=> ServerError::UpstreamResponseError(status), - ::imageflow_http_helpers::FetchError::ReqwestError(e) => ServerError::ReqwestError(e) - } - - } -} - -impl From for ServerError { - fn from(e: std::io::Error) -> ServerError { - ServerError::IoError(e) - } -} - -struct FetchedResponse { - bytes: Vec, - perf: AcquirePerf, - content_type: reqwest::header::HeaderValue, -} - -fn fetch_bytes(url: &str, config: Option) -> std::result::Result { - let start = precise_time_ns(); - let result = ::imageflow_http_helpers::fetch(url, config); - let downloaded = precise_time_ns(); - - match result{ - Ok(r) => { - if r.code.is_success() { - Ok(FetchedResponse { - bytes: r.bytes, - content_type: r.content_type, - perf: AcquirePerf { fetch_ns: downloaded - start, ..Default::default() } - }) - }else if r.bytes.len() > 0{ - Err(ServerError::UpstreamResponseErrorWithBytes((r.code, r.bytes))) - } else { - Err(ServerError::UpstreamResponseError(r.code)) - } - }, - Err(e) => Err(error_upstream(e.into())) - } -} - -fn error_upstream(from: ServerError) -> ServerError { - match from { - ServerError::HyperError(e) => ServerError::UpstreamHyperError(e), - ServerError::ReqwestError(e) => ServerError::UpstreamReqwestError(e), - ServerError::IoError(e) => ServerError::UpstreamIoError(e), - e => e, - } -} - - - - -#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] -struct CachedResponse { - bytes: Vec, - content_type: String, -} - -// Additional ways this can fail (compared to fetch_bytes) -// Parent directories are deleted from cache between .exists() and cache writes -// Permissions issues -// Cached file is deleted between .exists(0 and .read() -// Write fails due to out-of-space -// rename fails (it should overwrite, for eventual consistency, but ... filesystems) -fn fetch_bytes_using_cache_by_url(cache: &CacheFolder, url: &str) -> std::result::Result<(Vec, AcquirePerf), ServerError> { - let hash = hlp::hashing::hash_256(url.as_bytes()); - let entry = cache.entry(&hash); - if entry.exists() { - let start = precise_time_ns(); - match entry.read() { - Ok(vec) => { - let end = precise_time_ns(); - Ok((vec, AcquirePerf { cache_read_ns: end - start, ..Default::default() })) - }, - Err(e) => Err(ServerError::DiskCacheReadIoError(e)) - } - } else { - let result = fetch_bytes(url, Some(FetchConfig{ custom_ca_trust_file: None, read_error_body: Some(true) })); - if let Ok(FetchedResponse { bytes, perf, .. }) = result { - let start = precise_time_ns(); - match entry.write(&bytes) { - Ok(()) => { - let end = precise_time_ns(); - Ok((bytes, AcquirePerf { cache_write_ns: end - start, ..perf })) - }, - Err(e) => Err(ServerError::DiskCacheWriteIoError(e)) - } - } else { - Err(result.map_err(error_upstream).err().unwrap()) - } - } -} - -fn fetch_response_using_cache_by_url(cache: &CacheFolder, url: &str) -> std::result::Result<(CachedResponse, AcquirePerf), ServerError> { - let hash = hlp::hashing::hash_256(url.as_bytes()); //TODO: version this - let entry = cache.entry(&hash); - if entry.exists() { - let start = precise_time_ns(); - match entry.read() { - Ok(vec) => { - let end = precise_time_ns(); - let cached: CachedResponse = bincode::deserialize(&vec).unwrap(); - Ok((cached, AcquirePerf { cache_read_ns: end - start, ..Default::default() })) - }, - Err(e) => Err(ServerError::DiskCacheReadIoError(e)) - } - } else { - let result = fetch_bytes(url, None); - if let Ok(fetched) = result { - let start = precise_time_ns(); - let bytes = bincode::serialize(&fetched.bytes).unwrap(); - match entry.write(&bytes) { - Ok(()) => { - let end = precise_time_ns(); - Ok((CachedResponse { bytes: fetched.bytes, content_type: format!("{}", fetched.content_type.to_str().unwrap()) }, AcquirePerf { cache_write_ns: end - start, ..fetched.perf })) - }, - Err(e) => Err(ServerError::DiskCacheWriteIoError(e)) - } - } else { - Err(result.map_err(error_upstream).err().unwrap()) - } - } -} - -fn fetch_bytes_from_disk(url: &Path) -> std::result::Result<(Vec, AcquirePerf), ServerError> { - let start = precise_time_ns(); - let vec = hlp::filesystem::read_file_bytes(url)?; - let end = precise_time_ns(); - Ok((vec, AcquirePerf { cache_read_ns: end - start, ..Default::default() })) -} - -#[derive(Default, Copy, Clone, Debug)] -struct AcquirePerf { - fetch_ns: u64, - cache_read_ns: u64, - cache_write_ns: u64 -} - - -impl AcquirePerf { - fn total(&self) -> u64{ - self.fetch_ns + self.cache_read_ns + self.cache_write_ns - } -} - -struct RequestPerf { - acquire: AcquirePerf, - get_image_info_ns: u64, - execute_ns: u64, -} - -impl RequestPerf { - fn short(&self) -> String { - format!("execute {:.2}ms getinfo {:.2}ms fetch-through: {:.2}ms", - self.execute_ns as f64 / 1_000_000.0f64 - , self.get_image_info_ns as f64 / 1_000_000.0f64, - (self.acquire.total() as f64) / 1_000_000.0f64) - } -} - - -fn execute_using(bytes_provider: F2, framewise_generator: F) - -> std::result::Result<(stateless::BuildOutput, RequestPerf), ServerError> - where F: Fn(s::ImageInfo) -> std::result::Result, - F2: Fn() -> std::result::Result<(Vec, AcquirePerf), ServerError>, -{ - let (original_bytes, acquire_perf) = bytes_provider()?; - let mut client = stateless::LibClient {}; - let start_get_info = precise_time_ns(); - let info = client.get_image_info(&original_bytes)?; - let start_execute = precise_time_ns(); - - let result: stateless::BuildSuccess = client.build(stateless::BuildRequest { - framewise: framewise_generator(info)?, - inputs: vec![stateless::BuildInput { - io_id: 0, - bytes: &original_bytes, - }], - export_graphs_to: None, - })?; - let end_execute = precise_time_ns(); - Ok((result.outputs.into_iter().next().unwrap(), - RequestPerf { - acquire: acquire_perf, - get_image_info_ns: start_execute - start_get_info, - execute_ns: end_execute - start_execute, - })) -} - -fn respond_using(debug_info: &A, bytes_provider: F2, framewise_generator: F) - -> IronResult - where F: Fn(s::ImageInfo) -> std::result::Result, - F2: Fn() -> std::result::Result<(Vec, AcquirePerf), ServerError>, - A: std::fmt::Debug -{ - //TODO: support process=, cache=, etc? pass-through by default? - match execute_using(bytes_provider, framewise_generator) { - Ok((output, perf)) => { - let mime = output.mime_type - .parse::() - .unwrap_or_else(|_| Mime::from_str("application/octet-stream").unwrap()); - let mut res = Response::with((mime, status::Ok, output.bytes)); - - - - res.headers.set_raw("X-Imageflow-Perf", vec![perf.short().into_bytes()]); - Ok(res) - } - Err(e) => respond_with_server_error(&debug_info, e, true) - } -} - -fn respond_with_server_error(debug_info: &A, e: ServerError, detailed_errors: bool) -> IronResult where A: std::fmt::Debug { - match e { - ServerError::UpstreamResponseError(reqwest::StatusCode::NOT_FOUND) => { - let bytes = if detailed_errors { - b"Remote file not found (upstream server responded with 404)".to_vec() - }else { - format!("Remote file not found (upstream server responded with 404 to {:?})", debug_info).into_bytes() - }; - - Ok(Response::with((Mime::from_str("text/plain").unwrap(), - status::NotFound, - bytes))) - }, - e => { - let bytes = if detailed_errors { - format!("Internal Server Error\nInfo:{:?}\nError:{:?}", debug_info, e).into_bytes() - }else{ - b"Internal Server Error".to_vec() - }; - Ok(Response::with((Mime::from_str("text/plain").unwrap(), - status::InternalServerError, - bytes))) - // TODO: get a bit more specific with the error codes - } - } -} - - -fn ir4_http_respond(shared: &SharedData, url: &str, framewise_generator: F) -> IronResult - where F: Fn(s::ImageInfo) -> std::result::Result -{ - respond_using(&url, || fetch_bytes_using_cache_by_url(&shared.source_cache, url).map_err(error_upstream), framewise_generator) -} - -fn ir4_http_respond_uncached(_shared: &SharedData, url: &str, framewise_generator: F) -> IronResult - where F: Fn(s::ImageInfo) -> std::result::Result -{ - respond_using(&url, || { - fetch_bytes( url, None).map_err(error_upstream).map(|r| - (r.bytes, r.perf)) - }, framewise_generator) -} - - -fn ir4_framewise(_info: &s::ImageInfo, url: &url::Url) -> std::result::Result { - let t = ::imageflow_riapi::ir4::Ir4Translate{ - i: ::imageflow_riapi::ir4::Ir4Command::Url(url.as_str().to_owned()), - decode_id: Some(0), - encode_id: Some(1), - watermarks: None - }; - t.translate().map_err( ServerError::LayoutSizingError).and_then(|r: ::imageflow_riapi::ir4::Ir4Result| Ok(s::Framewise::Steps(r.steps.unwrap()))) -} - - -type EngineHandler = fn(req: &mut Request, engine_data: &T, mount: &MountLocation) -> IronResult; -type EngineSetup = fn(mount: &MountLocation) -> Result<(T, EngineHandler), String>; - - -fn ir4_local_respond(_: &SharedData, source: &Path, framewise_generator: F) -> IronResult - where F: Fn(s::ImageInfo) -> std::result::Result -{ - respond_using(&source, || fetch_bytes_from_disk(source), framewise_generator) -} - -fn ir4_local_handler(req: &mut Request, local_path: &PathBuf, _: &MountLocation) -> IronResult { - let requested_path = requested_path::RequestedPath::new(local_path, req); - - let url: url::Url = req.url.clone().into(); - let shared = req.get::>().unwrap(); - - if requested_path.path.exists() { - return ir4_local_respond(&shared, requested_path.path.as_path(), move |info: s::ImageInfo| { - ir4_framewise(&info, &url) - }); - } - - let _ = writeln!(&mut std::io::stderr(), "404 {:?} using local path {:?} and base {:?}", &url.path(), requested_path.path.as_path(), local_path); - //writeln!(&mut std::io::stdout(), "404 {:?} using local path {:?}", &url.path(), original ); - - Ok(Response::with((Mime::from_str("text/plain").unwrap(), - status::NotFound, - b"File not found".to_vec()))) -} - -fn static_handler(_: &mut Request, _: &Static, _: &MountLocation) -> IronResult { - - Ok(Response::with((Mime::from_str("text/plain").unwrap(), - status::InternalServerError, - b"Do not use".to_vec()))) -} - -fn ir4_local_setup(mount: &MountLocation) -> Result<(PathBuf, EngineHandler), String> { - if mount.engine_args.len() < 1 { - Err("ir4_local requires at least one argument - the path to the physical folder it is serving".to_owned()) - } else { - //TODO: validate path - let local_dir = Path::new(&mount.engine_args[0]).canonicalize().map_err(|e| format!("{:?} for {:?}", e, &mount.engine_args[0]))?; - Ok((local_dir, ir4_local_handler)) - } -} - -fn static_setup(mount: &MountLocation) -> Result<(Static, EngineHandler), String> { - if mount.engine_args.len() < 1 { - Err("static requires at least one argument - the path to the physical folder it is serving".to_owned()) - } else { - //TODO: validate path - let path = Path::new(&mount.engine_args[0]).canonicalize().map_err(|e| format!("{:?}", e))?; - let h = if mount.engine_args.len() > 1 { - panic!("Static file cache headers not yet supported") //(we must compile staticfile with the 'cache' feature enabled) -// let mins = mount.engine_args[1].parse::().expect("second argument to static must be the number of minutes to browser cache for"); -// Static::new(path).cache(Duration::minutes(mins)) - } else { - Static::new(path) - }; - Ok((h, static_handler)) - } -} - -//Function is passed as generic trait (generic over 2nd arg), thus &String -#[cfg_attr(feature = "cargo-clippy", allow(ptr_arg))] -fn permacache_proxy_handler(req: &mut Request, base_url: &String, _: &MountLocation) -> IronResult { - let url: url::Url = req.url.clone().into(); - let shared = req.get::>().unwrap(); - //TODO: Ensure the combined url is canonical (or, at least, lacks ..) - let remote_url = format!("{}{}{}", base_url, &url.path()[1..], req.url.query().unwrap_or("")); - - match fetch_response_using_cache_by_url(&shared.source_cache, &remote_url) { - Ok((output, _)) => { - let mime = output.content_type - .parse::() - .unwrap_or_else(|_|Mime::from_str("application/octet-stream").unwrap()); - - Ok(Response::with((mime, status::Ok, output.bytes))) - } - Err(e) => respond_with_server_error(&remote_url, e, true) - } -} -lazy_static! { - static ref MIME_TYPES: mime_types::Types = mime_types::Types::new().unwrap(); -} - -//Function is passed as generic trait (generic over 2nd arg), thus &String -#[cfg_attr(feature = "cargo-clippy", allow(ptr_arg))] -fn permacache_proxy_handler_guess_types(req: &mut Request, base_url: &String, _: &MountLocation) -> IronResult { - - let url: url::Url = req.url.clone().into(); - - let shared = req.get::>().unwrap(); - //TODO: Ensure the combined url is canonical (or, at least, lacks ..) - let remote_url = format!("{}{}{}", base_url, &url.path()[1..], req.url.query().unwrap_or("")); - match fetch_bytes_using_cache_by_url(&shared.source_cache, &remote_url) { - Ok((bytes, _)) => { - - let part_path = Path::new(&url.path()[1..]); - let mime_str = MIME_TYPES.mime_for_path(part_path); - let mime:Mime = mime_str.parse().unwrap(); - -// let mime = output.content_type -// .parse::() -// .unwrap_or(Mime::from_str("application/octet-stream").unwrap()); - - Ok(Response::with((mime, status::Ok, bytes))) - } - Err(e) => respond_with_server_error(&remote_url, e, true) - } -} - -//Function is passed as generic trait (generic over 2nd arg), thus &String -#[cfg_attr(feature = "cargo-clippy", allow(ptr_arg))] -fn ir4_http_handler(req: &mut Request, base_url: &String, _: &MountLocation) -> IronResult { - let url: url::Url = req.url.clone().into(); - let shared = req.get::>().unwrap(); - //TODO: Ensure the combined url is canonical (or, at least, lacks ..) - let remote_url = format!("{}{}", base_url, &url.path()[1..]); - - ir4_http_respond(&shared, &remote_url, move |info: s::ImageInfo| { - ir4_framewise(&info, &url) - }) -} - -#[cfg_attr(feature = "cargo-clippy", allow(ptr_arg))] -fn ir4_proxy_uncached_handler(req: &mut Request, base_url: &String, _: &MountLocation) -> IronResult { - let url: url::Url = req.url.clone().into(); - let shared = req.get::>().unwrap(); - //TODO: Ensure the combined url is canonical (or, at least, lacks ..) - let remote_url = format!("{}{}", base_url, &url.path()[1..]); - - ir4_http_respond_uncached(&shared, &remote_url, move |info: s::ImageInfo| { - ir4_framewise(&info, &url) - }) -} - -fn ir4_http_setup(mount: &MountLocation) -> Result<(String, EngineHandler), String> { - if mount.engine_args.len() < 1 { - Err("ir4_http requires at least one argument - the base url to suffix paths to".to_owned()) - } else { - Ok((mount.engine_args[0].to_owned(), ir4_http_handler)) - } -} - -fn ir4_http_uncached_setup(mount: &MountLocation) -> Result<(String, EngineHandler), String> { - if mount.engine_args.len() < 1 { - Err("ir4_proxy_uncached requires at least one argument - the base url to suffix paths to".to_owned()) - } else { - Ok((mount.engine_args[0].to_owned(), ir4_proxy_uncached_handler)) - } -} - -fn permacache_proxy_setup(mount: &MountLocation) -> Result<(String, EngineHandler), String> { - if mount.engine_args.len() < 1 { - Err("permacache_proxy requires at least one argument - the base url to suffix paths to".to_owned()) - } else { - Ok((mount.engine_args[0].to_owned(), permacache_proxy_handler)) - } -} -fn permacache_proxy_guess_content_types_setup(mount: &MountLocation) -> Result<(String, EngineHandler), String> { - if mount.engine_args.len() < 1 { - Err("permacache_proxy_guess_content_types requires at least one argument - the base url to suffix paths to".to_owned()) - } else { - Ok((mount.engine_args[0].to_owned(), permacache_proxy_handler_guess_types)) - } -} - -fn mount(mount: MountLocation, mou: &mut mount::Mount, setup: EngineSetup) -> Result<(), String> - where T: Send, T: Sync, T: 'static { - let (data, handler) = setup(&mount)?; - - let prefix = mount.prefix.clone(); - mou.mount(&prefix, move |r: &mut Request| { handler(r, &data, &mount) }); - Ok(()) -} - - -pub fn serve(c: StartServerConfig) { - env_logger::init(); - - let shared_data = SharedData { - source_cache: CacheFolder::new(c.data_dir.join(Path::new("source_cache")).as_path(), c.default_cache_layout.unwrap_or(FolderLayout::Normal)), - output_cache: CacheFolder::new(c.data_dir.join(Path::new("output_cache")).as_path(), c.default_cache_layout.unwrap_or(FolderLayout::Normal)), - requests_received: AtomicUsize::new(0) //NOT YET USED - }; - - let mut mou = mount::Mount::new(); - let mut router = Router::new(); - - // Mount prefix (external) (url|relative path) - // pass through static files (whitelisted??) - - for m in c.mounts { - let copy = m.clone(); - let mount_result = match m.engine { - //MountedEngine::Ir4Https => "ir4_https", - MountedEngine::Ir4Http => mount(m, &mut mou, ir4_http_setup), - MountedEngine::Ir4ProxyUncached => mount(m, &mut mou, ir4_http_uncached_setup), - MountedEngine::Ir4Local => mount(m, &mut mou, ir4_local_setup), - MountedEngine::PermacacheProxy => mount(m, &mut mou, permacache_proxy_setup), - MountedEngine::PermacacheProxyGuessContentTypes => mount(m, &mut mou, permacache_proxy_guess_content_types_setup), - MountedEngine::Static => { - mou.mount(&m.prefix, static_setup(&m).expect("Failed to mount static directory").0); - Ok(()) - }, - }; - if let Err(e) = mount_result{ - - panic!("Failed to mount {} using engine {} ({:?})\n({:?})\nCurrent dir: {:?}", ©.prefix, ©.engine.to_id(), ©, e, std::env::current_dir()) - } - } - - if c.integration_test { - router.get("/test/shutdown", move |_: &mut Request| -> IronResult { - println!("Stopping server due to GET /test/shutdown"); - std::process::exit(0); - - // Ok(Response::with((Mime::from_str("text/plain").unwrap(), - // status::InternalServerError, - // bytes))) - }, "test-shutdown"); - } - - router.get("/imageflow.ready", move |_: &mut Request| -> IronResult { - Ok(Response::with((Mime::from_str("text/plain").unwrap(), - status::Ok, - "Imageflow Server is ready to start accepting requests."))) - }, "imageflow-ready"); - - router.get("/imageflow.health", move |_: &mut Request| -> IronResult { - Ok(Response::with((Mime::from_str("text/plain").unwrap(), - status::Ok, - "Imageflow Server is healthy."))) - }, "imageflow-health"); - - mou.mount("/", router); - - let mut chain = Chain::new(mou); - - chain.link(persistent::Read::::both(shared_data)); - - let (logger_before, logger_after) = Logger::new(None); - - // Link logger_before as your first before middleware. - chain.link_before(logger_before); - - // Link logger_after as your *last* after middleware. - chain.link_after(logger_after); - - //let ssl = NativeTlsServer::new("identity.p12", "mypass").unwrap(); - - - println!("Listening on {}", c.bind_addr.as_str()); - if c.cert.is_some() { - let pwd = c.cert_pwd.unwrap_or_default(); - let ssl = NativeTlsServer::new(c.cert.unwrap(), &pwd).unwrap(); - - Iron::new(chain).https(c.bind_addr.as_str(), ssl).unwrap(); - }else{ - Iron::new(chain).http(c.bind_addr.as_str()).unwrap(); - } -} - - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum MountedEngine { - Ir4Local, - Ir4Http, - Ir4ProxyUncached, - PermacacheProxy, - PermacacheProxyGuessContentTypes, - Static, - //Ir4Https -} - -impl MountedEngine { - pub fn to_id(&self) -> &'static str { - match *self { - //MountedEngine::Ir4Https => "ir4_https", - MountedEngine::Ir4Http => "ir4_http", - MountedEngine::Ir4ProxyUncached => "ir4_proxy_uncached", - MountedEngine::Ir4Local => "ir4_local", - MountedEngine::PermacacheProxy => "permacache_proxy", - MountedEngine::PermacacheProxyGuessContentTypes => "permacache_proxy_guess_content_types", - MountedEngine::Static => "static" - } - } - pub fn from_id(s: &str) -> Option { - match s { - "ir4_local" => Some(MountedEngine::Ir4Local), - "ir4_http" => Some(MountedEngine::Ir4Http), - "ir4_proxy_uncached" => Some(MountedEngine::Ir4ProxyUncached), - "permacache_proxy" => Some(MountedEngine::PermacacheProxy), - "permacache_proxy_guess_content_types" => Some(MountedEngine::PermacacheProxyGuessContentTypes), - "static" => Some(MountedEngine::Static), - //"ir4_https" => Some(MountedEngine::Ir4Https), - _ => None - } - } - - pub fn id_values() -> &'static [&'static str] { - static ID_VALUES: [&'static str; 5] = ["ir4_local", "ir4_http", "permacache_proxy", "static", "permacache_proxy_guess_content_types"/* "ir4_https"*/]; - - &ID_VALUES - } -} - -trait Engine { - fn mount(self, mount: MountLocation, router: &mut Router) -> Result<(), String>; -} - -#[derive(Debug, Clone, PartialEq)] -pub struct MountLocation { - pub prefix: String, - pub engine: MountedEngine, - pub engine_args: Vec, - //TODO: HTTPS -} - -impl MountLocation { - pub fn parse(prefix: String, engine_name: String, args: Vec) -> std::result::Result { - lazy_static! { - static ref RE: Regex = Regex::new(r"\A(/[a-zA-Z0-9-_]+?)+?/\z").unwrap(); - } - if !RE.is_match(&prefix) { - return Err("mount points must be valid paths with leading and trailing slashes, like /img/logos/. Between slashes, [a-zA-Z0-9-_] may be used".to_owned()); - } - let engine = MountedEngine::from_id(engine_name.as_str()); - - if engine.is_none() { - return Err(format!("Valid engine names include {:?}. Provided {}", MountedEngine::id_values(), engine_name.as_str())); - } - - Ok(MountLocation { - prefix: prefix, - engine: engine.unwrap(), - engine_args: args - }) - } -} - - -#[derive(Debug, Clone, PartialEq)] -pub struct StartServerConfig { - pub data_dir: PathBuf, - pub bind_addr: String, - pub mounts: Vec, - pub default_cache_layout: Option, - pub integration_test: bool, - pub cert: Option, - pub cert_pwd: Option -} - - -#[test] -fn test_file_macro_for_this_build(){ - assert!(file!().starts_with(env!("CARGO_PKG_NAME"))) -} diff --git a/imageflow_server/src/main.rs b/imageflow_server/src/main.rs deleted file mode 100644 index ab68a7694..000000000 --- a/imageflow_server/src/main.rs +++ /dev/null @@ -1,200 +0,0 @@ -extern crate clap; -extern crate imageflow_server; - - -use clap::{App, Arg, SubCommand, AppSettings}; -use imageflow_server::preludes::*; -use std::path::{Path, PathBuf}; - -use std::net::ToSocketAddrs; - -extern crate imageflow_types as s; - -fn main() { - let exit_code = main_with_exit_code(); - std::process::exit(exit_code); -} - - -fn parse_mount(s: &str) -> std::result::Result{ - //Escape :: - let mut parts = s.replace("::","||||||").split(':').map(|s| s.replace("||||||",":")).collect::>(); - if parts.len() < 2 { - Err(format!("--mount prefix:engine:args Mount value must contain at least prefix:engine - received {:?} ({:?})", s, &parts)) - }else{ - MountLocation::parse(parts.remove(0), parts.remove(0), parts) - } -} - -fn main_with_exit_code() -> i32 { - let version = s::version::one_line_version(); - let app = App::new("imageflow_server").version(version.as_ref()) - .setting(AppSettings::VersionlessSubcommands).setting(AppSettings::SubcommandRequiredElseHelp) - .subcommand( - SubCommand::with_name("diagnose").setting(AppSettings::ArgRequiredElseHelp) - .about("Diagnostic utilities") - .arg( - Arg::with_name("show-compilation-info").long("show-compilation-info") - .help("Show all the information stored in this executable about the environment in which it was compiled.") - ).arg( - Arg::with_name("call-panic").long("call-panic") - .help("Triggers a Rust panic (so you can observe failure/backtrace behavior)") - ).arg( - Arg::with_name("smoke-test-core").long("smoke-test-core") - .help("Smoke test a few tiny image processing operations")) - ) - .subcommand( - SubCommand::with_name("start") - .about("Start HTTP server").setting(AppSettings::ArgRequiredElseHelp) - .arg(Arg::with_name("demo").long("demo").conflicts_with("mount").required_unless("mount") - .help("Start demo server (on localhost:39876 by default) with mounts /ir4/proxy/unsplash -> http://images.unsplash.com/")) - .arg( - Arg::with_name("mount").long("mount").takes_value(true).empty_values(false).multiple(true).required_unless("demo") - .validator(|f| parse_mount(&f).map(|_| ())) - .help("Serve images from the given location using the provided API, e.g --mount \"/prefix/:ir4_local:./{}\" --mount \"/extern/:ir4_http:http:://domain.com/\" --mount \"/extern/:ir4_proxy_uncached:http:://domain.com/\"\n Escape colons by doubling, e.g. http:// -> http:://") - ) - .arg(Arg::with_name("bind-address").long("bind-address").takes_value(true).required(false).default_value("localhost") - .help("The IPv4 or IPv6 address to bind to (or the hostname, like localhost). 0.0.0.0 binds to all addresses." - )) - .arg(Arg::with_name("port").long("port").short("-p").takes_value(true).default_value("39876").required(false).help("Set the port that the server will listen on")) - .arg(Arg::with_name("cert").long("certificate").takes_value(true).required(false).help("Path to a valid PKCS12 certificate (enables https)")) - .arg(Arg::with_name("cert-pwd").long("certificate-password").takes_value(true).required(false).help("Password to the PKCS12 certificate")) - - - .arg(Arg::with_name("data-dir").long("data-dir").takes_value(true).required_unless("demo") - .validator(|f| if Path::new(&f).is_dir() { Ok(()) } else { Err(format!("The specified data-dir {} must be an existing directory. ", f)) }) - .help("An existing directory for logging and caching")) - .arg(Arg::with_name("integration-test").long("integration-test").hidden(true).help("Never use this outside of an integration test. Exposes an HTTP endpoint to kill the server.")) - - - ); - - - - let matches = app.get_matches(); - - if let Some(matches) = matches.subcommand_matches("diagnose") { - let m: &clap::ArgMatches = matches; - - if m.is_present("show-compilation-info") { - println!("{}\n{}\n", - s::version::one_line_version(), - s::version::all_build_info_pairs()); - return 0; - } - if m.is_present("call-panic") { - panic!("Panicking on command"); - } - if m.is_present("smoke-test-core") { - ::imageflow_server::diagnose::smoke_test_core(); - return 0; - } - } - if let Some(matches) = matches.subcommand_matches("start") { - let m: &clap::ArgMatches = matches; - - - let port = matches.value_of("port").map(|s| s.parse::().expect("Port must be a valid 16-bit positive integer") ).unwrap_or(39_876); - let integration_test = matches.is_present("integration-test"); - let data_dir = m.value_of("data-dir").map(PathBuf::from); - let cert = m.value_of("cert").map(PathBuf::from); - if let Some(ref p) = cert{ - if !p.is_file(){ - println!("The provided certificate file does not exist: {:?}", &cert); - std::process::exit(64); - } - } - let bind = m.value_of("bind-address").map(|s| s.to_owned()).expect("bind address required"); - - let combined = format!("{}:{}", bind, port); - - { - let socket_addr_iter = combined.to_socket_addrs(); - if socket_addr_iter.is_err() || socket_addr_iter.unwrap().next().is_none() { - println!("Invalid value for --bind-address. {} failed to parse.", &combined); - std::process::exit(64); - } - } - - if m.is_present("demo"){ - //TODO: fetch an examples directory, with javascript/html/css and images, and mount that - - - // If not provided, ./imageflow_data is created and used - - let alt_data_dir = Path::new(".").join("imageflow_data"); - - - let demo_commit = s::version::get_build_env_value("GIT_COMMIT").unwrap(); - - let mut mounts = vec![ - MountLocation { - engine: MountedEngine::Ir4Http, - prefix: "/ir4/proxy_unsplash/".to_owned(), - engine_args: vec!["http://images.unsplash.com/".to_owned()] - }, - MountLocation { - engine: MountedEngine::PermacacheProxyGuessContentTypes, - prefix: "/proxied_demo/".to_owned(), - engine_args: vec![format!("https://raw.githubusercontent.com/imazen/imageflow/{}/imageflow_server/demo/", demo_commit)] - }, - MountLocation { - engine: MountedEngine::Ir4Http, - prefix: "/demo_images/".to_owned(), - engine_args: vec!["http://resizer-images.s3.amazonaws.com/".to_owned()] - }, - MountLocation { - engine: MountedEngine::Ir4Http, - prefix: "/website_images/".to_owned(), - engine_args: vec!["http://resizer-web.s3.amazonaws.com/".to_owned()] - }, - MountLocation { - engine: MountedEngine::Ir4ProxyUncached, - prefix: "/demo_images_uncached/".to_owned(), - engine_args: vec!["http://resizer-images.s3.amazonaws.com/".to_owned()] - } - ]; - let local_demo_folder = Path::new(env!("CARGO_MANIFEST_DIR")).join("demo"); - if local_demo_folder.exists() { - mounts.push(MountLocation { - engine: MountedEngine::Static, - prefix: "/src_demo/".to_owned(), - engine_args: vec![local_demo_folder.as_path().to_str().unwrap().to_owned()] - }); - - println!("Open your browser to http://{}/src_demo/index.html", &combined); - }else{ - println!("Open your browser to http://{}/proxied_demo/index.html", &combined); - - } - - println!("{}",&version); - ::imageflow_server::serve(StartServerConfig { - bind_addr: combined, - data_dir: data_dir.unwrap_or_else(|| { if !alt_data_dir.exists() { std::fs::create_dir_all(&alt_data_dir).unwrap(); } alt_data_dir }), - default_cache_layout: Some(FolderLayout::Tiny), - integration_test: integration_test, - mounts: mounts, - cert: cert, - cert_pwd: m.value_of("cert-pwd").map(|s| s.into()), - }); - }else { - let mounts = m.values_of_lossy("mount").expect("at least one --mount required").into_iter().map(|s| parse_mount(&s).expect("validator not working - bug in clap?")).collect::>(); - - println!("{}",&version); - ::imageflow_server::serve(StartServerConfig { - bind_addr: combined, - data_dir: data_dir.expect("data-dir required"), - mounts: mounts, - default_cache_layout: Some(FolderLayout::Normal), - integration_test: integration_test, - cert: cert, - cert_pwd: m.value_of("cert-pwd").map(|s| s.into()), - }); - } - return 0; - } - - 64 -} - diff --git a/imageflow_server/src/mem_cache.rs b/imageflow_server/src/mem_cache.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/imageflow_server/src/requested_path.rs b/imageflow_server/src/requested_path.rs deleted file mode 100644 index 56a0b106f..000000000 --- a/imageflow_server/src/requested_path.rs +++ /dev/null @@ -1,63 +0,0 @@ -/* The MIT License (MIT) - -Copyright (c) 2014 iron - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. */ - - -use iron::Request; -use std::iter::FromIterator; -use std::path::{Component, PathBuf, Path}; -use std::convert::AsRef; -use url::percent_encoding::percent_decode; - -pub struct RequestedPath { - pub path: PathBuf, -} - -#[inline] -fn decode_percents(string: &&str) -> String { - percent_decode(string.as_bytes()).decode_utf8().unwrap().into_owned() -} - -fn normalize_path(path: &Path) -> PathBuf { - path.components().fold(PathBuf::new(), |mut result, p| { - match p { - Component::Normal(x) => { - result.push(x); - result - } - Component::ParentDir => { - result.pop(); - result - }, - _ => result - } - }) -} - -impl RequestedPath { - pub fn new>(root_path: P, request: &Request) -> RequestedPath { - let decoded_req_path = PathBuf::from_iter(request.url.path().iter().map(decode_percents)); - let mut result = root_path.as_ref().to_path_buf(); - result.extend(&normalize_path(&decoded_req_path)); - RequestedPath { path: result } - } - -} diff --git a/imageflow_server/src/resizer/mod.rs b/imageflow_server/src/resizer/mod.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/imageflow_server/tests/test_ir4.rs b/imageflow_server/tests/test_ir4.rs deleted file mode 100644 index b5ce4cf26..000000000 --- a/imageflow_server/tests/test_ir4.rs +++ /dev/null @@ -1,458 +0,0 @@ - -extern crate imageflow_helpers; -extern crate imageflow_core as fc; -extern crate imageflow_types as s; -use imageflow_helpers::preludes::from_std::*; -extern crate hyper; - - -extern crate wait_timeout; -use wait_timeout::ChildExt; -use std::time::Duration; -use std::process::{Command, Stdio, Output}; -use std::net::{TcpListener}; - -#[macro_use] -extern crate lazy_static; - -use std::sync::Mutex; - -use imageflow_helpers::process_testing::*; -use crate::fc::test_helpers::process_testing::ProcTestContextExtras; -use ::imageflow_http_helpers::{fetch, fetch_bytes,get_status_code_for, FetchError, FetchConfig}; - -use std::collections::vec_deque::VecDeque; -use reqwest::StatusCode; - -lazy_static! { - static ref RECENT_PORTS: Mutex> = Mutex::new(VecDeque::new()); -} - -fn assert_valid_image(url: &str) { - match fetch(url, Some(FetchConfig{ custom_ca_trust_file: None, read_error_body: Some(true)})){ - Ok(v) => { - if !v.code.is_success(){ - panic!("Error {:?} for {}", v.code, &url); - } - fc::clients::stateless::LibClient {}.get_image_info(&v.bytes).expect("Image response should be valid"); - }, - Err(e) => { panic!("{:?} for {}", &e, &url); } - } -} - -fn assert_ok(url: &str) { - match fetch(url, Some(FetchConfig{ custom_ca_trust_file: None, read_error_body: Some(true)})){ - Ok(response) => { - if !response.code.is_success(){ - panic!("Error {:?} for {}", response.code, &url); - } - }, - Err(e) => { panic!("{:?} for {}", &e, &url); } - } -} -//fn write_env_vars(path: &Path){ -// let mut f = File::create(&path).unwrap(); -// for (k,v) in std::env::vars(){ -// write!(f, "{}={}\n", k, v).unwrap(); -// } -//} - -fn build_dirs() -> Vec{ - let target_triple = crate::s::version::get_build_env_value("TARGET").expect("TARGET triple required"); - let profile = crate::s::version::get_build_env_value("PROFILE").expect("PROFILE (debug/release) required"); - - - let target_dir = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().join("target"); - - let a = target_dir.join(target_triple).join(profile); - let b = target_dir.join(profile); - vec![a,b] -} -#[cfg(windows)] -fn binary_ext() -> &'static str{ - "exe" -} -#[cfg(not(windows))] -fn binary_ext() -> &'static str{ - "" -} - -fn locate_binary(name: &str) -> Option { - for dir in build_dirs() { - let file_path = dir.join(name).with_extension(binary_ext()); - - if file_path.exists() { - return Some(dir.join(name)) - } - } - None -} - - -fn server_path() -> PathBuf { - match locate_binary("imageflow_server"){ - Some(v) => v, - None => { - panic!("Failed to locate imageflow_server binary in {:?}", build_dirs()); - } - } -} - -fn enqueue_unique_port(q: &mut VecDeque, count: usize) -> u16{ - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - if !q.contains(&port) { - q.push_back(port); - if count <= 1{ - port - }else { - enqueue_unique_port(q, count - 1) - } - } else { - enqueue_unique_port(q, count) - } -} - -fn fetch_next_port(q: &mut VecDeque) -> u16 { - if q.len() < 1 { - let _ = enqueue_unique_port(q, 25); // pre-check ports 25 at a time. - } - q.pop_front().unwrap() -} - -fn get_next_port() -> u16 { - let mut q = RECENT_PORTS.lock().unwrap(); - fetch_next_port(&mut q) -} - - -struct ServerInstance{ - port: u16, - protocol: Proto, - #[allow(dead_code)] - trust_ca_file: Option, - #[allow(dead_code)] - cert: Option - -} - -type CallbackResult = std::result::Result<(), ::imageflow_http_helpers::FetchError>; - -#[derive(Debug,PartialEq,Eq,Copy,Clone)] -enum Proto{ - Http, - Https -} -impl ServerInstance{ - - fn hello(&self) -> Result { - get_status_code_for(&self.url_for("/hello/are/you/running?")) - } - - fn url_for(&self, rel_path: &str) -> String{ - if self.protocol == Proto::Https{ - format!("https://localhost:{}{}", self.port,rel_path) - }else{ - format!("http://localhost:{}{}", self.port,rel_path) - } - - } - - fn get_status(&self, rel_path: &str) -> Result { - get_status_code_for(&self.url_for(rel_path)) - } - - fn request_stop(&self) -> Result { - get_status_code_for(&self.url_for("/test/shutdown")) - } - - fn run(c: &ProcTestContext, protocol: Proto, args: Vec<&str>, callback: F) -> (ProcOutput, CallbackResult) - where F: Fn(&ServerInstance) -> CallbackResult { - let assets = Path::new(env!("CARGO_MANIFEST_DIR")).join(Path::new("src")).join(Path::new("assets")); - let cert_path = assets.join(Path::new("identity.p12")); - let ca_path = assets.join(Path::new("root-ca.pem")); - - - let instance = ServerInstance { - port: get_next_port(), - protocol, - trust_ca_file: Some(ca_path), - cert: Some(cert_path.clone()) - }; - // NOTE --bind=localhost::{} (two colons) causes a generic "error:",exit code 1, and no other output. This is bad UX. - let test_arg = "--integration-test"; - let port_arg = format!("--port={}", instance.port); - - let mut all_args = args.clone(); - if protocol == Proto::Https{ - all_args.insert(0, "mypass"); - all_args.insert(0, "--certificate-password"); - all_args.insert(0, cert_path.to_str().unwrap()); - all_args.insert(0, "--certificate"); - } - all_args.insert(0, test_arg); - all_args.insert(0, &port_arg); - all_args.insert(0, "start"); - - c.execute_callback(all_args, false, - |_child: &mut std::process::Child| -> std::result::Result<(), ::imageflow_http_helpers::FetchError> { - - ::std::thread::sleep(::std::time::Duration::from_millis(500)); - // Server may not be running - instance.hello()?; - - let r = callback(&instance); - - let _ = instance.request_stop(); - r - }) - //po.expect_status_code(Some(0)); - } -} - - -// ports 36,000 to 39,999 seem the safest. -#[test] -fn run_server_test_i4(){ - - //write_env_vars(&Path::new("env.txt")); - - let context = ProcTestContext::create_timestamp_subdir_within(std::env::current_dir().unwrap().join("server_tests"), Some(server_path())); - - { - let c = context.subfolder_context("basics"); - c.exec("diagnose --show-compilation-info").expect_status_code(Some(0)); - c.exec("--version").expect_status_code(Some(0)); - c.exec("-V").expect_status_code(Some(0)); - - //TODO: test diagnose --call-panic (xplat hard) - - //Test incorrect args - c.execute(vec!["demo"], false, |_child: &mut std::process::Child| { - }).expect_status_code(Some(1)); - - } - - { - let c = context.subfolder_context("demo"); //stuck on port 39876 - c.subfolder_context("demo"); - let (_po, callback_result) = ServerInstance::run(&c, Proto::Http, vec!["--demo", "--data-dir=."], | server | { - assert_ok(&server.url_for("/imageflow.ready")); - assert_ok(&server.url_for("/imageflow.health")); - - fetch_bytes(&server.url_for("/ir4/proxy_unsplash/photo-1422493757035-1e5e03968f95?width=100"))?; - //TODO: Find a way to test upstream 404 and 403 errors - // assert_eq!(server.get_status("/demo_images/notthere.jpg")?, http::StatusCode::NOT_FOUND); - - let url = server.url_for("/proxied_demo/index.html"); - match fetch(&url, Some(FetchConfig{ custom_ca_trust_file: None, read_error_body: Some(true)})){ - Ok(_) => {}, - Err(e) => { panic!("{:?} for {}", &e, &url); } - } - - assert_valid_image(&server.url_for("/demo_images/example-028-whitespace.jpg?width=600&trim.threshold=80&trim.percentpadding=0.5")); - - - Ok(()) - }); - - //po.expect_status_code(Some(0)); - - callback_result.unwrap(); - } - { - let c = context.subfolder_context("proxy"); - c.subfolder_context("proxy"); - let (_po, callback_result) = ServerInstance::run(&c, Proto::Http, vec!["--data-dir=.", "--mount","/extern/:ir4_http:http:://images.unsplash.com/"], | server | { - fetch_bytes(&server.url_for("/extern/photo-1422493757035-1e5e03968f95?width=100"))?; - Ok(()) - }); - - //po.expect_status_code(Some(0)); - - callback_result.unwrap(); - } - { - let c = context.subfolder_context("mount_local"); //stuck on port 39876 - c.create_blank_image_here("eh", 100,100, s::EncoderPreset::libpng32()); - let a = c.subfolder_context("a"); //stuck on port 39876 - a.create_blank_image_here("eh2", 100,100, s::EncoderPreset::libpng32()); - - let mut params = vec!["--data-dir=.", "--mount=/local/:ir4_local:./", - "--mount=/local_1/:ir4_local:./a", - "--mount=/local_2/:ir4_local:./a/", - "--mount=/local_3/:ir4_local:a"]; - if std::path::MAIN_SEPARATOR == '\\'{ - params.push(r"--mount=/local_4/:ir4_local:.\a"); - params.push(r"--mount=/local_5/:ir4_local:.\a/"); - params.push(r"--mount=/local_6/:ir4_local:.\a\"); - } - - let last_mount = params.len() - 2; - - let (_, callback_result) = ServerInstance::run(&c, Proto::Http, params , | server | { - assert_valid_image(&server.url_for("/local/eh.png?width=100")); - - for ix in 1..last_mount + 1{ - let url = format!("/local_{ix}/eh2.png?w=1", ix=ix); - println!("Testing {}", &url); - assert_valid_image(&server.url_for(&url)); - } - - - assert_eq!(server.get_status("/local/notthere.jpg")?, StatusCode::NOT_FOUND); - assert_eq!(server.get_status("/notrouted")?, StatusCode::NOT_FOUND); - Ok(()) - }); - //po.expect_status_code(Some(0)); - - callback_result.unwrap(); - } - - // we can't currently test https server support. We *should* be able to, on linux - but ... nope. - //test_https(context); -} - -#[allow(dead_code)] -#[cfg(not(any(target_os = "windows", target_os = "macos")))] -fn test_https(context: &ProcTestContext){ - { - let c = context.subfolder_context("https_demo"); //stuck on port 39876 - c.subfolder_context("demo"); - let (_, callback_result) = ServerInstance::run(&c, Proto::Https, vec!["--demo", "--data-dir=."], | server | { - let url = server.url_for("/ir4/proxy_unsplash/photo-1422493757035-1e5e03968f95?width=100"); - let bytes = fetch(&url, Some(FetchConfig{custom_ca_trust_file: server.trust_ca_file.clone(), read_error_body: Some(true) })).expect(&url).bytes; - let _ = fc::clients::stateless::LibClient {}.get_image_info(&bytes).expect("Image response should be valid"); - - //assert_eq!(server.get_status("/ir4/proxy_unsplash/notthere.jpg")?, http::StatusCode::NOT_FOUND); - Ok(()) - }); - - //po.expect_status_code(Some(0)); - - callback_result.unwrap(); - } -} - -#[allow(dead_code)] -#[cfg(any(target_os = "windows", target_os = "macos"))] -fn test_https(_context: ProcTestContext){} - -#[test] -fn run_server_test_ir4_heavy(){ - let context = ProcTestContext::create_timestamp_subdir_within(std::env::current_dir().unwrap().join("server_tests_heavy"), Some(server_path())); - { - let c = context.subfolder_context("mount_local_test"); //stuck on port 39876 - c.exec("diagnose --show-compilation-info").expect_status_code(Some(0)); - c.create_blank_image_here("eh", 100,100, s::EncoderPreset::libpng32()); - - let params = vec!["--data-dir=.", "--mount=/local/:ir4_local:./"]; - let (_, callback_result) = ServerInstance::run(&c, Proto::Http, params , | server | { - for _ in 1..20{ - assert_valid_image(&server.url_for("/local/eh.png?width=100")); - } - Ok(()) - }); - callback_result.unwrap(); - } -} - -trait ProcTestContextHttp{ - fn execute_callback(&self, args_vec: Vec<&str>, valgrind_on_signal_death: bool, callback: F) -> (ProcOutput, T) -where F: Fn(&mut std::process::Child) -> T; - -} -impl ProcTestContextHttp for ProcTestContext{ - - /// - /// Pass false for valgrind_on_signal_death if your callback might kill the child - fn execute_callback(&self, args_vec: Vec<&str>, valgrind_on_signal_death: bool, callback: F) -> (ProcOutput, T) - where F: Fn(&mut std::process::Child) -> T { - //TODO: serialize in a safer way - this isn't correct - let full_invocation = format!("{} {}", &self.bin_location().to_str().unwrap(), args_vec.join(" ")); - - let dir = self.working_dir(); - let exe = self.bin_location(); - - let valgrind_copy_result = self.create_valgrind_suppressions(); - let _ = writeln!(&mut std::io::stderr(), - "Executing from folder {} with valgrind_suppressions {:?}\n{}", - dir.to_str().unwrap(), - valgrind_copy_result, - full_invocation); - // change working dir to dir - let mut cmd = Command::new(exe); - cmd.args(args_vec.as_slice()).current_dir(dir).env("RUST_BACKTRACE", "1"); - - - //cmd.stderr(Stdio::piped()).stdout(Stdio::piped()); - cmd.stderr(Stdio::inherit()).stdout(Stdio::inherit()); - - - let mut child = cmd.spawn().expect("Failed to start?"); - - - let result = callback(&mut child); - - - //child.kill().unwrap(); - let timeout = Some(Duration::from_secs(1)); - - let (status_code, output) = match timeout { - Some(timeout) => { - match child.wait_timeout(timeout).unwrap() { - Some(status) => (status.code(), None), - None => { - // child hasn't exited yet - child.kill().unwrap(); - (child.wait().unwrap().code(), None) - } - } - } - None => { - let output: Output = child.wait_with_output().unwrap(); - (output.status.code(), Some(output)) - } - }; - - let _ = writeln!(&mut std::io::stderr(), - "exit code {:?}", status_code); - - // Double check we dumped output on segfault - if status_code == None { - if let Some(ref out) = output { - std::io::stderr().write_all(&out.stderr).unwrap(); - std::io::stdout().write_all(&out.stdout).unwrap(); - } - let _ = writeln!(&mut std::io::stderr(), - "exit code {:?}", status_code); - } - // Killed by signal. - // 11 Segmentation fault - // 4 illegal instruction 6 abort 8 floating point error - if status_code == None && valgrind_on_signal_death { - if std::env::var("VALGRIND_RUNNING").is_ok() { - let _ = writeln!(&mut std::io::stderr(), - "VALGRIND_RUNNING defined; skipping valgrind pass"); - } else { - //ALLOW TO FAIL; valgrind may not be present - let _ = writeln!(&mut std::io::stderr(), - "Starting valgrind from within self-test:"); - let mut cmd = Command::new("valgrind"); - cmd.arg("-q").arg("--error-exitcode=9").arg(exe); - cmd.args(args_vec.as_slice()).current_dir(dir).env("RUST_BACKTRACE", "1").env("VALGRIND_RUNNING", "1"); - - let _ = writeln!(&mut std::io::stderr(), - "{:?}", cmd); - - let _ = cmd.status(); //.expect("Failed to start valgrind?"); - } - } - - match output { - Some(out) => (ProcOutput::from(out), result), - None => (ProcOutput::from_code(status_code), result) - } - } - -} diff --git a/imageflow_server/try.sh b/imageflow_server/try.sh deleted file mode 100755 index a3b8e225f..000000000 --- a/imageflow_server/try.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -set -e - - -firefox http://localhost:3000 & cargo run --bin imageflow_server start & wait