diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 30d2147..9fe6dc5 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -100,6 +100,15 @@ jobs: run: | echo "nightly ${{ steps.vars.outputs.GITHUB_SHA_SHORT }} ${{ steps.vars.outputs.RELEASE_OS }} (${{ steps.vars.outputs.RELEASE_DATE }})" > build_metadata.txt + - name: (Mac only) Install "coreutils" to be able to get file hash + if: runner.os == 'macOS' + run: | + brew install coreutils + + - name: 🛒 Download Caddy + run: | + bin/download_caddy.bash + - name: 🏗 Build run: | cat build_metadata.txt @@ -189,6 +198,10 @@ jobs: run: | echo "nightly ${{ steps.vars.outputs.GITHUB_SHA_SHORT }} ${{ steps.vars.outputs.RELEASE_OS }} (${{ steps.vars.outputs.RELEASE_DATE }})" > build_metadata.txt + - name: 🛒 Download Caddy + run: | + bin/download_caddy.ps1 + - name: 🏗 Build run: | cat build_metadata.txt diff --git a/.gitignore b/.gitignore index 11d66d5..20d4197 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ +/bin/caddy +/bin/caddy.* +/build.err +/build.log /target -certs/* -!certs/generate_certificates.sh -.fpm.pid -.pid -_local_logs.txt +/certs/* +/!certs/generate_certificates.sh +/_local_logs.txt /tests/workdir/ -server.log +/server.log diff --git a/CHANGELOG.md b/CHANGELOG.md index b503f83..8c70dab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v0.3.0 + +* Embed Caddy server into Rymfony, instead of using Warp (by @Pierstoval in https://github.com/Orbitale/Rymfony/pull/85) + # v0.2.3 * Allow to run php-fpm (and by extension Rymfony itself) as root by @Shine-neko in #86 diff --git a/Cargo.lock b/Cargo.lock index 081bec0..173cef0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,12 +35,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "anyhow" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" - [[package]] name = "arrayref" version = "0.3.6" @@ -129,34 +123,12 @@ dependencies = [ "serde", ] -[[package]] -name = "buf_redux" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" -dependencies = [ - "memchr", - "safemem", -] - -[[package]] -name = "bumpalo" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" - [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" - [[package]] name = "cc" version = "1.0.68" @@ -169,19 +141,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", -] - [[package]] name = "clap" version = "2.33.3" @@ -218,16 +177,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "core-foundation" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.2" @@ -412,128 +361,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "fastcgi-client" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61fbb5ca89fa90ca84d1085d017bacd85c4de0df2164888ef03564519b8111e3" -dependencies = [ - "http", - "log", - "thiserror", - "tokio", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" - -[[package]] -name = "futures-io" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" - -[[package]] -name = "futures-macro" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" -dependencies = [ - "autocfg", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" - -[[package]] -name = "futures-task" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" - -[[package]] -name = "futures-util" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" -dependencies = [ - "autocfg", - "futures-core", - "futures-macro", - "futures-sink", - "futures-task", - "pin-project-lite", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - [[package]] name = "generic-array" version = "0.14.4" @@ -578,56 +405,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "h2" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" - -[[package]] -name = "headers" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855" -dependencies = [ - "base64", - "bitflags", - "bytes", - "headers-core", - "http", - "mime", - "sha-1", - "time", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - [[package]] name = "hermit-abi" version = "0.1.18" @@ -637,40 +414,6 @@ dependencies = [ "libc", ] -[[package]] -name = "http" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" - -[[package]] -name = "httpdate" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" - [[package]] name = "humantime" version = "1.3.0" @@ -686,86 +429,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-staticfile" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf435f95723ba94d2e44991abf717dd547b73f505830a917dc442a9195df06b" -dependencies = [ - "chrono", - "futures-util", - "http", - "hyper", - "mime_guess", - "percent-encoding", - "tokio", - "url", - "winapi", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "input_buffer" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" -dependencies = [ - "bytes", -] - -[[package]] -name = "instant" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" -dependencies = [ - "cfg-if", -] - [[package]] name = "is_executable" version = "1.0.1" @@ -781,15 +444,6 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" -[[package]] -name = "js-sys" -version = "0.3.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -802,15 +456,6 @@ version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" -[[package]] -name = "lock_api" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" -dependencies = [ - "scopeguard", -] - [[package]] name = "log" version = "0.4.14" @@ -820,12 +465,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" - [[package]] name = "memchr" version = "2.4.0" @@ -841,22 +480,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mime_guess" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "miniz_oxide" version = "0.4.4" @@ -867,64 +490,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mio" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "multipart" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4" -dependencies = [ - "buf_redux", - "httparse", - "log", - "mime", - "mime_guess", - "quick-error", - "rand 0.7.3", - "safemem", - "tempfile", - "twoway", -] - -[[package]] -name = "native-tls" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nix" version = "0.20.0" @@ -946,25 +511,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - [[package]] name = "num_cpus" version = "1.13.0" @@ -997,148 +543,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "openssl" -version = "0.10.35" +name = "os_info" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885" +checksum = "b3d2536ab8ff7605e8dc7044ec2f3eb0d49750cb559af9e5373c4564a3706cdd" dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", + "log", + "winapi", ] [[package]] -name = "openssl-probe" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" - -[[package]] -name = "openssl-src" -version = "111.15.0+1.1.1k" +name = "pretty_env_logger" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" dependencies = [ - "cc", + "env_logger 0.7.1", + "log", ] [[package]] -name = "openssl-sys" -version = "0.9.64" +name = "prettytable-rs" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209efc2fe0e980c8849efacdb567f975a1c80245c4f6980d6f012733bfa851af" -dependencies = [ - "autocfg", - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "os_info" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d2536ab8ff7605e8dc7044ec2f3eb0d49750cb559af9e5373c4564a3706cdd" -dependencies = [ - "log", - "winapi", -] - -[[package]] -name = "parking_lot" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.9", - "smallvec", - "winapi", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pin-project" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "pretty_env_logger" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger 0.7.1", - "log", -] - -[[package]] -name = "prettytable-rs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" +checksum = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" dependencies = [ "atty", "csv", @@ -1148,18 +576,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" version = "1.0.27" @@ -1184,87 +600,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", -] - -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", - "rand_hc 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - [[package]] name = "rayon" version = "1.5.1" @@ -1349,30 +684,6 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - [[package]] name = "runas" version = "0.2.1" @@ -1401,39 +712,18 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64", - "log", - "ring", - "sct", - "webpki", -] - [[package]] name = "rymfony" version = "0.1.0" dependencies = [ - "anyhow", "clap", "console", "ctrlc", "dirs 3.0.2", "env_logger 0.8.4", - "fastcgi-client", "glob", - "http", - "httparse", - "hyper", - "hyper-staticfile", "is_executable", "log", - "openssl", - "openssl-sys", "os_info", "pretty_env_logger", "prettytable-rs", @@ -1443,12 +733,8 @@ dependencies = [ "serde_json", "sha2", "sysinfo", - "tokio", - "tokio-native-tls", - "urldecode", "users", "version-compare", - "warp", "which 4.1.0", ] @@ -1458,67 +744,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" - -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "security-framework" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.126" @@ -1550,31 +781,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16" -dependencies = [ - "block-buffer", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.9.5" @@ -1588,43 +794,6 @@ dependencies = [ "opaque-debug", ] -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" - -[[package]] -name = "smallvec" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" - -[[package]] -name = "socket2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "strsim" version = "0.8.0" @@ -1658,20 +827,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if", - "libc", - "rand 0.8.4", - "redox_syscall 0.2.9", - "remove_dir_all", - "winapi", -] - [[package]] name = "term" version = "0.5.2" @@ -1711,235 +866,12 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "thiserror" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "tinyvec" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb2ed024293bb19f7a5dc54fe83bf86532a44c12a2bb8ba40d64a4509395ca2" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-stream" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b" -dependencies = [ - "futures-util", - "log", - "pin-project", - "tokio", - "tungstenite", -] - -[[package]] -name = "tokio-util" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - -[[package]] -name = "tracing" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "tungstenite" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24" -dependencies = [ - "base64", - "byteorder", - "bytes", - "http", - "httparse", - "input_buffer", - "log", - "rand 0.8.4", - "sha-1", - "url", - "utf-8", -] - -[[package]] -name = "twoway" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" -dependencies = [ - "memchr", -] - [[package]] name = "typenum" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" -dependencies = [ - "matches", -] - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-width" version = "0.1.8" @@ -1952,30 +884,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "urldecode" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "070c2eb79ba268848a73885f94a83b86d9e6441c5d5b10727d5f8989db2c8edc" - [[package]] name = "users" version = "0.11.0" @@ -1986,18 +894,6 @@ dependencies = [ "log", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "vec_map" version = "0.8.2" @@ -2016,46 +912,6 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "warp" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332d47745e9a0c38636dbd454729b147d16bd1ed08ae67b3ab281c4506771054" -dependencies = [ - "bytes", - "futures", - "headers", - "http", - "hyper", - "log", - "mime", - "mime_guess", - "multipart", - "percent-encoding", - "pin-project", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-rustls", - "tokio-stream", - "tokio-tungstenite", - "tokio-util", - "tower-service", - "tracing", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -2068,80 +924,6 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" -[[package]] -name = "wasm-bindgen" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" - -[[package]] -name = "web-sys" -version = "0.3.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "which" version = "3.1.1" diff --git a/Cargo.toml b/Cargo.toml index 5ff8319..120b821 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,34 +7,22 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0" clap = "2.33" console = "0.14" ctrlc = { version = "3.1", features = ["termination"] } dirs = "3.0" env_logger = "0.8" -fastcgi-client = "0.7" glob = "0.3" -http = "0.2" -httparse = "1.4" -hyper = "0.14" -hyper-staticfile = "0.6" is_executable = "1.0" log = "0.4" -openssl = { version = "0.10", features = ["vendored"] } -openssl-sys = "0.9" os_info = { version = "3.0", default-features = false } pretty_env_logger = "0.4" prettytable-rs = "0.8" regex = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.2", features = ["full"] } -tokio-native-tls = "0.3" -urldecode = "0.1" version-compare = "0.0.11" which = "4.1" -warp = { version = "0.3", features = ["tls"]} runas = "0.2" sha2 = "0.9" sysinfo = "0.18" @@ -42,6 +30,9 @@ sysinfo = "0.18" [target.'cfg(not(target_family = "windows"))'.dependencies] users = "0.11" +[build-dependencies] +which = "4.1" + [profile.release] opt-level = 'z' # Optimize for size. lto = true # Optimize at the link stage with "Link Time Optimization" diff --git a/bin/download_caddy.bash b/bin/download_caddy.bash new file mode 100755 index 0000000..f3889ac --- /dev/null +++ b/bin/download_caddy.bash @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +set -eu + +# The goal here is to +# Check releases, and update the associated data here. +# @link https://github.com/caddyserver/caddy/releases +caddy_version="2.4.5" + +function output { + style_start="" + style_end="" + if [ "${2:-}" != "" ]; then + case $2 in + "success") + style_start="\033[0;32m" + style_end="\033[0m" + ;; + "error") + style_start="\033[31;31m" + style_end="\033[0m" + ;; + "info"|"warning") + style_start="\033[33m" + style_end="\033[39m" + ;; + "heading") + style_start="\033[1;33m" + style_end="\033[22;39m" + ;; + esac + fi + + builtin echo -e "${style_start}${1}${style_end}" +} + + +kernel=$(uname -s 2>/dev/null || /usr/bin/uname -s) +case ${kernel} in + "Linux"|"linux") + kernel="linux" + ;; + "Darwin"|"darwin") + kernel="mac" + ;; + *) + output "Your OS '${kernel}' not supported" "error" + exit 1 + ;; +esac + + +machine=$(uname -m 2>/dev/null || /usr/bin/uname -m) +case ${machine} in + arm|armv7*) + machine="arm" + ;; + aarch64*|armv8*|arm64) + machine="arm64" + ;; + i[36]86) + machine="386" + ;; + x86_64) + machine="amd64" + ;; + *) + output "Your architecture '${machine}' is not currently supported" "error" + exit 1 + ;; +esac + +platform="${kernel}_${machine}" + +output "Platform: ${platform}" "info" + +release_filename="caddy_${caddy_version}_${platform}.tar.gz" + +binary_url="https://github.com/caddyserver/caddy/releases/download/v${caddy_version}/${release_filename}" + +output "Downloading ${release_filename}" "info" + +output "Downloading from "${binary_url}"" "info" + +tmpfile_caddy=$(mktemp /tmp/rymfonycaddy.XXXXXXXXXX) +curl -sSL "${binary_url}" --output "${tmpfile_caddy}" + +tar -xvzf "${tmpfile_caddy}" -C bin/ caddy + +output "Caddy was successfully downloaded to bin/caddy" "success" diff --git a/bin/download_caddy.ps1 b/bin/download_caddy.ps1 new file mode 100644 index 0000000..affa3cc --- /dev/null +++ b/bin/download_caddy.ps1 @@ -0,0 +1,33 @@ + +# The goal here is to +# Check releases, and update the associated data here. +# @link https://github.com/caddyserver/caddy/releases +$caddy_version = "2.4.3" + +# We only support this version for now. +# Windows won't probably be the most used platform anyway. +$release_filename = "windows_amd64" + +# Download Caddy +$binary_url = "https://github.com/caddyserver/caddy/releases/download/v${caddy_version}/caddy_${caddy_version}_${release_filename}.zip" +$tmpfile_caddy = New-TemporaryFile +Invoke-WebRequest -uri $binary_url -OutFile $tmpfile_caddy + +# Output it to bin/caddy.exe +$output_path = Write-Output $pwd\bin +Add-Type -AssemblyName System.IO.Compression.FileSystem +$zip = [System.IO.Compression.ZipFile]::OpenRead($tmpfile_caddy) # Open ZIP archive for reading +# Find all files in ZIP that match the filter "caddy.exe" +$zip.Entries | + Where-Object { $_.FullName -like 'caddy.exe' } | + ForEach-Object { + # extract the selected items from the ZIP archive and copy them to the output folder + $FileName = $_.Name + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "$output_path\$FileName", $true) + } +$zip.Dispose() # Close ZIP file + +# Remove temporary file +rm $tmpfile_caddy + +Write-Output "Caddy was successfully downloaded to $output_path\$FileName" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..213b668 --- /dev/null +++ b/build.rs @@ -0,0 +1,56 @@ +use std::process::Command; +use std::process::Stdio; +use std::path::Path; +use std::fs::File; +use std::fs::remove_file; +use std::fs::read_to_string; + +#[cfg(target_os="windows")] +mod config { + pub(crate) const CADDY_BIN_FILE: &'static str = "caddy.exe"; + pub(crate) const SHELL_TO_EXEC: &'static str = "powershell.exe"; + pub(crate) const DOWNLOAD_CADDY_SCRIPT: &'static str = "download_caddy.ps1"; +} + +#[cfg(not(target_os="windows"))] +mod config { + pub(crate) const CADDY_BIN_FILE: &'static str = "caddy"; + pub(crate) const SHELL_TO_EXEC: &'static str = "bash"; + pub(crate) const DOWNLOAD_CADDY_SCRIPT: &'static str = "download_caddy.bash"; +} + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=bin/{}", config::DOWNLOAD_CADDY_SCRIPT); + + println!("cargo:rerun-if-changed=bin/{}", config::CADDY_BIN_FILE); + + let stdout_file_path = Path::new("build.log"); + if stdout_file_path.is_file() { remove_file(stdout_file_path).unwrap(); } + + let stderr_file_path = Path::new("build.err"); + if stderr_file_path.is_file() { remove_file(stderr_file_path).unwrap(); } + + let shell = which::which(config::SHELL_TO_EXEC).unwrap(); + + let mut command = Command::new(shell); + command + .stdin(Stdio::null()) + .stdout(Stdio::from(File::create(stdout_file_path).unwrap())) + .stderr(Stdio::from(File::create(stderr_file_path).unwrap())) + .arg(format!("bin/{}", config::DOWNLOAD_CADDY_SCRIPT)) + ; + + match command.output() { + Ok(output) => { + let code = output.status.code().unwrap(); + if code != 0 { + let error = read_to_string("build.err").expect("Could not retrieve error log after failing to download Caddy server."); + panic!("\n An error occured when downloading Caddy.\n Here is the error log:\n{}\n", error); + } + }, + Err(e) => { + panic!("Could not download Caddy: {}", e); + } + }; +} diff --git a/src/commands/ca_install.rs b/src/commands/ca_install.rs deleted file mode 100644 index 1441b97..0000000 --- a/src/commands/ca_install.rs +++ /dev/null @@ -1,91 +0,0 @@ -use std::path::PathBuf; - -use clap::App; -use clap::ArgMatches; -use clap::SubCommand; -use runas::Command as SudoCommand; - -use crate::config::certificates; - -pub(crate) fn command_config<'a, 'b>() -> App<'a, 'b> { - SubCommand::with_name("server:ca:install") - .name("server:ca:install") - .alias("ca:install") - .about("Create and install a local Certificate Authority for serving HTTPS") -} - -pub(crate) fn ca_install(_args: &ArgMatches) { - let (certificate_path, _key_path) = certificates::get_ca_cert_path().unwrap(); - - if !certificate_path.exists() { - certificates::get_cert_path().unwrap(); - } - if !certificate_path.exists() { - panic!( - "Unable to generate Certificate Authority at : {}", - &certificate_path.to_str().unwrap() - ); - } - - if cfg!(target_os = "windows") { - window_ca_install(&certificate_path); - } else if cfg!(target_os = "linux") { - linux_debian_based_ca_install(&certificate_path); - } else if cfg!(target_os = "macos") { - macos_ca_install(&certificate_path); - } else { - panic!("Unable to install Certificate Authority on your system.") - } -} - -fn linux_debian_based_ca_install(certificate_path: &PathBuf) { - let debian_based_cert_path = PathBuf::from("/usr/local/share/ca-certificates/"); - - if !debian_based_cert_path.exists() { - error!("Could not find Certificate Authority directory on your system."); - return; - } - - let dest_path = debian_based_cert_path.join("rymfony_CA_cert.crt"); - - let status = SudoCommand::new("cp") - .arg(&certificate_path.to_str().unwrap()) - .arg(&dest_path.to_str().unwrap()) - .status() - .unwrap(); - - trace!("Copy result status {}", status); - - let statusupdate = SudoCommand::new("update-ca-certificates").status().unwrap(); - - trace!("Update CERT result status {}", statusupdate); -} - -fn macos_ca_install(certificate_path: &PathBuf) { - let status = SudoCommand::new("security") - .arg("add-trusted-cert") - .arg("-d") - .arg("-r") - .arg("trustRoot") - .arg("-k") - .arg("/Library/Keychains/System.keychain") - .arg(&certificate_path.to_str().unwrap()) - .gui(false) - .status() - .unwrap(); - - info!("Copy result status {}", status); -} - -fn window_ca_install(certificate_path: &PathBuf) { - let status = SudoCommand::new("certutil") - .arg("-addstore") - .arg("-f") - .arg("ROOT") - .arg(&certificate_path.to_str().unwrap()) - .gui(true) - .status() - .unwrap(); - - info!("Copy result status {}", status); -} diff --git a/src/commands/ca_uninstall.rs b/src/commands/ca_uninstall.rs deleted file mode 100644 index f142e04..0000000 --- a/src/commands/ca_uninstall.rs +++ /dev/null @@ -1,93 +0,0 @@ -use std::fs::read_to_string; -use std::path::PathBuf; - -use openssl::x509::X509; - -use clap::App; -use clap::ArgMatches; -use clap::SubCommand; -use runas::Command as SudoCommand; - -use crate::config::certificates; - -pub(crate) fn command_config<'a, 'b>() -> App<'a, 'b> { - SubCommand::with_name("server:ca:uninstall") - .name("server:ca:uninstall") - .alias("ca:uninstall") - .about("Uninstall the local Certificate Authority") -} - -pub(crate) fn ca_uninstall(_args: &ArgMatches) { - let (certificate_path, _key_path) = certificates::get_ca_cert_path().unwrap(); - - if !certificate_path.exists() { - panic!("Unable to uninstall Certificate Authority on your system : no CA certificate generated."); - } - - if cfg!(target_os = "windows") { - window_ca_uninstall(&certificate_path); - } else if cfg!(target_os = "linux") { - linux_debian_based_ca_uninstall(&certificate_path); - } else if cfg!(target_os = "macos") { - macos_ca_uninstall(&certificate_path); - } else { - panic!("Unable to install Certificate Authority on your system.") - } -} - -fn linux_debian_based_ca_uninstall(_certificate_path: &PathBuf) { - let debian_based_cert_path = PathBuf::from("/usr/local/share/ca-certificates/"); - - if !debian_based_cert_path.exists() { - info!("Could not find Certificate Authority directory on your system."); - return; - } - - let dest_path = debian_based_cert_path.join("rymfony_CA_cert.crt"); - - let status = SudoCommand::new("rm") - .arg(&dest_path.to_str().unwrap()) - .status() - .unwrap(); - - trace!("Remove result status {}", status); - - let statusupdate = SudoCommand::new("update-ca-certificates") - .arg("--fresh") - .status() - .unwrap(); - - trace!("Update CERT result status {}", statusupdate); -} - -fn macos_ca_uninstall(certificate_path: &PathBuf) { - let status = SudoCommand::new("security") - .arg("remove-trusted-cert") - .arg("-d") - .arg(&certificate_path.to_str().unwrap()) - .gui(false) - .status() - .unwrap(); - - trace!("Copy result status {}", status); -} - -fn window_ca_uninstall(certificate_path: &PathBuf) { - let content = read_to_string(certificate_path).unwrap(); - let certif = X509::from_pem(content.as_bytes()).unwrap(); - - let serial = certif.serial_number().to_bn().unwrap(); - - let hex = serial.to_hex_str().unwrap(); - trace!("Attempt to remove {}", hex.to_string()); - - let status = SudoCommand::new("certutil") - .arg("-delstore") - .arg("ROOT") - .arg(hex.to_string()) - .gui(true) - .status() - .unwrap(); - - trace!("Copy result status {}", status); -} diff --git a/src/commands/serve.rs b/src/commands/serve.rs index b7eff19..4987a76 100644 --- a/src/commands/serve.rs +++ b/src/commands/serve.rs @@ -75,11 +75,6 @@ It will do so in this order: .long("no-tls") .help("Disable TLS. Use HTTP only."), ) - .arg( - Arg::with_name("allow-http") - .long("allow-http") - .help("Do not redirect HTTP request to HTTPS"), - ) .arg( Arg::with_name("expose-server-header") .short("s") @@ -178,8 +173,6 @@ fn serve_foreground(args: &ArgMatches) { warn!("No PHP entrypoint file"); PhpServer::new(0, PhpServerSapi::Unknown) } else { - info!("Starting PHP..."); - php_server::start() }; @@ -189,8 +182,9 @@ fn serve_foreground(args: &ArgMatches) { PhpServerSapi::CGI => "CGI", PhpServerSapi::Unknown => "?", }; + if sapi == "?" { - info!("Skip PHP start"); + info!("Skipping PHP start"); } else { info!("PHP started with module {}", sapi); info!("PHP entrypoint file: {}", &script_filename); @@ -235,15 +229,12 @@ fn serve_foreground(args: &ArgMatches) { proxy_server::start( !args.is_present("no-tls"), - !args.is_present("allow-http"), port, php_server.port(), document_root, script_filename, args.is_present("expose-server-header"), ); - - unreachable!(); } fn serve_background(args: &ArgMatches) { @@ -258,9 +249,6 @@ fn serve_background(args: &ArgMatches) { if args.is_present("no-tls") { cmd.arg("--no-tls"); } - if args.is_present("allow-http") { - cmd.arg("--allow-http"); - } if args.is_present("expose-server-header") { cmd.arg("--expose-server-header"); } diff --git a/src/config/certificates.rs b/src/config/certificates.rs deleted file mode 100644 index 1c8b512..0000000 --- a/src/config/certificates.rs +++ /dev/null @@ -1,229 +0,0 @@ -use std::fs::metadata; -use std::fs::read_to_string; -use std::fs::File; -use std::io::Write; -use std::path::PathBuf; - -use dirs::home_dir; -use openssl::asn1::Asn1Time; -use openssl::bn::BigNum; -use openssl::bn::MsbOption; -use openssl::error::ErrorStack; -use openssl::hash::MessageDigest; -use openssl::pkey::PKey; -use openssl::pkey::PKeyRef; -use openssl::pkey::Private; -use openssl::rsa::Rsa; -use openssl::x509::extension::AuthorityKeyIdentifier; -use openssl::x509::extension::BasicConstraints; -use openssl::x509::extension::ExtendedKeyUsage; -use openssl::x509::extension::KeyUsage; -use openssl::x509::extension::SubjectAlternativeName; -use openssl::x509::extension::SubjectKeyIdentifier; -use openssl::x509::X509NameBuilder; -use openssl::x509::X509Ref; -use openssl::x509::X509Req; -use openssl::x509::X509ReqBuilder; -use openssl::x509::X509; - -type CertResult = std::result::Result>; - -pub(crate) fn get_cert_path() -> CertResult<(PathBuf, PathBuf)> { - let certificate_path = home_dir().unwrap().join(".rymfony").join("tls_cert.pem"); - let key_path = home_dir().unwrap().join(".rymfony").join("tls_key.pem"); - - let certificate_is_not_empty = file_is_not_empty(&certificate_path); - let key_is_not_empty = file_is_not_empty(&key_path); - - if certificate_is_not_empty && key_is_not_empty { - return Ok((certificate_path, key_path)); - } - - let mut cert_file = if certificate_is_not_empty { - File::open(&certificate_path) - } else { - File::create(&certificate_path) - }?; - - let mut key_file = if key_is_not_empty { - File::open(&key_path) - } else { - File::create(&key_path) - }?; - - let (ca_cert, ca_privkey) = load_or_generate_ca_cert()?; - - let (certificate, private_key) = generate_ca_signed_cert(&ca_cert, &ca_privkey)?; - - cert_file.write_all(&certificate.to_pem()?)?; - cert_file.write(&ca_cert.to_pem()?)?; - key_file.write_all(&private_key.private_key_to_pem_pkcs8()?)?; - - return Ok((certificate_path, key_path)); -} - -pub(crate) fn get_ca_cert_path() -> CertResult<(PathBuf, PathBuf)> { - let certificate_path = home_dir().unwrap().join(".rymfony").join("ca_tls_cert.pem"); - let key_path = home_dir().unwrap().join(".rymfony").join("ca_tls_key.pem"); - Ok((certificate_path, key_path)) -} - -fn load_or_generate_ca_cert() -> CertResult<(X509, PKey)> { - let (ca_path, ca_key_path) = get_ca_cert_path()?; - - if file_is_not_empty(&ca_path) && file_is_not_empty(&ca_key_path) { - let (ca_cert, ca_privkey) = load_ca_cert(&ca_path, &ca_key_path)?; - return Ok((ca_cert, ca_privkey)); - } - - let (ca_cert, ca_privkey) = generate_ca_key_pair()?; - - let mut cert_file = if file_is_not_empty(&ca_path) { - File::open(&ca_path) - } else { - File::create(&ca_path) - }?; - - let mut key_file = if file_is_not_empty(&ca_key_path) { - File::open(&ca_key_path) - } else { - File::create(&ca_key_path) - }?; - - cert_file.write_all(&ca_cert.to_pem()?)?; - key_file.write_all(&ca_privkey.private_key_to_pem_pkcs8()?)?; - - Ok((ca_cert, ca_privkey)) -} - -fn load_ca_cert( - certificate_path: &PathBuf, - key_path: &PathBuf, -) -> Result<(X509, PKey), ErrorStack> { - let content = read_to_string(certificate_path).unwrap(); - let certif = X509::from_pem(content.as_bytes()).unwrap(); - - let content_key = read_to_string(key_path).unwrap(); - let pkey = PKey::private_key_from_pem(content_key.as_bytes()).unwrap(); - - Ok((certif, pkey)) -} - -fn generate_ca_key_pair() -> Result<(X509, PKey), ErrorStack> { - let rsa = Rsa::generate(2048)?; - let privkey = PKey::from_rsa(rsa)?; - - let mut x509_name = X509NameBuilder::new()?; - x509_name.append_entry_by_text("C", "FR")?; - x509_name.append_entry_by_text("O", "Orbitale.io")?; - x509_name.append_entry_by_text("OU", "Orbitale.io localhost")?; - x509_name.append_entry_by_text("CN", "Orbitale CA (dev)")?; - let x509_name = x509_name.build(); - - let mut cert_builder = X509::builder()?; - cert_builder.set_version(2)?; - let serial_number = { - let mut serial = BigNum::new()?; - serial.rand(159, MsbOption::MAYBE_ZERO, false)?; - serial.to_asn1_integer()? - }; - cert_builder.set_serial_number(&serial_number)?; - cert_builder.set_subject_name(&x509_name)?; - cert_builder.set_issuer_name(&x509_name)?; - cert_builder.set_pubkey(&privkey)?; - let not_before = Asn1Time::days_from_now(0)?; - cert_builder.set_not_before(¬_before)?; - let not_after = Asn1Time::days_from_now(365)?; - cert_builder.set_not_after(¬_after)?; - - cert_builder.append_extension(BasicConstraints::new().critical().ca().build()?)?; - cert_builder.append_extension(KeyUsage::new().critical().key_cert_sign().build()?)?; - - let subject_key_identifier = - SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(None, None))?; - cert_builder.append_extension(subject_key_identifier)?; - - cert_builder.sign(&privkey, MessageDigest::sha256())?; - let cert = cert_builder.build(); - - Ok((cert, privkey)) -} - -fn generate_request(privkey: &PKey) -> Result { - let mut req_builder = X509ReqBuilder::new()?; - req_builder.set_pubkey(&privkey)?; - - let mut x509_name = X509NameBuilder::new()?; - x509_name.append_entry_by_text("C", "FR")?; - x509_name.append_entry_by_text("O", "Orbitale.io cert (dev)")?; - x509_name.append_entry_by_text("OU", "Orbitale localhost (dev)")?; - let x509_name = x509_name.build(); - req_builder.set_subject_name(&x509_name)?; - - req_builder.sign(&privkey, MessageDigest::sha256())?; - let req = req_builder.build(); - Ok(req) -} - -fn generate_ca_signed_cert( - ca_cert: &X509Ref, - ca_privkey: &PKeyRef, -) -> Result<(X509, PKey), ErrorStack> { - let rsa = Rsa::generate(2048)?; - let privkey = PKey::from_rsa(rsa)?; - - let req = generate_request(&privkey)?; - - let mut cert_builder = X509::builder()?; - cert_builder.set_version(2)?; - let serial_number = { - let mut serial = BigNum::new()?; - serial.rand(159, MsbOption::MAYBE_ZERO, false)?; - serial.to_asn1_integer()? - }; - cert_builder.set_serial_number(&serial_number)?; - cert_builder.set_subject_name(req.subject_name())?; - cert_builder.set_issuer_name(ca_cert.subject_name())?; - cert_builder.set_pubkey(&privkey)?; - let not_before = Asn1Time::days_from_now(0)?; - cert_builder.set_not_before(¬_before)?; - let not_after = Asn1Time::days_from_now(365)?; - cert_builder.set_not_after(¬_after)?; - - cert_builder.append_extension(BasicConstraints::new().critical().build()?)?; - - cert_builder.append_extension( - KeyUsage::new() - .critical() - .digital_signature() - .key_encipherment() - .build()?, - )?; - cert_builder.append_extension(ExtendedKeyUsage::new().server_auth().build()?)?; - - let subject_key_identifier = - SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(Some(ca_cert), None))?; - cert_builder.append_extension(subject_key_identifier)?; - - let auth_key_identifier = AuthorityKeyIdentifier::new() - .keyid(false) - .issuer(false) - .build(&cert_builder.x509v3_context(Some(ca_cert), None))?; - cert_builder.append_extension(auth_key_identifier)?; - - let subject_alt_name = SubjectAlternativeName::new() - .dns("localhost") - .ip("127.0.0.1") - .ip("::1") - .build(&cert_builder.x509v3_context(Some(ca_cert), None))?; - cert_builder.append_extension(subject_alt_name)?; - - cert_builder.sign(&ca_privkey, MessageDigest::sha256())?; - let cert = cert_builder.build(); - - Ok((cert, privkey)) -} - -fn file_is_not_empty(path: &PathBuf) -> bool { - path.exists() && metadata(&path.to_str().unwrap()).unwrap().len() > 0 -} diff --git a/src/http/caddy.rs b/src/http/caddy.rs new file mode 100644 index 0000000..8679fbd --- /dev/null +++ b/src/http/caddy.rs @@ -0,0 +1,140 @@ +use crate::utils::project_directory::get_rymfony_project_directory; + +use regex::Regex; +use std::path::PathBuf; +use std::fs; +use std::process::Command; +use std::process::Stdio; +#[cfg(not(target_os="windows"))] +use std::os::unix::fs::PermissionsExt; + +#[cfg(not(target_os="windows"))] +use runas::Command as SudoCommand; + +const CADDY_VERSION_REGEX: &'static str = r"^v(2\.\d+\.\d+) "; + +#[cfg(target_os="windows")] +const CADDY_BIN_FILE: &'static str = "caddy.exe"; + +#[cfg(not(target_os="windows"))] +const CADDY_BIN_FILE: &'static str = "caddy"; + +pub(crate) const CADDYFILE: &'static str = " +# ⚠⚠⚠ +# This file is a *template* created by Rymfony. +# The variables you see in brackets \"{{ … }}\" are +# replaced **at runtime** by Rymfony. +# +# Be warned that if you want to change it, +# it may have an impact on how your local project behaves. +# +# Change it at your own risk 💣 + +{ + {{ debug }}debug + log {{ log_file }} + {{ use_tls }}local_certs +} + +{{ host }}:{{ http_port }} { + root * {{ document_root }} + + encode gzip + + {{ with_server_sign }}header Server \"Rymfony\" + {{ without_server_sign }}header -Server + + php_fastcgi 127.0.0.1:{{ php_port }} { + index {{ php_entrypoint_file }} + resolve_root_symlink + } + + file_server +} +"; + +pub(crate) fn get_caddy_pid_path() -> PathBuf { + get_rymfony_project_directory().unwrap() + .join(".running_caddy.pid") +} + +pub(crate) fn get_caddy_path() -> PathBuf { + let caddy_from_path_env = caddy_from_path_env(); + + let caddy_path = match caddy_from_path_env { + Ok(path) => path, + Err(_) => { + let path = get_rymfony_project_directory() + .expect("Could not get Caddy path from Rymfony directory") + .join(CADDY_BIN_FILE) + ; + + if !path.exists() { + info!("Installing Caddy for your project..."); + + #[cfg(target_os="windows")] + fs::write(&path, include_bytes!("../../bin/caddy.exe")).expect("Could not extract built-in Caddy binary."); + #[cfg(not(target_os="windows"))] + fs::write(&path, include_bytes!("../../bin/caddy")).expect("Could not extract built-in Caddy binary."); + + #[cfg(not(target_os="windows"))] + fs::set_permissions(&path, fs::Permissions::from_mode(0o755)).expect("Could not make Caddy binary executable."); + + // On linux, we try to use "setcap" to give Caddy the ability to listen to port 80 + #[cfg(target_os="linux")] + set_http_capabilities(&path); + } + + path + } + }; + + check_caddy_version(&caddy_path); + + caddy_path +} + +fn caddy_from_path_env() -> which::Result { + return which::which("caddy"); +} + +fn check_caddy_version(caddy_path: &PathBuf) { + let mut command = Command::new(caddy_path); + + let output = command + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::null()) + .arg("version") + .output() + .expect(&format!("Could not execute Caddy at path \"{}\"", caddy_path.to_str().unwrap())) + ; + + let stdout = String::from_utf8(output.stdout).expect("Could not convert Caddy's output to a string."); + + let caddy_version_regex = Regex::new(CADDY_VERSION_REGEX).unwrap(); + + if !caddy_version_regex.is_match(&stdout) { + panic!("Invalid Caddy version output from binary at path \"{}\".", caddy_path.to_str().unwrap()) + } +} + +#[cfg(target_os="linux")] +fn set_http_capabilities(caddy_path: &PathBuf) { + + warn!("Caddy is usually unable to listen to port 80 when running as non-root user."); + warn!("To make it work, we will try to use the \"setcap\" command,"); + warn!("in order to give Caddy the necessary permissions to listen to port 80."); + + let status = SudoCommand::new("setcap") + .arg("cap_net_bind_service=+ep") + .arg(&caddy_path.to_str().unwrap()) + .status() + .expect("The \"setcap\" command did not execute when trying to give Caddy the ability to listen to port 80."); + + if status.code().unwrap_or(1) != 0 { + error!("The \"setcap\" command failed when trying to give Caddy the ability to listen to port 80.") + } else { + info!("Done! Caddy is now capable of listening to port 80 (for this project only)"); + } +} \ No newline at end of file diff --git a/src/http/fastcgi_handler.rs b/src/http/fastcgi_handler.rs deleted file mode 100644 index 98db9fd..0000000 --- a/src/http/fastcgi_handler.rs +++ /dev/null @@ -1,349 +0,0 @@ - -use fastcgi_client::Client; -use fastcgi_client::Params; -use fastcgi_client::Request as FastCgiRequest; -use http::Request; -use hyper::header::HeaderName; -use hyper::header::HeaderValue; -use hyper::Body; -use hyper::HeaderMap; -use hyper::Response; -use regex::Captures; -use regex::Regex; -use std::convert::Infallible; -use std::net::SocketAddr; -use std::path::PathBuf; -use tokio::net::TcpStream; -use warp::host::Authority; -use crate::get_version_suffix; - -pub(crate) async fn handle_fastcgi( - document_root: &str, - php_entrypoint_file: &str, - hostname: Authority, - remote_addr: SocketAddr, - req: Request, - http_port: &u16, - php_port: &u16, - use_tls: bool, -) -> Result, Infallible> { - let document_root = String::from(document_root); - let php_entrypoint_file = String::from(php_entrypoint_file); - - let remote_addr = remote_addr.ip().to_string(); - let uri = req.uri().clone(); - let request_uri = uri.to_string(); - let query_string = uri.query().unwrap_or("").to_string(); - let request_uri_without_query = request_uri.replace(format!("?{}", query_string).as_str(), ""); - let request_headers = req.headers().clone(); - let method = req.method().to_string(); - let (parts, request_body) = req.into_parts(); - let hostname = hostname.as_str(); - - let http_version = crate::http::version::as_str(parts.version); - - let stream = match TcpStream::connect(("127.0.0.1", *php_port)).await { - Ok(t) => t, - Err(e) => { - return Ok(error_as_response(e, 503)); - } - }; - - let mut client = Client::new(stream, false); - - let http_port_str = http_port.to_string(); - let php_port_str = php_port.to_string(); - - let (php_file, pathinfo) = get_pathinfo_from_uri(&request_uri); - let script_name = if php_file.len() > 0 { - php_file.clone() - } else { - php_entrypoint_file.clone() - }; - let script_name = format!("/{}", script_name); - let script_filename = get_script_filename(&document_root, php_entrypoint_file); - - // - // Mandatory FastCGI parameters. - // See: https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/ - // See also RFC there: https://tools.ietf.org/html/rfc3875#page-11 - // - let mut fcgi_params = Params::default(); - let empty_header = &HeaderValue::from_str("").unwrap(); - fcgi_params.insert( - "CONTENT_LENGTH", - get_header_value(&request_headers, "Content-Length", &empty_header), - ); - fcgi_params.insert( - "CONTENT_TYPE", - get_header_value(&request_headers, "Content-Type", &empty_header), - ); - - fcgi_params.insert("DOCUMENT_ROOT", &document_root); - fcgi_params.insert("DOCUMENT_URI", request_uri_without_query.as_str()); - fcgi_params.insert("PATH_INFO", pathinfo.as_str()); - fcgi_params.insert("QUERY_STRING", query_string.as_str()); - fcgi_params.insert("REMOTE_ADDR", remote_addr.as_str()); - fcgi_params.insert("REMOTE_PORT", php_port_str.as_str()); - fcgi_params.insert("REQUEST_METHOD", method.as_str()); - fcgi_params.insert("REQUEST_URI", request_uri.as_str()); - fcgi_params.insert("SCRIPT_FILENAME", script_filename.as_str()); - fcgi_params.insert("SCRIPT_NAME", script_name.as_str()); - fcgi_params.insert("SERVER_NAME", &hostname); - fcgi_params.insert("HTTP_HOST", &hostname); - fcgi_params.insert("SERVER_PORT", http_port_str.as_str()); - fcgi_params.insert("SERVER_PROTOCOL", http_version); - fcgi_params.insert("SERVER_SOFTWARE", "Rymfony"); - - if use_tls { - fcgi_params.insert("HTTPS", "On"); - } - - // - // Send all Request HTTP headers to FastCGI, - // in the form of "HTTP_..." parameters. - // That's supposed to be how FastCGI and PHP work. - // - let mut fcgi_headers_normalized = Vec::new(); - for (name, value) in request_headers.iter() { - let header_name = format!("HTTP_{}", name.as_str().replace("-", "_").to_uppercase()); - - fcgi_headers_normalized.push((header_name, value.to_str().unwrap())); - } - - fcgi_params.extend( - fcgi_headers_normalized - .iter() - .map(|(k, s)| (k.as_str(), *s)), - ); - - let request_body_bytes = hyper::body::to_bytes(request_body).await.unwrap(); - let mut fcgi_request_body = &mut std::io::Cursor::new(request_body_bytes); - - // - // Ignition! Do the request! - // - let fcgi_output = client.execute(FastCgiRequest::new(fcgi_params, &mut fcgi_request_body)).await; - - // Retrieve request output - let (raw_fcgi_stdout, fcgi_stderr) = match fcgi_output { - Ok(fcgi_output) => ( - fcgi_output.get_stdout().unwrap_or_default(), - fcgi_output.get_stderr().unwrap_or_default(), - ), - Err(e) => { - error!("FastCGI returned an error. It was displayed as a 502 to the end user."); - return Ok(error_as_response(e, 502)); - } - }; - - if raw_fcgi_stdout.len() == 0 { - error!( - "FastCGI returned an empty Response:\n{}", - std::str::from_utf8(&fcgi_stderr).unwrap() - ); - return Ok(error_as_response( - std::str::from_utf8(fcgi_stderr.as_slice()).unwrap(), - 502, - )); - } - - // - // The CGI response *never* returns the HTTP Status Line. - // However, the "httparse" crate needs it. - // So we create a fake one. - // Later on, this will be overriden by the "Status" header (see below), so it's a fine hack. - // - let mut fcgi_stdout: Vec = format!("{} 200 Ok\r\n", http_version).as_bytes().to_vec(); - fcgi_stdout.extend(raw_fcgi_stdout); - - trace!("Received FastCGI response."); - - if fcgi_stderr.len() > 0 { - error!( - "FastCGI returned an error:\n{}", - std::str::from_utf8(&fcgi_stderr).unwrap() - ); - return Ok(error_as_response( - std::str::from_utf8(fcgi_stderr.as_slice()).unwrap(), - 502, - )); - } - - // - // Convert the contents of "fcgi_stdout" into a proper list of HTTP Headers. - // Body is supposed to be a bunch of bytes. - // - let mut normalized_headers = [httparse::EMPTY_HEADER; 80]; - let mut res = httparse::Response::new(&mut normalized_headers); - let headers_len = res.parse(fcgi_stdout.as_slice()).unwrap().unwrap(); - let response_headers = res.headers; - debug!("Response headers ready to normalize"); - let mut headers_normalized: HeaderMap = response_headers - .iter() - .map(|header| { - let header_name = header.name.as_bytes(); - let header_value = std::str::from_utf8(header.value).unwrap(); - - debug!( - "Normalized headers: \"{}: {}\"", - std::str::from_utf8(&header_name).unwrap(), - &header_value - ); - - ( - HeaderName::from_bytes(header_name).unwrap(), - HeaderValue::from_str(header_value).unwrap(), - ) - }) - .collect(); - debug!("Response headers are now normalized"); - let (_, body) = fcgi_stdout.split_at(headers_len); - - // ... However, it seems I can't just put bytes in the body, and that only String is possible... - let response_body = Body::from(body.to_vec()); - - // - // CGI's RFC says that the "Status" response header - // can contain the HTTP Response Status code. - // It's not explicit whether it should be removed from the end response, - // but we use ".remove()" to do so, to make sure there is no conflict between - // the real HTTP Status line and the "Status" header (what a whoopsie it would be anyway...). - // See: https://tools.ietf.org/html/rfc3875#section-6.3.3 - // - let response_status_header = headers_normalized.remove("status"); - - let status_code: u16 = if let Some(status_header) = response_status_header { - use std::str::FromStr; - let status_code_as_string = &status_header - .to_str() - .unwrap() - .chars() - .take(3) - .collect::(); - let status_code = http::StatusCode::from_str(status_code_as_string).unwrap(); - status_code.as_u16() - } else { - debug!("Response does not contain the \"Status\" HTTP header"); - 200 - }; - - // - // Finally: a Hyper response. - // Everything has to be done to convert the fastcgi response into a Hyper response. - // - let mut response_builder = Response::builder(); - let response_headers = response_builder.headers_mut().unwrap(); - response_headers.extend(headers_normalized); - - let response = response_builder - .status(status_code) - .body(response_body) - .unwrap(); - - trace!("Finish response"); - - Ok(response) -} - -fn get_header_value<'a>( - headers: &'a HeaderMap, - header_name: &str, - empty_header: &'a HeaderValue, -) -> &'a str { - headers - .get(header_name) - .unwrap_or(empty_header) - .to_str() - .unwrap_or_default() -} - -fn get_pathinfo_from_uri(request_uri: &str) -> (String, String) { - let php_file_regex = Regex::new(r"(^.*\.php)((?:/|$).*)(?:\?.*)?$").unwrap(); - - if !php_file_regex.is_match(request_uri) { - return (String::from(""), filter_pathinfo(request_uri.to_string())); - } - - let capts: Captures = php_file_regex.captures(request_uri).unwrap(); - - let php_file = capts[1].trim_start_matches("/").to_string(); - let path_info = filter_pathinfo(capts[2].to_string()); - - (php_file, path_info) -} - -fn get_script_filename(document_root: &String, script_filename_arg: String) -> String { - let path = PathBuf::from(&script_filename_arg); - - if path.is_absolute() { - debug!("Script path \"{}\" is absolute.", script_filename_arg); - return script_filename_arg; - } - - debug!("Script path \"{}\" is relative.", script_filename_arg); - - let mut path = PathBuf::from(document_root); - path.push(&script_filename_arg); - - debug!( - "Relative script path \"{}\" resolved to \"{}\".", - &script_filename_arg, - path.to_str().unwrap() - ); - - String::from(path.to_str().unwrap()) -} - -fn filter_pathinfo(path_info: String) -> String { - if path_info == "/" { - // Seems like Symfony CLI does it. More research needed, if any issue. - return "".to_string(); - } - - path_info -} - -fn error_as_response(error: T, status_code: u16) -> Response -where - T: std::fmt::Display, -{ - let mut response_builder = Response::builder(); - let response_headers = response_builder.headers_mut().unwrap(); - response_headers.append("Content-Type", "text/html".parse().unwrap()); - - let body_str = format!( - r###" - - - - - Internal server error - - - -
-

Internal server error "{}"

-

The server returned:

-
{}
-
- - - "###, - &status_code, &error - ); - - let response = response_builder - .status(status_code) - .body( - Body::from(body_str), //Body::from(body) - ) - .unwrap(); - - response -} diff --git a/src/http/proxy_server.rs b/src/http/proxy_server.rs index 2cf67c4..af4fd94 100644 --- a/src/http/proxy_server.rs +++ b/src/http/proxy_server.rs @@ -1,215 +1,116 @@ -use std::collections::HashMap; -use std::convert::Infallible; -use std::net::SocketAddr; -use std::path::Path; +use std::process::Command; +use std::process::Stdio; +use crate::http::caddy::get_caddy_path; +use crate::http::caddy::CADDYFILE; +use crate::http::caddy::get_caddy_pid_path; +use crate::utils::project_directory::get_rymfony_project_directory; use std::path::PathBuf; +use std::fs::File; +use std::fs::read_to_string; +use std::fs::write; +use std::io::Write; -use console::style; -use http::HeaderMap; -use http::Method; -use hyper::Body; -use hyper::Request; -use hyper_staticfile::Static; -use warp::filters::header::headers_cloned; -use warp::filters::path::FullPath; -use warp::host::Authority; -use warp::http::Response; -use warp::hyper::body::Bytes; -use warp::method; -use warp::Filter; - -use crate::config::certificates::get_cert_path; -use crate::http::fastcgi_handler::handle_fastcgi; - -#[tokio::main] -pub(crate) async fn start( +pub(crate) fn start( use_tls: bool, - forward_http_to_https: bool, http_port: u16, php_port: u16, document_root: String, php_entrypoint_file: String, add_server_sign: bool, ) { - let http_port = http_port.clone(); - let php_port = php_port.clone(); - let document_root = document_root.clone(); - let php_entrypoint_file = php_entrypoint_file.clone(); - - let routes = warp::any() - .and(warp::addr::remote()) - .and(warp::filters::host::optional()) - .and(method()) - .and(warp::path::full()) - .and(warp::query::>()) - .and(headers_cloned()) - .and(warp::body::bytes()) - .and_then( - move |remote_addr: Option, - host: Option, - method: Method, - request_path: FullPath, - query: HashMap, - headers: HeaderMap, - body: Bytes| { - let http_port = http_port.clone(); - let php_port = php_port.clone(); - let document_root = document_root.clone(); - let php_entrypoint_file = php_entrypoint_file.clone(); - let method = method.clone(); - - async move { - let query_string: String = query - .iter() - .map(|(key, value)| format!("{}={}", key, value)) - .collect::>() - .join("&"); - - let request_path = request_path.as_str(); - let mut request_uri = request_path.to_string(); - - if query_string.len() > 0 { - request_uri.push_str("?"); - request_uri.push_str(&query_string); - } - - let mut req = http::Request::builder() - .method(&method) - .uri(&request_uri) - .body(Body::from(body.to_vec())) - .unwrap(); - - let mut cookies_value = "".to_string(); - let mut h = headers.clone(); - if headers.contains_key("cookie") { - let cookies = headers.get_all("cookie"); - for cookie in cookies { - if cookies_value.len() == 0 { - cookies_value = cookie.to_str().unwrap().to_string(); - continue; - } - cookies_value = - format!("{}; {}", cookies_value, cookie.to_str().unwrap()); - } - - h.remove("cookie"); - h.insert("cookie", cookies_value.parse().unwrap()); - } - - { - *req.headers_mut() = h; - } - - let render_static = get_render_static_path(&document_root, &request_path); - let render_static = !request_path.contains(".php") - && render_static != "" - && request_path != "" - && request_path != "/"; - - info!( - "{} {}{}", - style(method.as_str()).yellow(), - style(&request_uri).cyan(), - if render_static { " (static)" } else { "" } - ); - - let mut response = if render_static || php_port == 0 { - serve_static(req, Static::new(Path::new(&document_root))).await - } else { - trace!("Forwarding to FastCGI"); - - let remote_addr = remote_addr.unwrap(); - - handle_fastcgi( - &document_root, - &php_entrypoint_file, - host.unwrap(), - remote_addr, - req, - &http_port, - &php_port, - use_tls, - ) - .await - }; - if add_server_sign { - response - .as_mut() - .unwrap() - .headers_mut() - .append("server", "Rymfony".parse().unwrap()); - } - - response - } - }, - ); - - if use_tls { - let (cert_path, key_path) = get_cert_path().expect("Could not generate TLS certificate"); - - warp::serve(routes) - .tls() - .cert_path(cert_path) - .key_path(key_path) - .run(([127, 0, 0, 1], http_port)) - .await - } else { - warp::serve(routes).run(([127, 0, 0, 1], http_port)).await - }; -} + let http_log_file = get_http_log_file(); + if !http_log_file.exists() { File::create(&http_log_file).expect("Could not create HTTP log file."); } + + let http_error_file = get_http_error_file(); + if !http_error_file.exists() { File::create(&http_error_file).expect("Could not create HTTP error file."); } + + let caddy_path = get_caddy_path(); + let mut caddy_command = Command::new(&caddy_path); + + // TODO: implement ".wip" (or other) custom domains. + let host_name = "127.0.0.1".to_string(); + + let caddy_config_file = get_caddy_config_file(); + + caddy_command + .stdin(Stdio::piped()) + .stderr(Stdio::from(File::open(http_error_file).expect("Could not open HTTP error file."))) // TODO: check if is this working + .arg("run") + .arg("--adapter").arg("caddyfile") + .arg("--pidfile").arg(get_caddy_pid_path().to_str().unwrap()) + .arg("--config").arg("-") // This makes Caddy use STDIN for config + ; + + let mut caddy_command = caddy_command + .spawn() + .expect("Could not start HTTP server.") + ; + + let debug = false; // FIXME: use env var for this. + + { + let mut config: String = if !caddy_config_file.exists() { + write(&caddy_config_file, CADDYFILE).expect("Could not write Caddyfile config."); + debug!("Wrote Caddy config to {}", &caddy_config_file.to_str().unwrap()); + + CADDYFILE.to_string() + } else { + debug!("Reusing Caddy config from {}", &caddy_config_file.to_str().unwrap()); + + read_to_string(&caddy_config_file).expect("Could not read Caddyfile config file.") + }; + + config = config + .replace("{{ document_root }}", document_root.as_str()) + .replace("{{ php_port }}", &php_port.to_string()) + .replace("{{ http_port }}", &http_port.to_string()) + .replace("{{ https_port }}", &http_port.to_string()) + .replace("{{ php_entrypoint_file }}", php_entrypoint_file.as_str()) + .replace("{{ log_file }}", http_log_file.to_str().unwrap()) + .replace("{{ host }}", &host_name) + .replace("{{ with_server_sign }}", if add_server_sign { "" } else { "#" }) + .replace("{{ without_server_sign }}", if add_server_sign { "#" } else { "" }) + .replace("{{ use_tls }}", if use_tls { "" } else { "#" }) + .replace("{{ debug }}", if debug { "" } else { "#" }) + ; + + trace!("Final Caddy config:\n{}\n", &config); + + let caddy_stdin = caddy_command.stdin.as_mut().unwrap(); + caddy_stdin.write_all(config.as_bytes()).expect("Could not write server config to Caddy STDIN."); + } -async fn serve_static( - req: Request, - static_files_server: Static, -) -> Result, Infallible> { - let static_files_server = static_files_server.clone(); - let response_future = static_files_server.serve(req); + info!("Listening to {}://{}:{}", if use_tls { "https" } else { "http" }, host_name, http_port); - let response = response_future.await; + let output = caddy_command.wait_with_output().expect("Could not wait for Caddy to finish executing."); - anyhow::Result::Ok(response.unwrap()) -} + if output.status.code().unwrap() != 0 { + let stderr = String::from_utf8(output.stderr).unwrap(); + if stderr.contains("listen tcp :80: bind: permission denied") { + error!("Caddy is unable to listen to port 80, which is used for HTTP to HTTPS redirection."); + error!("This can happen when you run Caddy (and therefore Rymfony) as non-root user."); + error!("To make it work, you need to give Caddy the necessary network capabilities."); -fn get_render_static_path(document_root: &str, request_path: &str) -> String { - let directory_separators: &[_] = &['/', '\\']; - let request_path = urldecode::decode( - request_path - .trim_start_matches(directory_separators) - .to_string(), - ); - let document_root = document_root.trim_end_matches(directory_separators); - let static_doc_root = PathBuf::from(&document_root); - let docroot_path = PathBuf::from(&static_doc_root).join(&request_path); - - let docroot_public_path = PathBuf::from(&static_doc_root) - .join("public") - .join(&request_path); - - let docroot_web_path = PathBuf::from(&static_doc_root) - .join("web") - .join(&request_path); - - let mut render_static: &str = ""; - - if docroot_path.is_file() { - render_static = docroot_path.to_str().unwrap(); - debug!("Static file \"{}\" found in document root.", &render_static); - } else if docroot_public_path.is_file() { - render_static = docroot_public_path.to_str().unwrap(); - debug!( - "Static file \"{}\" found in \"public/\" subdirectory.", - &render_static - ); - } else if docroot_web_path.is_file() { - debug!( - "Static file \"{}\" found in \"web/\" subdirectory.", - &render_static - ); - render_static = docroot_web_path.to_str().unwrap(); - } else { - debug!("No static file found based on \"{}\" path.", request_path); + #[cfg(target_os = "linux")] { + error!("On most linux distribuions, you can do it by running this command (possibly with \"sudo\"):"); + error!(" setcap cap_net_bind_service=+ep {}", caddy_path.to_str().unwrap()); + } + } + panic!("Caddy failed to start."); } +} + +fn get_http_log_file() -> PathBuf { + get_rymfony_project_directory().unwrap() + .join("http.log") +} + +fn get_http_error_file() -> PathBuf { + get_rymfony_project_directory().unwrap() + .join("http.err") +} - String::from(render_static) +fn get_caddy_config_file() -> PathBuf { + get_rymfony_project_directory().unwrap() + .join("Caddyfile") } diff --git a/src/http/version.rs b/src/http/version.rs deleted file mode 100644 index 0d8bad2..0000000 --- a/src/http/version.rs +++ /dev/null @@ -1,12 +0,0 @@ -use http::Version; - -pub(crate) fn as_str(http_version: Version) -> &'static str { - match http_version { - Version::HTTP_09 => "HTTP/0.9", - Version::HTTP_10 => "HTTP/1.0", - Version::HTTP_11 => "HTTP/1.1", - Version::HTTP_2 => "HTTP/2.0", - Version::HTTP_3 => "HTTP/3.0", - _ => unreachable!(), - } -} diff --git a/src/main.rs b/src/main.rs index bc2ae70..6d05ec1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,18 +4,14 @@ extern crate prettytable; extern crate log; extern crate ctrlc; extern crate env_logger; -extern crate httparse; extern crate pretty_env_logger; extern crate regex; mod config { - pub(crate) mod certificates; pub(crate) mod config; } mod commands { - pub(crate) mod ca_install; - pub(crate) mod ca_uninstall; pub(crate) mod new_symfony; pub(crate) mod php_list; pub(crate) mod serve; @@ -39,9 +35,8 @@ mod php { } mod http { - pub(crate) mod fastcgi_handler; + pub(crate) mod caddy; pub(crate) mod proxy_server; - pub(crate) mod version; } use clap::App; @@ -62,8 +57,6 @@ use utils::current_process_name; fn main() { let application_commands = vec![ crate::commands::php_list::command_config(), - crate::commands::ca_install::command_config(), - crate::commands::ca_uninstall::command_config(), crate::commands::serve::command_config(), crate::commands::stop::command_config(), crate::commands::new_symfony::command_config(), @@ -117,12 +110,6 @@ https://github.com/Orbitale/Rymfony Some("server:start") => { crate::commands::serve::serve(matches.subcommand_matches("server:start").unwrap()) } - Some("server:ca:install") => crate::commands::ca_install::ca_install( - matches.subcommand_matches("server:ca:install").unwrap(), - ), - Some("server:ca:uninstall") => crate::commands::ca_uninstall::ca_uninstall( - matches.subcommand_matches("server:ca:uninstall").unwrap(), - ), Some("stop") => crate::commands::stop::stop(), Some("new") => { crate::commands::new_symfony::new_symfony(matches.subcommand_matches("new").unwrap()) diff --git a/src/php/php_server.rs b/src/php/php_server.rs index 24a41d0..418d3f9 100644 --- a/src/php/php_server.rs +++ b/src/php/php_server.rs @@ -122,7 +122,7 @@ pub(crate) fn start() -> PhpServer { } pub(crate) fn healthcheck(port: u16) -> u16 { - println!("Checking port {}", &port); + info!("Checking port {}", &port); 0 } diff --git a/src/php/server_fpm.rs b/src/php/server_fpm.rs index 5aa434e..f39147d 100644 --- a/src/php/server_fpm.rs +++ b/src/php/server_fpm.rs @@ -5,6 +5,7 @@ use { std::fmt, std::error::Error, std::fs::File, + std::fs::OpenOptions, std::fs::read_to_string, std::fs::remove_file, std::io::prelude::*, @@ -74,8 +75,6 @@ pub(crate) fn start(_php_bin: String) -> (PhpServer, Child) { #[cfg(not(target_family = "windows"))] pub(crate) fn start(php_bin: String) -> (PhpServer, Child) { - info!("Using php-fpm"); - let uid = get_current_uid(); let mut port = find_available_port(FPM_DEFAULT_PORT); @@ -100,7 +99,7 @@ pub(crate) fn start(php_bin: String) -> (PhpServer, Child) { fpm_config_file .write_all(config.as_bytes()) .expect("Could not write to php-fpm config file."); - info!("Saved FPM config file at {}", fpm_config_file_path.to_str().unwrap()); + debug!("Saved FPM config file at {}", fpm_config_file_path.to_str().unwrap()); } else { // Read the file and search the port let mut content = read_to_string(&fpm_config_file_path).unwrap(); @@ -120,15 +119,30 @@ pub(crate) fn start(php_bin: String) -> (PhpServer, Child) { ) .as_str(), ); - info!("Rewrote FPM config file at {}", fpm_config_file_path.to_str().unwrap()); + debug!("Rewrote FPM config file at {}", fpm_config_file_path.to_str().unwrap()); } + let fpm_log_file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(get_rymfony_project_directory().unwrap().join("fpm.log")) + .unwrap() + ; + let fpm_err_file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(get_rymfony_project_directory().unwrap().join("fpm.err")) + .unwrap() + ; + let pid_filename = format!("{}/fpm.pid", rymfony_project_path.to_str().unwrap()); let mut command = Command::new(php_bin); command - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) + .stdout(Stdio::from(fpm_log_file)) + .stderr(Stdio::from(fpm_err_file)) .arg("--nodaemonize") .arg("--pid") .arg(pid_filename) @@ -149,6 +163,7 @@ pub(crate) fn start(php_bin: String) -> (PhpServer, Child) { panic!("Could not start php-fpm."); } + #[cfg(not(target_family = "windows"))] #[derive(Debug)] struct ReadPortError(String);