From 330e9ba4efe4a1cb459ffc858db863b20c5b0e50 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Adri=C3=A1n=20Arroyo=20Calle?= Date: Mon, 19 Jun 2023 19:18:14 +0200 Subject: [PATCH] Multiple fixes for http libraries * use reqwest for http_open (still uses Hyper underneath) * use Hyper 1.0.0-rc3 for server * Modify all internal handling of server --- Cargo.lock | 412 +++++++++++++++++++++++++++++++----- Cargo.toml | 8 +- src/http.rs | 57 +++-- src/lib/http/http_server.pl | 39 ++-- src/machine/streams.rs | 57 +++-- src/machine/system_calls.rs | 170 +++++++-------- 6 files changed, 549 insertions(+), 194 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51a8fa49..15599610 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -49,12 +64,33 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "bit-set" version = "0.5.3" @@ -76,6 +112,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + [[package]] name = "bitvec" version = "1.0.1" @@ -253,7 +295,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crossterm_winapi", "libc", "mio 0.7.14", @@ -398,6 +440,15 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + [[package]] name = "endian-type" version = "0.1.2" @@ -446,12 +497,12 @@ dependencies = [ [[package]] name = "fd-lock" -version = "3.0.12" +version = "3.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ae6b3d9530211fb3b12a95374b8b0823be812f53d09e18c5675c0146b09642" +checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ "cfg-if", - "rustix", + "rustix 0.38.1", "windows-sys 0.48.0", ] @@ -476,6 +527,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + [[package]] name = "funty" version = "2.0.0" @@ -548,7 +608,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -620,6 +680,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "git-version" version = "0.3.5" @@ -654,9 +720,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -686,15 +752,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.1" @@ -748,6 +805,29 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body 1.0.0-rc.2", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" @@ -762,9 +842,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -772,7 +852,7 @@ dependencies = [ "futures-util", "h2", "http", - "http-body", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -784,6 +864,28 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 1.0.0-rc.2", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", + "tracing", + "want", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -791,7 +893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.27", "native-tls", "tokio", "tokio-native-tls", @@ -820,6 +922,16 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -845,11 +957,17 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + [[package]] name = "itertools" version = "0.10.5" @@ -906,7 +1024,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec", - "bitflags", + "bitflags 1.3.2", "cfg-if", "ryu", "static_assertions", @@ -914,9 +1032,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libffi" @@ -965,6 +1083,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + [[package]] name = "lock_api" version = "0.4.10" @@ -1034,6 +1158,21 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.7.14" @@ -1125,7 +1264,7 @@ version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cc", "cfg-if", "libc", @@ -1138,7 +1277,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "static_assertions", @@ -1164,14 +1303,23 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] +[[package]] +name = "object" +version = "0.30.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1190,7 +1338,7 @@ version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1207,7 +1355,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -1285,6 +1433,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + [[package]] name = "phf" version = "0.9.0" @@ -1432,18 +1586,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1500,7 +1654,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1509,7 +1663,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1535,6 +1689,43 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64 0.21.2", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "ring" version = "0.16.20" @@ -1581,17 +1772,36 @@ dependencies = [ "libc", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustix" -version = "0.37.20" +version = "0.37.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "62f25693a73057a1b4cb56179dd3c7ea21a7c6c5ee7d85781f5749b46f34b79c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] @@ -1607,7 +1817,7 @@ version = "9.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db7826789c0e25614b03e5a54a0717a86f9ff6e6e5247f92b369472869320039" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "clipboard-win", "dirs-next", @@ -1660,10 +1870,11 @@ name = "scryer-prolog" version = "0.9.1" dependencies = [ "assert_cmd", - "base64", + "base64 0.12.3", "bit-set", "bitvec", "blake2 0.8.1", + "bytes", "chrono", "cpu-time", "crossterm", @@ -1676,8 +1887,8 @@ dependencies = [ "fxhash", "git-version", "hostname", - "hyper", - "hyper-tls", + "http-body-util", + "hyper 1.0.0-rc.3", "indexmap", "lazy_static", "lexical", @@ -1692,6 +1903,7 @@ dependencies = [ "proc-macro2", "quote", "ref_thread_local", + "reqwest", "ring", "ripemd160", "roxmltree", @@ -1719,7 +1931,7 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -1753,6 +1965,29 @@ version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +[[package]] +name = "serde_json" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serial_test" version = "0.5.1" @@ -1966,9 +2201,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" dependencies = [ "proc-macro2", "quote", @@ -1991,7 +2226,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", + "rustix 0.37.21", "windows-sys 0.48.0", ] @@ -2029,7 +2264,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -2043,6 +2278,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "to-syn-value" version = "0.1.0" @@ -2066,11 +2316,12 @@ dependencies = [ [[package]] name = "tokio" -version = "1.28.2" +version = "1.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "374442f06ee49c3a28a8fc9f01a2596fed7559c6b99b31279c3261778e77d84f" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", "mio 0.8.8", @@ -2091,7 +2342,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -2156,12 +2407,27 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + [[package]] name = "unicode-ident" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.10.1" @@ -2180,6 +2446,17 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "utf-8" version = "0.7.6" @@ -2265,10 +2542,22 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.87" @@ -2287,7 +2576,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2374,9 +2663,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", @@ -2471,6 +2760,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 99218c71..c24d66f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,13 +61,15 @@ smallvec = "1.8.0" sodiumoxide = "0.2.6" static_assertions = "1.1.0" ryu = "1.0.9" -hyper = { version = "0.14", features = ["full"] } -hyper-tls = "0.5.0" -tokio = { version = "1.24.2", features = ["full"] } +hyper = { version = "1.0.0-rc.3", features = ["full"] } +tokio = { version = "1.28.2", features = ["full"] } futures = "0.3" libffi = "3.1.0" libloading = "0.7" derive_deref = "1.1.1" +http-body-util = "0.1.0-rc.2" +bytes = "1" +reqwest = { version = "0.11.18", features = ["blocking"] } [dev-dependencies] assert_cmd = "1.0.3" diff --git a/src/http.rs b/src/http.rs index 887366f8..71d1682c 100644 --- a/src/http.rs +++ b/src/http.rs @@ -1,25 +1,54 @@ -use std::sync::Arc; -use std::convert::Infallible; - -use hyper::{Response, Request, Body}; -use tokio::sync::Mutex; -use tokio::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::{Arc, Mutex, Condvar}; +use std::future::Future; +use std::pin::Pin; +use http_body_util::Full; +use bytes::Bytes; +use hyper::service::Service; +use hyper::{body::Incoming as IncomingBody, Request, Response}; pub struct HttpListener { - pub incoming: Receiver + pub incoming: std::sync::mpsc::Receiver } #[derive(Debug)] pub struct HttpRequest { - pub request: Request, + pub request: Request, pub response: HttpResponse, } -pub type HttpResponse = Sender>; +pub type HttpResponse = Arc<(Mutex, Mutex>>>, Condvar)>; + +pub struct HttpService { + pub tx: std::sync::mpsc::SyncSender, +} + +impl Service> for HttpService { + type Response = Response>; + type Error = hyper::Error; + type Future = Pin> + Send>>; + + fn call(&mut self, req: Request) -> Self::Future { + // new connection! + // we send the Request info to Prolog + let response = Arc::new((Mutex::new(false), Mutex::new(None), Condvar::new())); + let http_request = HttpRequest { request: req, response: Arc::clone(&response) }; + self.tx.send(http_request).unwrap(); -pub async fn serve_req(req: Request, tx: Arc>>) -> Result, Infallible> { - let (response_tx, mut rx) = channel(1); - let http_request = HttpRequest { request: req, response: response_tx }; - tx.lock().await.send(http_request).await.unwrap(); - Ok(rx.recv().await.unwrap()) + // we wait for the Response info from Prolog + { + let (ready, _response, cvar) = &*response; + let mut ready = ready.lock().unwrap(); + while !*ready { + ready = cvar.wait(ready).unwrap(); + } + } + { + let (_, response, _) = &*response; + let response = response.lock().unwrap().take(); + let res = response.expect("Data race error in HTTP Server"); + Box::pin(async move { + Ok(res) + }) + } + } } diff --git a/src/lib/http/http_server.pl b/src/lib/http/http_server.pl index 7f2de002..381d5607 100644 --- a/src/lib/http/http_server.pl +++ b/src/lib/http/http_server.pl @@ -121,37 +121,44 @@ http_loop(HttpListener, Handlers) :- send_response(ResponseHandle, http_response(StatusCode0, text(ResponseText), ResponseHeaders0)) :- default(StatusCode0, 200, StatusCode), maplist(map_header_kv_2, ResponseHeaders, ResponseHeaders0), - '$http_answer'(ResponseHandle, StatusCode, ResponseHeaders, ResponseStream), - call_cleanup( - format(ResponseStream, "~s", [ResponseText]), - close(ResponseStream) + '$http_answer'(ResponseHandle, StatusCode, ResponseHeaders, ResponseStream0), + open(stream(ResponseStream0), write, ResponseStream, [type(text)]), + catch( + call_cleanup(format(ResponseStream, "~s", [ResponseText]),close(ResponseStream)), + error(existence_error(stream, _), _), + true ). send_response(ResponseHandle, http_response(StatusCode0, bytes(ResponseBytes), ResponseHeaders0)) :- default(StatusCode0, 200, StatusCode), maplist(map_header_kv_2, ResponseHeaders, ResponseHeaders0), '$http_answer'(ResponseHandle, StatusCode, ResponseHeaders, ResponseStream), - call_cleanup( - format(ResponseStream, "~s", [ResponseBytes]), - close(ResponseStream) + catch( + call_cleanup(format(ResponseStream, "~s", [ResponseBytes]),close(ResponseStream)), + error(existence_error(stream, _), _), + true ). send_response(ResponseHandle, http_response(StatusCode0, file(Filename), ResponseHeaders0)) :- default(StatusCode0, 200, StatusCode), maplist(map_header_kv_2, ResponseHeaders, ResponseHeaders0), '$http_answer'(ResponseHandle, StatusCode, ResponseHeaders, ResponseStream), - call_cleanup( - setup_call_cleanup( - open(Filename, read, FileStream, [type(binary)]), - ( - get_n_chars(FileStream, _, FileCs), - format(ResponseStream, "~s", [FileCs]) + catch( + call_cleanup( + setup_call_cleanup( + open(Filename, read, FileStream, [type(binary)]), + ( + get_n_chars(FileStream, _, FileCs), + format(ResponseStream, "~s", [FileCs]) + ), + close(FileStream) ), - close(FileStream) + close(ResponseStream) ), - close(ResponseStream) + error(existence_error(stream, _), _), + true ). - + default(Var, Default, Out) :- (var(Var) -> Out = Default diff --git a/src/machine/streams.rs b/src/machine/streams.rs index 8d9f8407..27942cb2 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -9,6 +9,7 @@ use crate::machine::machine_errors::*; use crate::machine::machine_indices::*; use crate::machine::machine_state::*; use crate::types::*; +use crate::http::HttpResponse; pub use modular_bitfield::prelude::*; @@ -26,7 +27,6 @@ use std::ops::{Deref, DerefMut}; use std::ptr; use native_tls::TlsStream; -use hyper::body::{Bytes, Sender}; #[derive(Debug, BitfieldSpecifier, Clone, Copy, PartialEq, Eq, Hash)] #[bits = 1] @@ -276,7 +276,10 @@ impl Read for HttpReadStream { } pub struct HttpWriteStream { - body_writer: Sender, + status_code: u16, + headers: hyper::HeaderMap, + response: TypedArenaPtr, + buffer: Vec, } impl Debug for HttpWriteStream { @@ -288,17 +291,28 @@ impl Debug for HttpWriteStream { impl Write for HttpWriteStream { #[inline] fn write(&mut self, buf: &[u8]) -> std::io::Result { - let bytes = Bytes::copy_from_slice(buf); - let len = bytes.len(); - match self.body_writer.try_send_data(bytes) { - Ok(()) => Ok(len), - Err(_) => Err(std::io::Error::from(ErrorKind::Interrupted)) - } + self.buffer.extend_from_slice(buf); + Ok(buf.len()) } #[inline] fn flush(&mut self) -> std::io::Result<()> { - Ok(()) + let (ready, response, cvar) = &**self.response; + + let mut ready = ready.lock().unwrap(); + { + let mut response = response.lock().unwrap(); + + let bytes = bytes::Bytes::copy_from_slice(&self.buffer); + let mut response_ = hyper::Response::builder() + .status(self.status_code); + *response_.headers_mut().unwrap() = self.headers.clone(); + *response = Some(response_.body(http_body_util::Full::new(bytes)).unwrap()); + } + *ready = true; + cvar.notify_one(); + + Ok(()) } } @@ -1084,15 +1098,20 @@ impl Stream { #[inline] pub(crate) fn from_http_sender( - body_writer: Sender, - arena: &mut Arena, + response: TypedArenaPtr, + status_code: u16, + headers: hyper::HeaderMap, + arena: &mut Arena, ) -> Self { - Stream::HttpWrite(arena_alloc!( - StreamLayout::new(CharReader::new(HttpWriteStream { - body_writer - })), - arena - )) + Stream::HttpWrite(arena_alloc!( + StreamLayout::new(CharReader::new(HttpWriteStream { + response, + status_code, + headers, + buffer: Vec::new(), + })), + arena + )) } #[inline] @@ -1139,10 +1158,10 @@ impl Stream { Ok(()) } - Stream::HttpWrite(ref mut http_stream) => { + Stream::HttpWrite(ref mut http_stream) => { unsafe { http_stream.set_tag(ArenaHeaderTag::Dropped); - std::ptr::drop_in_place(&mut http_stream.inner_mut().body_writer as *mut _); + std::ptr::drop_in_place(&mut http_stream.inner_mut().buffer as *mut _); } Ok(()) diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 6a676ae9..2cfa521e 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -9,7 +9,7 @@ use crate::forms::*; use crate::ffi::*; use crate::heap_iter::*; use crate::heap_print::*; -use crate::http::{self, HttpListener, HttpResponse}; +use crate::http::{HttpService, HttpListener, HttpResponse}; use crate::instructions::*; use crate::machine; use crate::machine::{Machine, VERIFY_ATTR_INTERRUPT_LOC, get_structure_index}; @@ -39,7 +39,7 @@ use ref_thread_local::{RefThreadLocal, ref_thread_local}; use std::cell::Cell; use std::cmp::Ordering; use std::collections::BTreeSet; -use std::convert::{TryFrom, Infallible}; +use std::convert::{TryFrom}; use std::env; use std::ffi::CString; use std::fs; @@ -52,7 +52,6 @@ use std::num::NonZeroU32; use std::ops::Sub; use std::process; use std::str::FromStr; -use std::sync::Arc; use chrono::{offset::Local, DateTime}; use cpu_time::ProcessTime; @@ -80,13 +79,12 @@ use base64; use roxmltree; use select; -use hyper::{Body, Server, Client, HeaderMap, Method, Request, Response, Uri}; -use hyper::header::{HeaderName, HeaderValue}; -use hyper::body::Buf; -use hyper::service::{make_service_fn, service_fn}; -use hyper_tls::HttpsConnector; -use tokio::sync::Mutex; -use tokio::sync::mpsc::channel; +use hyper::server::conn::http1; +use hyper::header::{HeaderValue, HeaderName}; +use hyper::{HeaderMap, Method}; +use http_body_util::BodyExt; +use bytes::Buf; +use reqwest::Url; ref_thread_local! { pub(crate) static managed RANDOM_STATE: RandState<'static> = RandState::new(); @@ -3125,7 +3123,7 @@ impl Machine { } bytes.push(c as u8); - } + } } else { bytes = string.as_str().bytes().collect(); } @@ -4184,63 +4182,65 @@ impl Machine { }; if let Some(address_sink) = self.machine_st.value_to_str_like(address_sink) { let address_string = address_sink.as_str(); //to_string(); - let address: Uri = address_string.parse().unwrap(); - - let stream = self.runtime.block_on(async { - let https = HttpsConnector::new(); - let client = Client::builder() - .build::<_, hyper::Body>(https); - - // request - let mut req = Request::builder() - .method(method) - .uri(address) - .body(Body::from(bytes)) - .unwrap(); - // request headers - *req.headers_mut() = headers; - // do it! - let resp = client.request(req).await.unwrap(); - // status code - let status = resp.status().as_u16(); - self.machine_st.unify_fixnum(Fixnum::build_with(status as i64), address_status); - // headers - let headers: Vec = resp.headers().iter().map(|(header_name, header_value)| { - let h = self.machine_st.heap.len(); + let address: Url = address_string.parse().unwrap(); - let header_term = functor!( - self.machine_st.atom_tbl.build_with(header_name.as_str()), - [cell(string_as_cstr_cell!(self.machine_st.atom_tbl.build_with(header_value.to_str().unwrap())))] - ); + let client = reqwest::blocking::Client::builder() + .build() + .unwrap(); - self.machine_st.heap.extend(header_term.into_iter()); - str_loc_as_cell!(h) - }).collect(); - - let headers_list = iter_to_heap_list(&mut self.machine_st.heap, headers.into_iter()); - unify!(self.machine_st, heap_loc_as_cell!(headers_list), self.machine_st.registers[6]); - // body - let buf = hyper::body::aggregate(resp).await.unwrap(); - let reader = buf.reader(); - - let mut stream = Stream::from_http_stream( - self.machine_st.atom_tbl.build_with(&address_string), - Box::new(reader), - &mut self.machine_st.arena - ); - *stream.options_mut() = StreamOptions::default(); - if let Some(alias) = stream.options().get_alias() { - self.indices.stream_aliases.insert(alias, stream); - } + // request + let mut req = reqwest::blocking::Request::new(method, address); - self.indices.streams.insert(stream); + *req.headers_mut() = headers; + if bytes.len() > 0 { + *req.body_mut() = Some(reqwest::blocking::Body::from(bytes)); + } - stream_as_cell!(stream) - }); + // do it! + match client.execute(req) { + Ok(resp) => { + // status code + let status = resp.status().as_u16(); + self.machine_st.unify_fixnum(Fixnum::build_with(status as i64), address_status); + // headers + let headers: Vec = resp.headers().iter().map(|(header_name, header_value)| { + let h = self.machine_st.heap.len(); + + let header_term = functor!( + self.machine_st.atom_tbl.build_with(header_name.as_str()), + [cell(string_as_cstr_cell!(self.machine_st.atom_tbl.build_with(header_value.to_str().unwrap())))] + ); + + self.machine_st.heap.extend(header_term.into_iter()); + str_loc_as_cell!(h) + }).collect(); + + let headers_list = iter_to_heap_list(&mut self.machine_st.heap, headers.into_iter()); + unify!(self.machine_st, heap_loc_as_cell!(headers_list), self.machine_st.registers[6]); + // body + let reader = resp.bytes().unwrap().reader(); + + let mut stream = Stream::from_http_stream( + self.machine_st.atom_tbl.build_with(&address_string), + Box::new(reader), + &mut self.machine_st.arena + ); + *stream.options_mut() = StreamOptions::default(); + if let Some(alias) = stream.options().get_alias() { + self.indices.stream_aliases.insert(alias, stream); + } + + self.indices.streams.insert(stream); - let stream_addr = self.deref_register(2); - self.machine_st.bind(stream_addr.as_var().unwrap(), stream); + let stream = stream_as_cell!(stream); + let stream_addr = self.deref_register(2); + self.machine_st.bind(stream_addr.as_var().unwrap(), stream); + }, + Err(_) => { + self.machine_st.fail = true; + } + } } else { let err = self.machine_st.domain_error(DomainErrorType::SourceSink, address_sink); let stub = functor_stub(atom!("http_open"), 3); @@ -4264,26 +4264,31 @@ impl Machine { } }; - let (tx, rx) = channel(1); - let tx = Arc::new(Mutex::new(tx)); + let (tx, rx) = std::sync::mpsc::sync_channel(1024); let _guard = self.runtime.enter(); - let server = match Server::try_bind(&addr) { - Ok(server) => server, + let listener = match self.runtime.block_on(async { tokio::net::TcpListener::bind(addr).await }) { + Ok(listener) => listener, Err(_) => { return Err(self.machine_st.open_permission_error(address_sink, atom!("http_listen"), 2)); } }; self.runtime.spawn(async move { - let make_svc = make_service_fn(move |_conn| { + loop { let tx = tx.clone(); - async move { Ok::<_, Infallible>(service_fn(move |req| http::serve_req(req, tx.clone()))) } - }); - let server = server.serve(make_svc); - - if let Err(_) = server.await { - eprintln!("server error"); + let (stream, _) = listener.accept().await.unwrap(); + + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(stream, HttpService { + tx + }) + .await + { + eprintln!("Error serving connection: {:?}", err); + } + }); } }); let http_listener = HttpListener { incoming: rx }; @@ -4306,8 +4311,8 @@ impl Machine { (HeapCellValueTag::Cons, cons_ptr) => { match_untyped_arena_ptr!(cons_ptr, (ArenaHeaderTag::HttpListener, http_listener) => { - match http_listener.incoming.blocking_recv() { - Some(request) => { + match http_listener.incoming.recv() { + Ok(request) => { let method_atom = match *request.request.method() { Method::GET => atom!("get"), Method::POST => atom!("post"), @@ -4338,7 +4343,7 @@ impl Machine { let query_cell = string_as_cstr_cell!(query_atom); let hyper_req = request.request; - let buf = self.runtime.block_on(async {hyper::body::aggregate(hyper_req).await.unwrap()}); + let buf = self.runtime.block_on(async {hyper_req.collect().await.unwrap().aggregate()}); let reader = buf.reader(); let mut stream = Stream::from_http_stream( @@ -4360,7 +4365,7 @@ impl Machine { self.machine_st.bind(stream_addr.as_var().unwrap(), stream); self.machine_st.bind(handle_addr.as_var().unwrap(), typed_arena_ptr_as_cell!(handle)); } - None => { + Err(_) => { self.machine_st.fail = true; } } @@ -4418,15 +4423,10 @@ impl Machine { (HeapCellValueTag::Cons, cons_ptr) => { match_untyped_arena_ptr!(cons_ptr, (ArenaHeaderTag::HttpResponse, http_response) => { - let mut response = Response::builder() - .status(status_code); - *response.headers_mut().unwrap() = headers; - let (sender, body) = Body::channel(); - let response = response.body(body).unwrap(); - http_response.blocking_send(response).unwrap(); - let mut stream = Stream::from_http_sender( - sender, + http_response, + status_code, + headers, &mut self.machine_st.arena ); *stream.options_mut() = StreamOptions::default(); -- 2.54.0