зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1628459 - Update neqo to 0.2.4 r=agrover
Differential Revision: https://phabricator.services.mozilla.com/D70239 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
9e1706a554
Коммит
eb775d698e
|
@ -15,7 +15,7 @@ rev = "e3c3388e6632cf55e08d773b32e58b1cab9b2731"
|
|||
[source."https://github.com/mozilla/neqo"]
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
replace-with = "vendored-sources"
|
||||
tag = "v0.2.3"
|
||||
tag = "v0.2.4"
|
||||
|
||||
[source."https://github.com/mozilla/application-services"]
|
||||
git = "https://github.com/mozilla/application-services"
|
||||
|
|
|
@ -2816,8 +2816,8 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
|
|||
|
||||
[[package]]
|
||||
name = "neqo-common"
|
||||
version = "0.2.3"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.3#b10d8b3c3e480f6671b39c37f01f80cf2503697b"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.4#6fca78d008168e6fdf4c9d3a76b49acab07522a7"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
|
@ -2827,8 +2827,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-crypto"
|
||||
version = "0.2.3"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.3#b10d8b3c3e480f6671b39c37f01f80cf2503697b"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.4#6fca78d008168e6fdf4c9d3a76b49acab07522a7"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"log",
|
||||
|
@ -2840,8 +2840,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-http3"
|
||||
version = "0.2.3"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.3#b10d8b3c3e480f6671b39c37f01f80cf2503697b"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.4#6fca78d008168e6fdf4c9d3a76b49acab07522a7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"neqo-common",
|
||||
|
@ -2854,20 +2854,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neqo-qpack"
|
||||
version = "0.2.3"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.3#b10d8b3c3e480f6671b39c37f01f80cf2503697b"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.4#6fca78d008168e6fdf4c9d3a76b49acab07522a7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"neqo-common",
|
||||
"neqo-crypto",
|
||||
"neqo-transport",
|
||||
"num-traits",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neqo-transport"
|
||||
version = "0.2.3"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.3#b10d8b3c3e480f6671b39c37f01f80cf2503697b"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.2.4#6fca78d008168e6fdf4c9d3a76b49acab07522a7"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
|
|
|
@ -8,16 +8,16 @@ edition = "2018"
|
|||
name = "neqo_glue"
|
||||
|
||||
[dependencies]
|
||||
neqo-http3 = { tag = "v0.2.3", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.2.3", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.2.3", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.2.4", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.2.4", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.2.4", git = "https://github.com/mozilla/neqo" }
|
||||
nserror = { path = "../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
||||
xpcom = { path = "../../../xpcom/rust/xpcom" }
|
||||
thin-vec = { version = "0.1.0", features = ["gecko-ffi"] }
|
||||
|
||||
[dependencies.neqo-crypto]
|
||||
tag = "v0.2.3"
|
||||
tag = "v0.2.4"
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
default-features = false
|
||||
features = ["gecko"]
|
||||
|
|
|
@ -36,7 +36,7 @@ impl NeqoHttp3Conn {
|
|||
alpn: &nsACString,
|
||||
local_addr: &nsACString,
|
||||
remote_addr: &nsACString,
|
||||
max_table_size: u32,
|
||||
max_table_size: u64,
|
||||
max_blocked_streams: u16,
|
||||
) -> Result<RefPtr<NeqoHttp3Conn>, nsresult> {
|
||||
// Nss init.
|
||||
|
@ -117,7 +117,7 @@ pub extern "C" fn neqo_http3conn_new(
|
|||
alpn: &nsACString,
|
||||
local_addr: &nsACString,
|
||||
remote_addr: &nsACString,
|
||||
max_table_size: u32,
|
||||
max_table_size: u64,
|
||||
max_blocked_streams: u16,
|
||||
result: &mut *const NeqoHttp3Conn,
|
||||
) -> nsresult {
|
||||
|
|
|
@ -5,15 +5,15 @@ authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
neqo-transport = { tag = "v0.2.3", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.2.3", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.2.3", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-transport = { tag = "v0.2.4", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-common = { tag = "v0.2.4", git = "https://github.com/mozilla/neqo" }
|
||||
neqo-http3 = { tag = "v0.2.4", git = "https://github.com/mozilla/neqo" }
|
||||
mio = "0.6.17"
|
||||
mio-extras = "2.0.5"
|
||||
log = "0.4.0"
|
||||
|
||||
[dependencies.neqo-crypto]
|
||||
tag = "v0.2.3"
|
||||
tag = "v0.2.4"
|
||||
git = "https://github.com/mozilla/neqo"
|
||||
default-features = false
|
||||
features = ["gecko"]
|
||||
|
|
|
@ -170,7 +170,7 @@ fn process(
|
|||
}
|
||||
|
||||
fn main() -> Result<(), io::Error> {
|
||||
const MAX_TABLE_SIZE: u32 = 65536;
|
||||
const MAX_TABLE_SIZE: u64 = 65536;
|
||||
const MAX_BLOCKED_STREAMS: u16 = 10;
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"fe9e4d1c1e3cad6ea5cca57b296000a7007fb410d42df5c7e037fd62b93828bf","src/codec.rs":"00846df0051f32ec8b75b2f8e0344422e0693acbd4151aaec31e3ae02d6e696c","src/datagram.rs":"4beb13d5ea7927df6801fbe684dc231626c1856010eaef975d866ee66e894a45","src/incrdecoder.rs":"7b7b7fba57714a3baf0fe881010a9f5a9814bf26b9283a6d56d1c44010cbd822","src/lib.rs":"c5abb57c37bdd913bfa237b274fce08c0b06fe852a6518159f60180eb478a861","src/log.rs":"943e4e332400d94805d60f965d1d0ae7aad180f6d5b50936d0bd9e085bbc1502","src/timer.rs":"ad70a231bd1f5eb4c54021ce03e4af29ff8cf5e28b0b28127bb14411c64de39c","tests/log.rs":"480b165b7907ec642c508b303d63005eee1427115d6973a349eaf6b2242ed18d"},"package":null}
|
||||
{"files":{"Cargo.toml":"5014d3a1cafb9fea549a210316879e93af6b6cde4f56af8f33579f58efd688f1","src/codec.rs":"00846df0051f32ec8b75b2f8e0344422e0693acbd4151aaec31e3ae02d6e696c","src/datagram.rs":"4beb13d5ea7927df6801fbe684dc231626c1856010eaef975d866ee66e894a45","src/incrdecoder.rs":"7b7b7fba57714a3baf0fe881010a9f5a9814bf26b9283a6d56d1c44010cbd822","src/lib.rs":"c5abb57c37bdd913bfa237b274fce08c0b06fe852a6518159f60180eb478a861","src/log.rs":"943e4e332400d94805d60f965d1d0ae7aad180f6d5b50936d0bd9e085bbc1502","src/timer.rs":"ad70a231bd1f5eb4c54021ce03e4af29ff8cf5e28b0b28127bb14411c64de39c","tests/log.rs":"480b165b7907ec642c508b303d63005eee1427115d6973a349eaf6b2242ed18d"},"package":null}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "neqo-common"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = ["Bobby Holley <bobbyholley@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"a4c35a6c4fa513f1224c658876e0eec4f3b19e7617e5c5bf14d534a40926d228","TODO":"ac0f1c2ebcca03f5b3c0cc56c5aedbb030a4b511e438bc07a57361c789f91e9f","bindings/bindings.toml":"00ff7348732c956b4f8829f00df2b18b3a7211f5fa2a4cea4ae40c0f859e5f50","bindings/mozpkix.hpp":"77072c8bb0f6eb6bfe8cbadc111dcd92e0c79936d13f2e501aae1e5d289a6675","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"4250bc8cecf44ec155b2bf4119303f3a0bbcccce461db237e3f34da1636e8511","src/aead.rs":"2013408fbcf9e93331ae14d9d6bdd096966f125b3cf48f83e671f537e89d4e77","src/agent.rs":"4c7ad4f0e64aa64e743af0b6aa8aeef3971215324def68239208a09f333582e6","src/agentio.rs":"3aae54ef408add3ce98930e11d46668c4e17073d52e1aecf2aad4037b0bed9e7","src/auth.rs":"71ac7e297a5f872d26cf67b6bbd96e4548ea38374bdd84c1094f76a5de4ed1cb","src/cert.rs":"fd3fd2bbb38754bdcee3898549feae412943c9f719032531c1ad6e61783b5394","src/constants.rs":"e756c07525bd7c2ff271e504708f903b3ede0a3ae821446bd37701055eb11f5f","src/err.rs":"04f38831ca62d29d8aadfe9daf95fd29e68ece184e6d3e00bfb9ee1d12744033","src/exp.rs":"61586662407359c1ecb8ed4987bc3c702f26ba2e203a091a51b6d6363cbd510f","src/ext.rs":"bf7b5f23caf26ab14fba3baf0823dd093e4194f759779e4cfd608478312ed58c","src/hkdf.rs":"1bb57806bbf67af74966bb2bb724de9d6b0094c6f5cddbe12d46292d58ba1f16","src/hp.rs":"0384bc676d8cc66a2cfec7be9df176f04557e4f1424c6d19d03ba5687920ac86","src/lib.rs":"81c51aef34744748498e88ad8480883ae69c0537c2a80ae299f44f6bc237f8b0","src/once.rs":"d8b2bf7a9e3ce83bdd7f29d8f73ce7ad0268c9618ae7255028fea9f90c9c9fd6","src/p11.rs":"6e94cbb594b709c3081449bf50d9961d36648b5db95fb824779bff4f45125ad2","src/prio.rs":"bc4e97049563b136cb7b39f5171e7909d56a77ed46690aaacb781eeb4a4743e0","src/replay.rs":"9bc5826cc8be6afe787f0d403b3958245efce9bfbc7b3100734e5aec3f8b9753","src/result.rs":"cef34dfcb907723e195b56501132e4560e250b327783cb5e41201da5b63e9b5c","src/secrets.rs":"a60d6c5c949f575382b0eabaa217bb7dfed2361b2513242f62b4028cb112d0ee","src/selfencrypt.rs":"02e963e8b9ea0802f7ee64384e5ccef3e31420e75bc1aacd02270dd504ffbdb1","src/ssl.rs":"29c514427809ba3658ea0d9a4159fa6cf16809a9c19e034c4f02598f6bb42731","src/time.rs":"96d13a955a849249620b4a1dad15bb5964e89c288e6a5035b31ef8f4d35f1e0a","tests/aead.rs":"cccac271087fe37d0a890e5da04984bbfacb4bc12331473dfc189e4d6ebff5f2","tests/agent.rs":"4fa8fa803266b985e9b6329e6a218fe7bd779200b8e0cfa94f5813e0ccc10995","tests/ext.rs":"f5edc1f229703f786ec31a8035465c00275223f14a3c4abe52f3c7cf2686cc03","tests/handshake.rs":"bcc687c0e1b485658847faf28a9f5dbfdb297812bed1bd2e80593d5f9e1fee36","tests/hkdf.rs":"0e4853f629050ba4d8069be52b7a441b670d1abaf6b8cd670a8215e0b88beb37","tests/hp.rs":"e6dd3cb4bceebc6fca8f270d8302ef34e14bda6c91fc4f9342ba1681be57ee03","tests/init.rs":"55df7cb95deb629f8701b55a8bcb91e797f30fb10e847a36a0a5a4e80488b002","tests/selfencrypt.rs":"60bfe8a0729cdaa6c2171146083266fa0e625a1d98b5f8735cd22b725d32398b"},"package":null}
|
||||
{"files":{"Cargo.toml":"7b06f80130df7e4c49abd2efe4ddcc6bfedacb591623e9205bfd039f157ddf83","TODO":"ac0f1c2ebcca03f5b3c0cc56c5aedbb030a4b511e438bc07a57361c789f91e9f","bindings/bindings.toml":"00ff7348732c956b4f8829f00df2b18b3a7211f5fa2a4cea4ae40c0f859e5f50","bindings/mozpkix.hpp":"77072c8bb0f6eb6bfe8cbadc111dcd92e0c79936d13f2e501aae1e5d289a6675","bindings/nspr_err.h":"2d5205d017b536c2d838bcf9bc4ec79f96dd50e7bb9b73892328781f1ee6629d","bindings/nspr_error.h":"e41c03c77b8c22046f8618832c9569fbcc7b26d8b9bbc35eea7168f35e346889","bindings/nspr_io.h":"085b289849ef0e77f88512a27b4d9bdc28252bd4d39c6a17303204e46ef45f72","bindings/nspr_time.h":"2e637fd338a5cf0fd3fb0070a47f474a34c2a7f4447f31b6875f5a9928d0a261","bindings/nss_ciphers.h":"95ec6344a607558b3c5ba8510f463b6295f3a2fb3f538a01410531045a5f62d1","bindings/nss_init.h":"ef49045063782fb612aff459172cc6a89340f15005808608ade5320ca9974310","bindings/nss_p11.h":"0b81e64fe6db49b2ecff94edd850be111ef99ec11220e88ceb1c67be90143a78","bindings/nss_secerr.h":"713e8368bdae5159af7893cfa517dabfe5103cede051dee9c9557c850a2defc6","bindings/nss_ssl.h":"af222fb957b989e392e762fa2125c82608a0053aff4fb97e556691646c88c335","bindings/nss_sslerr.h":"24b97f092183d8486f774cdaef5030d0249221c78343570d83a4ee5b594210ae","bindings/nss_sslopt.h":"b7807eb7abdad14db6ad7bc51048a46b065a0ea65a4508c95a12ce90e59d1eea","build.rs":"4250bc8cecf44ec155b2bf4119303f3a0bbcccce461db237e3f34da1636e8511","src/aead.rs":"2013408fbcf9e93331ae14d9d6bdd096966f125b3cf48f83e671f537e89d4e77","src/agent.rs":"4c7ad4f0e64aa64e743af0b6aa8aeef3971215324def68239208a09f333582e6","src/agentio.rs":"27c33e821234134f65de74bb7215947bce995833603fa2c95e509e561ded33d6","src/auth.rs":"71ac7e297a5f872d26cf67b6bbd96e4548ea38374bdd84c1094f76a5de4ed1cb","src/cert.rs":"fd3fd2bbb38754bdcee3898549feae412943c9f719032531c1ad6e61783b5394","src/constants.rs":"e756c07525bd7c2ff271e504708f903b3ede0a3ae821446bd37701055eb11f5f","src/err.rs":"04f38831ca62d29d8aadfe9daf95fd29e68ece184e6d3e00bfb9ee1d12744033","src/exp.rs":"61586662407359c1ecb8ed4987bc3c702f26ba2e203a091a51b6d6363cbd510f","src/ext.rs":"bf7b5f23caf26ab14fba3baf0823dd093e4194f759779e4cfd608478312ed58c","src/hkdf.rs":"1bb57806bbf67af74966bb2bb724de9d6b0094c6f5cddbe12d46292d58ba1f16","src/hp.rs":"0384bc676d8cc66a2cfec7be9df176f04557e4f1424c6d19d03ba5687920ac86","src/lib.rs":"81c51aef34744748498e88ad8480883ae69c0537c2a80ae299f44f6bc237f8b0","src/once.rs":"d8b2bf7a9e3ce83bdd7f29d8f73ce7ad0268c9618ae7255028fea9f90c9c9fd6","src/p11.rs":"6e94cbb594b709c3081449bf50d9961d36648b5db95fb824779bff4f45125ad2","src/prio.rs":"bc4e97049563b136cb7b39f5171e7909d56a77ed46690aaacb781eeb4a4743e0","src/replay.rs":"9bc5826cc8be6afe787f0d403b3958245efce9bfbc7b3100734e5aec3f8b9753","src/result.rs":"cef34dfcb907723e195b56501132e4560e250b327783cb5e41201da5b63e9b5c","src/secrets.rs":"a60d6c5c949f575382b0eabaa217bb7dfed2361b2513242f62b4028cb112d0ee","src/selfencrypt.rs":"02e963e8b9ea0802f7ee64384e5ccef3e31420e75bc1aacd02270dd504ffbdb1","src/ssl.rs":"29c514427809ba3658ea0d9a4159fa6cf16809a9c19e034c4f02598f6bb42731","src/time.rs":"96d13a955a849249620b4a1dad15bb5964e89c288e6a5035b31ef8f4d35f1e0a","tests/aead.rs":"cccac271087fe37d0a890e5da04984bbfacb4bc12331473dfc189e4d6ebff5f2","tests/agent.rs":"4fa8fa803266b985e9b6329e6a218fe7bd779200b8e0cfa94f5813e0ccc10995","tests/ext.rs":"f5edc1f229703f786ec31a8035465c00275223f14a3c4abe52f3c7cf2686cc03","tests/handshake.rs":"bcc687c0e1b485658847faf28a9f5dbfdb297812bed1bd2e80593d5f9e1fee36","tests/hkdf.rs":"0e4853f629050ba4d8069be52b7a441b670d1abaf6b8cd670a8215e0b88beb37","tests/hp.rs":"e6dd3cb4bceebc6fca8f270d8302ef34e14bda6c91fc4f9342ba1681be57ee03","tests/init.rs":"55df7cb95deb629f8701b55a8bcb91e797f30fb10e847a36a0a5a4e80488b002","tests/selfencrypt.rs":"60bfe8a0729cdaa6c2171146083266fa0e625a1d98b5f8735cd22b725d32398b"},"package":null}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "neqo-crypto"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = ["Martin Thomson <mt@lowentropy.net>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
|
|
@ -260,10 +260,10 @@ impl ::std::fmt::Display for AgentIo {
|
|||
}
|
||||
|
||||
unsafe extern "C" fn agent_close(fd: PrFd) -> PrStatus {
|
||||
(*fd).secret = null_mut();
|
||||
if let Some(dtor) = (*fd).dtor {
|
||||
dtor(fd);
|
||||
}
|
||||
(*fd).secret = null_mut();
|
||||
PR_SUCCESS
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"6d8ebeed0293b39bb00ba5e3fc55abf028c6d089b32c37dfda66b738441db05f","src/client_events.rs":"8e77e6e92c3d5933621f2baee3baacab230486ad8b6df1eca321ea74ed7cdcbd","src/connection.rs":"8499ea115fc061eb5d2eedb0a5cac6069a255ad756e6e89ce2f6e6a8dc5772fc","src/connection_client.rs":"b803756b3a81f16757e672023a1424c1f60b07ca9f5351475258814e92ab0a2c","src/connection_server.rs":"24ca3746fadf090dcfa4b3e14e0a74722162adc0fe70463a68b0009a47210c09","src/control_stream_local.rs":"319f8277fc4765b31a4a094bfd663e681d71831532925b0043bae5da96202e64","src/control_stream_remote.rs":"c205633af8539cd55f289071c6845b5bb2b0a9778f15976829c5d4a492360e19","src/hframe.rs":"5b580d431ae9639bebfa1868a8f4f358e46884c34b81011126745e64244e4323","src/hsettings_frame.rs":"349a4413ce13f03e05264e6c4b22d231276a1c96e3983aada4478b038ec89dbc","src/lib.rs":"383bfaacfe138a7cbbd9162973a430016ee0fc59cd3ae087743cf37c148f7edd","src/response_stream.rs":"808c40e0bc51599e2b253cf9d535ae8404abaccc7fd875f8e08eafdfaeab3012","src/server.rs":"c4cfbf49a002a55c6e7c5167bcaa4e15bdd80811af98ba5ecb6cec1ccd473df3","src/server_connection_events.rs":"d2b973a095f29cb0ac6fb84705165b034960d09b2dde7693bab96e6b802c6fba","src/server_events.rs":"f997bd329d45115f6a527eba8f0f1ecf21c0dd9a3184f08fc5002e34f4cfe2f0","src/stream_type_reader.rs":"da2b7b0358cb4829493cb964cae67c85e9efdf4127958aade7a56733ddc4f12e","src/transaction_client.rs":"8a96f2acb0cd6f7c09d1e9b92a71171a474d46c7e21b55e546aa4d6c330981d3","src/transaction_server.rs":"1af45a238950acfc563484d2b5ebe805a83bdcc1096f5c03ed8d180c4e7428d5","tests/httpconn.rs":"7955f6ac4406b5d770e0fb10258aff529a1c01020374dfc5f85d8608abb68f6f"},"package":null}
|
||||
{"files":{"Cargo.toml":"852873c28cf410a18b26b7e9903bb03f10d0f16127637011350764aca717e52e","src/client_events.rs":"8e77e6e92c3d5933621f2baee3baacab230486ad8b6df1eca321ea74ed7cdcbd","src/connection.rs":"dc0736489ce1c0abf441eb6e9a10e48c0e6bc406ea628ae05fd26358c291b1f3","src/connection_client.rs":"8e9f2ece451d6fb1c7db9274aab3b342639337d9c36dba97280fb11842e7a88b","src/connection_server.rs":"0f55d4564bd7863bd2c3f83cb52cce78c4ad9271855376ce6b9562b9975e03ff","src/control_stream_local.rs":"e67877e148264fd7c19dfd13ef5a54ba48ef8f0b3109ae73d38f84417c4f2d0e","src/control_stream_remote.rs":"c205633af8539cd55f289071c6845b5bb2b0a9778f15976829c5d4a492360e19","src/hframe.rs":"5b580d431ae9639bebfa1868a8f4f358e46884c34b81011126745e64244e4323","src/hsettings_frame.rs":"349a4413ce13f03e05264e6c4b22d231276a1c96e3983aada4478b038ec89dbc","src/lib.rs":"9fd22f4da0854a08720f58163f2f64bee41717e62c45d162fed50566f786caf2","src/response_stream.rs":"808c40e0bc51599e2b253cf9d535ae8404abaccc7fd875f8e08eafdfaeab3012","src/server.rs":"9fe5fdbaa770d02059b8a4357b0cef0d52dba0d89ab58cb094aa3c70cbc7d84a","src/server_connection_events.rs":"d2b973a095f29cb0ac6fb84705165b034960d09b2dde7693bab96e6b802c6fba","src/server_events.rs":"f997bd329d45115f6a527eba8f0f1ecf21c0dd9a3184f08fc5002e34f4cfe2f0","src/stream_type_reader.rs":"da2b7b0358cb4829493cb964cae67c85e9efdf4127958aade7a56733ddc4f12e","src/transaction_client.rs":"8a96f2acb0cd6f7c09d1e9b92a71171a474d46c7e21b55e546aa4d6c330981d3","src/transaction_server.rs":"1af45a238950acfc563484d2b5ebe805a83bdcc1096f5c03ed8d180c4e7428d5","tests/httpconn.rs":"7955f6ac4406b5d770e0fb10258aff529a1c01020374dfc5f85d8608abb68f6f"},"package":null}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "neqo-http3"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
|
|
@ -46,7 +46,7 @@ enum Http3RemoteSettingsState {
|
|||
|
||||
#[derive(Debug, PartialEq, PartialOrd, Ord, Eq, Clone)]
|
||||
struct LocalSettings {
|
||||
max_table_size: u32,
|
||||
max_table_size: u64,
|
||||
max_blocked_streams: u16,
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ impl<T: Http3Transaction> ::std::fmt::Display for Http3Connection<T> {
|
|||
}
|
||||
|
||||
impl<T: Http3Transaction> Http3Connection<T> {
|
||||
pub fn new(max_table_size: u32, max_blocked_streams: u16) -> Self {
|
||||
pub fn new(max_table_size: u64, max_blocked_streams: u16) -> Self {
|
||||
if max_table_size > (1 << 30) - 1 {
|
||||
panic!("Wrong max_table_size");
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ impl<T: Http3Transaction> Http3Connection<T> {
|
|||
settings: HSettings::new(&[
|
||||
HSetting {
|
||||
setting_type: HSettingType::MaxTableCapacity,
|
||||
value: self.qpack_decoder.get_max_table_size().into(),
|
||||
value: self.qpack_decoder.get_max_table_size(),
|
||||
},
|
||||
HSetting {
|
||||
setting_type: HSettingType::BlockedStreams,
|
||||
|
@ -459,7 +459,6 @@ impl<T: Http3Transaction> Http3Connection<T> {
|
|||
.map_err(|_| Error::HttpStreamCreationError)?;
|
||||
Ok(false)
|
||||
}
|
||||
// TODO reserved stream types
|
||||
_ => {
|
||||
conn.stream_stop_sending(stream_id, Error::HttpStreamCreationError.code())?;
|
||||
Ok(false)
|
||||
|
@ -585,7 +584,7 @@ impl<T: Http3Transaction> Http3Connection<T> {
|
|||
match st {
|
||||
HSettingType::MaxTableCapacity => {
|
||||
if zero_rtt_value != 0 {
|
||||
return Err(Error::HttpSettingsError);
|
||||
return Err(Error::QpackError(neqo_qpack::Error::DecoderStream));
|
||||
}
|
||||
qpack_changed = true;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ impl Http3Client {
|
|||
cid_manager: Rc<RefCell<dyn ConnectionIdManager>>,
|
||||
local_addr: SocketAddr,
|
||||
remote_addr: SocketAddr,
|
||||
max_table_size: u32,
|
||||
max_table_size: u64,
|
||||
max_blocked_streams: u16,
|
||||
) -> Res<Self> {
|
||||
Ok(Self::new_with_conn(
|
||||
|
@ -51,7 +51,7 @@ impl Http3Client {
|
|||
))
|
||||
}
|
||||
|
||||
pub fn new_with_conn(c: Connection, max_table_size: u32, max_blocked_streams: u16) -> Self {
|
||||
pub fn new_with_conn(c: Connection, max_table_size: u64, max_blocked_streams: u16) -> Self {
|
||||
Self {
|
||||
conn: c,
|
||||
base_handler: Http3Connection::new(max_table_size, max_blocked_streams),
|
||||
|
@ -2816,7 +2816,7 @@ mod tests {
|
|||
HSetting::new(HSettingType::BlockedStreams, 100),
|
||||
HSetting::new(HSettingType::MaxHeaderListSize, 10000),
|
||||
],
|
||||
Http3State::Closing(CloseError::Application(265)),
|
||||
Http3State::Closing(CloseError::Application(514)),
|
||||
ENCODER_STREAM_DATA_WITH_CAP_INSTRUCTION,
|
||||
);
|
||||
}
|
||||
|
@ -3013,7 +3013,7 @@ mod tests {
|
|||
// We already had HeaderReady
|
||||
let header_ready: fn(&Http3ClientEvent) -> _ =
|
||||
|e| matches!(*e, Http3ClientEvent::HeaderReady { .. });
|
||||
assert!(!events.clone().iter().any(header_ready));
|
||||
assert!(!events.iter().any(header_ready));
|
||||
|
||||
// Check that we have a DataReady event. Reading from the stream will return fin=true.
|
||||
let data_readable: fn(&Http3ClientEvent) -> _ =
|
||||
|
@ -3075,7 +3075,7 @@ mod tests {
|
|||
// We already had HeaderReady
|
||||
let header_ready: fn(&Http3ClientEvent) -> _ =
|
||||
|e| matches!(*e, Http3ClientEvent::HeaderReady { .. });
|
||||
assert!(!events.clone().iter().any(header_ready));
|
||||
assert!(!events.iter().any(header_ready));
|
||||
|
||||
// Check that we have a DataReady event. Reading from the stream will return fin=true.
|
||||
let data_readable: fn(&Http3ClientEvent) -> _ =
|
||||
|
@ -3139,4 +3139,34 @@ mod tests {
|
|||
client.process(out.dgram(), now());
|
||||
assert_closed(&client, Error::HttpFrameUnexpected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transport_stream_readable_event_after_all_data() {
|
||||
let (mut client, mut server, request_stream_id) = connect_and_send_request(false);
|
||||
|
||||
// Send headers.
|
||||
let _ = server.conn.stream_send(request_stream_id, HTTP_RESPONSE_2);
|
||||
|
||||
let out = server.conn.process(None, now());
|
||||
client.process(out.dgram(), now());
|
||||
|
||||
// Send an empty data frame.
|
||||
let _ = server.conn.stream_send(request_stream_id, &[0x00, 0x00]);
|
||||
// ok NOW send fin
|
||||
server.conn.stream_close_send(request_stream_id).unwrap();
|
||||
|
||||
let out = server.conn.process(None, now());
|
||||
client.process_input(out.dgram().unwrap(), now());
|
||||
|
||||
let (h, fin) = client.read_response_headers(request_stream_id).unwrap();
|
||||
check_response_header_2(h);
|
||||
assert_eq!(fin, false);
|
||||
let mut buf = [0u8; 100];
|
||||
assert_eq!(
|
||||
client.read_response_data(now(), 0, &mut buf),
|
||||
Ok((3, false))
|
||||
);
|
||||
|
||||
client.process(None, now());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ impl ::std::fmt::Display for Http3ServerHandler {
|
|||
}
|
||||
|
||||
impl Http3ServerHandler {
|
||||
pub fn new(max_table_size: u32, max_blocked_streams: u16) -> Self {
|
||||
pub fn new(max_table_size: u64, max_blocked_streams: u16) -> Self {
|
||||
Self {
|
||||
base_handler: Http3Connection::new(max_table_size, max_blocked_streams),
|
||||
events: Http3ServerConnEvents::default(),
|
||||
|
|
|
@ -51,7 +51,7 @@ impl ControlStreamLocal {
|
|||
qtrace!([self], "Create a control stream.");
|
||||
self.stream_id = Some(conn.stream_create(StreamType::UniDi)?);
|
||||
let mut enc = Encoder::default();
|
||||
enc.encode_varint(HTTP3_UNI_STREAM_TYPE_CONTROL as u64);
|
||||
enc.encode_varint(HTTP3_UNI_STREAM_TYPE_CONTROL);
|
||||
self.buf.append(&mut enc.into());
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -131,8 +131,8 @@ impl From<AppError> for Error {
|
|||
0x10f => Self::HttpConnectError,
|
||||
0x110 => Self::HttpVersionFallback,
|
||||
0x200 => Self::QpackError(QpackError::DecompressionFailed),
|
||||
0x201 => Self::QpackError(QpackError::EncoderStreamError),
|
||||
0x202 => Self::QpackError(QpackError::DecoderStreamError),
|
||||
0x201 => Self::QpackError(QpackError::EncoderStream),
|
||||
0x202 => Self::QpackError(QpackError::DecoderStream),
|
||||
_ => Self::HttpInternalError,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ type HandlerRef = Rc<RefCell<Http3ServerHandler>>;
|
|||
|
||||
pub struct Http3Server {
|
||||
server: Server,
|
||||
max_table_size: u32,
|
||||
max_table_size: u64,
|
||||
max_blocked_streams: u16,
|
||||
http3_handlers: HashMap<ActiveConnectionRef, HandlerRef>,
|
||||
events: Http3ServerEvents,
|
||||
|
@ -41,7 +41,7 @@ impl Http3Server {
|
|||
protocols: &[impl AsRef<str>],
|
||||
anti_replay: AntiReplay,
|
||||
cid_manager: Rc<RefCell<dyn ConnectionIdManager>>,
|
||||
max_table_size: u32,
|
||||
max_table_size: u64,
|
||||
max_blocked_streams: u16,
|
||||
) -> Res<Self> {
|
||||
Ok(Self {
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"9fe6e7cc5408e8e6cfbae22aefc8050cd3ebb85dd6511ffa3b3f65cb6bb0c1df","src/decoder.rs":"acbd06547852e09e2779c397eb47a83fe83c0b9bd74328beaeb8aeb6fb805eb3","src/decoder_instructions.rs":"6a017bd56c0a157291c66924855eec14f409bfd8139958cb62641f040f9084ef","src/encoder.rs":"7b2bdbd742d15f747b51cb96a72bd94fc471e30ce218d7292f5391546755c308","src/encoder_instructions.rs":"bdeacaab2de61bfed7b675b6c245bb065a851d52f8ac749c717422e9ddb6f79e","src/header_block.rs":"08bc177f4fd899f00c958cc1417fdfc8ff7aee4bc82587609c0a63f1a530ddaf","src/huffman.rs":"720eedace45205098a0b2210c876906ce15b7be469a799e75e70baafac8adee8","src/huffman_decode_helper.rs":"e4734353591770dfe9a9047b0be5d9068150433e9cea8cad029444b42b0afa39","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"93e58f710554988f314d56a61568d61e154b6b691ba1cd554017ebe9d879d641","src/prefix.rs":"d74b640398da28cff8a0186f1d92c02e9561cef97609fdaf61d4dcfa4e265dc7","src/qpack_send_buf.rs":"e8c601ebbad5388ceac27909123e9bfa7c99267565a427df4c2514946fe0dc74","src/reader.rs":"bd776cde905dec0c036ebeece9b436295a9b9dd7ce94234af201ee0773d938a9","src/static_table.rs":"fda9d5c6f38f94b0bf92d3afdf8432dce6e27e189736596e16727090c77b78ec","src/table.rs":"dcd927d439ffe0b8e6b59d36b4794203e20b58b2b6c89564d7a885d7c3c0dd2e"},"package":null}
|
||||
{"files":{"Cargo.toml":"562a8d2e09f2e2484280044c9741c671d079941b1e5fa187555b5e165a8813dc","src/decoder.rs":"ab0d1170cbc44ac86a64613e3c63bf940b3d62302124d25d672b33926d800de2","src/decoder_instructions.rs":"52ae03b662200efc40862ddcd924cb0082638f6ccbbf8f7a676340c033392733","src/encoder.rs":"1d1084853eca860b55080c01ec4aa8157ebd95e5f74597a9b83de859d0c8b403","src/encoder_instructions.rs":"66c9276a52179bbe7caaee3a67d1e736098fa063c172ac3e7ce5ec36f8811bdb","src/header_block.rs":"2333ca6f134ca72718c1b685b381aefb4e6e5525ca3bb4402839f0b2e685b23b","src/huffman.rs":"0e49f818d1d186bef2208e47b70650d64a4b5389a3422af004a003e61286a0e0","src/huffman_decode_helper.rs":"1fb1423ee1cc0ceb27d05a515a994835359ae9af58c6885b37806e5e0fbf98c5","src/huffman_table.rs":"06fea766a6276ac56c7ee0326faed800a742c15fda1f33bf2513e6cc6a5e6d27","src/lib.rs":"1fd424fd8219d0244e56b81af168a3023801319f6d1c81c2eb0cac7e1e9e382e","src/prefix.rs":"8807126dbf4e7aff9afe164072c523b8fbfa0be5d4c57bb8291b510c8f0e8ca5","src/qpack_send_buf.rs":"8c1b97d17220038c8e040edb5d5bfc39eb72ab50dfa325016e799740acc47558","src/reader.rs":"ec7203354584d299ac843cc9565442a726f788dbc8a48082ac8e1cad21698547","src/static_table.rs":"fda9d5c6f38f94b0bf92d3afdf8432dce6e27e189736596e16727090c77b78ec","src/table.rs":"7de73afcd901d1191f20c0a18ccd5f3917f739ac78ded173f684818aa4b55486"},"package":null}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "neqo-qpack"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = ["Dragana Damjanovic <dragana.damjano@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
@ -11,6 +11,7 @@ neqo-transport = { path = "./../neqo-transport" }
|
|||
neqo-crypto = { path = "./../neqo-crypto" }
|
||||
log = {version = "0.4.0", default-features = false}
|
||||
static_assertions = "1.1.0"
|
||||
num-traits = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
test-fixture = { path = "../test-fixture" }
|
||||
|
|
|
@ -27,19 +27,20 @@ pub struct QPackDecoder {
|
|||
send_buf: QPData,
|
||||
local_stream_id: Option<u64>,
|
||||
remote_stream_id: Option<u64>,
|
||||
max_table_size: u32,
|
||||
max_table_size: u64,
|
||||
max_blocked_streams: usize,
|
||||
blocked_streams: Vec<(u64, u64)>, //stream_id and requested inserts count.
|
||||
}
|
||||
|
||||
impl QPackDecoder {
|
||||
pub fn new(max_table_size: u32, max_blocked_streams: u16) -> Self {
|
||||
#[must_use]
|
||||
pub fn new(max_table_size: u64, max_blocked_streams: u16) -> Self {
|
||||
qdebug!("Decoder: creating a new qpack decoder.");
|
||||
Self {
|
||||
instruction_reader: EncoderInstructionReader::new(),
|
||||
table: HeaderTable::new(false),
|
||||
total_num_of_inserts: 0,
|
||||
max_entries: (f64::from(max_table_size) / 32.0).floor() as u64,
|
||||
max_entries: max_table_size >> 5,
|
||||
send_buf: QPData::default(),
|
||||
local_stream_id: None,
|
||||
remote_stream_id: None,
|
||||
|
@ -49,27 +50,32 @@ impl QPackDecoder {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> u64 {
|
||||
#[must_use]
|
||||
fn capacity(&self) -> u64 {
|
||||
self.table.capacity()
|
||||
}
|
||||
|
||||
pub fn get_max_table_size(&self) -> u32 {
|
||||
#[must_use]
|
||||
pub fn get_max_table_size(&self) -> u64 {
|
||||
self.max_table_size
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_blocked_streams(&self) -> u16 {
|
||||
self.max_blocked_streams.try_into().unwrap()
|
||||
}
|
||||
|
||||
// returns a list of unblocked streams
|
||||
/// returns a list of unblocked streams
|
||||
/// # Errors
|
||||
/// May return: `ClosedCriticalStream` if stream has been closed or `EncoderStream`
|
||||
/// in case of any other transport error.
|
||||
pub fn receive(&mut self, conn: &mut Connection, stream_id: u64) -> Res<Vec<u64>> {
|
||||
self.read_instructions(conn, stream_id)?;
|
||||
let base = self.table.base();
|
||||
let r = self
|
||||
.blocked_streams
|
||||
.iter()
|
||||
.filter(|(_, req)| *req <= base)
|
||||
.map(|(id, _)| *id)
|
||||
.filter_map(|(id, req)| if *req <= base { Some(*id) } else { None })
|
||||
.collect::<Vec<_>>();
|
||||
self.blocked_streams.retain(|(_, req)| *req > base);
|
||||
Ok(r)
|
||||
|
@ -111,14 +117,14 @@ impl QPackDecoder {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_capacity(&mut self, cap: u64) -> Res<()> {
|
||||
fn set_capacity(&mut self, cap: u64) -> Res<()> {
|
||||
qdebug!([self], "received instruction capacity cap={}", cap);
|
||||
if cap > u64::from(self.max_table_size) {
|
||||
return Err(Error::EncoderStreamError);
|
||||
if cap > self.max_table_size {
|
||||
return Err(Error::EncoderStream);
|
||||
}
|
||||
self.table
|
||||
.set_capacity(cap)
|
||||
.map_err(|_| Error::EncoderStreamError)
|
||||
.map_err(|_| Error::EncoderStream)
|
||||
}
|
||||
|
||||
fn header_ack(&mut self, stream_id: u64, required_inserts: u64) {
|
||||
|
@ -135,6 +141,8 @@ impl QPackDecoder {
|
|||
DecoderInstruction::StreamCancellation { stream_id }.marshal(&mut self.send_buf);
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// May return DecoderStream in case of any transport error.
|
||||
pub fn send(&mut self, conn: &mut Connection) -> Res<()> {
|
||||
// Encode increment instruction if needed.
|
||||
let increment = self.total_num_of_inserts - self.table.get_acked_inserts_cnt();
|
||||
|
@ -148,7 +156,7 @@ impl QPackDecoder {
|
|||
Ok(())
|
||||
} else if let Some(stream_id) = self.local_stream_id {
|
||||
match conn.stream_send(stream_id, &self.send_buf[..]) {
|
||||
Err(_) => Err(Error::DecoderStreamError),
|
||||
Err(_) => Err(Error::DecoderStream),
|
||||
Ok(r) => {
|
||||
qdebug!([self], "{} bytes sent.", r);
|
||||
self.send_buf.read(r as usize);
|
||||
|
@ -160,7 +168,10 @@ impl QPackDecoder {
|
|||
}
|
||||
}
|
||||
|
||||
// this function returns None if the stream is blocked waiting for table insertions.
|
||||
/// This function returns None if the stream is blocked waiting for table insertions.
|
||||
/// 'buf' must contain the complete header block.
|
||||
/// # Errors
|
||||
/// May return `DecompressionFailed` if header block is incorrect or incomplete.
|
||||
pub fn decode_header_block(&mut self, buf: &[u8], stream_id: u64) -> Res<Option<Vec<Header>>> {
|
||||
qdebug!([self], "decode header block.");
|
||||
let mut decoder = HeaderDecoder::new(buf);
|
||||
|
@ -187,6 +198,7 @@ impl QPackDecoder {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_recv_stream(&self, stream_id: u64) -> bool {
|
||||
match self.remote_stream_id {
|
||||
Some(id) => id == stream_id,
|
||||
|
@ -199,17 +211,17 @@ impl QPackDecoder {
|
|||
panic!("Adding multiple local streams");
|
||||
}
|
||||
self.local_stream_id = Some(stream_id);
|
||||
self.send_buf
|
||||
.write_byte(QPACK_UNI_STREAM_TYPE_DECODER as u8);
|
||||
self.send_buf.encode_varint(QPACK_UNI_STREAM_TYPE_DECODER);
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// May return WrongStreamCount if Http3 has received multiple encoder streams.
|
||||
pub fn add_recv_stream(&mut self, stream_id: u64) -> Res<()> {
|
||||
match self.remote_stream_id {
|
||||
Some(_) => Err(Error::WrongStreamCount),
|
||||
None => {
|
||||
self.remote_stream_id = Some(stream_id);
|
||||
Ok(())
|
||||
}
|
||||
if self.remote_stream_id.is_some() {
|
||||
Err(Error::WrongStreamCount)
|
||||
} else {
|
||||
self.remote_stream_id = Some(stream_id);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,10 +234,10 @@ impl ::std::fmt::Display for QPackDecoder {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::{Connection, Error, Header, QPackDecoder, Res};
|
||||
use neqo_transport::StreamType;
|
||||
use std::convert::TryInto;
|
||||
use test_fixture::*;
|
||||
use test_fixture::now;
|
||||
|
||||
struct TestDecoder {
|
||||
decoder: QPackDecoder,
|
||||
|
@ -255,7 +267,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn recv_instruction(decoder: &mut TestDecoder, encoder_instruction: &[u8], res: Res<()>) {
|
||||
fn recv_instruction(decoder: &mut TestDecoder, encoder_instruction: &[u8], res: &Res<()>) {
|
||||
let _ = decoder
|
||||
.peer_conn
|
||||
.stream_send(decoder.recv_stream_id, encoder_instruction);
|
||||
|
@ -265,7 +277,7 @@ mod tests {
|
|||
decoder
|
||||
.decoder
|
||||
.read_instructions(&mut decoder.conn, decoder.recv_stream_id),
|
||||
res
|
||||
*res
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -273,7 +285,7 @@ mod tests {
|
|||
decoder.decoder.send(&mut decoder.conn).unwrap();
|
||||
let out = decoder.conn.process(None, now());
|
||||
decoder.peer_conn.process(out.dgram(), now());
|
||||
let mut buf = [0u8; 100];
|
||||
let mut buf = [0_u8; 100];
|
||||
let (amount, fin) = decoder
|
||||
.peer_conn
|
||||
.stream_recv(decoder.send_stream_id, &mut buf)
|
||||
|
@ -299,7 +311,7 @@ mod tests {
|
|||
fn test_instruction(
|
||||
capacity: u64,
|
||||
instruction: &[u8],
|
||||
res: Res<()>,
|
||||
res: &Res<()>,
|
||||
decoder_instruction: &[u8],
|
||||
check_capacity: u64,
|
||||
) {
|
||||
|
@ -326,7 +338,7 @@ mod tests {
|
|||
test_instruction(
|
||||
0,
|
||||
&[0xc4, 0x04, 0x31, 0x32, 0x33, 0x34],
|
||||
Err(Error::DecoderStreamError),
|
||||
&Err(Error::DecoderStream),
|
||||
&[0x03],
|
||||
0,
|
||||
);
|
||||
|
@ -338,7 +350,7 @@ mod tests {
|
|||
test_instruction(
|
||||
100,
|
||||
&[0xc4, 0x04, 0x31, 0x32, 0x33, 0x34],
|
||||
Ok(()),
|
||||
&Ok(()),
|
||||
&[0x03, 0x01],
|
||||
0,
|
||||
);
|
||||
|
@ -353,7 +365,7 @@ mod tests {
|
|||
0x4e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, 0x74,
|
||||
0x68, 0x04, 0x31, 0x32, 0x33, 0x34,
|
||||
],
|
||||
Ok(()),
|
||||
&Ok(()),
|
||||
&[0x03, 0x01],
|
||||
0,
|
||||
);
|
||||
|
@ -361,7 +373,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_recv_change_capacity() {
|
||||
test_instruction(0, &[0x3f, 0xa9, 0x01], Ok(()), &[0x03], 200);
|
||||
test_instruction(0, &[0x3f, 0xa9, 0x01], &Ok(()), &[0x03], 200);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -369,7 +381,7 @@ mod tests {
|
|||
test_instruction(
|
||||
0,
|
||||
&[0x3f, 0xf1, 0x02],
|
||||
Err(Error::EncoderStreamError),
|
||||
&Err(Error::EncoderStream),
|
||||
&[0x03],
|
||||
0,
|
||||
);
|
||||
|
@ -389,11 +401,11 @@ mod tests {
|
|||
0x4e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, 0x74,
|
||||
0x68, 0x04, 0x31, 0x32, 0x33, 0x34,
|
||||
],
|
||||
Ok(()),
|
||||
&Ok(()),
|
||||
);
|
||||
|
||||
// receive the second instruction, a duplicate instruction.
|
||||
recv_instruction(&mut decoder, &[0x00], Ok(()));
|
||||
recv_instruction(&mut decoder, &[0x00], &Ok(()));
|
||||
|
||||
send_instructions_and_check(&mut decoder, &[0x03, 0x02]);
|
||||
}
|
||||
|
@ -430,11 +442,11 @@ mod tests {
|
|||
|
||||
assert!(decoder.decoder.set_capacity(200).is_ok());
|
||||
|
||||
recv_instruction(&mut decoder, first_encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, first_encoder_inst, &Ok(()));
|
||||
|
||||
send_instructions_and_check(&mut decoder, &[0x03, 0x1]);
|
||||
|
||||
recv_instruction(&mut decoder, second_encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, second_encoder_inst, &Ok(()));
|
||||
|
||||
decode_headers(&mut decoder, header_block, &headers, 0);
|
||||
|
||||
|
@ -466,11 +478,11 @@ mod tests {
|
|||
|
||||
assert!(decoder.decoder.set_capacity(200).is_ok());
|
||||
|
||||
recv_instruction(&mut decoder, first_encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, first_encoder_inst, &Ok(()));
|
||||
|
||||
send_instructions_and_check(&mut decoder, &[0x03, 0x1]);
|
||||
|
||||
recv_instruction(&mut decoder, second_encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, second_encoder_inst, &Ok(()));
|
||||
|
||||
decode_headers(&mut decoder, header_block, &headers, 0);
|
||||
|
||||
|
@ -496,7 +508,7 @@ mod tests {
|
|||
|
||||
assert!(decoder.decoder.set_capacity(200).is_ok());
|
||||
|
||||
recv_instruction(&mut decoder, encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, encoder_inst, &Ok(()));
|
||||
|
||||
decode_headers(&mut decoder, header_block, &headers, 0);
|
||||
|
||||
|
@ -520,7 +532,7 @@ mod tests {
|
|||
|
||||
assert!(decoder.decoder.set_capacity(200).is_ok());
|
||||
|
||||
recv_instruction(&mut decoder, encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, encoder_inst, &Ok(()));
|
||||
|
||||
decode_headers(&mut decoder, header_block, &headers, 0);
|
||||
|
||||
|
@ -592,7 +604,7 @@ mod tests {
|
|||
for (i, t) in test_cases.iter().enumerate() {
|
||||
// receive an instruction
|
||||
if !t.encoder_inst.is_empty() {
|
||||
recv_instruction(&mut decoder, t.encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, t.encoder_inst, &Ok(()));
|
||||
}
|
||||
|
||||
decode_headers(
|
||||
|
@ -670,7 +682,7 @@ mod tests {
|
|||
for (i, t) in test_cases.iter().enumerate() {
|
||||
// receive an instruction.
|
||||
if !t.encoder_inst.is_empty() {
|
||||
recv_instruction(&mut decoder, t.encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, t.encoder_inst, &Ok(()));
|
||||
}
|
||||
|
||||
decode_headers(
|
||||
|
@ -687,6 +699,13 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_subtract_overflow_in_header_ack() {
|
||||
const HEADER_BLOCK_1: &[u8] = &[0x03, 0x81, 0x10, 0x11];
|
||||
const ENCODER_INST: &[u8] = &[
|
||||
0x4a, 0x6d, 0x79, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x61, 0x09, 0x6d, 0x79,
|
||||
0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x61, 0x4a, 0x6d, 0x79, 0x2d, 0x68, 0x65, 0x61,
|
||||
0x64, 0x65, 0x72, 0x62, 0x09, 0x6d, 0x79, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x62,
|
||||
];
|
||||
const HEADER_BLOCK_2: &[u8] = &[0x02, 0x80, 0x10];
|
||||
// Test for issue https://github.com/mozilla/neqo/issues/475
|
||||
// Send two instructions to insert values into the dynamic table and send a header
|
||||
// that references them both. This will increase number of acked inserts in the table
|
||||
|
@ -696,24 +715,17 @@ mod tests {
|
|||
(String::from("my-headera"), String::from("my-valuea")),
|
||||
(String::from("my-headerb"), String::from("my-valueb")),
|
||||
];
|
||||
let header_block = &[0x03, 0x81, 0x10, 0x11];
|
||||
let encoder_inst = &[
|
||||
0x4a, 0x6d, 0x79, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x61, 0x09, 0x6d, 0x79,
|
||||
0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x61, 0x4a, 0x6d, 0x79, 0x2d, 0x68, 0x65, 0x61,
|
||||
0x64, 0x65, 0x72, 0x62, 0x09, 0x6d, 0x79, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x62,
|
||||
];
|
||||
|
||||
let mut decoder = connect();
|
||||
|
||||
assert!(decoder.decoder.set_capacity(200).is_ok());
|
||||
|
||||
recv_instruction(&mut decoder, encoder_inst, Ok(()));
|
||||
recv_instruction(&mut decoder, ENCODER_INST, &Ok(()));
|
||||
|
||||
decode_headers(&mut decoder, header_block, &headers, 0);
|
||||
decode_headers(&mut decoder, HEADER_BLOCK_1, &headers, 0);
|
||||
|
||||
let headers = vec![(String::from("my-headera"), String::from("my-valuea"))];
|
||||
let header_block = &[0x02, 0x80, 0x10];
|
||||
|
||||
decode_headers(&mut decoder, header_block, &headers, 0);
|
||||
decode_headers(&mut decoder, HEADER_BLOCK_2, &headers, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ impl DecoderInstructionReader {
|
|||
}
|
||||
Err(Error::NoMoreData) => break Ok(None),
|
||||
Err(Error::ClosedCriticalStream) => break Err(Error::ClosedCriticalStream),
|
||||
_ => break Err(Error::DecoderStreamError),
|
||||
_ => break Err(Error::DecoderStream),
|
||||
},
|
||||
DecoderInstructionReaderState::ReadInt { reader } => match reader.read(recv) {
|
||||
Ok(Some(val)) => {
|
||||
|
@ -120,7 +120,7 @@ impl DecoderInstructionReader {
|
|||
}
|
||||
Ok(None) => break Ok(None),
|
||||
Err(Error::ClosedCriticalStream) => break Err(Error::ClosedCriticalStream),
|
||||
Err(_) => break Err(Error::DecoderStreamError),
|
||||
Err(_) => break Err(Error::DecoderStream),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ impl DecoderInstructionReader {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
use super::{DecoderInstruction, DecoderInstructionReader, Error, QPData};
|
||||
use crate::reader::test_receiver::TestReceiver;
|
||||
|
||||
fn test_encoding_decoding(instruction: DecoderInstruction) {
|
||||
|
@ -203,7 +203,7 @@ mod test {
|
|||
let mut decoder = DecoderInstructionReader::new();
|
||||
assert_eq!(
|
||||
decoder.read_instructions(&mut test_receiver),
|
||||
Err(Error::DecoderStreamError)
|
||||
Err(Error::DecoderStream)
|
||||
);
|
||||
|
||||
let mut test_receiver: TestReceiver = TestReceiver::default();
|
||||
|
@ -214,7 +214,7 @@ mod test {
|
|||
let mut decoder = DecoderInstructionReader::new();
|
||||
assert_eq!(
|
||||
decoder.read_instructions(&mut test_receiver),
|
||||
Err(Error::DecoderStreamError)
|
||||
Err(Error::DecoderStream)
|
||||
);
|
||||
|
||||
let mut test_receiver: TestReceiver = TestReceiver::default();
|
||||
|
@ -225,7 +225,7 @@ mod test {
|
|||
let mut decoder = DecoderInstructionReader::new();
|
||||
assert_eq!(
|
||||
decoder.read_instructions(&mut test_receiver),
|
||||
Err(Error::DecoderStreamError)
|
||||
Err(Error::DecoderStream)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use crate::Header;
|
|||
use crate::{Error, Res};
|
||||
use neqo_common::{qdebug, qtrace};
|
||||
use neqo_transport::Connection;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::convert::TryInto;
|
||||
|
||||
|
@ -38,6 +39,7 @@ pub struct QPackEncoder {
|
|||
}
|
||||
|
||||
impl QPackEncoder {
|
||||
#[must_use]
|
||||
pub fn new(use_huffman: bool) -> Self {
|
||||
Self {
|
||||
table: HeaderTable::new(true),
|
||||
|
@ -53,24 +55,37 @@ impl QPackEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
/// This function is use for setting encoders table max capacity. The value is received as
|
||||
/// a `SETTINGS_QPACK_MAX_TABLE_CAPACITY` setting parameter.
|
||||
/// # Errors
|
||||
/// `EncoderStream` if value is too big.
|
||||
pub fn set_max_capacity(&mut self, cap: u64) -> Res<()> {
|
||||
if cap > (1 << 30) - 1 {
|
||||
// TODO dragana check what is the correct error.
|
||||
return Err(Error::EncoderStreamError);
|
||||
return Err(Error::EncoderStream);
|
||||
}
|
||||
qdebug!([self], "Set max capacity to {}.", cap);
|
||||
self.max_entries = (cap as f64 / 32.0).floor() as u64;
|
||||
qdebug!(
|
||||
[self],
|
||||
"Set max capacity to {} {}.",
|
||||
cap,
|
||||
self.table.capacity()
|
||||
);
|
||||
self.max_entries = (cap.to_f64().unwrap() / 32.0).floor().to_u64().unwrap();
|
||||
// we also set our table to the max allowed. TODO we may not want to use max allowed.
|
||||
self.change_capacity(cap)
|
||||
}
|
||||
|
||||
/// This function is use for setting encoders max blocked streams. The value is received as
|
||||
/// a `SETTINGS_QPACK_BLOCKED_STREAMS` setting parameter.
|
||||
/// # Errors
|
||||
/// `EncoderStream` if value is too big.
|
||||
pub fn set_max_blocked_streams(&mut self, blocked_streams: u64) -> Res<()> {
|
||||
self.max_blocked_streams = blocked_streams
|
||||
.try_into()
|
||||
.or(Err(Error::EncoderStreamError))?;
|
||||
self.max_blocked_streams = blocked_streams.try_into().or(Err(Error::EncoderStream))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reads decoder instructions.
|
||||
/// # Errors
|
||||
/// TODO dragana: I think some errors are not correct, e.g. This can return Error:Internal.
|
||||
pub fn recv_if_encoder_stream(&mut self, conn: &mut Connection, stream_id: u64) -> Res<bool> {
|
||||
match self.remote_stream_id {
|
||||
Some(id) => {
|
||||
|
@ -99,13 +114,9 @@ impl QPackEncoder {
|
|||
fn recalculate_blocked_streams(&mut self) {
|
||||
let acked_inserts_cnt = self.table.get_acked_inserts_cnt();
|
||||
self.blocked_stream_cnt = 0;
|
||||
for (_, hb_list) in self.unacked_header_blocks.iter_mut() {
|
||||
for hb_list in self.unacked_header_blocks.values_mut() {
|
||||
debug_assert!(!hb_list.is_empty());
|
||||
if hb_list
|
||||
.iter()
|
||||
.flat_map(|hb| hb.iter())
|
||||
.any(|e| *e >= acked_inserts_cnt)
|
||||
{
|
||||
if hb_list.iter().flatten().any(|e| *e >= acked_inserts_cnt) {
|
||||
self.blocked_stream_cnt += 1;
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +184,8 @@ impl QPackEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn insert_with_name_ref(
|
||||
#[cfg(test)]
|
||||
fn insert_with_name_ref(
|
||||
&mut self,
|
||||
name_static_table: bool,
|
||||
index: u64,
|
||||
|
@ -210,7 +222,7 @@ impl QPackEncoder {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn insert_with_name_literal(&mut self, name: &[u8], value: &[u8]) -> Res<u64> {
|
||||
fn insert_with_name_literal(&mut self, name: &[u8], value: &[u8]) -> Res<u64> {
|
||||
qdebug!([self], "insert name {:x?}, value={:x?}.", name, value);
|
||||
// try to insert a new entry
|
||||
let index = self.table.insert(name, value)?;
|
||||
|
@ -225,26 +237,30 @@ impl QPackEncoder {
|
|||
Ok(index)
|
||||
}
|
||||
|
||||
pub fn duplicate(&mut self, index: u64) -> Res<()> {
|
||||
#[cfg(test)]
|
||||
fn duplicate(&mut self, index: u64) -> Res<()> {
|
||||
qdebug!([self], "duplicate entry {}.", index);
|
||||
self.table.duplicate(index)?;
|
||||
EncoderInstruction::Duplicate { index }.marshal(&mut self.send_buf, self.use_huffman);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn change_capacity(&mut self, value: u64) -> Res<()> {
|
||||
fn change_capacity(&mut self, value: u64) -> Res<()> {
|
||||
qdebug!([self], "change capacity: {}", value);
|
||||
self.table.set_capacity(value)?;
|
||||
EncoderInstruction::Capacity { value }.marshal(&mut self.send_buf, self.use_huffman);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sends any qpack encoder instructions.
|
||||
/// # Errors
|
||||
/// returns `EncoderStream` in case of an error.
|
||||
pub fn send(&mut self, conn: &mut Connection) -> Res<()> {
|
||||
if self.send_buf.is_empty() {
|
||||
Ok(())
|
||||
} else if let Some(stream_id) = self.local_stream_id {
|
||||
match conn.stream_send(stream_id, &self.send_buf[..]) {
|
||||
Err(_) => Err(Error::EncoderStreamError),
|
||||
Err(_) => Err(Error::EncoderStream),
|
||||
Ok(r) => {
|
||||
qdebug!([self], "{} bytes sent.", r);
|
||||
self.send_buf.read(r as usize);
|
||||
|
@ -259,7 +275,7 @@ impl QPackEncoder {
|
|||
fn is_stream_blocker(&self, stream_id: u64) -> bool {
|
||||
if let Some(hb_list) = self.unacked_header_blocks.get(&stream_id) {
|
||||
debug_assert!(!hb_list.is_empty());
|
||||
match hb_list.iter().flat_map(|hb| hb.iter()).max() {
|
||||
match hb_list.iter().flatten().max() {
|
||||
Some(max_ref) => *max_ref >= self.table.get_acked_inserts_cnt(),
|
||||
None => false,
|
||||
}
|
||||
|
@ -307,18 +323,15 @@ impl QPackEncoder {
|
|||
if !static_table {
|
||||
ref_entries.insert(index);
|
||||
}
|
||||
} else if !can_block {
|
||||
encoded_h.encode_literal_with_name_literal(&name, &value);
|
||||
} else {
|
||||
match self.insert_with_name_literal(&name, &value) {
|
||||
Ok(index) => {
|
||||
encoded_h.encode_indexed_dynamic(index);
|
||||
ref_entries.insert(index);
|
||||
}
|
||||
Err(_) => {
|
||||
encoded_h.encode_literal_with_name_literal(&name, &value);
|
||||
}
|
||||
} else if can_block {
|
||||
if let Ok(index) = self.insert_with_name_literal(&name, &value) {
|
||||
encoded_h.encode_indexed_dynamic(index);
|
||||
ref_entries.insert(index);
|
||||
} else {
|
||||
encoded_h.encode_literal_with_name_literal(&name, &value);
|
||||
}
|
||||
} else {
|
||||
encoded_h.encode_literal_with_name_literal(&name, &value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,27 +360,29 @@ impl QPackEncoder {
|
|||
encoded_h
|
||||
}
|
||||
|
||||
/// Encoder stream has been created. Add the stream id.
|
||||
pub fn add_send_stream(&mut self, stream_id: u64) {
|
||||
if self.local_stream_id.is_some() {
|
||||
panic!("Adding multiple local streams");
|
||||
}
|
||||
self.local_stream_id = Some(stream_id);
|
||||
self.send_buf
|
||||
.write_byte(QPACK_UNI_STREAM_TYPE_ENCODER as u8);
|
||||
self.send_buf.encode_varint(QPACK_UNI_STREAM_TYPE_ENCODER);
|
||||
}
|
||||
|
||||
/// We have received a remote decoder stream. Remember its stream id.
|
||||
/// # Errors
|
||||
/// If we receive multiple decoder streams this function will return `WrongStreamCount`.
|
||||
pub fn add_recv_stream(&mut self, stream_id: u64) -> Res<()> {
|
||||
match self.remote_stream_id {
|
||||
Some(_) => Err(Error::WrongStreamCount),
|
||||
None => {
|
||||
self.remote_stream_id = Some(stream_id);
|
||||
Ok(())
|
||||
}
|
||||
if self.remote_stream_id.is_some() {
|
||||
Err(Error::WrongStreamCount)
|
||||
} else {
|
||||
self.remote_stream_id = Some(stream_id);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn blocked_stream_cnt(&self) -> u16 {
|
||||
fn blocked_stream_cnt(&self) -> u16 {
|
||||
self.blocked_stream_cnt
|
||||
}
|
||||
}
|
||||
|
@ -380,9 +395,9 @@ impl ::std::fmt::Display for QPackEncoder {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::{Connection, Error, Header, QPackEncoder};
|
||||
use neqo_transport::StreamType;
|
||||
use test_fixture::*;
|
||||
use test_fixture::now;
|
||||
|
||||
struct TestEncoder {
|
||||
encoder: QPackEncoder,
|
||||
|
@ -416,7 +431,7 @@ mod tests {
|
|||
encoder.encoder.send(&mut encoder.conn).unwrap();
|
||||
let out = encoder.conn.process(None, now());
|
||||
encoder.peer_conn.process(out.dgram(), now());
|
||||
let mut buf = [0u8; 100];
|
||||
let mut buf = [0_u8; 100];
|
||||
let (amount, fin) = encoder
|
||||
.peer_conn
|
||||
.stream_recv(encoder.send_stream_id, &mut buf)
|
||||
|
@ -474,7 +489,7 @@ mod tests {
|
|||
.encoder
|
||||
.insert_with_name_ref(true, 4, VALUE_1)
|
||||
.unwrap_err();
|
||||
assert_eq!(Error::EncoderStreamError, e);
|
||||
assert_eq!(Error::EncoderStream, e);
|
||||
send_instructions(&mut encoder, &[0x02]);
|
||||
}
|
||||
|
||||
|
@ -502,7 +517,7 @@ mod tests {
|
|||
let res = encoder
|
||||
.encoder
|
||||
.insert_with_name_literal(HEADER_CONTENT_LENGTH, VALUE_1);
|
||||
assert_eq!(Error::EncoderStreamError, res.unwrap_err());
|
||||
assert_eq!(Error::EncoderStream, res.unwrap_err());
|
||||
send_instructions(&mut encoder, &[0x02]);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ impl EncoderInstructionReader {
|
|||
}
|
||||
Err(Error::NoMoreData) => Ok(false),
|
||||
Err(Error::ClosedCriticalStream) => Err(Error::ClosedCriticalStream),
|
||||
Err(_) => Err(Error::EncoderStreamError),
|
||||
Err(_) => Err(Error::EncoderStream),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ impl EncoderInstructionReader {
|
|||
}
|
||||
Ok(None) => break Ok(None),
|
||||
Err(Error::ClosedCriticalStream) => break Err(Error::ClosedCriticalStream),
|
||||
Err(_) => break Err(Error::EncoderStreamError),
|
||||
Err(_) => break Err(Error::EncoderStream),
|
||||
},
|
||||
EncoderInstructionReaderState::ReadFirstLiteral { reader } => {
|
||||
match reader.read(recv) {
|
||||
|
@ -201,7 +201,7 @@ impl EncoderInstructionReader {
|
|||
}
|
||||
Ok(None) => break Ok(None),
|
||||
Err(Error::ClosedCriticalStream) => break Err(Error::ClosedCriticalStream),
|
||||
Err(_) => break Err(Error::EncoderStreamError),
|
||||
Err(_) => break Err(Error::EncoderStream),
|
||||
}
|
||||
}
|
||||
EncoderInstructionReaderState::ReadSecondLiteral { reader } => {
|
||||
|
@ -218,7 +218,7 @@ impl EncoderInstructionReader {
|
|||
}
|
||||
Ok(None) => break Ok(None),
|
||||
Err(Error::ClosedCriticalStream) => break Err(Error::ClosedCriticalStream),
|
||||
Err(_) => break Err(Error::EncoderStreamError),
|
||||
Err(_) => break Err(Error::EncoderStream),
|
||||
}
|
||||
}
|
||||
EncoderInstructionReaderState::Done => {}
|
||||
|
@ -237,10 +237,10 @@ impl EncoderInstructionReader {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
use super::{EncoderInstruction, EncoderInstructionReader, Error, QPData};
|
||||
use crate::reader::test_receiver::TestReceiver;
|
||||
|
||||
fn test_encoding_decoding(instruction: EncoderInstruction, use_huffman: bool) {
|
||||
fn test_encoding_decoding(instruction: &EncoderInstruction, use_huffman: bool) {
|
||||
let mut buf = QPData::default();
|
||||
instruction.marshal(&mut buf, use_huffman);
|
||||
let mut test_receiver: TestReceiver = TestReceiver::default();
|
||||
|
@ -251,38 +251,38 @@ mod test {
|
|||
.read_instructions(&mut test_receiver)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
instruction
|
||||
*instruction
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encoding_decoding_instructions() {
|
||||
test_encoding_decoding(EncoderInstruction::Capacity { value: 1 }, false);
|
||||
test_encoding_decoding(EncoderInstruction::Capacity { value: 10_000 }, false);
|
||||
test_encoding_decoding(&EncoderInstruction::Capacity { value: 1 }, false);
|
||||
test_encoding_decoding(&EncoderInstruction::Capacity { value: 10_000 }, false);
|
||||
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
true,
|
||||
);
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
|
@ -290,28 +290,28 @@ mod test {
|
|||
);
|
||||
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
true,
|
||||
);
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
|
@ -319,25 +319,25 @@ mod test {
|
|||
);
|
||||
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameLiteral {
|
||||
&EncoderInstruction::InsertWithNameLiteral {
|
||||
name: vec![0x62, 0x64, 0x65],
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding(
|
||||
EncoderInstruction::InsertWithNameLiteral {
|
||||
&EncoderInstruction::InsertWithNameLiteral {
|
||||
name: vec![0x62, 0x64, 0x65],
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
test_encoding_decoding(EncoderInstruction::Duplicate { index: 1 }, false);
|
||||
test_encoding_decoding(EncoderInstruction::Duplicate { index: 10_000 }, false);
|
||||
test_encoding_decoding(&EncoderInstruction::Duplicate { index: 1 }, false);
|
||||
test_encoding_decoding(&EncoderInstruction::Duplicate { index: 10_000 }, false);
|
||||
}
|
||||
|
||||
fn test_encoding_decoding_slow_reader(instruction: EncoderInstruction, use_huffman: bool) {
|
||||
fn test_encoding_decoding_slow_reader(instruction: &EncoderInstruction, use_huffman: bool) {
|
||||
let mut buf = QPData::default();
|
||||
instruction.marshal(&mut buf, use_huffman);
|
||||
let mut test_receiver: TestReceiver = TestReceiver::default();
|
||||
|
@ -355,38 +355,38 @@ mod test {
|
|||
.read_instructions(&mut test_receiver)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
instruction
|
||||
*instruction
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encoding_decoding_instructions_slow_reader() {
|
||||
test_encoding_decoding_slow_reader(EncoderInstruction::Capacity { value: 1 }, false);
|
||||
test_encoding_decoding_slow_reader(EncoderInstruction::Capacity { value: 10_000 }, false);
|
||||
test_encoding_decoding_slow_reader(&EncoderInstruction::Capacity { value: 1 }, false);
|
||||
test_encoding_decoding_slow_reader(&EncoderInstruction::Capacity { value: 10_000 }, false);
|
||||
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
true,
|
||||
);
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefStatic {
|
||||
&EncoderInstruction::InsertWithNameRefStatic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
|
@ -394,28 +394,28 @@ mod test {
|
|||
);
|
||||
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 1,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
true,
|
||||
);
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameRefDynamic {
|
||||
&EncoderInstruction::InsertWithNameRefDynamic {
|
||||
index: 10_000,
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
|
@ -423,22 +423,22 @@ mod test {
|
|||
);
|
||||
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameLiteral {
|
||||
&EncoderInstruction::InsertWithNameLiteral {
|
||||
name: vec![0x62, 0x64, 0x65],
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
false,
|
||||
);
|
||||
test_encoding_decoding_slow_reader(
|
||||
EncoderInstruction::InsertWithNameLiteral {
|
||||
&EncoderInstruction::InsertWithNameLiteral {
|
||||
name: vec![0x62, 0x64, 0x65],
|
||||
value: vec![0x62, 0x64, 0x65],
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
test_encoding_decoding_slow_reader(EncoderInstruction::Duplicate { index: 1 }, false);
|
||||
test_encoding_decoding_slow_reader(EncoderInstruction::Duplicate { index: 10_000 }, false);
|
||||
test_encoding_decoding_slow_reader(&EncoderInstruction::Duplicate { index: 1 }, false);
|
||||
test_encoding_decoding_slow_reader(&EncoderInstruction::Duplicate { index: 10_000 }, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -451,7 +451,7 @@ mod test {
|
|||
let mut decoder = EncoderInstructionReader::new();
|
||||
assert_eq!(
|
||||
decoder.read_instructions(&mut test_receiver),
|
||||
Err(Error::EncoderStreamError)
|
||||
Err(Error::EncoderStream)
|
||||
);
|
||||
|
||||
let mut test_receiver: TestReceiver = TestReceiver::default();
|
||||
|
@ -462,7 +462,7 @@ mod test {
|
|||
let mut decoder = EncoderInstructionReader::new();
|
||||
assert_eq!(
|
||||
decoder.read_instructions(&mut test_receiver),
|
||||
Err(Error::EncoderStreamError)
|
||||
Err(Error::EncoderStream)
|
||||
);
|
||||
|
||||
let mut test_receiver: TestReceiver = TestReceiver::default();
|
||||
|
@ -471,7 +471,7 @@ mod test {
|
|||
let mut decoder = EncoderInstructionReader::new();
|
||||
assert_eq!(
|
||||
decoder.read_instructions(&mut test_receiver),
|
||||
Err(Error::EncoderStreamError)
|
||||
Err(Error::EncoderStream)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::table::HeaderTable;
|
|||
use crate::Header;
|
||||
use crate::{Error, Res};
|
||||
use neqo_common::qtrace;
|
||||
use std::ops::Deref;
|
||||
use std::ops::{Deref, Div};
|
||||
|
||||
#[derive(Default, Debug, PartialEq)]
|
||||
pub struct HeaderEncoder {
|
||||
|
@ -245,13 +245,13 @@ impl<'a> HeaderDecoder<'a> {
|
|||
|
||||
let b = self.buf.peek()?;
|
||||
if HEADER_FIELD_INDEX_STATIC.cmp_prefix(b) {
|
||||
h.push(self.read_indexed_static(table)?);
|
||||
h.push(self.read_indexed_static()?);
|
||||
} else if HEADER_FIELD_INDEX_DYNAMIC.cmp_prefix(b) {
|
||||
h.push(self.read_indexed_dynamic(table)?);
|
||||
} else if HEADER_FIELD_INDEX_DYNAMIC_POST.cmp_prefix(b) {
|
||||
h.push(self.read_indexed_dynamic_post(table)?);
|
||||
} else if HEADER_FIELD_LITERAL_NAME_REF_STATIC.cmp_prefix(b) {
|
||||
h.push(self.read_literal_with_name_ref_static(table)?);
|
||||
h.push(self.read_literal_with_name_ref_static()?);
|
||||
} else if HEADER_FIELD_LITERAL_NAME_REF_DYNAMIC.cmp_prefix(b) {
|
||||
h.push(self.read_literal_with_name_ref_dynamic(table)?);
|
||||
} else if HEADER_FIELD_LITERAL_NAME_LITERAL.cmp_prefix(b) {
|
||||
|
@ -271,7 +271,7 @@ impl<'a> HeaderDecoder<'a> {
|
|||
fn read_base(&mut self, max_entries: u64, total_num_of_inserts: u64) -> Res<()> {
|
||||
let insert_cnt = self.buf.read_prefixed_int(0)?;
|
||||
self.req_insert_cnt =
|
||||
self.calc_req_insert_cnt(insert_cnt, max_entries, total_num_of_inserts)?;
|
||||
HeaderDecoder::calc_req_insert_cnt(insert_cnt, max_entries, total_num_of_inserts)?;
|
||||
|
||||
let s = self.buf.peek()? & 0x80 != 0;
|
||||
let base_delta = self.buf.read_prefixed_int(1)?;
|
||||
|
@ -292,12 +292,7 @@ impl<'a> HeaderDecoder<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn calc_req_insert_cnt(
|
||||
&self,
|
||||
encoded: u64,
|
||||
max_entries: u64,
|
||||
total_num_of_inserts: u64,
|
||||
) -> Res<u64> {
|
||||
fn calc_req_insert_cnt(encoded: u64, max_entries: u64, total_num_of_inserts: u64) -> Res<u64> {
|
||||
if encoded == 0 {
|
||||
Ok(0)
|
||||
} else if max_entries == 0 {
|
||||
|
@ -308,7 +303,7 @@ impl<'a> HeaderDecoder<'a> {
|
|||
return Err(Error::DecompressionFailed);
|
||||
}
|
||||
let max_value = total_num_of_inserts + max_entries;
|
||||
let max_wrapped = (max_value as f64 / full_range as f64).floor() as u64 * full_range;
|
||||
let max_wrapped = max_value.div(full_range) * full_range;
|
||||
let mut req_insert_cnt = max_wrapped + encoded - 1;
|
||||
if req_insert_cnt > max_value {
|
||||
if req_insert_cnt < full_range {
|
||||
|
@ -321,13 +316,13 @@ impl<'a> HeaderDecoder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_indexed_static(&mut self, table: &HeaderTable) -> Res<Header> {
|
||||
fn read_indexed_static(&mut self) -> Res<Header> {
|
||||
let index = self
|
||||
.buf
|
||||
.read_prefixed_int(HEADER_FIELD_INDEX_STATIC.len())?;
|
||||
qtrace!([self], "decoder static indexed {}.", index);
|
||||
|
||||
match table.get_static(index) {
|
||||
match HeaderTable::get_static(index) {
|
||||
Ok(entry) => Ok((to_string(entry.name())?, to_string(entry.value())?)),
|
||||
Err(_) => Err(Error::DecompressionFailed),
|
||||
}
|
||||
|
@ -355,7 +350,7 @@ impl<'a> HeaderDecoder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_literal_with_name_ref_static(&mut self, table: &HeaderTable) -> Res<Header> {
|
||||
fn read_literal_with_name_ref_static(&mut self) -> Res<Header> {
|
||||
qtrace!(
|
||||
[self],
|
||||
"read literal with name reference to the static table."
|
||||
|
@ -365,7 +360,7 @@ impl<'a> HeaderDecoder<'a> {
|
|||
.buf
|
||||
.read_prefixed_int(HEADER_FIELD_LITERAL_NAME_REF_STATIC.len())?;
|
||||
|
||||
match table.get_static(index) {
|
||||
match HeaderTable::get_static(index) {
|
||||
Ok(entry) => Ok((
|
||||
to_string(entry.name())?,
|
||||
self.buf.read_literal_from_buffer(0)?,
|
||||
|
@ -423,7 +418,7 @@ impl<'a> HeaderDecoder<'a> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use super::{Deref, HeaderDecoder, HeaderDecoderResult, HeaderEncoder, HeaderTable};
|
||||
|
||||
const INDEX_STATIC_TEST: [(u64, &[u8], &str, &str); 4] = [
|
||||
(0, &[0x0, 0x0, 0xc0], ":authority", ""),
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(clippy::pedantic)]
|
||||
|
||||
use crate::huffman_decode_helper::{HuffmanDecodeTable, HUFFMAN_DECODE_ROOT};
|
||||
use crate::huffman_table::HUFFMAN_TABLE;
|
||||
use crate::{Error, Res};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Huffman {
|
||||
|
@ -106,14 +109,14 @@ impl Huffman {
|
|||
return Err(Error::DecompressionFailed);
|
||||
}
|
||||
|
||||
if entry.prefix_len > u16::from(self.decoding_bits_left) {
|
||||
if entry.prefix_len > self.decoding_bits_left {
|
||||
assert!(!self.has_more_data(len, *read));
|
||||
// This is the last bit and it is padding.
|
||||
return Ok(None);
|
||||
}
|
||||
let c = entry.val as u8;
|
||||
let c = u8::try_from(entry.val).unwrap();
|
||||
|
||||
self.decoding_bits_left -= entry.prefix_len as u8;
|
||||
self.decoding_bits_left -= entry.prefix_len;
|
||||
if self.decoding_bits_left > 0 {
|
||||
self.decoding_byte <<= entry.prefix_len;
|
||||
}
|
||||
|
@ -121,6 +124,7 @@ impl Huffman {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn encode_huffman(input: &[u8]) -> Vec<u8> {
|
||||
let mut output: Vec<u8> = Vec::new();
|
||||
let mut left: u8 = 8;
|
||||
|
@ -130,7 +134,8 @@ pub fn encode_huffman(input: &[u8]) -> Vec<u8> {
|
|||
|
||||
// Fill the previous byte
|
||||
if e.len < left {
|
||||
saved |= (e.val as u8) << (left - e.len);
|
||||
let b = u8::try_from(e.val & 0xFF).unwrap();
|
||||
saved |= b << (left - e.len);
|
||||
left -= e.len;
|
||||
e.len = 0;
|
||||
} else {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
pub struct HuffmanDecodeEntry {
|
||||
pub val: u16,
|
||||
pub prefix_len: u16,
|
||||
pub prefix_len: u8,
|
||||
}
|
||||
|
||||
pub struct HuffmanDecodeTable<'a> {
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
||||
#![warn(clippy::use_self)]
|
||||
#![warn(clippy::pedantic)]
|
||||
// This is because of Encoder and Decoder structs. TODO: think about a better namings for crate and structs.
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
// We need this because of TransportError.
|
||||
#![allow(clippy::pub_enum_variant_names)]
|
||||
|
||||
pub mod decoder;
|
||||
mod decoder_instructions;
|
||||
|
@ -39,25 +43,32 @@ impl ::std::fmt::Display for QPackSide {
|
|||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
DecompressionFailed,
|
||||
EncoderStreamError,
|
||||
DecoderStreamError,
|
||||
EncoderStream,
|
||||
DecoderStream,
|
||||
ClosedCriticalStream,
|
||||
|
||||
// These are internal errors, they will be transfromed into one of the above.
|
||||
HeaderLookupError,
|
||||
HeaderLookup,
|
||||
NoMoreData,
|
||||
IntegerOverflow,
|
||||
WrongStreamCount,
|
||||
InternalError,
|
||||
DecodingError, // this will be translated into Encoder/DecoderStreamError or DecompressionFailed depending on the caller
|
||||
Internal,
|
||||
Decoding, // this will be translated into Encoder/DecoderStreamError or DecompressionFailed depending on the caller
|
||||
|
||||
TransportError(neqo_transport::Error),
|
||||
}
|
||||
|
||||
impl Error {
|
||||
#[must_use]
|
||||
pub fn code(&self) -> neqo_transport::AppError {
|
||||
// TODO(mt): use real codes once QPACK defines some.
|
||||
3
|
||||
match self {
|
||||
Self::DecompressionFailed => 0x200,
|
||||
Self::EncoderStream => 0x201,
|
||||
Self::DecoderStream => 0x202,
|
||||
Self::ClosedCriticalStream => 0x104,
|
||||
// These are all internal errors.
|
||||
_ => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Prefix {
|
||||
prefix: u8,
|
||||
len: u8,
|
||||
|
@ -29,15 +30,15 @@ impl Prefix {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> u8 {
|
||||
pub fn len(self) -> u8 {
|
||||
self.len
|
||||
}
|
||||
|
||||
pub fn prefix(&self) -> u8 {
|
||||
pub fn prefix(self) -> u8 {
|
||||
self.prefix
|
||||
}
|
||||
|
||||
pub fn cmp_prefix(&self, b: u8) -> bool {
|
||||
pub fn cmp_prefix(self, b: u8) -> bool {
|
||||
(b & self.mask) == self.prefix
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
use crate::huffman::encode_huffman;
|
||||
use crate::prefix::Prefix;
|
||||
use std::convert::TryInto;
|
||||
use neqo_common::Encoder;
|
||||
use std::convert::TryFrom;
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(Default, Debug, PartialEq)]
|
||||
|
@ -19,10 +20,16 @@ impl QPData {
|
|||
self.buf.len()
|
||||
}
|
||||
|
||||
pub fn write_byte(&mut self, b: u8) {
|
||||
fn write_byte(&mut self, b: u8) {
|
||||
self.buf.push(b);
|
||||
}
|
||||
|
||||
pub fn encode_varint(&mut self, i: u64) {
|
||||
let mut enc = Encoder::default();
|
||||
enc.encode_varint(i);
|
||||
self.buf.append(&mut enc.into());
|
||||
}
|
||||
|
||||
fn encode_prefixed_encoded_int_internal(
|
||||
&mut self,
|
||||
offset: Option<usize>,
|
||||
|
@ -36,10 +43,11 @@ impl QPData {
|
|||
};
|
||||
|
||||
if val < u64::from(first_byte_max) {
|
||||
let v = u8::try_from(val).unwrap();
|
||||
if let Some(offset_val) = offset {
|
||||
self.buf[offset_val] = (prefix.prefix() & !first_byte_max) | (val as u8);
|
||||
self.buf[offset_val] = (prefix.prefix() & !first_byte_max) | v;
|
||||
} else {
|
||||
self.write_byte((prefix.prefix() & !first_byte_max) | (val as u8));
|
||||
self.write_byte((prefix.prefix() & !first_byte_max) | v);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -54,7 +62,7 @@ impl QPData {
|
|||
let mut written = 1;
|
||||
let mut done = false;
|
||||
while !done {
|
||||
let mut b = (val as u8) & 0x7f;
|
||||
let mut b = u8::try_from(val & 0x7f).unwrap();
|
||||
val >>= 7;
|
||||
if val > 0 {
|
||||
b |= 0x80;
|
||||
|
@ -96,10 +104,10 @@ impl QPData {
|
|||
|
||||
if use_huffman {
|
||||
let encoded = encode_huffman(value);
|
||||
self.encode_prefixed_encoded_int(real_prefix, encoded.len().try_into().unwrap());
|
||||
self.encode_prefixed_encoded_int(real_prefix, u64::try_from(encoded.len()).unwrap());
|
||||
self.write_bytes(&encoded);
|
||||
} else {
|
||||
self.encode_prefixed_encoded_int(real_prefix, value.len().try_into().unwrap());
|
||||
self.encode_prefixed_encoded_int(real_prefix, u64::try_from(value.len()).unwrap());
|
||||
self.write_bytes(&value);
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +134,7 @@ impl Deref for QPData {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::{Prefix, QPData};
|
||||
|
||||
#[test]
|
||||
fn test_encode_prefixed_encoded_int_1() {
|
||||
|
|
|
@ -14,10 +14,16 @@ use std::mem;
|
|||
use std::str;
|
||||
|
||||
pub trait ReadByte {
|
||||
/// # Errors
|
||||
/// Return error occurred while reading a byte.
|
||||
/// The exact error depends on trait implementation.
|
||||
fn read_byte(&mut self) -> Res<u8>;
|
||||
}
|
||||
|
||||
pub trait Reader {
|
||||
/// # Errors
|
||||
/// Return error occurred while reading date into a buffer.
|
||||
/// The exact error depends on trait implementation.
|
||||
fn read(&mut self, buf: &mut [u8]) -> Res<usize>;
|
||||
}
|
||||
|
||||
|
@ -52,9 +58,9 @@ impl<'a> ReceiverConnWrapper<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// This is only used by header decoder therefore all errors are DecompressionFailed.
|
||||
/// This is only used by header decoder therefore all errors are `DecompressionFailed`.
|
||||
/// A header block is read entirely before decoding it, therefore if there is not enough
|
||||
/// data in the buffer an error DecompressionFailed will be return.
|
||||
/// data in the buffer an error `DecompressionFailed` will be return.
|
||||
pub(crate) struct ReceiverBufferWrapper<'a> {
|
||||
buf: &'a [u8],
|
||||
offset: usize,
|
||||
|
@ -89,11 +95,11 @@ impl<'a> ReceiverBufferWrapper<'a> {
|
|||
self.offset == self.buf.len()
|
||||
}
|
||||
|
||||
/// The function decodes varint with a prefixed, i.e. ignores prefix_len bits of the first
|
||||
/// The function decodes varint with a prefixed, i.e. ignores `prefix_len` bits of the first
|
||||
/// byte.
|
||||
/// ReceiverBufferWrapper is only used for decoding header blocks. The header blocks are read
|
||||
/// `ReceiverBufferWrapper` is only used for decoding header blocks. The header blocks are read
|
||||
/// entirely before a decoding starts, therefore any incomplete varint because of reaching the
|
||||
/// end of a buffer will be treated as the DecompressionFailed error.
|
||||
/// end of a buffer will be treated as the `DecompressionFailed` error.
|
||||
pub fn read_prefixed_int(&mut self, prefix_len: u8) -> Res<u64> {
|
||||
debug_assert!(prefix_len < 8);
|
||||
|
||||
|
@ -105,17 +111,17 @@ impl<'a> ReceiverBufferWrapper<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Do not use LiteralReader here to avoid copying data.
|
||||
/// Do not use `LiteralReader` here to avoid copying data.
|
||||
/// The function decoded a literal with a prefix:
|
||||
/// 1) ignores prefix_len bits of the first byte,
|
||||
/// 1) ignores `prefix_len` bits of the first byte,
|
||||
/// 2) reads "huffman bit"
|
||||
/// 3) decode varint that is the length of a literal
|
||||
/// 4) reads the literal
|
||||
/// 5) performs huffman decoding if needed.
|
||||
///
|
||||
/// ReceiverBufferWrapper is only used for decoding header blocks. The header blocks are read
|
||||
/// `ReceiverBufferWrapper` is only used for decoding header blocks. The header blocks are read
|
||||
/// entirely before a decoding starts, therefore any incomplete varint or literal because of
|
||||
/// reaching the end of a buffer will be treated as the DecompressionFailed error.
|
||||
/// reaching the end of a buffer will be treated as the `DecompressionFailed` error.
|
||||
pub fn read_literal_from_buffer(&mut self, prefix_len: u8) -> Res<String> {
|
||||
debug_assert!(prefix_len < 7);
|
||||
|
||||
|
@ -154,8 +160,9 @@ pub struct IntReader {
|
|||
}
|
||||
|
||||
impl IntReader {
|
||||
/// IntReader is created by suppling the first byte anf prefix length.
|
||||
/// `IntReader` is created by suppling the first byte anf prefix length.
|
||||
/// A varint may take only one byte, In that case already the first by has set state to done.
|
||||
#[must_use]
|
||||
pub fn new(first_byte: u8, prefix_len: u8) -> Self {
|
||||
debug_assert!(prefix_len < 8, "prefix cannot larger than 7.");
|
||||
let mask = if prefix_len == 0 {
|
||||
|
@ -172,6 +179,7 @@ impl IntReader {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn make(first_byte: u8, prefixes: &[Prefix]) -> Self {
|
||||
for prefix in prefixes {
|
||||
if prefix.cmp_prefix(first_byte) {
|
||||
|
@ -183,10 +191,10 @@ impl IntReader {
|
|||
|
||||
/// This function reads more bytes until the varint is decoded or until stream/buffer does not
|
||||
/// have any more date.
|
||||
/// ### Error
|
||||
/// # Errors
|
||||
/// Possible errors are:
|
||||
/// 1) IntegerOverflow
|
||||
/// 2) Any ReadByte's error
|
||||
/// 1) `IntegerOverflow`
|
||||
/// 2) Any `ReadByte`'s error
|
||||
/// It returns Some(value) if reading the varint is done or None if it needs more data.
|
||||
pub fn read<R: ReadByte>(&mut self, s: &mut R) -> Res<Option<u64>> {
|
||||
// If it is not finished yet read more data.
|
||||
|
@ -242,7 +250,7 @@ impl Default for LiteralReaderState {
|
|||
}
|
||||
|
||||
/// This is decoder of a literal with a prefix:
|
||||
/// 1) ignores prefix_len bits of the first byte,
|
||||
/// 1) ignores `prefix_len` bits of the first byte,
|
||||
/// 2) reads "huffman bit"
|
||||
/// 3) decode varint that is the length of a literal
|
||||
/// 4) reads the literal
|
||||
|
@ -255,9 +263,10 @@ pub struct LiteralReader {
|
|||
}
|
||||
|
||||
impl LiteralReader {
|
||||
/// Creates LiteralReader with the first byte. This constructor is always used
|
||||
/// Creates `LiteralReader` with the first byte. This constructor is always used
|
||||
/// when a litreral has a prefix.
|
||||
/// For literals without a prefix please use the default constructor.
|
||||
#[must_use]
|
||||
pub fn new_with_first_byte(first_byte: u8, prefix_len: u8) -> Self {
|
||||
assert!(prefix_len < 8);
|
||||
Self {
|
||||
|
@ -271,10 +280,10 @@ impl LiteralReader {
|
|||
|
||||
/// This function reads bytes until the literal is decoded or until stream/buffer does not
|
||||
/// have any more date ready.
|
||||
/// ### Error
|
||||
/// # Errors
|
||||
/// Possible errors are:
|
||||
/// 1) IntegerOverflow
|
||||
/// 2) Any ReadByte's error
|
||||
/// 1) `IntegerOverflow`
|
||||
/// 2) Any `ReadByte`'s error
|
||||
/// It returns Some(value) if reading the literal is done or None if it needs more data.
|
||||
pub fn read<T: ReadByte + Reader>(&mut self, s: &mut T) -> Res<Option<Vec<u8>>> {
|
||||
loop {
|
||||
|
@ -295,7 +304,7 @@ impl LiteralReader {
|
|||
LiteralReaderState::ReadLength { reader } => match reader.read(s)? {
|
||||
Some(v) => {
|
||||
self.literal
|
||||
.resize(v.try_into().or(Err(Error::DecodingError))?, 0x0);
|
||||
.resize(v.try_into().or(Err(Error::Decoding))?, 0x0);
|
||||
self.state = LiteralReaderState::ReadLiteral { offset: 0 };
|
||||
}
|
||||
None => break Ok(None),
|
||||
|
@ -322,8 +331,10 @@ impl LiteralReader {
|
|||
}
|
||||
}
|
||||
|
||||
/// This is a helper function used only by ReceiverBufferWrapper, therefore it returns
|
||||
/// DecompressionFailed if any error happens.
|
||||
/// This is a helper function used only by `ReceiverBufferWrapper`, therefore it returns
|
||||
/// `DecompressionFailed` if any error happens.
|
||||
/// # Errors
|
||||
/// If an parsing error occurred, the function returns `DecompressionFailed`.
|
||||
pub fn to_string(v: &[u8]) -> Res<String> {
|
||||
match str::from_utf8(v) {
|
||||
Ok(s) => Ok(s.to_string()),
|
||||
|
@ -334,7 +345,7 @@ pub fn to_string(v: &[u8]) -> Res<String> {
|
|||
#[cfg(test)]
|
||||
pub(crate) mod test_receiver {
|
||||
|
||||
use super::*;
|
||||
use super::{Error, ReadByte, Reader, Res};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub struct TestReceiver {
|
||||
|
@ -381,7 +392,10 @@ pub(crate) mod test_receiver {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use super::{
|
||||
str, test_receiver, to_string, Error, IntReader, LiteralReader, ReadByte,
|
||||
ReceiverBufferWrapper, Res,
|
||||
};
|
||||
use test_receiver::TestReceiver;
|
||||
|
||||
const TEST_CASES_NUMBERS: [(&[u8], u8, u64); 7] = [
|
||||
|
@ -580,12 +594,15 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn read_failure_receiver_buffer_wrapper() {
|
||||
fn read_failure_receiver_buffer_wrapper_number() {
|
||||
let (buf, prefix_len, _) = &TEST_CASES_NUMBERS[4];
|
||||
let mut buffer = ReceiverBufferWrapper::new(&buf[..1]);
|
||||
let mut reader = IntReader::new(buffer.read_byte().unwrap(), *prefix_len);
|
||||
assert_eq!(reader.read(&mut buffer), Err(Error::DecompressionFailed));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_failure_receiver_buffer_wrapper_literal() {
|
||||
let (buf, prefix_len, _) = &TEST_CASES_LITERAL[0];
|
||||
let mut buffer = ReceiverBufferWrapper::new(&buf[..6]);
|
||||
assert_eq!(
|
||||
|
|
|
@ -108,50 +108,50 @@ impl HeaderTable {
|
|||
pub fn set_capacity(&mut self, cap: u64) -> Res<()> {
|
||||
qtrace!([self], "set capacity to {}", cap);
|
||||
if !self.evict_to(cap) {
|
||||
return Err(Error::InternalError);
|
||||
return Err(Error::Internal);
|
||||
}
|
||||
self.capacity = cap;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_static(&self, index: u64) -> Res<&StaticTableEntry> {
|
||||
if index > HEADER_STATIC_TABLE.len() as u64 {
|
||||
return Err(Error::HeaderLookupError);
|
||||
pub fn get_static(index: u64) -> Res<&'static StaticTableEntry> {
|
||||
let inx = usize::try_from(index).or(Err(Error::HeaderLookup))?;
|
||||
if inx > HEADER_STATIC_TABLE.len() {
|
||||
return Err(Error::HeaderLookup);
|
||||
}
|
||||
let res = &HEADER_STATIC_TABLE[index as usize];
|
||||
Ok(res)
|
||||
Ok(&HEADER_STATIC_TABLE[inx])
|
||||
}
|
||||
|
||||
fn get_dynamic_with_abs_index(&mut self, index: u64) -> Res<&mut DynamicTableEntry> {
|
||||
if self.base <= index {
|
||||
debug_assert!(false, "This is an iternal error");
|
||||
return Err(Error::InternalError);
|
||||
return Err(Error::Internal);
|
||||
}
|
||||
let inx = self.base - index - 1;
|
||||
let inx = usize::try_from(inx).or(Err(Error::HeaderLookupError))?;
|
||||
let inx = usize::try_from(inx).or(Err(Error::HeaderLookup))?;
|
||||
if inx >= self.dynamic.len() {
|
||||
return Err(Error::HeaderLookupError);
|
||||
return Err(Error::HeaderLookup);
|
||||
}
|
||||
Ok(&mut self.dynamic[inx])
|
||||
}
|
||||
|
||||
fn get_dynamic_with_relative_index(&self, index: u64) -> Res<&DynamicTableEntry> {
|
||||
let inx = usize::try_from(index).or(Err(Error::HeaderLookupError))?;
|
||||
let inx = usize::try_from(index).or(Err(Error::HeaderLookup))?;
|
||||
if inx >= self.dynamic.len() {
|
||||
return Err(Error::HeaderLookupError);
|
||||
return Err(Error::HeaderLookup);
|
||||
}
|
||||
Ok(&self.dynamic[inx])
|
||||
}
|
||||
|
||||
pub fn get_dynamic(&self, index: u64, base: u64, post: bool) -> Res<&DynamicTableEntry> {
|
||||
if self.base < base {
|
||||
return Err(Error::HeaderLookupError);
|
||||
return Err(Error::HeaderLookup);
|
||||
}
|
||||
let inx: u64;
|
||||
let base_rel = self.base - base;
|
||||
if post {
|
||||
if base_rel <= index {
|
||||
return Err(Error::HeaderLookupError);
|
||||
return Err(Error::HeaderLookup);
|
||||
}
|
||||
inx = base_rel - index - 1;
|
||||
} else {
|
||||
|
@ -204,7 +204,7 @@ impl HeaderTable {
|
|||
}
|
||||
}
|
||||
|
||||
for iter in self.dynamic.iter_mut() {
|
||||
for iter in &mut self.dynamic {
|
||||
if !can_block && iter.index() >= self.acked_inserts_cnt {
|
||||
continue;
|
||||
}
|
||||
|
@ -260,8 +260,8 @@ impl HeaderTable {
|
|||
};
|
||||
if entry.size() > self.capacity || !self.evict_to(self.capacity - entry.size()) {
|
||||
match self.qpack_side {
|
||||
QPackSide::Encoder => return Err(Error::EncoderStreamError),
|
||||
QPackSide::Decoder => return Err(Error::DecoderStreamError),
|
||||
QPackSide::Encoder => return Err(Error::EncoderStream),
|
||||
QPackSide::Decoder => return Err(Error::DecoderStream),
|
||||
}
|
||||
}
|
||||
self.base += 1;
|
||||
|
@ -289,7 +289,7 @@ impl HeaderTable {
|
|||
value
|
||||
);
|
||||
let name = if name_static_table {
|
||||
self.get_static(name_index)?.name().to_vec()
|
||||
HeaderTable::get_static(name_index)?.name().to_vec()
|
||||
} else {
|
||||
self.get_dynamic(name_index, self.base, false)?
|
||||
.name()
|
||||
|
@ -318,7 +318,7 @@ impl HeaderTable {
|
|||
qtrace!([self], "increment acked by {}", increment);
|
||||
self.acked_inserts_cnt += increment;
|
||||
if self.base < self.acked_inserts_cnt {
|
||||
return Err(Error::InternalError);
|
||||
return Err(Error::Internal);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"b6540b9503d44204c905d89db8eb4e455be996bbd3063a12bd6732f9703e9cd0","TODO":"d759cb804b32fa9d96ea8d3574a3c4073da9fe6a0b02b708a0e22cce5a5b4a0f","src/cc.rs":"b4639a63f4c4112a42223f164e71bd230419bd2a0777cbdfc1852d2a32ba3f3d","src/cid.rs":"f2add30abfa0406c8dbda402f12d15dfb1549085bf2ed1a5e7b287922cc92e93","src/connection.rs":"39f81eaeca08c1a63a60cefc619525254d4f1a8c4ff27e38a7c41eda01225be8","src/crypto.rs":"4147bb67d9967d47b84af1cadccb447762050c3d252255af7a5c3f3c20ecfde0","src/dump.rs":"d69ccb0e3b240823b886a791186afbac9f2e26d1f1f67a55dbf86f8cd3e6203e","src/events.rs":"07b1fa18efc538b96736ebfedba929b4854dffd460e1250ae02dc79cc86bb310","src/flow_mgr.rs":"0b1c6e7587e411635723207ecface6c62d1243599dd017745c61eb94805b9886","src/frame.rs":"246d4d8a3fe877c1bd6b187f5ea80b8b461bd040d0ff474ecdb5e2f551b954e3","src/lib.rs":"1d6404e9fc11edc51ca58d227e0016ca79947b74420f71ff19030d2c356a42fe","src/packet.rs":"b36d68083a5c35c7c40f4ba319d22fa85e5e32c22d04acab63741bf8f05787e2","src/path.rs":"829f5fd788f21525bbc6698abf04651594cfa79380f0ab1c6152a5d391669e58","src/recovery.rs":"5c00435186a28279a9c07cceda5ad00e56a02f334332e8778aa91d06a3b93296","src/recv_stream.rs":"0a0c44a3414e6088a704c1a245fd98dd8a8ed502d80bfab90d2defe039bd37cb","src/send_stream.rs":"4d8b929139092216ea2e2388184ac97782cfa92991933ed0ef350bc55b3d1aef","src/server.rs":"6eb850380f17e12c3cc79cb94ab93149eb36afb5c4d26dd9d9c2629f58f7f03e","src/stats.rs":"a276bd9902939091578d3bcc95aa7dd0b32f5d29e528c12e7b93a0ab88474478","src/stream_id.rs":"b3158cf2c6072da79bf6e77a31f71f2f3b970429221142a9ff1dd6cd07df2442","src/tparams.rs":"ef0e8d42ebd51f9494198525060c215ab8fe723c569dc25186de0af558034b66","src/tracking.rs":"4c6690be7a6f83566ba5203e59ed50204e943179ad93ad627e25dd4ac8af63b9","tests/conn_vectors.rs":"b541537a360886f4b9d7e85105bd38faeba83f1ef85b1b1f9ae79891481348a5","tests/connection.rs":"a93985c199a9ef987106f4a20b35ebf803cdbbb855c07b1362b403eed7101ef8","tests/server.rs":"d516bf134a63377c98ff4ac2cca2d4cc6562f48ea262b10a23866d38c4c82af3"},"package":null}
|
||||
{"files":{"Cargo.toml":"b828688e4d9b7b8a5c8eac8c8959f60e2260d8d52bae80b554ebc88792c2bdfe","TODO":"d759cb804b32fa9d96ea8d3574a3c4073da9fe6a0b02b708a0e22cce5a5b4a0f","src/cc.rs":"b4639a63f4c4112a42223f164e71bd230419bd2a0777cbdfc1852d2a32ba3f3d","src/cid.rs":"f2add30abfa0406c8dbda402f12d15dfb1549085bf2ed1a5e7b287922cc92e93","src/connection.rs":"c088ccb5123cd06070f039b41f446bb7902a4e824ebeccbfdd3759ac0b16792c","src/crypto.rs":"4147bb67d9967d47b84af1cadccb447762050c3d252255af7a5c3f3c20ecfde0","src/dump.rs":"d69ccb0e3b240823b886a791186afbac9f2e26d1f1f67a55dbf86f8cd3e6203e","src/events.rs":"deee6ef1112034582af770212bb70ed2cdcd2b1b8bb167c9118ef39bbf454451","src/flow_mgr.rs":"0b1c6e7587e411635723207ecface6c62d1243599dd017745c61eb94805b9886","src/frame.rs":"246d4d8a3fe877c1bd6b187f5ea80b8b461bd040d0ff474ecdb5e2f551b954e3","src/lib.rs":"1d6404e9fc11edc51ca58d227e0016ca79947b74420f71ff19030d2c356a42fe","src/packet.rs":"b36d68083a5c35c7c40f4ba319d22fa85e5e32c22d04acab63741bf8f05787e2","src/path.rs":"829f5fd788f21525bbc6698abf04651594cfa79380f0ab1c6152a5d391669e58","src/recovery.rs":"5c00435186a28279a9c07cceda5ad00e56a02f334332e8778aa91d06a3b93296","src/recv_stream.rs":"c961df90c50df0ba45d603d270bbccc17abcd6335f054a745f29d62d8d0c6688","src/send_stream.rs":"4d8b929139092216ea2e2388184ac97782cfa92991933ed0ef350bc55b3d1aef","src/server.rs":"6eb850380f17e12c3cc79cb94ab93149eb36afb5c4d26dd9d9c2629f58f7f03e","src/stats.rs":"a276bd9902939091578d3bcc95aa7dd0b32f5d29e528c12e7b93a0ab88474478","src/stream_id.rs":"b3158cf2c6072da79bf6e77a31f71f2f3b970429221142a9ff1dd6cd07df2442","src/tparams.rs":"ef0e8d42ebd51f9494198525060c215ab8fe723c569dc25186de0af558034b66","src/tracking.rs":"4c6690be7a6f83566ba5203e59ed50204e943179ad93ad627e25dd4ac8af63b9","tests/conn_vectors.rs":"b541537a360886f4b9d7e85105bd38faeba83f1ef85b1b1f9ae79891481348a5","tests/connection.rs":"a93985c199a9ef987106f4a20b35ebf803cdbbb855c07b1362b403eed7101ef8","tests/server.rs":"d516bf134a63377c98ff4ac2cca2d4cc6562f48ea262b10a23866d38c4c82af3"},"package":null}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "neqo-transport"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = ["EKR <ekr@rtfm.com>", "Andy Grover <agrover@mozilla.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
|
|
@ -4276,4 +4276,55 @@ mod tests {
|
|||
(Frame::Ack { .. }, PNSpace::ApplicationData)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_fin_is_read_conn_events_for_stream_should_be_removed() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let id = server.stream_create(StreamType::BiDi).unwrap();
|
||||
server.stream_send(id, &[6; 10]).unwrap();
|
||||
server.stream_close_send(id).unwrap();
|
||||
let out = server.process(None, now()).dgram();
|
||||
assert!(out.is_some());
|
||||
|
||||
let _ = client.process(out, now());
|
||||
|
||||
// read from the stream before checking connection events.
|
||||
let mut buf = vec![0; 4000];
|
||||
let (_, fin) = client.stream_recv(id, &mut buf).unwrap();
|
||||
assert_eq!(fin, true);
|
||||
|
||||
// Make sure we do not have RecvStreamReadable events for the stream when fin has been read.
|
||||
let readable_stream_evt =
|
||||
|e| matches!(e, ConnectionEvent::RecvStreamReadable { stream_id } if stream_id == id);
|
||||
assert!(!client.events().any(readable_stream_evt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_stream_stop_sending_is_called_conn_events_for_stream_should_be_removed() {
|
||||
let mut client = default_client();
|
||||
let mut server = default_server();
|
||||
connect(&mut client, &mut server);
|
||||
|
||||
let id = server.stream_create(StreamType::BiDi).unwrap();
|
||||
server.stream_send(id, &[6; 10]).unwrap();
|
||||
server.stream_close_send(id).unwrap();
|
||||
let out = server.process(None, now()).dgram();
|
||||
assert!(out.is_some());
|
||||
|
||||
let _ = client.process(out, now());
|
||||
|
||||
// send stop seending.
|
||||
client
|
||||
.stream_stop_sending(id, Error::NoError.code())
|
||||
.unwrap();
|
||||
|
||||
// Make sure we do not have RecvStreamReadable events for the stream after stream_stop_sending
|
||||
// has been called.
|
||||
let readable_stream_evt =
|
||||
|e| matches!(e, ConnectionEvent::RecvStreamReadable { stream_id } if stream_id == id);
|
||||
assert!(!client.events().any(readable_stream_evt));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,6 +126,11 @@ impl ConnectionEvents {
|
|||
self.insert(ConnectionEvent::ZeroRttRejected);
|
||||
}
|
||||
|
||||
pub fn recv_stream_complete(&self, stream_id: StreamId) {
|
||||
// If stopped, no longer readable.
|
||||
self.remove(|evt| matches!(evt, ConnectionEvent::RecvStreamReadable { stream_id: x } if *x == stream_id.as_u64()));
|
||||
}
|
||||
|
||||
pub fn events(&self) -> impl Iterator<Item = ConnectionEvent> {
|
||||
self.events.replace(VecDeque::new()).into_iter()
|
||||
}
|
||||
|
|
|
@ -373,6 +373,10 @@ impl RecvStream {
|
|||
.clear_max_stream_data(self.stream_id)
|
||||
}
|
||||
|
||||
if let RecvStreamState::DataRead = new_state {
|
||||
self.conn_events.recv_stream_complete(self.stream_id);
|
||||
}
|
||||
|
||||
self.state = new_state;
|
||||
}
|
||||
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,101 @@
|
|||
language: rust
|
||||
# sudo is required to enable kcov to use the personality syscall
|
||||
sudo: required
|
||||
dist: trusty
|
||||
cache: cargo
|
||||
|
||||
rust:
|
||||
- nightly
|
||||
- beta
|
||||
- stable
|
||||
- 1.31.0
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- FEATURES='--features "regexp regexp_macros"'
|
||||
|
||||
before_script:
|
||||
- eval git pull --rebase https://github.com/Geal/nom master
|
||||
- eval git log --pretty=oneline HEAD~5..HEAD
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- rust: nightly
|
||||
env: FEATURES='--no-default-features'
|
||||
- rust: nightly
|
||||
env: FEATURES='--no-default-features --features "alloc"'
|
||||
- rust: stable
|
||||
env: FEATURES=''
|
||||
- rust: nightly
|
||||
env: DOC_FEATURES='--features "std lexical regexp regexp_macros" --no-default-features'
|
||||
before_script:
|
||||
- export PATH=$HOME/.cargo/bin:$PATH
|
||||
script:
|
||||
- eval cargo doc --verbose $DOC_FEATURES
|
||||
- rust: nightly
|
||||
env: FEATURES=''
|
||||
before_script:
|
||||
- export PATH=$HOME/.cargo/bin:$PATH
|
||||
- cargo install cargo-update || echo "cargo-update already installed"
|
||||
- cargo install cargo-travis || echo "cargo-travis already installed"
|
||||
- cargo install-update -a
|
||||
- mkdir -p target/kcov-master
|
||||
script:
|
||||
cargo coveralls --verbose --all-features
|
||||
allow_failures:
|
||||
- rust: stable
|
||||
env: FEATURES=''
|
||||
before_script:
|
||||
- export PATH=$HOME/.cargo/bin:$PATH
|
||||
- rustup component add rustfmt-preview
|
||||
script:
|
||||
- eval cargo fmt -- --write-mode=diff
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/9c035a194ac4fd4cc061
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_start: false
|
||||
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
- binutils-dev
|
||||
- cmake
|
||||
sources:
|
||||
- kalakris-cmake
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- /home/travis/.cargo
|
||||
|
||||
before_cache:
|
||||
- rm -rf /home/travis/.cargo/registry
|
||||
|
||||
script:
|
||||
- eval cargo build --verbose $FEATURES
|
||||
- eval cargo test --verbose $FEATURES
|
||||
|
||||
after_success: |
|
||||
case "$TRAVIS_RUST_VERSION" in
|
||||
nightly)
|
||||
if [ "${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" != "master" ]; then
|
||||
git fetch &&
|
||||
git checkout master &&
|
||||
cargo bench --verbose
|
||||
fi
|
||||
|
||||
if [ "$FEATURES" == '--features "regexp regexp_macros"' ]; then
|
||||
cargo bench --verbose
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
esac
|
Загрузка…
Ссылка в новой задаче