Repository: c410-f3r/wtx (language: rust)

Issue:
[HTTP/2] Add low level operations
The current machinery automatically splits the data according to https://datatracker.ietf.org/doc/html/rfc9113#SETTINGS_MAX_FRAME_SIZE and sends each block concurrently respecting flow control parameters. This approach is pragmatic but lacks flexibility when it is necessary to have a more fine-grained control over how things are sent and received. 


Discussion / hints:

Fix patch:
diff --git a/.scripts/autobahn-fuzzingclient.sh b/.scripts/autobahn-fuzzingclient.sh
index 489753aa..7dc71558 100755
--- a/.scripts/autobahn-fuzzingclient.sh
+++ b/.scripts/autobahn-fuzzingclient.sh
@@ -5,8 +5,8 @@ if [ "$ARG" != "ci" ]; then
 	trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
 fi;
 
-cargo build --bin autobahn-server --features flate2,optimization,pool,tokio,web-socket-handshake --release
-cargo run --bin autobahn-server --features flate2,optimization,pool,tokio,web-socket-handshake --release & cargo_pid=$!
+cargo build --bin autobahn-server --features flate2,nightly,optimization,pool,tokio,web-socket-handshake --release
+cargo run --bin autobahn-server --features flate2,nightly,optimization,pool,tokio,web-socket-handshake --release & cargo_pid=$!
 sleep 1
 mkdir -p .scripts/autobahn/reports/fuzzingclient
 podman run \
diff --git a/.scripts/curl.sh b/.scripts/curl.sh
index 52b8ad5d..55307316 100755
--- a/.scripts/curl.sh
+++ b/.scripts/curl.sh
@@ -11,8 +11,10 @@ else
     autoreconf -fi
     ./configure --enable-debug --with-nghttp2 --without-ssl
     make
-    cd tests
+    cd tests/server
+    make
+    cd ..
 fi
 
-cargo build --bin wtx-ui --features http-client --release
+cargo build --bin wtx-ui --features _curl,http-client --release
 ./runtests.pl -d -n -c "$PWD/../../target/release/wtx-ui"
\ No newline at end of file
diff --git a/.scripts/h2load.sh b/.scripts/h2load.sh
new file mode 100755
index 00000000..0650f5ff
--- /dev/null
+++ b/.scripts/h2load.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -euxo pipefail
+
+ARG=${1:-""}
+if [ "$ARG" != "ci" ]; then
+	trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
+fi;
+
+cargo build --bin h2load --features="wtx/http2,wtx/nightly" --profile deploy
+cargo run --bin h2load --features="wtx/http2,wtx/nightly" --profile deploy &
+sleep 1
+
+h2load -c100 -m10 -n100000 --no-tls-proto=h2c http://localhost:9000
diff --git a/.scripts/h2spec.sh b/.scripts/h2spec.sh
index da8f8347..b6d099b4 100755
--- a/.scripts/h2spec.sh
+++ b/.scripts/h2spec.sh
@@ -1,15 +1,24 @@
+#!/usr/bin/env bash
+
 set -euxo pipefail
 
-ARG=${1:-""}
-if [ "$ARG" != "ci" ]; then
+TY=${1:-"high"}
+CI=${2:-""}
+
+if [ "$CI" != "ci" ]; then
 	trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
 fi;
 
-cargo build --bin h2spec-server --features="http2,tokio" --release
-cargo run --bin h2spec-server --features="http2,tokio" --release &> /tmp/h2spec-server.txt & cargo_pid=$!
-sleep 1
 touch /tmp/h2spec-server.xml
 
+if [ "$TY" != "high" ]; then
+	TY="low";
+fi;
+
+cargo build --bin "h2spec-$TY-server" --features="http2,nightly,tokio" --release
+cargo run --bin "h2spec-$TY-server" --features="http2,nightly,tokio" --release &> /tmp/h2spec-server.txt &
+sleep 1
+
 podman run \
 	-v "/tmp/h2spec-server.xml:/tmp/h2spec-server.xml" \
 	--name h2spec \
@@ -59,5 +68,3 @@ podman run \
 		http2/7 \
 		http2/8.1 \
 		`#http2/8.2 - Server push is unsupported`
-
-kill -9 $cargo_pid
diff --git a/Cargo.lock b/Cargo.lock
index f9c4ae07..23af778d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
 
 [[package]]
 name = "addr2line"
-version = "0.24.1"
+version = "0.24.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
 dependencies = [
  "gimli",
 ]
@@ -52,6 +52,17 @@ dependencies = [
  "subtle",
 ]
 
+[[package]]
+name = "ahash"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
 [[package]]
 name = "aho-corasick"
 version = "1.1.3"
@@ -61,6 +72,12 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "allocator-api2"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
+
 [[package]]
 name = "android-tzdata"
 version = "0.1.1"
@@ -78,9 +95,9 @@ dependencies = [
 
 [[package]]
 name = "anstyle"
-version = "1.0.8"
+version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56"
 
 [[package]]
 name = "arbitrary"
@@ -100,6 +117,7 @@ dependencies = [
  "base64ct",
  "blake2",
  "cpufeatures",
+ "password-hash",
 ]
 
 [[package]]
@@ -157,6 +175,18 @@ version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
+[[package]]
+name = "bitvec"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
 [[package]]
 name = "blake2"
 version = "0.10.6"
@@ -195,7 +225,7 @@ dependencies = [
  "proc-macro-crate",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
  "syn_derive",
 ]
 
@@ -205,6 +235,28 @@ version = "3.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
 
+[[package]]
+name = "bytecheck"
+version = "0.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2"
+dependencies = [
+ "bytecheck_derive",
+ "ptr_meta",
+ "simdutf8",
+]
+
+[[package]]
+name = "bytecheck_derive"
+version = "0.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
 [[package]]
 name = "byteorder"
 version = "1.5.0"
@@ -213,15 +265,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
-version = "1.7.2"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
+checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
 
 [[package]]
 name = "cc"
-version = "1.1.24"
+version = "1.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
+checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
 dependencies = [
  "jobserver",
  "libc",
@@ -275,9 +327,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.19"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615"
+checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -285,9 +337,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.19"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b"
+checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
 dependencies = [
  "anstyle",
  "clap_lex",
@@ -302,7 +354,7 @@ dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -387,7 +439,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -436,6 +488,12 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
 
+[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
 [[package]]
 name = "generic-array"
 version = "0.14.7"
@@ -469,9 +527,9 @@ dependencies = [
 
 [[package]]
 name = "gimli"
-version = "0.31.0"
+version = "0.31.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
 
 [[package]]
 name = "glob"
@@ -481,9 +539,12 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 
 [[package]]
 name = "hashbrown"
-version = "0.14.5"
+version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+dependencies = [
+ "ahash",
+]
 
 [[package]]
 name = "hashbrown"
@@ -491,6 +552,7 @@ version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
 dependencies = [
+ "allocator-api2",
  "foldhash",
 ]
 
@@ -552,12 +614,12 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.5.0"
+version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
+checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
 dependencies = [
  "equivalent",
- "hashbrown 0.14.5",
+ "hashbrown 0.15.0",
 ]
 
 [[package]]
@@ -586,9 +648,9 @@ dependencies = [
 
 [[package]]
 name = "js-sys"
-version = "0.3.70"
+version = "0.3.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
+checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -601,9 +663,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.159"
+version = "0.2.161"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
 
 [[package]]
 name = "libfuzzer-sys"
@@ -624,9 +686,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
 
 [[package]]
 name = "libz-ng-sys"
-version = "1.1.16"
+version = "1.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4436751a01da56f1277f323c80d584ffad94a3d14aecd959dd0dff75aa73a438"
+checksum = "8f0f7295a34685977acb2e8cc8b08ee4a8dffd6cf278eeccddbe1ed55ba815d5"
 dependencies = [
  "cmake",
  "libc",
@@ -717,21 +779,18 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.36.4"
+version = "0.36.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
+checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
 name = "once_cell"
-version = "1.20.1"
+version = "1.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
-dependencies = [
- "portable-atomic",
-]
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
 
 [[package]]
 name = "opaque-debug"
@@ -739,6 +798,17 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
 
+[[package]]
+name = "password-hash"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
+dependencies = [
+ "base64ct",
+ "rand_core",
+ "subtle",
+]
+
 [[package]]
 name = "pb-rs"
 version = "0.10.0"
@@ -761,9 +831,9 @@ dependencies = [
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.14"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
 
 [[package]]
 name = "polyval"
@@ -777,12 +847,6 @@ dependencies = [
  "universal-hash",
 ]
 
-[[package]]
-name = "portable-atomic"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
-
 [[package]]
 name = "ppv-lite86"
 version = "0.2.20"
@@ -826,9 +890,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
 dependencies = [
  "unicode-ident",
 ]
@@ -849,6 +913,26 @@ dependencies = [
  "unarray",
 ]
 
+[[package]]
+name = "ptr_meta"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1"
+dependencies = [
+ "ptr_meta_derive",
+]
+
+[[package]]
+name = "ptr_meta_derive"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
 [[package]]
 name = "quick-protobuf"
 version = "0.8.1"
@@ -867,6 +951,12 @@ dependencies = [
  "proc-macro2",
 ]
 
+[[package]]
+name = "radium"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
 [[package]]
 name = "rand"
 version = "0.8.5"
@@ -908,9 +998,9 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.11.0"
+version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -950,6 +1040,15 @@ version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 
+[[package]]
+name = "rend"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c"
+dependencies = [
+ "bytecheck",
+]
+
 [[package]]
 name = "ring"
 version = "0.17.8"
@@ -965,6 +1064,35 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
+[[package]]
+name = "rkyv"
+version = "0.7.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b"
+dependencies = [
+ "bitvec",
+ "bytecheck",
+ "bytes",
+ "hashbrown 0.12.3",
+ "ptr_meta",
+ "rend",
+ "rkyv_derive",
+ "seahash",
+ "tinyvec",
+ "uuid",
+]
+
+[[package]]
+name = "rkyv_derive"
+version = "0.7.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
 [[package]]
 name = "rust_decimal"
 version = "1.36.0"
@@ -972,8 +1100,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555"
 dependencies = [
  "arrayvec",
+ "borsh",
+ "bytes",
  "num-traits",
  "proptest",
+ "rand",
+ "rkyv",
+ "serde",
+ "serde_json",
 ]
 
 [[package]]
@@ -984,9 +1118,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
 
 [[package]]
 name = "rustls"
-version = "0.23.13"
+version = "0.23.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
+checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993"
 dependencies = [
  "once_cell",
  "ring",
@@ -1028,31 +1162,37 @@ version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
 
+[[package]]
+name = "seahash"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
+
 [[package]]
 name = "serde"
-version = "1.0.210"
+version = "1.0.213"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.210"
+version = "1.0.213"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.128"
+version = "1.0.132"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
+checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
 dependencies = [
  "itoa",
  "memchr",
@@ -1162,7 +1302,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "structmeta-derive",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -1173,7 +1313,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -1195,9 +1335,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.79"
+version = "2.0.85"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1213,9 +1353,21 @@ dependencies = [
  "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
+name = "target-triple"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078"
+
 [[package]]
 name = "termcolor"
 version = "1.4.1"
@@ -1234,27 +1386,27 @@ dependencies = [
  "proc-macro2",
  "quote",
  "structmeta",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
 name = "thiserror"
-version = "1.0.64"
+version = "1.0.65"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
+checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.64"
+version = "1.0.65"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
+checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -1284,9 +1436,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.40.0"
+version = "1.41.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
+checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb"
 dependencies = [
  "backtrace",
  "bytes",
@@ -1306,7 +1458,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -1373,7 +1525,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -1414,14 +1566,15 @@ dependencies = [
 
 [[package]]
 name = "trybuild"
-version = "1.0.99"
+version = "1.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8"
+checksum = "8dcd332a5496c026f1e14b7f3d2b7bd98e509660c04239c58b0ba38a12daded4"
 dependencies = [
  "glob",
  "serde",
  "serde_derive",
  "serde_json",
+ "target-triple",
  "termcolor",
  "toml",
 ]
@@ -1460,6 +1613,12 @@ version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
 
+[[package]]
+name = "uuid"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
+
 [[package]]
 name = "valuable"
 version = "0.1.0"
@@ -1480,9 +1639,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
+checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -1491,24 +1650,24 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
+checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
+checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -1516,22 +1675,22 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
+checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
+checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
 
 [[package]]
 name = "webpki-roots"
@@ -1742,6 +1901,15 @@ dependencies = [
  "wtx",
 ]
 
+[[package]]
+name = "wyz"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
+dependencies = [
+ "tap",
+]
+
 [[package]]
 name = "x509-certificate"
 version = "0.23.1"
@@ -1779,7 +1947,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
 
 [[package]]
@@ -1799,5 +1967,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.85",
 ]
diff --git a/README.md b/README.md
index e5ace4e7..847d0326 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,9 @@
 [![crates.io](https://img.shields.io/crates/v/wtx.svg)](https://crates.io/crates/wtx)
 [![Documentation](https://docs.rs/wtx/badge.svg)](https://docs.rs/wtx)
 [![License](https://img.shields.io/badge/license-APACHE2-blue.svg)](https://github.com/c410-f3r/wtx/blob/main/LICENSE)
-[![Rustc](https://img.shields.io/badge/rustc-1.82-lightgray")](https://blog.rust-lang.org/2023/12/28/Rust-1.80.0.html)
+[![Rustc](https://img.shields.io/badge/rustc-1.82-lightgray")](https://blog.rust-lang.org/2024/10/17/Rust-1.82.0.html)
 
-A collection of different transport implementations and related tools focused primarily on web technologies. Contains the implementations of 5 IETF RFCs ([RFC6265](https://datatracker.ietf.org/doc/html/rfc6265), [RFC6455](https://datatracker.ietf.org/doc/html/rfc6455), [RFC7541](https://datatracker.ietf.org/doc/html/rfc7541), [RFC7692](https://datatracker.ietf.org/doc/html/rfc7692), [RFC9113](https://datatracker.ietf.org/doc/html/rfc9113)), 2 formal specifications ([gRPC](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), [PostgreSQL](https://www.postgresql.org/docs/16/protocol.html)) and several other invented ideas.
+A collection of different transport implementations and related tools focused primarily on web technologies. Contains the implementations of 6 IETF RFCs ([6265](https://datatracker.ietf.org/doc/html/rfc6265), [6455](https://datatracker.ietf.org/doc/html/rfc6455), [7541](https://datatracker.ietf.org/doc/html/rfc7541), [7692](https://datatracker.ietf.org/doc/html/rfc7692), [8441](https://datatracker.ietf.org/doc/html/rfc8441), [9113](https://datatracker.ietf.org/doc/html/rfc9113)), 2 formal specifications ([gRPC](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), [PostgreSQL](https://www.postgresql.org/docs/current/protocol.html)) and several other invented ideas.
 
 1. [Client API Framework](https://c410-f3r.github.io/wtx/client-api-framework/index.html)
 2. [Database Client](https://c410-f3r.github.io/wtx/database-client/index.html)
@@ -18,6 +18,7 @@ A collection of different transport implementations and related tools focused pr
 8. [Pool Manager](https://c410-f3r.github.io/wtx/pool/index.html)
 9. [UI tools](https://c410-f3r.github.io/wtx/ui-tools/index.html)
 10. [WebSocket Client/Server](https://c410-f3r.github.io/wtx/web-socket/index.html)
+11. [WebSocket over HTTP/2](https://c410-f3r.github.io/wtx/web-socket-over-http2/index.html)
 
 Embedded devices with a working heap allocator can use this `no_std` crate.
 
@@ -47,18 +48,18 @@ Anything marked with `#[bench]` in the repository is considered a low-level benc
 
 Take a look at <https://bencher.dev/perf/wtx> to see all low-level benchmarks over different periods of time.
 
+## Transport Layer Security (TLS)
+
+When using a feature that requires network connection, it is often necessary to perform encrypted communication and since `wtx` is not hard-coded with a specific stream implementation, it is up to you to choose the best TLS provider.
+
+Some utilities like `TokioRustlsConnector` or `TokioRustlsAcceptor` are provided to make things more convenient but keep in mind that it is still necessary to activate a crate that provides certificates for client usage.
+
 ## Examples
 
 Demonstrations of different use-cases can be found in the `wtx-instances` directory as well as in the documentation.
 
 ## Limitations
 
-Does not support systems with 16bit memory addresses and expects the infallible addition of the sizes of 8 allocated chunks of memories, otherwise the program will overflow in certain arithmetic operations involving `usize` potentially resulting in unexpected operations.
-
-For example, in a 32bit system you can allocate a maximum of 2^29 bytes of memory for at most 8 elements. Such a scenario should be viable with little swap memory due to the likely triggering of the OOM killer or through specific limiters like `ulimit`.
-
-## Possible future features
+* Does not support systems with pointer length of 16 bits.
 
-* WebSocket over an HTTP/2 stream (<https://datatracker.ietf.org/doc/html/rfc8441>).
-* WebTransport over HTTP/2 (<https://datatracker.ietf.org/doc/draft-ietf-webtrans-http2>).
-* Static web server
+* Expects the infallible sum of the lengths of an arbitrary number of slices, otherwise the program will likely trigger an overflow that can possibly result in unexpected operations. For example, in a 32bit system such a scenario should be viable without swap memory or through specific limiters like `ulimit`.
diff --git a/wtx-docs/src/client-api-framework/README.md b/wtx-docs/src/client-api-framework/README.md
index 66f34dbf..0da719cc 100644
--- a/wtx-docs/src/client-api-framework/README.md
+++ b/wtx-docs/src/client-api-framework/README.md
@@ -2,7 +2,9 @@
 
 A flexible client API framework for writing asynchronous, fast, organizable, scalable and maintainable applications. Supports several data formats, transports and custom parameters.
 
-Activation feature is called `client-api-framework`. Checkout the `wtx-apis` project to see a collection of APIs based on `wtx`.
+Checkout the `wtx-apis` project to see a collection of APIs based on `wtx`.
+
+To use this functionality, it necessary to activate the `client-api-framework` feature.
 
 ## Objective
 
diff --git a/wtx-docs/src/database-client/README.md b/wtx-docs/src/database-client/README.md
index f7a2dab1..599deaff 100644
--- a/wtx-docs/src/database-client/README.md
+++ b/wtx-docs/src/database-client/README.md
@@ -3,9 +3,9 @@
 
 PostgreSQL is currently the only supported database. Implements <https://www.postgresql.org/docs/16/protocol.html>.
 
-More benchmarks are available at https://github.com/diesel-rs/metrics.
+More benchmarks are available at <https://github.com/diesel-rs/metrics>.
 
-Activation feature is called `postgres`.
+To use this functionality, it necessary to activate the `postgres` feature.
 
 ![PostgreSQL Benchmark](https://i.imgur.com/vf2tYxY.jpeg)
 
diff --git a/wtx-docs/src/grpc/README.md b/wtx-docs/src/grpc/README.md
index 614be691..2a0803eb 100644
--- a/wtx-docs/src/grpc/README.md
+++ b/wtx-docs/src/grpc/README.md
@@ -7,7 +7,7 @@ Basic implementation that currently supports only unary calls.
 
 Due to the lack of an official parser, the definitions of a `Service` must be manually typed.
 
-Activation feature is called `grpc`.
+To use this functionality, it necessary to activate the `grpc` feature.
 
 ## Client Example
 
diff --git a/wtx-docs/src/http-client-framework/README.md b/wtx-docs/src/http-client-framework/README.md
index 5f982eab..2a403984 100644
--- a/wtx-docs/src/http-client-framework/README.md
+++ b/wtx-docs/src/http-client-framework/README.md
@@ -2,7 +2,7 @@
 
 High-level pool of HTTP clients that currently only supports HTTP/2. Allows multiple connections that can be referenced in concurrent scenarios.
 
-Activation feature is called `http-client-framework`.
+To use this functionality, it necessary to activate the `http-client-framework` feature.
 
 ## Example
 
diff --git a/wtx-docs/src/http-server-framework/README.md b/wtx-docs/src/http-server-framework/README.md
index 21d8359c..3e688181 100644
--- a/wtx-docs/src/http-server-framework/README.md
+++ b/wtx-docs/src/http-server-framework/README.md
@@ -4,7 +4,7 @@ A small and fast to compile framework that can interact with many built-in featu
 
 If dynamic or nested routes are needed, then it is necessary to activate the `matchit` feature. Without it, only simple and flat routes will work.
 
-Activation feature is called `http-server-framework`.
+To use this functionality, it necessary to activate the `http-server-framework` feature.
 
 ![HTTP/2 Benchmarks](https://i.imgur.com/lUOX3iM.png)
 
diff --git a/wtx-docs/src/http2/README.md b/wtx-docs/src/http2/README.md
index a4820b7c..5861a732 100644
--- a/wtx-docs/src/http2/README.md
+++ b/wtx-docs/src/http2/README.md
@@ -4,16 +4,16 @@ Implementation of [RFC7541](https://datatracker.ietf.org/doc/html/rfc7541) and [
 
 Passes the `hpack-test-case` and the `h2spec` test suites. Due to official deprecation, server push and prioritization are not supported.
 
-Activation feature is called `http2`.
+To use this functionality, it necessary to activate the `http2` feature.
 
 ## Client Example
 
 ```rust,edition2021,no_run
-{{#rustdoc_include ../../../wtx-instances/generic-examples/http2-client.rs}}
+{{#rustdoc_include ../../../wtx-instances/http2-examples/http2-client.rs}}
 ```
 
 ## Server Example
 
 ```rust,edition2021,no_run
-{{#rustdoc_include ../../../wtx-instances/generic-examples/http2-server.rs}}
+{{#rustdoc_include ../../../wtx-instances/http2-examples/http2-server.rs}}
 ```
\ No newline at end of file
diff --git a/wtx-docs/src/web-socket-over-http2/README.md b/wtx-docs/src/web-socket-over-http2/README.md
new file mode 100644
index 00000000..12086365
--- /dev/null
+++ b/wtx-docs/src/web-socket-over-http2/README.md
@@ -0,0 +1,17 @@
+# WebSocket over HTTP/2
+
+
+At the current time only servers support the handshake procedure defined in [RFC6455](https://https://datatracker.ietf.org/doc/html/rfc8441).
+
+While HTTP/2 inherently supports full-duplex communication, web browsers typically don't expose this functionality directly to developers and that is why WebSocket tunneling over HTTP/2 is important.
+
+1. Servers can efficiently handle multiple concurrent streams within a single TCP connection
+2. Client applications can continue using existing WebSocket APIs without modification
+
+To use this functionality, it necessary to activate the `http2` and `web-socket` features.
+
+## Example
+
+```rust,edition2021,no_run
+{{#rustdoc_include ../../../wtx-instances/http3-examples/web-socket-server.rs}}
+```
\ No newline at end of file
diff --git a/wtx-docs/src/web-socket/README.md b/wtx-docs/src/web-socket/README.md
index 06061487..9787cbcd 100644
--- a/wtx-docs/src/web-socket/README.md
+++ b/wtx-docs/src/web-socket/README.md
@@ -2,7 +2,7 @@
 
 Implementation of [RFC6455](https://datatracker.ietf.org/doc/html/rfc6455) and [RFC7692](https://datatracker.ietf.org/doc/html/rfc7692).
 
-Activation feature is called `web-socket`.
+To use this functionality, it necessary to activate the `web-socket` feature.
 
 ![WebSocket Benchmark](https://i.imgur.com/Iv2WzJV.jpg)
 
diff --git a/wtx-fuzz/web_socket.rs b/wtx-fuzz/web_socket.rs
index 0787f8f5..0173ede0 100644
--- a/wtx-fuzz/web_socket.rs
+++ b/wtx-fuzz/web_socket.rs
@@ -6,10 +6,10 @@
 use tokio::runtime::Builder;
 use wtx::{
   misc::{simple_seed, BytesStream, Xorshift64},
-  web_socket::{FrameBufferVec, FrameMutVec, OpCode, WebSocketBuffer, WebSocketServerOwned},
+  web_socket::{Frame, OpCode, WebSocketBuffer, WebSocketServerOwned},
 };
 
-libfuzzer_sys::fuzz_target!(|data: (OpCode, &[u8])| {
+libfuzzer_sys::fuzz_target!(|data: (OpCode, Vec<u8>)| {
   Builder::new_current_thread().enable_all().build().unwrap().block_on(async move {
     let Ok(mut ws) = WebSocketServerOwned::new(
       (),
@@ -20,13 +20,10 @@ libfuzzer_sys::fuzz_target!(|data: (OpCode, &[u8])| {
       return;
     };
     ws.set_max_payload_len(u16::MAX.into());
-    let fb = &mut FrameBufferVec::default();
-    let Ok(mut frame) = FrameMutVec::new_fin(fb, data.0, data.1) else {
-      return;
-    };
+    let mut frame = Frame::new_fin(data.0, data.1);
     if ws.write_frame(&mut frame).await.is_err() {
       return;
     };
-    let _rslt = ws.read_frame(fb).await;
+    let _rslt = ws.read_frame().await;
   });
 });
diff --git a/wtx-instances/Cargo.toml b/wtx-instances/Cargo.toml
index 1c317f34..e83329a1 100644
--- a/wtx-instances/Cargo.toml
+++ b/wtx-instances/Cargo.toml
@@ -8,12 +8,22 @@ required-features = ["wtx/flate2", "wtx/web-socket-handshake"]
 [[bin]]
 name = "autobahn-server"
 path = "src/bin/autobahn-server.rs"
-required-features = ["wtx/flate2", "wtx/pool", "wtx/web-socket-handshake"]
+required-features = ["wtx/flate2", "wtx/nightly", "wtx/pool", "wtx/web-socket-handshake"]
 
 [[bin]]
-name = "h2spec-server"
-path = "src/bin/h2spec-server.rs"
-required-features = ["wtx/http2"]
+name = "h2load"
+path = "src/bin/h2load.rs"
+required-features = ["wtx/http2", "wtx/nightly"]
+
+[[bin]]
+name = "h2spec-high-server"
+path = "src/bin/h2spec-high-server.rs"
+required-features = ["wtx/http2", "wtx/nightly"]
+
+[[bin]]
+name = "h2spec-low-server"
+path = "src/bin/h2spec-low-server.rs"
+required-features = ["wtx/http2", "wtx/nightly"]
 
 # Database Examples
 
@@ -54,16 +64,6 @@ name = "http-client-framework"
 path = "generic-examples/http-client-framework.rs"
 required-features = ["wtx/http-client-framework"]
 
-[[example]]
-name = "http2-client"
-path = "generic-examples/http2-client.rs"
-required-features = ["wtx/http2"]
-
-[[example]]
-name = "http2-server"
-path = "generic-examples/http2-server.rs"
-required-features = ["wtx/http2", "wtx/tokio-rustls"]
-
 [[example]]
 name = "pool"
 path = "generic-examples/pool.rs"
@@ -101,6 +101,23 @@ name = "http-server-framework-session"
 path = "http-server-framework-examples/http-server-framework-session.rs"
 required-features = ["argon2", "rand_chacha", "rand_core", "serde", "serde_json", "wtx/argon2", "wtx/http-server-framework", "wtx/http-session", "wtx/pool", "wtx/postgres", "wtx/rand_chacha"]
 
+# HTTP/2 Examples
+
+[[example]]
+name = "http2-client"
+path = "http2-examples/http2-client.rs"
+required-features = ["wtx/http2"]
+
+[[example]]
+name = "http2-server"
+path = "http2-examples/http2-server.rs"
+required-features = ["wtx/http2", "wtx/tokio-rustls", "wtx/web-socket"]
+
+[[example]]
+name = "http2-web-socket"
+path = "http2-examples/http2-web-socket.rs"
+required-features = ["wtx/http2", "wtx/tokio-rustls", "wtx/web-socket"]
+
 [build-dependencies]
 pb-rs = { default-features = false, optional = true, version = "0.10" }
 
@@ -117,7 +134,6 @@ wtx = { default-features = false, features = ["tokio"], path = "../wtx" }
 wtx-macros = { default-features = false, optional = true, path = "../wtx-macros" }
 
 [features]
-_tracing-tree = ["wtx/_tracing-tree"]
 grpc = ["pb-rs", "quick-protobuf", "wtx/grpc", "wtx/quick-protobuf"]
 postgres = ["wtx/postgres"]
 
diff --git a/wtx-instances/generic-examples/client-api-framework.rs b/wtx-instances/generic-examples/client-api-framework.rs
index 0078f853..d4f8c572 100644
--- a/wtx-instances/generic-examples/client-api-framework.rs
+++ b/wtx-instances/generic-examples/client-api-framework.rs
@@ -22,7 +22,7 @@ use wtx::{
   data_transformation::dnsn::SerdeJson,
   http::client_framework::ClientFrameworkTokio,
   misc::{simple_seed, Uri, Xorshift64},
-  web_socket::{FrameBufferVec, WebSocketBuffer, WebSocketClient},
+  web_socket::{WebSocketBuffer, WebSocketClient},
 };
 
 wtx::create_packages_aux_wrapper!();
@@ -99,7 +99,7 @@ async fn main() -> wtx::Result<()> {
   async fn web_socket_pair() -> wtx::Result<
     Pair<
       PkgsAux<GenericThrottlingApi, SerdeJson, WsParams>,
-      (FrameBufferVec, WebSocketClient<(), Xorshift64, TcpStream, WebSocketBuffer>),
+      WebSocketClient<(), TcpStream, WebSocketBuffer>,
     >,
   > {
     let uri = Uri::new("ws://generic_web_socket_uri.com");
@@ -121,7 +121,7 @@ async fn main() -> wtx::Result<()> {
         SerdeJson,
         WsParams::default(),
       ),
-      (FrameBufferVec::default(), web_socket),
+      web_socket,
     ))
   }
 
diff --git a/wtx-instances/generic-examples/grpc-server.rs b/wtx-instances/generic-examples/grpc-server.rs
index 05d14ef3..360be929 100644
--- a/wtx-instances/generic-examples/grpc-server.rs
+++ b/wtx-instances/generic-examples/grpc-server.rs
@@ -26,7 +26,7 @@ async fn main() -> wtx::Result<()> {
   )?;
   ServerFrameworkBuilder::new(router)
     .with_req_aux(|| QuickProtobuf::default())
-    .listen_tls(
+    .listen_tokio_rustls(
       (wtx_instances::CERT, wtx_instances::KEY),
       &wtx_instances::host_from_args(),
       Xorshift64::from(simple_seed()),
@@ -38,10 +38,10 @@ async fn main() -> wtx::Result<()> {
 async fn wtx_generic_service_generic_method(
   state: State<'_, (), GrpcManager<QuickProtobuf>, ReqResBuffer>,
 ) -> wtx::Result<StatusCode> {
-  let _generic_request: GenericRequest = state.ra.des_from_req_bytes(&state.req.rrd.data)?;
+  let _generic_request: GenericRequest = state.ra.des_from_req_bytes(&state.req.rrd.body)?;
   state.req.rrd.clear();
   state.ra.ser_to_res_bytes(
-    &mut state.req.rrd.data,
+    &mut state.req.rrd.body,
     GenericResponse {
       generic_response_field0: Cow::Borrowed(b"generic_response_value"),
       generic_response_field1: 321,
diff --git a/wtx-instances/generic-examples/http-client-framework.rs b/wtx-instances/generic-examples/http-client-framework.rs
index 49147571..90166020 100644
--- a/wtx-instances/generic-examples/http-client-framework.rs
+++ b/wtx-instances/generic-examples/http-client-framework.rs
@@ -19,6 +19,6 @@ async fn main() -> wtx::Result<()> {
   let buffer = ReqResBuffer::empty();
   let client = ClientFramework::tokio(1).build();
   let res = client.send(Method::Get, buffer, &uri.to_ref()).await?;
-  println!("{}", from_utf8_basic(&res.rrd.data)?);
+  println!("{}", from_utf8_basic(&res.rrd.body)?);
   Ok(())
 }
diff --git a/wtx-instances/generic-examples/http2-server.rs b/wtx-instances/generic-examples/http2-server.rs
deleted file mode 100644
index 2c764e16..00000000
--- a/wtx-instances/generic-examples/http2-server.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-//! Serves requests using low-level HTTP/2 resources along side self-made certificates.
-
-extern crate tokio;
-extern crate wtx;
-extern crate wtx_instances;
-
-use wtx::{
-  http::{LowLevelServer, ReqResBuffer, Request, Response, StatusCode},
-  http2::{Http2Buffer, Http2Params},
-  misc::{simple_seed, TokioRustlsAcceptor, Xorshift64},
-};
-
-#[tokio::main]
-async fn main() -> wtx::Result<()> {
-  LowLevelServer::tokio_http2(
-    &wtx_instances::host_from_args(),
-    || Ok(((), Http2Buffer::new(Xorshift64::from(simple_seed())), Http2Params::default())),
-    |error| eprintln!("{error}"),
-    handle,
-    || Ok(((), ReqResBuffer::empty())),
-    (
-      || {
-        TokioRustlsAcceptor::without_client_auth()
-          .build_with_cert_chain_and_priv_key(wtx_instances::CERT, wtx_instances::KEY)
-      },
-      |acceptor| acceptor.clone(),
-      |acceptor, stream| async move { Ok(tokio::io::split(acceptor.accept(stream).await?)) },
-    ),
-  )
-  .await
-}
-
-async fn handle(
-  _: (),
-  _: (),
-  mut req: Request<ReqResBuffer>,
-) -> Result<Response<ReqResBuffer>, wtx::Error> {
-  req.rrd.clear();
-  Ok(req.into_response(StatusCode::Ok))
-}
diff --git a/wtx-instances/generic-examples/web-socket-client.rs b/wtx-instances/generic-examples/web-socket-client.rs
index 2416619e..b8952118 100644
--- a/wtx-instances/generic-examples/web-socket-client.rs
+++ b/wtx-instances/generic-examples/web-socket-client.rs
@@ -13,13 +13,12 @@ use tokio::{
 };
 use wtx::{
   misc::{simple_seed, Uri, Xorshift64},
-  web_socket::{FrameBufferVec, FrameMutVec, OpCode, WebSocketBuffer, WebSocketClient},
+  web_socket::{Frame, OpCode, WebSocketBuffer, WebSocketClient},
 };
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
   let uri = Uri::new("ws://www.example.com");
-  let fb = &mut FrameBufferVec::default();
   let mut ws = WebSocketClient::connect(
     (),
     [],
@@ -30,11 +29,11 @@ async fn main() -> wtx::Result<()> {
     |_| wtx::Result::Ok(()),
   )
   .await?;
-  let mut buffer = String::new();
+  let mut buffer = Vec::new();
   let mut reader = BufReader::new(tokio::io::stdin());
   loop {
     tokio::select! {
-      frame_rslt = ws.read_frame(fb) => {
+      frame_rslt = ws.read_frame() => {
         let frame = frame_rslt?;
         match (frame.op_code(), frame.text_payload()) {
           (_, Some(elem)) => println!("{elem}"),
@@ -42,9 +41,9 @@ async fn main() -> wtx::Result<()> {
           _ => {}
         }
       }
-      read_rslt = reader.read_line(&mut buffer) => {
+      read_rslt = reader.read_until(b'\n', &mut buffer) => {
         let _ = read_rslt?;
-        ws.write_frame(&mut FrameMutVec::new_fin(fb, OpCode::Text, buffer.as_bytes())?).await?;
+        ws.write_frame(&mut Frame::new_fin(OpCode::Text, &mut buffer)).await?;
       }
     }
   }
diff --git a/wtx-instances/generic-examples/web-socket-server.rs b/wtx-instances/generic-examples/web-socket-server.rs
index 93ea5be1..d6e6d09a 100644
--- a/wtx-instances/generic-examples/web-socket-server.rs
+++ b/wtx-instances/generic-examples/web-socket-server.rs
@@ -8,14 +8,14 @@ extern crate wtx_instances;
 use tokio::net::TcpStream;
 use tokio_rustls::server::TlsStream;
 use wtx::{
-  http::LowLevelServer,
-  misc::{TokioRustlsAcceptor, Xorshift64},
-  web_socket::{FrameBufferVec, OpCode, WebSocketBuffer, WebSocketServer},
+  http::OptionedServer,
+  misc::TokioRustlsAcceptor,
+  web_socket::{OpCode, WebSocketBuffer, WebSocketServer},
 };
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  LowLevelServer::tokio_web_socket(
+  OptionedServer::tokio_web_socket(
     &wtx_instances::host_from_args(),
     None,
     || {},
@@ -34,14 +34,14 @@ async fn main() -> wtx::Result<()> {
 }
 
 async fn handle(
-  fb: &mut FrameBufferVec,
-  mut ws: WebSocketServer<(), Xorshift64, TlsStream<TcpStream>, &mut WebSocketBuffer>,
+  mut ws: WebSocketServer<(), TlsStream<TcpStream>, &mut WebSocketBuffer>,
 ) -> wtx::Result<()> {
+  let (mut common, mut reader, mut writer) = ws.parts();
   loop {
-    let mut frame = ws.read_frame(fb).await?;
+    let mut frame = reader.read_frame(&mut common).await?;
     match frame.op_code() {
       OpCode::Binary | OpCode::Text => {
-        ws.write_frame(&mut frame).await?;
+        writer.write_frame(&mut common, &mut frame).await?;
       }
       OpCode::Close => break,
       _ => {}
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs b/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs
index 69d61dc3..713f7eec 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework-cors.rs
@@ -10,7 +10,7 @@ async fn main() -> wtx::Result<()> {
   let router = Router::new(wtx::paths!(("/hello", get(hello))), (), CorsMiddleware::permissive())?;
   ServerFrameworkBuilder::new(router)
     .without_aux()
-    .listen("0.0.0.0:9000", Xorshift64::from(simple_seed()), |error: wtx::Error| {
+    .listen_tokio("0.0.0.0:9000", Xorshift64::from(simple_seed()), |error: wtx::Error| {
       eprintln!("{error:?}")
     })
     .await?;
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs b/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs
index c0f9d009..5f4e9f9e 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework-redirect.rs
@@ -14,7 +14,7 @@ async fn main() -> wtx::Result<()> {
     Router::paths(wtx::paths!(("/permanent", get(permanent)), ("/temporary", get(temporary))))?;
   ServerFrameworkBuilder::new(router)
     .without_aux()
-    .listen(&wtx_instances::host_from_args(), Xorshift64::from(simple_seed()), |error| {
+    .listen_tokio(&wtx_instances::host_from_args(), Xorshift64::from(simple_seed()), |error| {
       eprintln!("{error}")
     })
     .await
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework-session.rs b/wtx-instances/http-server-framework-examples/http-server-framework-session.rs
index 0944875b..1e516099 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework-session.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework-session.rs
@@ -44,9 +44,6 @@ const ARGON2_PARAMS: Params = {
   };
   elem
 };
-const LOGIN: &str = "/login";
-const LOGOUT: &str = "/logout";
-
 type ConnAux = (Session, ChaCha20Rng);
 type Pool = SimplePoolTokio<PostgresRM<wtx::Error, TcpStream>>;
 type Session = SessionTokio<u32, wtx::Error, Pool>;
@@ -54,8 +51,8 @@ type Session = SessionTokio<u32, wtx::Error, Pool>;
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
   let router = Router::new(
-    wtx::paths!((LOGIN, post(login)), (LOGOUT, get(logout)),),
-    (SessionDecoder::new(), SessionEnforcer::new([LOGIN, LOGOUT])),
+    wtx::paths!(("/login", post(login)), ("/logout", get(logout)),),
+    (SessionDecoder::new(), SessionEnforcer::new(["/admin"])),
     (),
   )?;
   let pool = Pool::new(4, PostgresRM::tokio("postgres://USER:PASSWORD@localhost/DB_NAME".into()));
@@ -69,7 +66,7 @@ async fn main() -> wtx::Result<()> {
   let rng_clone = rng.clone();
   ServerFrameworkBuilder::new(router)
     .with_conn_aux(move || (session.clone(), rng_clone.clone()))
-    .listen("0.0.0.0:9000", rng, |err| eprintln!("{err:?}"))
+    .listen_tokio("0.0.0.0:9000", rng, |err| eprintln!("{err:?}"))
     .await?;
   Ok(())
 }
diff --git a/wtx-instances/http-server-framework-examples/http-server-framework.rs b/wtx-instances/http-server-framework-examples/http-server-framework.rs
index a7a9e536..f907c036 100644
--- a/wtx-instances/http-server-framework-examples/http-server-framework.rs
+++ b/wtx-instances/http-server-framework-examples/http-server-framework.rs
@@ -44,7 +44,7 @@ async fn main() -> wtx::Result<()> {
   let pool = Pool::new(4, rm);
   ServerFrameworkBuilder::new(router)
     .with_req_aux(move || pool.clone())
-    .listen(&wtx_instances::host_from_args(), Xorshift64::from(simple_seed()), |error| {
+    .listen_tokio(&wtx_instances::host_from_args(), Xorshift64::from(simple_seed()), |error| {
       eprintln!("{error:?}")
     })
     .await
@@ -68,7 +68,7 @@ async fn db(
   let mut lock = state.ra.get().await?;
   let record = lock.fetch_with_stmt("SELECT name FROM persons WHERE id = $1", (id,)).await?;
   let name = record.decode::<_, &str>(0)?;
-  state.req.rrd.data.write_fmt(format_args!("Person of id `1` has name `{name}`"))?;
+  state.req.rrd.body.write_fmt(format_args!("Person of id `1` has name `{name}`"))?;
   Ok(StatusCode::Ok)
 }
 
diff --git a/wtx-instances/generic-examples/http2-client.rs b/wtx-instances/http2-examples/http2-client.rs
similarity index 87%
rename from wtx-instances/generic-examples/http2-client.rs
rename to wtx-instances/http2-examples/http2-client.rs
index 5ff5e9ae..61abb1cc 100644
--- a/wtx-instances/generic-examples/http2-client.rs
+++ b/wtx-instances/http2-examples/http2-client.rs
@@ -26,9 +26,9 @@ async fn main() -> wtx::Result<()> {
   let rrb = ReqResBuffer::empty();
   let mut stream = http2.stream().await?;
   stream.send_req(Request::http2(Method::Get, b"Hello!"), &uri.to_ref()).await?;
-  let (res_rrb, opt) = stream.recv_res(rrb).await?;
-  let _status_code = opt.unwrap();
-  println!("{}", from_utf8_basic(&res_rrb.data)?);
+  let (_, res_rrb) = stream.recv_res(rrb).await?;
+  stream.common().clear(false).await?;
+  println!("{}", from_utf8_basic(&res_rrb.body)?);
   http2.send_go_away(Http2ErrorCode::NoError).await;
   Ok(())
 }
diff --git a/wtx-instances/http2-examples/http2-server.rs b/wtx-instances/http2-examples/http2-server.rs
new file mode 100644
index 00000000..e2375e5e
--- /dev/null
+++ b/wtx-instances/http2-examples/http2-server.rs
@@ -0,0 +1,74 @@
+//! Serves requests using low-level HTTP/2 resources along side self-made certificates.
+
+extern crate tokio;
+extern crate tokio_rustls;
+extern crate wtx;
+extern crate wtx_instances;
+
+use tokio::{io::WriteHalf, net::TcpStream};
+use tokio_rustls::server::TlsStream;
+use wtx::{
+  http::{Headers, OptionedServer, ReqResBuffer, Request, Response, StatusCode},
+  http2::{Http2Buffer, Http2Params, ServerStreamTokio, WebSocketOverStream},
+  misc::{simple_seed, TokioRustlsAcceptor, Vector, Xorshift64},
+  web_socket::{Frame, OpCode},
+};
+
+#[tokio::main]
+async fn main() -> wtx::Result<()> {
+  OptionedServer::tokio_high_http2(
+    &wtx_instances::host_from_args(),
+    auto,
+    || {
+      Ok((
+        (),
+        Http2Buffer::new(Xorshift64::from(simple_seed())),
+        Http2Params::default()
+          .set_enable_connect_protocol(true)
+          .set_max_hpack_len((128 * 1024, 128 * 1024)),
+      ))
+    },
+    |error| eprintln!("{error}"),
+    manual,
+    || Ok((Vector::new(), ReqResBuffer::empty())),
+    (
+      || {
+        TokioRustlsAcceptor::without_client_auth()
+          .http2()
+          .build_with_cert_chain_and_priv_key(wtx_instances::CERT, wtx_instances::KEY)
+      },
+      |acceptor| acceptor.clone(),
+      |acceptor, stream| async move { Ok(tokio::io::split(acceptor.accept(stream).await?)) },
+    ),
+  )
+  .await
+}
+
+async fn auto(
+  _: (),
+  _: Vector<u8>,
+  mut req: Request<ReqResBuffer>,
+) -> Result<Response<ReqResBuffer>, wtx::Error> {
+  req.rrd.clear();
+  Ok(req.into_response(StatusCode::Ok))
+}
+
+async fn manual(
+  _: (),
+  mut buffer: Vector<u8>,
+  _: Headers,
+  stream: ServerStreamTokio<Http2Buffer, WriteHalf<TlsStream<TcpStream>>, false>,
+) -> Result<(), wtx::Error> {
+  let rng = Xorshift64::from(simple_seed());
+  let mut wos = WebSocketOverStream::new(&Headers::new(), rng, stream).await?;
+  loop {
+    let mut frame = wos.read_frame(&mut buffer).await?;
+    match (frame.op_code(), frame.text_payload()) {
+      (_, Some(elem)) => println!("{elem}"),
+      (OpCode::Close, _) => break,
+      _ => {}
+    }
+    wos.write_frame(&mut Frame::new_fin(OpCode::Text, frame.payload_mut())).await?;
+  }
+  Ok(())
+}
diff --git a/wtx-instances/http2-examples/http2-web-socket.rs b/wtx-instances/http2-examples/http2-web-socket.rs
new file mode 100644
index 00000000..a8342100
--- /dev/null
+++ b/wtx-instances/http2-examples/http2-web-socket.rs
@@ -0,0 +1,62 @@
+//! Low level HTTP/2 server that only accepts one WebSocket stream for demonstration purposes.
+//!
+//! It is worth noting that the optioned server in the `http2-server` example automatically
+//! handles WebSocket connections.
+
+extern crate tokio;
+extern crate wtx;
+extern crate wtx_instances;
+
+use core::mem;
+
+use tokio::net::TcpListener;
+use wtx::{
+  http::{Headers, ReqResBuffer},
+  http2::{is_web_socket_handshake, Http2Buffer, Http2Params, Http2Tokio, WebSocketOverStream},
+  misc::{simple_seed, Either, TokioRustlsAcceptor, Vector, Xorshift64},
+  web_socket::{Frame, OpCode},
+};
+
+#[tokio::main]
+async fn main() -> wtx::Result<()> {
+  let listener = TcpListener::bind(&wtx_instances::host_from_args()).await?;
+  let mut rng = Xorshift64::from(simple_seed());
+  let (tcp_stream, _) = listener.accept().await?;
+  let acceptor = TokioRustlsAcceptor::without_client_auth()
+    .http2()
+    .build_with_cert_chain_and_priv_key(wtx_instances::CERT, wtx_instances::KEY)?;
+  let (frame_reader, mut http2) = Http2Tokio::accept(
+    Http2Buffer::new(&mut rng),
+    Http2Params::default()
+      .set_enable_connect_protocol(true)
+      .set_max_hpack_len((128 * 1024, 128 * 1024)),
+    tokio::io::split(acceptor.accept(tcp_stream).await?),
+  )
+  .await?;
+  tokio::spawn(frame_reader);
+  let (mut stream, headers_opt) = match http2
+    .stream(ReqResBuffer::empty(), |headers, method, protocol| {
+      is_web_socket_handshake(headers, method, protocol).then(|| mem::take(headers))
+    })
+    .await?
+  {
+    Either::Left(_) => return Ok(()),
+    Either::Right(elem) => elem,
+  };
+  let Some(_headers) = headers_opt else {
+    return Ok(());
+  };
+  let mut buffer = Vector::new();
+  let mut wos = WebSocketOverStream::new(&Headers::new(), rng, &mut stream).await?;
+  loop {
+    let mut frame = wos.read_frame(&mut buffer).await?;
+    match (frame.op_code(), frame.text_payload()) {
+      (_, Some(elem)) => println!("{elem}"),
+      (OpCode::Close, _) => break,
+      _ => {}
+    }
+    wos.write_frame(&mut Frame::new_fin(OpCode::Text, frame.payload_mut())).await?;
+  }
+  stream.common().clear(false).await?;
+  Ok(())
+}
diff --git a/wtx-instances/src/bin/autobahn-client.rs b/wtx-instances/src/bin/autobahn-client.rs
index fa99301e..ef2f1ec3 100644
--- a/wtx-instances/src/bin/autobahn-client.rs
+++ b/wtx-instances/src/bin/autobahn-client.rs
@@ -3,18 +3,14 @@
 use tokio::net::TcpStream;
 use wtx::{
   misc::{simple_seed, UriRef, Xorshift64},
-  web_socket::{
-    compression::Flate2, CloseCode, FrameBufferVec, FrameMutVec, OpCode, WebSocketBuffer,
-    WebSocketClient,
-  },
+  web_socket::{compression::Flate2, Frame, OpCode, WebSocketBuffer, WebSocketClient},
 };
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  let fb = &mut FrameBufferVec::default();
   let host = "127.0.0.1:9080";
   let mut wsb = WebSocketBuffer::default();
-  for case in 1..=get_case_count(fb, host, &mut wsb).await? {
+  for case in 1..=get_case_count(host, &mut wsb).await? {
     let mut ws = WebSocketClient::connect(
       Flate2::default(),
       [],
@@ -25,17 +21,17 @@ async fn main() -> wtx::Result<()> {
       |_| wtx::Result::Ok(()),
     )
     .await?;
+    let (mut common, mut reader, mut writer) = ws.parts();
     loop {
-      let mut frame = match ws.read_frame(fb).await {
-        Err(error) => {
-          eprintln!("Error: {error}");
-          ws.write_frame(&mut FrameMutVec::new_fin(fb, OpCode::Close, &[])?).await?;
+      let mut frame = match reader.read_frame(&mut common).await {
+        Err(_err) => {
+          ws.write_frame(&mut Frame::new_fin(OpCode::Close, &mut [])).await?;
           break;
         }
         Ok(elem) => elem,
       };
       match frame.op_code() {
-        OpCode::Binary | OpCode::Text => ws.write_frame(&mut frame).await?,
+        OpCode::Binary | OpCode::Text => writer.write_frame(&mut common, &mut frame).await?,
         OpCode::Close => break,
         _ => {}
       }
@@ -51,15 +47,11 @@ async fn main() -> wtx::Result<()> {
     |_| wtx::Result::Ok(()),
   )
   .await?
-  .write_frame(&mut FrameMutVec::close_from_params(CloseCode::Normal, fb, &[])?)
+  .write_frame(&mut Frame::new_fin(OpCode::Close, &mut []))
   .await
 }
 
-async fn get_case_count(
-  fb: &mut FrameBufferVec,
-  host: &str,
-  wsb: &mut WebSocketBuffer,
-) -> wtx::Result<u32> {
+async fn get_case_count(host: &str, wsb: &mut WebSocketBuffer) -> wtx::Result<u32> {
   let mut ws = WebSocketClient::connect(
     (),
     [],
@@ -70,7 +62,7 @@ async fn get_case_count(
     |_| wtx::Result::Ok(()),
   )
   .await?;
-  let rslt = ws.read_frame(fb).await?.text_payload().unwrap_or_default().parse()?;
-  ws.write_frame(&mut FrameMutVec::close_from_params(CloseCode::Normal, fb, &[])?).await?;
+  let rslt = ws.read_frame().await?.text_payload().unwrap_or_default().parse()?;
+  ws.write_frame(&mut Frame::new_fin(OpCode::Close, &mut [])).await?;
   Ok(rslt)
 }
diff --git a/wtx-instances/src/bin/autobahn-server.rs b/wtx-instances/src/bin/autobahn-server.rs
index 230289d4..02041ef8 100644
--- a/wtx-instances/src/bin/autobahn-server.rs
+++ b/wtx-instances/src/bin/autobahn-server.rs
@@ -4,17 +4,16 @@
 
 use tokio::net::TcpStream;
 use wtx::{
-  http::LowLevelServer,
-  misc::Xorshift64,
+  http::OptionedServer,
   web_socket::{
     compression::{Flate2, NegotiatedFlate2},
-    FrameBufferVec, OpCode, WebSocketBuffer, WebSocketServer,
+    OpCode, WebSocketBuffer, WebSocketServer,
   },
 };
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  LowLevelServer::tokio_web_socket(
+  OptionedServer::tokio_web_socket(
     "127.0.0.1:9070",
     None,
     Flate2::default,
@@ -26,14 +25,14 @@ async fn main() -> wtx::Result<()> {
 }
 
 async fn handle(
-  fb: &mut FrameBufferVec,
-  mut ws: WebSocketServer<Option<NegotiatedFlate2>, Xorshift64, TcpStream, &mut WebSocketBuffer>,
+  mut ws: WebSocketServer<Option<NegotiatedFlate2>, TcpStream, &mut WebSocketBuffer>,
 ) -> wtx::Result<()> {
+  let (mut common, mut reader, mut writer) = ws.parts();
   loop {
-    let mut frame = ws.read_frame(fb).await?;
+    let mut frame = reader.read_frame(&mut common).await?;
     match frame.op_code() {
       OpCode::Binary | OpCode::Text => {
-        ws.write_frame(&mut frame).await?;
+        writer.write_frame(&mut common, &mut frame).await?;
       }
       OpCode::Close => break,
       _ => {}
diff --git a/wtx-instances/src/bin/h2load.rs b/wtx-instances/src/bin/h2load.rs
new file mode 100644
index 00000000..c89e204d
--- /dev/null
+++ b/wtx-instances/src/bin/h2load.rs
@@ -0,0 +1,51 @@
+//! h2spec
+
+#![expect(clippy::print_stderr, reason = "internal")]
+
+use std::u32;
+
+use tokio::net::tcp::OwnedWriteHalf;
+use wtx::{
+  http::{Headers, OptionedServer, ReqResBuffer, Request, Response, StatusCode},
+  http2::{Http2Buffer, Http2Params, ServerStreamTokio},
+  misc::{simple_seed, Xorshift64},
+};
+
+#[tokio::main]
+async fn main() -> wtx::Result<()> {
+  OptionedServer::tokio_high_http2(
+    "127.0.0.1:9000",
+    auto,
+    || {
+      Ok((
+        (),
+        Http2Buffer::new(Xorshift64::from(simple_seed())),
+        Http2Params::default()
+          .set_max_concurrent_streams_num(u32::MAX)
+          .set_max_recv_streams_num(u32::MAX),
+      ))
+    },
+    |error| eprintln!("{error}"),
+    manual,
+    || Ok(((), ReqResBuffer::empty())),
+    (|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
+  )
+  .await
+}
+async fn auto(
+  _: (),
+  _: (),
+  mut req: Request<ReqResBuffer>,
+) -> Result<Response<ReqResBuffer>, wtx::Error> {
+  req.rrd.clear();
+  Ok(req.into_response(StatusCode::Ok))
+}
+
+async fn manual(
+  _: (),
+  _: (),
+  _: Headers,
+  _: ServerStreamTokio<Http2Buffer, OwnedWriteHalf, false>,
+) -> Result<(), wtx::Error> {
+  Ok(())
+}
diff --git a/wtx-instances/src/bin/h2spec-server.rs b/wtx-instances/src/bin/h2spec-high-server.rs
similarity index 57%
rename from wtx-instances/src/bin/h2spec-server.rs
rename to wtx-instances/src/bin/h2spec-high-server.rs
index 4f47b14d..ce8a4a86 100644
--- a/wtx-instances/src/bin/h2spec-server.rs
+++ b/wtx-instances/src/bin/h2spec-high-server.rs
@@ -2,33 +2,42 @@
 
 #![expect(clippy::print_stderr, reason = "internal")]
 
+use tokio::net::tcp::OwnedWriteHalf;
 use wtx::{
-  http::{LowLevelServer, ReqResBuffer, Request, Response, StatusCode},
-  http2::{Http2Buffer, Http2Params},
+  http::{Headers, OptionedServer, ReqResBuffer, Request, Response, StatusCode},
+  http2::{Http2Buffer, Http2Params, ServerStreamTokio},
   misc::{simple_seed, Xorshift64},
 };
 
 #[tokio::main]
 async fn main() -> wtx::Result<()> {
-  #[cfg(feature = "_tracing-tree")]
-  let _rslt = wtx::misc::tracing_tree_init(None);
-  LowLevelServer::tokio_http2(
+  OptionedServer::tokio_high_http2(
     "127.0.0.1:9000",
+    auto,
     || Ok(((), Http2Buffer::new(Xorshift64::from(simple_seed())), Http2Params::default())),
     |error| eprintln!("{error}"),
-    handle,
+    manual,
     || Ok(((), ReqResBuffer::empty())),
     (|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
   )
   .await
 }
 
-async fn handle(
+async fn auto(
   _: (),
   _: (),
   mut req: Request<ReqResBuffer>,
 ) -> Result<Response<ReqResBuffer>, wtx::Error> {
   req.rrd.clear();
-  req.rrd.data.extend_from_slice(b"Hello")?;
+  req.rrd.body.extend_from_copyable_slice(b"Hello")?;
   Ok(req.into_response(StatusCode::Ok))
 }
+
+async fn manual(
+  _: (),
+  _: (),
+  _: Headers,
+  _: ServerStreamTokio<Http2Buffer, OwnedWriteHalf, false>,
+) -> Result<(), wtx::Error> {
+  Ok(())
+}
diff --git a/wtx-instances/src/bin/h2spec-low-server.rs b/wtx-instances/src/bin/h2spec-low-server.rs
new file mode 100644
index 00000000..cbc9c158
--- /dev/null
+++ b/wtx-instances/src/bin/h2spec-low-server.rs
@@ -0,0 +1,65 @@
+//! h2spec
+
+#![expect(clippy::print_stderr, reason = "internal")]
+
+use std::mem;
+
+use tokio::net::TcpListener;
+use wtx::{
+  http::{ReqResBuffer, StatusCode},
+  http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2RecvStatus, Http2Tokio, SendDataMode},
+  misc::{simple_seed, Either, Xorshift64},
+};
+
+#[tokio::main]
+async fn main() -> wtx::Result<()> {
+  let listener = TcpListener::bind("127.0.0.1:9000").await?;
+  loop {
+    let (tcp_stream, _) = listener.accept().await?;
+    let _conn_jh = tokio::spawn(async move {
+      let fun = async {
+        let http2_params = Http2Params::default();
+        let http2_buffer = Http2Buffer::new(Xorshift64::from(simple_seed()));
+        let tuple = Http2Tokio::accept(http2_buffer, http2_params, tcp_stream.into_split()).await?;
+        let (frame_reader, mut http2) = tuple;
+        let _jh = tokio::spawn(frame_reader);
+        loop {
+          let (mut http2_stream, headers) = match http2
+            .stream(ReqResBuffer::default(), |headers, _, _| mem::take(headers))
+            .await?
+          {
+            Either::Left(_) => return wtx::Result::Ok(()),
+            Either::Right(elem) => elem,
+          };
+          let _stream_jh = tokio::spawn(async move {
+            let mut common = http2_stream.common();
+            let fun = async {
+              loop {
+                let hrs = common.recv_data().await?;
+                match hrs {
+                  Http2RecvStatus::ClosedConnection | Http2RecvStatus::ClosedStream => {
+                    return Ok(())
+                  }
+                  Http2RecvStatus::Eos(_) => break,
+                  Http2RecvStatus::Ongoing(_) => continue,
+                }
+              }
+              let _ = common.recv_trailers().await?;
+              let _ = common.send_headers(&headers, false, StatusCode::Ok).await?;
+              let _ = common.send_data(SendDataMode::scattered_data_frames(b"Hello"), true).await?;
+              common.clear(true).await?;
+              wtx::Result::Ok(())
+            };
+            if let Err(err) = fun.await {
+              http2_stream.common().send_go_away(Http2ErrorCode::InternalError).await;
+              eprint!("{err}");
+            }
+          });
+        }
+      };
+      if let Err(err) = fun.await {
+        eprint!("{err}");
+      }
+    });
+  }
+}
diff --git a/wtx-ui/Cargo.toml b/wtx-ui/Cargo.toml
index 4ddd5cce..0feaa5f4 100644
--- a/wtx-ui/Cargo.toml
+++ b/wtx-ui/Cargo.toml
@@ -15,6 +15,8 @@ schema-manager-dev = ["dotenv", "schema-manager", "wtx/_tracing-tree", "wtx/sche
 unified = []
 web-socket = ["clap", "wtx/web-socket-handshake"]
 
+_curl = []
+
 [package]
 authors = ["Caio Fernandes <c410.f3r@gmail.com>"]
 categories = ["asynchronous", "command-line-interface", "gui"]
diff --git a/wtx-ui/src/clap.rs b/wtx-ui/src/clap.rs
index 56261fbb..49f3e9bc 100644
--- a/wtx-ui/src/clap.rs
+++ b/wtx-ui/src/clap.rs
@@ -65,7 +65,14 @@ struct Cli {
 /// Command-line interface for different web transport implementations
 #[derive(Debug, clap::Parser)]
 #[cfg(not(feature = "unified"))]
-#[command(author, long_about = None, name = "wtx", version)]
+#[cfg_attr(
+  feature = "_curl",
+  command(
+    name = "curl",
+    version = "8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0\nProtocols: http\nFeatures: HTTP2"
+  )
+)]
+#[cfg_attr(not(feature = "_curl"), command(author, long_about = None, name = "wtx", version))]
 struct Cli {
   #[cfg(all(
     feature = "embed-migrations",
diff --git a/wtx-ui/src/http_client.rs b/wtx-ui/src/http_client.rs
index b4e33942..e31e9c62 100644
--- a/wtx-ui/src/http_client.rs
+++ b/wtx-ui/src/http_client.rs
@@ -38,7 +38,7 @@ pub(crate) async fn http_client(http_client: HttpClient) {
       .unwrap();
   }
   if let Some(elem) = data {
-    rrb.data.extend_from_slice(elem.as_bytes()).unwrap();
+    rrb.body.extend_from_copyable_slice(elem.as_bytes()).unwrap();
   }
   let res = ReqBuilder::new(method, rrb).send(&client, &Uri::new(uri).to_ref()).await.unwrap();
   if let Some(elem) = output {
@@ -48,9 +48,9 @@ pub(crate) async fn http_client(http_client: HttpClient) {
       .write(true)
       .open(elem)
       .unwrap()
-      .write_all(&res.rrd.data)
+      .write_all(&res.rrd.body)
       .unwrap();
   } else {
-    println!("{}", from_utf8_basic(&res.rrd.data).unwrap());
+    println!("{}", from_utf8_basic(&res.rrd.body).unwrap());
   }
 }
diff --git a/wtx-ui/src/web_socket.rs b/wtx-ui/src/web_socket.rs
index 1cfddf71..b31374ae 100644
--- a/wtx-ui/src/web_socket.rs
+++ b/wtx-ui/src/web_socket.rs
@@ -4,14 +4,11 @@ use tokio::{
 };
 use wtx::{
   misc::{simple_seed, UriRef, Xorshift64},
-  web_socket::{
-    FrameBufferVec, FrameMutVec, OpCode, WebSocketBuffer, WebSocketClient, WebSocketServer,
-  },
+  web_socket::{Frame, OpCode, WebSocketBuffer, WebSocketClient, WebSocketServer},
 };
 
 pub(crate) async fn connect(uri: &str, cb: impl Fn(&str)) -> wtx::Result<()> {
   let uri = UriRef::new(uri);
-  let fb = &mut FrameBufferVec::default();
   let wsb = &mut WebSocketBuffer::default();
   let mut ws = WebSocketClient::connect(
     (),
@@ -23,11 +20,11 @@ pub(crate) async fn connect(uri: &str, cb: impl Fn(&str)) -> wtx::Result<()> {
     |_| wtx::Result::Ok(()),
   )
   .await?;
-  let mut buffer = String::new();
+  let mut buffer = Vec::new();
   let mut reader = BufReader::new(tokio::io::stdin());
   loop {
     tokio::select! {
-      frame_rslt = ws.read_frame(fb) => {
+      frame_rslt = ws.read_frame() => {
         let frame = frame_rslt?;
         match (frame.op_code(), frame.text_payload()) {
           (_, Some(elem)) => cb(elem),
@@ -35,9 +32,9 @@ pub(crate) async fn connect(uri: &str, cb: impl Fn(&str)) -> wtx::Result<()> {
           _ => {}
         }
       }
-      read_rslt = reader.read_line(&mut buffer) => {
+      read_rslt = reader.read_until(b'\n', &mut buffer) => {
         let _ = read_rslt?;
-        ws.write_frame(&mut FrameMutVec::new_fin(fb, OpCode::Text, buffer.as_bytes())?).await?;
+        ws.write_frame(&mut Frame::new_fin(OpCode::Text, &mut buffer)).await?;
       }
     }
   }
@@ -55,7 +52,7 @@ pub(crate) async fn serve(
   loop {
     let (stream, _) = listener.accept().await?;
     let _jh = tokio::spawn(async move {
-      let sun = || async move {
+      let fun = async move {
         let mut ws = WebSocketServer::accept(
           (),
           Xorshift64::from(simple_seed()),
@@ -64,19 +61,18 @@ pub(crate) async fn serve(
           |_| wtx::Result::Ok(()),
         )
         .await?;
-        let mut fb = FrameBufferVec::default();
         loop {
-          let frame = ws.read_frame(&mut fb).await?;
+          let frame = ws.read_frame().await?;
           match (frame.op_code(), frame.text_payload()) {
             (_, Some(elem)) => str(elem),
-            (OpCode::Binary, _) => binary(frame.fb().payload()),
+            (OpCode::Binary, _) => binary(frame.payload()),
             (OpCode::Close, _) => break,
             _ => {}
           }
         }
         wtx::Result::Ok(())
       };
-      if let Err(err) = sun().await {
+      if let Err(err) = fun.await {
         error(err);
       }
     });
diff --git a/wtx/Cargo.toml b/wtx/Cargo.toml
index b99b2a1b..a26e2900 100644
--- a/wtx/Cargo.toml
+++ b/wtx/Cargo.toml
@@ -3,7 +3,7 @@ aes-gcm = { default-features = false, optional = true, version = "0.10" }
 arbitrary = { default-features = false, features = ["derive_arbitrary"], optional = true, version = "1.0" }
 argon2 = { default-features = false, optional = true, version = "0.5" }
 base64 = { default-features = false, features = ["alloc"], optional = true, version = "0.22" }
-borsh = { default-features = false, features = ["derive", "std"], optional = true, version = "1.0" }
+borsh = { default-features = false, features = ["derive"], optional = true, version = "1.0" }
 chrono = { default-features = false, optional = true, version = "0.4" }
 cl-aux = { default-features = false, optional = true, features = ["alloc"], version = "5.0" }
 crypto-common = { default-features = false, optional = true, version = "0.1" }
@@ -22,8 +22,8 @@ rand_chacha = { default-features = false, optional = true, version = "0.3" }
 rand_core = { default-features = false, optional = true, version = "0.6" }
 ring = { default-features = false, optional = true, version = "0.17" }
 rust_decimal = { default-features = false, features = ["maths"], optional = true, version = "1.0" }
-rustls-pemfile = { default-features = false, features = ["std"], optional = true, version = "2.0" }
-rustls-pki-types = { default-features = false, optional = true, version = "1.10" }
+rustls-pemfile = { default-features = false, optional = true, version = "2.0" }
+rustls-pki-types = { default-features = false, optional = true, version = "1.0" }
 serde = { default-features = false, features = ["alloc", "derive"], optional = true, version = "1.0" }
 serde_json = { default-features = false, features = ["alloc"], optional = true, version = "1.0" }
 sha1 = { default-features = false, optional = true, version = "0.10" }
@@ -50,6 +50,7 @@ data-transformation = []
 database = []
 default = []
 digest = ["dep:digest"]
+executor = []
 fastrand = ["dep:fastrand"]
 flate2 = ["dep:flate2"]
 foldhash = ["dep:foldhash", "hashbrown?/default-hasher"]
@@ -65,7 +66,8 @@ http-session = ["chrono/serde", "http-cookie-secure", "serde_json"]
 http2 = ["foldhash", "hashbrown", "http"]
 httparse = ["dep:httparse"]
 memchr = ["dep:memchr"]
-optimization = ["memchr", "simdutf8"]
+nightly = ["hashbrown?/nightly"]
+optimization = ["memchr", "rand_chacha?/simd", "simdutf8"]
 pool = []
 postgres = ["base64", "crypto-common", "database", "digest", "foldhash", "hashbrown", "hmac", "sha2"]
 proptest = ["dep:proptest"]
@@ -80,7 +82,7 @@ serde_json = ["serde", "dep:serde_json", "std"]
 sha1 = ["dep:sha1"]
 sha2 = ["dep:sha2"]
 simdutf8 = ["dep:simdutf8"]
-std = ["cl-aux?/std", "foldhash?/std", "memchr?/std", "serde?/std", "serde_json?/std", "simdutf8?/std"]
+std = ["aes-gcm?/std", "argon2?/std", "base64?/std", "borsh?/std", "chrono?/std", "cl-aux?/std", "crypto-common?/std", "digest?/std", "fastrand?/std", "foldhash?/std", "hmac?/std", "httparse?/std", "memchr?/std", "proptest?/std", "quick-protobuf?/std", "rand_chacha?/std", "rand_core?/std", "ring?/std", "rust_decimal?/std", "rustls-pemfile?/std", "rustls-pki-types?/std", "serde?/std", "serde_json?/std", "sha1?/std", "sha2?/std", "simdutf8?/std", "tracing?/std", "tracing-subscriber?/std"]
 test-strategy = ["dep:test-strategy", "proptest", "std"]
 tokio = ["std", "dep:tokio"]
 tokio-rustls = ["ring", "dep:rustls-pemfile", "dep:rustls-pki-types", "tokio", "dep:tokio-rustls"]
diff --git a/wtx/src/client_api_framework/network/transport.rs b/wtx/src/client_api_framework/network/transport.rs
index f8577eba..de4014a7 100644
--- a/wtx/src/client_api_framework/network/transport.rs
+++ b/wtx/src/client_api_framework/network/transport.rs
@@ -199,7 +199,7 @@ mod tests {
   impl<DRSR> Serialize<DRSR> for _Ping {
     #[inline]
     fn to_bytes(&mut self, bytes: &mut Vector<u8>, _: &mut DRSR) -> crate::Result<()> {
-      bytes.extend_from_slice(b"ping")?;
+      bytes.extend_from_copyable_slice(b"ping")?;
       Ok(())
     }
   }
diff --git a/wtx/src/client_api_framework/network/transport/mock.rs b/wtx/src/client_api_framework/network/transport/mock.rs
index 6e4a92a5..da3add93 100644
--- a/wtx/src/client_api_framework/network/transport/mock.rs
+++ b/wtx/src/client_api_framework/network/transport/mock.rs
@@ -131,7 +131,7 @@ where
     <Self as Transport<DRSR>>::send(self, pkg, pkgs_aux).await?;
     let response = self.pop_response()?;
     pkgs_aux.byte_buffer.clear();
-    pkgs_aux.byte_buffer.extend_from_slice(response.lease()).map_err(Into::into)?;
+    pkgs_aux.byte_buffer.extend_from_copyable_slice(response.lease()).map_err(Into::into)?;
     Ok(0..pkgs_aux.byte_buffer.len())
   }
 }
diff --git a/wtx/src/client_api_framework/network/transport/std.rs b/wtx/src/client_api_framework/network/transport/std.rs
index 3c37bdeb..59453f77 100644
--- a/wtx/src/client_api_framework/network/transport/std.rs
+++ b/wtx/src/client_api_framework/network/transport/std.rs
@@ -142,7 +142,7 @@ where
   Ok(0..len)
 }
 
-#[cfg(test)]
+#[cfg(all(feature = "_async-tests", test))]
 mod tests {
   use crate::{
     client_api_framework::{
diff --git a/wtx/src/client_api_framework/network/transport/wtx_http.rs b/wtx/src/client_api_framework/network/transport/wtx_http.rs
index 8707dc5f..a3029c6e 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_http.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_http.rs
@@ -18,7 +18,7 @@ use core::{mem, ops::Range};
 impl<DRSR, HD, RL, RM, SW> Transport<DRSR> for ClientFramework<RL, RM>
 where
   HD: RefCounter + 'static,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer<ReqResBuffer>, ReqResBuffer, SW, true>>,
+  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
   RM: ResourceManager<
     CreateAux = str,
@@ -65,7 +65,7 @@ where
 impl<DRSR, HD, RL, RM, SW> Transport<DRSR> for &ClientFramework<RL, RM>
 where
   HD: RefCounter + 'static,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer<ReqResBuffer>, ReqResBuffer, SW, true>>,
+  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
   RM: ResourceManager<
     CreateAux = str,
@@ -118,7 +118,7 @@ where
   A: Api,
   P: Package<A, DRSR, HttpParams>,
   HD: RefCounter + 'static,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer<ReqResBuffer>, ReqResBuffer, SW, true>>,
+  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
   RM: ResourceManager<
     CreateAux = str,
@@ -147,10 +147,10 @@ where
     ))?;
   }
   let mut rrb = ReqResBuffer::empty();
-  mem::swap(&mut rrb.data, &mut pkgs_aux.byte_buffer);
+  mem::swap(&mut rrb.body, &mut pkgs_aux.byte_buffer);
   mem::swap(&mut rrb.headers, headers);
   let mut res = (*client).send(*method, rrb, &uri.to_ref()).await?;
-  mem::swap(&mut pkgs_aux.byte_buffer, &mut res.rrd.data);
+  mem::swap(&mut pkgs_aux.byte_buffer, &mut res.rrd.body);
   mem::swap(headers, &mut res.rrd.headers);
   pkgs_aux.tp.ext_res_params_mut().status_code = res.status_code;
   manage_after_sending_related(pkg, pkgs_aux).await?;
diff --git a/wtx/src/client_api_framework/network/transport/wtx_ws.rs b/wtx/src/client_api_framework/network/transport/wtx_ws.rs
index 0e144a94..4922da6e 100644
--- a/wtx/src/client_api_framework/network/transport/wtx_ws.rs
+++ b/wtx/src/client_api_framework/network/transport/wtx_ws.rs
@@ -8,18 +8,16 @@ use crate::{
     pkg::{Package, PkgsAux},
     Api, ClientApiFrameworkError,
   },
-  misc::{LeaseMut, Rng, Stream},
+  misc::{LeaseMut, Stream},
   web_socket::{
-    compression::NegotiatedCompression, FrameBufferVec, FrameBufferVecMut, FrameMutVec, OpCode,
-    WebSocketBuffer, WebSocketClient,
+    compression::NegotiatedCompression, Frame, OpCode, WebSocketBuffer, WebSocketClient,
   },
 };
 use core::ops::Range;
 
-impl<DRSR, NC, RNG, S, WSB> Transport<DRSR> for (FrameBufferVec, WebSocketClient<NC, RNG, S, WSB>)
+impl<DRSR, NC, S, WSB> Transport<DRSR> for WebSocketClient<NC, S, WSB>
 where
   NC: NegotiatedCompression,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
@@ -36,7 +34,7 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Params>,
   {
-    send(&mut self.0, pkg, pkgs_aux, &mut self.1).await
+    send(pkg, pkgs_aux, self).await
   }
 
   #[inline]
@@ -49,14 +47,13 @@ where
     A: Api,
     P: Package<A, DRSR, Self::Params>,
   {
-    send_recv(&mut self.0, pkg, pkgs_aux, &mut self.1).await
+    send_recv(pkg, pkgs_aux, self).await
   }
 }
 
-impl<DRSR, NC, RNG, S, WSB> BiTransport<DRSR> for (FrameBufferVec, WebSocketClient<NC, RNG, S, WSB>)
+impl<DRSR, NC, S, WSB> BiTransport<DRSR> for WebSocketClient<NC, S, WSB>
 where
   NC: NegotiatedCompression,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
@@ -68,137 +65,71 @@ where
   where
     A: Api,
   {
-    retrieve(pkgs_aux, &mut self.1).await
+    retrieve(pkgs_aux, self).await
   }
 }
 
-impl<DRSR, NC, RNG, S, WSB> Transport<DRSR>
-  for (&mut FrameBufferVec, &mut WebSocketClient<NC, RNG, S, WSB>)
-where
-  NC: NegotiatedCompression,
-  RNG: Rng,
-  S: Stream,
-  WSB: LeaseMut<WebSocketBuffer>,
-{
-  const GROUP: TransportGroup = TransportGroup::WebSocket;
-  type Params = WsParams;
-
-  #[inline]
-  async fn send<A, P>(
-    &mut self,
-    pkg: &mut P,
-    pkgs_aux: &mut PkgsAux<A, DRSR, Self::Params>,
-  ) -> Result<(), A::Error>
-  where
-    A: Api,
-    P: Package<A, DRSR, Self::Params>,
-  {
-    send(self.0, pkg, pkgs_aux, self.1).await
-  }
-
-  #[inline]
-  async fn send_recv<A, P>(
-    &mut self,
-    pkg: &mut P,
-    pkgs_aux: &mut PkgsAux<A, DRSR, Self::Params>,
-  ) -> Result<Range<usize>, A::Error>
-  where
-    A: Api,
-    P: Package<A, DRSR, Self::Params>,
-  {
-    send_recv(self.0, pkg, pkgs_aux, self.1).await
-  }
-}
-
-impl<DRSR, NC, RNG, S, WSB> BiTransport<DRSR>
-  for (&mut FrameBufferVec, &mut WebSocketClient<NC, RNG, S, WSB>)
-where
-  NC: NegotiatedCompression,
-  RNG: Rng,
-  S: Stream,
-  WSB: LeaseMut<WebSocketBuffer>,
-{
-  #[inline]
-  async fn retrieve<A>(
-    &mut self,
-    pkgs_aux: &mut PkgsAux<A, DRSR, Self::Params>,
-  ) -> crate::Result<Range<usize>>
-  where
-    A: Api,
-  {
-    retrieve(pkgs_aux, self.1).await
-  }
-}
-
-async fn retrieve<A, DRSR, NC, RNG, S, WSB>(
+async fn retrieve<A, DRSR, NC, S, WSB>(
   pkgs_aux: &mut PkgsAux<A, DRSR, WsParams>,
-  ws: &mut WebSocketClient<NC, RNG, S, WSB>,
+  ws: &mut WebSocketClient<NC, S, WSB>,
 ) -> crate::Result<Range<usize>>
 where
   NC: NegotiatedCompression,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
   pkgs_aux.byte_buffer.clear();
-  let fb = &mut FrameBufferVecMut::from(&mut pkgs_aux.byte_buffer);
-  let frame = ws.read_frame(fb).await?;
+  let frame = ws.read_frame().await?;
   if let OpCode::Close = frame.op_code() {
     return Err(ClientApiFrameworkError::ClosedWsConnection.into());
   }
-  let indcs = frame.fb().indcs();
-  Ok(indcs.1.into()..indcs.2)
+  pkgs_aux.byte_buffer.extend_from_copyable_slice(frame.payload())?;
+  Ok(0..pkgs_aux.byte_buffer.len())
 }
 
-async fn send<A, DRSR, NC, P, RNG, S, WSB>(
-  fb: &mut FrameBufferVec,
+async fn send<A, DRSR, NC, P, S, WSB>(
   pkg: &mut P,
   pkgs_aux: &mut PkgsAux<A, DRSR, WsParams>,
-  ws: &mut WebSocketClient<NC, RNG, S, WSB>,
+  ws: &mut WebSocketClient<NC, S, WSB>,
 ) -> Result<(), A::Error>
 where
   A: Api,
   NC: NegotiatedCompression,
   P: Package<A, DRSR, WsParams>,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
-  let mut trans = (fb, ws);
   pkgs_aux.byte_buffer.clear();
-  manage_before_sending_related(pkg, pkgs_aux, &mut trans).await?;
+  manage_before_sending_related(pkg, pkgs_aux, &mut *ws).await?;
   let op_code = match pkgs_aux.tp.ext_req_params_mut().ty {
     WsReqParamsTy::Bytes => OpCode::Binary,
     WsReqParamsTy::String => OpCode::Text,
   };
-  let frame_rslt = FrameMutVec::new_fin(trans.0, op_code, &pkgs_aux.byte_buffer);
-  trans.1.write_frame(&mut frame_rslt.map_err(Into::into)?).await.map_err(Into::into)?;
+  let mut frame = Frame::new_fin(op_code, &mut pkgs_aux.byte_buffer);
+  ws.write_frame(&mut frame).await.map_err(Into::into)?;
   pkgs_aux.byte_buffer.clear();
   manage_after_sending_related(pkg, pkgs_aux).await?;
   pkgs_aux.tp.reset();
   Ok(())
 }
 
-async fn send_recv<A, DRSR, NC, P, RNG, S, WSB>(
-  fb: &mut FrameBufferVec,
+async fn send_recv<A, DRSR, NC, P, S, WSB>(
   pkg: &mut P,
   pkgs_aux: &mut PkgsAux<A, DRSR, WsParams>,
-  ws: &mut WebSocketClient<NC, RNG, S, WSB>,
+  ws: &mut WebSocketClient<NC, S, WSB>,
 ) -> Result<Range<usize>, A::Error>
 where
   A: Api,
   NC: NegotiatedCompression,
   P: Package<A, DRSR, WsParams>,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
-  send(fb, pkg, pkgs_aux, ws).await?;
-  let fb = &mut FrameBufferVecMut::from(&mut pkgs_aux.byte_buffer);
-  let frame = ws.read_frame(fb).await.map_err(Into::into)?;
+  send(pkg, pkgs_aux, ws).await?;
+  let frame = ws.read_frame().await.map_err(Into::into)?;
   if let OpCode::Close = frame.op_code() {
     return Err(A::Error::from(ClientApiFrameworkError::ClosedWsConnection.into()));
   }
-  let indcs = frame.fb().indcs();
-  Ok(indcs.1.into()..indcs.2)
+  pkgs_aux.byte_buffer.extend_from_copyable_slice(frame.payload()).map_err(Into::into)?;
+  Ok(0..pkgs_aux.byte_buffer.len())
 }
diff --git a/wtx/src/data_transformation/format/misc.rs b/wtx/src/data_transformation/format/misc.rs
index 0a3300cf..06280a90 100644
--- a/wtx/src/data_transformation/format/misc.rs
+++ b/wtx/src/data_transformation/format/misc.rs
@@ -36,10 +36,10 @@ mod serde_json {
         A: SeqAccess<'de>,
       {
         if let Some(elem) = seq.size_hint() {
-          self.0.reserve(elem).map_err(|err| A::Error::custom(err))?;
+          self.0.reserve(elem).map_err(A::Error::custom)?;
         }
         while let Some(elem) = seq.next_element()? {
-          self.0.push(elem).map_err(|err| A::Error::custom(err))?;
+          self.0.push(elem).map_err(A::Error::custom)?;
         }
         Ok(())
       }
diff --git a/wtx/src/database/client/postgres.rs b/wtx/src/database/client/postgres.rs
index 45af8620..cf7cd758 100644
--- a/wtx/src/database/client/postgres.rs
+++ b/wtx/src/database/client/postgres.rs
@@ -25,7 +25,6 @@ mod ty;
 mod tys;
 
 use crate::database::{Database, DatabaseTy};
-pub(crate) use authentication::Authentication;
 pub use config::Config;
 use core::marker::PhantomData;
 pub use db_error::{DbError, ErrorPosition, Severity};
@@ -33,10 +32,7 @@ pub use decode_value::DecodeValue;
 pub use encode_value::EncodeValue;
 pub use executor::Executor;
 pub use executor_buffer::ExecutorBuffer;
-pub(crate) use message::MessageTy;
-pub(crate) use msg_field::MsgField;
 pub use postgres_error::PostgresError;
-pub(crate) use protocol::*;
 pub use record::Record;
 pub use records::Records;
 pub use sql_state::SqlState;
diff --git a/wtx/src/database/client/postgres/executor.rs b/wtx/src/database/client/postgres/executor.rs
index 59998baa..1dab7b06 100644
--- a/wtx/src/database/client/postgres/executor.rs
+++ b/wtx/src/database/client/postgres/executor.rs
@@ -7,11 +7,11 @@ mod simple_query;
 use crate::{
   database::{
     client::postgres::{
-      encrypted_conn,
       executor::commons::FetchWithStmtCommons,
       executor_buffer::{ExecutorBuffer, ExecutorBufferPartsMut},
-      initial_conn_msg, Config, MessageTy, Postgres, PostgresError, Record, Records,
-      TransactionManager,
+      message::MessageTy,
+      protocol::{encrypted_conn, initial_conn_msg},
+      Config, Postgres, PostgresError, Record, Records, TransactionManager,
     },
     Database, RecordValues, StmtCmd, TransactionManager as _,
   },
diff --git a/wtx/src/database/client/postgres/executor/authentication.rs b/wtx/src/database/client/postgres/executor/authentication.rs
index 59b78d9a..85123c7e 100644
--- a/wtx/src/database/client/postgres/executor/authentication.rs
+++ b/wtx/src/database/client/postgres/executor/authentication.rs
@@ -1,9 +1,12 @@
 use crate::{
   database::{
     client::postgres::{
+      authentication::Authentication,
       config::ChannelBinding,
       executor_buffer::{ExecutorBuffer, ExecutorBufferPartsMut},
-      sasl_first, sasl_second, Authentication, Config, Executor, MessageTy, PostgresError,
+      message::MessageTy,
+      protocol::{sasl_first, sasl_second},
+      Config, Executor, PostgresError,
     },
     Identifier,
   },
@@ -107,7 +110,7 @@ where
   }
 
   pub(crate) async fn read_after_authentication_data(&mut self) -> crate::Result<()> {
-    self.eb.lease_mut().nb._expand_buffer(2048)?;
+    self.eb.lease_mut().nb._reserve(2048)?;
     loop {
       let ExecutorBufferPartsMut { conn_params, nb, .. } = self.eb.lease_mut().parts_mut();
       let msg = Self::fetch_msg_from_stream(&mut self.cs, nb, &mut self.stream).await?;
@@ -143,7 +146,7 @@ where
   {
     let tsep_data = tls_server_end_point.unwrap_or_default();
     let local_nonce = nonce(rng);
-    nb._expand_buffer(2048)?;
+    nb._reserve(2048)?;
     {
       let mut fbw = FilledBufferWriter::from(&mut *nb);
       sasl_first(&mut fbw, (method_bytes, method_header), &local_nonce)?;
@@ -166,7 +169,8 @@ where
       (
         {
           let mut vec = Vector::with_capacity(64)?;
-          let _ = vec.extend_from_slices([&b"n=,r="[..], &local_nonce, &b","[..], payload])?;
+          let _ =
+            vec.extend_from_copyable_slices([&b"n=,r="[..], &local_nonce, &b","[..], payload])?;
           vec
         },
         ArrayVector::<u8, 68>::from_copyable_slice(nonce)?,
diff --git a/wtx/src/database/client/postgres/executor/fetch.rs b/wtx/src/database/client/postgres/executor/fetch.rs
index 756741ed..3b7d1684 100644
--- a/wtx/src/database/client/postgres/executor/fetch.rs
+++ b/wtx/src/database/client/postgres/executor/fetch.rs
@@ -1,8 +1,10 @@
 use crate::{
   database::{
     client::postgres::{
-      executor::commons::FetchWithStmtCommons, message::Message, statements::Statement, Executor,
-      ExecutorBuffer, MessageTy, Postgres, PostgresError, Record,
+      executor::commons::FetchWithStmtCommons,
+      message::{Message, MessageTy},
+      statements::Statement,
+      Executor, ExecutorBuffer, Postgres, PostgresError, Record,
     },
     RecordValues,
   },
@@ -68,7 +70,7 @@ where
     read: &mut usize,
     stream: &mut S,
   ) -> crate::Result<(u8, usize)> {
-    let buffer = nb._following_trail_mut();
+    let buffer = nb._following_rest_mut();
     let [mt_n, b, c, d, e] = _read_until::<5, S>(buffer, read, 0, stream).await?;
     let len: usize = u32::from_be_bytes([b, c, d, e]).try_into()?;
     Ok((mt_n, len.wrapping_add(1)))
@@ -93,14 +95,14 @@ where
     stream: &mut S,
   ) -> crate::Result<()> {
     let mut is_payload_filled = false;
-    nb._expand_buffer(len)?;
+    nb._reserve(len)?;
     for _ in 0..=len {
       if *read >= len {
         is_payload_filled = true;
         break;
       }
       *read = read.wrapping_add(
-        stream.read(nb._following_trail_mut().get_mut(*read..).unwrap_or_default()).await?,
+        stream.read(nb._following_rest_mut().get_mut(*read..).unwrap_or_default()).await?,
       );
     }
     if !is_payload_filled {
diff --git a/wtx/src/database/client/postgres/executor/prepare.rs b/wtx/src/database/client/postgres/executor/prepare.rs
index 17fb87e7..87822750 100644
--- a/wtx/src/database/client/postgres/executor/prepare.rs
+++ b/wtx/src/database/client/postgres/executor/prepare.rs
@@ -1,14 +1,14 @@
 use crate::{
   database::{
     client::postgres::{
-      bind, describe, execute,
       executor::commons::FetchWithStmtCommons,
       executor_buffer::ExecutorBuffer,
-      parse,
+      message::MessageTy,
+      msg_field::MsgField,
+      protocol::{bind, describe, execute, parse, sync},
       statements::{Column, PushRslt, Statement},
-      sync,
       ty::Ty,
-      Executor, MessageTy, MsgField, Postgres, PostgresError, Statements,
+      Executor, Postgres, PostgresError, Statements,
     },
     RecordValues, StmtCmd,
   },
diff --git a/wtx/src/database/client/postgres/executor/simple_query.rs b/wtx/src/database/client/postgres/executor/simple_query.rs
index 0db5b185..edbb25d6 100644
--- a/wtx/src/database/client/postgres/executor/simple_query.rs
+++ b/wtx/src/database/client/postgres/executor/simple_query.rs
@@ -1,7 +1,7 @@
 use crate::{
   database::client::postgres::{
-    executor_buffer::ExecutorBufferPartsMut, query, Executor, ExecutorBuffer, MessageTy,
-    PostgresError,
+    executor_buffer::ExecutorBufferPartsMut, message::MessageTy, protocol::query, Executor,
+    ExecutorBuffer, PostgresError,
   },
   misc::{FilledBufferWriter, LeaseMut, Stream},
 };
diff --git a/wtx/src/database/client/postgres/message.rs b/wtx/src/database/client/postgres/message.rs
index 0450db94..3f95e629 100644
--- a/wtx/src/database/client/postgres/message.rs
+++ b/wtx/src/database/client/postgres/message.rs
@@ -1,5 +1,5 @@
 use crate::{
-  database::client::postgres::{Authentication, DbError, PostgresError},
+  database::client::postgres::{authentication::Authentication, DbError, PostgresError},
   misc::{bytes_rsplit1, bytes_split1, from_utf8_basic, ConnectionState, FromRadix10},
 };
 use core::any::type_name;
diff --git a/wtx/src/database/client/postgres/protocol.rs b/wtx/src/database/client/postgres/protocol.rs
index 36b06c1d..b185a1f1 100644
--- a/wtx/src/database/client/postgres/protocol.rs
+++ b/wtx/src/database/client/postgres/protocol.rs
@@ -196,7 +196,7 @@ pub(crate) fn sasl_second(
     local_fbw._extend_from_slices([b",r=", response_nonce])?;
 
     let local_bytes = local_fbw._curr_bytes().get(5..).unwrap_or_default();
-    let _ = auth_data.extend_from_slices([&b","[..], local_bytes])?;
+    let _ = auth_data.extend_from_copyable_slices([&b","[..], local_bytes])?;
 
     let client_key: [u8; 32] = {
       let mut mac = Hmac::<Sha256>::new_from_slice(salted_password)?;
diff --git a/wtx/src/database/client/postgres/tys.rs b/wtx/src/database/client/postgres/tys.rs
index 3edecf6a..cd773348 100644
--- a/wtx/src/database/client/postgres/tys.rs
+++ b/wtx/src/database/client/postgres/tys.rs
@@ -1,7 +1,6 @@
 macro_rules! proptest {
   ($name:ident, $ty:ty) => {
-    #[cfg(feature = "_proptest")]
-    #[cfg(test)]
+    #[cfg(all(feature = "_proptest", test))]
     #[test_strategy::proptest]
     fn $name(instance: $ty) {
       let mut vec = &mut crate::misc::FilledBuffer::_new();
diff --git a/wtx/src/database/schema_manager/migration.rs b/wtx/src/database/schema_manager/migration.rs
index 09489ec1..3c744560 100644
--- a/wtx/src/database/schema_manager/migration.rs
+++ b/wtx/src/database/schema_manager/migration.rs
@@ -4,6 +4,5 @@ mod migration_group;
 mod user_migration;
 
 pub use db_migration::*;
-pub(crate) use migration_common::*;
 pub use migration_group::*;
 pub use user_migration::*;
diff --git a/wtx/src/database/schema_manager/migration/db_migration.rs b/wtx/src/database/schema_manager/migration/db_migration.rs
index fe58b985..54c9e59b 100644
--- a/wtx/src/database/schema_manager/migration/db_migration.rs
+++ b/wtx/src/database/schema_manager/migration/db_migration.rs
@@ -1,6 +1,9 @@
 use crate::{
   database::{
-    schema_manager::{MigrationCommon, MigrationGroup, Repeatability, SchemaManagerError},
+    schema_manager::{
+      migration::migration_common::MigrationCommon, MigrationGroup, Repeatability,
+      SchemaManagerError,
+    },
     DatabaseTy, Identifier,
   },
   misc::FromRadix10,
diff --git a/wtx/src/database/schema_manager/migration/user_migration.rs b/wtx/src/database/schema_manager/migration/user_migration.rs
index eb4075ae..342599d9 100644
--- a/wtx/src/database/schema_manager/migration/user_migration.rs
+++ b/wtx/src/database/schema_manager/migration/user_migration.rs
@@ -1,7 +1,7 @@
 use crate::{
   database::{
     schema_manager::{
-      migration::MigrationCommon,
+      migration::migration_common::MigrationCommon,
       misc::{calc_checksum, is_sorted_and_unique},
       Repeatability,
     },
diff --git a/wtx/src/executor.rs b/wtx/src/executor.rs
new file mode 100644
index 00000000..11e68706
--- /dev/null
+++ b/wtx/src/executor.rs
@@ -0,0 +1,9 @@
+mod executor;
+mod executor_builder;
+mod sleep;
+mod task;
+
+pub use executor::Executor;
+pub use executor_builder::ExecutorBuilder;
+pub use sleep::Sleep;
+pub use task::Task;
diff --git a/wtx/src/grpc.rs b/wtx/src/grpc.rs
index 5dbdbafb..c79217ab 100644
--- a/wtx/src/grpc.rs
+++ b/wtx/src/grpc.rs
@@ -17,7 +17,7 @@ fn serialize<DRSR, T>(bytes: &mut Vector<u8>, mut data: T, drsr: &mut DRSR) -> c
 where
   T: Serialize<DRSR>,
 {
-  bytes.extend_from_slice(&[0; 5])?;
+  bytes.extend_from_copyable_slice(&[0; 5])?;
   let before_len = bytes.len();
   data.to_bytes(bytes, drsr)?;
   let after_len = bytes.len();
diff --git a/wtx/src/grpc/client.rs b/wtx/src/grpc/client.rs
index e65b9e00..9eb617fa 100644
--- a/wtx/src/grpc/client.rs
+++ b/wtx/src/grpc/client.rs
@@ -25,7 +25,7 @@ pub struct Client<DRSR, RL, RM> {
 impl<DRSR, HD, RL, RM, SW> Client<DRSR, RL, RM>
 where
   HD: RefCounter + 'static,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer<ReqResBuffer>, ReqResBuffer, SW, true>>,
+  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
   RM: ResourceManager<
     CreateAux = str,
@@ -68,11 +68,11 @@ where
   where
     VerbatimRequest<T>: Serialize<DRSR>,
   {
-    rrb.data.clear();
+    rrb.body.clear();
     rrb.headers.clear();
     rrb.uri.truncate_with_initial_len();
     rrb.uri.push_path(format_args!("/{package}.{service}/{method}"))?;
-    serialize(&mut rrb.data, VerbatimRequest { data }, &mut self.drsr)?;
+    serialize(&mut rrb.body, VerbatimRequest { data }, &mut self.drsr)?;
     Self::push_headers(&mut rrb.headers)?;
     let res = self.cf.send(Method::Post, rrb, ReqUri::Data).await?;
     Ok(Response::http2(res.rrd, res.status_code))
diff --git a/wtx/src/grpc/grpc_manager.rs b/wtx/src/grpc/grpc_manager.rs
index 11400a96..2e52a7a5 100644
--- a/wtx/src/grpc/grpc_manager.rs
+++ b/wtx/src/grpc/grpc_manager.rs
@@ -4,7 +4,7 @@ use crate::{
     format::{VerbatimRequest, VerbatimResponse},
   },
   grpc::{serialize, GrpcStatusCode},
-  http::{server_framework::ReqAux, ReqResDataMut},
+  http::{server_framework::ReqAux, ReqResBuffer},
   misc::Vector,
 };
 
@@ -57,10 +57,7 @@ where
   type Init = DRSR;
 
   #[inline]
-  fn req_aux<RRD>(init: Self::Init, _: &mut crate::http::Request<RRD>) -> crate::Result<Self>
-  where
-    RRD: ReqResDataMut,
-  {
+  fn req_aux(init: Self::Init, _: &mut crate::http::Request<ReqResBuffer>) -> crate::Result<Self> {
     Ok(GrpcManager::from_drsr(init))
   }
 }
diff --git a/wtx/src/grpc/grpc_res_middleware.rs b/wtx/src/grpc/grpc_res_middleware.rs
index 6e0ef9d6..a84c2a35 100644
--- a/wtx/src/grpc/grpc_res_middleware.rs
+++ b/wtx/src/grpc/grpc_res_middleware.rs
@@ -1,23 +1,25 @@
 use crate::{
   grpc::GrpcManager,
-  http::{server_framework::ResMiddleware, Header, KnownHeaderName, Mime, ReqResDataMut, Response},
+  http::{
+    server_framework::ResMiddleware, Header, KnownHeaderName, Mime, ReqResBuffer, ReqResDataMut,
+    Response,
+  },
 };
 
 /// Applies gRPC headers
 #[derive(Debug)]
 pub struct GrpcResMiddleware;
 
-impl<CA, DRSR, E, RRD> ResMiddleware<CA, E, GrpcManager<DRSR>, RRD> for GrpcResMiddleware
+impl<CA, DRSR, E> ResMiddleware<CA, E, GrpcManager<DRSR>> for GrpcResMiddleware
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut,
 {
   #[inline]
   async fn apply_res_middleware(
     &self,
     _: &mut CA,
     ra: &mut GrpcManager<DRSR>,
-    res: Response<&mut RRD>,
+    res: Response<&mut ReqResBuffer>,
   ) -> Result<(), E> {
     res.rrd.headers_mut().push_from_iter_many([
       Header::from_name_and_value(
diff --git a/wtx/src/http.rs b/wtx/src/http.rs
index fedb2858..d7493837 100644
--- a/wtx/src/http.rs
+++ b/wtx/src/http.rs
@@ -12,9 +12,11 @@ mod generic_response;
 mod header_name;
 mod headers;
 mod http_error;
-mod low_level_server;
 mod method;
 mod mime;
+mod misc;
+#[cfg(feature = "nightly")]
+mod optioned_server;
 mod percent_encoding;
 mod protocol;
 mod req_res_buffer;
@@ -29,8 +31,6 @@ mod session;
 mod status_code;
 mod version;
 
-#[cfg(any(feature = "http-client-framework", feature = "http-server-framework"))]
-pub(crate) use conn_params::ConnParams;
 #[cfg(feature = "http-session")]
 pub use cookie::*;
 pub use generic_header::GenericHeader;
@@ -39,9 +39,11 @@ pub use generic_response::GenericResponse;
 pub use header_name::*;
 pub use headers::{Header, Headers, Trailers};
 pub use http_error::HttpError;
-pub use low_level_server::LowLevelServer;
 pub use method::Method;
 pub use mime::Mime;
+pub use misc::*;
+#[cfg(feature = "nightly")]
+pub use optioned_server::OptionedServer;
 pub use percent_encoding::{AsciiSet, PercentDecode, PercentEncode};
 pub use protocol::Protocol;
 pub use req_res_buffer::ReqResBuffer;
diff --git a/wtx/src/http/client_framework.rs b/wtx/src/http/client_framework.rs
index 4a062803..76f717b4 100644
--- a/wtx/src/http/client_framework.rs
+++ b/wtx/src/http/client_framework.rs
@@ -12,9 +12,9 @@ mod integration_tests;
 mod req_builder;
 
 use crate::{
-  http::{ConnParams, Method, ReqResBuffer, ReqResData, ReqUri, Request, Response},
-  http2::{Http2, Http2Buffer, Http2Data, Http2ErrorCode},
-  misc::{LeaseMut, Lock, RefCounter, StreamWriter},
+  http::{conn_params::ConnParams, Method, ReqResBuffer, ReqUri, Request, Response},
+  http2::{Http2, Http2Buffer, Http2Data, Http2ErrorCode, Http2RecvStatus},
+  misc::{Lock, RefCounter, StreamWriter},
   pool::{Pool, ResourceManager, SimplePool, SimplePoolResource},
 };
 use core::marker::PhantomData;
@@ -41,10 +41,10 @@ pub struct ClientFrameworkRM<S> {
   _phantom: PhantomData<S>,
 }
 
-impl<HD, RL, RM, RRB, SW> ClientFramework<RL, RM>
+impl<HD, RL, RM, SW> ClientFramework<RL, RM>
 where
   HD: RefCounter + 'static,
-  HD::Item: Lock<Resource = Http2Data<Http2Buffer<RRB>, RRB, SW, true>>,
+  HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
   RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
   RM: ResourceManager<
     CreateAux = str,
@@ -52,7 +52,6 @@ where
     RecycleAux = str,
     Resource = Http2<HD, true>,
   >,
-  RRB: LeaseMut<ReqResBuffer> + ReqResData,
   SW: StreamWriter,
   for<'any> RL: 'any,
   for<'any> RM: 'any,
@@ -60,7 +59,12 @@ where
   /// Closes all active connections
   #[inline]
   pub async fn close_all(&self) {
-    self.pool._into_for_each(|elem| elem.send_go_away(Http2ErrorCode::NoError)).await;
+    self
+      .pool
+      ._into_for_each(|elem| async move {
+        elem.send_go_away(Http2ErrorCode::NoError).await;
+      })
+      .await;
   }
 
   /// Sends an arbitrary request.
@@ -70,24 +74,25 @@ where
   pub async fn send(
     &self,
     method: Method,
-    rrb: RRB,
+    rrb: ReqResBuffer,
     req_uri: impl Into<ReqUri<'_>>,
-  ) -> crate::Result<Response<RRB>> {
+  ) -> crate::Result<Response<ReqResBuffer>> {
     let actual_req_uri = req_uri.into();
     let uri = match actual_req_uri {
-      ReqUri::Data => &rrb.lease().uri(),
+      ReqUri::Data => &rrb.uri.to_ref(),
       ReqUri::Param(elem) => elem,
     };
     let mut guard = self.pool.get(uri.as_str(), uri.as_str()).await?;
     let mut stream = guard.stream().await?;
-    if stream.send_req(Request::http2(method, rrb.lease()), actual_req_uri).await?.is_none() {
+    if stream.send_req(Request::http2(method, &rrb), actual_req_uri).await?.is_closed() {
       return Err(crate::Error::ClosedConnection);
     }
-    let (res_rrb, opt) = stream.recv_res(rrb).await?;
-    let status_code = match opt {
-      None => return Err(crate::Error::ClosedConnection),
-      Some(elem) => elem,
+    let (hrs, res_rrb) = stream.recv_res(rrb).await?;
+    let status_code = match hrs {
+      Http2RecvStatus::Eos(elem) => elem,
+      _ => return Err(crate::Error::ClosedConnection),
     };
+    stream.common().clear(false).await?;
     Ok(Response::http2(res_rrb, status_code))
   }
 }
@@ -95,10 +100,7 @@ where
 #[cfg(feature = "tokio")]
 mod tokio {
   use crate::{
-    http::{
-      client_framework::{ClientFramework, ClientFrameworkBuilder, ClientFrameworkRM},
-      ReqResBuffer,
-    },
+    http::client_framework::{ClientFramework, ClientFrameworkBuilder, ClientFrameworkRM},
     http2::{Http2Buffer, Http2Tokio},
     misc::UriRef,
     pool::{ResourceManager, SimplePoolResource},
@@ -111,7 +113,7 @@ mod tokio {
   /// A [`ClientFramework`] using the elements of `tokio`.
   pub type ClientFrameworkTokio =
     ClientFramework<Mutex<SimplePoolResource<Instance>>, ClientFrameworkRM<TcpStream>>;
-  type Instance = Http2Tokio<Http2Buffer<ReqResBuffer>, ReqResBuffer, OwnedWriteHalf, true>;
+  type Instance = Http2Tokio<Http2Buffer, OwnedWriteHalf, true>;
 
   impl ClientFrameworkTokio {
     /// Creates a new builder with the maximum number of connections delimited by `len`.
@@ -174,10 +176,7 @@ mod tokio {
 #[cfg(feature = "tokio-rustls")]
 mod tokio_rustls {
   use crate::{
-    http::{
-      client_framework::{ClientFramework, ClientFrameworkBuilder, ClientFrameworkRM},
-      ReqResBuffer,
-    },
+    http::client_framework::{ClientFramework, ClientFrameworkBuilder, ClientFrameworkRM},
     http2::{Http2Buffer, Http2Tokio},
     misc::{TokioRustlsConnector, UriRef},
     pool::{ResourceManager, SimplePoolResource},
@@ -188,7 +187,7 @@ mod tokio_rustls {
   /// A [`ClientFramework`] using the elements of `tokio-rustls`.
   pub type ClientFrameworkTokioRustls =
     ClientFramework<Mutex<SimplePoolResource<Instance>>, ClientFrameworkRM<Writer>>;
-  type Instance = Http2Tokio<Http2Buffer<ReqResBuffer>, ReqResBuffer, Writer, true>;
+  type Instance = Http2Tokio<Http2Buffer, Writer, true>;
   type Writer = WriteHalf<TlsStream<TcpStream>>;
 
   impl ClientFrameworkTokioRustls {
diff --git a/wtx/src/http/client_framework/client_framework_builder.rs b/wtx/src/http/client_framework/client_framework_builder.rs
index 6a061b48..35131df9 100644
--- a/wtx/src/http/client_framework/client_framework_builder.rs
+++ b/wtx/src/http/client_framework/client_framework_builder.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
     client_framework::{ClientFramework, ClientFrameworkRM},
-    ConnParams,
+    conn_params::ConnParams,
   },
   misc::Lock,
   pool::{ResourceManager, SimplePool, SimplePoolResource},
diff --git a/wtx/src/http/client_framework/req_builder.rs b/wtx/src/http/client_framework/req_builder.rs
index a3e771a5..c23dab78 100644
--- a/wtx/src/http/client_framework/req_builder.rs
+++ b/wtx/src/http/client_framework/req_builder.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
-    client_framework::ClientFramework, Header, KnownHeaderName, Method, Mime, ReqResBuffer,
-    ReqResData, ReqUri, Response,
+    client_framework::ClientFramework, Header, KnownHeaderName, Method, Mime, ReqResBuffer, ReqUri,
+    Response,
   },
   http2::{Http2, Http2Buffer, Http2Data},
   misc::{LeaseMut, Lock, RefCounter, StreamWriter},
@@ -14,31 +14,25 @@ use crate::{
 ///
 /// It is also possible to work directly with fields.
 #[derive(Debug)]
-pub struct ReqBuilder<RRB> {
+pub struct ReqBuilder {
   /// Method
   pub method: Method,
   /// Buffer
-  pub rrb: RRB,
+  pub rrb: ReqResBuffer,
 }
 
-impl<RRB> ReqBuilder<RRB>
-where
-  RRB: LeaseMut<ReqResBuffer>,
-{
+impl ReqBuilder {
   /// Constructor shortcut
   #[inline]
-  pub const fn new(method: Method, rrb: RRB) -> Self {
+  pub const fn new(method: Method, rrb: ReqResBuffer) -> Self {
     Self { method, rrb }
   }
 }
 
-impl<RRB> ReqBuilder<RRB>
-where
-  RRB: LeaseMut<ReqResBuffer>,
-{
+impl ReqBuilder {
   /// A instance suitable for `GET` requests.
   #[inline]
-  pub fn get(rrb: RRB) -> Self {
+  pub fn get(rrb: ReqResBuffer) -> Self {
     Self { method: Method::Get, rrb }
   }
 
@@ -48,10 +42,10 @@ where
     self,
     client: &ClientFramework<RL, RM>,
     req_uri: impl Into<ReqUri<'_>>,
-  ) -> crate::Result<Response<RRB>>
+  ) -> crate::Result<Response<ReqResBuffer>>
   where
     HD: RefCounter + 'static,
-    HD::Item: Lock<Resource = Http2Data<Http2Buffer<RRB>, RRB, SW, true>>,
+    HD::Item: Lock<Resource = Http2Data<Http2Buffer, SW, true>>,
     RL: Lock<Resource = SimplePoolResource<RM::Resource>>,
     RM: ResourceManager<
       CreateAux = str,
@@ -59,7 +53,6 @@ where
       RecycleAux = str,
       Resource = Http2<HD, true>,
     >,
-    RRB: LeaseMut<ReqResBuffer> + ReqResData,
     SW: StreamWriter,
     for<'any> RL: 'any,
     for<'any> RM: 'any,
diff --git a/wtx/src/http/conn_params.rs b/wtx/src/http/conn_params.rs
index f06fd911..29235042 100644
--- a/wtx/src/http/conn_params.rs
+++ b/wtx/src/http/conn_params.rs
@@ -1,12 +1,12 @@
 #[derive(Clone, Copy, Debug)]
 pub(crate) struct ConnParams {
-  pub(crate) initial_window_len: u32,
-  pub(crate) max_body_len: u32,
-  pub(crate) max_concurrent_streams_num: u32,
-  pub(crate) max_frame_len: u32,
-  pub(crate) max_headers_len: u32,
-  pub(crate) max_hpack_len: (u32, u32),
-  pub(crate) max_recv_streams_num: u32,
+  pub(crate) _initial_window_len: u32,
+  pub(crate) _max_body_len: u32,
+  pub(crate) _max_concurrent_streams_num: u32,
+  pub(crate) _max_frame_len: u32,
+  pub(crate) _max_headers_len: u32,
+  pub(crate) _max_hpack_len: (u32, u32),
+  pub(crate) _max_recv_streams_num: u32,
 }
 
 #[cfg(feature = "http2")]
@@ -14,13 +14,13 @@ impl ConnParams {
   #[inline]
   pub(crate) fn _to_hp(self) -> crate::http2::Http2Params {
     crate::http2::Http2Params::default()
-      .set_initial_window_len(self.initial_window_len)
-      .set_max_body_len(self.max_body_len)
-      .set_max_concurrent_streams_num(self.max_concurrent_streams_num)
-      .set_max_frame_len(self.max_frame_len)
-      .set_max_headers_len(self.max_headers_len)
-      .set_max_hpack_len(self.max_hpack_len)
-      .set_max_recv_streams_num(self.max_recv_streams_num)
+      .set_initial_window_len(self._initial_window_len)
+      .set_max_body_len(self._max_body_len)
+      .set_max_concurrent_streams_num(self._max_concurrent_streams_num)
+      .set_max_frame_len(self._max_frame_len)
+      .set_max_headers_len(self._max_headers_len)
+      .set_max_hpack_len(self._max_hpack_len)
+      .set_max_recv_streams_num(self._max_recv_streams_num)
   }
 }
 
@@ -28,13 +28,13 @@ impl Default for ConnParams {
   #[inline]
   fn default() -> Self {
     Self {
-      initial_window_len: u32::MAX,
-      max_body_len: 4 * 1024 * 1024,
-      max_concurrent_streams_num: u32::MAX,
-      max_frame_len: 64 * 1024,
-      max_headers_len: 8 * 1024,
-      max_hpack_len: (128 * 1024, 128 * 1024),
-      max_recv_streams_num: u32::MAX,
+      _initial_window_len: u32::MAX,
+      _max_body_len: 4 * 1024 * 1024,
+      _max_concurrent_streams_num: u32::MAX,
+      _max_frame_len: 64 * 1024,
+      _max_headers_len: 8 * 1024,
+      _max_hpack_len: (128 * 1024, 128 * 1024),
+      _max_recv_streams_num: u32::MAX,
     }
   }
 }
diff --git a/wtx/src/http/cookie.rs b/wtx/src/http/cookie.rs
index 832ecb6b..e52c5a99 100644
--- a/wtx/src/http/cookie.rs
+++ b/wtx/src/http/cookie.rs
@@ -25,7 +25,7 @@ pub(crate) fn decrypt(
   key: &[u8],
   (name, value): (&[u8], &[u8]),
 ) -> crate::Result<()> {
-  use crate::misc::BufferParam;
+  use crate::misc::BufferMode;
   use aes_gcm::{
     aead::{generic_array::GenericArray, AeadInPlace},
     Aes256Gcm, Tag,
@@ -35,7 +35,7 @@ pub(crate) fn decrypt(
   let start = buffer.len();
   let (nonce, content, tag) = {
     let expand_len = NONCE_LEN.wrapping_add(value.len()).wrapping_add(TAG_LEN);
-    buffer.expand(BufferParam::Additional(expand_len), 0)?;
+    buffer.expand(BufferMode::Additional(expand_len), 0)?;
     let actual_len = STANDARD.decode_slice(value, buffer)?;
     buffer.truncate(start.wrapping_add(actual_len));
     #[rustfmt::skip]
@@ -80,7 +80,7 @@ pub(crate) fn encrypt<RNG>(
 where
   RNG: Rng,
 {
-  use crate::misc::BufferParam;
+  use crate::misc::BufferMode;
   use aes_gcm::{
     aead::{generic_array::GenericArray, AeadInPlace},
     Aes256Gcm,
@@ -90,8 +90,12 @@ where
   let start = buffer.len();
   let content_len = NONCE_LEN.wrapping_add(value.len()).wrapping_add(TAG_LEN);
   let base64_len = base64::encoded_len(content_len, true).unwrap_or(usize::MAX);
-  buffer.expand(BufferParam::Additional(base64_len), 0)?;
-  let _ = buffer.extend_from_slices([[0; NONCE_LEN].as_slice(), value, [0; TAG_LEN].as_slice()])?;
+  buffer.expand(BufferMode::Additional(base64_len), 0)?;
+  let _ = buffer.extend_from_copyable_slices([
+    [0; NONCE_LEN].as_slice(),
+    value,
+    [0; TAG_LEN].as_slice(),
+  ])?;
   {
     let content_start = start.wrapping_add(base64_len);
     #[rustfmt::skip]
diff --git a/wtx/src/http/cookie/cookie_bytes.rs b/wtx/src/http/cookie/cookie_bytes.rs
index 2631b6c5..60a37942 100644
--- a/wtx/src/http/cookie/cookie_bytes.rs
+++ b/wtx/src/http/cookie/cookie_bytes.rs
@@ -35,10 +35,10 @@ impl<'bytes> CookieBytes<'bytes> {
       let (name, value) = if let Some(elem) = bytes_split_once1(first_semicolon, b'=') {
         (elem.0.trim_ascii(), elem.1.trim_ascii())
       } else {
-        return Err(crate::Error::from(CookieError::IrregularCookie).into());
+        return Err(crate::Error::from(CookieError::IrregularCookie));
       };
       if name.is_empty() {
-        return Err(crate::Error::from(CookieError::MissingName).into());
+        return Err(crate::Error::from(CookieError::MissingName));
       }
       let before_name_len = vector.len();
       let has_decoded_name = PercentDecode::new(name).decode(vector)?;
@@ -70,7 +70,7 @@ impl<'bytes> CookieBytes<'bytes> {
       let (name, value) = if let Some(elem) = bytes_split_once1(semicolon, b'=') {
         (elem.0.trim_ascii(), elem.1.trim_ascii())
       } else {
-        return Err(crate::Error::from(CookieError::IrregularCookie).into());
+        return Err(crate::Error::from(CookieError::IrregularCookie));
       };
       make_lowercase::<12>(&mut lower_case, name);
       match (lower_case.as_ref(), value) {
diff --git a/wtx/src/http/cookie/cookie_generic.rs b/wtx/src/http/cookie/cookie_generic.rs
index 47c57264..e2eb0510 100644
--- a/wtx/src/http/cookie/cookie_generic.rs
+++ b/wtx/src/http/cookie/cookie_generic.rs
@@ -8,7 +8,7 @@ use core::{
   time::Duration,
 };
 
-#[derive(Debug, Default)]
+#[derive(Debug)]
 pub(crate) struct CookieGeneric<T, V> {
   pub(crate) domain: T,
   pub(crate) expire: Option<DateTime<Utc>>,
diff --git a/wtx/src/http/headers.rs b/wtx/src/http/headers.rs
index bb7ee3d8..0b3a7784 100644
--- a/wtx/src/http/headers.rs
+++ b/wtx/src/http/headers.rs
@@ -148,7 +148,7 @@ impl Headers {
 
   /// Pushes a new header with its value composed by [`Arguments`].
   ///
-  /// ```
+  /// ```rust
   /// use wtx::http::{Header, Headers};
   /// let mut headers = Headers::new();
   /// headers.push_from_fmt(Header::from_name_and_value(b"name", format_args!("{}", 1))).unwrap();
@@ -182,7 +182,7 @@ impl Headers {
 
   /// Pushes a new header with its value composed by several slices.
   ///
-  /// ```
+  /// ```rust
   /// use wtx::http::{Header, Headers};
   /// let mut headers = Headers::new();
   /// headers.push_from_iter(Header::from_name_and_value(b"name", ["value0".as_bytes(), "_value1".as_bytes()])).unwrap();
@@ -194,28 +194,27 @@ impl Headers {
     V: IntoIterator<Item = &'bytes [u8]>,
     V::IntoIter: Clone,
   {
-    // FIXME(MIRI): a function, even it it is #[inline], breaks the tracking of the pointer
-    macro_rules! copy {
-      ($bytes:expr, $header_end:expr, $value:expr) => {{
-        // SAFETY: `header_end is within bounds`
-        let dst = unsafe { $bytes.as_mut_ptr().add(*$header_end) };
-        // SAFETY: `reserve` allocated memory
-        unsafe {
-          ptr::copy_nonoverlapping($value.as_ptr(), dst, $value.len());
-        }
-        *$header_end = $header_end.wrapping_add($value.len());
-      }};
+    #[inline]
+    fn copy(header_end: &mut usize, ptr: *mut u8, value: &[u8]) {
+      // SAFETY: `header_end is within bounds`
+      let dst = unsafe { ptr.add(*header_end) };
+      // SAFETY: `reserve` allocated memory
+      unsafe {
+        ptr::copy_nonoverlapping(value.as_ptr(), dst, value.len());
+      }
+      *header_end = header_end.wrapping_add(value.len());
     }
 
     let iter = header.value.into_iter();
     let header_len = Self::header_len(header.name, iter.clone());
     self.reserve(header_len, 1)?;
     let header_begin = self.bytes.len();
+    let ptr = self.bytes.as_ptr_mut();
     let mut header_end = header_begin;
-    copy!(&mut self.bytes, &mut header_end, header.name);
+    copy(&mut header_end, ptr, header.name);
     let header_name_end = header_end;
     for value in iter {
-      copy!(&mut self.bytes, &mut header_end, value);
+      copy(&mut header_end, ptr, value);
     }
     // SAFETY: `header_end is within bounds`
     unsafe {
diff --git a/wtx/src/http/low_level_server/tokio_http2.rs b/wtx/src/http/low_level_server/tokio_http2.rs
deleted file mode 100644
index 155eedd3..00000000
--- a/wtx/src/http/low_level_server/tokio_http2.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-use crate::{
-  http::{low_level_server::LowLevelServer, ReqResBuffer, Request, Response},
-  http2::{Http2ErrorCode, Http2Params, Http2Tokio},
-  misc::{Either, FnFut, StreamReader, StreamWriter},
-};
-use core::future::Future;
-use tokio::net::{TcpListener, TcpStream};
-
-type Http2Buffer = crate::http2::Http2Buffer<ReqResBuffer>;
-
-impl LowLevelServer {
-  /// Optioned HTTP/2 server using tokio.
-  #[inline]
-  pub async fn tokio_http2<ACPT, CA, E, F, RA, SR, SF, SW>(
-    addr: &str,
-    conn_cb: impl Clone + Fn() -> crate::Result<(CA, Http2Buffer, Http2Params)> + Send + 'static,
-    err_cb: impl Clone + Fn(E) + Send + 'static,
-    handle_cb: F,
-    req_cb: impl Clone + Fn() -> crate::Result<(RA, ReqResBuffer)> + Send + 'static,
-    (acceptor_cb, local_acceptor_cb, stream_cb): (
-      impl FnOnce() -> crate::Result<ACPT> + Send + 'static,
-      impl Clone + Fn(&ACPT) -> ACPT + Send + 'static,
-      impl Clone + Fn(ACPT, TcpStream) -> SF + Send + 'static,
-    ),
-  ) -> crate::Result<()>
-  where
-    CA: Clone + Send + 'static,
-    ACPT: Send + 'static,
-    E: From<crate::Error> + Send + 'static,
-    F: Clone
-      + FnFut<(CA, RA, Request<ReqResBuffer>), Result = Result<Response<ReqResBuffer>, E>>
-      + Send
-      + 'static,
-    F::Future: Send,
-    RA: Send + 'static,
-    SF: Send + Future<Output = crate::Result<(SR, SW)>>,
-    SR: Send + StreamReader<read(..): Send, read_skip(..): Send> + Unpin + 'static,
-    SW: Send + StreamWriter<write_all(..): Send, write_all_vectored(..): Send> + Unpin + 'static,
-    for<'handle> &'handle F: Send,
-  {
-    let listener = TcpListener::bind(addr).await?;
-    let acceptor = acceptor_cb()?;
-    loop {
-      let (tcp_stream, _) = listener.accept().await?;
-      let local_acceptor = local_acceptor_cb(&acceptor);
-      let local_conn_cb = conn_cb.clone();
-      let local_err_cb = err_cb.clone();
-      let local_handle_cb = handle_cb.clone();
-      let local_req_cb = req_cb.clone();
-      let local_stream_cb = stream_cb.clone();
-      let _conn_jh = tokio::spawn(async move {
-        let local_local_err_cb = local_err_cb.clone();
-        let fut = manage_conn(
-          local_acceptor,
-          tcp_stream,
-          local_conn_cb,
-          local_err_cb,
-          local_handle_cb,
-          local_req_cb,
-          local_stream_cb,
-        );
-        if let Err(err) = fut.await {
-          local_local_err_cb(E::from(err));
-        }
-      });
-    }
-  }
-}
-
-async fn manage_conn<ACPT, CA, E, F, RA, SR, SF, SW>(
-  local_acceptor: ACPT,
-  tcp_stream: TcpStream,
-  conn_cb: impl Clone + Fn() -> crate::Result<(CA, Http2Buffer, Http2Params)> + Send + 'static,
-  err_cb: impl Clone + Fn(E) + Send + 'static,
-  handle_cb: F,
-  req_cb: impl Clone + Fn() -> crate::Result<(RA, ReqResBuffer)> + Send + 'static,
-  stream_cb: impl Clone + Fn(ACPT, TcpStream) -> SF + Send + 'static,
-) -> crate::Result<()>
-where
-  CA: Clone + Send + 'static,
-  E: From<crate::Error> + Send + 'static,
-  F: Clone
-    + FnFut<(CA, RA, Request<ReqResBuffer>), Result = Result<Response<ReqResBuffer>, E>>
-    + Send
-    + 'static,
-  F::Future: Send,
-  RA: Send + 'static,
-  SF: Send + Future<Output = crate::Result<(SR, SW)>>,
-  SR: Send + StreamReader<read(..): Send, read_skip(..): Send> + Unpin + 'static,
-  SW: Send + StreamWriter<write_all(..): Send, write_all_vectored(..): Send> + Unpin + 'static,
-  for<'handle> &'handle F: Send,
-{
-  let (ca, http2_buffer, http2_params) = conn_cb()?;
-  let tuple = stream_cb(local_acceptor, tcp_stream).await?;
-  let (frame_reader, mut http2) = Http2Tokio::accept(http2_buffer, http2_params, tuple).await?;
-  let _jh = tokio::spawn(frame_reader);
-  loop {
-    let (ra, rrb) = req_cb()?;
-    let mut http2_stream = match http2.stream(rrb).await? {
-      Either::Left(_) => return Ok(()),
-      Either::Right(elem) => elem,
-    };
-    let local_ca = ca.clone();
-    let local_handle_cb = handle_cb.clone();
-    let local_err_cb = err_cb.clone();
-    let _stream_jh = tokio::spawn(async move {
-      let fun = || async {
-        let (local_rrb, opt) = http2_stream.recv_req().await?;
-        let method = match opt {
-          None => return Ok(()),
-          Some(elem) => elem,
-        };
-        let req = local_rrb.into_http2_request(method);
-        let res = local_handle_cb.call((local_ca, ra, req)).await?;
-        if http2_stream.send_res(res).await?.is_none() {
-          return Ok(());
-        }
-        Ok::<_, E>(())
-      };
-      if let Err(err) = fun().await {
-        http2_stream.send_go_away(Http2ErrorCode::InternalError).await;
-        local_err_cb(err);
-      }
-    });
-  }
-}
diff --git a/wtx/src/http/misc.rs b/wtx/src/http/misc.rs
new file mode 100644
index 00000000..edf1d9f7
--- /dev/null
+++ b/wtx/src/http/misc.rs
@@ -0,0 +1,13 @@
+use crate::{
+  http::{Headers, ReqResBuffer, Request},
+  misc::Vector,
+};
+
+/// Used as an auxiliary tool for tests.
+#[inline]
+pub fn state_tuple_wo_uri<CA, RA>(
+  (ca, ra, req): &mut (CA, RA, Request<ReqResBuffer>),
+) -> (&mut CA, &mut RA, Request<(&mut Vector<u8>, &mut Headers)>) {
+  let (body, headers, _) = req.rrd.parts_mut();
+  (ca, ra, Request { method: req.method, rrd: (body, headers), version: req.version })
+}
diff --git a/wtx/src/http/low_level_server.rs b/wtx/src/http/optioned_server.rs
similarity index 72%
rename from wtx/src/http/low_level_server.rs
rename to wtx/src/http/optioned_server.rs
index f99eb3ab..67334677 100644
--- a/wtx/src/http/low_level_server.rs
+++ b/wtx/src/http/optioned_server.rs
@@ -1,11 +1,13 @@
 //! Optioned high-level abstraction for servers. You can use one of listed suggestions or
 //! create your own.
+//
+// FIXME(STABLE): Return type notation
 
 #[cfg(all(feature = "http2", feature = "tokio"))]
 mod tokio_http2;
 #[cfg(all(feature = "pool", feature = "tokio", feature = "web-socket-handshake"))]
 mod tokio_web_socket;
 
-/// Optioned high-level abstractions for low-level servers.
+/// Optioned abstractions of low-level servers.
 #[derive(Debug)]
-pub struct LowLevelServer;
+pub struct OptionedServer;
diff --git a/wtx/src/http/optioned_server/tokio_http2.rs b/wtx/src/http/optioned_server/tokio_http2.rs
new file mode 100644
index 00000000..683fc2bd
--- /dev/null
+++ b/wtx/src/http/optioned_server/tokio_http2.rs
@@ -0,0 +1,157 @@
+use crate::{
+  http::{optioned_server::OptionedServer, Headers, ReqResBuffer, Request, Response},
+  http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2Tokio, ServerStreamTokio},
+  misc::{Either, FnFut, StreamReader, StreamWriter},
+};
+use core::future::Future;
+use tokio::net::{TcpListener, TcpStream};
+
+impl OptionedServer {
+  /// Optioned HTTP/2 server using tokio.
+  #[inline]
+  pub async fn tokio_high_http2<A, ACPT, CA, E, M, SA, SR, SF, SW>(
+    addr: &str,
+    auto_cb: A,
+    conn_cb: impl Clone + Fn() -> crate::Result<(CA, Http2Buffer, Http2Params)> + Send + 'static,
+    err_cb: impl Clone + Fn(E) + Send + 'static,
+    manual_cb: M,
+    stream_cb: impl Clone + Fn() -> crate::Result<(SA, ReqResBuffer)> + Send + 'static,
+    (acceptor_cb, local_acceptor_cb, net_cb): (
+      impl FnOnce() -> crate::Result<ACPT> + Send + 'static,
+      impl Clone + Fn(&ACPT) -> ACPT + Send + 'static,
+      impl Clone + Fn(ACPT, TcpStream) -> SF + Send + 'static,
+    ),
+  ) -> crate::Result<()>
+  where
+    A: Clone
+      + FnFut<(CA, SA, Request<ReqResBuffer>), Result = Result<Response<ReqResBuffer>, E>>
+      + Send
+      + 'static,
+    A::Future: Send,
+    CA: Clone + Send + 'static,
+    ACPT: Send + 'static,
+    E: From<crate::Error> + Send + 'static,
+    M: Clone
+      + FnFut<(CA, SA, Headers, ServerStreamTokio<Http2Buffer, SW, false>), Result = Result<(), E>>
+      + Send
+      + 'static,
+    M::Future: Send,
+    SA: Send + 'static,
+    SF: Send + Future<Output = crate::Result<(SR, SW)>>,
+    SR: Send + StreamReader<read(..): Send, read_skip(..): Send> + Unpin + 'static,
+    SW: Send + StreamWriter<write_all(..): Send, write_all_vectored(..): Send> + Unpin + 'static,
+    for<'handle> &'handle A: Send,
+    for<'handle> &'handle M: Send,
+  {
+    let listener = TcpListener::bind(addr).await?;
+    let acceptor = acceptor_cb()?;
+    loop {
+      let (tcp_stream, _) = listener.accept().await?;
+      let local_acceptor = local_acceptor_cb(&acceptor);
+      let local_auto_cb = auto_cb.clone();
+      let local_conn_cb = conn_cb.clone();
+      let local_err_cb = err_cb.clone();
+      let local_manual_cb = manual_cb.clone();
+      let local_net_cb = net_cb.clone();
+      let local_stream_cb = stream_cb.clone();
+      let _conn_jh = tokio::spawn(async move {
+        let local_local_err_cb = local_err_cb.clone();
+        let fut = manage_conn(
+          local_acceptor,
+          local_auto_cb,
+          local_conn_cb,
+          local_err_cb,
+          local_manual_cb,
+          local_net_cb,
+          local_stream_cb,
+          tcp_stream,
+        );
+        if let Err(err) = fut.await {
+          local_local_err_cb(E::from(err));
+        }
+      });
+    }
+  }
+}
+
+async fn manage_conn<A, ACPT, CA, E, M, SA, SR, SF, SW>(
+  acceptor: ACPT,
+  auto_cb: A,
+  conn_cb: impl Clone + Fn() -> crate::Result<(CA, Http2Buffer, Http2Params)> + Send + 'static,
+  err_cb: impl Clone + Fn(E) + Send + 'static,
+  manual_cb: M,
+  net_cb: impl Clone + Fn(ACPT, TcpStream) -> SF + Send + 'static,
+  stream_cb: impl Clone + Fn() -> crate::Result<(SA, ReqResBuffer)> + Send + 'static,
+  tcp_stream: TcpStream,
+) -> crate::Result<()>
+where
+  A: Clone
+    + FnFut<(CA, SA, Request<ReqResBuffer>), Result = Result<Response<ReqResBuffer>, E>>
+    + Send
+    + 'static,
+  A::Future: Send,
+  CA: Clone + Send + 'static,
+  E: From<crate::Error> + Send + 'static,
+  M: Clone
+    + FnFut<(CA, SA, Headers, ServerStreamTokio<Http2Buffer, SW, false>), Result = Result<(), E>>
+    + Send
+    + 'static,
+  M::Future: Send,
+  SA: Send + 'static,
+  SF: Send + Future<Output = crate::Result<(SR, SW)>>,
+  SR: Send + StreamReader<read(..): Send, read_skip(..): Send> + Unpin + 'static,
+  SW: Send + StreamWriter<write_all(..): Send, write_all_vectored(..): Send> + Unpin + 'static,
+  for<'handle> &'handle A: Send,
+  for<'handle> &'handle M: Send,
+{
+  let (ca, http2_buffer, http2_params) = conn_cb()?;
+  let net_tuple = net_cb(acceptor, tcp_stream).await?;
+  let accept_tuple = Http2Tokio::accept(http2_buffer, http2_params, net_tuple).await?;
+  let (frame_reader, mut http2) = accept_tuple;
+  let _jh = tokio::spawn(frame_reader);
+  loop {
+    let (ra, rrb) = stream_cb()?;
+    let (mut http2_stream, _headers_opt) = match http2
+      .stream(rrb, |_headers, _method, _protocol| {
+        #[cfg(feature = "web-socket")]
+        {
+          let is_ws = crate::http2::is_web_socket_handshake(_headers, _method, _protocol);
+          is_ws.then(|| core::mem::take(_headers))
+        }
+      })
+      .await?
+    {
+      Either::Left(_) => return Ok(()),
+      Either::Right(elem) => elem,
+    };
+    let local_auto_cb = auto_cb.clone();
+    let local_ca = ca.clone();
+    let local_err_cb = err_cb.clone();
+    let _local_manual_cb = manual_cb.clone();
+    let _stream_jh = tokio::spawn(async move {
+      let fun = async {
+        #[cfg(feature = "web-socket")]
+        if let Some(headers) = _headers_opt {
+          _local_manual_cb.call((local_ca, ra, headers, http2_stream.clone())).await?;
+          return Ok(());
+        }
+        let (hrs, local_rrb) = http2_stream.recv_req().await?;
+        if hrs.is_closed() {
+          return Ok(());
+        }
+        let req = local_rrb.into_http2_request(http2_stream.method());
+        let res = local_auto_cb.call((local_ca, ra, req)).await?;
+        if http2_stream.send_res(res).await?.is_closed() {
+          return Ok(());
+        }
+        Ok::<_, E>(())
+      };
+      let rslt = fun.await;
+      let _rslt = http2_stream.common().clear(true).await;
+      if let Err(err) = rslt {
+        http2_stream.common().send_go_away(Http2ErrorCode::InternalError).await;
+        local_err_cb(err);
+      }
+    });
+  }
+}
diff --git a/wtx/src/http/low_level_server/tokio_web_socket.rs b/wtx/src/http/optioned_server/tokio_web_socket.rs
similarity index 66%
rename from wtx/src/http/low_level_server/tokio_web_socket.rs
rename to wtx/src/http/optioned_server/tokio_web_socket.rs
index d974f296..feea489d 100644
--- a/wtx/src/http/low_level_server/tokio_web_socket.rs
+++ b/wtx/src/http/optioned_server/tokio_web_socket.rs
@@ -1,8 +1,8 @@
 use crate::{
-  http::LowLevelServer,
-  misc::{FnFut, Stream, Vector, Xorshift64, _number_or_available_parallelism, simple_seed},
+  http::OptionedServer,
+  misc::{FnFut, Stream, Xorshift64, _number_or_available_parallelism, simple_seed},
   pool::{SimplePoolGetElem, SimplePoolResource, SimplePoolTokio, WebSocketRM},
-  web_socket::{Compression, FrameBuffer, FrameBufferVec, WebSocketBuffer, WebSocketServer},
+  web_socket::{Compression, WebSocketBuffer, WebSocketServer},
 };
 use core::{fmt::Debug, future::Future};
 use std::sync::OnceLock;
@@ -11,7 +11,7 @@ use tokio::{
   sync::MutexGuard,
 };
 
-impl LowLevelServer {
+impl OptionedServer {
   /// Optioned WebSocket server using tokio.
   #[inline]
   pub async fn tokio_web_socket<ACPT, C, E, F, S, SF>(
@@ -31,20 +31,16 @@ impl LowLevelServer {
     C: Compression<false> + Send + 'static,
     C::NegotiatedCompression: Send,
     E: Debug + From<crate::Error> + Send + 'static,
-    for<'fb, 'wsb> F: Clone
+    for<'wsb> F: Clone
       + FnFut<
-        (
-          &'fb mut FrameBufferVec,
-          WebSocketServer<C::NegotiatedCompression, Xorshift64, S, &'wsb mut WebSocketBuffer>,
-        ),
+        (WebSocketServer<C::NegotiatedCompression, S, &'wsb mut WebSocketBuffer>,),
         Result = Result<(), E>,
       > + Send
       + 'static,
     S: Stream<read(..): Send, write_all(..): Send> + Send,
     SF: Send + Future<Output = crate::Result<S>>,
-    for<'fb, 'wsb> <F as FnFut<(
-      &'fb mut FrameBufferVec,
-      WebSocketServer<C::NegotiatedCompression, Xorshift64, S, &'wsb mut WebSocketBuffer>,
+    for<'wsb> <F as FnFut<(
+      WebSocketServer<C::NegotiatedCompression, S, &'wsb mut WebSocketBuffer>,
     )>>::Future: Send,
     for<'handle> &'handle F: Send,
   {
@@ -61,25 +57,22 @@ impl LowLevelServer {
       let local_handle_cb = handle_cb.clone();
       let local_stream_cb = stream_cb.clone();
       let _jh = tokio::spawn(async move {
-        let (fb, wsb) = &mut ***conn_buffer_guard;
-        let fun = || async move {
+        let wsb = &mut ***conn_buffer_guard;
+        let fun = async move {
           let stream = local_stream_cb(local_acceptor, tcp_stream).await?;
           local_handle_cb
-            .call((
-              fb,
-              WebSocketServer::accept(
-                local_compression_cb(),
-                Xorshift64::from(simple_seed()),
-                stream,
-                wsb,
-                |_| crate::Result::Ok(()),
-              )
-              .await?,
-            ))
+            .call((WebSocketServer::accept(
+              local_compression_cb(),
+              Xorshift64::from(simple_seed()),
+              stream,
+              wsb,
+              |_| crate::Result::Ok(()),
+            )
+            .await?,))
             .await?;
           Ok::<_, E>(())
         };
-        if let Err(err) = fun().await {
+        if let Err(err) = fun.await {
           local_conn_err(err);
         }
       });
@@ -89,11 +82,7 @@ impl LowLevelServer {
 
 async fn conn_buffer(
   len: usize,
-) -> crate::Result<
-  SimplePoolGetElem<
-    MutexGuard<'static, SimplePoolResource<(FrameBuffer<Vector<u8>>, WebSocketBuffer)>>,
-  >,
-> {
+) -> crate::Result<SimplePoolGetElem<MutexGuard<'static, SimplePoolResource<WebSocketBuffer>>>> {
   static POOL: OnceLock<SimplePoolTokio<WebSocketRM>> = OnceLock::new();
   POOL
     .get_or_init(|| SimplePoolTokio::new(len, WebSocketRM::new(|| Ok(Default::default()))))
diff --git a/wtx/src/http/percent_encoding.rs b/wtx/src/http/percent_encoding.rs
index e1b69bf8..8bbb3893 100644
--- a/wtx/src/http/percent_encoding.rs
+++ b/wtx/src/http/percent_encoding.rs
@@ -138,7 +138,7 @@ impl<'bytes> PercentDecode<'bytes> {
       return Ok(false);
     };
     let local_bytes = self.bytes.get(..idx).unwrap_or_default();
-    let _ = vector.extend_from_slices([local_bytes, &[decoded_byte][..]])?;
+    let _ = vector.extend_from_copyable_slices([local_bytes, &[decoded_byte][..]])?;
     while let [byte, rest @ ..] = bytes {
       bytes = rest;
       vector.push(if *byte == b'%' {
diff --git a/wtx/src/http/req_res_buffer.rs b/wtx/src/http/req_res_buffer.rs
index e119f313..165c7e25 100644
--- a/wtx/src/http/req_res_buffer.rs
+++ b/wtx/src/http/req_res_buffer.rs
@@ -1,6 +1,6 @@
 use crate::{
   http::{Headers, Method, ReqResData, ReqResDataMut, Request, Response, StatusCode, Version},
-  misc::{Lease, LeaseMut, UriRef, UriString, Vector},
+  misc::{Lease, LeaseMut, UriString, Vector},
 };
 use alloc::string::String;
 
@@ -8,7 +8,7 @@ use alloc::string::String;
 #[derive(Debug)]
 pub struct ReqResBuffer {
   /// See [`Vector`].
-  pub data: Vector<u8>,
+  pub body: Vector<u8>,
   /// See [`Headers`].
   pub headers: Headers,
   /// See [`UriString`].
@@ -25,7 +25,7 @@ impl ReqResBuffer {
   /// Constructor shortcut
   #[inline]
   pub const fn new(data: Vector<u8>, headers: Headers, uri: UriString) -> Self {
-    Self { data, headers, uri }
+    Self { body: data, headers, uri }
   }
 
   /// Shortcut to create a HTTP/2 [Request].
@@ -57,7 +57,7 @@ impl ReqResBuffer {
   /// The internal vector as well as the internal headers are returned in a valid state.
   #[inline]
   pub fn clear(&mut self) {
-    let Self { data, headers, uri } = self;
+    let Self { body: data, headers, uri } = self;
     data.clear();
     headers.clear();
     uri.clear();
@@ -74,6 +74,12 @@ impl ReqResBuffer {
   pub fn into_http2_response(self, status_code: StatusCode) -> Response<Self> {
     Response { rrd: self, status_code, version: Version::Http2 }
   }
+
+  /// Mutable parts
+  #[inline]
+  pub fn parts_mut(&mut self) -> (&mut Vector<u8>, &mut Headers, &mut UriString) {
+    (&mut self.body, &mut self.headers, &mut self.uri)
+  }
 }
 
 impl ReqResData for ReqResBuffer {
@@ -81,7 +87,7 @@ impl ReqResData for ReqResBuffer {
 
   #[inline]
   fn body(&self) -> &Self::Body {
-    &self.data
+    &self.body
   }
 
   #[inline]
@@ -90,20 +96,20 @@ impl ReqResData for ReqResBuffer {
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    self.uri.to_ref()
+  fn uri(&self) -> &UriString {
+    &self.uri
   }
 }
 
 impl ReqResDataMut for ReqResBuffer {
   #[inline]
   fn body_mut(&mut self) -> &mut Self::Body {
-    &mut self.data
+    &mut self.body
   }
 
   #[inline]
   fn clear(&mut self) {
-    self.data.clear();
+    self.body.clear();
     self.headers.clear();
   }
 
@@ -113,15 +119,15 @@ impl ReqResDataMut for ReqResBuffer {
   }
 
   #[inline]
-  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, UriRef<'_>) {
-    (&mut self.data, &mut self.headers, self.uri.to_ref())
+  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, &UriString) {
+    (&mut self.body, &mut self.headers, &self.uri)
   }
 }
 
 impl Lease<[u8]> for ReqResBuffer {
   #[inline]
   fn lease(&self) -> &[u8] {
-    &self.data
+    &self.body
   }
 }
 
@@ -139,11 +145,25 @@ impl LeaseMut<ReqResBuffer> for ReqResBuffer {
   }
 }
 
+impl Default for ReqResBuffer {
+  #[inline]
+  fn default() -> Self {
+    Self::empty()
+  }
+}
+
+impl From<Vector<u8>> for ReqResBuffer {
+  #[inline]
+  fn from(from: Vector<u8>) -> Self {
+    Self { body: from, headers: Headers::new(), uri: UriString::_empty(String::new()) }
+  }
+}
+
 #[cfg(feature = "std")]
 impl core::fmt::Write for ReqResBuffer {
   #[inline]
   fn write_str(&mut self, s: &str) -> core::fmt::Result {
-    self.data.extend_from_slice(s.as_bytes()).map_err(|_err| core::fmt::Error)
+    self.body.extend_from_copyable_slice(s.as_bytes()).map_err(|_err| core::fmt::Error)
   }
 }
 
@@ -151,11 +171,11 @@ impl core::fmt::Write for ReqResBuffer {
 impl std::io::Write for ReqResBuffer {
   #[inline]
   fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
-    self.data.write(buf)
+    self.body.write(buf)
   }
 
   #[inline]
   fn flush(&mut self) -> std::io::Result<()> {
-    self.data.flush()
+    self.body.flush()
   }
 }
diff --git a/wtx/src/http/req_res_data.rs b/wtx/src/http/req_res_data.rs
index 2984c2d0..501ad838 100644
--- a/wtx/src/http/req_res_data.rs
+++ b/wtx/src/http/req_res_data.rs
@@ -1,6 +1,6 @@
 use crate::{
   http::Headers,
-  misc::{Lease, LeaseMut, Uri, UriRef},
+  misc::{Lease, LeaseMut, Uri, UriString, _EMPTY_URI_STRING},
 };
 use alloc::boxed::Box;
 
@@ -15,8 +15,8 @@ pub trait ReqResData {
   /// See [Headers].
   fn headers(&self) -> &Headers;
 
-  /// See [`UriRef`].
-  fn uri(&self) -> UriRef<'_>;
+  /// See [`UriString`].
+  fn uri(&self) -> &UriString;
 }
 
 impl<T> ReqResData for &T
@@ -36,7 +36,7 @@ where
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
+  fn uri(&self) -> &UriString {
     (*self).uri()
   }
 }
@@ -58,7 +58,7 @@ where
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
+  fn uri(&self) -> &UriString {
     (**self).uri()
   }
 }
@@ -77,8 +77,8 @@ impl ReqResData for &[u8] {
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    UriRef::_empty("")
+  fn uri(&self) -> &UriString {
+    &_EMPTY_URI_STRING
   }
 }
 
@@ -96,8 +96,8 @@ impl<const N: usize> ReqResData for [u8; N] {
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    UriRef::_empty("")
+  fn uri(&self) -> &UriString {
+    &_EMPTY_URI_STRING
   }
 }
 
@@ -115,8 +115,8 @@ impl ReqResData for () {
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    UriRef::_empty("")
+  fn uri(&self) -> &UriString {
+    &_EMPTY_URI_STRING
   }
 }
 
@@ -137,8 +137,8 @@ where
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    UriRef::_empty("")
+  fn uri(&self) -> &UriString {
+    &_EMPTY_URI_STRING
   }
 }
 
@@ -159,8 +159,8 @@ where
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    UriRef::_empty("")
+  fn uri(&self) -> &UriString {
+    &_EMPTY_URI_STRING
   }
 }
 
@@ -178,8 +178,8 @@ impl ReqResData for Headers {
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    UriRef::_empty("")
+  fn uri(&self) -> &UriString {
+    &_EMPTY_URI_STRING
   }
 }
 
@@ -200,8 +200,8 @@ where
   }
 
   #[inline]
-  fn uri(&self) -> UriRef<'_> {
-    self.to_ref()
+  fn uri(&self) -> &UriString {
+    &_EMPTY_URI_STRING
   }
 }
 
@@ -223,7 +223,7 @@ pub trait ReqResDataMut: ReqResData {
   }
 
   /// Mutable parts
-  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, UriRef<'_>);
+  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, &UriString);
 }
 
 impl<T> ReqResDataMut for &mut T
@@ -246,7 +246,7 @@ where
   }
 
   #[inline]
-  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, UriRef<'_>) {
+  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, &UriString) {
     (**self).parts_mut()
   }
 }
@@ -271,7 +271,7 @@ where
   }
 
   #[inline]
-  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, UriRef<'_>) {
+  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, &UriString) {
     (**self).parts_mut()
   }
 }
@@ -281,8 +281,8 @@ impl ReqResDataMut for Headers {
   fn clear(&mut self) {}
 
   #[inline]
-  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, UriRef<'_>) {
-    (&mut [], self, UriRef::_empty(""))
+  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, &UriString) {
+    (&mut [], self, &_EMPTY_URI_STRING)
   }
 }
 
@@ -294,7 +294,7 @@ where
   fn clear(&mut self) {}
 
   #[inline]
-  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, UriRef<'_>) {
-    (&mut self.0, self.1.lease_mut(), UriRef::_empty(""))
+  fn parts_mut(&mut self) -> (&mut Self::Body, &mut Headers, &UriString) {
+    (&mut self.0, self.1.lease_mut(), &_EMPTY_URI_STRING)
   }
 }
diff --git a/wtx/src/http/request.rs b/wtx/src/http/request.rs
index 596fc167..e7088189 100644
--- a/wtx/src/http/request.rs
+++ b/wtx/src/http/request.rs
@@ -1,4 +1,4 @@
-use crate::http::{Method, ReqResData, Response, StatusCode, Version};
+use crate::http::{Method, Response, StatusCode, Version};
 
 /// An HTTP request received by a server or to be sent by a client.
 #[derive(Debug)]
@@ -11,10 +11,7 @@ pub struct Request<RRD> {
   pub version: Version,
 }
 
-impl<RRD> Request<RRD>
-where
-  RRD: ReqResData,
-{
+impl<RRD> Request<RRD> {
   #[inline]
   pub(crate) fn _new(method: Method, rrd: RRD, version: Version) -> Self {
     Self { method, rrd, version }
diff --git a/wtx/src/http/response.rs b/wtx/src/http/response.rs
index 16368946..0b097509 100644
--- a/wtx/src/http/response.rs
+++ b/wtx/src/http/response.rs
@@ -11,16 +11,18 @@ pub struct Response<RRD> {
   pub version: Version,
 }
 
-impl<RRD> Response<RRD>
-where
-  RRD: ReqResData,
-{
+impl<RRD> Response<RRD> {
   /// Constructor that defaults to an HTTP/2 version.
   #[inline]
   pub fn http2(data: RRD, status_code: StatusCode) -> Self {
     Self { rrd: data, status_code, version: Version::Http2 }
   }
+}
 
+impl<RRD> Response<RRD>
+where
+  RRD: ReqResData,
+{
   /// Shortcut to access the body of `data`.
   #[inline]
   pub fn body(&self) -> &RRD::Body {
diff --git a/wtx/src/http/server_framework.rs b/wtx/src/http/server_framework.rs
index 050030a7..b288d7c8 100644
--- a/wtx/src/http/server_framework.rs
+++ b/wtx/src/http/server_framework.rs
@@ -17,12 +17,10 @@ mod route_wrappers;
 mod router;
 mod server_framework_builder;
 mod state;
+#[cfg(feature = "nightly")]
+mod tokio;
 
-use crate::{
-  http::{ConnParams, LowLevelServer, ReqResBuffer, Request, Response},
-  http2::Http2Buffer,
-  misc::Rng,
-};
+use crate::http::{conn_params::ConnParams, ReqResBuffer, Request, Response};
 use alloc::sync::Arc;
 pub use conn_aux::ConnAux;
 pub use cors_middleware::CorsMiddleware;
@@ -42,86 +40,23 @@ pub use state::{State, StateClean, StateGeneric};
 /// Server
 #[derive(Debug)]
 pub struct ServerFramework<CA, CAC, E, P, RA, RAC, REQM, RESM> {
-  ca_cb: CAC,
-  cp: ConnParams,
-  ra_cb: RAC,
-  router: Arc<Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>>,
+  _ca_cb: CAC,
+  _cp: ConnParams,
+  _ra_cb: RAC,
+  _router: Arc<Router<CA, E, P, RA, REQM, RESM>>,
 }
 
 impl<CA, CAC, E, P, RA, RAC, REQM, RESM> ServerFramework<CA, CAC, E, P, RA, RAC, REQM, RESM>
 where
-  CA: Clone + ConnAux + Send + 'static,
-  CAC: Clone + Fn() -> CA::Init + Send + 'static,
-  E: From<crate::Error> + Send + 'static,
-  P: PathManagement<CA, E, RA, ReqResBuffer, manage_path(..): Send> + Send + 'static,
-  RA: ReqAux + Send + 'static,
-  RAC: Clone + Fn() -> RA::Init + Send + 'static,
-  REQM: ReqMiddleware<CA, E, RA, ReqResBuffer, apply_req_middleware(..): Send> + Send + 'static,
-  RESM: ResMiddleware<CA, E, RA, ReqResBuffer, apply_res_middleware(..): Send> + Send + 'static,
-  Arc<Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>>: Send,
-  Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>: Send,
-  for<'any> &'any Arc<Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>>: Send,
-  for<'any> &'any Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>: Send,
+  E: From<crate::Error>,
+  P: PathManagement<CA, E, RA>,
+  RA: ReqAux,
+  REQM: ReqMiddleware<CA, E, RA>,
+  RESM: ResMiddleware<CA, E, RA>,
 {
-  /// Starts listening to incoming requests based on the given `host`.
-  #[inline]
-  pub async fn listen<RNG>(
-    self,
-    host: &str,
-    rng: RNG,
-    err_cb: impl Clone + Fn(E) + Send + 'static,
-  ) -> crate::Result<()>
-  where
-    RNG: Clone + Rng + Send + 'static,
-  {
-    let Self { ca_cb, cp, ra_cb, router } = self;
-    LowLevelServer::tokio_http2(
-      host,
-      move || Ok((CA::conn_aux(ca_cb())?, Http2Buffer::new(rng.clone()), cp._to_hp())),
-      err_cb,
-      Self::handle,
-      move || Ok(((ra_cb.clone(), Arc::clone(&router)), ReqResBuffer::empty())),
-      (|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
-    )
-    .await
-  }
-
-  /// Starts listening to incoming encrypted requests based on the given `host`.
-  #[cfg(feature = "tokio-rustls")]
-  #[inline]
-  pub async fn listen_tls<RNG>(
-    self,
-    (cert_chain, priv_key): (&'static [u8], &'static [u8]),
-    host: &str,
-    rng: RNG,
-    err_cb: impl Clone + Fn(E) + Send + 'static,
-  ) -> crate::Result<()>
-  where
-    RNG: Clone + Rng + Send + 'static,
-  {
-    let Self { ca_cb, cp, ra_cb, router } = self;
-    LowLevelServer::tokio_http2(
-      host,
-      move || Ok((CA::conn_aux(ca_cb())?, Http2Buffer::new(rng.clone()), cp._to_hp())),
-      err_cb,
-      Self::handle,
-      move || Ok(((ra_cb.clone(), Arc::clone(&router)), ReqResBuffer::empty())),
-      (
-        || {
-          crate::misc::TokioRustlsAcceptor::without_client_auth()
-            .http2()
-            .build_with_cert_chain_and_priv_key(cert_chain, priv_key)
-        },
-        |acceptor| acceptor.clone(),
-        |acceptor, stream| async move { Ok(tokio::io::split(acceptor.accept(stream).await?)) },
-      ),
-    )
-    .await
-  }
-
-  async fn handle(
+  async fn _auto(
     mut ca: CA,
-    (ra_cb, router): (impl Fn() -> RA::Init, Arc<Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>>),
+    (ra_cb, router): (impl Fn() -> RA::Init, Arc<Router<CA, E, P, RA, REQM, RESM>>),
     mut req: Request<ReqResBuffer>,
   ) -> Result<Response<ReqResBuffer>, E> {
     let mut ra = RA::req_aux(ra_cb(), &mut req)?;
diff --git a/wtx/src/http/server_framework/cors_middleware.rs b/wtx/src/http/server_framework/cors_middleware.rs
index 22ee4cc3..f4d53ff3 100644
--- a/wtx/src/http/server_framework/cors_middleware.rs
+++ b/wtx/src/http/server_framework/cors_middleware.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
     server_framework::{ConnAux, ResMiddleware},
-    Header, KnownHeaderName, Method, ReqResDataMut, Response,
+    Header, KnownHeaderName, Method, ReqResBuffer, ReqResDataMut, Response,
   },
   misc::ArrayVector,
 };
@@ -116,17 +116,16 @@ impl ConnAux for CorsMiddleware {
   }
 }
 
-impl<CA, E, RA, RRD> ResMiddleware<CA, E, RA, RRD> for CorsMiddleware
+impl<CA, E, RA> ResMiddleware<CA, E, RA> for CorsMiddleware
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut,
 {
   #[inline]
   async fn apply_res_middleware(
     &self,
     _: &mut CA,
     _: &mut RA,
-    res: Response<&mut RRD>,
+    res: Response<&mut ReqResBuffer>,
   ) -> Result<(), E> {
     let Self {
       allow_credentials,
diff --git a/wtx/src/http/server_framework/endpoint.rs b/wtx/src/http/server_framework/endpoint.rs
index 3b9b89ac..6b52bdd0 100644
--- a/wtx/src/http/server_framework/endpoint.rs
+++ b/wtx/src/http/server_framework/endpoint.rs
@@ -1,26 +1,25 @@
 use crate::{
-  http::{server_framework::ResFinalizer, ReqResDataMut, Request, StatusCode},
+  http::{server_framework::ResFinalizer, ReqResBuffer, Request, StatusCode},
   misc::{FnFut, FnFutWrapper},
 };
 use core::future::Future;
 
 /// Endpoint that generates a response.
-pub trait Endpoint<CA, E, RA, RRD> {
+pub trait Endpoint<CA, E, RA> {
   /// Calls endpoint logic
   fn call(
     &self,
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> impl Future<Output = Result<StatusCode, E>>;
 }
 
-impl<CA, E, F, RA, RES, RRD> Endpoint<CA, E, RA, RRD> for FnFutWrapper<(), F>
+impl<CA, E, F, RA, RES> Endpoint<CA, E, RA> for FnFutWrapper<(), F>
 where
   F: FnFut<(), Result = RES>,
-  RES: ResFinalizer<E, RRD>,
-  RRD: ReqResDataMut,
+  RES: ResFinalizer<E>,
 {
   #[inline]
   async fn call(
@@ -28,7 +27,7 @@ where
     _: &mut CA,
     _: (u8, &[(&'static str, u8)]),
     _: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     req.rrd.clear();
     self.0.call(()).await.finalize_response(req)
diff --git a/wtx/src/http/server_framework/middleware.rs b/wtx/src/http/server_framework/middleware.rs
index 14b82110..78dc90ab 100644
--- a/wtx/src/http/server_framework/middleware.rs
+++ b/wtx/src/http/server_framework/middleware.rs
@@ -1,11 +1,11 @@
 use crate::{
-  http::{Request, Response},
+  http::{ReqResBuffer, Request, Response},
   misc::{FnFut, FnFutWrapper},
 };
 use core::future::Future;
 
 /// Request middleware
-pub trait ReqMiddleware<CA, E, RA, RRD>
+pub trait ReqMiddleware<CA, E, RA>
 where
   E: From<crate::Error>,
 {
@@ -14,38 +14,44 @@ where
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> impl Future<Output = Result<(), E>>;
 }
 
-impl<CA, E, RA, RRD, T> ReqMiddleware<CA, E, RA, RRD> for &T
+impl<CA, E, RA, T> ReqMiddleware<CA, E, RA> for &T
 where
   E: From<crate::Error>,
-  T: for<'any> FnFut<(&'any mut CA, &'any mut RA, &'any mut Request<RRD>), Result = Result<(), E>>,
+  T: for<'any> FnFut<
+    (&'any mut CA, &'any mut RA, &'any mut Request<ReqResBuffer>),
+    Result = Result<(), E>,
+  >,
 {
   #[inline]
   async fn apply_req_middleware(
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<(), E> {
     self.call((ca, ra, req)).await?;
     Ok(())
   }
 }
 
-impl<CA, E, RA, RRD, T> ReqMiddleware<CA, E, RA, RRD> for [T]
+impl<CA, E, RA, T> ReqMiddleware<CA, E, RA> for [T]
 where
   E: From<crate::Error>,
-  T: for<'any> FnFut<(&'any mut CA, &'any mut RA, &'any mut Request<RRD>), Result = Result<(), E>>,
+  T: for<'any> FnFut<
+    (&'any mut CA, &'any mut RA, &'any mut Request<ReqResBuffer>),
+    Result = Result<(), E>,
+  >,
 {
   #[inline]
   async fn apply_req_middleware(
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<(), E> {
     for elem in self {
       elem.call((ca, ra, req)).await?;
@@ -54,10 +60,13 @@ where
   }
 }
 
-impl<CA, E, F, RA, RRD> ReqMiddleware<CA, E, RA, RRD>
-  for FnFutWrapper<(&mut CA, &mut RA, &mut Request<RRD>), F>
+impl<CA, E, F, RA> ReqMiddleware<CA, E, RA>
+  for FnFutWrapper<(&mut CA, &mut RA, &mut Request<ReqResBuffer>), F>
 where
-  F: for<'any> FnFut<(&'any mut CA, &'any mut RA, &'any mut Request<RRD>), Result = Result<(), E>>,
+  F: for<'any> FnFut<
+    (&'any mut CA, &'any mut RA, &'any mut Request<ReqResBuffer>),
+    Result = Result<(), E>,
+  >,
   E: From<crate::Error>,
 {
   #[inline]
@@ -65,7 +74,7 @@ where
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<(), E> {
     self.0.call((ca, ra, req)).await?;
     Ok(())
@@ -73,7 +82,7 @@ where
 }
 
 /// Response middleware
-pub trait ResMiddleware<CA, E, RA, RRD>
+pub trait ResMiddleware<CA, E, RA>
 where
   E: From<crate::Error>,
 {
@@ -82,38 +91,44 @@ where
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    res: Response<&mut RRD>,
+    res: Response<&mut ReqResBuffer>,
   ) -> impl Future<Output = Result<(), E>>;
 }
 
-impl<CA, E, RA, RRD, T> ResMiddleware<CA, E, RA, RRD> for &T
+impl<CA, E, RA, T> ResMiddleware<CA, E, RA> for &T
 where
   E: From<crate::Error>,
-  T: for<'any> FnFut<(&'any mut CA, &'any mut RA, Response<&'any mut RRD>), Result = Result<(), E>>,
+  T: for<'any> FnFut<
+    (&'any mut CA, &'any mut RA, Response<&'any mut ReqResBuffer>),
+    Result = Result<(), E>,
+  >,
 {
   #[inline]
   async fn apply_res_middleware(
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    res: Response<&mut RRD>,
+    res: Response<&mut ReqResBuffer>,
   ) -> Result<(), E> {
     self.call((ca, ra, res)).await?;
     Ok(())
   }
 }
 
-impl<CA, E, RA, RRD, T> ResMiddleware<CA, E, RA, RRD> for [T]
+impl<CA, E, RA, T> ResMiddleware<CA, E, RA> for [T]
 where
   E: From<crate::Error>,
-  T: for<'any> FnFut<(&'any mut CA, &'any mut RA, Response<&'any mut RRD>), Result = Result<(), E>>,
+  T: for<'any> FnFut<
+    (&'any mut CA, &'any mut RA, Response<&'any mut ReqResBuffer>),
+    Result = Result<(), E>,
+  >,
 {
   #[inline]
   async fn apply_res_middleware(
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    res: Response<&mut RRD>,
+    res: Response<&mut ReqResBuffer>,
   ) -> Result<(), E> {
     for elem in self {
       let local_res =
@@ -124,10 +139,13 @@ where
   }
 }
 
-impl<CA, E, F, RA, RRD> ResMiddleware<CA, E, RA, RRD>
-  for FnFutWrapper<(&mut CA, &mut RA, Response<&mut RRD>), F>
+impl<CA, E, F, RA> ResMiddleware<CA, E, RA>
+  for FnFutWrapper<(&mut CA, &mut RA, Response<&mut ReqResBuffer>), F>
 where
-  F: for<'any> FnFut<(&'any mut CA, &'any mut RA, Response<&'any mut RRD>), Result = Result<(), E>>,
+  F: for<'any> FnFut<
+    (&'any mut CA, &'any mut RA, Response<&'any mut ReqResBuffer>),
+    Result = Result<(), E>,
+  >,
   E: From<crate::Error>,
 {
   #[inline]
@@ -135,7 +153,7 @@ where
     &self,
     ca: &mut CA,
     ra: &mut RA,
-    res: Response<&mut RRD>,
+    res: Response<&mut ReqResBuffer>,
   ) -> Result<(), E> {
     self.0.call((ca, ra, res)).await?;
     Ok(())
diff --git a/wtx/src/http/server_framework/param_wrappers.rs b/wtx/src/http/server_framework/param_wrappers.rs
index 00fa72d9..d31dfc68 100644
--- a/wtx/src/http/server_framework/param_wrappers.rs
+++ b/wtx/src/http/server_framework/param_wrappers.rs
@@ -5,7 +5,7 @@ mod serde_json;
 
 use crate::{
   http::HttpError,
-  misc::{bytes_split1, UriRef},
+  misc::{bytes_split1, UriString},
 };
 pub use path_owned::PathOwned;
 pub use path_str::PathStr;
@@ -15,7 +15,7 @@ pub use serde_json::SerdeJson;
 #[inline]
 fn manage_path<'uri>(
   path_defs: (u8, &[(&'static str, u8)]),
-  uri: &'uri UriRef<'_>,
+  uri: &'uri UriString,
 ) -> crate::Result<&'uri str> {
   let fun = || {
     let path = uri.path();
diff --git a/wtx/src/http/server_framework/param_wrappers/path_owned.rs b/wtx/src/http/server_framework/param_wrappers/path_owned.rs
index 423b68be..c9902598 100644
--- a/wtx/src/http/server_framework/param_wrappers/path_owned.rs
+++ b/wtx/src/http/server_framework/param_wrappers/path_owned.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
     server_framework::{param_wrappers::manage_path, Endpoint, ResFinalizer, StateGeneric},
-    ReqResDataMut, Request, StatusCode,
+    ReqResBuffer, Request, StatusCode,
   },
   misc::{FnFut, FnFutWrapper},
 };
@@ -14,14 +14,13 @@ pub struct PathOwned<T>(
   pub T,
 );
 
-impl<CA, E, F, P, RA, RES, RRD> Endpoint<CA, E, RA, RRD> for FnFutWrapper<(PathOwned<P>,), F>
+impl<CA, E, F, P, RA, RES> Endpoint<CA, E, RA> for FnFutWrapper<(PathOwned<P>,), F>
 where
   E: From<crate::Error>,
   P: FromStr,
   P::Err: Into<crate::Error>,
   F: for<'any> FnFut<(PathOwned<P>,), Result = RES>,
-  RES: ResFinalizer<E, RRD>,
-  RRD: ReqResDataMut,
+  RES: ResFinalizer<E>,
 {
   #[inline]
   async fn call(
@@ -29,25 +28,23 @@ where
     _: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     _: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     req.rrd.clear();
-    let uri = req.rrd.uri();
-    let path = manage_path(path_defs, &uri).map_err(From::from)?;
+    let path = manage_path(path_defs, &req.rrd.uri).map_err(From::from)?;
     let path_owned = PathOwned(P::from_str(path).map_err(Into::into)?);
     self.0.call((path_owned,)).await.finalize_response(req)
   }
 }
 
-impl<CA, E, F, P, RA, RES, RRD, const CLEAN: bool> Endpoint<CA, E, RA, RRD>
-  for FnFutWrapper<(StateGeneric<'_, CA, RA, RRD, CLEAN>, PathOwned<P>), F>
+impl<CA, E, F, P, RA, RES, const CLEAN: bool> Endpoint<CA, E, RA>
+  for FnFutWrapper<(StateGeneric<'_, CA, RA, ReqResBuffer, CLEAN>, PathOwned<P>), F>
 where
   E: From<crate::Error>,
   P: FromStr,
   P::Err: Into<crate::Error>,
-  F: for<'any> FnFut<(StateGeneric<'any, CA, RA, RRD, CLEAN>, PathOwned<P>), Result = RES>,
-  RES: ResFinalizer<E, RRD>,
-  RRD: ReqResDataMut,
+  F: for<'any> FnFut<(StateGeneric<'any, CA, RA, ReqResBuffer, CLEAN>, PathOwned<P>), Result = RES>,
+  RES: ResFinalizer<E>,
 {
   #[inline]
   async fn call(
@@ -55,10 +52,9 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
-    let uri = req.rrd.uri();
-    let path = manage_path(path_defs, &uri).map_err(From::from)?;
+    let path = manage_path(path_defs, &req.rrd.uri).map_err(From::from)?;
     let path_owned = PathOwned(P::from_str(path).map_err(Into::into)?);
     self.0.call((StateGeneric::new(ca, ra, req), path_owned)).await.finalize_response(req)
   }
diff --git a/wtx/src/http/server_framework/param_wrappers/path_str.rs b/wtx/src/http/server_framework/param_wrappers/path_str.rs
index 2fc51ab5..61493417 100644
--- a/wtx/src/http/server_framework/param_wrappers/path_str.rs
+++ b/wtx/src/http/server_framework/param_wrappers/path_str.rs
@@ -1,9 +1,9 @@
 use crate::{
   http::{
     server_framework::{param_wrappers::manage_path, Endpoint, ResFinalizer, StateGeneric},
-    Headers, ReqResDataMut, Request, StatusCode,
+    Headers, ReqResBuffer, Request, StatusCode,
   },
-  misc::{FnFut, FnFutWrapper},
+  misc::{FnFut, FnFutWrapper, Vector},
 };
 
 /// String reference extracted from a URI path.
@@ -13,12 +13,11 @@ pub struct PathStr<'uri>(
   pub &'uri str,
 );
 
-impl<CA, E, F, RA, RES, RRD> Endpoint<CA, E, RA, RRD> for FnFutWrapper<(PathStr<'_>,), F>
+impl<CA, E, F, RA, RES> Endpoint<CA, E, RA> for FnFutWrapper<(PathStr<'_>,), F>
 where
   E: From<crate::Error>,
   F: for<'any> FnFut<(PathStr<'any>,), Result = RES>,
-  RES: ResFinalizer<E, RRD>,
-  RRD: ReqResDataMut,
+  RES: ResFinalizer<E>,
 {
   #[inline]
   async fn call(
@@ -26,28 +25,26 @@ where
     _: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     _: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     req.rrd.clear();
-    let uri = req.rrd.uri();
-    let path = manage_path(path_defs, &uri).map_err(From::from)?;
+    let path = manage_path(path_defs, &req.rrd.uri).map_err(From::from)?;
     self.0.call((PathStr(path),)).await.finalize_response(req)
   }
 }
 
-impl<CA, E, F, RA, RES, RRD, const CLEAN: bool> Endpoint<CA, E, RA, RRD>
+impl<CA, E, F, RA, RES, const CLEAN: bool> Endpoint<CA, E, RA>
   for FnFutWrapper<
-    (StateGeneric<'_, CA, RA, (&mut RRD::Body, &mut Headers), CLEAN>, PathStr<'_>),
+    (StateGeneric<'_, CA, RA, (&mut Vector<u8>, &mut Headers), CLEAN>, PathStr<'_>),
     F,
   >
 where
   E: From<crate::Error>,
   F: for<'any> FnFut<
-    (StateGeneric<'any, CA, RA, (&'any mut RRD::Body, &'any mut Headers), CLEAN>, PathStr<'any>),
+    (StateGeneric<'any, CA, RA, (&'any mut Vector<u8>, &'any mut Headers), CLEAN>, PathStr<'any>),
     Result = RES,
   >,
-  RES: ResFinalizer<E, RRD>,
-  RRD: ReqResDataMut,
+  RES: ResFinalizer<E>,
 {
   #[inline]
   async fn call(
@@ -55,11 +52,11 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     let (body, headers, uri) = req.rrd.parts_mut();
     let mut new_req = Request::_new(req.method, (body, headers), req.version);
-    let path = manage_path(path_defs, &uri).map_err(From::from)?;
+    let path = manage_path(path_defs, uri).map_err(From::from)?;
     self
       .0
       .call((StateGeneric::new(ca, ra, &mut new_req), PathStr(path)))
diff --git a/wtx/src/http/server_framework/param_wrappers/serde_json.rs b/wtx/src/http/server_framework/param_wrappers/serde_json.rs
index 24eb4cb4..87ef3073 100644
--- a/wtx/src/http/server_framework/param_wrappers/serde_json.rs
+++ b/wtx/src/http/server_framework/param_wrappers/serde_json.rs
@@ -1,9 +1,9 @@
 use crate::{
   http::{
     server_framework::{Endpoint, ResFinalizer},
-    Header, KnownHeaderName, Mime, ReqResDataMut, Request, StatusCode,
+    Header, KnownHeaderName, Mime, ReqResBuffer, Request, StatusCode,
   },
-  misc::{serde_collect_seq_rslt, FnFut, FnFutWrapper, IterWrapper, Vector},
+  misc::{serde_collect_seq_rslt, FnFut, FnFutWrapper, IterWrapper, LeaseMut},
 };
 use serde::{de::DeserializeOwned, Serialize};
 
@@ -14,12 +14,11 @@ pub struct SerdeJson<T>(
   pub T,
 );
 
-impl<CA, E, F, RA, RES, RRD, T> Endpoint<CA, E, RA, RRD> for FnFutWrapper<(SerdeJson<T>,), F>
+impl<CA, E, F, RA, RES, T> Endpoint<CA, E, RA> for FnFutWrapper<(SerdeJson<T>,), F>
 where
   E: From<crate::Error>,
   F: FnFut<(SerdeJson<T>,), Result = RES>,
-  RES: ResFinalizer<E, RRD>,
-  RRD: ReqResDataMut<Body = Vector<u8>>,
+  RES: ResFinalizer<E>,
   T: DeserializeOwned,
 {
   #[inline]
@@ -28,49 +27,47 @@ where
     _: &mut CA,
     _: (u8, &[(&'static str, u8)]),
     _: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
-    let elem = serde_json::from_slice(req.rrd.body()).map_err(crate::Error::from)?;
-    req.rrd.clear();
+    let elem = serde_json::from_slice(&req.rrd.lease_mut().body).map_err(crate::Error::from)?;
+    req.rrd.lease_mut().clear();
     self.0.call((SerdeJson(elem),)).await.finalize_response(req)
   }
 }
 
-impl<E, RRD, T> ResFinalizer<E, RRD> for SerdeJson<T>
+impl<E, T> ResFinalizer<E> for SerdeJson<T>
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut<Body = Vector<u8>>,
   T: Serialize,
 {
   #[inline]
-  fn finalize_response(self, req: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, req: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     push_content_type(req).map_err(crate::Error::from)?;
-    serde_json::to_writer(req.rrd.body_mut(), &self.0).map_err(crate::Error::from)?;
+    serde_json::to_writer(&mut req.rrd.lease_mut().body, &self.0).map_err(crate::Error::from)?;
     Ok(StatusCode::Ok)
   }
 }
 
-impl<E, RRD, I, T> ResFinalizer<E, RRD> for SerdeJson<IterWrapper<I>>
+impl<E, I, T> ResFinalizer<E> for SerdeJson<IterWrapper<I>>
 where
   E: From<crate::Error> + From<serde_json::Error>,
-  RRD: ReqResDataMut<Body = Vector<u8>>,
   I: Iterator<Item = Result<T, E>>,
   T: Serialize,
 {
   #[inline]
-  fn finalize_response(self, req: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, req: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     push_content_type(req).map_err(crate::Error::from)?;
-    serde_collect_seq_rslt(&mut serde_json::Serializer::new(req.rrd.body_mut()), self.0 .0)?;
+    serde_collect_seq_rslt(
+      &mut serde_json::Serializer::new(&mut req.rrd.lease_mut().body),
+      self.0 .0,
+    )?;
     Ok(StatusCode::Ok)
   }
 }
 
 #[inline]
-fn push_content_type<RRD>(req: &mut Request<RRD>) -> crate::Result<()>
-where
-  RRD: ReqResDataMut,
-{
-  req.rrd.headers_mut().push_from_iter(Header::from_name_and_value(
+fn push_content_type(req: &mut Request<ReqResBuffer>) -> crate::Result<()> {
+  req.rrd.lease_mut().headers.push_from_iter(Header::from_name_and_value(
     KnownHeaderName::ContentType.into(),
     [Mime::Json.as_str().as_bytes()],
   ))?;
diff --git a/wtx/src/http/server_framework/path_management.rs b/wtx/src/http/server_framework/path_management.rs
index e4b91d73..5ecace07 100644
--- a/wtx/src/http/server_framework/path_management.rs
+++ b/wtx/src/http/server_framework/path_management.rs
@@ -1,11 +1,11 @@
 use crate::{
-  http::{Request, StatusCode},
+  http::{ReqResBuffer, Request, StatusCode},
   misc::{ArrayVector, Vector},
 };
 use core::future::Future;
 
 /// Used by all structures that somehow interact with incoming requests.
-pub trait PathManagement<CA, E, RA, RRD>
+pub trait PathManagement<CA, E, RA>
 where
   E: From<crate::Error>,
 {
@@ -18,7 +18,7 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> impl Future<Output = Result<StatusCode, E>>;
 
   /// Used internally to fill `vec` with the indices of all nested routes.
@@ -39,10 +39,10 @@ where
   ) -> crate::Result<()>;
 }
 
-impl<CA, E, RA, RRD, T> PathManagement<CA, E, RA, RRD> for &T
+impl<CA, E, RA, T> PathManagement<CA, E, RA> for &T
 where
   E: From<crate::Error>,
-  T: PathManagement<CA, E, RA, RRD>,
+  T: PathManagement<CA, E, RA>,
 {
   const IS_ROUTER: bool = T::IS_ROUTER;
 
@@ -52,7 +52,7 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     (*self).manage_path(ca, path_defs, ra, req).await
   }
diff --git a/wtx/src/http/server_framework/redirect.rs b/wtx/src/http/server_framework/redirect.rs
index c23bebb7..c2a21367 100644
--- a/wtx/src/http/server_framework/redirect.rs
+++ b/wtx/src/http/server_framework/redirect.rs
@@ -1,6 +1,6 @@
 use crate::http::{
-  server_framework::ResFinalizer, Header, Headers, KnownHeaderName, ReqResDataMut, Request,
-  StatusCode,
+  server_framework::ResFinalizer, Header, Headers, KnownHeaderName, ReqResBuffer, ReqResDataMut,
+  Request, StatusCode,
 };
 
 /// Redirects a request to another location.
@@ -65,13 +65,12 @@ impl Redirect {
   }
 }
 
-impl<E, RRD> ResFinalizer<E, RRD> for Redirect
+impl<E> ResFinalizer<E> for Redirect
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut,
 {
   #[inline]
-  fn finalize_response(self, req: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, req: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     Self::push_headers(req.rrd.headers_mut(), self.uri)?;
     Ok(self.status_code)
   }
diff --git a/wtx/src/http/server_framework/req_aux.rs b/wtx/src/http/server_framework/req_aux.rs
index 38ff6a23..fd1a6e7a 100644
--- a/wtx/src/http/server_framework/req_aux.rs
+++ b/wtx/src/http/server_framework/req_aux.rs
@@ -1,4 +1,4 @@
-use crate::http::{ReqResDataMut, Request};
+use crate::http::{ReqResBuffer, Request};
 
 /// Auxiliary structure for requests
 pub trait ReqAux: Sized {
@@ -6,7 +6,5 @@ pub trait ReqAux: Sized {
   type Init;
 
   /// Creates a new instance with [`ReqAux::Init`] as well as with a request.
-  fn req_aux<RRD>(init: Self::Init, req: &mut Request<RRD>) -> crate::Result<Self>
-  where
-    RRD: ReqResDataMut;
+  fn req_aux(init: Self::Init, req: &mut Request<ReqResBuffer>) -> crate::Result<Self>;
 }
diff --git a/wtx/src/http/server_framework/res_finalizer.rs b/wtx/src/http/server_framework/res_finalizer.rs
index 976a6fc6..926bb14d 100644
--- a/wtx/src/http/server_framework/res_finalizer.rs
+++ b/wtx/src/http/server_framework/res_finalizer.rs
@@ -1,78 +1,71 @@
-use crate::{
-  http::{server_framework::StateClean, ReqResDataMut, Request, StatusCode},
-  misc::Vector,
-};
+use crate::http::{server_framework::StateClean, ReqResBuffer, Request, StatusCode};
 
 /// Modifies responses
-pub trait ResFinalizer<E, RRD> {
+pub trait ResFinalizer<E> {
   /// Finalize response
-  fn finalize_response(self, req: &mut Request<RRD>) -> Result<StatusCode, E>;
+  fn finalize_response(self, req: &mut Request<ReqResBuffer>) -> Result<StatusCode, E>;
 }
 
-impl<E, RRD> ResFinalizer<E, RRD> for ()
+impl<E> ResFinalizer<E> for ()
 where
   E: From<crate::Error>,
 {
   #[inline]
-  fn finalize_response(self, _: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, _: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     Ok(StatusCode::Ok)
   }
 }
 
-impl<CA, E, RA, RRD> ResFinalizer<E, RRD> for (StateClean<'_, CA, RA, RRD>, StatusCode)
+impl<CA, E, RA> ResFinalizer<E> for (StateClean<'_, CA, RA, ReqResBuffer>, StatusCode)
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut,
 {
   #[inline]
-  fn finalize_response(self, _: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, _: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     self.0.req.rrd.clear();
     Ok(self.1)
   }
 }
 
-impl<CA, E, RA, RRD> ResFinalizer<E, RRD> for StateClean<'_, CA, RA, RRD>
+impl<CA, E, RA> ResFinalizer<E> for StateClean<'_, CA, RA, ReqResBuffer>
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut,
 {
   #[inline]
-  fn finalize_response(self, _: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, _: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     self.req.rrd.clear();
     Ok(StatusCode::Ok)
   }
 }
 
-impl<E, RRD> ResFinalizer<E, RRD> for StatusCode
+impl<E> ResFinalizer<E> for StatusCode
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut,
 {
   #[inline]
-  fn finalize_response(self, _: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, _: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     Ok(self)
   }
 }
 
-impl<E, RRD> ResFinalizer<E, RRD> for &'static str
+impl<E> ResFinalizer<E> for &'static str
 where
   E: From<crate::Error>,
-  RRD: ReqResDataMut<Body = Vector<u8>>,
 {
   #[inline]
-  fn finalize_response(self, req: &mut Request<RRD>) -> Result<StatusCode, E> {
-    req.rrd.body_mut().extend_from_slice(self.as_bytes()).map_err(From::from)?;
+  fn finalize_response(self, req: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
+    req.rrd.body.extend_from_copyable_slice(self.as_bytes()).map_err(From::from)?;
     Ok(StatusCode::Ok)
   }
 }
 
-impl<E, RRD, T> ResFinalizer<E, RRD> for Result<T, E>
+impl<E, T> ResFinalizer<E> for Result<T, E>
 where
   E: From<crate::Error>,
-  T: ResFinalizer<E, RRD>,
+  T: ResFinalizer<E>,
 {
   #[inline]
-  fn finalize_response(self, req: &mut Request<RRD>) -> Result<StatusCode, E> {
+  fn finalize_response(self, req: &mut Request<ReqResBuffer>) -> Result<StatusCode, E> {
     self.and_then(|elem| elem.finalize_response(req))
   }
 }
diff --git a/wtx/src/http/server_framework/route_wrappers.rs b/wtx/src/http/server_framework/route_wrappers.rs
index dfbbf20b..2b1e3373 100644
--- a/wtx/src/http/server_framework/route_wrappers.rs
+++ b/wtx/src/http/server_framework/route_wrappers.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
     server_framework::{Endpoint, PathManagement},
-    HttpError, KnownHeaderName, Method, Mime, ReqResData, Request, StatusCode,
+    HttpError, KnownHeaderName, Method, Mime, ReqResBuffer, ReqResData, Request, StatusCode,
   },
   misc::{ArrayVector, FnFut, Vector},
 };
@@ -22,10 +22,10 @@ where
   Get(ty.into_wrapper())
 }
 
-impl<CA, E, RA, RRD, T> PathManagement<CA, E, RA, RRD> for Get<T>
+impl<CA, E, RA, T> PathManagement<CA, E, RA> for Get<T>
 where
   E: From<crate::Error>,
-  T: Endpoint<CA, E, RA, RRD>,
+  T: Endpoint<CA, E, RA>,
 {
   const IS_ROUTER: bool = false;
 
@@ -35,7 +35,7 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     if req.method != Method::Get {
       return Err(E::from(crate::Error::from(HttpError::UnexpectedHttpMethod {
@@ -71,11 +71,10 @@ where
   Json(ty.into_wrapper())
 }
 
-impl<CA, E, T, RA, RRD> PathManagement<CA, E, RA, RRD> for Json<T>
+impl<CA, E, T, RA> PathManagement<CA, E, RA> for Json<T>
 where
   E: From<crate::Error>,
-  T: Endpoint<CA, E, RA, RRD>,
-  RRD: ReqResData,
+  T: Endpoint<CA, E, RA>,
 {
   const IS_ROUTER: bool = false;
 
@@ -85,7 +84,7 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     if req
       .rrd
@@ -129,10 +128,10 @@ where
   Post(ty.into_wrapper())
 }
 
-impl<CA, E, T, RA, RRD> PathManagement<CA, E, RA, RRD> for Post<T>
+impl<CA, E, T, RA> PathManagement<CA, E, RA> for Post<T>
 where
   E: From<crate::Error>,
-  T: Endpoint<CA, E, RA, RRD>,
+  T: Endpoint<CA, E, RA>,
 {
   const IS_ROUTER: bool = false;
 
@@ -142,7 +141,7 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     if req.method != Method::Post {
       return Err(E::from(crate::Error::from(HttpError::UnexpectedHttpMethod {
diff --git a/wtx/src/http/server_framework/router.rs b/wtx/src/http/server_framework/router.rs
index aacac44c..db54e0c6 100644
--- a/wtx/src/http/server_framework/router.rs
+++ b/wtx/src/http/server_framework/router.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
     server_framework::{PathManagement, ReqMiddleware, ResMiddleware},
-    ReqResData, Request, Response, StatusCode,
+    ReqResBuffer, Request, Response, StatusCode,
   },
   misc::{ArrayVector, Vector},
 };
@@ -9,19 +9,19 @@ use core::marker::PhantomData;
 
 /// Redirects requests to specific asynchronous functions based on the set of inner URIs.
 #[derive(Debug)]
-pub struct Router<CA, E, P, RA, REQM, RESM, RRD> {
+pub struct Router<CA, E, P, RA, REQM, RESM> {
   pub(crate) paths: P,
-  pub(crate) phantom: PhantomData<(CA, E, RA, RRD)>,
+  pub(crate) phantom: PhantomData<(CA, E, RA)>,
   pub(crate) req_middlewares: REQM,
   pub(crate) res_middlewares: RESM,
   #[cfg(feature = "matchit")]
   pub(crate) router: matchit::Router<ArrayVector<(&'static str, u8), 8>>,
 }
 
-impl<CA, E, P, RA, REQM, RESM, RRD> Router<CA, E, P, RA, REQM, RESM, RRD>
+impl<CA, E, P, RA, REQM, RESM> Router<CA, E, P, RA, REQM, RESM>
 where
   E: From<crate::Error>,
-  P: PathManagement<CA, E, RA, RRD>,
+  P: PathManagement<CA, E, RA>,
 {
   /// Creates a new instance with paths and middlewares.
   #[inline]
@@ -54,10 +54,10 @@ where
   }
 }
 
-impl<CA, E, P, RA, RRD> Router<CA, E, P, RA, (), (), RRD>
+impl<CA, E, P, RA> Router<CA, E, P, RA, (), ()>
 where
   E: From<crate::Error>,
-  P: PathManagement<CA, E, RA, RRD>,
+  P: PathManagement<CA, E, RA>,
 {
   /// Creates a new instance of empty middlewares.
   #[inline]
@@ -75,14 +75,12 @@ where
   }
 }
 
-impl<CA, E, P, RA, REQM, RESM, RRD> PathManagement<CA, E, RA, RRD>
-  for Router<CA, E, P, RA, REQM, RESM, RRD>
+impl<CA, E, P, RA, REQM, RESM> PathManagement<CA, E, RA> for Router<CA, E, P, RA, REQM, RESM>
 where
   E: From<crate::Error>,
-  P: PathManagement<CA, E, RA, RRD>,
-  REQM: ReqMiddleware<CA, E, RA, RRD>,
-  RESM: ResMiddleware<CA, E, RA, RRD>,
-  RRD: ReqResData,
+  P: PathManagement<CA, E, RA>,
+  REQM: ReqMiddleware<CA, E, RA>,
+  RESM: ResMiddleware<CA, E, RA>,
 {
   const IS_ROUTER: bool = true;
 
@@ -92,7 +90,7 @@ where
     ca: &mut CA,
     path_defs: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     self.req_middlewares.apply_req_middleware(ca, ra, req).await?;
     let status_code = self.paths.manage_path(ca, path_defs, ra, req).await?;
diff --git a/wtx/src/http/server_framework/server_framework_builder.rs b/wtx/src/http/server_framework/server_framework_builder.rs
index 5c4897e4..877a1b18 100644
--- a/wtx/src/http/server_framework/server_framework_builder.rs
+++ b/wtx/src/http/server_framework/server_framework_builder.rs
@@ -1,6 +1,6 @@
 use crate::http::{
+  conn_params::ConnParams,
   server_framework::{ConnAux, ReqAux, Router, ServerFramework},
-  ConnParams, ReqResBuffer,
 };
 use alloc::sync::Arc;
 
@@ -8,7 +8,7 @@ use alloc::sync::Arc;
 #[derive(Debug)]
 pub struct ServerFrameworkBuilder<CA, E, P, RA, REQM, RESM> {
   cp: ConnParams,
-  router: Arc<Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>>,
+  router: Arc<Router<CA, E, P, RA, REQM, RESM>>,
 }
 
 impl<CA, E, P, RA, REQM, RESM> ServerFrameworkBuilder<CA, E, P, RA, REQM, RESM>
@@ -18,7 +18,7 @@ where
 {
   /// New instance with default connection values.
   #[inline]
-  pub fn new(router: Router<CA, E, P, RA, REQM, RESM, ReqResBuffer>) -> Self {
+  pub fn new(router: Router<CA, E, P, RA, REQM, RESM>) -> Self {
     Self { cp: ConnParams::default(), router: Arc::new(router) }
   }
 
@@ -33,7 +33,7 @@ where
     CAC: Fn() -> CA::Init,
     RAC: Fn() -> RA::Init,
   {
-    ServerFramework { ca_cb, cp: self.cp, ra_cb, router: self.router }
+    ServerFramework { _ca_cb: ca_cb, _cp: self.cp, _ra_cb: ra_cb, _router: self.router }
   }
 
   /// Fills the initialization structures for all auxiliaries with default values.
@@ -51,7 +51,7 @@ where
     {
       T::default()
     }
-    ServerFramework { ca_cb: fun, cp: self.cp, ra_cb: fun, router: self.router }
+    ServerFramework { _ca_cb: fun, _cp: self.cp, _ra_cb: fun, _router: self.router }
   }
 }
 
@@ -59,7 +59,7 @@ impl<E, P, REQM, RESM> ServerFrameworkBuilder<(), E, P, (), REQM, RESM> {
   /// Build without state
   #[inline]
   pub fn without_aux(self) -> ServerFramework<(), fn() -> (), E, P, (), fn() -> (), REQM, RESM> {
-    ServerFramework { ca_cb: nothing, cp: self.cp, ra_cb: nothing, router: self.router }
+    ServerFramework { _ca_cb: nothing, _cp: self.cp, _ra_cb: nothing, _router: self.router }
   }
 }
 
@@ -76,7 +76,7 @@ where
   where
     CAC: Fn() -> CA::Init,
   {
-    ServerFramework { ca_cb, cp: self.cp, ra_cb: nothing, router: self.router }
+    ServerFramework { _ca_cb: ca_cb, _cp: self.cp, _ra_cb: nothing, _router: self.router }
   }
 }
 
@@ -93,7 +93,7 @@ where
   where
     RAC: Fn() -> RA::Init,
   {
-    ServerFramework { ca_cb: nothing, cp: self.cp, ra_cb, router: self.router }
+    ServerFramework { _ca_cb: nothing, _cp: self.cp, _ra_cb: ra_cb, _router: self.router }
   }
 }
 
diff --git a/wtx/src/http/server_framework/state.rs b/wtx/src/http/server_framework/state.rs
index e7b5afc9..771004bb 100644
--- a/wtx/src/http/server_framework/state.rs
+++ b/wtx/src/http/server_framework/state.rs
@@ -1,7 +1,7 @@
 use crate::{
   http::{
     server_framework::{Endpoint, ResFinalizer},
-    ReqResDataMut, Request, StatusCode,
+    ReqResBuffer, ReqResDataMut, Request, StatusCode,
   },
   misc::{FnFut, FnFutWrapper},
 };
@@ -41,12 +41,11 @@ where
   }
 }
 
-impl<CA, E, F, RA, RES, RRD, const CLEAN: bool> Endpoint<CA, E, RA, RRD>
-  for FnFutWrapper<(StateGeneric<'_, CA, RA, RRD, CLEAN>,), F>
+impl<CA, E, F, RA, RES, const CLEAN: bool> Endpoint<CA, E, RA>
+  for FnFutWrapper<(StateGeneric<'_, CA, RA, ReqResBuffer, CLEAN>,), F>
 where
-  F: for<'any> FnFut<(StateGeneric<'any, CA, RA, RRD, CLEAN>,), Result = RES>,
-  RES: ResFinalizer<E, RRD>,
-  RRD: ReqResDataMut,
+  F: for<'any> FnFut<(StateGeneric<'any, CA, RA, ReqResBuffer, CLEAN>,), Result = RES>,
+  RES: ResFinalizer<E>,
 {
   #[inline]
   async fn call(
@@ -54,8 +53,27 @@ where
     ca: &mut CA,
     _: (u8, &[(&'static str, u8)]),
     ra: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<StatusCode, E> {
     self.0.call((StateGeneric::new(ca, ra, req),)).await.finalize_response(req)
   }
 }
+
+impl<'any, CA, RA, RRD, const CLEAN: bool> From<&'any mut (CA, RA, Request<RRD>)>
+  for StateGeneric<'any, CA, RA, RRD, CLEAN>
+{
+  #[inline]
+  fn from((ca, ra, req): &'any mut (CA, RA, Request<RRD>)) -> Self {
+    Self { ca, ra, req }
+  }
+}
+
+impl<'any, CA, RA, RRD, const CLEAN: bool>
+  From<&'any mut (&'any mut CA, &'any mut RA, Request<RRD>)>
+  for StateGeneric<'any, CA, RA, RRD, CLEAN>
+{
+  #[inline]
+  fn from((ca, ra, req): &'any mut (&'any mut CA, &'any mut RA, Request<RRD>)) -> Self {
+    Self { ca, ra, req }
+  }
+}
diff --git a/wtx/src/http/server_framework/tokio.rs b/wtx/src/http/server_framework/tokio.rs
new file mode 100644
index 00000000..c0088024
--- /dev/null
+++ b/wtx/src/http/server_framework/tokio.rs
@@ -0,0 +1,110 @@
+use tokio::{
+  io::WriteHalf,
+  net::{tcp::OwnedWriteHalf, TcpStream},
+};
+use tokio_rustls::server::TlsStream;
+
+use crate::{
+  http::{
+    server_framework::{
+      ConnAux, PathManagement, ReqAux, ReqMiddleware, ResMiddleware, Router, ServerFramework,
+    },
+    Headers, OptionedServer, ReqResBuffer,
+  },
+  http2::{Http2Buffer, ServerStreamTokio},
+  misc::Rng,
+  web_socket::WebSocketError,
+};
+use std::sync::Arc;
+
+impl<CA, CAC, E, P, RA, RAC, REQM, RESM> ServerFramework<CA, CAC, E, P, RA, RAC, REQM, RESM>
+where
+  CA: Clone + ConnAux + Send + 'static,
+  CAC: Clone + Fn() -> CA::Init + Send + 'static,
+  E: From<crate::Error> + Send + 'static,
+  P: PathManagement<CA, E, RA, manage_path(..): Send> + Send + 'static,
+  RA: ReqAux + Send + 'static,
+  RAC: Clone + Fn() -> RA::Init + Send + 'static,
+  REQM: ReqMiddleware<CA, E, RA, apply_req_middleware(..): Send> + Send + 'static,
+  RESM: ResMiddleware<CA, E, RA, apply_res_middleware(..): Send> + Send + 'static,
+  Arc<Router<CA, E, P, RA, REQM, RESM>>: Send,
+  Router<CA, E, P, RA, REQM, RESM>: Send,
+  for<'any> &'any Arc<Router<CA, E, P, RA, REQM, RESM>>: Send,
+  for<'any> &'any Router<CA, E, P, RA, REQM, RESM>: Send,
+{
+  /// Starts listening to incoming requests based on the given `host`.
+  #[inline]
+  pub async fn listen_tokio<RNG>(
+    self,
+    host: &str,
+    rng: RNG,
+    err_cb: impl Clone + Fn(E) + Send + 'static,
+  ) -> crate::Result<()>
+  where
+    RNG: Clone + Rng + Send + 'static,
+  {
+    let Self { _ca_cb: ca_cb, _cp: cp, _ra_cb: ra_cb, _router: router } = self;
+    OptionedServer::tokio_high_http2(
+      host,
+      Self::_auto,
+      move || Ok((CA::conn_aux(ca_cb())?, Http2Buffer::new(rng.clone()), cp._to_hp())),
+      err_cb,
+      Self::manual_tokio,
+      move || Ok(((ra_cb.clone(), Arc::clone(&router)), ReqResBuffer::empty())),
+      (|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
+    )
+    .await
+  }
+
+  /// Starts listening to incoming encrypted requests based on the given `host`.
+  #[cfg(feature = "tokio-rustls")]
+  #[inline]
+  pub async fn listen_tokio_rustls<RNG>(
+    self,
+    (cert_chain, priv_key): (&'static [u8], &'static [u8]),
+    host: &str,
+    rng: RNG,
+    err_cb: impl Clone + Fn(E) + Send + 'static,
+  ) -> crate::Result<()>
+  where
+    RNG: Clone + Rng + Send + 'static,
+  {
+    let Self { _ca_cb: ca_cb, _cp: cp, _ra_cb: ra_cb, _router: router } = self;
+    OptionedServer::tokio_high_http2(
+      host,
+      Self::_auto,
+      move || Ok((CA::conn_aux(ca_cb())?, Http2Buffer::new(rng.clone()), cp._to_hp())),
+      err_cb,
+      Self::manual_tokio_rustls,
+      move || Ok(((ra_cb.clone(), Arc::clone(&router)), ReqResBuffer::empty())),
+      (
+        || {
+          crate::misc::TokioRustlsAcceptor::without_client_auth()
+            .http2()
+            .build_with_cert_chain_and_priv_key(cert_chain, priv_key)
+        },
+        |acceptor| acceptor.clone(),
+        |acceptor, stream| async move { Ok(tokio::io::split(acceptor.accept(stream).await?)) },
+      ),
+    )
+    .await
+  }
+
+  async fn manual_tokio(
+    _: CA,
+    _: (impl Fn() -> RA::Init, Arc<Router<CA, E, P, RA, REQM, RESM>>),
+    _: Headers,
+    _: ServerStreamTokio<Http2Buffer, OwnedWriteHalf, false>,
+  ) -> Result<(), E> {
+    Err(E::from(crate::Error::WebSocketError(WebSocketError::ConnectionClosed)))
+  }
+
+  async fn manual_tokio_rustls(
+    _: CA,
+    _: (impl Fn() -> RA::Init, Arc<Router<CA, E, P, RA, REQM, RESM>>),
+    _: Headers,
+    _: ServerStreamTokio<Http2Buffer, WriteHalf<TlsStream<TcpStream>>, false>,
+  ) -> Result<(), E> {
+    Err(E::from(crate::Error::WebSocketError(WebSocketError::ConnectionClosed)))
+  }
+}
diff --git a/wtx/src/http/session.rs b/wtx/src/http/session.rs
index f02a72a0..c8f617e2 100644
--- a/wtx/src/http/session.rs
+++ b/wtx/src/http/session.rs
@@ -9,7 +9,7 @@ use crate::{
   http::{
     cookie::{encrypt, CookieGeneric},
     server_framework::ConnAux,
-    Header, KnownHeaderName, ReqResDataMut,
+    Header, KnownHeaderName, ReqResBuffer, ReqResDataMut,
   },
   misc::{GenericTime, Lease, LeaseMut, Lock, Rng, Vector},
 };
@@ -81,7 +81,7 @@ where
   where
     CS: Serialize,
     RNG: Rng,
-    RRD: ReqResDataMut<Body = Vector<u8>>,
+    RRD: LeaseMut<ReqResBuffer>,
   {
     let SessionInner { cookie_def, phantom: _, key, state } = &mut *self.content.lock().await;
     cookie_def.value.clear();
@@ -93,18 +93,18 @@ where
     } else {
       SessionState { custom_state, expire: None, id }
     };
-    let idx = rrd.body().len();
-    serde_json::to_writer(rrd.body_mut(), &local_state).map_err(Into::into)?;
+    let idx = rrd.lease().body.len();
+    serde_json::to_writer(&mut rrd.lease_mut().body, &local_state).map_err(Into::into)?;
     *state = Some(local_state);
     let rslt = encrypt(
       &mut cookie_def.value,
       key,
-      (cookie_def.name, rrd.body().get(idx..).unwrap_or_default()),
+      (cookie_def.name, rrd.lease().body.get(idx..).unwrap_or_default()),
       rng,
     );
-    rrd.body_mut().truncate(idx);
+    rrd.lease_mut().body.truncate(idx);
     rslt?;
-    rrd.headers_mut().push_from_fmt(Header::from_name_and_value(
+    rrd.lease_mut().headers.push_from_fmt(Header::from_name_and_value(
       KnownHeaderName::SetCookie.into(),
       format_args!("{}", &cookie_def),
     ))?;
diff --git a/wtx/src/http/session/session_decoder.rs b/wtx/src/http/session/session_decoder.rs
index 9ceaae2c..e58ecc49 100644
--- a/wtx/src/http/session/session_decoder.rs
+++ b/wtx/src/http/session/session_decoder.rs
@@ -2,10 +2,10 @@ use crate::{
   http::{
     cookie::{decrypt, CookieBytes},
     server_framework::ReqMiddleware,
-    KnownHeaderName, ReqResDataMut, Request, Session, SessionError, SessionInner, SessionState,
+    KnownHeaderName, ReqResBuffer, Request, Session, SessionError, SessionInner, SessionState,
     SessionStore,
   },
-  misc::{GenericTime, LeaseMut, Lock, Vector},
+  misc::{GenericTime, LeaseMut, Lock},
 };
 use chrono::DateTime;
 use core::marker::PhantomData;
@@ -28,13 +28,12 @@ impl<L, SS> SessionDecoder<L, SS> {
   }
 }
 
-impl<CA, CS, E, L, RA, RRD, SS> ReqMiddleware<CA, E, RA, RRD> for SessionDecoder<L, SS>
+impl<CA, CS, E, L, RA, SS> ReqMiddleware<CA, E, RA> for SessionDecoder<L, SS>
 where
   CA: LeaseMut<Session<L, SS>>,
   CS: DeserializeOwned + PartialEq,
   E: From<crate::Error>,
   L: Lock<Resource = SessionInner<CS, E>>,
-  RRD: ReqResDataMut<Body = Vector<u8>>,
   SS: SessionStore<CS, E>,
 {
   #[inline]
@@ -42,7 +41,7 @@ where
     &self,
     ca: &mut CA,
     _: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<(), E> {
     let Session { content, store } = ca.lease_mut();
     let SessionInner { cookie_def, phantom: _, key, state } = &mut *content.lock().await;
@@ -57,7 +56,8 @@ where
       }
       return Ok(());
     }
-    let (vector, headers, _) = req.rrd.parts_mut();
+    let lease = req.rrd.lease_mut();
+    let (vector, headers) = (&mut lease.body, &mut lease.headers);
     for header in headers.iter() {
       if header.name != <&[u8]>::from(KnownHeaderName::Cookie) {
         continue;
@@ -67,7 +67,7 @@ where
         continue;
       }
       let idx = vector.len();
-      vector.extend_from_slice(&cookie_def.value).map_err(Into::into)?;
+      vector.extend_from_copyable_slice(&cookie_def.value).map_err(Into::into)?;
       cookie_def.value.clear();
       let dec_rslt = decrypt(
         &mut cookie_def.value,
diff --git a/wtx/src/http/session/session_enforcer.rs b/wtx/src/http/session/session_enforcer.rs
index cbdc2973..30dfa293 100644
--- a/wtx/src/http/session/session_enforcer.rs
+++ b/wtx/src/http/session/session_enforcer.rs
@@ -2,7 +2,8 @@ use core::marker::PhantomData;
 
 use crate::{
   http::{
-    server_framework::ReqMiddleware, ReqResData, Request, Session, SessionError, SessionInner,
+    server_framework::ReqMiddleware, ReqResBuffer, ReqResData, Request, Session, SessionError,
+    SessionInner,
   },
   misc::{Lease, Lock},
 };
@@ -12,36 +13,34 @@ use crate::{
 ///
 #[derive(Debug)]
 pub struct SessionEnforcer<L, SS, const N: usize> {
-  paths: [&'static str; N],
+  denied: [&'static str; N],
   phantom: PhantomData<(L, SS)>,
 }
 
 impl<L, SS, const N: usize> SessionEnforcer<L, SS, N> {
   /// Creates a new instance with paths that are not taken into consideration.
   #[inline]
-  pub fn new(paths: [&'static str; N]) -> Self {
-    Self { paths, phantom: PhantomData }
+  pub fn new(denied: [&'static str; N]) -> Self {
+    Self { denied, phantom: PhantomData }
   }
 }
 
-impl<CA, CS, E, L, RA, RRD, SS, const N: usize> ReqMiddleware<CA, E, RA, RRD>
-  for SessionEnforcer<L, SS, N>
+impl<CA, CS, E, L, RA, SS, const N: usize> ReqMiddleware<CA, E, RA> for SessionEnforcer<L, SS, N>
 where
   CA: Lease<Session<L, SS>>,
   E: From<crate::Error>,
   L: Lock<Resource = SessionInner<CS, E>>,
-  RRD: ReqResData,
 {
   #[inline]
   async fn apply_req_middleware(
     &self,
     ca: &mut CA,
     _: &mut RA,
-    req: &mut Request<RRD>,
+    req: &mut Request<ReqResBuffer>,
   ) -> Result<(), E> {
     let uri = req.rrd.uri();
     let path = uri.path();
-    if self.paths.iter().any(|elem| *elem == path) {
+    if self.denied.iter().all(|elem| *elem != path) {
       return Ok(());
     }
     if ca.lease().content.lock().await.state().is_none() {
diff --git a/wtx/src/http2.rs b/wtx/src/http2.rs
index 8f148d5c..b8094a5a 100644
--- a/wtx/src/http2.rs
+++ b/wtx/src/http2.rs
@@ -1,7 +1,7 @@
 //! HTTP/2
 //!
 //! 1. Does not support padded headers when writing.
-//! 2. Does not support push promises (Deprecated by the RFC).
+//! 2. Does not support push promises (Deprecated by major third-parties).
 //! 3. Does not support prioritization (Deprecated by the RFC).
 
 #[macro_use]
@@ -9,6 +9,7 @@ mod macros;
 
 mod client_stream;
 mod common_flags;
+mod common_stream;
 mod continuation_frame;
 mod data_frame;
 mod frame_init;
@@ -26,12 +27,16 @@ mod http2_error;
 mod http2_error_code;
 mod http2_params;
 mod http2_params_send;
+mod http2_status;
 mod huffman;
 mod huffman_tables;
+mod index_map;
+mod initial_server_header;
 mod misc;
 mod ping_frame;
 mod process_receipt_frame_ty;
 mod reset_stream_frame;
+mod send_data_mode;
 mod send_msg;
 mod server_stream;
 mod settings_frame;
@@ -41,14 +46,16 @@ mod stream_state;
 mod tests;
 mod u31;
 mod uri_buffer;
+#[cfg(feature = "web-socket")]
+mod web_socket_over_stream;
 mod window;
 mod window_update_frame;
 
 use crate::{
-  http::ReqResBuffer,
+  http::{Headers, Method, Protocol, ReqResBuffer},
   http2::misc::{
     frame_reader_rslt, manage_initial_stream_receiving, process_higher_operation_err, protocol_err,
-    write_array,
+    sorp_mut, write_array,
   },
   misc::{
     AtomicWaker, ConnectionState, Either, LeaseMut, Lock, PartitionedFilledBuffer, RefCounter,
@@ -57,8 +64,7 @@ use crate::{
 };
 use alloc::sync::Arc;
 pub use client_stream::ClientStream;
-pub(crate) use common_flags::CommonFlags;
-pub(crate) use continuation_frame::ContinuationFrame;
+pub use common_stream::CommonStream;
 use core::{
   future::{poll_fn, Future},
   mem,
@@ -66,33 +72,18 @@ use core::{
   sync::atomic::{AtomicBool, Ordering},
   task::Poll,
 };
-pub(crate) use data_frame::DataFrame;
-pub(crate) use frame_init::{FrameInit, FrameInitTy};
-pub(crate) use go_away_frame::GoAwayFrame;
 use hashbrown::HashMap;
-pub(crate) use headers_frame::HeadersFrame;
-pub(crate) use hpack_decoder::HpackDecoder;
-pub(crate) use hpack_encoder::HpackEncoder;
-pub(crate) use hpack_header::HpackHeaderBasic;
-pub(crate) use hpack_headers::HpackHeaders;
-pub(crate) use hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders};
 pub use http2_buffer::Http2Buffer;
 pub use http2_data::Http2Data;
 pub use http2_error::Http2Error;
 pub use http2_error_code::Http2ErrorCode;
 pub use http2_params::Http2Params;
-pub(crate) use huffman::{huffman_decode, huffman_encode};
-pub(crate) use ping_frame::PingFrame;
-pub(crate) use process_receipt_frame_ty::ProcessReceiptFrameTy;
-pub(crate) use reset_stream_frame::ResetStreamFrame;
+pub use http2_status::{Http2RecvStatus, Http2SendStatus};
+pub use send_data_mode::{SendDataMode, SendDataModeBytes};
 pub use server_stream::ServerStream;
-pub(crate) use settings_frame::SettingsFrame;
-pub(crate) use stream_receiver::{StreamControlRecvParams, StreamOverallRecvParams};
-pub(crate) use stream_state::StreamState;
-pub(crate) use u31::U31;
-pub(crate) use uri_buffer::UriBuffer;
-pub(crate) use window::Windows;
-pub(crate) use window_update_frame::WindowUpdateFrame;
+#[cfg(feature = "web-socket")]
+pub use web_socket_over_stream::{is_web_socket_handshake, WebSocketOverStream};
+pub use window::{Window, Windows};
 
 pub(crate) const MAX_BODY_LEN: u32 = max_body_len!();
 pub(crate) const MAX_HPACK_LEN: u32 = max_hpack_len!();
@@ -108,29 +99,33 @@ const PREFACE: &[u8; 24] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
 
 /// [`Http2`] instance using the mutex from tokio.
 #[cfg(feature = "tokio")]
-pub type Http2Tokio<HB, RRB, SW, const IS_CLIENT: bool> =
-  Http2<Http2DataTokio<HB, RRB, SW, IS_CLIENT>, IS_CLIENT>;
+pub type Http2Tokio<HB, SW, const IS_CLIENT: bool> =
+  Http2<Http2DataTokio<HB, SW, IS_CLIENT>, IS_CLIENT>;
 /// [`Http2Data`] instance using the mutex from tokio.
 #[cfg(feature = "tokio")]
-pub type Http2DataTokio<HB, RRB, SW, const IS_CLIENT: bool> =
-  Arc<tokio::sync::Mutex<Http2Data<HB, RRB, SW, IS_CLIENT>>>;
+pub type Http2DataTokio<HB, SW, const IS_CLIENT: bool> =
+  Arc<tokio::sync::Mutex<Http2Data<HB, SW, IS_CLIENT>>>;
+/// [`ServerStream`] instance using the mutex from tokio;
+#[cfg(feature = "tokio")]
+pub type ServerStreamTokio<HB, SW, const IS_CLIENT: bool> =
+  ServerStream<Http2DataTokio<HB, SW, IS_CLIENT>>;
 
-pub(crate) type Scrp = HashMap<U31, StreamControlRecvParams>;
-pub(crate) type Sorp<RRB> = HashMap<U31, StreamOverallRecvParams<RRB>>;
+pub(crate) type Scrp = HashMap<u31::U31, stream_receiver::StreamControlRecvParams>;
+pub(crate) type Sorp = HashMap<u31::U31, stream_receiver::StreamOverallRecvParams>;
 
 /// Negotiates initial "handshakes" or connections and also manages the creation of streams.
 #[derive(Debug)]
 pub struct Http2<HD, const IS_CLIENT: bool> {
   hd: HD,
   is_conn_open: Arc<AtomicBool>,
+  ish_id: u32,
 }
 
-impl<HB, HD, RRB, SW, const IS_CLIENT: bool> Http2<HD, IS_CLIENT>
+impl<HB, HD, SW, const IS_CLIENT: bool> Http2<HD, IS_CLIENT>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, IS_CLIENT>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, IS_CLIENT>>,
   SW: StreamWriter,
 {
   /// See [`ConnectionState`].
@@ -139,12 +134,7 @@ where
     ConnectionState::from(self.is_conn_open.load(Ordering::Relaxed))
   }
 
-  /// Sends a GOAWAY frame to the peer, which cancels the connection and consequently all ongoing
-  /// streams.
-  #[inline]
-  pub async fn send_go_away(self, error_code: Http2ErrorCode) {
-    misc::send_go_away(error_code, &mut self.hd.lock().await.parts_mut()).await;
-  }
+  send_go_away_method!();
 
   #[inline]
   pub(crate) async fn _swap_buffers(&mut self, hb: &mut HB) {
@@ -153,7 +143,7 @@ where
 
   #[inline]
   async fn manage_initial_params<const HAS_PREFACE: bool>(
-    hb: &mut Http2Buffer<RRB>,
+    hb: &mut Http2Buffer,
     hp: &Http2Params,
     stream_writer: &mut SW,
   ) -> crate::Result<(Arc<AtomicBool>, u32, PartitionedFilledBuffer, Arc<AtomicWaker>)> {
@@ -168,9 +158,9 @@ where
         write_array([sf_bytes], &hb.is_conn_open, stream_writer).await?;
       }
     } else {
-      let wuf = WindowUpdateFrame::new(
+      let wuf = window_update_frame::WindowUpdateFrame::new(
         hp.initial_window_len().wrapping_sub(initial_window_len!()).into(),
-        U31::ZERO,
+        u31::U31::ZERO,
       )?;
       if HAS_PREFACE {
         write_array([PREFACE, sf_bytes, &wuf.bytes()], &hb.is_conn_open, stream_writer).await?;
@@ -179,8 +169,10 @@ where
       }
     }
     hb.hpack_dec.set_max_bytes(hp.max_hpack_len().0);
+    hb.hpack_dec.reserve(4, 256)?;
     hb.hpack_enc.set_max_dyn_super_bytes(hp.max_hpack_len().1);
-    hb.pfb._expand_buffer(*Usize::from(hp.read_buffer_len()))?;
+    hb.hpack_enc.reserve(4, 256)?;
+    hb.pfb._reserve(*Usize::from(hp.read_buffer_len()))?;
     Ok((
       Arc::clone(&hb.is_conn_open),
       hp.max_frame_len(),
@@ -190,12 +182,11 @@ where
   }
 }
 
-impl<HB, HD, RRB, SW> Http2<HD, false>
+impl<HB, HD, SW> Http2<HD, false>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, false>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, false>>,
   SW: StreamWriter,
 {
   /// Accepts an initial connection sending the local parameters to the remote peer.
@@ -213,14 +204,16 @@ where
     let _ = stream_reader.read(&mut buffer).await?;
     if &buffer != PREFACE {
       let _rslt = stream_writer
-        .write_all(&GoAwayFrame::new(Http2ErrorCode::ProtocolError, U31::ZERO).bytes())
+        .write_all(
+          &go_away_frame::GoAwayFrame::new(Http2ErrorCode::ProtocolError, u31::U31::ZERO).bytes(),
+        )
         .await;
       return Err(protocol_err(Http2Error::NoPreface));
     }
     let (is_conn_open, max_frame_len, pfb, read_frame_waker) =
       Self::manage_initial_params::<false>(hb.lease_mut(), &hp, &mut stream_writer).await?;
     let hd = HD::new(HD::Item::new(Http2Data::new(hb, hp, stream_writer)));
-    let this = Self { hd: hd.clone(), is_conn_open: Arc::clone(&is_conn_open) };
+    let this = Self { hd: hd.clone(), is_conn_open: Arc::clone(&is_conn_open), ish_id: 0 };
     Ok((
       frame_reader::frame_reader(
         hd,
@@ -239,73 +232,105 @@ where
   /// Returns [`Either::Left`] if the network connection has been closed, either locally
   /// or externally.
   #[inline]
-  pub async fn stream(&mut self, rrb: RRB) -> crate::Result<Either<Option<RRB>, ServerStream<HD>>> {
-    let Self { hd, is_conn_open } = self;
+  pub async fn stream<T>(
+    &mut self,
+    rrb: ReqResBuffer,
+    cb: impl Fn(&mut Headers, Method, Option<Protocol>) -> T,
+  ) -> crate::Result<Either<ReqResBuffer, (ServerStream<HD>, T)>> {
+    let Self { hd, is_conn_open, ish_id } = self;
+    let curr_ish_id = *ish_id;
+    *ish_id = ish_id.wrapping_add(1);
     let rrb_opt = &mut Some(rrb);
     let mut lock_pin = pin!(hd.lock());
-    match poll_fn(|cx| {
+    let rslt = poll_fn(|cx| {
       let mut lock = lock_pin!(cx, hd, lock_pin);
       let hdpm = lock.parts_mut();
-      if let Some(mut elem) = rrb_opt.take() {
-        if !manage_initial_stream_receiving(is_conn_open, &mut elem) {
-          let rslt = frame_reader_rslt(hdpm.frame_reader_error);
-          return Poll::Ready(Either::Left((Some(elem), rslt)));
+      if let Some(mut this_rrb) = rrb_opt.take() {
+        if !manage_initial_stream_receiving(is_conn_open, &mut this_rrb) {
+          return Poll::Ready(Ok(Either::Left((
+            this_rrb,
+            frame_reader_rslt(hdpm.frame_reader_error),
+          ))));
         }
-        hdpm.hb.initial_server_header_buffers.push_back((elem, cx.waker().clone()));
+        drop(hdpm.hb.initial_server_headers.push_back(
+          curr_ish_id,
+          initial_server_header::InitialServerHeader {
+            method: Method::Get,
+            protocol: None,
+            rrb: this_rrb,
+            stream_id: u31::U31::ZERO,
+            waker: cx.waker().clone(),
+          },
+        ));
         Poll::Pending
       } else {
+        let Some(ish) = hdpm.hb.initial_server_headers.remove(&curr_ish_id) else {
+          return Poll::Ready(Err(protocol_err(Http2Error::UnknownInitialServerHeaderId)));
+        };
+        hdpm.hb.initial_server_headers.decrease_cursor();
         if !is_conn_open.load(Ordering::Relaxed) {
-          return Poll::Ready(Either::Left((
-            hdpm.hb.initial_server_header_buffers.pop_front().map(|el| el.0),
+          let this_rrb = if ish.stream_id.is_zero() {
+            ish.rrb
+          } else {
+            mem::take(&mut sorp_mut(&mut hdpm.hb.sorp, ish.stream_id)?.rrb)
+          };
+          return Poll::Ready(Ok(Either::Left((
+            this_rrb,
             frame_reader_rslt(hdpm.frame_reader_error),
-          )));
+          ))));
         }
-        let Some((method, stream_id)) = hdpm.hb.initial_server_header_params.pop_front() else {
-          return Poll::Pending;
-        };
-        Poll::Ready(Either::Right((method, stream_id)))
+        let rslt = cb(
+          &mut sorp_mut(&mut hdpm.hb.sorp, ish.stream_id)?.rrb.headers,
+          ish.method,
+          ish.protocol,
+        );
+        Poll::Ready(Ok(Either::Right((ish.method, ish.protocol, ish.stream_id, rslt))))
       }
     })
-    .await
-    {
+    .await;
+    match rslt? {
       Either::Left(elem) => {
         elem.1?;
         Ok(Either::Left(elem.0))
       }
-      Either::Right((method, stream_id)) => Ok(Either::Right(ServerStream::new(
-        hd.clone(),
-        Arc::clone(is_conn_open),
-        method,
-        _trace_span!("New server stream", stream_id = %stream_id),
-        stream_id,
+      Either::Right((method, protocol, stream_id, elem_cb)) => Ok(Either::Right((
+        ServerStream::new(
+          hd.clone(),
+          Arc::clone(is_conn_open),
+          method,
+          protocol,
+          _trace_span!("New server stream", stream_id = %stream_id),
+          stream_id,
+        ),
+        elem_cb,
       ))),
     }
   }
 }
 
-impl<HB, HD, RRB, SW> Http2<HD, true>
+impl<HB, HD, SW> Http2<HD, true>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, true>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, true>>,
   SW: StreamWriter,
 {
   /// Tries to connect to a server sending the local parameters.
   #[inline]
   pub async fn connect<SR>(
     mut hb: HB,
-    hp: Http2Params,
+    mut hp: Http2Params,
     (stream_reader, mut stream_writer): (SR, SW),
   ) -> crate::Result<(impl Future<Output = ()>, Self)>
   where
     SR: StreamReader,
   {
     hb.lease_mut().clear();
+    hp = hp.set_enable_connect_protocol(false);
     let (is_conn_open, max_frame_len, pfb, read_frame_waker) =
       Self::manage_initial_params::<true>(hb.lease_mut(), &hp, &mut stream_writer).await?;
     let hd = HD::new(HD::Item::new(Http2Data::new(hb, hp, stream_writer)));
-    let this = Self { hd: hd.clone(), is_conn_open: Arc::clone(&is_conn_open) };
+    let this = Self { hd: hd.clone(), is_conn_open: Arc::clone(&is_conn_open), ish_id: 0 };
     Ok((
       frame_reader::frame_reader(
         hd,
@@ -334,14 +359,14 @@ where
     let span = _trace_span!("New client stream", stream_id = %stream_id);
     drop(hdpm.hb.scrp.insert(
       stream_id,
-      StreamControlRecvParams {
+      stream_receiver::StreamControlRecvParams {
         is_stream_open: true,
-        stream_state: StreamState::Idle,
+        stream_state: stream_state::StreamState::Idle,
         waker: NOOP_WAKER.clone(),
         windows: Windows::initial(hdpm.hp, hdpm.hps),
       },
     ));
-    *hdpm.last_stream_id = hdpm.last_stream_id.wrapping_add(U31::TWO);
+    *hdpm.last_stream_id = hdpm.last_stream_id.wrapping_add(u31::U31::TWO);
     drop(guard);
     Ok(ClientStream::new(self.hd.clone(), Arc::clone(&self.is_conn_open), span, stream_id))
   }
@@ -353,6 +378,6 @@ where
 {
   #[inline]
   fn clone(&self) -> Self {
-    Self { hd: self.hd.clone(), is_conn_open: Arc::clone(&self.is_conn_open) }
+    Self { hd: self.hd.clone(), is_conn_open: Arc::clone(&self.is_conn_open), ish_id: self.ish_id }
   }
 }
diff --git a/wtx/src/http2/client_stream.rs b/wtx/src/http2/client_stream.rs
index 2d0aba11..fa3f1fb0 100644
--- a/wtx/src/http2/client_stream.rs
+++ b/wtx/src/http2/client_stream.rs
@@ -1,13 +1,17 @@
 use crate::{
   http::{ReqResBuffer, ReqResData, ReqUri, Request, StatusCode},
   http2::{
+    hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
     misc::{
       frame_reader_rslt, manage_initial_stream_receiving, manage_recurrent_stream_receiving,
-      process_higher_operation_err, send_go_away, send_reset_stream,
+      process_higher_operation_err,
     },
     send_msg::send_msg,
-    HpackStaticRequestHeaders, HpackStaticResponseHeaders, Http2Buffer, Http2Data, Http2ErrorCode,
-    StreamOverallRecvParams, StreamState, Windows, U31,
+    stream_receiver::StreamOverallRecvParams,
+    stream_state::StreamState,
+    u31::U31,
+    window::Windows,
+    CommonStream, Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus,
   },
   misc::{Lease, LeaseMut, Lock, RefCounter, StreamWriter, _Span},
 };
@@ -42,25 +46,40 @@ impl<HD> ClientStream<HD> {
   }
 }
 
-impl<HB, HD, RRB, SW> ClientStream<HD>
+impl<HB, HD, SW> ClientStream<HD>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, true>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, true>>,
   SW: StreamWriter,
 {
+  /// See [`CommonStream`].
+  #[inline]
+  pub fn common(&mut self) -> CommonStream<'_, HD, true> {
+    CommonStream {
+      hd: &mut self.hd,
+      is_conn_open: &self.is_conn_open,
+      span: &mut self.span,
+      stream_id: self.stream_id,
+    }
+  }
+
   /// Receive response
   ///
-  /// Higher operation that awaits for the data necessary to build a response and then closes the
+  /// High-level operation that awaits for the data necessary to build a response and then closes the
   /// stream.
   ///
   /// Returns [`Option::None`] if the network/stream connection has been closed, either locally
   /// or externally.
   ///
-  /// Should be called after [`Self::send_req`] is successfully executed.
+  /// Should be called after [`Self::send_req`] or any other low level methods that send data
+  /// are successfully executed. More specifically, should only be called in a half-closed stream
+  /// state.
   #[inline]
-  pub async fn recv_res(&mut self, rrb: RRB) -> crate::Result<(RRB, Option<StatusCode>)> {
+  pub async fn recv_res(
+    &mut self,
+    rrb: ReqResBuffer,
+  ) -> crate::Result<(Http2RecvStatus<StatusCode, ()>, ReqResBuffer)> {
     let rrb_opt = &mut Some(rrb);
     let Self { hd, is_conn_open, span, stream_id, windows } = self;
     let _e = span._enter();
@@ -72,7 +91,7 @@ where
       if let Some(mut elem) = rrb_opt.take() {
         if !manage_initial_stream_receiving(is_conn_open, &mut elem) {
           frame_reader_rslt(hdpm.frame_reader_error)?;
-          return Poll::Ready(Ok((elem, None)));
+          return Poll::Ready(Ok((Http2RecvStatus::ClosedConnection, elem)));
         }
         drop(hdpm.hb.sorp.insert(
           *stream_id,
@@ -80,6 +99,7 @@ where
             body_len: 0,
             content_length: None,
             has_initial_header: false,
+            has_one_or_more_data_frames: false,
             is_stream_open: true,
             rrb: elem,
             status_code: StatusCode::Ok,
@@ -102,16 +122,9 @@ where
     rslt
   }
 
-  /// Sends a GOAWAY frame to the peer, which cancels the connection and consequently all ongoing
-  /// streams.
-  #[inline]
-  pub async fn send_go_away(self, error_code: Http2ErrorCode) {
-    send_go_away(error_code, &mut self.hd.lock().await.parts_mut()).await;
-  }
-
   /// Send Request
   ///
-  /// Higher operation that sends all data related to a request.
+  /// Sends all data related to a request.
   ///
   /// Returns [`Option::None`] if the network/stream connection has been closed, either locally
   /// or externally.
@@ -122,7 +135,7 @@ where
     &mut self,
     req: Request<RRD>,
     req_uri: impl Into<ReqUri<'_>>,
-  ) -> crate::Result<Option<()>>
+  ) -> crate::Result<Http2SendStatus>
   where
     RRD: ReqResData,
     RRD::Body: Lease<[u8]>,
@@ -130,10 +143,10 @@ where
     let _e = self.span._enter();
     _trace!("Sending request");
     let uri = match req_uri.into() {
-      ReqUri::Data => &req.rrd.uri(),
+      ReqUri::Data => &req.rrd.uri().to_ref(),
       ReqUri::Param(elem) => elem,
     };
-    send_msg::<_, _, _, _, true>(
+    send_msg::<_, _, _, true>(
       req.rrd.body().lease(),
       &self.hd,
       req.rrd.headers(),
@@ -157,19 +170,4 @@ where
     )
     .await
   }
-
-  /// Sends a `RST_STREAM` frame to the peer, which cancels this stream.
-  #[inline]
-  pub async fn send_reset(self, error_code: Http2ErrorCode) {
-    let mut guard = self.hd.lock().await;
-    let hdpm = guard.parts_mut();
-    let _ = send_reset_stream(
-      error_code,
-      &mut hdpm.hb.scrp,
-      &mut hdpm.hb.sorp,
-      hdpm.stream_writer,
-      self.stream_id,
-    )
-    .await;
-  }
 }
diff --git a/wtx/src/http2/common_stream.rs b/wtx/src/http2/common_stream.rs
new file mode 100644
index 00000000..979f6455
--- /dev/null
+++ b/wtx/src/http2/common_stream.rs
@@ -0,0 +1,307 @@
+use crate::{
+  http::{Headers, StatusCode},
+  http2::{
+    hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
+    misc::{check_content_length, frame_reader_rslt, sorp_mut, status_recv, status_send},
+    send_data_mode::SendDataModeBytes,
+    send_msg::{
+      encode_headers, write_standalone_data, write_standalone_headers, write_standalone_trailers,
+    },
+    u31::U31,
+    window::WindowsPair,
+    Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus, SendDataMode,
+  },
+  misc::{LeaseMut, Lock, RefCounter, StreamWriter, Vector, _Span},
+};
+use alloc::sync::Arc;
+use core::{
+  future::{poll_fn, Future},
+  mem,
+  pin::pin,
+  sync::atomic::AtomicBool,
+  task::{ready, Poll},
+};
+
+/// Groups common client and server operations as well as low level methods that deal with
+/// individual frames.
+#[derive(Debug)]
+pub struct CommonStream<'instance, HD, const IS_CLIENT: bool> {
+  pub(crate) hd: &'instance mut HD,
+  pub(crate) is_conn_open: &'instance Arc<AtomicBool>,
+  pub(crate) span: &'instance mut _Span,
+  pub(crate) stream_id: U31,
+}
+
+impl<'instance, HB, HD, SW, const IS_CLIENT: bool> CommonStream<'instance, HD, IS_CLIENT>
+where
+  HB: LeaseMut<Http2Buffer>,
+  HD: RefCounter,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, IS_CLIENT>>,
+  SW: StreamWriter,
+{
+  /// Removes internal elements that are no longer necessary after the end of the stream.
+  ///
+  /// If `linger` is true, then the stream will remain alive for a short period of time to allow
+  /// the possible receiving of control frames.
+  #[inline]
+  pub async fn clear(&self, linger: bool) -> crate::Result<()> {
+    if linger {
+      crate::misc::sleep(core::time::Duration::from_millis(50)).await?;
+    }
+    let mut lock = self.hd.lock().await;
+    let hdpm = lock.parts_mut();
+    if let Some(elem) = hdpm.hb.scrp.remove(&self.stream_id) {
+      elem.waker.wake();
+    }
+    if let Some(elem) = hdpm.hb.sorp.remove(&self.stream_id) {
+      elem.waker.wake();
+    }
+    Ok(())
+  }
+
+  /// Receive Data
+  ///
+  /// Low level operation that retrieves a DATA frame sent by the remote peer. Shouldn't interact
+  /// with higher operations.
+  ///
+  /// Returns [`Http2Status::Ok`] with `true` if no more data needs to be fetched.
+  #[inline]
+  pub async fn recv_data(&mut self) -> crate::Result<Http2RecvStatus<Vector<u8>, Vector<u8>>> {
+    let _e = self.span._enter();
+    _trace!("Fetching data");
+    let mut pin = pin!(self.hd.lock());
+    poll_fn(|cx| {
+      let mut lock = lock_pin!(cx, self.hd, pin);
+      let hdpm = lock.parts_mut();
+      let sorp = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+      if let Some(elem) = status_recv(&self.is_conn_open, sorp, |local_sorp| {
+        check_content_length(&local_sorp)?;
+        Ok(mem::take(&mut local_sorp.rrb.body))
+      })? {
+        return Poll::Ready(Ok(elem));
+      }
+      if sorp.has_one_or_more_data_frames && !sorp.rrb.body.is_empty() {
+        frame_reader_rslt(hdpm.frame_reader_error)?;
+        let rslt = sorp.rrb.body.clone();
+        sorp.rrb.body.clear();
+        Poll::Ready(Ok(Http2RecvStatus::Ongoing(rslt)))
+      } else {
+        sorp.waker.clone_from(cx.waker());
+        Poll::Pending
+      }
+    })
+    .await
+  }
+
+  /// Receive Trailers
+  ///
+  /// Low level operation that retrieves one or more frames that compose a header. Shouldn't interact
+  /// with higher operations.
+  #[inline]
+  pub async fn recv_trailers(&mut self) -> crate::Result<Http2RecvStatus<Headers, ()>> {
+    let _e = self.span._enter();
+    _trace!("Fetching trailers");
+    let mut pin = pin!(self.hd.lock());
+    poll_fn(|cx| {
+      let mut lock = lock_pin!(cx, self.hd, pin);
+      let hdpm = lock.parts_mut();
+      let sorp = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+      if let Some(elem) = status_recv(&self.is_conn_open, sorp, |local_sorp| {
+        Ok(mem::take(&mut local_sorp.rrb.headers))
+      })? {
+        return Poll::Ready(Ok(elem));
+      }
+      sorp.waker.clone_from(cx.waker());
+      frame_reader_rslt(hdpm.frame_reader_error)?;
+      Poll::Pending
+    })
+    .await
+  }
+
+  /// Should be used when receiving data to re-evaluated flow control values. Both connection and
+  /// stream capacities are modified.
+  ///
+  /// `value` is capped to an integer of 31 bits.
+  #[inline]
+  pub async fn release_capacity(&mut self, value: u32) -> crate::Result<()> {
+    let mut lock = self.hd.lock().await;
+    let hdpm = lock.parts_mut();
+    let elem = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+    let mut wp = WindowsPair::new(hdpm.windows, &mut elem.windows);
+    wp.withdrawn_recv(
+      hdpm.hp,
+      &self.is_conn_open,
+      hdpm.stream_writer,
+      self.stream_id,
+      U31::from_u32(value),
+    )
+    .await
+  }
+
+  /// Should be used when sending data to re-evaluated flow control values. Both connection and
+  /// stream capacities are modified.
+  ///
+  /// `value` is capped to an integer of 31 bits.
+  #[inline]
+  pub async fn reserve_capacity(&mut self, value: u32) -> crate::Result<()> {
+    let mut lock = self.hd.lock().await;
+    let hdpm = lock.parts_mut();
+    let elem = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+    let mut wp = WindowsPair::new(hdpm.windows, &mut elem.windows);
+    wp.withdrawn_send(Some(self.stream_id), U31::from_u32(value))
+  }
+
+  /// Low level operation that sends the content of `data` as one or more DATA frames. If `eos` is
+  /// true, then the last frame is set with the end-of-stream flag. Shouldn't interact with
+  /// [`Self::send_res`].
+  ///
+  /// This method will spin until the entirety of `data` is sent and such behavior depends on the
+  /// current available window size as well as the negotiated maximum frame length.
+  #[inline]
+  pub async fn send_data<'bytes, B, const IS_SCATTERED: bool>(
+    &mut self,
+    mut data: SendDataMode<B, IS_SCATTERED>,
+    is_eos: bool,
+  ) -> crate::Result<Http2SendStatus>
+  where
+    B: SendDataModeBytes<'bytes, IS_SCATTERED>,
+  {
+    let _e = self.span._enter();
+    _trace!("Sending data");
+    let mut has_data = false;
+    let mut pin = pin!(self.hd.lock());
+    poll_fn(|cx| {
+      let mut lock = lock_pin!(cx, self.hd, pin);
+      let hdpm = lock.parts_mut();
+      let sorp = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+      if let Some(elem) = status_send::<false>(&self.is_conn_open, sorp) {
+        return Poll::Ready(Ok(elem));
+      }
+      let mut wp = WindowsPair::new(hdpm.windows, &mut sorp.windows);
+      let Ok(available_send @ 1..=u32::MAX) = u32::try_from(wp.available_send()) else {
+        cx.waker().wake_by_ref();
+        return Poll::Pending;
+      };
+      let fut = write_standalone_data(
+        available_send,
+        &mut data,
+        is_eos,
+        &mut has_data,
+        false,
+        &self.is_conn_open,
+        hdpm.hps.max_frame_len,
+        hdpm.stream_writer,
+        self.stream_id,
+        &mut wp,
+      );
+      let _ = ready!(pin!(fut).poll(cx))?;
+      if has_data {
+        Poll::Ready(Ok(Http2SendStatus::Ok))
+      } else {
+        cx.waker().wake_by_ref();
+        Poll::Pending
+      }
+    })
+    .await
+  }
+
+  send_go_away_method!();
+
+  /// Low level operation that sends the content of `headers` with at most two frames. If `is_eos`
+  /// is true, then the last frame is set with the end-of-stream flag. Shouldn't interact with
+  /// [`Self::send_res`].
+  ///
+  /// If two frames aren't enough for the contents of `headers`, try increasing the maximum frame
+  /// length.
+  #[inline]
+  pub async fn send_headers(
+    &mut self,
+    headers: &Headers,
+    is_eos: bool,
+    status_code: StatusCode,
+  ) -> crate::Result<Http2SendStatus> {
+    let _e = self.span._enter();
+    _trace!("Sending headers");
+    let mut guard = self.hd.lock().await;
+    let hdpm = guard.parts_mut();
+    let sorp = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+    if let Some(elem) = status_send::<false>(&self.is_conn_open, sorp) {
+      return Ok(elem);
+    }
+    let hsreh = HpackStaticResponseHeaders { status_code: Some(status_code) };
+    encode_headers::<false>(
+      headers,
+      (&mut hdpm.hb.hpack_enc, &mut hdpm.hb.hpack_enc_buffer),
+      (HpackStaticRequestHeaders::EMPTY, hsreh),
+    )?;
+    let _ = write_standalone_headers::<_, IS_CLIENT>(
+      &mut hdpm.hb.hpack_enc_buffer,
+      (HpackStaticRequestHeaders::EMPTY, hsreh),
+      &self.is_conn_open,
+      is_eos,
+      hdpm.hps.max_frame_len,
+      hdpm.stream_writer,
+      self.stream_id,
+    )
+    .await?;
+    Ok(Http2SendStatus::Ok)
+  }
+
+  /// Sends a reset frame to the peer, which cancels this stream.
+  #[inline]
+  pub async fn send_reset(&self, error_code: crate::http2::Http2ErrorCode) {
+    let mut guard = self.hd.lock().await;
+    let hdpm = guard.parts_mut();
+    let _ = crate::http2::misc::send_reset_stream(
+      error_code,
+      &mut hdpm.hb.scrp,
+      &mut hdpm.hb.sorp,
+      hdpm.stream_writer,
+      self.stream_id,
+    )
+    .await;
+  }
+
+  /// Low level operation that sends headers that are preceded by DATA frames and then closes
+  /// the stream. Shouldn't interact with [`Self::send_res`].
+  ///
+  /// An error will probably be returned if the end-of-stream flag was set in previous operations.
+  ///
+  /// Returns `false` if the stream is already closed.
+  #[inline]
+  pub async fn send_trailers(&mut self, trailers: &Headers) -> crate::Result<Http2SendStatus> {
+    let _e = self.span._enter();
+    _trace!("Sending {} trailers", trailers.headers_len());
+    let mut lock = self.hd.lock().await;
+    let hdpm = lock.parts_mut();
+    let sorp = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+    if let Some(elem) = status_send::<false>(&self.is_conn_open, sorp) {
+      return Ok(elem);
+    }
+    write_standalone_trailers(
+      trailers,
+      (&mut hdpm.hb.hpack_enc, &mut hdpm.hb.hpack_enc_buffer),
+      &self.is_conn_open,
+      hdpm.hps.max_frame_len,
+      hdpm.stream_writer,
+      self.stream_id,
+    )
+    .await?;
+    Ok(Http2SendStatus::Ok)
+  }
+
+  /// Stream ID
+  #[inline]
+  pub const fn stream_id(&self) -> u32 {
+    self.stream_id.u32()
+  }
+
+  /// Low level operation that returns the current flow control parameters of the stream.
+  #[inline]
+  pub async fn windows(&self) -> crate::Result<crate::http2::Windows> {
+    let mut lock = self.hd.lock().await;
+    let hdpm = lock.parts_mut();
+    let elem = sorp_mut(&mut hdpm.hb.sorp, self.stream_id)?;
+    Ok(elem.windows)
+  }
+}
diff --git a/wtx/src/http2/continuation_frame.rs b/wtx/src/http2/continuation_frame.rs
index 8d634f05..6b165408 100644
--- a/wtx/src/http2/continuation_frame.rs
+++ b/wtx/src/http2/continuation_frame.rs
@@ -1,4 +1,8 @@
-use crate::http2::{CommonFlags, FrameInit, FrameInitTy, U31};
+use crate::http2::{
+  common_flags::CommonFlags,
+  frame_init::{FrameInit, FrameInitTy},
+  u31::U31,
+};
 
 #[derive(Debug)]
 pub(crate) struct ContinuationFrame {
diff --git a/wtx/src/http2/data_frame.rs b/wtx/src/http2/data_frame.rs
index bba260b3..d8968705 100644
--- a/wtx/src/http2/data_frame.rs
+++ b/wtx/src/http2/data_frame.rs
@@ -1,6 +1,9 @@
 use crate::http2::{
+  common_flags::CommonFlags,
+  frame_init::{FrameInit, FrameInitTy},
   misc::{protocol_err, trim_frame_pad},
-  CommonFlags, FrameInit, FrameInitTy, Http2Error, U31,
+  u31::U31,
+  Http2Error,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/frame_init.rs b/wtx/src/http2/frame_init.rs
index 2904e83c..344ea305 100644
--- a/wtx/src/http2/frame_init.rs
+++ b/wtx/src/http2/frame_init.rs
@@ -1,4 +1,4 @@
-use crate::http2::{CommonFlags, U31};
+use crate::http2::{common_flags::CommonFlags, u31::U31};
 
 _create_enum! {
   #[derive(Debug, Copy, Clone, PartialEq, Eq)]
diff --git a/wtx/src/http2/frame_reader.rs b/wtx/src/http2/frame_reader.rs
index a73c7afe..61d8084b 100644
--- a/wtx/src/http2/frame_reader.rs
+++ b/wtx/src/http2/frame_reader.rs
@@ -9,7 +9,6 @@ macro_rules! prft {
       is_conn_open: &$hdpm.hb.is_conn_open,
       last_stream_id: &mut $hdpm.last_stream_id,
       pfb: $pfb,
-      phantom: PhantomData,
       read_frame_waker: &$hdpm.hb.read_frame_waker,
       recv_streams_num: &mut $hdpm.recv_streams_num,
       stream_reader: $stream_reader,
@@ -20,11 +19,15 @@ macro_rules! prft {
 }
 
 use crate::{
-  http::ReqResBuffer,
   http2::{
+    frame_init::{FrameInit, FrameInitTy},
+    go_away_frame::GoAwayFrame,
     misc::{process_higher_operation_err, protocol_err, read_frame, send_go_away, write_array},
-    FrameInit, FrameInitTy, GoAwayFrame, Http2Buffer, Http2Data, Http2Error, PingFrame,
-    ProcessReceiptFrameTy, SettingsFrame, WindowUpdateFrame,
+    ping_frame::PingFrame,
+    process_receipt_frame_ty::ProcessReceiptFrameTy,
+    settings_frame::SettingsFrame,
+    window_update_frame::WindowUpdateFrame,
+    Http2Buffer, Http2Data, Http2Error,
   },
   misc::{
     AtomicWaker, LeaseMut, Lock, PartitionedFilledBuffer, RefCounter, StreamReader, StreamWriter,
@@ -33,14 +36,13 @@ use crate::{
 use alloc::sync::Arc;
 use core::{
   future::{poll_fn, Future},
-  marker::PhantomData,
   mem,
   pin::pin,
   sync::atomic::AtomicBool,
-  task::Poll,
+  task::{ready, Poll},
 };
 
-pub(crate) async fn frame_reader<HB, HD, RRB, SR, SW, const IS_CLIENT: bool>(
+pub(crate) async fn frame_reader<HB, HD, SR, SW, const IS_CLIENT: bool>(
   hd: HD,
   is_conn_open: Arc<AtomicBool>,
   max_frame_len: u32,
@@ -48,10 +50,9 @@ pub(crate) async fn frame_reader<HB, HD, RRB, SR, SW, const IS_CLIENT: bool>(
   read_frame_waker: Arc<AtomicWaker>,
   mut stream_reader: SR,
 ) where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, IS_CLIENT>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, IS_CLIENT>>,
   SR: StreamReader,
   SW: StreamWriter,
 {
@@ -86,26 +87,27 @@ pub(crate) async fn frame_reader<HB, HD, RRB, SR, SW, const IS_CLIENT: bool>(
 }
 
 #[inline]
-async fn finish<HB, HD, RRB, SW, const IS_CLIENT: bool>(
+async fn finish<HB, HD, SW, const IS_CLIENT: bool>(
   err: Option<crate::Error>,
   hd: &HD,
   pfb: &mut PartitionedFilledBuffer,
 ) where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, IS_CLIENT>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, IS_CLIENT>>,
   SW: StreamWriter,
 {
   let mut lock = hd.lock().await;
   let hdpm = lock.parts_mut();
-  *hdpm.frame_reader_error = err;
+  if let Some(elem) = err {
+    *hdpm.frame_reader_error = Some(elem);
+  }
   mem::swap(pfb, &mut hdpm.hb.pfb);
   _trace!("Finishing the reading of frames");
 }
 
 #[inline]
-async fn manage_fi<HB, HD, RRB, SR, SW, const IS_CLIENT: bool>(
+async fn manage_fi<HB, HD, SR, SW, const IS_CLIENT: bool>(
   fi: FrameInit,
   hd: &HD,
   is_conn_open: &AtomicBool,
@@ -113,10 +115,9 @@ async fn manage_fi<HB, HD, RRB, SR, SW, const IS_CLIENT: bool>(
   stream_reader: &mut SR,
 ) -> crate::Result<()>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, IS_CLIENT>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, IS_CLIENT>>,
   SR: StreamReader,
   SW: StreamWriter,
 {
@@ -143,35 +144,30 @@ where
         prft!(fi, hdpm, pfb, stream_reader).header_client(&mut hdpm.hb.sorp).await?;
       } else if let Some(elem) = hdpm.hb.sorp.get_mut(&fi.stream_id) {
         prft!(fi, hdpm, pfb, stream_reader).header_server_trailer(elem).await?;
-      } else if let Some((rrb, waker)) = hdpm.hb.initial_server_header_buffers.pop_front() {
-        let rslt = prft!(fi, hdpm, pfb, stream_reader)
-          .header_server_init(&mut hdpm.hb.initial_server_header_params, rrb, &mut hdpm.hb.sorp)
-          .await;
-        waker.wake();
+      } else if let Some(ish) = hdpm.hb.initial_server_headers.front_mut() {
+        let prft = prft!(fi, hdpm, pfb, stream_reader);
+        let rslt = prft.header_server_init(ish, &mut hdpm.hb.sorp).await;
+        ish.waker.wake_by_ref();
+        hdpm.hb.initial_server_headers.increase_cursor();
         rslt?;
       } else {
         drop(lock);
         let mut lock_pin = pin!(hd.lock());
-        let (mut local_lock, rrb, waker) = poll_fn(|cx| {
+        poll_fn(|cx| {
           let mut local_lock = lock_pin!(cx, hd, lock_pin);
-          let local_hdpm = local_lock.parts_mut();
-          let Some((rrb, waker)) = local_hdpm.hb.initial_server_header_buffers.pop_front() else {
+          let mut local_hdpm = local_lock.parts_mut();
+          let Some(ish) = local_hdpm.hb.initial_server_headers.front_mut() else {
             cx.waker().wake_by_ref();
             return Poll::Pending;
           };
-          Poll::Ready((local_lock, rrb, waker))
+          let prft = prft!(fi, local_hdpm, pfb, stream_reader);
+          let poll = pin!(prft.header_server_init(ish, &mut local_hdpm.hb.sorp)).poll(cx);
+          let rslt = ready!(poll);
+          ish.waker.wake_by_ref();
+          local_hdpm.hb.initial_server_headers.increase_cursor();
+          Poll::Ready(rslt)
         })
-        .await;
-        let mut local_hdpm = local_lock.parts_mut();
-        let rslt = prft!(fi, local_hdpm, pfb, stream_reader)
-          .header_server_init(
-            &mut local_hdpm.hb.initial_server_header_params,
-            rrb,
-            &mut local_hdpm.hb.sorp,
-          )
-          .await;
-        waker.wake();
-        rslt?;
+        .await?;
       }
     }
     FrameInitTy::Ping => {
@@ -205,7 +201,7 @@ where
     FrameInitTy::WindowUpdate => {
       if fi.stream_id.is_zero() {
         let wuf = WindowUpdateFrame::read(pfb._current(), fi)?;
-        hd.lock().await.parts_mut().windows.send.deposit(None, wuf.size_increment().i32())?;
+        hd.lock().await.parts_mut().windows.send_mut().deposit(None, wuf.size_increment().i32())?;
       } else {
         let mut lock = hd.lock().await;
         let mut hdpm = lock.parts_mut();
diff --git a/wtx/src/http2/go_away_frame.rs b/wtx/src/http2/go_away_frame.rs
index 275a1531..566f7606 100644
--- a/wtx/src/http2/go_away_frame.rs
+++ b/wtx/src/http2/go_away_frame.rs
@@ -1,5 +1,9 @@
 use crate::http2::{
-  misc::protocol_err, CommonFlags, FrameInit, FrameInitTy, Http2Error, Http2ErrorCode, U31,
+  common_flags::CommonFlags,
+  frame_init::{FrameInit, FrameInitTy},
+  misc::protocol_err,
+  u31::U31,
+  Http2Error, Http2ErrorCode,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/headers_frame.rs b/wtx/src/http2/headers_frame.rs
index 0259d991..e51c992d 100644
--- a/wtx/src/http2/headers_frame.rs
+++ b/wtx/src/http2/headers_frame.rs
@@ -1,11 +1,17 @@
 use crate::{
   http::{Header, HeaderName, KnownHeaderName, Method, ReqResBuffer},
   http2::{
+    common_flags::CommonFlags,
+    frame_init::{FrameInit, FrameInitTy},
+    hpack_decoder::HpackDecoder,
+    hpack_header::HpackHeaderBasic,
+    hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
     misc::{protocol_err, trim_frame_pad},
-    CommonFlags, FrameInit, FrameInitTy, HpackDecoder, HpackHeaderBasic, HpackStaticRequestHeaders,
-    HpackStaticResponseHeaders, Http2Error, Http2Params, UriBuffer, U31,
+    u31::U31,
+    uri_buffer::UriBuffer,
+    Http2Error, Http2Params,
   },
-  misc::{from_utf8_basic, ArrayString, FromRadix10, Usize},
+  misc::{from_utf8_basic, ArrayString, FromRadix10, LeaseMut, Usize},
 };
 
 // Some fields of `hsreqh` are only meant to be used locally for writing purposes.
@@ -69,7 +75,8 @@ impl<'uri> HeadersFrame<'uri> {
     fi.cf.only_eoh_eos_pad_pri();
     uri_buffer.clear();
 
-    let (rrb_body, rrb_headers, rrb_uri) = (&rrb.data, &mut rrb.headers, &mut rrb.uri);
+    let lease = rrb.lease_mut();
+    let (rrb_body, rrb_headers, rrb_uri) = (&lease.body, &mut lease.headers, &mut lease.uri);
     let mut data_bytes = data.unwrap_or_else(|| rrb_body.get(rrb_body_start..).unwrap_or_default());
     let _ = trim_frame_pad(fi.cf, &mut data_bytes)?;
     trim_priority(fi.cf, &mut data_bytes);
diff --git a/wtx/src/http2/hpack_decoder.rs b/wtx/src/http2/hpack_decoder.rs
index d7a056df..ef9dfdb3 100644
--- a/wtx/src/http2/hpack_decoder.rs
+++ b/wtx/src/http2/hpack_decoder.rs
@@ -2,9 +2,10 @@ use crate::{
   http::{KnownHeaderName, Method, StatusCode, _HeaderNameBuffer, _HeaderValueBuffer},
   http2::{
     hpack_header::{HpackHeaderBasic, HpackHeaderName},
-    huffman_decode,
+    hpack_headers::HpackHeaders,
+    huffman::huffman_decode,
     misc::protocol_err,
-    HpackHeaders, Http2Error, Http2ErrorCode,
+    Http2Error, Http2ErrorCode,
   },
   misc::{ArrayVector, Usize},
 };
@@ -47,7 +48,7 @@ impl HpackDecoder {
     mut cb: impl FnMut((HpackHeaderBasic, &[u8], &[u8])) -> crate::Result<()>,
   ) -> crate::Result<()> {
     if let Some(elem) = self.max_bytes.1.take() {
-      self.dyn_headers.set_max_bytes(*Usize::from(elem), |_, _| {});
+      self.dyn_headers.set_max_bytes(*Usize::from(elem), |_| {});
       self.max_bytes.0 = elem;
     }
     let mut did_update = false;
@@ -73,6 +74,11 @@ impl HpackDecoder {
     Ok(())
   }
 
+  #[inline]
+  pub(crate) fn reserve(&mut self, headers: usize, bytes: usize) -> crate::Result<()> {
+    self.dyn_headers.reserve(headers, bytes)
+  }
+
   // It is not possible to lower the initial set value
   #[inline]
   pub(crate) fn set_max_bytes(&mut self, max_bytes: u32) {
@@ -159,7 +165,7 @@ impl HpackDecoder {
       (hhb, name, value)
     };
     if STORE {
-      self.dyn_headers.push_front(hhb, name, [value].into_iter(), false, |_, _| {})?;
+      self.dyn_headers.push_front(hhb, name, [value].into_iter(), false, |_| {})?;
     }
     Ok(())
   }
@@ -370,7 +376,7 @@ impl HpackDecoder {
             Some(Http2Error::OutOfBoundsIndex),
           ));
         }
-        self.dyn_headers.set_max_bytes(*Usize::from(local_max_bytes), |_, _| {});
+        self.dyn_headers.set_max_bytes(*Usize::from(local_max_bytes), |_| {});
       }
     }
     Ok(())
@@ -413,7 +419,7 @@ impl TryFrom<u8> for DecodeIdx {
 mod bench {
   use crate::{
     http::Header,
-    http2::{HpackDecoder, HpackEncoder},
+    http2::{hpack_decoder::HpackDecoder, hpack_encoder::HpackEncoder},
     misc::{simple_seed, Usize, Vector, Xorshift64},
   };
 
diff --git a/wtx/src/http2/hpack_encoder.rs b/wtx/src/http2/hpack_encoder.rs
index 439b6216..b9a510b0 100644
--- a/wtx/src/http2/hpack_encoder.rs
+++ b/wtx/src/http2/hpack_encoder.rs
@@ -11,7 +11,8 @@
 use crate::{
   http::{Header, KnownHeaderName, Method, StatusCode},
   http2::{
-    hpack_header::HpackHeaderBasic, huffman_encode, misc::protocol_err, HpackHeaders, Http2Error,
+    hpack_header::HpackHeaderBasic, hpack_headers::HpackHeaders, huffman::huffman_encode,
+    misc::protocol_err, Http2Error,
   },
   misc::{Rng, Usize, Vector, _random_state, _shift_copyable_chunks, _unreachable},
 };
@@ -65,23 +66,26 @@ impl HpackEncoder {
   pub(crate) fn encode<'pseudo, 'user>(
     &mut self,
     buffer: &mut Vector<u8>,
-    pseudo_headers: impl Iterator<Item = (HpackHeaderBasic, &'pseudo [u8])>,
-    user_headers: impl Iterator<Item = Header<'user, &'user [u8]>>,
+    pseudo_headers: impl IntoIterator<Item = (HpackHeaderBasic, &'pseudo [u8])>,
+    user_headers: impl IntoIterator<Item = Header<'user, &'user [u8]>>,
   ) -> crate::Result<()> {
+    let pseudo_headers_iter = pseudo_headers.into_iter();
+    let user_headers_iter = user_headers.into_iter();
     self.adjust_indices(
-      pseudo_headers
+      pseudo_headers_iter
         .size_hint()
         .1
-        .and_then(|el| el.checked_add(user_headers.size_hint().1?))
+        .and_then(|el| el.checked_add(user_headers_iter.size_hint().1?))
         .unwrap_or(usize::MAX),
     );
-    buffer.reserve(pseudo_headers.size_hint().0.wrapping_add(user_headers.size_hint().0))?;
+    let reserve = pseudo_headers_iter.size_hint().0.wrapping_add(user_headers_iter.size_hint().0);
+    buffer.reserve(reserve)?;
     self.manage_size_update(buffer)?;
-    for (hhb, value) in pseudo_headers {
+    for (hhb, value) in pseudo_headers_iter {
       let idx = self.encode_idx((&[], value, false), hhb, Self::shi_pseudo((hhb, value)))?;
       Self::manage_encode(buffer, (&[], value), idx)?;
     }
-    for Header { is_sensitive, name, value, .. } in user_headers {
+    for Header { is_sensitive, name, value, .. } in user_headers_iter {
       let idx = self.encode_idx(
         (name, value, is_sensitive),
         HpackHeaderBasic::Field,
@@ -92,6 +96,11 @@ impl HpackEncoder {
     Ok(())
   }
 
+  #[inline]
+  pub(crate) fn reserve(&mut self, headers: usize, bytes: usize) -> crate::Result<()> {
+    self.dyn_headers.reserve(headers, bytes)
+  }
+
   // It is not possible to lower the initial set value
   #[inline]
   pub(crate) fn set_max_dyn_sub_bytes(&mut self, max_dyn_sub_bytes: u32) -> crate::Result<()> {
@@ -390,16 +399,16 @@ impl HpackEncoder {
   fn manage_size_update(&mut self, buffer: &mut Vector<u8>) -> crate::Result<()> {
     match self.max_dyn_sub_bytes.take() {
       Some((lower, None)) => {
-        self.dyn_headers.set_max_bytes(*Usize::from(lower), |metadata, _| {
+        self.dyn_headers.set_max_bytes(*Usize::from(lower), |metadata| {
           Self::remove_outdated_indices(&mut self.indcs, metadata);
         });
         let _ = Self::encode_int(buffer, 0b0010_0000, lower)?;
       }
       Some((lower, Some(upper))) => {
-        self.dyn_headers.set_max_bytes(*Usize::from(lower), |metadata, _| {
+        self.dyn_headers.set_max_bytes(*Usize::from(lower), |metadata| {
           Self::remove_outdated_indices(&mut self.indcs, metadata);
         });
-        self.dyn_headers.set_max_bytes(*Usize::from(upper), |metadata, _| {
+        self.dyn_headers.set_max_bytes(*Usize::from(upper), |metadata| {
           Self::remove_outdated_indices(&mut self.indcs, metadata);
         });
         let _ = Self::encode_int(buffer, 0b0010_0000, lower)?;
@@ -428,7 +437,7 @@ impl HpackEncoder {
       name,
       [value].into_iter(),
       is_sensitive,
-      |metadata, _| {
+      |metadata| {
         Self::remove_outdated_indices(&mut self.indcs, metadata);
       },
     )?;
@@ -645,7 +654,7 @@ struct StaticHeader {
 mod bench {
   use crate::{
     http::Header,
-    http2::HpackEncoder,
+    http2::hpack_encoder::HpackEncoder,
     misc::{simple_seed, Usize, Vector, Xorshift64},
   };
 
diff --git a/wtx/src/http2/hpack_headers.rs b/wtx/src/http2/hpack_headers.rs
index f5bbf35d..1507ec48 100644
--- a/wtx/src/http2/hpack_headers.rs
+++ b/wtx/src/http2/hpack_headers.rs
@@ -1,6 +1,6 @@
 use crate::misc::{Block, BlocksQueue};
-use core::fmt::{Debug, Formatter};
 
+#[derive(Debug)]
 pub(crate) struct HpackHeaders<M> {
   bq: BlocksQueue<u8, Metadata<M>>,
   max_bytes: usize,
@@ -47,7 +47,7 @@ where
     name: &'bytes [u8],
     values: I,
     is_sensitive: bool,
-    cb: impl FnMut(M, &mut [u8]),
+    cb: impl FnMut(M),
   ) -> crate::Result<()>
   where
     I: IntoIterator<Item = &'bytes [u8]>,
@@ -70,8 +70,14 @@ where
     Ok(())
   }
 
+  #[inline(always)]
+  pub(crate) fn reserve(&mut self, headers: usize, bytes: usize) -> crate::Result<()> {
+    self.bq.reserve_front(headers, bytes)?;
+    Ok(())
+  }
+
   #[inline]
-  pub(crate) fn set_max_bytes(&mut self, max_bytes: usize, cb: impl FnMut(M, &mut [u8])) {
+  pub(crate) fn set_max_bytes(&mut self, max_bytes: usize, cb: impl FnMut(M)) {
     self.max_bytes = max_bytes;
     self.remove_until_max_bytes(0, cb);
   }
@@ -87,33 +93,20 @@ where
   }
 
   #[inline]
-  fn pop_back(&mut self) -> Option<(Metadata<M>, &mut [u8])> {
+  fn pop_back(&mut self) -> Option<Metadata<M>> {
     self.bq.pop_back()
   }
 
   #[inline]
-  fn remove_until_max_bytes(&mut self, additional: usize, mut cb: impl FnMut(M, &mut [u8])) {
+  fn remove_until_max_bytes(&mut self, additional: usize, mut cb: impl FnMut(M)) {
     while self.bytes_len().wrapping_add(additional) > self.max_bytes {
       if let Some(elem) = self.pop_back() {
-        cb(elem.0.misc, elem.1);
+        cb(elem.misc);
       }
     }
   }
 }
 
-impl<M> Debug for HpackHeaders<M>
-where
-  M: Copy + Debug,
-{
-  #[inline]
-  fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
-    f.debug_struct("AbstractHeaders")
-      .field("max_bytes", &self.max_bytes)
-      .field("bq", &self.bq)
-      .finish()
-  }
-}
-
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub(crate) struct AbstractHeader<'ah, M> {
   pub(crate) is_sensitive: bool,
diff --git a/wtx/src/http2/hpack_static_headers.rs b/wtx/src/http2/hpack_static_headers.rs
index c53f2a9e..b7bb51e7 100644
--- a/wtx/src/http2/hpack_static_headers.rs
+++ b/wtx/src/http2/hpack_static_headers.rs
@@ -1,6 +1,6 @@
 use crate::{
   http::{Method, Protocol, StatusCode},
-  http2::HpackHeaderBasic,
+  http2::hpack_header::HpackHeaderBasic,
 };
 
 /// Mandatory headers of a HTTP/2 request
diff --git a/wtx/src/http2/http2_buffer.rs b/wtx/src/http2/http2_buffer.rs
index b331b252..ab850d6f 100644
--- a/wtx/src/http2/http2_buffer.rs
+++ b/wtx/src/http2/http2_buffer.rs
@@ -1,32 +1,30 @@
 use crate::{
-  http::Method,
-  http2::{HpackDecoder, HpackEncoder, Scrp, Sorp, UriBuffer, U31},
+  http2::{
+    hpack_decoder::HpackDecoder, hpack_encoder::HpackEncoder, index_map::IndexMap,
+    initial_server_header::InitialServerHeader, uri_buffer::UriBuffer, Scrp, Sorp,
+  },
   misc::{simple_seed, AtomicWaker, Lease, LeaseMut, PartitionedFilledBuffer, Rng, Vector},
 };
-use alloc::{boxed::Box, collections::VecDeque, sync::Arc};
-use core::{
-  sync::atomic::{AtomicBool, Ordering},
-  task::Waker,
-};
+use alloc::{boxed::Box, sync::Arc};
+use core::sync::atomic::{AtomicBool, Ordering};
 use hashbrown::HashMap;
 
 /// Groups all intermediate structures necessary to perform HTTP/2 connections.
 #[derive(Debug)]
-pub struct Http2Buffer<RRB> {
+pub struct Http2Buffer {
   pub(crate) hpack_dec: HpackDecoder,
   pub(crate) hpack_enc: HpackEncoder,
   pub(crate) hpack_enc_buffer: Vector<u8>,
-  pub(crate) initial_server_header_buffers: VecDeque<(RRB, Waker)>,
-  pub(crate) initial_server_header_params: VecDeque<(Method, U31)>,
+  pub(crate) initial_server_headers: IndexMap<u32, InitialServerHeader>,
   pub(crate) is_conn_open: Arc<AtomicBool>,
   pub(crate) pfb: PartitionedFilledBuffer,
   pub(crate) read_frame_waker: Arc<AtomicWaker>,
   pub(crate) scrp: Scrp,
-  pub(crate) sorp: Sorp<RRB>,
+  pub(crate) sorp: Sorp,
   pub(crate) uri_buffer: Box<UriBuffer>,
 }
 
-impl<RRB> Http2Buffer<RRB> {
+impl Http2Buffer {
   /// Creates a new instance without pre-allocated resources.
   #[inline]
   pub fn new<RNG>(rng: RNG) -> Self
@@ -37,8 +35,7 @@ impl<RRB> Http2Buffer<RRB> {
       hpack_dec: HpackDecoder::new(),
       hpack_enc: HpackEncoder::new(rng),
       hpack_enc_buffer: Vector::new(),
-      initial_server_header_buffers: VecDeque::new(),
-      initial_server_header_params: VecDeque::new(),
+      initial_server_headers: IndexMap::new(),
       is_conn_open: Arc::new(AtomicBool::new(false)),
       pfb: PartitionedFilledBuffer::new(),
       read_frame_waker: Arc::new(AtomicWaker::new()),
@@ -54,8 +51,7 @@ impl<RRB> Http2Buffer<RRB> {
       hpack_dec,
       hpack_enc,
       hpack_enc_buffer,
-      initial_server_header_buffers,
-      initial_server_header_params,
+      initial_server_headers,
       is_conn_open,
       pfb,
       read_frame_waker,
@@ -66,8 +62,7 @@ impl<RRB> Http2Buffer<RRB> {
     hpack_dec.clear();
     hpack_enc.clear();
     hpack_enc_buffer.clear();
-    initial_server_header_buffers.clear();
-    initial_server_header_params.clear();
+    initial_server_headers.clear();
     is_conn_open.store(false, Ordering::Relaxed);
     pfb._clear();
     let _waker = read_frame_waker.take();
@@ -77,23 +72,23 @@ impl<RRB> Http2Buffer<RRB> {
   }
 }
 
-impl<RRB> Default for Http2Buffer<RRB> {
+impl Default for Http2Buffer {
   #[inline]
   fn default() -> Self {
     Self::new(crate::misc::Xorshift64::from(simple_seed()))
   }
 }
 
-impl<RRB> Lease<Http2Buffer<RRB>> for Http2Buffer<RRB> {
+impl Lease<Http2Buffer> for Http2Buffer {
   #[inline]
-  fn lease(&self) -> &Http2Buffer<RRB> {
+  fn lease(&self) -> &Http2Buffer {
     self
   }
 }
 
-impl<RRB> LeaseMut<Http2Buffer<RRB>> for Http2Buffer<RRB> {
+impl LeaseMut<Http2Buffer> for Http2Buffer {
   #[inline]
-  fn lease_mut(&mut self) -> &mut Http2Buffer<RRB> {
+  fn lease_mut(&mut self) -> &mut Http2Buffer {
     self
   }
 }
diff --git a/wtx/src/http2/http2_data.rs b/wtx/src/http2/http2_data.rs
index 8a0b12d2..5638fc21 100644
--- a/wtx/src/http2/http2_data.rs
+++ b/wtx/src/http2/http2_data.rs
@@ -1,28 +1,26 @@
 use crate::{
-  http::ReqResBuffer,
-  http2::{http2_params_send::Http2ParamsSend, Http2Buffer, Http2Params, Windows, U31},
+  http2::{
+    http2_params_send::Http2ParamsSend, u31::U31, window::Windows, Http2Buffer, Http2Params,
+  },
   misc::{Lease, LeaseMut, StreamWriter},
 };
-use core::marker::PhantomData;
 
 /// Internal resource used in every new instance of `Http2`.
 #[derive(Debug)]
-pub struct Http2Data<HB, RRB, SW, const IS_CLIENT: bool> {
+pub struct Http2Data<HB, SW, const IS_CLIENT: bool> {
   frame_reader_error: Option<crate::Error>,
   hb: HB,
   hp: Http2Params,
   hps: Http2ParamsSend,
   last_stream_id: U31,
-  phantom: PhantomData<RRB>,
   recv_streams_num: u32,
   stream_writer: SW,
   windows: Windows,
 }
 
-impl<HB, RRB, SW, const IS_CLIENT: bool> Http2Data<HB, RRB, SW, IS_CLIENT>
+impl<HB, SW, const IS_CLIENT: bool> Http2Data<HB, SW, IS_CLIENT>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HB: LeaseMut<Http2Buffer>,
   SW: StreamWriter,
 {
   #[inline]
@@ -35,7 +33,6 @@ where
       hp,
       hps,
       last_stream_id: if IS_CLIENT { U31::ONE } else { U31::ZERO },
-      phantom: PhantomData,
       recv_streams_num: 0,
       stream_writer,
       windows,
@@ -43,7 +40,7 @@ where
   }
 
   #[inline]
-  pub(crate) fn parts_mut(&mut self) -> Http2DataPartsMut<'_, RRB, SW> {
+  pub(crate) fn parts_mut(&mut self) -> Http2DataPartsMut<'_, SW, IS_CLIENT> {
     Http2DataPartsMut {
       frame_reader_error: &mut self.frame_reader_error,
       hb: self.hb.lease_mut(),
@@ -57,27 +54,27 @@ where
   }
 }
 
-impl<HB, RRB, SW, const IS_CLIENT: bool> Lease<Http2Data<HB, RRB, SW, IS_CLIENT>>
-  for Http2Data<HB, RRB, SW, IS_CLIENT>
+impl<HB, SW, const IS_CLIENT: bool> Lease<Http2Data<HB, SW, IS_CLIENT>>
+  for Http2Data<HB, SW, IS_CLIENT>
 {
   #[inline]
-  fn lease(&self) -> &Http2Data<HB, RRB, SW, IS_CLIENT> {
+  fn lease(&self) -> &Http2Data<HB, SW, IS_CLIENT> {
     self
   }
 }
 
-impl<HB, RRB, SW, const IS_CLIENT: bool> LeaseMut<Http2Data<HB, RRB, SW, IS_CLIENT>>
-  for Http2Data<HB, RRB, SW, IS_CLIENT>
+impl<HB, SW, const IS_CLIENT: bool> LeaseMut<Http2Data<HB, SW, IS_CLIENT>>
+  for Http2Data<HB, SW, IS_CLIENT>
 {
   #[inline]
-  fn lease_mut(&mut self) -> &mut Http2Data<HB, RRB, SW, IS_CLIENT> {
+  fn lease_mut(&mut self) -> &mut Http2Data<HB, SW, IS_CLIENT> {
     self
   }
 }
 
-pub(crate) struct Http2DataPartsMut<'instance, RRB, SW> {
+pub(crate) struct Http2DataPartsMut<'instance, SW, const IS_CLIENT: bool> {
   pub(crate) frame_reader_error: &'instance mut Option<crate::Error>,
-  pub(crate) hb: &'instance mut Http2Buffer<RRB>,
+  pub(crate) hb: &'instance mut Http2Buffer,
   pub(crate) hp: &'instance mut Http2Params,
   pub(crate) hps: &'instance mut Http2ParamsSend,
   pub(crate) last_stream_id: &'instance mut U31,
diff --git a/wtx/src/http2/http2_error.rs b/wtx/src/http2/http2_error.rs
index 764b59c1..b3e82852 100644
--- a/wtx/src/http2/http2_error.rs
+++ b/wtx/src/http2/http2_error.rs
@@ -34,6 +34,8 @@ pub enum Http2Error {
   HpackDecodingBufferIsTooSmall,
   /// There are no bytes left to decode HPACK headers.
   InsufficientHpackBytes,
+  /// Content length has a value that is different than the actual payload length
+  InvalidContentLength,
   /// Continuation frame found in invalid order
   InvalidContinuationFrame,
   /// Length is greater than [`u32::MAX`].
@@ -114,14 +116,18 @@ pub enum Http2Error {
   UnexpectedPreFixedHeaderName,
   /// Servers must only receive odd IDs or IDs are lower than the current highest value
   UnexpectedStreamId,
-  /// Type is out of range or unsupported.
-  UnknownSettingFrameTy,
   /// A stream ID is not locally stored to allow the processing of data frames.
   UnknownDataStreamReceiver,
   /// A stream ID is not locally stored to allow the processing of header frames.
   UnknownHeaderStreamReceiver,
+  /// A programming error that shouldn't never happen
+  UnknownInitialServerHeaderId,
   /// A stream ID is not locally stored to allow the processing of reset frames.
   UnknownResetStreamReceiver,
+  /// Type is out of range or unsupported.
+  UnknownSettingFrameTy,
+  /// Stream id doesn't exist locally
+  UnknownStreamId,
   /// A stream ID is not locally stored.
   UnknownStreamReceiver,
   /// A stream ID is not locally stored to allow the processing of window update frames.
diff --git a/wtx/src/http2/http2_params.rs b/wtx/src/http2/http2_params.rs
index 2cb4347c..735a0561 100644
--- a/wtx/src/http2/http2_params.rs
+++ b/wtx/src/http2/http2_params.rs
@@ -1,7 +1,7 @@
 use crate::http2::{
-  SettingsFrame, MAX_BODY_LEN, MAX_CONCURRENT_STREAMS_NUM, MAX_FRAME_LEN,
+  settings_frame::SettingsFrame, u31::U31, MAX_BODY_LEN, MAX_CONCURRENT_STREAMS_NUM, MAX_FRAME_LEN,
   MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND, MAX_HEADERS_LEN, MAX_HPACK_LEN,
-  MAX_RECV_STREAMS_NUM, READ_BUFFER_LEN, U31,
+  MAX_RECV_STREAMS_NUM, READ_BUFFER_LEN,
 };
 
 /// Indicates to a remote peer the receiving parameters of a connection as well as its streams.
@@ -23,8 +23,8 @@ pub struct Http2Params {
 impl Http2Params {
   /// Enable connect protocol
   ///
-  /// Allows the execution of other protocols like WebSockets within HTTP/2 connections. At the
-  /// current time this parameter has no effect.
+  /// Servers only. Allows the execution of other protocols like WebSockets within HTTP/2
+  /// connections.
   ///
   /// Corresponds to `SETTINGS_ENABLE_CONNECT_PROTOCOL`. Defaults to `false`.
   #[inline]
@@ -138,6 +138,14 @@ impl Http2Params {
     self.read_buffer_len
   }
 
+  /// Mutable version of [`Self::enable_connect_protocol`].
+  #[inline]
+  #[must_use]
+  pub fn set_enable_connect_protocol(mut self, value: bool) -> Self {
+    self.enable_connect_protocol = value;
+    self
+  }
+
   /// Mutable version of [`Self::initial_window_len`].
   #[inline]
   #[must_use]
diff --git a/wtx/src/http2/http2_params_send.rs b/wtx/src/http2/http2_params_send.rs
index 7c6b0f0e..eb3411a7 100644
--- a/wtx/src/http2/http2_params_send.rs
+++ b/wtx/src/http2/http2_params_send.rs
@@ -1,6 +1,6 @@
 use crate::http2::{
-  HpackEncoder, Scrp, SettingsFrame, Sorp, MAX_FRAME_LEN, MAX_FRAME_LEN_LOWER_BOUND,
-  MAX_FRAME_LEN_UPPER_BOUND, MAX_HPACK_LEN, U31,
+  hpack_encoder::HpackEncoder, settings_frame::SettingsFrame, u31::U31, Scrp, Sorp, MAX_FRAME_LEN,
+  MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND, MAX_HPACK_LEN,
 };
 use core::cmp::Ordering;
 
@@ -16,12 +16,12 @@ pub(crate) struct Http2ParamsSend {
 }
 
 impl Http2ParamsSend {
-  pub(crate) fn update<RRB>(
+  pub(crate) fn update(
     &mut self,
     hpack_enc: &mut HpackEncoder,
     scrp: &mut Scrp,
     sf: &SettingsFrame,
-    sorp: &mut Sorp<RRB>,
+    sorp: &mut Sorp,
   ) -> crate::Result<()> {
     if let Some(elem) = sf.enable_connect_protocol() {
       self.enable_connect_protocol = u32::from(elem);
@@ -32,22 +32,22 @@ impl Http2ParamsSend {
         Ordering::Greater => {
           let inc = initial_window_size.wrapping_sub(self.initial_window_len);
           for (stream_id, elem) in scrp {
-            elem.windows.send.deposit(Some(*stream_id), inc.i32())?;
+            elem.windows.send_mut().deposit(Some(*stream_id), inc.i32())?;
             elem.waker.wake_by_ref();
           }
           for (stream_id, elem) in sorp {
-            elem.windows.send.deposit(Some(*stream_id), inc.i32())?;
+            elem.windows.send_mut().deposit(Some(*stream_id), inc.i32())?;
             elem.waker.wake_by_ref();
           }
         }
         Ordering::Less => {
           let dec = self.initial_window_len.wrapping_sub(initial_window_size);
           for (stream_id, elem) in scrp {
-            elem.windows.send.withdrawn(Some(*stream_id), dec.i32())?;
+            elem.windows.send_mut().withdrawn(Some(*stream_id), dec.i32())?;
             elem.waker.wake_by_ref();
           }
           for (stream_id, elem) in sorp {
-            elem.windows.send.withdrawn(Some(*stream_id), dec.i32())?;
+            elem.windows.send_mut().withdrawn(Some(*stream_id), dec.i32())?;
             elem.waker.wake_by_ref();
           }
         }
diff --git a/wtx/src/http2/http2_status.rs b/wtx/src/http2/http2_status.rs
new file mode 100644
index 00000000..45f888b0
--- /dev/null
+++ b/wtx/src/http2/http2_status.rs
@@ -0,0 +1,41 @@
+/// The possible states of a stream operation that is receiving data.
+#[derive(Clone, Copy, Debug)]
+pub enum Http2RecvStatus<E, O> {
+  /// Connection was closed, either locally or externally.
+  ClosedConnection,
+  /// Stream was closed, either locally or externally.
+  ClosedStream,
+  /// Remote peer sent an end of stream flag
+  Eos(E),
+  /// Signals an ongoing operation of an open stream
+  Ongoing(O),
+}
+
+impl<E, O> Http2RecvStatus<E, O> {
+  /// Is closed connection or stream
+  #[inline]
+  pub fn is_closed(&self) -> bool {
+    matches!(self, Self::ClosedConnection | Self::ClosedStream)
+  }
+}
+
+/// The possible states of a stream operation that is sending data.
+#[derive(Clone, Copy, Debug)]
+pub enum Http2SendStatus {
+  /// Connection was closed, either locally or externally.
+  ClosedConnection,
+  /// Stream was closed, either locally or externally.
+  ClosedStream,
+  /// The stream is in a state where it is impossible to locally send data.
+  InvalidState,
+  /// Successful operation
+  Ok,
+}
+
+impl Http2SendStatus {
+  /// Is closed connection or stream
+  #[inline]
+  pub fn is_closed(&self) -> bool {
+    matches!(self, Self::ClosedConnection | Self::ClosedStream)
+  }
+}
diff --git a/wtx/src/http2/huffman.rs b/wtx/src/http2/huffman.rs
index b9cec066..67eb0a81 100644
--- a/wtx/src/http2/huffman.rs
+++ b/wtx/src/http2/huffman.rs
@@ -137,7 +137,7 @@ pub(crate) fn huffman_encode(from: &[u8], wb: &mut Vector<u8>) -> crate::Result<
 mod bench {
   use crate::{
     bench::_data,
-    http2::{huffman_decode, huffman_encode},
+    http2::huffman::{huffman_decode, huffman_encode},
     misc::{ArrayVector, Vector},
   };
   use alloc::boxed::Box;
@@ -166,12 +166,11 @@ mod bench {
   }
 }
 
-#[cfg(feature = "_proptest")]
-#[cfg(test)]
+#[cfg(all(feature = "_proptest", test))]
 mod proptest {
   use crate::{
     http::_HeaderValueBuffer,
-    http2::{huffman_decode, huffman_encode},
+    http2::huffman::{huffman_decode, huffman_encode},
     misc::Vector,
   };
 
diff --git a/wtx/src/http2/index_map.rs b/wtx/src/http2/index_map.rs
new file mode 100644
index 00000000..b05e3e21
--- /dev/null
+++ b/wtx/src/http2/index_map.rs
@@ -0,0 +1,74 @@
+use alloc::collections::VecDeque;
+use core::{borrow::Borrow, hash::Hash};
+use hashbrown::HashMap;
+
+#[derive(Debug)]
+pub(crate) struct IndexMap<K, V> {
+  cursor: usize,
+  elements: HashMap<K, V>,
+  keys: VecDeque<K>,
+}
+
+impl<K, V> IndexMap<K, V>
+where
+  K: Clone + Copy + Eq + Hash,
+{
+  #[inline]
+  pub(crate) fn new() -> Self {
+    Self { cursor: 0, elements: HashMap::new(), keys: VecDeque::new() }
+  }
+
+  #[inline]
+  pub(crate) fn clear(&mut self) {
+    self.cursor = 0;
+    self.elements.clear();
+    self.keys.clear();
+  }
+
+  #[inline]
+  pub(crate) fn decrease_cursor(&mut self) {
+    self.cursor = self.cursor.wrapping_sub(1);
+  }
+
+  #[inline]
+  pub(crate) fn front_mut(&mut self) -> Option<&mut V> {
+    if self.cursor >= self.elements.len() {
+      return None;
+    }
+    let key = self.keys.front()?;
+    let value = self.elements.get_mut(key)?;
+    Some(value)
+  }
+
+  #[inline]
+  pub(crate) fn increase_cursor(&mut self) {
+    self.cursor = self.cursor.wrapping_add(1);
+  }
+
+  #[inline]
+  pub(crate) fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
+    self.elements.iter()
+  }
+
+  #[inline]
+  pub(crate) fn push_back(&mut self, key: K, value: V) -> Option<V> {
+    let prev_value = self.elements.insert(key.clone(), value);
+    if prev_value.is_none() {
+      self.keys.push_back(key);
+    }
+    prev_value
+  }
+
+  #[inline]
+  pub(crate) fn remove<Q>(&mut self, key: &Q) -> Option<V>
+  where
+    K: Borrow<Q>,
+    Q: Eq + Hash + ?Sized,
+  {
+    let value = self.elements.remove(key)?;
+    if self.elements.is_empty() {
+      self.keys.clear();
+    }
+    Some(value)
+  }
+}
diff --git a/wtx/src/http2/initial_server_header.rs b/wtx/src/http2/initial_server_header.rs
new file mode 100644
index 00000000..be0b649c
--- /dev/null
+++ b/wtx/src/http2/initial_server_header.rs
@@ -0,0 +1,14 @@
+use crate::{
+  http::{Method, Protocol, ReqResBuffer},
+  http2::u31::U31,
+};
+use core::task::Waker;
+
+#[derive(Debug)]
+pub(crate) struct InitialServerHeader {
+  pub(crate) method: Method,
+  pub(crate) protocol: Option<Protocol>,
+  pub(crate) rrb: ReqResBuffer,
+  pub(crate) stream_id: U31,
+  pub(crate) waker: Waker,
+}
diff --git a/wtx/src/http2/macros.rs b/wtx/src/http2/macros.rs
index c3dbf244..eb6baa41 100644
--- a/wtx/src/http2/macros.rs
+++ b/wtx/src/http2/macros.rs
@@ -6,6 +6,17 @@ macro_rules! lock_pin {
   }};
 }
 
+macro_rules! send_go_away_method {
+  () => {
+    /// Sends a GOAWAY frame to the peer, which cancels the connection and consequently all ongoing
+    /// streams.
+    #[inline]
+    pub async fn send_go_away(&self, error_code: crate::http2::Http2ErrorCode) {
+      crate::http2::misc::send_go_away(error_code, &mut self.hd.lock().await.parts_mut()).await;
+    }
+  };
+}
+
 macro_rules! initial_window_len {
   () => {
     65_535
diff --git a/wtx/src/http2/misc.rs b/wtx/src/http2/misc.rs
index 39915cbb..f7fac57f 100644
--- a/wtx/src/http2/misc.rs
+++ b/wtx/src/http2/misc.rs
@@ -1,9 +1,19 @@
 use crate::{
   http::ReqResBuffer,
   http2::{
-    http2_data::Http2DataPartsMut, CommonFlags, FrameInit, FrameInitTy, GoAwayFrame, HeadersFrame,
-    HpackDecoder, Http2Buffer, Http2Data, Http2Error, Http2ErrorCode, Http2Params,
-    ResetStreamFrame, Scrp, Sorp, StreamOverallRecvParams, StreamState, UriBuffer, U31,
+    common_flags::CommonFlags,
+    frame_init::{FrameInit, FrameInitTy},
+    go_away_frame::GoAwayFrame,
+    headers_frame::HeadersFrame,
+    hpack_decoder::HpackDecoder,
+    http2_data::Http2DataPartsMut,
+    reset_stream_frame::ResetStreamFrame,
+    stream_receiver::{StreamControlRecvParams, StreamOverallRecvParams},
+    stream_state::StreamState,
+    u31::U31,
+    uri_buffer::UriBuffer,
+    Http2Buffer, Http2Data, Http2Error, Http2ErrorCode, Http2Params, Http2RecvStatus,
+    Http2SendStatus, Scrp, Sorp,
   },
   misc::{
     AtomicWaker, LeaseMut, Lock, PartitionedFilledBuffer, RefCounter, StreamReader, StreamWriter,
@@ -18,15 +28,12 @@ use core::{
 };
 
 #[inline]
-pub(crate) fn check_content_length<RRB>(
-  content_length: usize,
-  sorp: &StreamOverallRecvParams<RRB>,
-) -> crate::Result<()>
-where
-  RRB: LeaseMut<ReqResBuffer>,
-{
-  if sorp.rrb.lease().data.len() != content_length {
-    return Err(protocol_err(Http2Error::InvalidHeaderData));
+pub(crate) fn check_content_length(sorp: &StreamOverallRecvParams) -> crate::Result<()> {
+  let Some(content_length) = sorp.content_length else {
+    return Ok(());
+  };
+  if sorp.rrb.body.len() != content_length {
+    return Err(protocol_err(Http2Error::InvalidContentLength));
   }
   Ok(())
 }
@@ -40,58 +47,76 @@ pub(crate) fn frame_reader_rslt(err: &mut Option<crate::Error>) -> crate::Result
 }
 
 #[inline]
-pub(crate) fn manage_initial_stream_receiving<RRB>(is_conn_open: &AtomicBool, rrb: &mut RRB) -> bool
-where
-  RRB: LeaseMut<ReqResBuffer>,
-{
+#[track_caller]
+pub(crate) fn scrp_mut(
+  scrp: &mut Scrp,
+  stream_id: U31,
+) -> crate::Result<&mut StreamControlRecvParams> {
+  scrp.get_mut(&stream_id).ok_or_else(|| protocol_err(Http2Error::UnknownStreamId))
+}
+
+#[inline]
+#[track_caller]
+pub(crate) fn sorp_mut(
+  sorp: &mut Sorp,
+  stream_id: U31,
+) -> crate::Result<&mut StreamOverallRecvParams> {
+  sorp.get_mut(&stream_id).ok_or_else(|| protocol_err(Http2Error::UnknownStreamId))
+}
+
+#[inline]
+pub(crate) fn manage_initial_stream_receiving(
+  is_conn_open: &AtomicBool,
+  rrb: &mut ReqResBuffer,
+) -> bool {
   if !is_conn_open.load(Ordering::Relaxed) {
     return false;
   }
-  rrb.lease_mut().clear();
+  rrb.clear();
   true
 }
 
 #[inline]
-pub(crate) fn manage_recurrent_stream_receiving<RRB, SW, T>(
+pub(crate) fn manage_recurrent_stream_receiving<E, SW, const IS_CLIENT: bool>(
   cx: &mut Context<'_>,
-  mut hdpm: Http2DataPartsMut<'_, RRB, SW>,
+  mut hdpm: Http2DataPartsMut<'_, SW, IS_CLIENT>,
   is_conn_open: &AtomicBool,
   stream_id: U31,
   cb: impl FnOnce(
     &mut Context<'_>,
-    &mut Http2DataPartsMut<'_, RRB, SW>,
-    &StreamOverallRecvParams<RRB>,
-  ) -> T,
-) -> Poll<crate::Result<(RRB, Option<T>)>>
-where
-  RRB: LeaseMut<ReqResBuffer>,
-{
-  let Some(sorp) = hdpm.hb.sorp.get_mut(&stream_id) else {
-    return Poll::Ready(Err(protocol_err(Http2Error::UnknownStreamReceiver)));
-  };
+    &mut Http2DataPartsMut<'_, SW, IS_CLIENT>,
+    &StreamOverallRecvParams,
+  ) -> E,
+) -> Poll<crate::Result<(Http2RecvStatus<E, ()>, ReqResBuffer)>> {
+  let sorp = sorp_mut(&mut hdpm.hb.sorp, stream_id)?;
   'block: {
-    let rrb_opt = match (is_conn_open.load(Ordering::Relaxed), sorp.is_stream_open) {
+    let (hrs, rrb_opt) = match (is_conn_open.load(Ordering::Relaxed), sorp.is_stream_open) {
       (false, false) => {
         if let Some(elem) = hdpm.hb.scrp.remove(&stream_id) {
           elem.waker.wake();
         }
-        hdpm.hb.sorp.remove(&stream_id).map(|el| {
+        let rrb_opt = hdpm.hb.sorp.remove(&stream_id).map(|el| {
           el.waker.wake();
           el.rrb
-        })
+        });
+        (Http2RecvStatus::ClosedConnection, rrb_opt)
+      }
+      (false, true) => {
+        let rrb_opt = hdpm.hb.sorp.remove(&stream_id).map(|el| {
+          el.waker.wake();
+          el.rrb
+        });
+        (Http2RecvStatus::ClosedConnection, rrb_opt)
       }
-      (false, true) => hdpm.hb.sorp.remove(&stream_id).map(|el| {
-        el.waker.wake();
-        el.rrb
-      }),
       (true, false) => {
         if let Some(elem) = hdpm.hb.scrp.remove(&stream_id) {
           elem.waker.wake();
         }
-        hdpm.hb.sorp.remove(&stream_id).map(|el| {
+        let rrb_opt = hdpm.hb.sorp.remove(&stream_id).map(|el| {
           el.waker.wake();
           el.rrb
-        })
+        });
+        (Http2RecvStatus::ClosedStream, rrb_opt)
       }
       (true, true) => {
         break 'block;
@@ -99,17 +124,15 @@ where
     };
     if let Some(elem) = rrb_opt {
       frame_reader_rslt(hdpm.frame_reader_error)?;
-      return Poll::Ready(Ok((elem, None)));
+      return Poll::Ready(Ok((hrs, elem)));
     }
     return Poll::Ready(Err(protocol_err(Http2Error::UnknownStreamReceiver)));
   }
   if sorp.stream_state.recv_eos() {
     if let Some(elem) = hdpm.hb.sorp.remove(&stream_id) {
-      if let Some(idx) = elem.content_length {
-        check_content_length(idx, &elem)?;
-      }
+      check_content_length(&elem)?;
       let rslt = cb(cx, &mut hdpm, &elem);
-      return Poll::Ready(Ok((elem.rrb, Some(rslt))));
+      return Poll::Ready(Ok((Http2RecvStatus::Eos(rslt), elem.rrb)));
     }
   } else {
     sorp.waker.clone_from(cx.waker());
@@ -123,14 +146,13 @@ pub(crate) const fn protocol_err(error: Http2Error) -> crate::Error {
 }
 
 #[inline]
-pub(crate) async fn process_higher_operation_err<HB, HD, RRB, SW, const IS_CLIENT: bool>(
+pub(crate) async fn process_higher_operation_err<HB, HD, SW, const IS_CLIENT: bool>(
   err: &crate::Error,
   hd: &HD,
 ) where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, IS_CLIENT>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, IS_CLIENT>>,
   SW: StreamWriter,
 {
   let mut lock = hd.lock().await;
@@ -170,7 +192,7 @@ where
     for _ in 0.._max_frames_mismatches!() {
       pfb._clear_if_following_is_empty();
       let mut read = pfb._following_len();
-      let buffer = pfb._following_trail_mut();
+      let buffer = pfb._following_rest_mut();
       let array = _read_until::<9, _>(buffer, &mut read, 0, stream_reader).await?;
       let (fi_opt, data_len) = FrameInit::from_array(array);
       if data_len > max_frame_len {
@@ -198,16 +220,14 @@ where
       };
       _trace!("Received frame: {fi:?}");
       let mut is_fulfilled = false;
-      pfb._expand_buffer(*Usize::from(data_len))?;
+      pfb._reserve(*Usize::from(data_len))?;
       for _ in 0..=data_len {
         if read >= frame_len {
           is_fulfilled = true;
           break;
         }
         read = read.wrapping_add(
-          stream_reader
-            .read(pfb._following_trail_mut().get_mut(read..).unwrap_or_default())
-            .await?,
+          stream_reader.read(pfb._following_rest_mut().get_mut(read..).unwrap_or_default()).await?,
         );
       }
       if !is_fulfilled {
@@ -259,7 +279,7 @@ where
   }
 
   let rrb_body_start = if IS_TRAILER {
-    rrb.data.len()
+    rrb.body.len()
   } else {
     rrb.clear();
     0
@@ -284,7 +304,7 @@ where
     return Ok((content_length, hf.has_eos(), headers_cb(&hf)?));
   }
 
-  rrb.data.extend_from_slice(pfb._current())?;
+  rrb.body.extend_from_copyable_slice(pfb._current())?;
 
   'continuation_frames: {
     for _ in 0.._max_continuation_frames!() {
@@ -304,7 +324,7 @@ where
       if has_diff_id || is_not_continuation {
         return Err(protocol_err(Http2Error::UnexpectedContinuationFrame));
       }
-      rrb.data.extend_from_slice(pfb._current())?;
+      rrb.body.extend_from_copyable_slice(pfb._current())?;
       if frame_fi.cf.has_eoh() {
         break 'continuation_frames;
       }
@@ -321,7 +341,7 @@ where
     uri_buffer,
   )?;
   if IS_TRAILER {
-    rrb.data.truncate(rrb_body_start);
+    rrb.body.truncate(rrb_body_start);
   } else {
     rrb.clear();
   }
@@ -335,17 +355,17 @@ where
 }
 
 #[inline]
-pub(crate) async fn send_go_away<SW, RRB>(
+pub(crate) async fn send_go_away<SW, const IS_CLIENT: bool>(
   error_code: Http2ErrorCode,
-  hdpm: &mut Http2DataPartsMut<'_, RRB, SW>,
+  hdpm: &mut Http2DataPartsMut<'_, SW, IS_CLIENT>,
 ) where
   SW: StreamWriter,
 {
   hdpm.hb.is_conn_open.store(false, Ordering::Relaxed);
   let gaf = GoAwayFrame::new(error_code, *hdpm.last_stream_id);
   let _rslt = hdpm.stream_writer.write_all(&gaf.bytes()).await;
-  for (_, waker) in &hdpm.hb.initial_server_header_buffers {
-    waker.wake_by_ref();
+  for (_, value) in hdpm.hb.initial_server_headers.iter() {
+    value.waker.wake_by_ref();
   }
   for scrp in hdpm.hb.scrp.values() {
     scrp.waker.wake_by_ref();
@@ -357,10 +377,10 @@ pub(crate) async fn send_go_away<SW, RRB>(
 }
 
 #[inline]
-pub(crate) async fn send_reset_stream<RRB, SW>(
+pub(crate) async fn send_reset_stream<SW>(
   error_code: Http2ErrorCode,
   scrp: &mut Scrp,
-  sorp: &mut Sorp<RRB>,
+  sorp: &mut Sorp,
   stream_writer: &mut SW,
   stream_id: U31,
 ) -> bool
@@ -393,6 +413,41 @@ pub(crate) fn server_header_stream_state(has_eos: bool) -> StreamState {
   }
 }
 
+#[inline]
+pub(crate) fn status_recv<E, O>(
+  is_conn_open: &AtomicBool,
+  sorp: &mut StreamOverallRecvParams,
+  eos_cb: impl FnOnce(&mut StreamOverallRecvParams) -> crate::Result<E>,
+) -> crate::Result<Option<Http2RecvStatus<E, O>>> {
+  if !is_conn_open.load(Ordering::Relaxed) {
+    return Ok(Some(Http2RecvStatus::ClosedConnection));
+  }
+  if !sorp.is_stream_open {
+    return Ok(Some(Http2RecvStatus::ClosedStream));
+  }
+  if sorp.stream_state.recv_eos() {
+    return Ok(Some(Http2RecvStatus::Eos(eos_cb(sorp)?)));
+  }
+  Ok(None)
+}
+
+#[inline]
+pub(crate) fn status_send<const IS_CLIENT: bool>(
+  is_conn_open: &AtomicBool,
+  sorp: &StreamOverallRecvParams,
+) -> Option<Http2SendStatus> {
+  if !is_conn_open.load(Ordering::Relaxed) {
+    return Some(Http2SendStatus::ClosedConnection);
+  }
+  if !sorp.is_stream_open {
+    return Some(Http2SendStatus::ClosedStream);
+  }
+  if !sorp.stream_state.can_send::<IS_CLIENT>() {
+    return Some(Http2SendStatus::InvalidState);
+  }
+  None
+}
+
 #[inline]
 pub(crate) fn trim_frame_pad(cf: CommonFlags, data: &mut &[u8]) -> crate::Result<Option<u8>> {
   let mut pad_len = None;
diff --git a/wtx/src/http2/ping_frame.rs b/wtx/src/http2/ping_frame.rs
index f8c7a7b1..338208d9 100644
--- a/wtx/src/http2/ping_frame.rs
+++ b/wtx/src/http2/ping_frame.rs
@@ -1,4 +1,9 @@
-use crate::http2::{CommonFlags, FrameInit, FrameInitTy, Http2Error, Http2ErrorCode, U31};
+use crate::http2::{
+  common_flags::CommonFlags,
+  frame_init::{FrameInit, FrameInitTy},
+  u31::U31,
+  Http2Error, Http2ErrorCode,
+};
 
 #[derive(Debug, Eq, PartialEq)]
 pub(crate) struct PingFrame {
diff --git a/wtx/src/http2/process_receipt_frame_ty.rs b/wtx/src/http2/process_receipt_frame_ty.rs
index d95a4fdb..57021256 100644
--- a/wtx/src/http2/process_receipt_frame_ty.rs
+++ b/wtx/src/http2/process_receipt_frame_ty.rs
@@ -1,21 +1,30 @@
 use crate::{
-  http::{HttpError, Method, ReqResBuffer, StatusCode},
+  http::{HttpError, StatusCode},
   http2::{
+    data_frame::DataFrame,
+    frame_init::FrameInit,
+    hpack_decoder::HpackDecoder,
     http2_params_send::Http2ParamsSend,
+    initial_server_header::InitialServerHeader,
     misc::{
       protocol_err, read_header_and_continuations, send_reset_stream, server_header_stream_state,
+      sorp_mut,
     },
-    window::WindowsPair,
-    DataFrame, FrameInit, HpackDecoder, Http2Error, Http2ErrorCode, Http2Params, ResetStreamFrame,
-    Scrp, Sorp, StreamOverallRecvParams, StreamState, UriBuffer, WindowUpdateFrame, Windows, U31,
+    reset_stream_frame::ResetStreamFrame,
+    stream_receiver::StreamOverallRecvParams,
+    stream_state::StreamState,
+    u31::U31,
+    uri_buffer::UriBuffer,
+    window::{Windows, WindowsPair},
+    window_update_frame::WindowUpdateFrame,
+    Http2Error, Http2ErrorCode, Http2Params, Scrp, Sorp,
   },
-  misc::{AtomicWaker, LeaseMut, PartitionedFilledBuffer, StreamReader, StreamWriter, NOOP_WAKER},
+  misc::{AtomicWaker, PartitionedFilledBuffer, StreamReader, StreamWriter, NOOP_WAKER},
 };
-use alloc::collections::VecDeque;
-use core::{marker::PhantomData, sync::atomic::AtomicBool, task::Waker};
+use core::{mem, sync::atomic::AtomicBool, task::Waker};
 
 #[derive(Debug)]
-pub(crate) struct ProcessReceiptFrameTy<'instance, RRB, SR, SW> {
+pub(crate) struct ProcessReceiptFrameTy<'instance, SR, SW> {
   pub(crate) conn_windows: &'instance mut Windows,
   pub(crate) fi: FrameInit,
   pub(crate) hp: &'instance mut Http2Params,
@@ -24,7 +33,6 @@ pub(crate) struct ProcessReceiptFrameTy<'instance, RRB, SR, SW> {
   pub(crate) is_conn_open: &'instance AtomicBool,
   pub(crate) last_stream_id: &'instance mut U31,
   pub(crate) pfb: &'instance mut PartitionedFilledBuffer,
-  pub(crate) phantom: PhantomData<RRB>,
   pub(crate) read_frame_waker: &'instance AtomicWaker,
   pub(crate) recv_streams_num: &'instance mut u32,
   pub(crate) stream_reader: &'instance mut SR,
@@ -32,14 +40,13 @@ pub(crate) struct ProcessReceiptFrameTy<'instance, RRB, SR, SW> {
   pub(crate) uri_buffer: &'instance mut UriBuffer,
 }
 
-impl<RRB, SR, SW> ProcessReceiptFrameTy<'_, RRB, SR, SW>
+impl<SR, SW> ProcessReceiptFrameTy<'_, SR, SW>
 where
-  RRB: LeaseMut<ReqResBuffer>,
   SR: StreamReader,
   SW: StreamWriter,
 {
   #[inline]
-  pub(crate) async fn data(self, sorp: &mut Sorp<RRB>) -> crate::Result<()> {
+  pub(crate) async fn data(self, sorp: &mut Sorp) -> crate::Result<()> {
     let Some(elem) = sorp.get_mut(&self.fi.stream_id) else {
       if self.fi.stream_id <= *self.last_stream_id {
         return Err(crate::Error::Http2ErrorGoAway(
@@ -64,7 +71,8 @@ where
     };
     elem.body_len = local_body_len;
     let (df, body_bytes) = DataFrame::read(self.pfb._current(), self.fi)?;
-    elem.rrb.lease_mut().data.extend_from_slice(body_bytes)?;
+    elem.rrb.body.extend_from_copyable_slice(body_bytes)?;
+    elem.has_one_or_more_data_frames = true;
     WindowsPair::new(self.conn_windows, &mut elem.windows)
       .withdrawn_recv(
         self.hp,
@@ -76,16 +84,14 @@ where
       .await?;
     if df.has_eos() {
       elem.stream_state = StreamState::HalfClosedRemote;
-      elem.waker.wake_by_ref();
     }
+    elem.waker.wake_by_ref();
     Ok(())
   }
 
   #[inline]
-  pub(crate) async fn header_client(self, sorp: &mut Sorp<RRB>) -> crate::Result<()> {
-    let Some(elem) = sorp.get_mut(&self.fi.stream_id) else {
-      return Err(protocol_err(Http2Error::UnknownHeaderStreamReceiver));
-    };
+  pub(crate) async fn header_client(self, sorp: &mut Sorp) -> crate::Result<()> {
+    let elem = sorp_mut(sorp, self.fi.stream_id)?;
     let has_eos = if elem.has_initial_header {
       read_header_and_continuations::<_, _, true, true>(
         self.fi,
@@ -94,7 +100,7 @@ where
         self.hpack_dec,
         self.pfb,
         self.read_frame_waker,
-        elem.rrb.lease_mut(),
+        &mut elem.rrb,
         self.stream_reader,
         self.uri_buffer,
         |_| Ok(()),
@@ -109,7 +115,7 @@ where
         self.hpack_dec,
         self.pfb,
         self.read_frame_waker,
-        elem.rrb.lease_mut(),
+        &mut elem.rrb,
         self.stream_reader,
         self.uri_buffer,
         |hf| hf.hsresh().status_code.ok_or_else(|| HttpError::MissingResponseStatusCode.into()),
@@ -129,9 +135,8 @@ where
   #[inline]
   pub(crate) async fn header_server_init(
     self,
-    initial_server_header_params: &mut VecDeque<(Method, U31)>,
-    mut rrb: RRB,
-    sorp: &mut Sorp<RRB>,
+    ish: &mut InitialServerHeader,
+    sorp: &mut Sorp,
   ) -> crate::Result<()> {
     if self.fi.stream_id <= *self.last_stream_id || self.fi.stream_id.u32() % 2 == 0 {
       return Err(protocol_err(Http2Error::UnexpectedStreamId));
@@ -141,20 +146,28 @@ where
     }
     *self.recv_streams_num = self.recv_streams_num.wrapping_add(1);
     *self.last_stream_id = self.fi.stream_id;
-    let (content_length, has_eos, method) = read_header_and_continuations::<_, _, false, false>(
+    let tuple = read_header_and_continuations::<_, _, false, false>(
       self.fi,
       self.is_conn_open,
       self.hp,
       self.hpack_dec,
       self.pfb,
       self.read_frame_waker,
-      rrb.lease_mut(),
+      &mut ish.rrb,
       self.stream_reader,
       self.uri_buffer,
-      |hf| hf.hsreqh().method.ok_or_else(|| HttpError::MissingRequestMethod.into()),
+      |hf| {
+        Ok((
+          hf.hsreqh().method.ok_or_else(|| HttpError::MissingRequestMethod)?,
+          hf.hsreqh().protocol,
+        ))
+      },
     )
     .await?;
-    initial_server_header_params.push_back((method, self.fi.stream_id));
+    let (content_length, has_eos, (method, protocol)) = tuple;
+    ish.method = method;
+    ish.protocol = protocol;
+    ish.stream_id = self.fi.stream_id;
     let stream_state = server_header_stream_state(has_eos);
     drop(sorp.insert(
       self.fi.stream_id,
@@ -162,8 +175,9 @@ where
         body_len: 0,
         content_length,
         has_initial_header: true,
+        has_one_or_more_data_frames: false,
         is_stream_open: true,
-        rrb,
+        rrb: mem::take(&mut ish.rrb),
         status_code: StatusCode::Ok,
         stream_state,
         waker: NOOP_WAKER.clone(),
@@ -176,7 +190,7 @@ where
   #[inline]
   pub(crate) async fn header_server_trailer(
     self,
-    sorp: &mut StreamOverallRecvParams<RRB>,
+    sorp: &mut StreamOverallRecvParams,
   ) -> crate::Result<()> {
     if sorp.stream_state.recv_eos() {
       return Err(protocol_err(Http2Error::UnexpectedHeaderFrame));
@@ -188,7 +202,7 @@ where
       self.hpack_dec,
       self.pfb,
       self.read_frame_waker,
-      sorp.rrb.lease_mut(),
+      &mut sorp.rrb,
       self.stream_reader,
       self.uri_buffer,
       |_| Ok(()),
@@ -202,7 +216,7 @@ where
   }
 
   #[inline]
-  pub(crate) async fn reset(self, scrp: &mut Scrp, sorp: &mut Sorp<RRB>) -> crate::Result<()> {
+  pub(crate) async fn reset(self, scrp: &mut Scrp, sorp: &mut Sorp) -> crate::Result<()> {
     let rsf = ResetStreamFrame::read(self.pfb._current(), self.fi)?;
     if !send_reset_stream(rsf.error_code(), scrp, sorp, self.stream_writer, self.fi.stream_id).await
     {
@@ -212,7 +226,7 @@ where
   }
 
   #[inline]
-  pub(crate) fn window_update(self, scrp: &mut Scrp, sorp: &mut Sorp<RRB>) -> crate::Result<()> {
+  pub(crate) fn window_update(self, scrp: &mut Scrp, sorp: &mut Sorp) -> crate::Result<()> {
     if let Some(elem) = scrp.get_mut(&self.fi.stream_id) {
       self.do_window_update(&mut elem.windows, &elem.waker)?;
       return Ok(());
@@ -227,7 +241,7 @@ where
   #[inline]
   fn do_window_update(self, windows: &mut Windows, waker: &Waker) -> crate::Result<()> {
     let wuf = WindowUpdateFrame::read(self.pfb._current(), self.fi)?;
-    windows.send.deposit(Some(self.fi.stream_id), wuf.size_increment().i32())?;
+    windows.send_mut().deposit(Some(self.fi.stream_id), wuf.size_increment().i32())?;
     waker.wake_by_ref();
     Ok(())
   }
diff --git a/wtx/src/http2/reset_stream_frame.rs b/wtx/src/http2/reset_stream_frame.rs
index 39f126fd..b927e1ef 100644
--- a/wtx/src/http2/reset_stream_frame.rs
+++ b/wtx/src/http2/reset_stream_frame.rs
@@ -1,5 +1,9 @@
 use crate::http2::{
-  misc::protocol_err, CommonFlags, FrameInit, FrameInitTy, Http2Error, Http2ErrorCode, U31,
+  common_flags::CommonFlags,
+  frame_init::{FrameInit, FrameInitTy},
+  misc::protocol_err,
+  u31::U31,
+  Http2Error, Http2ErrorCode,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/http2/send_data_mode.rs b/wtx/src/http2/send_data_mode.rs
new file mode 100644
index 00000000..8e576dbf
--- /dev/null
+++ b/wtx/src/http2/send_data_mode.rs
@@ -0,0 +1,124 @@
+/// Dictates how HTTP/2 data frames should be delivered.
+#[derive(Debug)]
+pub struct SendDataMode<B, const IS_SCATTERED: bool> {
+  bytes: B,
+}
+
+impl<'bytes, B, const IS_SCATTERED: bool> SendDataMode<B, IS_SCATTERED>
+where
+  B: SendDataModeBytes<'bytes, IS_SCATTERED>,
+{
+  #[inline]
+  const fn new(bytes: B) -> Self {
+    Self { bytes }
+  }
+
+  #[inline]
+  pub(crate) fn concat<'first, 'rslt, 'this>(&'this self, first: &'first [u8]) -> [&'rslt [u8]; 3]
+  where
+    'first: 'rslt,
+    'this: 'rslt,
+  {
+    self.bytes.concat(first)
+  }
+
+  #[inline]
+  pub(crate) fn first_mut(&mut self) -> &mut &'bytes [u8] {
+    self.bytes.first_mut()
+  }
+
+  #[inline]
+  pub(crate) fn len(&self) -> usize {
+    self.bytes.len()
+  }
+}
+
+impl<'bytes> SendDataMode<[&'bytes [u8]; 1], true> {
+  /// `bytes` is broken down into smaller pieces until everything is submitted. This process
+  /// depends on the maximum payload length as well as the current window size.
+  #[inline]
+  pub const fn scattered_data_frames(bytes: &'bytes [u8]) -> Self {
+    Self::new([bytes])
+  }
+}
+
+impl<'bytes, B> SendDataMode<B, false>
+where
+  B: SendDataModeBytes<'bytes, false>,
+{
+  /// The concatenation of `bytes` is delivered in a single data frame.
+  ///
+  /// If the maximum frame payload or the current window size is less than the total size, then the
+  /// submission will return an error.
+  #[inline]
+  pub const fn single_data_frame(array: B) -> Self {
+    Self::new(array)
+  }
+}
+
+/// Array implementations for [`SendDataMode`].
+pub trait SendDataModeBytes<'bytes, const IS_SCATTERED: bool> {
+  /// Returns an array of concatenated references with an initial `first` slice.
+  fn concat<'first, 'rslt, 'this>(&'this self, first: &'first [u8]) -> [&'rslt [u8]; 3]
+  where
+    'first: 'rslt,
+    'this: 'rslt;
+
+  /// First inner mutable slice.
+  fn first_mut(&mut self) -> &mut &'bytes [u8];
+
+  /// Sum of all inner slice lengths.
+  fn len(&self) -> usize;
+}
+
+impl<'bytes, const IS_SCATTERED: bool> SendDataModeBytes<'bytes, IS_SCATTERED>
+  for [&'bytes [u8]; 1]
+{
+  #[inline]
+  fn concat<'first, 'rslt, 'this>(&'this self, first: &'first [u8]) -> [&'rslt [u8]; 3]
+  where
+    'first: 'rslt,
+    'this: 'rslt,
+  {
+    [first, &self[0], &[]]
+  }
+
+  #[inline]
+  fn first_mut(&mut self) -> &mut &'bytes [u8] {
+    &mut self[0]
+  }
+
+  #[inline]
+  fn len(&self) -> usize {
+    let mut len = 0usize;
+    for elem in self {
+      len = len.wrapping_add(elem.len());
+    }
+    len
+  }
+}
+
+impl<'bytes> SendDataModeBytes<'bytes, false> for [&'bytes [u8]; 2] {
+  #[inline]
+  fn concat<'first, 'rslt, 'this>(&'this self, first: &'first [u8]) -> [&'rslt [u8]; 3]
+  where
+    'first: 'rslt,
+    'this: 'rslt,
+  {
+    [first, &self[0], &self[1]]
+  }
+
+  #[inline]
+  fn first_mut(&mut self) -> &mut &'bytes [u8] {
+    &mut self[0]
+  }
+
+  #[inline]
+  fn len(&self) -> usize {
+    let mut len = 0usize;
+    for elem in self {
+      len = len.wrapping_add(elem.len());
+    }
+    len
+  }
+}
diff --git a/wtx/src/http2/send_msg.rs b/wtx/src/http2/send_msg.rs
index 565480ac..56824718 100644
--- a/wtx/src/http2/send_msg.rs
+++ b/wtx/src/http2/send_msg.rs
@@ -7,10 +7,10 @@
 //! Control frames like Settings or `WindowUpdate` are out of scope.
 
 macro_rules! init {
-  ($bytes:expr, $frame:expr) => {{
+  ($frame_len:expr, $frame:expr) => {{
     let mut buffer = [0; 9];
     let [a, b, c, d, e, f, g, h, i] = &mut buffer;
-    let [_, j, k, l] = u32::try_from($bytes.len()).unwrap_or_default().to_be_bytes();
+    let [_, j, k, l] = $frame_len.to_be_bytes();
     let [_, _, _, m, n, o, p, q, r] = $frame.bytes();
     *a = j;
     *b = k;
@@ -26,13 +26,20 @@ macro_rules! init {
 }
 
 use crate::{
-  http::{Headers, ReqResBuffer, Trailers},
+  http::{Headers, Trailers},
   http2::{
+    continuation_frame::ContinuationFrame,
+    data_frame::DataFrame,
+    headers_frame::HeadersFrame,
+    hpack_encoder::HpackEncoder,
+    hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
     http2_data::Http2DataPartsMut,
-    misc::{process_higher_operation_err, protocol_err, write_array},
+    misc::{process_higher_operation_err, protocol_err, scrp_mut, write_array},
+    send_data_mode::SendDataModeBytes,
+    stream_state::StreamState,
+    u31::U31,
     window::WindowsPair,
-    ContinuationFrame, DataFrame, HeadersFrame, HpackEncoder, HpackStaticRequestHeaders,
-    HpackStaticResponseHeaders, Http2Buffer, Http2Data, Http2Error, StreamState, U31,
+    Http2Buffer, Http2Data, Http2Error, Http2SendStatus, SendDataMode,
   },
   misc::{LeaseMut, Lock, RefCounter, StreamWriter, Usize, Vector},
 };
@@ -44,20 +51,54 @@ use core::{
 };
 
 #[inline]
-pub(crate) async fn send_msg<HB, HD, RRB, SW, const IS_CLIENT: bool>(
+pub(crate) fn encode_headers<const IS_CLIENT: bool>(
+  headers: &Headers,
+  (hpack_enc, hpack_enc_buffer): (&mut HpackEncoder, &mut Vector<u8>),
+  (hsreqh, hsresh): (HpackStaticRequestHeaders<'_>, HpackStaticResponseHeaders),
+) -> crate::Result<()> {
+  hpack_enc_buffer.clear();
+  match headers.trailers() {
+    Trailers::None => {
+      if IS_CLIENT {
+        hpack_enc.encode(hpack_enc_buffer, hsreqh.iter(), headers.iter())?;
+      } else {
+        hpack_enc.encode(hpack_enc_buffer, hsresh.iter(), headers.iter())?;
+      }
+    }
+    Trailers::Mixed => {
+      let iter = headers.iter().filter(|el| !el.is_trailer);
+      if IS_CLIENT {
+        hpack_enc.encode(hpack_enc_buffer, hsreqh.iter(), iter)?;
+      } else {
+        hpack_enc.encode(hpack_enc_buffer, hsresh.iter(), iter)?;
+      }
+    }
+    Trailers::Tail(idx) => {
+      let iter = headers.iter().take(idx);
+      if IS_CLIENT {
+        hpack_enc.encode(hpack_enc_buffer, hsreqh.iter(), iter)?;
+      } else {
+        hpack_enc.encode(hpack_enc_buffer, hsresh.iter(), iter)?;
+      }
+    }
+  }
+  Ok(())
+}
+
+#[inline]
+pub(crate) async fn send_msg<HB, HD, SW, const IS_CLIENT: bool>(
   mut data_bytes: &[u8],
   hd: &HD,
   headers: &Headers,
   (hsreqh, hsresh): (HpackStaticRequestHeaders<'_>, HpackStaticResponseHeaders),
   is_conn_open: &AtomicBool,
   stream_id: U31,
-  mut cb: impl FnMut(Http2DataPartsMut<'_, RRB, SW>),
-) -> crate::Result<Option<()>>
+  mut cb: impl FnMut(Http2DataPartsMut<'_, SW, IS_CLIENT>),
+) -> crate::Result<Http2SendStatus>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, IS_CLIENT>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, IS_CLIENT>>,
   SW: StreamWriter,
 {
   let (mut has_headers, mut has_data) = (false, false);
@@ -65,11 +106,11 @@ where
   let mut lock_pin = pin!(hd.lock());
   let rslt = poll_fn(move |cx| {
     if !is_conn_open.load(Ordering::Relaxed) {
-      return Poll::Ready(Ok(None));
+      return Poll::Ready(Ok(Http2SendStatus::ClosedConnection));
     }
     let mut lock = lock_pin!(cx, hd, lock_pin);
     let hdpm = lock.parts_mut();
-    let fut = do_send_msg::<_, _, IS_CLIENT>(
+    let fut = do_send_msg::<_, IS_CLIENT>(
       &mut data_bytes,
       (&mut has_headers, &mut has_data),
       headers,
@@ -87,10 +128,10 @@ where
           } else {
             _trace!("Response has been sent");
           };
-          return Poll::Ready(Ok(Some(())));
+          return Poll::Ready(Ok(Http2SendStatus::Ok));
         }
       } else {
-        return Poll::Ready(Ok(None));
+        return Poll::Ready(Ok(Http2SendStatus::ClosedStream));
       }
     }
     Poll::Pending
@@ -102,6 +143,179 @@ where
   rslt
 }
 
+/// Tries to send up two data frames in a single round trip. If exhausted, returns `true`.
+#[inline]
+pub(crate) async fn write_standalone_data<'bytes, B, SW, const IS_SCATTERED: bool>(
+  available_send: u32,
+  data: &mut SendDataMode<B, IS_SCATTERED>,
+  force_eos: bool,
+  has_data: &mut bool,
+  has_trailers: bool,
+  is_conn_open: &AtomicBool,
+  max_frame_len: u32,
+  stream: &mut SW,
+  stream_id: U31,
+  wp: &mut WindowsPair<'_>,
+) -> crate::Result<bool>
+where
+  B: SendDataModeBytes<'bytes, IS_SCATTERED>,
+  SW: StreamWriter,
+{
+  #[inline]
+  fn should_stop(
+    data: &[u8],
+    frame: &mut DataFrame,
+    has_data: &mut bool,
+    has_trailers: bool,
+  ) -> bool {
+    if data.is_empty() {
+      *has_data = true;
+      if has_trailers {
+        false
+      } else {
+        frame.set_eos();
+        true
+      }
+    } else {
+      false
+    }
+  }
+  if IS_SCATTERED {
+    if let Some(available_send_rest @ 1..=u32::MAX) = available_send.checked_sub(max_frame_len) {
+      let tuple = split_frame_bytes(data.first_mut(), max_frame_len);
+      let (left0 @ [_, ..], right0) = tuple else {
+        *has_data = true;
+        return Ok(false);
+      };
+      let frame0_len = data_frame_len(left0.len());
+      let mut frame0 = DataFrame::new(frame0_len.into(), stream_id);
+      let split_len = max_frame_len.min(available_send_rest);
+      if let (left1 @ [_, ..], right1) = split_frame_bytes(right0, split_len) {
+        let frame1_len = data_frame_len(left1.len());
+        let mut frame1 = DataFrame::new(frame1_len.into(), stream_id);
+        let should_stop = should_stop(right1, &mut frame1, has_data, has_trailers);
+        if force_eos {
+          frame1.set_eos();
+        }
+        write_array(
+          [&init!(frame0_len, frame0), left0, &init!(frame1_len, frame1), left1],
+          is_conn_open,
+          stream,
+        )
+        .await?;
+        wp.withdrawn_send(Some(stream_id), frame0_len.wrapping_add(frame1_len).into())?;
+        *data.first_mut() = right1;
+        Ok(should_stop)
+      } else {
+        let should_stop = should_stop(right0, &mut frame0, has_data, has_trailers);
+        if force_eos {
+          frame0.set_eos();
+        }
+        write_array([&init!(frame0_len, frame0), left0], is_conn_open, stream).await?;
+        wp.withdrawn_send(Some(stream_id), frame0_len.into())?;
+        *data.first_mut() = right0;
+        Ok(should_stop)
+      }
+    } else {
+      let tuple = split_frame_bytes(data.first_mut(), available_send);
+      let (left0 @ [_, ..], right0) = tuple else {
+        *has_data = true;
+        return Ok(false);
+      };
+      let frame0_len = data_frame_len(left0.len());
+      let mut frame0 = DataFrame::new(frame0_len.into(), stream_id);
+      let should_stop = should_stop(right0, &mut frame0, has_data, has_trailers);
+      if force_eos {
+        frame0.set_eos();
+      }
+      write_array([&init!(frame0_len, frame0), left0], is_conn_open, stream).await?;
+      wp.withdrawn_send(Some(stream_id), frame0_len.into())?;
+      *data.first_mut() = right0;
+      Ok(should_stop)
+    }
+  } else {
+    let data_len = data.len();
+    if data_len >= *Usize::from(max_frame_len) || data_len >= *Usize::from(available_send) {
+      return Err(protocol_err(Http2Error::InvalidDataFrameDataLen));
+    }
+    let frame0_len = data_frame_len(data_len);
+    let frame0 = DataFrame::new(frame0_len.into(), stream_id);
+    write_array(data.concat(&init!(frame0_len, frame0)), is_conn_open, stream).await?;
+    wp.withdrawn_send(Some(stream_id), frame0_len.into())?;
+    *has_data = true;
+    Ok(false)
+  }
+}
+
+// Tries to send all initial headers
+#[inline]
+pub(crate) async fn write_standalone_headers<SW, const IS_CLIENT: bool>(
+  hpack_enc_buffer: &mut Vector<u8>,
+  (hsreqh, hsresh): (HpackStaticRequestHeaders<'_>, HpackStaticResponseHeaders),
+  is_conn_open: &AtomicBool,
+  is_eos: bool,
+  max_frame_len: u32,
+  stream: &mut SW,
+  stream_id: U31,
+) -> crate::Result<bool>
+where
+  SW: StreamWriter,
+{
+  let (left0, right0) = split_frame_bytes(hpack_enc_buffer, max_frame_len);
+  let mut frame0 = HeadersFrame::new((hsreqh, hsresh), stream_id);
+  let should_stop = if is_eos {
+    frame0.set_eos();
+    true
+  } else {
+    false
+  };
+  write_headers_or_trailers(
+    &mut frame0,
+    is_conn_open,
+    (left0, right0),
+    max_frame_len,
+    stream,
+    stream_id,
+  )
+  .await?;
+  Ok(should_stop)
+}
+
+/// Tries to send all trailer headers
+#[inline]
+pub(crate) async fn write_standalone_trailers<SW>(
+  headers: &Headers,
+  (hpack_enc, hpack_enc_buffer): (&mut HpackEncoder, &mut Vector<u8>),
+  is_conn_open: &AtomicBool,
+  max_frame_len: u32,
+  stream: &mut SW,
+  stream_id: U31,
+) -> crate::Result<()>
+where
+  SW: StreamWriter,
+{
+  hpack_enc_buffer.clear();
+  encode_trailers(headers, (hpack_enc, hpack_enc_buffer))?;
+  let (left0 @ [_, ..], right0) = split_frame_bytes(hpack_enc_buffer, max_frame_len) else {
+    return Ok(());
+  };
+  let mut frame0 = HeadersFrame::new(
+    (HpackStaticRequestHeaders::EMPTY, HpackStaticResponseHeaders::EMPTY),
+    stream_id,
+  );
+  frame0.set_eos();
+  write_headers_or_trailers(
+    &mut frame0,
+    is_conn_open,
+    (left0, right0),
+    max_frame_len,
+    stream,
+    stream_id,
+  )
+  .await?;
+  Ok(())
+}
+
 #[inline]
 fn change_final_stream_state<const IS_CLIENT: bool>(stream_state: &mut StreamState) {
   *stream_state = if IS_CLIENT { StreamState::HalfClosedLocal } else { StreamState::Closed };
@@ -115,34 +329,31 @@ fn change_initial_stream_state<const IS_CLIENT: bool>(stream_state: &mut StreamS
 }
 
 #[inline]
-fn data_frame_len(bytes: &[u8]) -> U31 {
-  U31::from_u32(u32::try_from(bytes.len()).unwrap_or_default())
+fn data_frame_len(bytes_len: usize) -> u32 {
+  u32::try_from(bytes_len).unwrap_or_default()
 }
 
 // Tries to at least send initial headers when the windows size does not allow sending data frames
 #[inline]
-async fn do_send_msg<RRB, SW, const IS_CLIENT: bool>(
+async fn do_send_msg<SW, const IS_CLIENT: bool>(
   data_bytes: &mut &[u8],
   (has_headers, has_data): (&mut bool, &mut bool),
   headers: &Headers,
-  hdpm: Http2DataPartsMut<'_, RRB, SW>,
+  hdpm: Http2DataPartsMut<'_, SW, IS_CLIENT>,
   (hsreqh, hsresh): (HpackStaticRequestHeaders<'_>, HpackStaticResponseHeaders),
   stream_id: U31,
   waker: &Waker,
-  cb: &mut impl FnMut(Http2DataPartsMut<'_, RRB, SW>),
+  cb: &mut impl FnMut(Http2DataPartsMut<'_, SW, IS_CLIENT>),
 ) -> crate::Result<Option<bool>>
 where
-  RRB: LeaseMut<ReqResBuffer>,
   SW: StreamWriter,
 {
   let Http2Buffer { hpack_enc, hpack_enc_buffer, is_conn_open, scrp, .. } = hdpm.hb;
-  let Some(elem) = scrp.get_mut(&stream_id) else {
-    return Err(protocol_err(Http2Error::BadLocalFlow));
-  };
+  let elem = scrp_mut(scrp, stream_id)?;
   if !elem.is_stream_open {
     return Ok(None);
   }
-  if !elem.stream_state.can_send_stream::<IS_CLIENT>() {
+  if !elem.stream_state.can_send::<IS_CLIENT>() {
     return Err(protocol_err(Http2Error::InvalidSendStreamState));
   }
 
@@ -153,10 +364,10 @@ where
       if !*has_headers {
         encode_headers::<IS_CLIENT>(headers, (hpack_enc, hpack_enc_buffer), (hsreqh, hsresh))?;
         if write_standalone_headers::<SW, IS_CLIENT>(
-          data_bytes,
           hpack_enc_buffer,
           (hsreqh, hsresh),
           is_conn_open,
+          data_bytes.is_empty(),
           hdpm.hps.max_frame_len,
           hdpm.stream_writer,
           stream_id,
@@ -195,8 +406,9 @@ where
     if !*has_data {
       if write_standalone_data(
         available_send,
+        &mut SendDataMode::scattered_data_frames(data_bytes),
+        false,
         has_data,
-        data_bytes,
         headers.trailers().has_any(),
         is_conn_open,
         hdpm.hps.max_frame_len,
@@ -216,7 +428,6 @@ where
     write_standalone_trailers(
       headers,
       (hpack_enc, hpack_enc_buffer),
-      (hsreqh, hsresh),
       is_conn_open,
       hdpm.hps.max_frame_len,
       hdpm.stream_writer,
@@ -229,56 +440,20 @@ where
   Ok(Some(true))
 }
 
-#[inline]
-fn encode_headers<const IS_CLIENT: bool>(
-  headers: &Headers,
-  (hpack_enc, hpack_enc_buffer): (&mut HpackEncoder, &mut Vector<u8>),
-  (hsreqh, hsresh): (HpackStaticRequestHeaders<'_>, HpackStaticResponseHeaders),
-) -> crate::Result<()> {
-  hpack_enc_buffer.clear();
-  match headers.trailers() {
-    Trailers::None => {
-      if IS_CLIENT {
-        hpack_enc.encode(hpack_enc_buffer, hsreqh.iter(), headers.iter())?;
-      } else {
-        hpack_enc.encode(hpack_enc_buffer, hsresh.iter(), headers.iter())?;
-      }
-    }
-    Trailers::Mixed => {
-      let iter = headers.iter().filter(|el| !el.is_trailer);
-      if IS_CLIENT {
-        hpack_enc.encode(hpack_enc_buffer, hsreqh.iter(), iter)?;
-      } else {
-        hpack_enc.encode(hpack_enc_buffer, hsresh.iter(), iter)?;
-      }
-    }
-    Trailers::Tail(idx) => {
-      let iter = headers.iter().take(idx);
-      if IS_CLIENT {
-        hpack_enc.encode(hpack_enc_buffer, hsreqh.iter(), iter)?;
-      } else {
-        hpack_enc.encode(hpack_enc_buffer, hsresh.iter(), iter)?;
-      }
-    }
-  }
-  Ok(())
-}
-
 #[inline]
 fn encode_trailers(
   headers: &Headers,
   (hpack_enc, hpack_enc_buffer): (&mut HpackEncoder, &mut Vector<u8>),
 ) -> crate::Result<()> {
-  let pseudo = [].into_iter();
   match headers.trailers() {
     Trailers::None => {
-      hpack_enc.encode(hpack_enc_buffer, pseudo, headers.iter())?;
+      hpack_enc.encode(hpack_enc_buffer, [], headers.iter())?;
     }
     Trailers::Mixed => {
-      hpack_enc.encode(hpack_enc_buffer, pseudo, headers.iter().filter(|el| el.is_trailer))?;
+      hpack_enc.encode(hpack_enc_buffer, [], headers.iter().filter(|el| el.is_trailer))?;
     }
     Trailers::Tail(idx) => {
-      hpack_enc.encode(hpack_enc_buffer, pseudo, headers.iter().skip(idx))?;
+      hpack_enc.encode(hpack_enc_buffer, [], headers.iter().skip(idx))?;
     }
   }
   Ok(())
@@ -315,6 +490,7 @@ where
     let Some(data_len) = has_delimited_bytes(data_bytes, available_send.min(max_frame_len)) else {
       break 'headers_with_others;
     };
+
     if headers.trailers().has_any() {
       let idx = hpack_enc_buffer.len();
       encode_trailers(headers, (hpack_enc, hpack_enc_buffer))?;
@@ -338,11 +514,11 @@ where
       frame2.set_eos();
       write_array(
         [
-          &init!(headers_bytes, frame0),
+          &init!(data_frame_len(headers_bytes.len()), frame0),
           headers_bytes,
-          &init!(data_bytes, frame1),
+          &init!(data_frame_len(data_bytes.len()), frame1),
           data_bytes,
-          &init!(trailers_bytes, frame2),
+          &init!(data_frame_len(trailers_bytes.len()), frame2),
           trailers_bytes,
         ],
         is_conn_open,
@@ -359,9 +535,9 @@ where
       frame1.set_eos();
       write_array(
         [
-          &init!(hpack_enc_buffer, frame0),
+          &init!(data_frame_len(hpack_enc_buffer.len()), frame0),
           hpack_enc_buffer,
-          &init!(data_bytes, frame1),
+          &init!(data_frame_len(data_bytes.len()), frame1),
           data_bytes,
         ],
         is_conn_open,
@@ -374,10 +550,10 @@ where
   }
 
   write_standalone_headers::<_, IS_CLIENT>(
-    data_bytes,
     hpack_enc_buffer,
     (hsreqh, hsresh),
     is_conn_open,
+    data_bytes.is_empty(),
     max_frame_len,
     stream,
     stream_id,
@@ -388,11 +564,7 @@ where
 #[inline]
 fn split_frame_bytes(bytes: &[u8], len: u32) -> (&[u8], &[u8]) {
   let n = *Usize::from(len);
-  if n >= bytes.len() {
-    (bytes, &[])
-  } else {
-    (bytes.get(..n).unwrap_or_default(), bytes.get(n..).unwrap_or_default())
-  }
+  (bytes.get(..n).unwrap_or(bytes), bytes.get(n..).unwrap_or_default())
 }
 
 #[inline]
@@ -413,157 +585,20 @@ where
       return Err(protocol_err(Http2Error::HeadersOverflow));
     }
     frame1.set_eoh();
-    let init1 = init!(left1, frame1);
-    write_array([&init!(left0, frame0), left0, &init1, left1], is_conn_open, stream).await?;
+    write_array(
+      [
+        &init!(data_frame_len(left0.len()), frame0),
+        left0,
+        &init!(data_frame_len(left1.len()), frame1),
+        left1,
+      ],
+      is_conn_open,
+      stream,
+    )
+    .await?;
   } else {
     frame0.set_eoh();
-    write_array([&init!(left0, frame0), left0], is_conn_open, stream).await?;
-  }
-  Ok(())
-}
-
-/// Tries to send up two data frames in a single round trip. If exhausted, returns `true`.
-#[inline]
-async fn write_standalone_data<SW>(
-  available_send: u32,
-  has_data: &mut bool,
-  data_bytes: &mut &[u8],
-  has_trailers: bool,
-  is_conn_open: &AtomicBool,
-  max_frame_len: u32,
-  stream: &mut SW,
-  stream_id: U31,
-  wp: &mut WindowsPair<'_>,
-) -> crate::Result<bool>
-where
-  SW: StreamWriter,
-{
-  #[inline]
-  fn should_stop(
-    data: &[u8],
-    frame: &mut DataFrame,
-    has_data: &mut bool,
-    has_trailers: bool,
-  ) -> bool {
-    if data.is_empty() {
-      *has_data = true;
-      if has_trailers {
-        false
-      } else {
-        frame.set_eos();
-        true
-      }
-    } else {
-      false
-    }
-  }
-
-  if let Some(available_send_rest @ 1..=u32::MAX) = available_send.checked_sub(max_frame_len) {
-    let (left0 @ [_, ..], right0) = split_frame_bytes(data_bytes, max_frame_len) else {
-      *has_data = true;
-      return Ok(false);
-    };
-    let frame0_len = data_frame_len(left0);
-    let mut frame0 = DataFrame::new(frame0_len, stream_id);
-    let split_len = max_frame_len.min(available_send_rest);
-    if let (left1 @ [_, ..], right1) = split_frame_bytes(right0, split_len) {
-      let mut frame1 = DataFrame::new(data_frame_len(left1), stream_id);
-      let frame1_len = data_frame_len(left1);
-      let should_stop = should_stop(right1, &mut frame1, has_data, has_trailers);
-      write_array(
-        [&init!(left0, frame0), left0, &init!(left1, frame1), left1],
-        is_conn_open,
-        stream,
-      )
-      .await?;
-      wp.withdrawn_send(Some(stream_id), frame0_len.wrapping_add(frame1_len))?;
-      *data_bytes = right1;
-      Ok(should_stop)
-    } else {
-      let should_stop = should_stop(right0, &mut frame0, has_data, has_trailers);
-      write_array([&init!(left0, frame0), left0], is_conn_open, stream).await?;
-      wp.withdrawn_send(Some(stream_id), frame0_len)?;
-      *data_bytes = right0;
-      Ok(should_stop)
-    }
-  } else {
-    let (left0 @ [_, ..], right0) = split_frame_bytes(data_bytes, available_send) else {
-      *has_data = true;
-      return Ok(false);
-    };
-    let frame0_len = data_frame_len(left0);
-    let mut frame0 = DataFrame::new(frame0_len, stream_id);
-    let should_stop = should_stop(right0, &mut frame0, has_data, has_trailers);
-    write_array([&init!(left0, frame0), left0], is_conn_open, stream).await?;
-    wp.withdrawn_send(Some(stream_id), frame0_len)?;
-    *data_bytes = right0;
-    Ok(should_stop)
+    write_array([&init!(data_frame_len(left0.len()), frame0), left0], is_conn_open, stream).await?;
   }
-}
-
-// Tries to send all initial headers
-#[inline]
-async fn write_standalone_headers<SW, const IS_CLIENT: bool>(
-  data_bytes: &[u8],
-  hpack_enc_buffer: &mut Vector<u8>,
-  (hsreqh, hsresh): (HpackStaticRequestHeaders<'_>, HpackStaticResponseHeaders),
-  is_conn_open: &AtomicBool,
-  max_frame_len: u32,
-  stream: &mut SW,
-  stream_id: U31,
-) -> crate::Result<bool>
-where
-  SW: StreamWriter,
-{
-  let (left0, right0) = split_frame_bytes(hpack_enc_buffer, max_frame_len);
-  let mut frame0 = HeadersFrame::new((hsreqh, hsresh), stream_id);
-  let should_stop = if data_bytes.is_empty() {
-    frame0.set_eos();
-    true
-  } else {
-    false
-  };
-  write_headers_or_trailers(
-    &mut frame0,
-    is_conn_open,
-    (left0, right0),
-    max_frame_len,
-    stream,
-    stream_id,
-  )
-  .await?;
-  Ok(should_stop)
-}
-
-/// Tries to send all trailer headers
-#[inline]
-async fn write_standalone_trailers<SW>(
-  headers: &Headers,
-  (hpack_enc, hpack_enc_buffer): (&mut HpackEncoder, &mut Vector<u8>),
-  (hsreqh, hsresh): (HpackStaticRequestHeaders<'_>, HpackStaticResponseHeaders),
-  is_conn_open: &AtomicBool,
-  max_frame_len: u32,
-  stream: &mut SW,
-  stream_id: U31,
-) -> crate::Result<()>
-where
-  SW: StreamWriter,
-{
-  hpack_enc_buffer.clear();
-  encode_trailers(headers, (hpack_enc, hpack_enc_buffer))?;
-  let (left0 @ [_, ..], right0) = split_frame_bytes(hpack_enc_buffer, max_frame_len) else {
-    return Ok(());
-  };
-  let mut frame0 = HeadersFrame::new((hsreqh, hsresh), stream_id);
-  frame0.set_eos();
-  write_headers_or_trailers(
-    &mut frame0,
-    is_conn_open,
-    (left0, right0),
-    max_frame_len,
-    stream,
-    stream_id,
-  )
-  .await?;
   Ok(())
 }
diff --git a/wtx/src/http2/server_stream.rs b/wtx/src/http2/server_stream.rs
index 1a59077d..b45500a3 100644
--- a/wtx/src/http2/server_stream.rs
+++ b/wtx/src/http2/server_stream.rs
@@ -1,30 +1,29 @@
 use crate::{
-  http::{Method, ReqResBuffer, ReqResData, Response},
+  http::{Method, Protocol, ReqResBuffer, ReqResData, Response},
   http2::{
-    misc::{
-      manage_recurrent_stream_receiving, process_higher_operation_err, send_go_away,
-      send_reset_stream,
-    },
+    hpack_static_headers::{HpackStaticRequestHeaders, HpackStaticResponseHeaders},
+    misc::{manage_recurrent_stream_receiving, process_higher_operation_err},
     send_msg::send_msg,
-    HpackStaticRequestHeaders, HpackStaticResponseHeaders, Http2Buffer, Http2Data, Http2ErrorCode,
-    StreamControlRecvParams, U31,
+    stream_receiver::StreamControlRecvParams,
+    u31::U31,
+    CommonStream, Http2Buffer, Http2Data, Http2RecvStatus, Http2SendStatus,
   },
-  misc::{Lease, LeaseMut, Lock, RefCounter, StreamWriter, _Span, sleep},
+  misc::{Lease, LeaseMut, Lock, RefCounter, SingleTypeStorage, StreamWriter, _Span},
 };
 use alloc::sync::Arc;
 use core::{
   future::{poll_fn, Future},
   pin::pin,
   sync::atomic::AtomicBool,
-  time::Duration,
 };
 
 /// Created when a server receives an initial stream.
-#[derive(Debug)]
+#[derive(Clone, Debug)]
 pub struct ServerStream<HD> {
   hd: HD,
   is_conn_open: Arc<AtomicBool>,
   method: Method,
+  protocol: Option<Protocol>,
   span: _Span,
   stream_id: U31,
 }
@@ -35,32 +34,55 @@ impl<HD> ServerStream<HD> {
     hd: HD,
     is_conn_open: Arc<AtomicBool>,
     method: Method,
+    protocol: Option<Protocol>,
     span: _Span,
     stream_id: U31,
   ) -> Self {
-    Self { hd, is_conn_open, method, span, stream_id }
+    Self { hd, is_conn_open, method, protocol, span, stream_id }
   }
 }
 
-impl<HB, HD, RRB, SW> ServerStream<HD>
+impl<HB, HD, SW> ServerStream<HD>
 where
-  HB: LeaseMut<Http2Buffer<RRB>>,
+  HB: LeaseMut<Http2Buffer>,
   HD: RefCounter,
-  HD::Item: Lock<Resource = Http2Data<HB, RRB, SW, false>>,
-  RRB: LeaseMut<ReqResBuffer>,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, false>>,
   SW: StreamWriter,
 {
+  /// See [`CommonStream`].
+  #[inline]
+  pub fn common(&mut self) -> CommonStream<'_, HD, false> {
+    CommonStream {
+      hd: &mut self.hd,
+      is_conn_open: &self.is_conn_open,
+      span: &mut self.span,
+      stream_id: self.stream_id,
+    }
+  }
+
+  /// See [`Method`].
+  #[inline]
+  pub fn method(&self) -> Method {
+    self.method
+  }
+
+  /// See [`Protocol`].
+  #[inline]
+  pub fn protocol(&self) -> Option<Protocol> {
+    self.protocol
+  }
+
   /// Receive request
   ///
-  /// Higher operation that awaits for the data necessary to build a request.
+  /// High level operation that awaits for the data necessary to build a request.
   ///
-  /// Returns [`Option::None`] if the network/stream connection has been closed, either locally
+  /// Returns `false` if the network/stream connection has been closed, either locally
   /// or externally.
   ///
   /// Shouldn't be called more than once.
   #[inline]
-  pub async fn recv_req(&mut self) -> crate::Result<(RRB, Option<Method>)> {
-    let Self { hd, is_conn_open, method, span, stream_id } = self;
+  pub async fn recv_req(&mut self) -> crate::Result<(Http2RecvStatus<(), ()>, ReqResBuffer)> {
+    let Self { hd, is_conn_open, method: _, protocol: _, span, stream_id } = self;
     let _e = span._enter();
     _trace!("Receiving request");
     let mut lock_pin = pin!(hd.lock());
@@ -81,7 +103,6 @@ where
               windows: sorp.windows,
             },
           ));
-          *method
         },
       )
     })
@@ -92,13 +113,6 @@ where
     rslt
   }
 
-  /// Sends a GOAWAY frame to the peer, which cancels the connection and consequently all ongoing
-  /// streams.
-  #[inline]
-  pub async fn send_go_away(self, error_code: Http2ErrorCode) {
-    send_go_away(error_code, &mut self.hd.lock().await.parts_mut()).await;
-  }
-
   /// Send Response
   ///
   /// Higher operation that sends all data related to a response and then closes the stream.
@@ -106,16 +120,18 @@ where
   /// Returns [`Option::None`] if the network/stream connection has been closed, either locally
   /// or externally.
   ///
-  /// Should be called after [`Self::recv_req`] is successfully executed.
+  /// Should be called after [`Self::recv_req`] or any other low level methods that receive data
+  /// are successfully executed. More specifically, should only be called in a half-closed stream
+  /// state.
   #[inline]
-  pub async fn send_res<RRD>(&mut self, res: Response<RRD>) -> crate::Result<Option<()>>
+  pub async fn send_res<RRD>(&mut self, res: Response<RRD>) -> crate::Result<Http2SendStatus>
   where
     RRD: ReqResData,
     RRD::Body: Lease<[u8]>,
   {
     let _e = self.span._enter();
     _trace!("Sending response");
-    if send_msg::<_, _, _, _, false>(
+    let hss = send_msg::<_, _, _, false>(
       res.rrd.body().lease(),
       &self.hd,
       res.rrd.headers(),
@@ -127,28 +143,28 @@ where
       self.stream_id,
       |_| {},
     )
-    .await?
-    .is_none()
-    {
-      return Ok(None);
+    .await?;
+    if !matches!(hss, Http2SendStatus::ClosedConnection) {
+      return Ok(hss);
     }
-    sleep(Duration::from_millis(50)).await?;
-    drop(self.hd.lock().await.parts_mut().hb.scrp.remove(&self.stream_id));
-    Ok(Some(()))
+    Ok(Http2SendStatus::Ok)
   }
+}
 
-  /// Sends a stream reset to the peer, which cancels this stream.
+impl<HD> Lease<ServerStream<HD>> for ServerStream<HD> {
   #[inline]
-  pub async fn send_reset(self, error_code: Http2ErrorCode) {
-    let mut guard = self.hd.lock().await;
-    let hdpm = guard.parts_mut();
-    let _ = send_reset_stream(
-      error_code,
-      &mut hdpm.hb.scrp,
-      &mut hdpm.hb.sorp,
-      hdpm.stream_writer,
-      self.stream_id,
-    )
-    .await;
+  fn lease(&self) -> &ServerStream<HD> {
+    self
   }
 }
+
+impl<HD> LeaseMut<ServerStream<HD>> for ServerStream<HD> {
+  #[inline]
+  fn lease_mut(&mut self) -> &mut ServerStream<HD> {
+    self
+  }
+}
+
+impl<HD> SingleTypeStorage for ServerStream<HD> {
+  type Item = HD;
+}
diff --git a/wtx/src/http2/settings_frame.rs b/wtx/src/http2/settings_frame.rs
index ac49ad4d..4eb74bb8 100644
--- a/wtx/src/http2/settings_frame.rs
+++ b/wtx/src/http2/settings_frame.rs
@@ -1,7 +1,10 @@
 use crate::{
   http2::{
-    misc::protocol_err, CommonFlags, FrameInit, FrameInitTy, Http2Error, Http2ErrorCode,
-    MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND, U31,
+    common_flags::CommonFlags,
+    frame_init::{FrameInit, FrameInitTy},
+    misc::protocol_err,
+    u31::U31,
+    Http2Error, Http2ErrorCode, MAX_FRAME_LEN_LOWER_BOUND, MAX_FRAME_LEN_UPPER_BOUND,
   },
   misc::ArrayChunks,
 };
diff --git a/wtx/src/http2/stream_receiver.rs b/wtx/src/http2/stream_receiver.rs
index 7496dd24..bd5df030 100644
--- a/wtx/src/http2/stream_receiver.rs
+++ b/wtx/src/http2/stream_receiver.rs
@@ -1,30 +1,35 @@
 use crate::{
-  http::StatusCode,
-  http2::{StreamState, Windows},
+  http::{ReqResBuffer, StatusCode},
+  http2::{stream_state::StreamState, window::Windows},
 };
 use core::task::Waker;
 
+/// Parameters used when a stream should only receive control frames like `RST_STREAM` or
+/// `WINDOW_UPDATE`.
+///
+/// Used only by unidirectional streams when they are sending data or when the state is closed.
+#[derive(Debug)]
+pub(crate) struct StreamControlRecvParams {
+  pub(crate) is_stream_open: bool,
+  pub(crate) stream_state: StreamState,
+  pub(crate) waker: Waker,
+  pub(crate) windows: Windows,
+}
+
 /// Parameters used when a stream should receive any type of frame, including `HEADER` or
 /// `DATA` frames.
+///
+/// Used by bidirectional or unidirectional streams.
 #[derive(Debug)]
-pub(crate) struct StreamOverallRecvParams<RRB> {
+pub(crate) struct StreamOverallRecvParams {
   pub(crate) content_length: Option<usize>,
   pub(crate) body_len: u32,
   pub(crate) has_initial_header: bool,
+  pub(crate) has_one_or_more_data_frames: bool,
   pub(crate) is_stream_open: bool,
-  pub(crate) rrb: RRB,
+  pub(crate) rrb: ReqResBuffer,
   pub(crate) status_code: StatusCode,
   pub(crate) stream_state: StreamState,
   pub(crate) windows: Windows,
   pub(crate) waker: Waker,
 }
-
-/// Parameters used when a stream should only receive control frames like `RST_STREAM` or
-/// `WINDOW_UPDATE`. This can happen when the stream finishes or when the stream is sending data.
-#[derive(Debug)]
-pub(crate) struct StreamControlRecvParams {
-  pub(crate) is_stream_open: bool,
-  pub(crate) stream_state: StreamState,
-  pub(crate) waker: Waker,
-  pub(crate) windows: Windows,
-}
diff --git a/wtx/src/http2/stream_state.rs b/wtx/src/http2/stream_state.rs
index f38cdc67..af4c18b0 100644
--- a/wtx/src/http2/stream_state.rs
+++ b/wtx/src/http2/stream_state.rs
@@ -1,12 +1,12 @@
 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
 pub(crate) enum StreamState {
-  /// Final stage. Sent/received `EOS_STREAM`/`RST_STREAM` after
+  /// Final stage. Sent/received `END_STREAM`/`RST_STREAM` after
   /// [`StreamState::HalfClosedLocal`]/[`StreamState::HalfClosedRemote`] or sent/received
   /// `RST_STREAM` after [`StreamState::Open`].
   Closed,
-  /// The system sent `EOS_STREAM` after [`StreamState::Open`].
+  /// The system sent `END_STREAM` after [`StreamState::Open`].
   HalfClosedLocal,
-  /// The system received `EOS_STREAM` after [`StreamState::Open`].
+  /// The system received `END_STREAM` after [`StreamState::Open`].
   HalfClosedRemote,
   /// Initial state. Awaiting initial headers.
   Idle,
@@ -16,11 +16,11 @@ pub(crate) enum StreamState {
 
 impl StreamState {
   /// If the system can send to a peer regardless of the frame type.
-  pub(crate) fn can_send_stream<const IS_CLIENT: bool>(self) -> bool {
+  pub(crate) fn can_send<const IS_CLIENT: bool>(self) -> bool {
     if IS_CLIENT {
       matches!(self, Self::Idle | Self::Open)
     } else {
-      matches!(self, Self::HalfClosedRemote)
+      matches!(self, Self::HalfClosedRemote | Self::Open)
     }
   }
 
diff --git a/wtx/src/http2/web_socket_over_stream.rs b/wtx/src/http2/web_socket_over_stream.rs
new file mode 100644
index 00000000..d0cd7a73
--- /dev/null
+++ b/wtx/src/http2/web_socket_over_stream.rs
@@ -0,0 +1,193 @@
+//! Tools to manage WebSocket connections in HTTP/2 streams
+
+use crate::{
+  http::{Headers, Method, Protocol, StatusCode},
+  http2::{Http2Buffer, Http2Data, Http2RecvStatus, SendDataMode, ServerStream},
+  misc::{
+    ConnectionState, LeaseMut, Lock, RefCounter, SingleTypeStorage, StreamWriter, Vector,
+    Xorshift64,
+  },
+  web_socket::{
+    web_socket_reader::{
+      manage_auto_reply, manage_op_code_of_continuation_frames,
+      manage_op_code_of_first_continuation_frame, manage_op_code_of_first_final_frame,
+      manage_text_of_first_continuation_frame, manage_text_of_recurrent_continuation_frames,
+      unmask_nb,
+    },
+    Frame, FrameMut, ReadFrameInfo,
+  },
+};
+
+/// Verifies if the initial received headers represent a WebSocket connection.
+#[inline]
+pub fn is_web_socket_handshake(
+  headers: &Headers,
+  method: Method,
+  protocol: Option<Protocol>,
+) -> bool {
+  method == Method::Connect
+    && protocol == Some(Protocol::WebSocket)
+    && headers.get_by_name(b"sec-websocket-version").map(|el| el.value) == Some(b"13")
+}
+
+/// WebSocket tunneling
+#[derive(Debug)]
+pub struct WebSocketOverStream<S> {
+  connection_state: ConnectionState,
+  rng: Xorshift64,
+  stream: S,
+}
+
+impl<HB, HD, S, SW> WebSocketOverStream<S>
+where
+  HB: LeaseMut<Http2Buffer>,
+  HD: RefCounter,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, false>>,
+  S: LeaseMut<ServerStream<HD>> + SingleTypeStorage<Item = HD>,
+  SW: StreamWriter,
+{
+  /// Creates a new instance sending an `Ok` status codes that confirms the WebSocket handshake.
+  #[inline]
+  pub async fn new(headers: &Headers, rng: Xorshift64, mut stream: S) -> crate::Result<Self> {
+    let hss = stream.lease_mut().common().send_headers(headers, false, StatusCode::Ok).await?;
+    if hss.is_closed() {
+      return Err(crate::Error::ClosedConnection);
+    }
+    Ok(Self { connection_state: ConnectionState::Open, rng, stream })
+  }
+
+  /// Reads a frame from the stream.
+  ///
+  /// If a frame is made up of other sub-frames or continuations, then everything is collected
+  /// until all fragments are received.
+  #[inline]
+  pub async fn read_frame<'buffer>(
+    &mut self,
+    buffer: &'buffer mut Vector<u8>,
+  ) -> crate::Result<FrameMut<'buffer, false>> {
+    buffer.clear();
+    let first_rfi = loop {
+      let (rfi, is_eos) = recv_data(buffer, self.stream.lease_mut()).await?;
+      if !rfi.fin {
+        if is_eos {
+          return Err(crate::Error::ClosedConnection);
+        }
+        break rfi;
+      }
+      if manage_auto_reply::<_, _, false>(
+        self.stream.lease_mut(),
+        &mut self.connection_state,
+        rfi.op_code,
+        buffer,
+        &mut self.rng,
+        &mut write_control_frame_cb,
+      )
+      .await?
+      {
+        manage_op_code_of_first_final_frame(rfi.op_code, buffer)?;
+        return Ok(FrameMut::new_fin(rfi.op_code, buffer));
+      }
+    };
+    loop {
+      let (rfi, is_eos) = recv_data(buffer, self.stream.lease_mut()).await?;
+      if !rfi.fin && is_eos {
+        return Err(crate::Error::ClosedConnection);
+      }
+      let begin = buffer.len();
+      let mut iuc = manage_op_code_of_first_continuation_frame(
+        first_rfi.op_code,
+        buffer,
+        manage_text_of_first_continuation_frame,
+      )?;
+      let payload = buffer.get_mut(begin..).unwrap_or_default();
+      if !manage_auto_reply::<_, _, false>(
+        self.stream.lease_mut(),
+        &mut self.connection_state,
+        rfi.op_code,
+        payload,
+        &mut self.rng,
+        &mut write_control_frame_cb,
+      )
+      .await?
+      {
+        buffer.truncate(begin);
+        continue;
+      }
+      if manage_op_code_of_continuation_frames(
+        rfi.fin,
+        first_rfi.op_code,
+        &mut iuc,
+        rfi.op_code,
+        payload,
+        manage_text_of_recurrent_continuation_frames,
+      )? {
+        return Ok(FrameMut::new_fin(first_rfi.op_code, buffer));
+      }
+    }
+  }
+
+  /// Writes a frame to the stream.
+  #[inline]
+  pub async fn write_frame<P>(&mut self, frame: &mut Frame<P, false>) -> crate::Result<()>
+  where
+    P: LeaseMut<[u8]>,
+  {
+    let (header, payload) = frame.header_and_payload();
+    let hss = self
+      .stream
+      .lease_mut()
+      .common()
+      .send_data(SendDataMode::single_data_frame([header, payload.lease()]), false)
+      .await?;
+    if hss.is_closed() {
+      return Err(crate::Error::ClosedConnection);
+    }
+    Ok(())
+  }
+}
+
+#[inline]
+async fn recv_data<'buffer, HB, HD, SW>(
+  buffer: &'buffer mut Vector<u8>,
+  stream: &mut ServerStream<HD>,
+) -> crate::Result<(ReadFrameInfo, bool)>
+where
+  HB: LeaseMut<Http2Buffer>,
+  HD: RefCounter,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, false>>,
+  SW: StreamWriter,
+{
+  let (data, is_eos) = match stream.common().recv_data().await? {
+    Http2RecvStatus::ClosedConnection => {
+      return Err(crate::Error::ClosedConnection);
+    }
+    Http2RecvStatus::ClosedStream => {
+      return Err(crate::Error::ClosedConnection);
+    }
+    Http2RecvStatus::Eos(data) => (data, true),
+    Http2RecvStatus::Ongoing(data) => (data, false),
+  };
+  let mut slice = data.as_slice();
+  let rfi = ReadFrameInfo::from_bytes::<_, false>(&mut slice, usize::MAX, &())?;
+  let before = buffer.len();
+  buffer.extend_from_copyable_slice(slice)?;
+  unmask_nb::<false>(buffer.get_mut(before..).unwrap_or_default(), &rfi)?;
+  Ok((rfi, is_eos))
+}
+
+#[inline]
+async fn write_control_frame_cb<HB, HD, SW>(
+  stream: &mut ServerStream<HD>,
+  header: &[u8],
+  payload: &[u8],
+) -> crate::Result<()>
+where
+  HB: LeaseMut<Http2Buffer>,
+  HD: RefCounter,
+  HD::Item: Lock<Resource = Http2Data<HB, SW, false>>,
+  SW: StreamWriter,
+{
+  let array = [header, payload];
+  let _ = stream.common().send_data(SendDataMode::single_data_frame(array), true).await?;
+  Ok(())
+}
diff --git a/wtx/src/http2/window.rs b/wtx/src/http2/window.rs
index 0fcc21eb..83d08b52 100644
--- a/wtx/src/http2/window.rs
+++ b/wtx/src/http2/window.rs
@@ -1,7 +1,7 @@
 use crate::{
   http2::{
-    http2_params_send::Http2ParamsSend, misc::write_array, Http2Error, Http2ErrorCode, Http2Params,
-    WindowUpdateFrame, U31,
+    http2_params_send::Http2ParamsSend, misc::write_array, u31::U31,
+    window_update_frame::WindowUpdateFrame, Http2Error, Http2ErrorCode, Http2Params,
   },
   misc::StreamWriter,
 };
@@ -9,7 +9,7 @@ use core::sync::atomic::AtomicBool;
 
 /// A "credit" system used to restrain the exchange of data.
 #[derive(Clone, Copy, Debug)]
-pub(crate) struct Window {
+pub struct Window {
   available: i32,
 }
 
@@ -19,6 +19,7 @@ impl Window {
     Self { available }
   }
 
+  /// The amount of data available to send or receive. Depends if you are a client or a server.
   #[inline]
   pub(crate) const fn available(self) -> i32 {
     self.available
@@ -76,13 +77,16 @@ impl Window {
   }
 }
 
+/// A "credit" system used to restrain the exchange of data.
+///
+/// Groups the sending the receiving  parameters.
 #[derive(Clone, Copy, Debug)]
-pub(crate) struct Windows {
+pub struct Windows {
   /// Parameters used to received data. It is defined locally.
-  pub(crate) recv: Window,
+  recv: Window,
   /// Parameters used to send data. It is initially defined locally with default parameters
   /// and then defined by a remote peer.
-  pub(crate) send: Window,
+  send: Window,
 }
 
 impl Windows {
@@ -99,6 +103,24 @@ impl Windows {
   pub(crate) const fn new() -> Self {
     Self { recv: Window::new(0), send: Window::new(0) }
   }
+
+  /// Parameters used to received data. It is defined locally.
+  #[inline]
+  pub const fn recv(&self) -> Window {
+    self.recv
+  }
+
+  /// Parameters used to send data. It is initially defined locally with default parameters
+  /// and then defined by a remote peer.
+  #[inline]
+  pub const fn send(&self) -> Window {
+    self.send
+  }
+
+  #[inline]
+  pub(crate) fn send_mut(&mut self) -> &mut Window {
+    &mut self.send
+  }
 }
 
 #[derive(Debug)]
@@ -118,7 +140,7 @@ impl<'any> WindowsPair<'any> {
     self.stream.send.available()
   }
 
-  /// withdrawn - Receive
+  /// Withdrawn - Receive
   ///
   /// Controls window sizes received from external sources. Invalid or negative values trigger a
   /// frame dispatch to return to the default window size.
diff --git a/wtx/src/http2/window_update_frame.rs b/wtx/src/http2/window_update_frame.rs
index 34454120..e89aad8d 100644
--- a/wtx/src/http2/window_update_frame.rs
+++ b/wtx/src/http2/window_update_frame.rs
@@ -1,5 +1,9 @@
 use crate::http2::{
-  misc::protocol_err, CommonFlags, FrameInit, FrameInitTy, Http2Error, Http2ErrorCode, U31,
+  common_flags::CommonFlags,
+  frame_init::{FrameInit, FrameInitTy},
+  misc::protocol_err,
+  u31::U31,
+  Http2Error, Http2ErrorCode,
 };
 
 #[derive(Debug, Eq, PartialEq)]
diff --git a/wtx/src/lib.rs b/wtx/src/lib.rs
index 611d0c00..895f0f7a 100644
--- a/wtx/src/lib.rs
+++ b/wtx/src/lib.rs
@@ -1,8 +1,8 @@
-#![allow(incomplete_features, reason = "essential async feature")]
+#![cfg_attr(feature = "nightly", allow(incomplete_features, reason = "essential async feature"))]
 #![cfg_attr(feature = "_bench", allow(soft_unstable))]
 #![cfg_attr(feature = "_bench", feature(test))]
 #![doc = include_str!("../README.md")]
-#![cfg_attr(feature = "tokio", feature(return_type_notation))]
+#![cfg_attr(feature = "nightly", feature(return_type_notation))]
 #![no_std]
 
 extern crate alloc;
diff --git a/wtx/src/macros.rs b/wtx/src/macros.rs
index ca4e37d6..dd5fa85e 100644
--- a/wtx/src/macros.rs
+++ b/wtx/src/macros.rs
@@ -4,7 +4,7 @@ macro_rules! _conn_params_methods {
     #[inline]
     #[must_use]
     pub fn initial_window_len(mut self, elem: u32) -> Self {
-      self.cp.initial_window_len = elem;
+      self.cp._initial_window_len = elem;
       self
     }
 
@@ -12,7 +12,7 @@ macro_rules! _conn_params_methods {
     #[inline]
     #[must_use]
     pub fn max_body_len(mut self, elem: u32) -> Self {
-      self.cp.max_body_len = elem;
+      self.cp._max_body_len = elem;
       self
     }
 
@@ -20,7 +20,7 @@ macro_rules! _conn_params_methods {
     #[inline]
     #[must_use]
     pub fn max_concurrent_streams_num(mut self, elem: u32) -> Self {
-      self.cp.max_concurrent_streams_num = elem;
+      self.cp._max_concurrent_streams_num = elem;
       self
     }
 
@@ -28,7 +28,7 @@ macro_rules! _conn_params_methods {
     #[inline]
     #[must_use]
     pub fn max_frame_len(mut self, elem: u32) -> Self {
-      self.cp.max_frame_len = elem;
+      self.cp._max_frame_len = elem;
       self
     }
 
@@ -44,7 +44,7 @@ macro_rules! _conn_params_methods {
     #[inline]
     #[must_use]
     pub fn max_hpack_len(mut self, elem: (u32, u32)) -> Self {
-      self.cp.max_hpack_len = elem;
+      self.cp._max_hpack_len = elem;
       self
     }
 
@@ -52,7 +52,7 @@ macro_rules! _conn_params_methods {
     #[inline]
     #[must_use]
     pub fn max_headers_len(mut self, elem: u32) -> Self {
-      self.cp.max_headers_len = elem;
+      self.cp._max_headers_len = elem;
       self
     }
 
@@ -62,7 +62,7 @@ macro_rules! _conn_params_methods {
     #[inline]
     #[must_use]
     pub fn max_recv_streams_num(mut self, elem: u32) -> Self {
-      self.cp.max_recv_streams_num = elem;
+      self.cp._max_recv_streams_num = elem;
       self
     }
   };
@@ -305,6 +305,43 @@ macro_rules! _max_frames_mismatches {
   };
 }
 
+macro_rules! _simd {
+  (
+    512 => $_512:expr,
+    256 => $_256:expr,
+    128 => $_128:expr,
+    _ => $fallback:expr $(,)?
+  ) => {{
+    #[cfg(target_feature = "avx512f")]
+    let rslt = $_512;
+
+    #[cfg(all(target_feature = "avx2", not(target_feature = "avx512f")))]
+    let rslt = $_256;
+
+    #[cfg(all(
+      target_feature = "neon",
+      not(any(target_feature = "avx2", target_feature = "avx512f"))
+    ))]
+    let rslt = $_128;
+
+    #[cfg(all(
+      target_feature = "sse2",
+      not(any(target_feature = "avx2", target_feature = "avx512f", target_feature = "neon"))
+    ))]
+    let rslt = $_128;
+
+    #[cfg(not(any(
+      target_feature = "avx2",
+      target_feature = "avx512f",
+      target_feature = "neon",
+      target_feature = "sse2"
+    )))]
+    let rslt = $fallback;
+
+    rslt
+  }};
+}
+
 macro_rules! _trace {
   ($($tt:tt)+) => {
     #[cfg(feature = "tracing")]
diff --git a/wtx/src/misc.rs b/wtx/src/misc.rs
index 23bb991d..bc6b5e9c 100644
--- a/wtx/src/misc.rs
+++ b/wtx/src/misc.rs
@@ -3,9 +3,8 @@
 mod array_chunks;
 mod array_string;
 mod array_vector;
-mod atomic_waker;
 mod blocks_queue;
-mod buffer_param;
+mod buffer_mode;
 mod bytes_fmt;
 mod connection_state;
 mod either;
@@ -25,13 +24,13 @@ mod optimization;
 mod partitioned_filled_buffer;
 mod query_writer;
 mod queue;
-mod queue_utils;
 mod ref_counter;
 mod rng;
 mod role;
 mod single_type_storage;
 mod span;
 mod stream;
+mod sync;
 #[cfg(feature = "tokio-rustls")]
 mod tokio_rustls;
 mod tuple_impls;
@@ -45,9 +44,8 @@ pub use self::tokio_rustls::{TokioRustlsAcceptor, TokioRustlsConnector};
 pub use array_chunks::{ArrayChunks, ArrayChunksMut};
 pub use array_string::{ArrayString, ArrayStringError};
 pub use array_vector::{ArrayVector, ArrayVectorError, IntoIter};
-pub use atomic_waker::AtomicWaker;
 pub use blocks_queue::{Block, BlocksQueue, BlocksQueueError};
-pub use buffer_param::BufferParam;
+pub use buffer_mode::BufferMode;
 pub use bytes_fmt::BytesFmt;
 pub use connection_state::ConnectionState;
 use core::{any::type_name, fmt::Write, ops::Range, time::Duration};
@@ -70,6 +68,7 @@ pub use rng::*;
 pub use role::Role;
 pub use single_type_storage::SingleTypeStorage;
 pub use stream::{BytesStream, Stream, StreamReader, StreamWithTls, StreamWriter};
+pub use sync::*;
 pub use uri::{Uri, UriArrayString, UriRef, UriString};
 pub use usize::Usize;
 pub use utf8_errors::{BasicUtf8Error, ExtUtf8Error, StdUtf8Error};
@@ -80,6 +79,7 @@ pub(crate) use {
   mem_transfer::_shift_copyable_chunks,
   partitioned_filled_buffer::PartitionedFilledBuffer,
   span::{_Entered, _Span},
+  uri::_EMPTY_URI_STRING,
 };
 
 /// Useful when a request returns an optional field but the actual usage is within a
@@ -251,7 +251,7 @@ pub(crate) fn _number_or_available_parallelism(n: Option<usize>) -> crate::Resul
 #[cfg(feature = "foldhash")]
 pub(crate) fn _random_state(mut rng: impl Rng) -> foldhash::fast::FixedState {
   let [a, b, c, d, e, f, g, h] = rng.u8_8();
-  foldhash::fast::FixedState::with_seed(u64::from_le_bytes([a, b, c, d, e, f, g, h]))
+  foldhash::fast::FixedState::with_seed(u64::from_ne_bytes([a, b, c, d, e, f, g, h]))
 }
 
 pub(crate) async fn _read_until<const LEN: usize, SR>(
diff --git a/wtx/src/misc/array_vector.rs b/wtx/src/misc/array_vector.rs
index de3c2682..6dff541a 100644
--- a/wtx/src/misc/array_vector.rs
+++ b/wtx/src/misc/array_vector.rs
@@ -44,7 +44,7 @@ impl<T, const N: usize> ArrayVector<T, N> {
     // SAFETY: The inner `data` as well as the provided `array` have the same layout in different
     // memory regions
     unsafe {
-      ptr::copy_nonoverlapping(array.as_ptr(), this.as_mut_ptr(), N);
+      ptr::copy_nonoverlapping(array.as_ptr(), this.as_ptr_mut(), N);
     }
     mem::forget(array);
     this
@@ -78,14 +78,14 @@ impl<T, const N: usize> ArrayVector<T, N> {
     // SAFETY: The inner `data` as well as the provided `data` have the same layout in different
     // memory regions
     unsafe {
-      ptr::copy_nonoverlapping(data.as_ptr(), this.as_mut_ptr(), actual_len_usize);
+      ptr::copy_nonoverlapping(data.as_ptr(), this.as_ptr_mut(), actual_len_usize);
     }
     if Self::NEEDS_DROP {
       let diff_opt = data.len().checked_sub(actual_len_usize);
       if let Some(diff @ 1..=usize::MAX) = diff_opt {
         // SAFETY: Indices are within bounds
         unsafe {
-          drop_elements(actual_len, diff, data.as_mut_ptr());
+          drop_elements(diff, actual_len, data.as_mut_ptr());
         }
       };
     }
@@ -183,19 +183,19 @@ impl<T, const N: usize> ArrayVector<T, N> {
     if Self::NEEDS_DROP {
       // SAFETY: Indices are within bounds
       unsafe {
-        drop_elements(new_len, *Usize::from(diff), self.as_mut_ptr());
+        drop_elements(*Usize::from(diff), new_len, self.as_ptr_mut());
       }
     }
   }
 
   #[inline]
-  fn as_mut_ptr(&mut self) -> *mut T {
-    self.data.as_mut_ptr().cast()
+  const fn as_ptr(&self) -> *const T {
+    self.data.as_ptr().cast()
   }
 
   #[inline]
-  const fn as_ptr(&self) -> *const T {
-    self.data.as_ptr().cast()
+  fn as_ptr_mut(&mut self) -> *mut T {
+    self.data.as_mut_ptr().cast()
   }
 
   #[inline]
@@ -275,7 +275,7 @@ where
       return Err(ArrayVectorError::ExtendFromSliceOverflow);
     };
     // SAFETY: The above check ensures bounds
-    let dst = unsafe { self.as_mut_ptr().add(Usize::from_u32(len).into_usize()) };
+    let dst = unsafe { self.as_ptr_mut().add(Usize::from_u32(len).into_usize()) };
     // SAFETY: Parameters are valid
     unsafe {
       ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len_usize);
@@ -336,7 +336,7 @@ impl<T, const N: usize> DerefMut for ArrayVector<T, N> {
   #[inline]
   fn deref_mut(&mut self) -> &mut Self::Target {
     // SAFETY: `len` ensures initialized elements
-    unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), *Usize::from(self.len)) }
+    unsafe { slice::from_raw_parts_mut(self.as_ptr_mut(), *Usize::from(self.len)) }
   }
 }
 
@@ -529,7 +529,7 @@ impl<T, const N: usize> Drop for IntoIter<T, N> {
       if diff > 0 {
         // SAFETY: Indices are within bounds
         unsafe {
-          drop_elements(idx, *Usize::from(diff), self.data.as_mut_ptr());
+          drop_elements(*Usize::from(diff), idx, self.data.as_ptr_mut());
         }
       }
     }
@@ -560,9 +560,9 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
 }
 
 #[inline]
-unsafe fn drop_elements<T>(begin: u32, len: usize, ptr: *mut T) {
+unsafe fn drop_elements<T>(len: usize, offset: u32, ptr: *mut T) {
   // SAFETY: It is up to the caller to provide a valid pointer with a valid index
-  let data = unsafe { ptr.add(*Usize::from(begin)) };
+  let data = unsafe { ptr.add(*Usize::from(offset)) };
   // SAFETY: It is up to the caller to provide a valid length
   let elements = unsafe { slice::from_raw_parts_mut(data, len) };
   // SAFETY: It is up to the caller to provide parameters that can lead to droppable elements
diff --git a/wtx/src/misc/blocks_queue.rs b/wtx/src/misc/blocks_queue.rs
index 24e14ffa..961d9941 100644
--- a/wtx/src/misc/blocks_queue.rs
+++ b/wtx/src/misc/blocks_queue.rs
@@ -1,52 +1,35 @@
-macro_rules! as_slices {
-  ($empty:expr, $ptr:ident, $slice:ident, $this:expr, $($ref:tt)*) => {{
-    let len = $this.data.len();
-    // SAFETY: `this.head` will never be greater than capacity
-    let rhs_len = unsafe { $this.data.capacity().unchecked_sub($this.head) };
-    let ptr = $this.data.$ptr();
-    // SAFETY: inner data is expected to point to valid memory
-    let added_ptr = unsafe { ptr.add($this.head) };
-    if rhs_len < len {
-      // SAFETY: `ìf` check ensures bounds
-      let lhs = unsafe { $($ref)* *ptr::$slice(ptr, len.wrapping_sub(rhs_len)) };
-      // SAFETY: `ìf` check ensures bounds
-      let rhs = unsafe { $($ref)* *ptr::$slice(added_ptr, rhs_len) };
-      (lhs, rhs)
-    } else {
-      // SAFETY: `ìf` check ensures bounds
-      let lhs = unsafe { $($ref)* *ptr::$slice(added_ptr, len) };
-      (lhs, $empty)
-    }
-  }}
-}
-
 macro_rules! do_get {
   ($block:ident, $metadata:expr, $ptr:expr, $slice:ident, $($ref:tt)*) => {
     $block {
       data: {
         // SAFETY: `metadata` is always constructed with valid indices
-        let pointer = unsafe {$ptr.add($metadata.begin)};
+        let pointer = unsafe { $ptr.add($metadata.begin) };
         // SAFETY: same as above
         unsafe { $($ref)* *ptr::$slice(pointer, $metadata.len) }
       },
       misc: $($ref)* $metadata.misc,
-      range: {
-        let end = $metadata.begin.wrapping_add($metadata.len);
-        $metadata.begin..end
-      }
+      range: $metadata.begin..$metadata.begin.wrapping_add($metadata.len)
     }
   }
 }
 
-use crate::misc::{
-  queue_utils::{reserve, wrap_sub},
-  Lease, Queue, SingleTypeStorage, Vector,
-};
-use core::{
-  fmt::{Debug, Formatter},
-  ops::Range,
-  ptr,
-};
+macro_rules! get {
+  ($metadata:expr, $ptr:expr) => {
+    do_get!(BlockRef, $metadata, $ptr, slice_from_raw_parts, &)
+  }
+}
+
+macro_rules! get_mut {
+  ($metadata:expr, $ptr:expr) => {
+    do_get!(BlockMut, $metadata, $ptr, slice_from_raw_parts_mut, &mut)
+  }
+}
+
+#[cfg(test)]
+mod tests;
+
+use crate::misc::Queue;
+use core::{ops::Range, ptr};
 
 /// [`Block`] composed by references.
 type BlockRef<'bq, D, M> = Block<&'bq [D], &'bq M>;
@@ -66,41 +49,48 @@ pub enum BlocksQueueError {
 
 /// A circular buffer where elements are added in one-way blocks that will never intersect
 /// boundaries.
+#[derive(Debug)]
 pub struct BlocksQueue<D, M> {
-  data: Vector<D>,
-  head: usize,
-  metadata: Queue<BlocksQueueMetadata<M>>,
-  tail: usize,
+  data: Queue<D>,
+  metadata: Queue<Metadata<M>>,
 }
 
 impl<D, M> BlocksQueue<D, M> {
   /// Creates a new empty instance.
   #[inline]
   pub const fn new() -> Self {
-    Self { data: Vector::new(), head: 0, metadata: Queue::new(), tail: 0 }
+    Self { data: Queue::new(), metadata: Queue::new() }
   }
 
   /// Constructs a new, empty instance with at least the specified capacity.
   #[inline]
   pub fn with_capacity(blocks: usize, elements: usize) -> Result<Self, BlocksQueueError> {
     Ok(Self {
-      data: Vector::with_capacity(elements)
+      data: Queue::with_capacity(elements)
         .map_err(|_err| BlocksQueueError::WithCapacityOverflow)?,
-      head: 0,
       metadata: Queue::with_capacity(blocks)
         .map_err(|_err| BlocksQueueError::WithCapacityOverflow)?,
-      tail: 0,
+    })
+  }
+
+  /// Constructs a new, empty instance with the exact specified capacity.
+  #[inline]
+  pub fn with_exact_capacity(blocks: usize, elements: usize) -> Result<Self, BlocksQueueError> {
+    Ok(Self {
+      data: Queue::with_exact_capacity(elements)
+        .map_err(|_err| BlocksQueueError::WithCapacityOverflow)?,
+      metadata: Queue::with_exact_capacity(blocks)
+        .map_err(|_err| BlocksQueueError::WithCapacityOverflow)?,
     })
   }
 
   /// Returns a pair of slices which contain, in order, the contents of the queue.
   #[inline]
   pub fn as_slices(&self) -> (&[D], &[D]) {
-    as_slices!(&[][..], as_ptr, slice_from_raw_parts, self, &)
+    self.data.as_slices()
   }
 
   /// Returns the number of blocks the queue can hold without reallocating.
-  #[cfg(test)]
   #[inline]
   pub fn blocks_capacity(&self) -> usize {
     self.metadata.capacity()
@@ -115,11 +105,9 @@ impl<D, M> BlocksQueue<D, M> {
   /// Clears the queue, removing all values.
   #[inline]
   pub fn clear(&mut self) {
-    let Self { data, head, metadata, tail } = self;
+    let Self { data, metadata } = self;
     data.clear();
-    *head = 0;
     metadata.clear();
-    *tail = 0;
   }
 
   /// Returns the number of elements the queue can hold without reallocating.
@@ -137,19 +125,30 @@ impl<D, M> BlocksQueue<D, M> {
   /// Provides a reference to a block at the given index.
   #[inline]
   pub fn get(&self, idx: usize) -> Option<BlockRef<'_, D, M>> {
-    Some(Self::do_get(&self.data, self.metadata.get(idx)?))
+    let metadata = self.metadata.get(idx)?;
+    Some(get!(metadata, self.data.as_ptr()))
   }
 
   /// Mutable version of [`Self::get`].
   #[inline]
   pub fn get_mut(&mut self, idx: usize) -> Option<BlockMut<'_, D, M>> {
-    Some(Self::do_get_mut(&mut self.data, self.metadata.get_mut(idx)?))
+    let metadata = self.metadata.get_mut(idx)?;
+    Some(get_mut!(metadata, self.data.as_ptr_mut()))
   }
 
   /// Returns a front-to-back iterator.
   #[inline]
   pub fn iter(&self) -> impl Iterator<Item = BlockRef<'_, D, M>> {
-    self.metadata.iter().map(|metadata| Self::do_get(&self.data, metadata))
+    self.metadata.iter().map(|metadata| get!(metadata, self.data.as_ptr()))
+  }
+
+  /// Mutable version of [`Self::iter`].
+  #[inline]
+  pub fn iter_mut(&mut self) -> impl Iterator<Item = BlockMut<'_, D, M>> {
+    let Self { data, metadata } = self;
+    metadata
+      .iter_mut()
+      .map(move |elem| do_get!(BlockMut, elem, data.as_ptr_mut(), slice_from_raw_parts_mut, &mut))
   }
 
   /// Returns the last block.
@@ -160,193 +159,56 @@ impl<D, M> BlocksQueue<D, M> {
 
   /// Removes the last element from the queue and returns it, or `None` if it is empty.
   #[inline]
-  pub fn pop_back(&mut self) -> Option<(M, &mut [D])> {
+  pub fn pop_back(&mut self) -> Option<M> {
     let metadata = self.metadata.pop_back()?;
-    if let Some(elem) = self.metadata.last() {
-      self.tail = elem.begin.wrapping_add(elem.len);
-    } else {
-      self.head = 0;
-      self.tail = 0;
-    };
-    let new_len = self.data.len().wrapping_sub(metadata.len);
-    // SAFETY: `metadata` is expected to contain valid data
-    let ptr = unsafe { self.data.as_mut_ptr().add(metadata.begin) };
-    // SAFETY: same as above
-    let slice = unsafe { &mut *ptr::slice_from_raw_parts_mut(ptr, metadata.len) };
-    // SAFETY: same as above
-    unsafe {
-      self.data.set_len(new_len);
-    }
-    Some((metadata.misc, slice))
+    self.data.truncate_back(self.elements_len().wrapping_sub(metadata.len));
+    Some(metadata.misc)
   }
 
   /// Removes the first element and returns it, or [`Option::None`] if the queue is empty.
   #[inline]
-  pub fn pop_front(&mut self) -> Option<(M, &mut [D])> {
+  pub fn pop_front(&mut self) -> Option<M> {
     let metadata = self.metadata.pop_front()?;
-    if let Some(elem) = self.metadata.get(0) {
-      self.head = elem.begin;
-    } else {
-      self.head = 0;
-      self.tail = 0;
-    };
-    let new_len = self.data.len().wrapping_sub(metadata.len);
-    // SAFETY: `metadata` is expected to contain valid data
-    let ptr = unsafe { self.data.as_mut_ptr().add(metadata.begin) };
-    // SAFETY: same as above
-    let slice = unsafe { &mut *ptr::slice_from_raw_parts_mut(ptr, metadata.len) };
-    // SAFETY: same as above
-    unsafe {
-      self.data.set_len(new_len);
-    }
-    Some((metadata.misc, slice))
-  }
-
-  #[inline]
-  fn do_get<'this>(
-    data: &'this Vector<D>,
-    metadata: &'this BlocksQueueMetadata<M>,
-  ) -> BlockRef<'this, D, M> {
-    do_get!(BlockRef, metadata, data.as_ptr(), slice_from_raw_parts, &)
-  }
-
-  #[inline]
-  fn do_get_mut<'this>(
-    data: &'this mut Vector<D>,
-    metadata: &'this mut BlocksQueueMetadata<M>,
-  ) -> BlockMut<'this, D, M> {
-    do_get!(BlockMut, metadata, data.as_mut_ptr(), slice_from_raw_parts_mut, &mut)
-  }
-
-  #[inline]
-  fn free(&self, cb: impl FnOnce()) -> (usize, usize) {
-    self.wrap_logic(
-      || {
-        cb();
-        (self.data.capacity(), 0)
-      },
-      || (self.head, self.data.capacity().wrapping_sub(self.tail)),
-      || (self.head.wrapping_sub(self.tail), 0),
-    )
-  }
-
-  #[inline]
-  fn head_lhs(&self, len: usize) -> usize {
-    wrap_sub(self.data.capacity(), self.head, len)
-  }
-
-  #[inline]
-  fn head_rhs(&self, len: usize) -> usize {
-    self.data.capacity().wrapping_sub(len)
+    self.data.truncate_front(self.elements_len().wrapping_sub(metadata.len));
+    Some(metadata.misc)
   }
 
-  #[inline]
-  fn is_wrapped(&self) -> bool {
-    self.wrap_logic(|| false, || false, || true)
-  }
-
-  #[inline]
-  fn wrap_logic<R>(
-    &self,
-    empty: impl FnOnce() -> R,
-    contiguous: impl FnOnce() -> R,
-    wraps: impl FnOnce() -> R,
-  ) -> R {
-    if self.head == 0 && self.tail == 0 {
-      empty()
-    } else if self.head <= self.tail {
-      contiguous()
-    } else {
-      wraps()
-    }
-  }
-}
-
-impl<D, M> BlocksQueue<D, M>
-where
-  D: Copy,
-  M: Copy,
-{
   /// Prepends an block to the queue.
   #[inline]
   pub fn push_front<'data, I>(&mut self, data: I, misc: M) -> Result<(), BlocksQueueError>
   where
-    D: 'data,
+    D: Copy + 'data,
     I: IntoIterator<Item = &'data [D]>,
     I::IntoIter: Clone,
   {
-    let iter = data.into_iter();
-    let mut total_data_len: usize = 0;
-    for elem in iter.clone() {
-      total_data_len = total_data_len.wrapping_add(elem.len());
-    }
-    self.reserve(1, total_data_len).map_err(|_err| BlocksQueueError::PushOverflow)?;
-    let mut tail = self.tail;
-    let (left_free, right_free) = self.free(|| {
-      tail = self.data.capacity();
-    });
-    let head = match (left_free >= total_data_len, right_free >= total_data_len) {
-      (true, _) => self.head_lhs(total_data_len),
-      (false, true) => self.head_rhs(total_data_len),
-      (false, false) => return Ok(()),
-    };
-    let metadata = BlocksQueueMetadata { begin: head, len: total_data_len, misc };
-    let _rslt = self.metadata.push_front(metadata);
-    let mut start = head;
-    for value in iter {
-      // SAFETY: `start is within bounds`
-      let dst = unsafe { self.data.as_mut_ptr().add(start) };
-      // SAFETY: the above `match` handled capacity
-      unsafe {
-        ptr::copy_nonoverlapping(value.as_ptr(), dst, value.len());
-      }
-      start = start.wrapping_add(value.len());
-    }
-    self.head = head;
-    self.tail = tail;
-    // SAFETY: the above `match` handled capacity
-    unsafe {
-      self.data.set_len(self.data.len().wrapping_add(total_data_len));
-    }
+    let (total_data_len, head_shift) = self
+      .data
+      .extend_front_from_copyable_slices(data)
+      .map_err(|_err| BlocksQueueError::PushOverflow)?;
+    self
+      .metadata
+      .push_front(Metadata { begin: self.data.head(), len: total_data_len, misc })
+      .map_err(|_err| BlocksQueueError::PushOverflow)?;
+    self.adjust_metadata(head_shift, 1);
     Ok(())
   }
 
   /// Reserves capacity for at least additional more elements to be inserted in the given queue.
   #[inline(always)]
-  pub fn reserve(&mut self, blocks: usize, elements: usize) -> Result<(), BlocksQueueError> {
-    let is_not_wrapped = !self.is_wrapped();
-    let prev_head = self.head;
-    let diff_opt = reserve(elements, &mut self.data, &mut self.head)
-      .map_err(|_err| BlocksQueueError::ReserveOverflow)?;
-    self.metadata.reserve(blocks).map_err(|_err| BlocksQueueError::ReserveOverflow)?;
-    if let Some(diff) = diff_opt {
-      if is_not_wrapped {
-        self.tail = self.tail.wrapping_add(diff);
-      }
-      let mut iter = self.metadata.iter_mut();
-      for elem in iter.by_ref() {
-        if elem.begin >= prev_head {
-          elem.begin = elem.begin.wrapping_add(diff);
-          break;
-        }
-      }
-      for elem in iter {
-        elem.begin = elem.begin.wrapping_add(diff);
-      }
-    }
+  pub fn reserve_front(&mut self, blocks: usize, elements: usize) -> Result<(), BlocksQueueError> {
+    let _ = self.metadata.reserve_front(blocks).map_err(|_er| BlocksQueueError::ReserveOverflow)?;
+    let n = self.data.reserve_front(elements).map_err(|_err| BlocksQueueError::ReserveOverflow)?;
+    self.adjust_metadata(n, 0);
     Ok(())
   }
-}
 
-impl<D, M> Debug for BlocksQueue<D, M>
-where
-  D: Debug,
-  M: Debug,
-{
   #[inline]
-  fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
-    let (lhs, rhs) = self.as_slices();
-    f.debug_struct("BlocksQueue").field("lhs", &lhs).field("rhs", &rhs).finish()
+  fn adjust_metadata(&mut self, head_shift: usize, skip: usize) {
+    if head_shift > 0 {
+      for metadata in self.metadata.iter_mut().skip(skip) {
+        metadata.begin = metadata.begin.wrapping_add(head_shift);
+      }
+    }
   }
 }
 
@@ -359,10 +221,7 @@ impl<D, M> Default for BlocksQueue<D, M> {
 
 /// Block
 #[derive(Debug, PartialEq)]
-pub struct Block<D, M>
-where
-  D: Lease<[D::Item]> + SingleTypeStorage,
-{
+pub struct Block<D, M> {
   /// Opaque data
   pub data: D,
   /// Miscellaneous
@@ -372,218 +231,8 @@ where
 }
 
 #[derive(Clone, Copy, Debug)]
-struct BlocksQueueMetadata<M> {
+struct Metadata<M> {
   begin: usize,
   len: usize,
   misc: M,
 }
-
-// H = Head (Inclusive)
-// LF = Left Free
-// LO = Left Occupied
-// RF = Right Free
-// RO = Right Occupied
-// T = Tail (Exclusive)
-#[cfg(test)]
-mod tests {
-  use crate::misc::{blocks_queue::BlockRef, BlocksQueue};
-
-  // [. . . . . . . .]: Empty - (LF=8, LO=0,RF=0, RO=0) - (H=0, T=0)
-  // [. . . . . . . H]: Push front - (LF=7, LO=0, RF=0, RO=1) - (H=7, T=8)
-  // [. . . . . H * *]: Push front - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
-  // [. . H * * * * *]: Push front - (LF=2, LO=0, RF=0, RO=6) - (H=2, T=8)
-  // [H * * * * * * *]: Push front - (LF=0, LO=0, RF=0, RO=8) - (H=0, T=8)
-  // [H * * * * * * .]: Pop back - (LF=0, LO=0, RF=2, RO=6) - (H=0, T=7)
-  // [* * * * * * * H]: Push front - (LF=0, LO=7, RF=0, RO=0) - (H=7, T=7)
-  // [* * * * * . . H]: Pop back - (LF=2, LO=5, RF=0, RO=1) - (H=7, T=5)
-  // [* * . . . . . H]: Pop back - (LF=5, LO=2, RF=0, RO=1) - (H=7, T=2)
-  // [* * . . H * * *]: Push front - (LF=2, LO=2, RF=0, RO=4) - (H=4, T=2)
-  // [* * H * * * * *]: Push front - (LF=0, LO=2, RF=0, RO=6) - (H=2, T=2)
-  // [. . H * * * * *]: Pop back - (LF=2, LO=0, RF=0, RO=6) - (H=2, T=8)
-  // [. . H * * * * .]: Pop back - (LF=2, LO=0, RF=1, RO=5) - (H=2, T=7)
-  // [. . H * . . . .]: Pop back - (LF=1, LO=0, RF=4, RO=3) - (H=2, T=4)
-  // [. H * * . . . .]: Push front - (LF=1, LO=0, RF=4, RO=3) - (H=2, T=4)
-  // [H * * * . . . .]: Push front - (LF=0, LO=0, RF=4, RO=4) - (H=0, T=4)
-  // [H . . . . . . .]: Pop back - (LF=0, LO=0, RF=7, RO=1) - (H=0, T=1)
-  // [. . . . . . . .]: Pop back - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
-  #[test]
-  fn pop_back() {
-    let mut q = BlocksQueue::with_capacity(4, 8).unwrap();
-    check_state(&q, 0, 0, 0, 0);
-
-    q.push_front([&[1][..]], ()).unwrap();
-    check_state(&q, 1, 1, 7, 8);
-
-    q.push_front([&[2, 3][..]], ()).unwrap();
-    check_state(&q, 2, 3, 5, 8);
-
-    q.push_front([&[4, 5], &[6][..]], ()).unwrap();
-    check_state(&q, 3, 6, 2, 8);
-
-    q.push_front([&[7, 8][..]], ()).unwrap();
-    check_state(&q, 4, 8, 0, 8);
-
-    let _ = q.pop_back();
-    check_state(&q, 3, 7, 0, 7);
-
-    q.push_front([&[9][..]], ()).unwrap();
-    check_state(&q, 4, 8, 7, 7);
-
-    let _ = q.pop_back();
-    check_state(&q, 3, 6, 7, 5);
-
-    let _ = q.pop_back();
-    check_state(&q, 2, 3, 7, 2);
-
-    q.push_front([&[10], &[11, 12][..]], ()).unwrap();
-    check_state(&q, 3, 6, 4, 2);
-
-    q.push_front([&[13, 14][..]], ()).unwrap();
-    check_state(&q, 4, 8, 2, 2);
-
-    let _ = q.pop_back();
-    check_state(&q, 3, 6, 2, 8);
-
-    let _ = q.pop_back();
-    check_state(&q, 2, 5, 2, 7);
-
-    let _ = q.pop_back();
-    check_state(&q, 1, 2, 2, 4);
-
-    q.push_front([&[15][..]], ()).unwrap();
-    check_state(&q, 2, 3, 1, 4);
-
-    q.push_front([&[16][..]], ()).unwrap();
-    check_state(&q, 3, 4, 0, 4);
-
-    let _ = q.pop_back();
-    check_state(&q, 2, 2, 0, 2);
-
-    let _ = q.pop_back();
-    check_state(&q, 1, 1, 0, 1);
-
-    let _ = q.pop_back();
-    check_state(&q, 0, 0, 0, 0);
-  }
-
-  // [. . . . . . . .]: Empty - (LF=8, LO=0,RF=0, RO=0) - (H=0, T=0)
-  // [. . . . . H * *]: Push front - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
-  // [H * * * * * * *]: Push front - (LF=0, LO=0, RF=0, RO=8) - (H=0, T=8)
-  // [. . . . . H * *]: Push front - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
-  // [. . . . . . . .]: Pop back - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
-  #[test]
-  fn pop_front() {
-    let mut q = BlocksQueue::with_capacity(2, 8).unwrap();
-    check_state(&q, 0, 0, 0, 0);
-
-    q.push_front([&[1, 2, 3][..]], ()).unwrap();
-    check_state(&q, 1, 3, 5, 8);
-
-    q.push_front([&[4, 5], &[6, 7, 8][..]], ()).unwrap();
-    check_state(&q, 2, 8, 0, 8);
-
-    let _ = q.pop_front();
-    check_state(&q, 1, 3, 5, 8);
-
-    let _ = q.pop_front();
-    check_state(&q, 0, 0, 0, 0);
-  }
-
-  // []: Empty - (LF=0, LO=0,RF=0, RO=0) - (H=0, T=0)
-  // [H * * *]: Push front - (LF=0, LO=0, RF=0, RO=4) - (H=0, T=4)
-  #[test]
-  fn push_reserve_and_push() {
-    let mut q = BlocksQueue::new();
-    q.reserve(1, 4).unwrap();
-    q.push_front([&[0, 1, 2, 3][..]], ()).unwrap();
-    check_state(&q, 1, 4, 0, 4);
-    assert_eq!(q.get(0), Some(BlockRef { data: &[0, 1, 2, 3], misc: &(), range: 0..4 }));
-    assert_eq!(q.get(1), None);
-    q.reserve(1, 6).unwrap();
-    q.push_front([&[4, 5, 6, 7, 8, 9][..]], ()).unwrap();
-    check_state(&q, 2, 10, 0, 10);
-    assert_eq!(q.get(0), Some(BlockRef { data: &[4, 5, 6, 7, 8, 9], misc: &(), range: 0..6 }));
-    assert_eq!(q.get(1), Some(BlockRef { data: &[0, 1, 2, 3], misc: &(), range: 6..10 }));
-    assert_eq!(q.get(2), None);
-  }
-
-  #[test]
-  fn reserve() {
-    let mut queue = BlocksQueue::<i32, ()>::new();
-    assert_eq!(queue.blocks_capacity(), 0);
-    assert_eq!(queue.elements_capacity(), 0);
-    queue.reserve(5, 10).unwrap();
-    assert_eq!(queue.blocks_capacity(), 5);
-    assert_eq!(queue.elements_capacity(), 10);
-  }
-
-  // [. . . . . H * * ]: Pop back - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
-  // [. . . . . . . . ]: Pop back - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
-  #[test]
-  fn wrap_pop_back() {
-    let mut q = wrap_initial();
-    let _ = q.pop_back();
-    let _ = q.pop_back();
-    check_state(&q, 1, 3, 5, 8);
-    assert_eq!(q.get(0).unwrap().data, &[1, 2, 3]);
-    let _ = q.pop_back();
-    check_state(&q, 0, 0, 0, 0);
-  }
-
-  // [. . H * . . . . ]: Pop front - (LF=2, LO=0, RF=4, RO=0) - (H=2, T=4)
-  // [. . . . . . . . ]: Pop front - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
-  #[test]
-  fn wrap_pop_front() {
-    let mut q = wrap_initial();
-    let _ = q.pop_front();
-    check_state(&q, 2, 2, 2, 4);
-    assert_eq!(q.get(0).unwrap().data, &[0]);
-    assert_eq!(q.get(1).unwrap().data, &[0]);
-    let _ = q.pop_front();
-    let _ = q.pop_front();
-    check_state(&q, 0, 0, 0, 0);
-  }
-
-  // [. . . . . . . . ]: Empty - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
-  // [. . H * * * * * ]: Push front - (LF=2, LO=0, RF=0, RO=6) - (H=2, T=8)
-  // [. . H * . . . . ]: Pop back - (LF=2, LO=0, RF=4, RO=0) - (H=2, T=4)
-  // [. . * * . H * * ]: Push front - (LF=1, LO=2, RF=0, RO=3) - (H=5, T=4)
-  fn wrap_initial() -> BlocksQueue<i32, ()> {
-    let mut q = BlocksQueue::with_capacity(6, 8).unwrap();
-    check_state(&q, 0, 0, 0, 0);
-    for _ in 0..6 {
-      q.push_front([&[0][..]], ()).unwrap();
-    }
-    check_state(&q, 6, 6, 2, 8);
-    for idx in 0..6 {
-      assert_eq!(q.get(idx).unwrap().data, &[0]);
-    }
-    let _ = q.pop_back();
-    let _ = q.pop_back();
-    let _ = q.pop_back();
-    let _ = q.pop_back();
-    check_state(&q, 2, 2, 2, 4);
-    assert_eq!(q.get(0).unwrap().data, &[0]);
-    assert_eq!(q.get(1).unwrap().data, &[0]);
-    q.push_front([&[1, 2, 3][..]], ()).unwrap();
-    check_state(&q, 3, 5, 5, 4);
-    assert_eq!(q.get(0).unwrap().data, &[1, 2, 3]);
-    assert_eq!(q.get(1).unwrap().data, &[0]);
-    assert_eq!(q.get(2).unwrap().data, &[0]);
-    q
-  }
-
-  #[track_caller]
-  fn check_state(
-    q: &BlocksQueue<i32, ()>,
-    blocks_len: usize,
-    elements_len: usize,
-    head: usize,
-    tail: usize,
-  ) {
-    assert_eq!(q.blocks_len(), blocks_len);
-    assert_eq!(q.elements_len(), elements_len);
-    assert_eq!(q.head, head);
-    assert_eq!(q.tail, tail);
-  }
-}
diff --git a/wtx/src/misc/buffer_param.rs b/wtx/src/misc/buffer_mode.rs
similarity index 66%
rename from wtx/src/misc/buffer_param.rs
rename to wtx/src/misc/buffer_mode.rs
index 5535bf8a..408de02a 100644
--- a/wtx/src/misc/buffer_param.rs
+++ b/wtx/src/misc/buffer_mode.rs
@@ -1,18 +1,18 @@
 /// Generic parameter used in different buffer operations
 #[derive(Clone, Copy, Debug)]
-pub enum BufferParam {
+pub enum BufferMode {
   /// Buffer should be modified with more elements
   Additional(usize),
   /// Buffer should be modified using the exact specified length.
   Len(usize),
 }
 
-impl BufferParam {
+impl BufferMode {
   #[inline]
   pub(crate) fn params(self, len: usize) -> Option<(usize, usize)> {
     Some(match self {
-      BufferParam::Additional(elem) => (elem, len.checked_add(elem)?),
-      BufferParam::Len(elem) => (elem.checked_sub(len)?, elem),
+      BufferMode::Additional(elem) => (elem, len.checked_add(elem)?),
+      BufferMode::Len(elem) => (elem.checked_sub(len)?, elem),
     })
   }
 }
diff --git a/wtx/src/misc/connection_state.rs b/wtx/src/misc/connection_state.rs
index 8df701a9..5ee0e570 100644
--- a/wtx/src/misc/connection_state.rs
+++ b/wtx/src/misc/connection_state.rs
@@ -1,10 +1,10 @@
 /// The state of a connection between two parties.
 #[derive(Clone, Copy, Debug)]
 pub enum ConnectionState {
-  /// Is locally open. Does not necessary means that both parties are in the same state.
-  Open,
   /// Is locally closed. Does not necessary means that both parties are in the same state.
   Closed,
+  /// Is locally open. Does not necessary means that both parties are in the same state.
+  Open,
 }
 
 impl ConnectionState {
@@ -31,3 +31,13 @@ impl From<bool> for ConnectionState {
     }
   }
 }
+
+impl From<ConnectionState> for bool {
+  #[inline]
+  fn from(from: ConnectionState) -> Self {
+    match from {
+      ConnectionState::Closed => false,
+      ConnectionState::Open => true,
+    }
+  }
+}
diff --git a/wtx/src/misc/filled_buffer.rs b/wtx/src/misc/filled_buffer.rs
index efb10e86..d629e3b0 100644
--- a/wtx/src/misc/filled_buffer.rs
+++ b/wtx/src/misc/filled_buffer.rs
@@ -1,4 +1,4 @@
-use crate::misc::{BufferParam, Vector, VectorError};
+use crate::misc::{BufferMode, Vector, VectorError};
 use core::{
   fmt::Debug,
   ops::{Deref, DerefMut},
@@ -11,6 +11,16 @@ pub(crate) struct FilledBuffer {
 }
 
 impl FilledBuffer {
+  #[inline]
+  pub(crate) fn _from_vector(vector: Vector<u8>) -> Self {
+    let mut this = Self { data: vector };
+    // SAFETY: Zero input is always safe.
+    unsafe {
+      this._fill_remaining_capacity(0);
+    }
+    this
+  }
+
   #[inline]
   pub(crate) const fn _new() -> Self {
     Self { data: Vector::new() }
@@ -21,7 +31,7 @@ impl FilledBuffer {
     let mut data = Vector::with_capacity(cap)?;
     // SAFETY: memory have been allocated
     unsafe {
-      slice::from_raw_parts_mut(data.as_mut_ptr(), data.capacity()).fill(0);
+      slice::from_raw_parts_mut(data.as_ptr_mut(), data.capacity()).fill(0);
     }
     Ok(Self { data })
   }
@@ -40,7 +50,7 @@ impl FilledBuffer {
     // SAFETY: allocated elements are always initialized
     unsafe {
       let len = self.data.capacity();
-      slice::from_raw_parts_mut(self.data.as_mut_ptr(), len)
+      slice::from_raw_parts_mut(self.data.as_ptr_mut(), len)
     }
   }
 
@@ -55,7 +65,7 @@ impl FilledBuffer {
   }
 
   #[inline(always)]
-  pub(crate) fn _expand(&mut self, bp: BufferParam) -> Result<(), VectorError> {
+  pub(crate) fn _expand(&mut self, bp: BufferMode) -> Result<(), VectorError> {
     let len = self.data.len();
     let Some((additional, new_len)) = bp.params(len) else {
       return Ok(());
@@ -68,6 +78,12 @@ impl FilledBuffer {
     Ok(())
   }
 
+  #[inline]
+  pub(crate) fn _extend_from_slice(&mut self, other: &[u8]) -> Result<(), VectorError> {
+    let _ = self._extend_from_slices([other])?;
+    Ok(())
+  }
+
   #[inline]
   pub(crate) fn _extend_from_slices<'iter, I>(&mut self, others: I) -> Result<usize, VectorError>
   where
@@ -75,7 +91,7 @@ impl FilledBuffer {
     I::IntoIter: Clone,
   {
     let prev_cap = self.data.capacity();
-    let len = self.data.extend_from_slices(others)?;
+    let len = self.data.extend_from_copyable_slices(others)?;
     // SAFETY: memory have been allocated
     unsafe {
       self._fill_remaining_capacity(prev_cap);
@@ -83,11 +99,6 @@ impl FilledBuffer {
     Ok(len)
   }
 
-  #[inline]
-  pub(crate) fn _len(&self) -> usize {
-    self.data.len()
-  }
-
   #[inline(always)]
   pub(crate) fn _reserve(&mut self, additional: usize) -> Result<(), VectorError> {
     let prev_cap = self.data.capacity();
@@ -118,7 +129,7 @@ impl FilledBuffer {
       return;
     };
     // SAFETY: caller must ensure `prev_cap` elements
-    let ptr = unsafe { self.data.as_mut_ptr().add(count) };
+    let ptr = unsafe { self.data.as_ptr_mut().add(count) };
     // SAFETY: caller must ensure allocated memory
     unsafe {
       slice::from_raw_parts_mut(ptr, diff).fill(0);
@@ -138,7 +149,26 @@ impl Deref for FilledBuffer {
 impl DerefMut for FilledBuffer {
   #[inline]
   fn deref_mut(&mut self) -> &mut Self::Target {
-    self.data.as_mut_slice()
+    self.data.as_slice_mut()
+  }
+}
+
+impl From<FilledBuffer> for Vector<u8> {
+  #[inline]
+  fn from(from: FilledBuffer) -> Self {
+    from.data
+  }
+}
+
+impl From<Vector<u8>> for FilledBuffer {
+  #[inline]
+  fn from(from: Vector<u8>) -> Self {
+    let mut this = Self { data: from };
+    // SAFETY: Zero input is always safe.
+    unsafe {
+      this._fill_remaining_capacity(0);
+    }
+    this
   }
 }
 
@@ -155,8 +185,7 @@ impl std::io::Write for FilledBuffer {
   }
 }
 
-#[cfg(feature = "_proptest")]
-#[cfg(test)]
+#[cfg(all(feature = "_proptest", test))]
 mod proptest {
   use crate::misc::FilledBuffer;
 
diff --git a/wtx/src/misc/filled_buffer_writer.rs b/wtx/src/misc/filled_buffer_writer.rs
index 678831f6..ee6debf8 100644
--- a/wtx/src/misc/filled_buffer_writer.rs
+++ b/wtx/src/misc/filled_buffer_writer.rs
@@ -1,4 +1,4 @@
-use crate::misc::{BufferParam, FilledBuffer, Lease, LeaseMut, VectorError};
+use crate::misc::{BufferMode, FilledBuffer, Lease, LeaseMut, VectorError};
 
 /// Helper that manages the copy of initialized bytes.
 #[derive(Debug)]
@@ -85,7 +85,7 @@ impl<'vec> FilledBufferWriter<'vec> {
   #[inline]
   pub(crate) fn _shift_idx(&mut self, n: usize) -> Result<(), VectorError> {
     let new_len = self._curr_idx.wrapping_add(n);
-    self._vec._expand(BufferParam::Len(new_len))?;
+    self._vec._expand(BufferMode::Len(new_len))?;
     self._curr_idx = new_len;
     Ok(())
   }
diff --git a/wtx/src/misc/fn_fut.rs b/wtx/src/misc/fn_fut.rs
index ef9e1ad5..4fe4ee35 100644
--- a/wtx/src/misc/fn_fut.rs
+++ b/wtx/src/misc/fn_fut.rs
@@ -1,3 +1,5 @@
+// FIXME(STABLE): async closures
+
 #![allow(non_snake_case, reason = "macro stuff")]
 
 macro_rules! create_and_implement {
@@ -64,6 +66,7 @@ create_and_implement!(&Self, Fn, FnFut, (A,));
 create_and_implement!(&Self, Fn, FnFut, (A, B,));
 create_and_implement!(&Self, Fn, FnFut, (A, B, C,));
 create_and_implement!(&Self, Fn, FnFut, (A, B, C, D,));
+create_and_implement!(&Self, Fn, FnFut, (A, B, C, D, E,));
 
 /// Simulates `impl for<'any> FnMut(&'any ..) -> impl Future + 'any` due to the lack of compiler
 /// support.
@@ -92,31 +95,4 @@ create_and_implement!(&mut Self, FnMut, FnMutFut, (A,));
 create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B,));
 create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B, C,));
 create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B, C, D,));
-
-/// Simulates `impl for<'any> FnOnce(&'any ..) -> impl Future + 'any` due to the lack of compiler
-/// support.
-///
-/// If applied as a function parameter, then callers must create their own async functions
-/// instead of using closures.
-///
-/// Credits to `Daniel Henry-Mantilla`.
-pub trait FnOnceFut<A> {
-  /// Returning future.
-  type Future: Future<Output = Self::Result>;
-  /// Function result.
-  type Result;
-  /// A wrapper that can be used to work around coherence rules.
-  type Wrapper;
-
-  /// Calls inner function that returns [`Self::Future`].
-  fn call(self, args: A) -> Self::Future;
-
-  /// Wraps itself with [`Self::Wrapper`].
-  fn into_wrapper(self) -> Self::Wrapper;
-}
-
-create_and_implement!(Self, FnOnce, FnOnceFut, ());
-create_and_implement!(Self, FnOnce, FnOnceFut, (A,));
-create_and_implement!(Self, FnOnce, FnOnceFut, (A, B,));
-create_and_implement!(Self, FnOnce, FnOnceFut, (A, B, C,));
-create_and_implement!(Self, FnOnce, FnOnceFut, (A, B, C, D,));
+create_and_implement!(&mut Self, FnMut, FnMutFut, (A, B, C, D, E,));
diff --git a/wtx/src/misc/mem_transfer.rs b/wtx/src/misc/mem_transfer.rs
index 14d6f4e2..2200daff 100644
--- a/wtx/src/misc/mem_transfer.rs
+++ b/wtx/src/misc/mem_transfer.rs
@@ -33,7 +33,7 @@ where
     return &mut [];
   }
   for Range { start, end } in iter {
-    let Some((diff, local_new_len)) = end.checked_sub(start).and_then(|diff| {
+    let Some((diff @ 1..usize::MAX, local_new_len)) = end.checked_sub(start).and_then(|diff| {
       let local_new_len = new_len.checked_add(diff)?;
       if local_new_len > slice.len() {
         return None;
@@ -58,8 +58,7 @@ where
   unsafe { slice.get_unchecked_mut(..new_len) }
 }
 
-#[cfg(feature = "_proptest")]
-#[cfg(test)]
+#[cfg(all(feature = "_proptest", test))]
 mod proptest {
   use crate::misc::{Vector, _shift_copyable_chunks};
   use core::ops::Range;
diff --git a/wtx/src/misc/noop_waker.rs b/wtx/src/misc/noop_waker.rs
index 74872ac6..d20e88d9 100644
--- a/wtx/src/misc/noop_waker.rs
+++ b/wtx/src/misc/noop_waker.rs
@@ -5,8 +5,9 @@ use core::{
 
 const VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
 
-// FIXME(STABLE): noop_waker
 /// A waker that does nothing.
+//
+// FIXME(STABLE): noop_waker
 pub static NOOP_WAKER: Waker = {
   let raw = RawWaker::new(ptr::null(), &VTABLE);
   // SAFETY: Contract is upheld
diff --git a/wtx/src/misc/partitioned_filled_buffer.rs b/wtx/src/misc/partitioned_filled_buffer.rs
index cdca2a41..72a44a8c 100644
--- a/wtx/src/misc/partitioned_filled_buffer.rs
+++ b/wtx/src/misc/partitioned_filled_buffer.rs
@@ -2,15 +2,23 @@ use crate::misc::{FilledBuffer, FilledBufferWriter, VectorError};
 use core::ops::Range;
 
 // ```
-// [ Antecedent | Current | Following | Trailing ]
-//              |         |           |          |
-//              |         |           |          |--> _antecedent_end_idx
-//              |         |           |
-//              |         |           |-------------> _current_end_idx
-//              |         |
-//              |         |-------------------------> _buffer.len()
-//              |
-//              |-----------------------------------> _buffer.capacity()
+// [=========================All=========================]
+//
+// [=================Buffer=================|            ]
+//
+// [              |=============Current rest=============]
+//
+// [                          |======Following rest======]
+//
+// [==Antecedent==|==Current==|==Following==|==Trailing==]
+//                |           |             |            |
+//                |           |             |            |--> _buffer.capacity()
+//                |           |             |
+//                |           |             |---------------> _buffer.len()
+//                |           |
+//                |           |-----------------------------> _current_end_idx
+//                |
+//                |-----------------------------------------> _antecedent_end_idx
 // ```
 #[derive(Debug)]
 pub(crate) struct PartitionedFilledBuffer {
@@ -87,16 +95,11 @@ impl PartitionedFilledBuffer {
   }
 
   #[inline]
-  pub(crate) fn _current_trail_mut(&mut self) -> &mut [u8] {
+  pub(crate) fn _current_rest_mut(&mut self) -> &mut [u8] {
     let idx = self._antecedent_end_idx();
     self._buffer._all_mut().get_mut(idx..).unwrap_or_default()
   }
 
-  #[inline]
-  pub(crate) fn _expand_buffer(&mut self, additional: usize) -> Result<(), VectorError> {
-    self._buffer._reserve(additional)
-  }
-
   #[inline]
   pub(crate) fn _following(&self) -> &[u8] {
     let idx = self._current_end_idx();
@@ -105,7 +108,7 @@ impl PartitionedFilledBuffer {
 
   #[inline]
   pub(crate) fn _following_end_idx(&self) -> usize {
-    self._buffer._len()
+    self._buffer.len()
   }
 
   #[inline]
@@ -120,7 +123,7 @@ impl PartitionedFilledBuffer {
   }
 
   #[inline]
-  pub(crate) fn _following_trail_mut(&mut self) -> &mut [u8] {
+  pub(crate) fn _following_rest_mut(&mut self) -> &mut [u8] {
     let idx = self._current_end_idx();
     self._buffer._all_mut().get_mut(idx..).unwrap_or_default()
   }
@@ -130,6 +133,18 @@ impl PartitionedFilledBuffer {
     self._following_end_idx() > self._current_end_idx()
   }
 
+  #[inline]
+  pub(crate) fn _reserve(&mut self, additional: usize) -> Result<(), VectorError> {
+    self._buffer._reserve(additional)
+  }
+
+  #[inline]
+  pub(crate) fn _set_current(&mut self, bytes: &[u8]) -> crate::Result<()> {
+    self._buffer._extend_from_slice(bytes)?;
+    self._set_indices(0, bytes.len(), 0)?;
+    Ok(())
+  }
+
   #[inline]
   pub(crate) fn _set_indices(
     &mut self,
diff --git a/wtx/src/misc/queue.rs b/wtx/src/misc/queue.rs
index 8b3ebcc4..d793a5f0 100644
--- a/wtx/src/misc/queue.rs
+++ b/wtx/src/misc/queue.rs
@@ -1,37 +1,44 @@
 macro_rules! as_slices {
   ($empty:expr, $ptr:ident, $slice:ident, $this:expr, $($ref:tt)*) => {{
+    let capacity = $this.data.capacity();
+    let head = $this.head;
     let len = $this.data.len();
-    // SAFETY: `this.head` will never be greater than capacity
-    let rhs_len = unsafe { $this.data.capacity().unchecked_sub($this.head) };
     let ptr = $this.data.$ptr();
+    let tail = $this.tail;
     // SAFETY: inner data is expected to point to valid memory
-    let added_ptr = unsafe { ptr.add($this.head) };
-    if rhs_len < len {
+    let head_ptr = unsafe { ptr.add(head) };
+    if is_wrapping(head, len, tail) {
+      let front_len = capacity.wrapping_sub(head);
       // SAFETY: `ìf` check ensures bounds
-      let lhs = unsafe { $($ref)* *ptr::$slice(ptr, len.wrapping_sub(rhs_len)) };
+      let front = unsafe { $($ref)* *ptr::$slice(head_ptr, front_len) };
       // SAFETY: `ìf` check ensures bounds
-      let rhs = unsafe { $($ref)* *ptr::$slice(added_ptr, rhs_len) };
-      (lhs, rhs)
+      let back = unsafe { $($ref)* *ptr::$slice(ptr, tail) };
+      (front, back)
     } else {
-      // SAFETY: `ìf` check ensures bounds
-      let lhs = unsafe { $($ref)* *ptr::$slice(added_ptr, len) };
-      (lhs, $empty)
+      // SAFETY: inner data is expected to point to valid memory
+      let front = unsafe { $($ref)* *ptr::$slice(head_ptr, len) };
+      (front, $empty)
     }
   }}
 }
 
-use crate::misc::{
-  queue_utils::{reserve, wrap_add, wrap_sub},
-  Vector,
-};
+#[cfg(all(feature = "_proptest", test))]
+mod proptest;
+#[cfg(test)]
+mod tests;
+
+use crate::misc::Vector;
 use core::{
   fmt::{Debug, Formatter},
-  ptr,
+  mem::needs_drop,
+  ptr, slice,
 };
 
 /// Errors of [Queue].
 #[derive(Debug)]
 pub enum QueueError {
+  #[doc = doc_single_elem_cap_overflow!()]
+  ExtendFromSliceOverflow,
   #[doc = doc_single_elem_cap_overflow!()]
   PushFrontOverflow,
   #[doc = doc_reserve_overflow!()]
@@ -41,16 +48,19 @@ pub enum QueueError {
 }
 
 /// A circular buffer.
-pub struct Queue<D> {
-  data: Vector<D>,
+pub struct Queue<T> {
+  data: Vector<T>,
   head: usize,
+  tail: usize,
 }
 
-impl<D> Queue<D> {
+impl<T> Queue<T> {
+  const NEEDS_DROP: bool = needs_drop::<T>();
+
   /// Creates a new empty instance.
   #[inline]
   pub const fn new() -> Self {
-    Self { data: Vector::new(), head: 0 }
+    Self { data: Vector::new(), head: 0, tail: 0 }
   }
 
   /// Constructs a new, empty instance with at least the specified capacity.
@@ -59,23 +69,63 @@ impl<D> Queue<D> {
     Ok(Self {
       data: Vector::with_capacity(cap).map_err(|_err| QueueError::WithCapacityOverflow)?,
       head: 0,
+      tail: 0,
+    })
+  }
+
+  /// Constructs a new, empty instance with at least the specified capacity.
+  #[inline]
+  pub fn with_exact_capacity(cap: usize) -> Result<Self, QueueError> {
+    Ok(Self {
+      data: Vector::with_capacity(cap).map_err(|_err| QueueError::WithCapacityOverflow)?,
+      head: 0,
+      tail: 0,
     })
   }
 
+  /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
+  /// valid for zero sized reads if the vector didn't allocate.
+  #[inline]
+  pub fn as_ptr(&self) -> *const T {
+    self.data.as_ptr()
+  }
+
+  /// Returns an unsafe mutable pointer to the queue's buffer, or a dangling
+  /// raw pointer valid for zero sized reads if the vector didn't allocate.
+  #[inline]
+  pub fn as_ptr_mut(&mut self) -> *mut T {
+    self.data.as_mut_ptr()
+  }
+
   /// Returns a pair of slices which contain, in order, the contents of the queue.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::with_capacity(8).unwrap();
+  /// queue.push_front(3).unwrap();
+  /// queue.push_back(1).unwrap();
+  /// queue.push_back(2).unwrap();
+  /// assert_eq!(queue.as_slices(), (&[3][..], &[1, 2][..]));
+  /// ```
   #[inline]
-  pub fn as_slices(&self) -> (&[D], &[D]) {
+  pub fn as_slices(&self) -> (&[T], &[T]) {
     as_slices!(&[][..], as_ptr, slice_from_raw_parts, self, &)
   }
 
   /// Mutable version of [`Self::as_slices`].
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_front(3);
+  /// queue.push_back(1);
+  /// queue.push_back(2);
+  /// assert_eq!(queue.as_slices_mut(), (&mut [3][..], &mut [1, 2][..]));
+  /// ```
   #[inline]
-  pub fn as_slices_mut(&mut self) -> (&mut [D], &mut [D]) {
-    as_slices!(&mut [][..], as_mut_ptr, slice_from_raw_parts_mut, self, &mut)
+  pub fn as_slices_mut(&mut self) -> (&mut [T], &mut [T]) {
+    as_slices!(&mut [][..], as_ptr_mut, slice_from_raw_parts_mut, self, &mut)
   }
 
   /// Returns the number of elements the queue can hold without reallocating.
-  #[cfg(test)]
   #[inline]
   pub fn capacity(&self) -> usize {
     self.data.capacity()
@@ -84,13 +134,22 @@ impl<D> Queue<D> {
   /// Clears the queue, removing all values.
   #[inline]
   pub fn clear(&mut self) {
-    self.head = 0;
-    self.data.clear();
+    let Self { data, head, tail } = self;
+    data.clear();
+    *head = 0;
+    *tail = 0;
   }
 
   /// Provides a reference to the element at the given index.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_back(1);
+  /// queue.push_back(3);
+  /// assert_eq!(queue.get(0), Some(&1));
+  /// ```
   #[inline]
-  pub fn get(&self, mut idx: usize) -> Option<&D> {
+  pub fn get(&self, mut idx: usize) -> Option<&T> {
     if idx >= self.data.len() {
       return None;
     }
@@ -102,35 +161,62 @@ impl<D> Queue<D> {
   }
 
   /// Mutable version of [`Self::get`].
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_back(1);
+  /// queue.push_back(3);
+  /// assert_eq!(queue.get_mut(0), Some(&mut 1));
+  /// ```
   #[inline]
-  pub fn get_mut(&mut self, mut idx: usize) -> Option<&mut D> {
+  pub fn get_mut(&mut self, mut idx: usize) -> Option<&mut T> {
     if idx >= self.data.len() {
       return None;
     }
     idx = wrap_add(self.data.capacity(), self.head, idx);
     // SAFETY: `idx` points to valid memory
-    let rslt = unsafe { self.data.as_mut_ptr().add(idx) };
+    let rslt = unsafe { self.data.as_ptr_mut().add(idx) };
     // SAFETY: `idx` points to valid memory
     unsafe { Some(&mut *rslt) }
   }
 
   /// Returns a front-to-back iterator.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_back(1);
+  /// queue.push_front(3);
+  /// let mut iter = queue.iter();
+  /// assert_eq!(iter.next(), Some(&3));
+  /// assert_eq!(iter.next(), Some(&1));
+  /// assert_eq!(iter.next(), None);
+  /// ```
   #[inline]
-  pub fn iter(&self) -> impl Iterator<Item = &D> {
-    let (lhs, rhs) = self.as_slices();
-    rhs.iter().chain(lhs)
+  pub fn iter(&self) -> impl Iterator<Item = &T> {
+    let (front, back) = self.as_slices();
+    front.iter().chain(back)
   }
 
   /// Mutable version of [`Self::iter`].
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_back(1);
+  /// queue.push_front(3);
+  /// let mut iter = queue.iter_mut();
+  /// assert_eq!(iter.next(), Some(&mut 3));
+  /// assert_eq!(iter.next(), Some(&mut 1));
+  /// assert_eq!(iter.next(), None);
+  /// ```
   #[inline]
-  pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut D> {
-    let (lhs, rhs) = self.as_slices_mut();
-    rhs.iter_mut().chain(lhs)
+  pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
+    let (front, back) = self.as_slices_mut();
+    front.iter_mut().chain(back)
   }
 
   /// Returns the last element.
   #[inline]
-  pub fn last(&self) -> Option<&D> {
+  pub fn last(&self) -> Option<&T> {
     self.get(self.len().checked_sub(1)?)
   }
 
@@ -141,222 +227,463 @@ impl<D> Queue<D> {
   }
 
   /// Removes the last element from the queue and returns it, or `None` if it is empty.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_back(1);
+  /// queue.push_back(3);
+  /// queue.pop_back();
+  /// assert_eq!(queue.as_slices(), (&[1][..], &[][..]));
+  /// ```
   #[inline]
-  pub fn pop_back(&mut self) -> Option<D> {
+  pub fn pop_back(&mut self) -> Option<T> {
     let new_len = self.data.len().checked_sub(1)?;
+    let curr_tail = wrap_sub(self.data.capacity(), self.tail, 1);
+    self.tail = curr_tail;
     // SAFETY: is within bounds
     unsafe {
       self.data.set_len(new_len);
     }
-    let idx = wrap_add(self.data.capacity(), self.head, new_len);
     // SAFETY: `idx` points to valid memory
-    let src = unsafe { self.data.as_mut_ptr().add(idx) };
+    let src = unsafe { self.data.as_ptr_mut().add(curr_tail) };
     // SAFETY: `src` points to valid memory
-    unsafe { Some(ptr::read(src)) }
+    Some(unsafe { ptr::read(src) })
   }
 
   /// Removes the first element and returns it, or [`Option::None`] if the queue is empty.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_back(1);
+  /// queue.push_back(3);
+  /// queue.pop_front();
+  /// assert_eq!(queue.as_slices(), (&[3][..], &[][..]));
+  /// ```
   #[inline]
-  pub fn pop_front(&mut self) -> Option<D> {
+  pub fn pop_front(&mut self) -> Option<T> {
     let new_len = self.data.len().checked_sub(1)?;
     let prev_head = self.head;
-    self.head = wrap_add(self.data.capacity(), self.head, 1);
+    self.head = wrap_add(self.data.capacity(), prev_head, 1);
+    // SAFETY: is within bounds
+    unsafe {
+      self.data.set_len(new_len);
+    }
     // SAFETY: `prev_head` points to valid memory
-    let src = unsafe { self.data.as_mut_ptr().add(prev_head) };
+    let src = unsafe { self.data.as_ptr_mut().add(prev_head) };
     // SAFETY: `src` points to valid memory
-    let rslt = unsafe { ptr::read(src) };
+    Some(unsafe { ptr::read(src) })
+  }
+
+  /// Appends an element to the back of the queue.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_back(1);
+  /// queue.push_back(3);
+  /// assert_eq!(queue.as_slices(), (&[1, 3][..], &[][..]));
+  /// ```
+  #[inline]
+  pub fn push_back(&mut self, value: T) -> Result<(), QueueError> {
+    let _ = self.reserve_back(1).map_err(|_err| QueueError::PushFrontOverflow)?;
+    let len = self.data.len();
+    let tail = self.tail;
+    self.tail = wrap_add(self.data.capacity(), tail, 1);
+    // SAFETY: `idx` is within bounds
+    let dst = unsafe { self.data.as_ptr_mut().add(tail) };
+    // SAFETY: `dst` points to valid memory
+    unsafe {
+      ptr::write(dst, value);
+    }
     // SAFETY: is within bounds
     unsafe {
-      self.data.set_len(new_len);
+      self.data.set_len(len.wrapping_add(1));
     }
-    Some(rslt)
+    Ok(())
   }
-}
 
-impl<D> Queue<D>
-where
-  D: Copy,
-{
   /// Prepends an element to the queue.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_front(1);
+  /// queue.push_front(3);
+  /// assert_eq!(queue.as_slices(), (&[3, 1][..], &[][..]));
+  /// ```
   #[inline]
-  pub fn push_front(&mut self, value: D) -> Result<(), QueueError> {
-    self.reserve(1).map_err(|_err| QueueError::PushFrontOverflow)?;
+  pub fn push_front(&mut self, value: T) -> Result<(), QueueError> {
+    let _ = self.reserve_front(1).map_err(|_err| QueueError::PushFrontOverflow)?;
     let len = self.data.len();
     self.head = wrap_sub(self.data.capacity(), self.head, 1);
     // SAFETY: `self.head` points to valid memory
-    let dst = unsafe { self.data.as_mut_ptr().add(self.head) };
+    let dst = unsafe { self.data.as_ptr_mut().add(self.head) };
     // SAFETY: `dst` points to valid memory
     unsafe {
       ptr::write(dst, value);
     }
-    // SAFETY: top-level check ensures capacity
-    let new_len = unsafe { len.unchecked_add(1) };
     // SAFETY: is within bounds
     unsafe {
-      self.data.set_len(new_len);
+      self.data.set_len(len.wrapping_add(1));
     }
     Ok(())
   }
 
-  /// Reserves capacity for at least additional more elements to be inserted in the given queue.
+  /// Reserves capacity for at least additional more elements to be inserted at the back of the
+  /// queue.
   #[inline(always)]
-  pub fn reserve(&mut self, additional: usize) -> Result<(), QueueError> {
-    reserve(additional, &mut self.data, &mut self.head)
-      .map(|_el| ())
-      .map_err(|_err| QueueError::ReserveOverflow)
+  pub fn reserve_back(&mut self, additional: usize) -> Result<usize, QueueError> {
+    let tuple = reserve::<_, true>(additional, &mut self.data, &mut self.head, &mut self.tail)?;
+    Ok(tuple.2)
+  }
+
+  /// Reserves capacity for at least additional more elements to be inserted at the front of the
+  /// queue.
+  #[inline(always)]
+  pub fn reserve_front(&mut self, additional: usize) -> Result<usize, QueueError> {
+    let tuple = reserve::<_, false>(additional, &mut self.data, &mut self.head, &mut self.tail)?;
+    Ok(tuple.2)
+  }
+
+  /// Shortens the queue, keeping the first `new_len` elements.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_front(1);
+  /// queue.push_front(3);
+  /// queue.push_back(5);
+  /// queue.push_back(7);
+  /// queue.truncate_back(2);
+  /// assert_eq!(queue.as_slices(), (&[3, 1][..], &[][..]));
+  /// queue.truncate_back(0);
+  /// assert_eq!(queue.as_slices(), (&[][..], &[][..]));
+  /// ```
+  #[inline]
+  pub fn truncate_back(&mut self, new_len: usize) {
+    let len = self.data.len();
+    let Some(diff @ 1..=usize::MAX) = len.checked_sub(new_len) else {
+      return;
+    };
+    if is_wrapping(self.head, len, self.tail) {
+      if let Some(back_begin) = self.tail.checked_sub(diff) {
+        if Self::NEEDS_DROP {
+          // SAFETY: Indices are within bounds
+          unsafe {
+            drop_elements(diff, back_begin, self.data.as_ptr_mut());
+          }
+        }
+        self.tail = if self.tail == diff { self.data.capacity() } else { back_begin }
+      } else {
+        let front_len = diff.wrapping_sub(self.tail);
+        let front_begin = self.data.capacity().wrapping_sub(front_len);
+        if Self::NEEDS_DROP {
+          // SAFETY: Indices are within bounds
+          unsafe {
+            drop_elements(self.tail, 0, self.data.as_ptr_mut());
+          }
+          // SAFETY: Indices are within bounds
+          unsafe {
+            drop_elements(front_len, front_begin, self.data.as_ptr_mut());
+          }
+        }
+        self.tail = front_begin;
+      }
+    } else {
+      let curr_tail = self.tail.wrapping_sub(diff);
+      if Self::NEEDS_DROP {
+        // SAFETY: Indices are within bounds
+        unsafe {
+          drop_elements(diff, curr_tail, self.data.as_ptr_mut());
+        }
+      }
+      self.tail = curr_tail;
+    }
+    // SAFETY: is within bounds
+    unsafe {
+      self.data.set_len(new_len);
+    }
+  }
+
+  /// Shortens the queue, keeping the last `new_len` elements.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_front(1);
+  /// queue.push_front(3);
+  /// queue.push_back(5);
+  /// queue.push_back(7);
+  /// queue.truncate_front(2);
+  /// assert_eq!(queue.as_slices(), (&[5, 7][..], &[][..]));
+  /// queue.truncate_front(0);
+  /// assert_eq!(queue.as_slices(), (&[][..], &[][..]));
+  /// ```
+  #[inline]
+  pub fn truncate_front(&mut self, new_len: usize) {
+    let len = self.data.len();
+    let Some(diff @ 1..=usize::MAX) = len.checked_sub(new_len) else {
+      return;
+    };
+    if is_wrapping(self.head, len, self.tail) {
+      let front_slots = self.data.capacity().wrapping_sub(self.head);
+      if front_slots >= diff {
+        if Self::NEEDS_DROP {
+          // SAFETY: Indices are within bounds
+          unsafe {
+            drop_elements(diff, self.head, self.data.as_ptr_mut());
+          }
+        }
+        self.head = if front_slots == diff { 0 } else { self.head.wrapping_add(diff) }
+      } else {
+        let back_len = diff.wrapping_sub(front_slots);
+        if Self::NEEDS_DROP {
+          // SAFETY: Indices are within bounds
+          unsafe {
+            drop_elements(front_slots, self.head, self.data.as_ptr_mut());
+          }
+          // SAFETY: Indices are within bounds
+          unsafe {
+            drop_elements(back_len, 0, self.data.as_ptr_mut());
+          }
+        }
+        self.head = back_len;
+      }
+    } else {
+      let prev_head = self.head;
+      if Self::NEEDS_DROP {
+        // SAFETY: Indices are within bounds
+        unsafe {
+          drop_elements(diff, prev_head, self.data.as_ptr_mut());
+        }
+      }
+      self.head = prev_head.wrapping_add(diff);
+    }
+    // SAFETY: is within bounds
+    unsafe {
+      self.data.set_len(new_len);
+    }
   }
 }
 
-impl<D> Debug for Queue<D>
+impl<T> Queue<T>
 where
-  D: Debug,
+  T: Copy,
+{
+  /// Iterates over the `others` slices, copies each element, and then prepends
+  /// it to this vector. The `others` slices are traversed in-order.
+  ///
+  /// ```rust
+  /// let mut queue = wtx::misc::Queue::new();
+  /// queue.push_front(4);
+  /// queue.extend_front_from_copyable_slices([&[2, 3][..]]);
+  /// queue.extend_front_from_copyable_slices([&[0, 1][..], &[1][..]]);
+  /// assert_eq!(queue.as_slices(), (&[0, 1, 1, 2, 3, 4][..], &[][..]));
+  /// ```
+  #[inline]
+  pub fn extend_front_from_copyable_slices<'iter, I>(
+    &mut self,
+    others: I,
+  ) -> Result<(usize, usize), QueueError>
+  where
+    I: IntoIterator<Item = &'iter [T]>,
+    I::IntoIter: Clone,
+    T: 'iter,
+  {
+    let mut others_len: usize = 0;
+    let iter = others.into_iter();
+    for other in iter.clone() {
+      let Some(curr_len) = others_len.checked_add(other.len()) else {
+        return Err(QueueError::ExtendFromSliceOverflow);
+      };
+      others_len = curr_len;
+    }
+    let tuple = reserve::<_, false>(others_len, &mut self.data, &mut self.head, &mut self.tail)?;
+    let mut head = tuple.0;
+    self.head = head;
+    for other in iter {
+      // SAFETY: `self.head` points to valid memory
+      let dst = unsafe { self.data.as_ptr_mut().add(head) };
+      // SAFETY: `dst` points to valid memory
+      unsafe {
+        ptr::copy_nonoverlapping(other.as_ptr(), dst, other.len());
+      }
+      head = head.wrapping_add(other.len());
+    }
+    // SAFETY: is within bounds
+    unsafe {
+      self.data.set_len(self.data.len().wrapping_add(others_len));
+    }
+    Ok((others_len, tuple.2))
+  }
+
+  pub(crate) fn head(&self) -> usize {
+    self.head
+  }
+}
+
+impl<T> Debug for Queue<T>
+where
+  T: Debug,
 {
   #[inline]
   fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
-    let (lhs, rhs) = self.as_slices();
-    f.debug_struct("Queue").field("lhs", &lhs).field("rhs", &rhs).finish()
+    let (front, back) = self.as_slices();
+    f.debug_struct("Queue").field("front", &front).field("back", &back).finish()
   }
 }
 
-impl<D> Default for Queue<D> {
+impl<T> Default for Queue<T> {
   #[inline]
   fn default() -> Self {
     Self::new()
   }
 }
 
-#[cfg(feature = "_proptest")]
-#[cfg(test)]
-mod _proptest {
-  use crate::misc::Queue;
-  use alloc::{collections::VecDeque, vec::Vec};
-
-  #[test_strategy::proptest]
-  fn queue(bytes: Vec<u8>) {
-    let mut queue = Queue::with_capacity(bytes.len()).unwrap();
-    let mut vec_deque = VecDeque::with_capacity(bytes.len());
-
-    for byte in bytes.iter().copied() {
-      queue.push_front(byte).unwrap();
-      vec_deque.push_front(byte);
+#[inline]
+unsafe fn drop_elements<T>(len: usize, offset: usize, ptr: *mut T) {
+  // SAFETY: It is up to the caller to provide a valid pointer with a valid index
+  let data = unsafe { ptr.add(offset) };
+  // SAFETY: It is up to the caller to provide a valid length
+  let elements = unsafe { slice::from_raw_parts_mut(data, len) };
+  // SAFETY: It is up to the caller to provide parameters that can lead to droppable elements
+  unsafe {
+    ptr::drop_in_place(elements);
+  }
+}
+
+/// All wrapping structures should have at least 1 element.
+///
+/// ```txt
+/// H = Head (inclusive)
+/// T = Tail (exclusive)
+///
+/// H(7) > T(0): . . . . . . . H (wrapping)
+/// H(7) > T(1): T . . . . . . H (wrapping)
+/// H(6) > T(4): * * * T . . H * (wrapping)
+///
+/// H(0) = T(0): . . . . . . . . (no wrapping)
+/// H(1) = T(1): . . . . . . . . (no wrapping)
+/// H(0) = T(0): H * * * * * * T (wrapping)
+/// H(2) = T(2): * T H * * * * * (wrapping)
+/// H(7) = T(7): * * * * * * T H (wrapping)
+///
+/// H(0) < T(1): H . . . . . . . (no wrapping)
+/// H(7) < T(8): . . . . . . . H (no wrapping)
+/// H(0) < T(2): H T . . . . . . (no wrapping)
+/// H(3) < T(6): . . . H * T . . (no wrapping)
+/// H(0) < T(8): H * * * * * * T (no wrapping)
+/// ```
+#[inline]
+fn is_wrapping(head: usize, len: usize, tail: usize) -> bool {
+  if tail > head {
+    false
+  } else {
+    len > 0
+  }
+}
+
+/// Returns the starting and ending index where the `additional` number of elements
+/// can be inserted.
+#[inline(always)]
+fn reserve<D, const IS_BACK: bool>(
+  additional: usize,
+  data: &mut Vector<D>,
+  head: &mut usize,
+  tail: &mut usize,
+) -> Result<(usize, usize, usize), QueueError> {
+  let len = data.len();
+  let prev_cap = data.capacity();
+  data.reserve(additional).map_err(|_err| QueueError::ReserveOverflow)?;
+  let curr_cap = data.capacity();
+  let prev_head = prev_cap.min(*head);
+  let prev_tail = prev_cap.min(*tail);
+  if len == 0 {
+    return Ok(if IS_BACK {
+      (0, additional, 0)
+    } else {
+      (curr_cap.wrapping_sub(additional), curr_cap, 0)
+    });
+  }
+  if is_wrapping(prev_head, len, prev_tail) {
+    let free_slots = prev_head.wrapping_sub(prev_tail);
+    if free_slots >= additional {
+      return Ok(if IS_BACK {
+        (prev_tail, prev_tail.wrapping_add(additional), 0)
+      } else {
+        (prev_head.wrapping_sub(additional), prev_head, 0)
+      });
     }
-    assert_eq!((queue.capacity(), queue.len()), (vec_deque.capacity(), vec_deque.len()));
-    for _ in 0..(bytes.len() / 2) {
-      assert_eq!(queue.as_slices(), vec_deque.as_slices());
-      assert_eq!(queue.get(0), vec_deque.get(0));
-      assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
-      assert_eq!(queue.pop_back(), vec_deque.pop_back());
-      assert_eq!(queue.as_slices(), vec_deque.as_slices());
-      assert_eq!(queue.get(0), vec_deque.get(0));
-      assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
-      assert_eq!(queue.pop_front(), vec_deque.pop_front());
+    let front_len = prev_cap.wrapping_sub(prev_head);
+    let curr_head = curr_cap.wrapping_sub(front_len);
+    // SAFETY: `prev_head` is equal or less than the current capacity
+    let src = unsafe { data.as_ptr_mut().add(prev_head) };
+    // SAFETY: `curr_head` is equal or less than the current capacity
+    let dst = unsafe { data.as_ptr_mut().add(curr_head) };
+    // SAFETY: memory has been allocated
+    unsafe {
+      ptr::copy(src, dst, front_len);
     }
-    queue.reserve(queue.capacity() + 10).unwrap();
-    vec_deque.reserve(vec_deque.capacity() + 10);
-    loop {
-      if queue.len() == 0 {
-        break;
+    *head = curr_head;
+    if IS_BACK {
+      Ok((prev_tail, prev_tail.wrapping_add(additional), 0))
+    } else {
+      Ok((curr_head.wrapping_sub(additional), curr_head, curr_cap.wrapping_sub(prev_cap)))
+    }
+  } else {
+    let left_free = prev_head;
+    let right_free = curr_cap.wrapping_sub(prev_tail);
+    if IS_BACK {
+      if right_free >= additional {
+        return Ok((prev_tail, prev_tail.wrapping_add(additional), 0));
+      }
+      if right_free == 0 && left_free >= additional {
+        return Ok((0, additional, 0));
+      }
+      // SAFETY: `prev_head` is equal or less than the current capacity
+      let src = unsafe { data.as_ptr_mut().add(prev_head) };
+      // SAFETY: memory has been allocated
+      unsafe {
+        ptr::copy(src, data.as_ptr_mut(), len);
+      }
+      let curr_tail = len;
+      *head = 0;
+      *tail = curr_tail;
+      Ok((curr_tail, curr_tail.wrapping_add(additional), 0))
+    } else {
+      if left_free >= additional {
+        return Ok((prev_head.wrapping_sub(additional), prev_head, 0));
+      }
+      if left_free == 0 && right_free >= additional {
+        return Ok((curr_cap.wrapping_sub(additional), curr_cap, 0));
       }
-      assert_eq!(queue.as_slices(), vec_deque.as_slices());
-      assert_eq!(queue.get(0), vec_deque.get(0));
-      assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
-      assert_eq!(queue.pop_back(), vec_deque.pop_back());
-      if queue.len() == 0 {
-        break;
+      let curr_head = curr_cap.wrapping_sub(len);
+      // SAFETY: `prev_head` is equal or less than the current capacity
+      let src = unsafe { data.as_ptr_mut().add(prev_head) };
+      // SAFETY: `curr_head` is equal or less than the current capacity
+      let dst = unsafe { data.as_ptr_mut().add(curr_head) };
+      // SAFETY: memory has been allocated
+      unsafe {
+        ptr::copy(src, dst, len);
       }
-      assert_eq!(queue.as_slices(), vec_deque.as_slices());
-      assert_eq!(queue.get(0), vec_deque.get(0));
-      assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
-      assert_eq!(queue.pop_front(), vec_deque.pop_front());
+      *head = curr_head;
+      *tail = curr_cap;
+      Ok((curr_head.wrapping_sub(additional), curr_head, right_free))
     }
-    assert_eq!((queue.capacity(), queue.len()), (vec_deque.capacity(), vec_deque.len()));
-    assert_eq!((queue.len(), vec_deque.len()), (0, 0));
   }
 }
 
-#[cfg(test)]
-mod tests {
-  use crate::misc::Queue;
-
-  #[test]
-  fn as_slices() {
-    let mut queue = Queue::with_capacity(4).unwrap();
-    queue.push_front(1).unwrap();
-    queue.push_front(2).unwrap();
-    queue.push_front(3).unwrap();
-    queue.push_front(4).unwrap();
-    let _ = queue.pop_back();
-    let _ = queue.pop_back();
-    queue.push_front(5).unwrap();
-    assert_eq!(queue.as_slices(), (&[4, 3][..], &[5][..]));
-  }
-
-  #[test]
-  fn clear() {
-    let mut queue = Queue::with_capacity(1).unwrap();
-    assert_eq!(queue.len(), 0);
-    queue.push_front(1).unwrap();
-    assert_eq!(queue.len(), 1);
-    queue.clear();
-    assert_eq!(queue.len(), 0);
-  }
-
-  #[test]
-  fn get() {
-    let mut queue = Queue::with_capacity(1).unwrap();
-    assert_eq!(queue.get(0), None);
-    assert_eq!(queue.get_mut(0), None);
-    queue.push_front(1).unwrap();
-    assert_eq!(queue.get(0), Some(&1i32));
-    assert_eq!(queue.get_mut(0), Some(&mut 1i32));
-  }
-
-  #[test]
-  fn pop_back() {
-    let mut queue = Queue::with_capacity(1).unwrap();
-    assert_eq!(queue.pop_back(), None);
-    queue.push_front(1).unwrap();
-    assert_eq!(queue.pop_back(), Some(1));
-    assert_eq!(queue.pop_back(), None);
-  }
-
-  #[test]
-  fn pop_front() {
-    let mut queue = Queue::with_capacity(1).unwrap();
-    assert_eq!(queue.pop_front(), None);
-    queue.push_front(1).unwrap();
-    assert_eq!(queue.pop_front(), Some(1));
-    assert_eq!(queue.pop_front(), None);
-  }
-
-  #[test]
-  fn push_front() {
-    let mut queue = Queue::with_capacity(1).unwrap();
-    assert_eq!(queue.len(), 0);
-    queue.push_front(1).unwrap();
-    assert_eq!(queue.len(), 1);
-  }
-
-  #[test]
-  fn push_when_full() {
-    let mut bq = Queue::with_capacity(5).unwrap();
-    bq.push_front(0).unwrap();
-    bq.push_front(1).unwrap();
-    bq.push_front(2).unwrap();
-    bq.push_front(3).unwrap();
-    bq.push_front(4).unwrap();
-    let _ = bq.pop_back();
-    let _ = bq.pop_back();
-    bq.push_front(5).unwrap();
-    bq.push_front(6).unwrap();
-    assert_eq!(bq.as_slices(), (&[4, 3, 2][..], &[6, 5][..]));
-  }
-
-  #[test]
-  fn reserve() {
-    let mut queue = Queue::<u8>::new();
-    assert_eq!(queue.capacity(), 0);
-    queue.reserve(10).unwrap();
-    assert_eq!(queue.capacity(), 10);
+#[inline]
+fn wrap_add(capacity: usize, idx: usize, value: usize) -> usize {
+  wrap_idx(idx.wrapping_add(value), capacity)
+}
+
+#[inline]
+fn wrap_idx(idx: usize, cap: usize) -> usize {
+  idx.checked_sub(cap).unwrap_or(idx)
+}
+
+#[inline]
+fn wrap_sub(capacity: usize, idx: usize, value: usize) -> usize {
+  #[inline]
+  fn wrap_idx(idx: usize, cap: usize) -> usize {
+    idx.checked_sub(cap).unwrap_or(idx)
   }
+  wrap_idx(idx.wrapping_sub(value).wrapping_add(capacity), capacity)
 }
diff --git a/wtx/src/misc/queue_utils.rs b/wtx/src/misc/queue_utils.rs
deleted file mode 100644
index 81f1f29f..00000000
--- a/wtx/src/misc/queue_utils.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use crate::misc::{Vector, _shift_copyable_chunks};
-use core::{hint::assert_unchecked, iter, ptr};
-
-/// If memory is allocated, tail elements are shifted to the right.
-///
-/// ```ignore
-/// |4|3|2|6|5|
-///       |
-///        Head
-///
-/// |4|3|2|6|5| | | | | | | | | |
-///       |                 |
-///        Previous head     Current head
-///
-/// |4|3|2| | | | | | | | | |6|5|
-///                         |
-///                          Head
-/// ```
-#[inline(always)]
-pub(crate) fn reserve<D>(
-  additional: usize,
-  data: &mut Vector<D>,
-  head: &mut usize,
-) -> Result<Option<usize>, ()>
-where
-  D: Copy,
-{
-  let prev_cap = data.capacity();
-  data.reserve(additional).map_err(|_err| ())?;
-  let prev_head = *head;
-  let rhs_len = prev_cap.wrapping_sub(prev_head);
-  let curr_cap = data.capacity();
-  let cap_diff = curr_cap.wrapping_sub(prev_cap);
-  if data.len() == 0 {
-    return Ok(None);
-  }
-  let curr_head = curr_cap.wrapping_sub(rhs_len);
-  // SAFETY: memory has been allocated
-  let allocated = unsafe { &mut *ptr::slice_from_raw_parts_mut(data.as_mut_ptr(), curr_cap) };
-  // SAFETY: head will never be greater than the number of allocated elements
-  unsafe {
-    assert_unchecked(allocated.len() >= curr_head || prev_cap >= prev_head);
-  }
-  let _ = _shift_copyable_chunks(curr_head, allocated, iter::once(prev_head..prev_cap));
-  *head = curr_head;
-  Ok(Some(cap_diff))
-}
-
-#[inline]
-pub(crate) fn wrap_add(cap: usize, idx: usize, value: usize) -> usize {
-  wrap_idx(idx.wrapping_add(value), cap)
-}
-
-#[inline]
-pub(crate) fn wrap_idx(idx: usize, cap: usize) -> usize {
-  idx.checked_sub(cap).unwrap_or(idx)
-}
-
-#[inline]
-pub(crate) fn wrap_sub(cap: usize, idx: usize, value: usize) -> usize {
-  wrap_idx(idx.wrapping_sub(value).wrapping_add(cap), cap)
-}
diff --git a/wtx/src/misc/rng/seed.rs b/wtx/src/misc/rng/seed.rs
index c3bf8535..7f0ce67c 100644
--- a/wtx/src/misc/rng/seed.rs
+++ b/wtx/src/misc/rng/seed.rs
@@ -9,35 +9,53 @@ use core::{
 /// Uses a combination of weak strategies that will likely result in poor results.
 ///
 /// 1. The address of a heap allocation.
-/// 2. A large fixed number.
-/// 3. The value of an ever increasing static counter.
-/// 4. The line and column of the caller location.
+/// 2. The value of an ever increasing static counter.
+/// 3. The line and column of the caller location.
 #[inline]
 pub fn simple_seed() -> u64 {
   static COUNTER: AtomicU64 = AtomicU64::new(0);
-
-  struct Foo {
-    _bar: usize,
-    _baz: usize,
-  }
-
-  let elem = Box::new(Foo { _bar: 1, _baz: 2 });
+  let heap = Box::new(0u8);
+  let location = Location::caller();
   // FIXME(STABLE): strict_provenance
   // SAFETY: Memory location is not relevant
-  let ptr_addr = unsafe { *ptr::addr_of!(elem).cast() };
-  let mut rslt = Usize::from_usize(ptr_addr).into_u64();
-  rslt = rslt.wrapping_add(11_400_714_819_323_198_485);
-  rslt = rslt.wrapping_add(COUNTER.fetch_add(1, Ordering::Release));
-  let location = Location::caller();
-  rslt = rslt.wrapping_add(u64::from(location.column().wrapping_add(location.line())));
-  rslt
+  let ptr_addr = unsafe { *ptr::addr_of!(heap).cast() };
+  let mut seed = Usize::from_usize(ptr_addr).into_u64();
+  seed = mix(seed, COUNTER.fetch_add(1, Ordering::Release));
+  seed = mix(seed, u64::from(location.column().wrapping_add(location.line())));
+  seed
 }
 
 /// Seed retrieved from the machinery of the standard library.
+///
+/// This method is slower than [`simple_seed`] but will probably deliver better results.
 #[cfg(feature = "std")]
 #[inline]
 pub fn std_seed() -> u64 {
+  use crate::misc::GenericTime;
   use core::hash::{BuildHasher, Hasher};
   use std::hash::RandomState;
-  Hasher::finish(&BuildHasher::build_hasher(&RandomState::new()))
+  let mut seed = Hasher::finish(&BuildHasher::build_hasher(&RandomState::new()));
+  if let Ok(timestamp) = GenericTime::timestamp().map(|el| el.as_nanos()) {
+    let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = timestamp.to_le_bytes();
+    let hi = u64::from_le_bytes([a, b, c, d, e, f, g, h]);
+    let lo = u64::from_le_bytes([i, j, k, l, m, n, o, p]);
+    seed = mix(mix(seed, hi), lo);
+  }
+  seed
+}
+
+// Credits to the `foldhash` project.
+#[inline]
+fn folded_multiplication(x: u64, y: u64) -> u64 {
+  let array = u128::from(x).wrapping_mul(u128::from(y)).to_le_bytes();
+  let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = array;
+  let hi = u64::from_le_bytes([a, b, c, d, e, f, g, h]);
+  let lo = u64::from_le_bytes([i, j, k, l, m, n, o, p]);
+  hi ^ lo
+}
+
+#[inline]
+fn mix(seed: u64, n: u64) -> u64 {
+  const FIXED: u64 = 10_526_836_309_316_205_339;
+  folded_multiplication(seed ^ n, FIXED)
 }
diff --git a/wtx/src/misc/stream/bytes_stream.rs b/wtx/src/misc/stream/bytes_stream.rs
index af8edc5d..611033a1 100644
--- a/wtx/src/misc/stream/bytes_stream.rs
+++ b/wtx/src/misc/stream/bytes_stream.rs
@@ -45,14 +45,14 @@ impl StreamReader for BytesStream {
 impl StreamWriter for BytesStream {
   #[inline]
   async fn write_all(&mut self, bytes: &[u8]) -> crate::Result<()> {
-    self.buffer.extend_from_slice(bytes)?;
+    self.buffer.extend_from_copyable_slice(bytes)?;
     Ok(())
   }
 
   #[inline]
   async fn write_all_vectored(&mut self, bytes: &[&[u8]]) -> crate::Result<()> {
     for elem in bytes {
-      self.buffer.extend_from_slice(elem)?;
+      self.buffer.extend_from_copyable_slice(elem)?;
     }
     Ok(())
   }
diff --git a/wtx/src/misc/sync.rs b/wtx/src/misc/sync.rs
new file mode 100644
index 00000000..3714e411
--- /dev/null
+++ b/wtx/src/misc/sync.rs
@@ -0,0 +1,17 @@
+// All `no_std` structures located in this module were copied from the
+// https://github.com/crossbeam-rs/crossbeam project and modified to fit into `wtx`.
+//
+// As well as many other structures of many other modules, everything here should have been
+// provided by the standard library. Unfortunately, several individuals spread across different
+// levels of authority defend a minimum std with "reference" crates.
+
+mod atomic_cell;
+mod atomic_waker;
+mod back_off;
+mod cache_padded;
+mod seq_lock;
+
+pub use atomic_cell::AtomicCell;
+pub use atomic_waker::AtomicWaker;
+pub use back_off::Backoff;
+pub use cache_padded::CachePadded;
diff --git a/wtx/src/misc/sync/atomic_cell.rs b/wtx/src/misc/sync/atomic_cell.rs
new file mode 100644
index 00000000..60ab7a9d
--- /dev/null
+++ b/wtx/src/misc/sync/atomic_cell.rs
@@ -0,0 +1,156 @@
+#![allow(clippy::as_conversions, reason = "address is only used as an heuristic to retrieve locks")]
+
+use crate::misc::{sync::seq_lock::SeqLock, CachePadded};
+use core::{
+  cell::UnsafeCell,
+  fmt::{Debug, Formatter},
+  mem,
+  panic::{RefUnwindSafe, UnwindSafe},
+  ptr,
+};
+
+const LEN: usize = 67;
+
+static LOCKS: [CachePadded<SeqLock>; LEN] = [const { CachePadded(SeqLock::new()) }; LEN];
+
+/// A type that allows copyable elements to be safely shared between threads.
+pub struct AtomicCell<T> {
+  value: UnsafeCell<T>,
+}
+
+impl<T> AtomicCell<T> {
+  /// Creates a new instance.
+  #[inline]
+  pub const fn new(value: T) -> AtomicCell<T> {
+    AtomicCell { value: UnsafeCell::new(value) }
+  }
+
+  /// Returns inner data.
+  ///
+  /// ```rust
+  /// let ac = wtx::misc::AtomicCell::new(7);
+  /// assert_eq!(ac.into_inner(), 7);
+  /// ```
+  #[inline]
+  pub fn into_inner(self) -> T {
+    self.value.into_inner()
+  }
+
+  /// Loads a value from the atomic cell.
+  ///
+  /// ```rust
+  /// let ac = wtx::misc::AtomicCell::new(7);
+  /// assert_eq!(ac.load(), 7);
+  /// ```
+  #[inline]
+  pub fn load(&self) -> T
+  where
+    T: Copy,
+  {
+    let src = self.as_ptr();
+    // FIXME(STABLE): strict_provenance
+    let lock = lock(src as usize);
+
+    if let Some(stamp) = lock.optimistic_read() {
+      // SAFETY: pointer doesn't have offsets
+      let value = unsafe { ptr::read_volatile(src) };
+      if lock.validate_read(stamp) {
+        return value;
+      }
+    }
+
+    let guard = lock.write();
+    // SAFETY: pointer doesn't have offsets
+    let value = unsafe { ptr::read(src) };
+    guard.abort();
+    value
+  }
+
+  /// Stores `value` into the atomic cell.
+  ///
+  /// ```
+  /// let ac = wtx::misc::AtomicCell::new(7);
+  /// assert_eq!(ac.load(), 7);
+  /// ac.store(8);
+  /// assert_eq!(ac.load(), 8);
+  /// ```
+  #[inline]
+  pub fn store(&self, value: T) {
+    if const { mem::needs_drop::<T>() } {
+      drop(self.swap(value));
+    } else {
+      let dst = self.as_ptr();
+      // FIXME(STABLE): strict_provenance
+      let _guard = lock(dst as usize).write();
+      // SAFETY: pointer doesn't have offsets and `value` has the same size and alignment of `self`
+      unsafe {
+        ptr::write(dst, value);
+      }
+    }
+  }
+
+  /// Stores `value` into the atomic cell and returns the previous value.
+  ///
+  /// ```
+  /// let ac = wtx::misc::AtomicCell::new(7);
+  /// assert_eq!(ac.load(), 7);
+  /// assert_eq!(ac.swap(8), 7);
+  /// assert_eq!(ac.load(), 8);
+  /// ```
+  #[inline]
+  pub fn swap(&self, value: T) -> T {
+    let dst = self.value.get();
+    // FIXME(STABLE): strict_provenance
+    let _guard = lock(dst as usize).write();
+    // SAFETY: pointer doesn't have offsets and `value` has the same size and alignment of `self`
+    unsafe { ptr::replace(dst, value) }
+  }
+
+  #[inline]
+  fn as_ptr(&self) -> *mut T {
+    self.value.get()
+  }
+}
+
+impl<T> Debug for AtomicCell<T>
+where
+  T: Copy + Debug,
+{
+  #[inline]
+  fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+    f.debug_struct("AtomicCell").field("value", &self.load()).finish()
+  }
+}
+
+impl<T> Default for AtomicCell<T>
+where
+  T: Default,
+{
+  #[inline]
+  fn default() -> AtomicCell<T> {
+    AtomicCell::new(T::default())
+  }
+}
+
+impl<T> From<T> for AtomicCell<T> {
+  #[inline]
+  fn from(value: T) -> AtomicCell<T> {
+    AtomicCell::new(value)
+  }
+}
+
+impl<T> RefUnwindSafe for AtomicCell<T> {}
+
+// SAFETY: Concurrent access is manually managed
+unsafe impl<T> Send for AtomicCell<T> where T: Send {}
+
+// SAFETY: Concurrent access is manually managed
+unsafe impl<T: Send> Sync for AtomicCell<T> {}
+
+impl<T> UnwindSafe for AtomicCell<T> where T: Send {}
+
+#[inline]
+fn lock(addr: usize) -> &'static SeqLock {
+  #[allow(clippy::indexing_slicing, reason = "modulo result will always be in-bounds")]
+  &LOCKS[addr % LEN].0
+}
diff --git a/wtx/src/misc/atomic_waker.rs b/wtx/src/misc/sync/atomic_waker.rs
similarity index 100%
rename from wtx/src/misc/atomic_waker.rs
rename to wtx/src/misc/sync/atomic_waker.rs
diff --git a/wtx/src/misc/sync/back_off.rs b/wtx/src/misc/sync/back_off.rs
new file mode 100644
index 00000000..227b0602
--- /dev/null
+++ b/wtx/src/misc/sync/back_off.rs
@@ -0,0 +1,92 @@
+use core::{
+  cell::Cell,
+  fmt::{Debug, Formatter},
+  hint::spin_loop,
+};
+
+const SPIN_LIMIT: u32 = 6;
+const YIELD_LIMIT: u32 = 10;
+
+/// Performs exponential backoff in spin loops, which reduces contention and improves overall
+/// performance.
+pub struct Backoff {
+  step: Cell<u32>,
+}
+
+impl Backoff {
+  /// Creates a new instance.
+  #[inline]
+  pub const fn new() -> Self {
+    Backoff { step: Cell::new(0) }
+  }
+
+  /// Returns `true` if exponential backoff has completed and blocking the thread is advised.
+  #[inline]
+  pub fn is_completed(&self) -> bool {
+    self.step.get() > YIELD_LIMIT
+  }
+
+  /// Resets the instance.
+  #[inline]
+  pub fn reset(&self) {
+    self.step.set(0);
+  }
+
+  /// Backs off in a blocking loop.
+  ///
+  /// Should be used when it is desirable to wait for another thread to make progress.
+  #[inline]
+  pub fn snooze(&self) {
+    if self.step.get() <= SPIN_LIMIT {
+      let until = 1 << self.step.get();
+      for _ in 0..until {
+        spin_loop();
+      }
+    } else {
+      #[cfg(feature = "std")]
+      std::thread::yield_now();
+      #[cfg(not(feature = "std"))]
+      {
+        let until = 1 << self.step.get();
+        for _ in 0..until {
+          spin_loop();
+        }
+      }
+    }
+    if self.step.get() <= YIELD_LIMIT {
+      self.step.set(self.step.get().wrapping_add(1));
+    }
+  }
+
+  /// Backs off in a lock-free loop.
+  ///
+  /// Should be used when it is desirable to retry an operation because another thread made
+  /// progress.
+  #[inline]
+  pub fn spin(&self) {
+    let until = 1 << self.step.get().min(SPIN_LIMIT);
+    for _ in 0..until {
+      spin_loop();
+    }
+    if self.step.get() <= SPIN_LIMIT {
+      self.step.set(self.step.get().wrapping_add(1));
+    }
+  }
+}
+
+impl Debug for Backoff {
+  #[inline]
+  fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+    f.debug_struct("Backoff")
+      .field("is_completed", &self.is_completed())
+      .field("step", &self.step)
+      .finish()
+  }
+}
+
+impl Default for Backoff {
+  #[inline]
+  fn default() -> Backoff {
+    Backoff::new()
+  }
+}
diff --git a/wtx/src/misc/sync/cache_padded.rs b/wtx/src/misc/sync/cache_padded.rs
new file mode 100644
index 00000000..da3828cf
--- /dev/null
+++ b/wtx/src/misc/sync/cache_padded.rs
@@ -0,0 +1,39 @@
+use core::ops::{Deref, DerefMut};
+
+/// Prevents false sharing by padding and aligning to the length of a cache line.
+#[cfg_attr(
+  any(target_arch = "aarch64", target_arch = "powerpc64", target_arch = "x86_64",),
+  repr(align(128))
+)]
+#[cfg_attr(
+  not(any(target_arch = "aarch64", target_arch = "powerpc64", target_arch = "x86_64",)),
+  repr(align(64))
+)]
+#[derive(Debug)]
+pub struct CachePadded<T>(
+  /// Element
+  pub T,
+);
+
+impl<T> Deref for CachePadded<T> {
+  type Target = T;
+
+  #[inline]
+  fn deref(&self) -> &T {
+    &self.0
+  }
+}
+
+impl<T> DerefMut for CachePadded<T> {
+  #[inline]
+  fn deref_mut(&mut self) -> &mut T {
+    &mut self.0
+  }
+}
+
+impl<T> From<T> for CachePadded<T> {
+  #[inline]
+  fn from(t: T) -> Self {
+    CachePadded(t)
+  }
+}
diff --git a/wtx/src/misc/sync/seq_lock.rs b/wtx/src/misc/sync/seq_lock.rs
new file mode 100644
index 00000000..30a9eaf5
--- /dev/null
+++ b/wtx/src/misc/sync/seq_lock.rs
@@ -0,0 +1,70 @@
+use crate::misc::Backoff;
+use core::{
+  mem,
+  sync::atomic::{fence, AtomicUsize, Ordering},
+};
+
+pub(crate) struct SeqLock {
+  state: AtomicUsize,
+}
+
+impl SeqLock {
+  #[inline]
+  pub(crate) const fn new() -> Self {
+    Self { state: AtomicUsize::new(0) }
+  }
+
+  #[inline]
+  pub(crate) fn optimistic_read(&self) -> Option<usize> {
+    let state = self.state.load(Ordering::Acquire);
+    if state == 1 {
+      None
+    } else {
+      Some(state)
+    }
+  }
+
+  /// Returns `true` if the current stamp is equal to `stamp`.
+  ///
+  /// This method should be called after optimistic reads to check whether they are valid. The
+  /// argument `stamp` should correspond to the one returned by method `optimistic_read`.
+  #[inline]
+  pub(crate) fn validate_read(&self, stamp: usize) -> bool {
+    fence(Ordering::Acquire);
+    self.state.load(Ordering::Relaxed) == stamp
+  }
+
+  #[inline]
+  pub(crate) fn write(&'static self) -> SeqLockWriteGuard {
+    let backoff = Backoff::new();
+    loop {
+      let previous = self.state.swap(1, Ordering::Acquire);
+      if previous != 1 {
+        fence(Ordering::Release);
+        return SeqLockWriteGuard { lock: self, state: previous };
+      }
+      backoff.snooze();
+    }
+  }
+}
+
+pub(crate) struct SeqLockWriteGuard {
+  lock: &'static SeqLock,
+  state: usize,
+}
+
+impl SeqLockWriteGuard {
+  #[inline]
+  pub(crate) fn abort(self) {
+    self.lock.state.store(self.state, Ordering::Release);
+    #[allow(clippy::mem_forget, reason = "avoids incrementing the stamp")]
+    mem::forget(self);
+  }
+}
+
+impl Drop for SeqLockWriteGuard {
+  #[inline]
+  fn drop(&mut self) {
+    self.lock.state.store(self.state.wrapping_add(2), Ordering::Release);
+  }
+}
diff --git a/wtx/src/misc/tuple_impls.rs b/wtx/src/misc/tuple_impls.rs
index 4cfb75ff..11c4c10e 100644
--- a/wtx/src/misc/tuple_impls.rs
+++ b/wtx/src/misc/tuple_impls.rs
@@ -46,7 +46,7 @@ macro_rules! impl_0_16 {
     mod http_server_framework {
       use crate::{
         http::{
-          HttpError, Request, ReqResData, ReqResDataMut, Response, StatusCode,
+          HttpError, Request, ReqResBuffer,  Response, StatusCode,
           server_framework::{ConnAux, ReqAux, ReqMiddleware, ResMiddleware, PathManagement, PathParams}
         },
         misc::{ArrayVector, Vector}
@@ -72,33 +72,30 @@ macro_rules! impl_0_16 {
           type Init = ($($T::Init,)*);
 
           #[inline]
-          fn req_aux<RRD>(_init: Self::Init, _req: &mut Request<RRD>) -> crate::Result<Self>
-          where
-            RRD: ReqResDataMut
-          {
+          fn req_aux(_init: Self::Init, _req: &mut Request<ReqResBuffer>) -> crate::Result<Self> {
             Ok(($( $T::req_aux(_init.$N, _req)?, )*))
           }
         }
 
-        impl<$($T,)* CA, ERR, RA, RRD> ReqMiddleware<CA, ERR, RA, RRD> for ($($T,)*)
+        impl<$($T,)* CA, ERR, RA> ReqMiddleware<CA, ERR, RA> for ($($T,)*)
         where
-          $($T: ReqMiddleware<CA, ERR, RA, RRD>,)*
+          $($T: ReqMiddleware<CA, ERR, RA>,)*
           ERR: From<crate::Error>
         {
           #[inline]
-          async fn apply_req_middleware(&self, _ca: &mut CA, _ra: &mut RA, _req: &mut Request<RRD>) -> Result<(), ERR> {
+          async fn apply_req_middleware(&self, _ca: &mut CA, _ra: &mut RA, _req: &mut Request<ReqResBuffer>) -> Result<(), ERR> {
             $( self.$N.apply_req_middleware(_ca, _ra, _req).await?; )*
             Ok(())
           }
         }
 
-        impl<$($T,)* CA, ERR, RA, RRD> ResMiddleware<CA, ERR, RA, RRD> for ($($T,)*)
+        impl<$($T,)* CA, ERR, RA> ResMiddleware<CA, ERR, RA> for ($($T,)*)
         where
-          $($T: ResMiddleware<CA, ERR, RA, RRD>,)*
+          $($T: ResMiddleware<CA, ERR, RA>,)*
           ERR: From<crate::Error>
         {
           #[inline]
-          async fn apply_res_middleware(&self, _ca: &mut CA, _ra: &mut RA, mut _res: Response<&mut RRD>) -> Result<(), ERR> {
+          async fn apply_res_middleware(&self, _ca: &mut CA, _ra: &mut RA, mut _res: Response<&mut ReqResBuffer>) -> Result<(), ERR> {
             $({
               let local_res = Response {
                 rrd: &mut *_res.rrd,
@@ -111,11 +108,10 @@ macro_rules! impl_0_16 {
           }
         }
 
-        impl<$($T,)* CA, ERR, RA, RRD> PathManagement<CA, ERR, RA, RRD> for ($(PathParams<$T>,)*)
+        impl<$($T,)* CA, ERR, RA> PathManagement<CA, ERR, RA> for ($(PathParams<$T>,)*)
         where
-          $($T: PathManagement<CA, ERR, RA, RRD>,)*
+          $($T: PathManagement<CA, ERR, RA>,)*
           ERR: From<crate::Error>,
-          RRD: ReqResData
         {
           const IS_ROUTER: bool = false;
 
@@ -125,7 +121,7 @@ macro_rules! impl_0_16 {
             _ca: &mut CA,
             _path_defs: (u8, &[(&'static str, u8)]),
             _ra: &mut RA,
-            _req: &mut Request<RRD>,
+            _req: &mut Request<ReqResBuffer>,
           ) -> Result<StatusCode, ERR> {
             #[cfg(feature = "matchit")]
             match _path_defs.1.get(usize::from(_path_defs.0)).map(|el| el.1) {
@@ -141,7 +137,7 @@ macro_rules! impl_0_16 {
               _ => Err(ERR::from(HttpError::UriMismatch.into()))
             }
             #[cfg(not(feature = "matchit"))]
-            match _req.rrd.uri().path() {
+            match _req.rrd.uri.path() {
               $(
                 elem if elem == self.$N.full_path => {
                   return self
diff --git a/wtx/src/misc/uri.rs b/wtx/src/misc/uri.rs
index 200a10d1..996d2908 100644
--- a/wtx/src/misc/uri.rs
+++ b/wtx/src/misc/uri.rs
@@ -5,6 +5,8 @@ use crate::misc::{
 use alloc::string::String;
 use core::fmt::{Arguments, Debug, Display, Formatter, Write};
 
+pub(crate) static _EMPTY_URI_STRING: UriString = UriString::_empty(String::new());
+
 /// [Uri] with an owned array.
 pub type UriArrayString<const N: usize> = Uri<ArrayString<N>>;
 /// [Uri] with a string reference.
diff --git a/wtx/src/misc/utf8_errors.rs b/wtx/src/misc/utf8_errors.rs
index 5608cf2a..1731095d 100644
--- a/wtx/src/misc/utf8_errors.rs
+++ b/wtx/src/misc/utf8_errors.rs
@@ -18,6 +18,7 @@ pub struct BasicUtf8Error;
 
 impl From<BasicUtf8Error> for crate::Error {
   #[inline]
+  #[track_caller]
   fn from(_: BasicUtf8Error) -> Self {
     Self::InvalidUTF8
   }
diff --git a/wtx/src/misc/vector.rs b/wtx/src/misc/vector.rs
index ed3cd77d..0ca7077d 100644
--- a/wtx/src/misc/vector.rs
+++ b/wtx/src/misc/vector.rs
@@ -1,4 +1,4 @@
-use crate::misc::{BufferParam, Lease, LeaseMut, _unlikely_elem};
+use crate::misc::{BufferMode, Lease, LeaseMut, _unlikely_elem};
 use alloc::vec::{Drain, IntoIter, Vec};
 use core::{
   borrow::{Borrow, BorrowMut},
@@ -108,17 +108,17 @@ impl<T> Vector<T> {
     Ok(this)
   }
 
-  /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
-  /// raw pointer valid for zero sized reads if the vector didn't allocate.
-  #[inline]
-  pub fn as_mut_ptr(&mut self) -> *mut T {
-    self.data.as_mut_ptr()
-  }
-
-  /// Extracts a slice containing the entire mutable vector.
-  #[inline]
-  pub fn as_mut_slice(&mut self) -> &mut [T] {
-    self.data.as_mut_slice()
+  /// Constructs a new, empty instance with the exact specified capacity.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::<u8>::with_exact_capacity(2).unwrap();
+  /// assert_eq!(vec.capacity(), 2);
+  /// ```
+  #[inline(always)]
+  pub fn with_exact_capacity(cap: usize) -> Result<Self, VectorError> {
+    let mut this = Self { data: Vec::new() };
+    this.reserve_exact(cap)?;
+    Ok(this)
   }
 
   /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
@@ -128,12 +128,25 @@ impl<T> Vector<T> {
     self.data.as_ptr()
   }
 
+  /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
+  /// raw pointer valid for zero sized reads if the vector didn't allocate.
+  #[inline]
+  pub fn as_ptr_mut(&mut self) -> *mut T {
+    self.data.as_mut_ptr()
+  }
+
   /// Extracts a slice containing the entire vector.
   #[inline]
   pub fn as_slice(&self) -> &[T] {
     self.data.as_slice()
   }
 
+  /// Extracts a slice containing the entire mutable vector.
+  #[inline]
+  pub fn as_slice_mut(&mut self) -> &mut [T] {
+    self.data.as_mut_slice()
+  }
+
   /// Returns the total number of elements the vector can hold without reallocating.
   ///
   /// ```rust
@@ -171,6 +184,12 @@ impl<T> Vector<T> {
   }
 
   /// Clones and appends all elements in the iterator.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::new();
+  /// vec.extend_from_iter(0..2);
+  /// assert_eq!(vec.as_slice(), &[0, 1]);
+  /// ```
   #[inline]
   pub fn extend_from_iter(&mut self, ii: impl IntoIterator<Item = T>) -> Result<(), VectorError> {
     let iter = ii.into_iter();
@@ -182,6 +201,14 @@ impl<T> Vector<T> {
   }
 
   /// Constructs a new instance with elements provided by `iter`.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::from_iter(1u8..4).unwrap();
+  /// vec.insert(1, 4);
+  /// assert_eq!(vec.as_slice(), [1, 4, 2, 3]);
+  /// vec.insert(4, 5);
+  /// assert_eq!(vec.as_slice(), [1, 4, 2, 3, 5]);
+  /// ```
   #[inline]
   pub fn insert(&mut self, idx: usize, elem: T) -> Result<(), VectorError> {
     let len = self.len();
@@ -190,7 +217,7 @@ impl<T> Vector<T> {
     }
     self.reserve(1)?;
     // SAFETY: Top-level check ensures bounds
-    let ptr = unsafe { self.as_mut_ptr().add(idx) };
+    let ptr = unsafe { self.as_ptr_mut().add(idx) };
     if idx < len {
       // SAFETY: Top-level check ensures bounds
       let diff = unsafe { len.unchecked_sub(idx) };
@@ -215,12 +242,24 @@ impl<T> Vector<T> {
   }
 
   /// Removes the last element from a vector and returns it, or [None] if it is empty.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::from_iter(1u8..4).unwrap();
+  /// assert_eq!(vec.pop(), Some(3));
+  /// assert_eq!(vec.as_slice(), [1, 2]);
+  /// ```
   #[inline]
   pub fn pop(&mut self) -> Option<T> {
     self.data.pop()
   }
 
   /// Appends an element to the back of the collection.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::new();
+  /// vec.push(3);
+  /// assert_eq!(vec.as_slice(), [3]);
+  /// ```
   #[inline]
   pub fn push(&mut self, value: T) -> Result<(), VectorError> {
     self.reserve(1).map_err(|_err| VectorError::PushOverflow)?;
@@ -241,6 +280,12 @@ impl<T> Vector<T> {
   }
 
   /// Shortens the vector, keeping the first len elements and dropping the rest.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::from_iter(1u8..4).unwrap();
+  /// assert_eq!(vec.remove(1), Some(2));
+  /// assert_eq!(vec.as_slice(), [1, 3]);
+  /// ```
   #[inline]
   pub fn remove(&mut self, idx: usize) -> Option<T> {
     if idx >= self.data.len() {
@@ -254,6 +299,12 @@ impl<T> Vector<T> {
   /// speculatively avoid frequent reallocations. After calling `reserve`,
   /// capacity will be greater than or equal to `self.len() + additional`.
   /// Does nothing if capacity is already sufficient.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::<u8>::new();
+  /// vec.reserve(10);
+  /// assert!(vec.capacity() >= 10);
+  /// ```
   #[inline(always)]
   pub fn reserve(&mut self, additional: usize) -> Result<(), VectorError> {
     self.data.try_reserve(additional).map_err(|_err| VectorError::ReserveOverflow)?;
@@ -264,7 +315,33 @@ impl<T> Vector<T> {
     Ok(())
   }
 
+  /// Tries to reserve the minimum capacity for at least `additional`
+  /// elements to be inserted in the given instance. Unlike [`try_reserve`],
+  /// this will not deliberately over-allocate to speculatively avoid frequent
+  /// allocations.
+  ///
+  /// ```rust
+  /// let mut vec = wtx::misc::Vector::<u8>::new();
+  /// vec.reserve(10);
+  /// assert!(vec.capacity() >= 10);
+  /// ```
+  #[inline(always)]
+  pub fn reserve_exact(&mut self, additional: usize) -> Result<(), VectorError> {
+    self.data.try_reserve_exact(additional).map_err(|_err| VectorError::ReserveOverflow)?;
+    // SAFETY: `len` will never be greater than the current capacity
+    unsafe {
+      assert_unchecked(self.data.capacity() >= self.data.len());
+    }
+    Ok(())
+  }
+
   /// Shortens the vector, keeping the first len elements and dropping the rest.
+  ///
+  /// ```
+  /// let mut vec = wtx::misc::Vector::from_iter(1u8..6).unwrap();
+  /// vec.truncate(2);
+  /// assert_eq!(vec.as_slice(), [1, 2]);
+  /// ```
   #[inline]
   pub fn truncate(&mut self, len: usize) {
     self.data.truncate(len);
@@ -293,7 +370,7 @@ where
   #[inline]
   pub fn from_cloneable_elem(len: usize, value: T) -> Result<Self, VectorError> {
     let mut this = Self::with_capacity(len)?;
-    this.expand(BufferParam::Len(len), value)?;
+    this.expand(BufferMode::Len(len), value)?;
     Ok(this)
   }
 
@@ -301,7 +378,7 @@ where
   ///
   /// Does nothing if the calculated length is equal or less than the current length.
   #[inline(always)]
-  pub fn expand(&mut self, bp: BufferParam, value: T) -> Result<(), VectorError> {
+  pub fn expand(&mut self, bp: BufferMode, value: T) -> Result<(), VectorError> {
     let len = self.data.len();
     let Some((additional, new_len)) = bp.params(len) else {
       return Ok(());
@@ -329,19 +406,15 @@ where
   #[inline]
   pub fn from_slice(slice: &[T]) -> Result<Self, VectorError> {
     let mut this = Self::new();
-    this.extend_from_slice(slice)?;
+    this.extend_from_copyable_slice(slice)?;
     Ok(this)
   }
 
   /// Iterates over the slice `other`, copies each element, and then appends
   /// it to this vector. The `other` slice is traversed in-order.
   #[inline]
-  pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), VectorError> {
-    self.reserve(other.len()).map_err(|_err| VectorError::ExtendFromSliceOverflow)?;
-    // SAFETY: memory has been allocated
-    unsafe {
-      self.do_extend_from_slice(other);
-    }
+  pub fn extend_from_copyable_slice(&mut self, other: &[T]) -> Result<(), VectorError> {
+    let _ = self.extend_from_copyable_slices([other])?;
     Ok(())
   }
 
@@ -349,7 +422,7 @@ where
   ///
   /// Returns the sum of the lengths of all slices.
   #[inline(always)]
-  pub fn extend_from_slices<'iter, I>(&mut self, others: I) -> Result<usize, VectorError>
+  pub fn extend_from_copyable_slices<'iter, I>(&mut self, others: I) -> Result<usize, VectorError>
   where
     I: IntoIterator<Item = &'iter [T]>,
     I::IntoIter: Clone,
@@ -452,61 +525,6 @@ mod serde {
   }
 }
 
-#[cfg(feature = "quick-protobuf")]
-impl quick_protobuf::writer::WriterBackend for &mut Vector<u8> {
-  #[inline]
-  fn pb_write_u8(&mut self, x: u8) -> quick_protobuf::Result<()> {
-    self.push(x).map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-
-  #[inline]
-  fn pb_write_u32(&mut self, x: u32) -> quick_protobuf::Result<()> {
-    self
-      .extend_from_slice(&x.to_be_bytes())
-      .map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-
-  #[inline]
-  fn pb_write_i32(&mut self, x: i32) -> quick_protobuf::Result<()> {
-    self
-      .extend_from_slice(&x.to_be_bytes())
-      .map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-
-  #[inline]
-  fn pb_write_f32(&mut self, x: f32) -> quick_protobuf::Result<()> {
-    self
-      .extend_from_slice(&x.to_be_bytes())
-      .map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-
-  #[inline]
-  fn pb_write_u64(&mut self, x: u64) -> quick_protobuf::Result<()> {
-    self
-      .extend_from_slice(&x.to_be_bytes())
-      .map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-
-  #[inline]
-  fn pb_write_i64(&mut self, x: i64) -> quick_protobuf::Result<()> {
-    self
-      .extend_from_slice(&x.to_be_bytes())
-      .map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-
-  #[inline]
-  fn pb_write_f64(&mut self, x: f64) -> quick_protobuf::Result<()> {
-    self
-      .extend_from_slice(&x.to_be_bytes())
-      .map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-
-  #[inline]
-  fn pb_write_all(&mut self, buf: &[u8]) -> quick_protobuf::Result<()> {
-    self.extend_from_slice(buf).map_err(|_err| quick_protobuf::Error::UnexpectedEndOfBuffer)
-  }
-}
-
 impl<T> AsMut<[T]> for Vector<T> {
   #[inline]
   fn as_mut(&mut self) -> &mut [T] {
@@ -595,7 +613,7 @@ impl<T> From<Vector<T>> for Vec<T> {
 impl core::fmt::Write for Vector<u8> {
   #[inline]
   fn write_str(&mut self, s: &str) -> core::fmt::Result {
-    self.extend_from_slice(s.as_bytes()).map_err(|_err| core::fmt::Error)
+    self.extend_from_copyable_slice(s.as_bytes()).map_err(|_err| core::fmt::Error)
   }
 }
 
@@ -675,8 +693,7 @@ mod cl_aux {
   }
 }
 
-#[cfg(feature = "_proptest")]
-#[cfg(test)]
+#[cfg(all(feature = "_proptest", test))]
 mod _proptest {
   use crate::misc::Vector;
   use alloc::vec::Vec;
diff --git a/wtx/src/pool.rs b/wtx/src/pool.rs
index bc6fd81a..23a0705c 100644
--- a/wtx/src/pool.rs
+++ b/wtx/src/pool.rs
@@ -13,19 +13,13 @@ pub use simple_pool::*;
 
 /// Manages HTTP/2 resources for clients and servers.
 #[cfg(feature = "http2")]
-pub type Http2BufferRM<RRB> =
-  SimpleRM<fn() -> Result<crate::http2::Http2Buffer<RRB>, crate::Error>>;
+pub type Http2BufferRM = SimpleRM<fn() -> crate::Result<crate::http2::Http2Buffer>>;
 /// Manages resources for HTTP2 requests and responses.
 #[cfg(feature = "http2")]
-pub type StreamBufferRM = SimpleRM<fn() -> Result<crate::http::ReqResBuffer, crate::Error>>;
+pub type StreamBufferRM = SimpleRM<fn() -> crate::Result<crate::http::ReqResBuffer>>;
 /// Manages WebSocket resources.
 #[cfg(feature = "web-socket")]
-pub type WebSocketRM = SimpleRM<
-  fn() -> Result<
-    (crate::web_socket::FrameBufferVec, crate::web_socket::WebSocketBuffer),
-    crate::Error,
-  >,
->;
+pub type WebSocketRM = SimpleRM<fn() -> crate::Result<crate::web_socket::WebSocketBuffer>>;
 
 /// A pool contains a set of resources that are behind some synchronism mechanism.
 pub trait Pool {
diff --git a/wtx/src/pool/simple_pool.rs b/wtx/src/pool/simple_pool.rs
index ea09d5b6..d74a1cf0 100644
--- a/wtx/src/pool/simple_pool.rs
+++ b/wtx/src/pool/simple_pool.rs
@@ -94,7 +94,10 @@ impl<RL, RM> crate::http::server_framework::ReqAux for SimplePool<RL, RM> {
   type Init = Self;
 
   #[inline]
-  fn req_aux<RRD>(init: Self::Init, _: &mut crate::http::Request<RRD>) -> crate::Result<Self> {
+  fn req_aux(
+    init: Self::Init,
+    _: &mut crate::http::Request<crate::http::ReqResBuffer>,
+  ) -> crate::Result<Self> {
     Ok(init)
   }
 }
diff --git a/wtx/src/web_socket.rs b/wtx/src/web_socket.rs
index 8a6fc7ea..7fc4cd4d 100644
--- a/wtx/src/web_socket.rs
+++ b/wtx/src/web_socket.rs
@@ -1,99 +1,72 @@
 //! A computer communications protocol, providing full-duplex communication channels over a single
 //! TCP connection.
 
-// # Reading copy
-//
-// |    Frame   |   With Decompression  | Without Decompression |
-// |------------|-----------------------|-----------------------|
-// |Single      |(PB -> FB)¹            |(PB -> FB)¹            |
-// |Continuation|(PB -> DB)* (DB -> FB)¹|(PB -> FB)*            |
-
 mod close_code;
 pub mod compression;
 mod frame;
-mod frame_buffer;
 #[cfg(feature = "web-socket-handshake")]
 mod handshake;
 mod misc;
 mod op_code;
+mod payload_ty;
+mod read_frame_info;
 mod unmask;
 mod web_socket_buffer;
 mod web_socket_error;
+mod web_socket_parts;
+pub(crate) mod web_socket_reader;
+mod web_socket_writer;
 
 use crate::{
-  misc::{
-    from_utf8_basic, from_utf8_ext, BufferParam, CompletionErr, ConnectionState, ExtUtf8Error,
-    FilledBuffer, IncompleteUtf8Char, Lease, LeaseMut, PartitionedFilledBuffer, Rng, Stream,
-    Vector, _read_until,
-  },
+  misc::{ConnectionState, LeaseMut, Stream, Xorshift64},
+  web_socket::payload_ty::PayloadTy,
   _MAX_PAYLOAD_LEN,
 };
 pub use close_code::CloseCode;
 pub use compression::{Compression, CompressionLevel, DeflateConfig};
-use core::ops::Range;
+use core::marker::PhantomData;
 pub use frame::{
-  Frame, FrameControlArray, FrameControlArrayMut, FrameMut, FrameMutControlArray,
-  FrameMutControlArrayMut, FrameMutMut, FrameMutVec, FrameMutVecMut, FrameVec, FrameVecMut,
-};
-pub use frame_buffer::{
-  FrameBuffer, FrameBufferControlArray, FrameBufferControlArrayMut, FrameBufferMut, FrameBufferVec,
-  FrameBufferVecMut,
+  Frame, FrameControlArray, FrameControlArrayMut, FrameMut, FrameRef, FrameVector, FrameVectorMut,
+  FrameVectorRef,
 };
-pub use misc::Expand;
-use misc::{define_fb_from_header_params, op_code};
+pub use misc::fill_with_close_code;
 pub use op_code::OpCode;
-use unmask::unmask;
+pub use read_frame_info::ReadFrameInfo;
 pub use web_socket_buffer::WebSocketBuffer;
 pub use web_socket_error::WebSocketError;
+pub use web_socket_parts::{WebSocketCommonPart, WebSocketReaderPart, WebSocketWriterPart};
 
-pub(crate) const DECOMPRESSION_SUFFIX: [u8; 4] = [0, 0, 255, 255];
-pub(crate) const DFLT_FRAME_BUFFER_VEC_LEN: usize = 32 * 1024;
-pub(crate) const MAX_CONTROL_FRAME_LEN: usize = MAX_HDR_LEN_USIZE + MAX_CONTROL_FRAME_PAYLOAD_LEN;
-pub(crate) const MAX_CONTROL_FRAME_PAYLOAD_LEN: usize = 125;
-pub(crate) const MAX_HDR_LEN_U8: u8 = 14;
-pub(crate) const MAX_HDR_LEN_USIZE: usize = 14;
-pub(crate) const MIN_HEADER_LEN_USIZE: usize = 2;
+const MAX_CONTROL_PAYLOAD_LEN: usize = 125;
+const MAX_HEADER_LEN_USIZE: usize = 14;
 
 /// Always masks the payload before sending.
-pub type WebSocketClient<NC, RNG, S, WSB> = WebSocket<NC, RNG, S, WSB, true>;
+pub type WebSocketClient<NC, S, WSB> = WebSocket<NC, S, WSB, true>;
 /// [`WebSocketClient`] with a mutable reference of [`WebSocketBuffer`].
-pub type WebSocketClientMut<'wsb, NC, RNG, S> =
-  WebSocketClient<NC, RNG, S, &'wsb mut WebSocketBuffer>;
+pub type WebSocketClientMut<'wsb, NC, S> = WebSocketClient<NC, S, &'wsb mut WebSocketBuffer>;
 /// [`WebSocketClient`] with an owned [`WebSocketBuffer`].
-pub type WebSocketClientOwned<NC, RNG, S> = WebSocketClient<NC, RNG, S, WebSocketBuffer>;
+pub type WebSocketClientOwned<NC, S> = WebSocketClient<NC, S, WebSocketBuffer>;
 /// Always unmasks the payload after receiving.
-pub type WebSocketServer<NC, RNG, S, WSB> = WebSocket<NC, RNG, S, WSB, false>;
+pub type WebSocketServer<NC, S, WSB> = WebSocket<NC, S, WSB, false>;
 /// [`WebSocketServer`] with a mutable reference of [`WebSocketBuffer`].
-pub type WebSocketServerMut<'wsb, NC, RNG, S> =
-  WebSocketServer<NC, RNG, S, &'wsb mut WebSocketBuffer>;
+pub type WebSocketServerMut<'wsb, NC, S> = WebSocketServer<NC, S, &'wsb mut WebSocketBuffer>;
 /// [`WebSocketServer`] with an owned [`WebSocketBuffer`].
-pub type WebSocketServerOwned<NC, RNG, S> = WebSocketServer<NC, RNG, S, WebSocketBuffer>;
+pub type WebSocketServerOwned<NC, S> = WebSocketServer<NC, S, WebSocketBuffer>;
 
-type ReadContinuationFramesCbs<B> = (
-  fn(&[u8]) -> crate::Result<Option<IncompleteUtf8Char>>,
-  fn(&[u8], &mut Option<IncompleteUtf8Char>) -> crate::Result<()>,
-  fn(
-    &mut FrameBuffer<B>,
-    &ReadFrameInfo,
-    usize,
-    &mut WebSocketBuffer,
-  ) -> crate::Result<(bool, usize)>,
-);
-
-/// Protocol implementation over an asynchronous stream.
+/// Full-duplex communication over an asynchronous stream.
 ///
 /// <https://tools.ietf.org/html/rfc6455>
 #[derive(Debug)]
-pub struct WebSocket<NC, RNG, S, WSB, const IS_CLIENT: bool> {
-  ct: ConnectionState,
+pub struct WebSocket<NC, S, WSB, const IS_CLIENT: bool> {
+  connection_state: ConnectionState,
+  curr_payload: PayloadTy,
   max_payload_len: usize,
   nc: NC,
-  rng: RNG,
+  rng: Xorshift64,
   stream: S,
   wsb: WSB,
 }
 
-impl<NC, RNG, S, WSB, const IS_CLIENT: bool> WebSocket<NC, RNG, S, WSB, IS_CLIENT> {
+impl<NC, S, WSB, const IS_CLIENT: bool> WebSocket<NC, S, WSB, IS_CLIENT> {
   /// Sets whether to automatically close the connection when a received frame payload length
   /// exceeds `max_payload_len`. Defaults to `64 * 1024 * 1024` bytes (64 MiB).
   #[inline]
@@ -102,854 +75,106 @@ impl<NC, RNG, S, WSB, const IS_CLIENT: bool> WebSocket<NC, RNG, S, WSB, IS_CLIEN
   }
 }
 
-impl<NC, RNG, S, WSB, const IS_CLIENT: bool> WebSocket<NC, RNG, S, WSB, IS_CLIENT>
+impl<NC, S, WSB, const IS_CLIENT: bool> WebSocket<NC, S, WSB, IS_CLIENT>
 where
   NC: compression::NegotiatedCompression,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
   /// Creates a new instance from a stream that supposedly has already completed the handshake.
   #[inline]
-  pub fn new(nc: NC, rng: RNG, stream: S, mut wsb: WSB) -> crate::Result<Self> {
-    wsb.lease_mut().nb._clear_if_following_is_empty();
-    wsb.lease_mut().nb._expand_buffer(MAX_HDR_LEN_USIZE)?;
-    Ok(Self { ct: ConnectionState::Open, max_payload_len: _MAX_PAYLOAD_LEN, nc, rng, stream, wsb })
+  pub fn new(nc: NC, rng: Xorshift64, stream: S, mut wsb: WSB) -> crate::Result<Self> {
+    wsb.lease_mut().network_buffer._clear_if_following_is_empty();
+    wsb.lease_mut().network_buffer._reserve(MAX_HEADER_LEN_USIZE)?;
+    Ok(Self {
+      connection_state: ConnectionState::Open,
+      curr_payload: PayloadTy::None,
+      max_payload_len: _MAX_PAYLOAD_LEN,
+      nc,
+      rng,
+      stream,
+      wsb,
+    })
   }
 
-  /// Reads a frame from the stream.
-  ///
-  /// If a frame is made up of other frames, everything is collected until all fragments are
-  /// received.
+  /// The current frame payload that is set when [`Self::read_frame`] is called, otherwise,
+  /// returns an empty slice.
   #[inline]
-  pub async fn read_frame<'fb, B>(
-    &mut self,
-    fb: &'fb mut FrameBuffer<B>,
-  ) -> crate::Result<Frame<&'fb mut FrameBuffer<B>, IS_CLIENT>>
-  where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
-  {
-    fb.clear();
-    let header_buffer_len = header_placeholder::<IS_CLIENT>();
-    let payload_start_idx = header_buffer_len.into();
-    let Some(first_rfi) = self.read_first_frame(fb, header_buffer_len, payload_start_idx).await?
-    else {
-      return Frame::from_fb(fb);
-    };
-    let mut total_frame_len = payload_start_idx;
-    let payload_len = if first_rfi.should_decompress {
-      self
-        .read_continuation_frames(
-          fb,
-          &first_rfi,
-          payload_start_idx,
-          &mut total_frame_len,
-          (
-            |_| Ok(None),
-            |_, _| Ok(()),
-            |_, rfi, local_tfl, local_wsb| {
-              Ok((true, Self::copy_from_compressed_pb_to_db(local_tfl, rfi, local_wsb)?))
-            },
-          ),
-        )
-        .await?;
-      let payload_len = Self::copy_from_compressed_db_to_fb(
-        &mut self.wsb.lease_mut().db,
-        fb,
-        &mut self.nc,
-        payload_start_idx,
-      )?;
-      let payload = lease_as_slice(fb.buffer())
-        .get(payload_start_idx..payload_start_idx.wrapping_add(payload_len))
-        .unwrap_or_default();
-      if matches!(first_rfi.op_code, OpCode::Text) && from_utf8_basic(payload).is_err() {
-        return Err(crate::Error::InvalidUTF8);
-      }
-      payload_len
-    } else {
-      self
-        .read_continuation_frames(
-          fb,
-          &first_rfi,
-          payload_start_idx,
-          &mut total_frame_len,
-          (
-            |curr_payload| {
-              Ok(match from_utf8_ext(curr_payload) {
-                Err(ExtUtf8Error::Incomplete { incomplete_ending_char, .. }) => {
-                  Some(incomplete_ending_char)
-                }
-                Err(ExtUtf8Error::Invalid { .. }) => {
-                  return Err(crate::Error::InvalidUTF8);
-                }
-                Ok(_) => None,
-              })
-            },
-            if matches!(first_rfi.op_code, OpCode::Binary) {
-              |_, _| Ok(())
-            } else {
-              Self::manage_continuation_text
-            },
-            |local_fb, rfi, local_tfl, local_wsb| {
-              Ok((
-                false,
-                Self::copy_from_uncompressed_pb_to_fb(local_fb, local_tfl, &mut local_wsb.nb, rfi)?,
-              ))
-            },
-          ),
-        )
-        .await?;
-      total_frame_len.wrapping_sub(payload_start_idx)
-    };
-    define_fb_from_header_params::<_, IS_CLIENT>(
-      fb,
-      true,
-      Some(header_buffer_len),
-      first_rfi.op_code,
-      payload_len,
-      self.nc.rsv1(),
-    )?;
-    Frame::from_fb(fb)
+  pub fn curr_payload(&mut self) -> &mut [u8] {
+    match self.curr_payload {
+      PayloadTy::Network => self.wsb.lease_mut().network_buffer._current_mut(),
+      PayloadTy::None => &mut [],
+      PayloadTy::FirstReader => self.wsb.lease_mut().reader_buffer_first.as_slice_mut(),
+      PayloadTy::SecondReader => self.wsb.lease_mut().reader_buffer_second.as_slice_mut(),
+    }
   }
 
-  /// Writes a frame to the stream.
+  /// Different mutable parts that allow sending received frames using the same original instance.
   #[inline]
-  pub async fn write_frame<B, FB>(&mut self, frame: &mut Frame<FB, IS_CLIENT>) -> crate::Result<()>
-  where
-    B: LeaseMut<[u8]>,
-    FB: LeaseMut<FrameBuffer<B>>,
-  {
-    Self::do_write_frame(
-      &mut self.ct,
-      frame,
-      &mut self.nc,
-      &mut self.wsb.lease_mut().nb,
-      &mut self.rng,
-      &mut self.stream,
-    )
-    .await?;
-    Ok(())
-  }
-
-  fn begin_fb_bytes_mut<B>(fb: &mut FrameBuffer<B>, payload_start_idx: usize) -> &mut [u8]
-  where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
-  {
-    LeaseMut::<[u8]>::lease_mut(fb.buffer_mut()).get_mut(payload_start_idx..).unwrap_or_default()
-  }
-
-  fn compress_frame<'pb, B, FB>(
-    frame: &Frame<FB, IS_CLIENT>,
-    nc: &mut NC,
-    pfb: &'pb mut PartitionedFilledBuffer,
-  ) -> crate::Result<FrameMut<'pb, IS_CLIENT>>
-  where
-    B: LeaseMut<[u8]>,
-    FB: LeaseMut<FrameBuffer<B>>,
-  {
-    let fb = frame.fb().lease();
-    let len = pfb._following_end_idx();
-    let len_with_header = len.wrapping_add(fb.header().len());
-    let mut payload_len = nc.compress(
-      fb.payload(),
-      pfb,
-      |local_pfb| {
-        local_pfb._expand_buffer(fb.frame().len().wrapping_add(128))?;
-        Ok(local_pfb._buffer_mut().get_mut(len_with_header..).unwrap_or_default())
-      },
-      |local_pfb, written| {
-        local_pfb._expand_buffer(128)?;
-        let start = len_with_header.wrapping_add(written);
-        Ok(local_pfb._buffer_mut().get_mut(start..).unwrap_or_default())
+  pub fn parts(
+    &mut self,
+  ) -> (
+    WebSocketCommonPart<'_, NC, S, IS_CLIENT>,
+    WebSocketReaderPart<'_, NC, S, IS_CLIENT>,
+    WebSocketWriterPart<'_, NC, S, IS_CLIENT>,
+  ) {
+    let WebSocket { connection_state, curr_payload, nc, rng, stream, wsb, max_payload_len } = self;
+    let WebSocketBuffer {
+      writer_buffer,
+      network_buffer,
+      reader_buffer_first,
+      reader_buffer_second,
+    } = wsb.lease_mut();
+    (
+      WebSocketCommonPart { connection_state, curr_payload, nc, rng, stream },
+      WebSocketReaderPart {
+        max_payload_len: *max_payload_len,
+        network_buffer,
+        phantom: PhantomData,
+        reader_buffer_first,
+        reader_buffer_second,
       },
-    )?;
-    if frame.fin() {
-      payload_len = payload_len.saturating_sub(4);
-    }
-    let mut compressed_fb = FrameBufferMut::new(
-      pfb
-        ._following_trail_mut()
-        .get_mut(len..len_with_header.wrapping_add(payload_len))
-        .unwrap_or_default(),
-    );
-    define_fb_from_header_params::<_, IS_CLIENT>(
-      &mut compressed_fb,
-      frame.fin(),
-      Some(fb.header_len()),
-      frame.op_code(),
-      payload_len,
-      nc.rsv1(),
-    )?;
-    FrameMut::from_fb(compressed_fb)
-  }
-
-  // Final compressed continuation frame
-  fn copy_from_compressed_db_to_fb<B>(
-    db: &mut FilledBuffer,
-    fb: &mut FrameBuffer<B>,
-    nc: &mut NC,
-    payload_start_idx: usize,
-  ) -> crate::Result<usize>
-  where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
-  {
-    let _ = db._extend_from_slices([DECOMPRESSION_SUFFIX.as_slice()])?;
-    let mut buffer_len = payload_start_idx
-      .checked_add(db._len())
-      .map(|element| element.max(lease_as_slice(fb.buffer()).len()));
-    let payload_size = nc.decompress(
-      db.get(payload_start_idx..).unwrap_or_default(),
-      fb,
-      |local_fb| Ok(Self::begin_fb_bytes_mut(local_fb, payload_start_idx)),
-      |local_fb, written| Self::expand_fb(&mut buffer_len, local_fb, payload_start_idx, written),
-    )?;
-    db._clear();
-    Ok(payload_size)
-  }
-
-  // Intermediate compressed continuation frame
-  fn copy_from_compressed_pb_to_db(
-    payload_start_idx: usize,
-    rfi: &ReadFrameInfo,
-    wsb: &mut WebSocketBuffer,
-  ) -> crate::Result<usize> {
-    Self::copy_from_pb(&mut wsb.db, &mut wsb.nb, rfi, |local_pb, local_db| {
-      let n = payload_start_idx.saturating_add(rfi.payload_len);
-      local_db._expand(BufferParam::Len(n))?;
-      local_db
-        .get_mut(payload_start_idx..n)
-        .unwrap_or_default()
-        .copy_from_slice(local_pb._current().get(rfi.header_end_idx..).unwrap_or_default());
-      Ok(())
-    })?;
-    Ok(rfi.payload_len)
-  }
-
-  // Final compressed single frame
-  fn copy_from_compressed_pb_to_fb<B>(
-    fb: &mut FrameBuffer<B>,
-    nc: &mut NC,
-    payload_start_idx: usize,
-    pb: &mut PartitionedFilledBuffer,
-    rfi: &ReadFrameInfo,
-  ) -> crate::Result<usize>
-  where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
-  {
-    let mut buffer_len = payload_start_idx
-      .checked_add(rfi.payload_len)
-      .map(|element| element.max(lease_as_slice(fb.buffer()).len()));
-    let payload_len = Self::copy_from_pb(fb, pb, rfi, |local_pb, local_fb| {
-      local_pb._expand_buffer(4)?;
-      let curr_end_idx = local_pb._current().len();
-      let curr_end_idx_4p = curr_end_idx.wrapping_add(4);
-      let has_following = local_pb._has_following();
-      let range = rfi.header_end_idx..curr_end_idx_4p;
-      let input = local_pb._current_trail_mut().get_mut(range).unwrap_or_default();
-      let original = if let [.., a, b, c, d] = input {
-        let original = [*a, *b, *c, *d];
-        *a = 0;
-        *b = 0;
-        *c = 255;
-        *d = 255;
-        original
-      } else {
-        [0, 0, 0, 0]
-      };
-      if has_following {
-        let payload_len = nc.decompress(
-          input,
-          local_fb,
-          |local_local_fb| Ok(Self::begin_fb_bytes_mut(local_local_fb, payload_start_idx)),
-          |local_local_fb, written| {
-            Self::expand_fb(&mut buffer_len, local_local_fb, payload_start_idx, written)
-          },
-        )?;
-        if let [.., a, b, c, d] = input {
-          *a = original[0];
-          *b = original[1];
-          *c = original[2];
-          *d = original[3];
-        }
-        Ok(payload_len)
-      } else {
-        nc.decompress(
-          input,
-          local_fb,
-          |local_local_fb| Ok(Self::begin_fb_bytes_mut(local_local_fb, payload_start_idx)),
-          |local_local_fb, written| {
-            Self::expand_fb(&mut buffer_len, local_local_fb, payload_start_idx, written)
-          },
-        )
-      }
-    })?;
-    Ok(payload_len)
-  }
-
-  fn copy_from_pb<O, T>(
-    output: &mut O,
-    pb: &mut PartitionedFilledBuffer,
-    rfi: &ReadFrameInfo,
-    cb: impl FnOnce(&mut PartitionedFilledBuffer, &mut O) -> crate::Result<T>,
-  ) -> crate::Result<T> {
-    _debug!(
-      "{:<5} - {:<5} - {:<25}: {:?}, {:?}",
-      <&str>::from(crate::misc::Role::from_is_client(IS_CLIENT)),
-      "Read",
-      "Masked",
-      misc::_truncated_slice(pb._current(), 0..32),
-      rfi.op_code
-    );
-
-    if !IS_CLIENT {
-      unmask(
-        pb._current_mut().get_mut(rfi.header_end_idx..).unwrap_or_default(),
-        rfi.mask.ok_or(WebSocketError::MissingFrameMask)?,
-      );
-    }
-
-    _debug!(
-      "{:<5} - {:<5} - {:<25}: {:?}, {:?}",
-      <&str>::from(crate::misc::Role::from_is_client(IS_CLIENT)),
-      "Read",
-      "Unmasked",
-      misc::_truncated_slice(pb._current(), 0..32),
-      rfi.op_code
-    );
-
-    let rslt = cb(pb, output)?;
-    pb._clear_if_following_is_empty();
-
-    Ok(rslt)
-  }
-
-  // Final uncompressed single frame as well as intermediate uncompressed continuation frame
-  fn copy_from_uncompressed_pb_to_fb<B>(
-    fb: &mut FrameBuffer<B>,
-    payload_start_idx: usize,
-    pb: &mut PartitionedFilledBuffer,
-    rfi: &ReadFrameInfo,
-  ) -> crate::Result<usize>
-  where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
-  {
-    Self::copy_from_pb(fb, pb, rfi, |local_pb, local_fb| {
-      let n = payload_start_idx.saturating_add(rfi.payload_len);
-      local_fb.expand_buffer(n)?;
-      LeaseMut::<[u8]>::lease_mut(local_fb.buffer_mut())
-        .get_mut(payload_start_idx..n)
-        .unwrap_or_default()
-        .copy_from_slice(local_pb._current().get(rfi.header_end_idx..).unwrap_or_default());
-      Ok(())
-    })?;
-    Ok(rfi.payload_len)
-  }
-
-  fn curr_payload_bytes<'bytes, B>(
-    db: &'bytes FilledBuffer,
-    fb: &'bytes FrameBuffer<B>,
-    range: Range<usize>,
-    should_use_db: bool,
-  ) -> &'bytes [u8]
-  where
-    B: LeaseMut<[u8]>,
-  {
-    if should_use_db {
-      db.get(range).unwrap_or_default()
-    } else {
-      fb.buffer().lease().get(range).unwrap_or_default()
-    }
-  }
-
-  async fn do_write_frame<B, FB>(
-    ct: &mut ConnectionState,
-    frame: &mut Frame<FB, IS_CLIENT>,
-    nc: &mut NC,
-    pb: &mut PartitionedFilledBuffer,
-    rng: &mut RNG,
-    stream: &mut S,
-  ) -> crate::Result<()>
-  where
-    B: LeaseMut<[u8]>,
-    FB: LeaseMut<FrameBuffer<B>>,
-  {
-    let mut should_compress = false;
-    if frame.op_code() == OpCode::Close {
-      *ct = ConnectionState::Closed;
-    }
-    if !frame.op_code().is_control() {
-      if let Some(first) = frame.fb_mut().lease_mut().header_mut().first_mut() {
-        should_compress = nc.rsv1() != 0;
-        *first |= nc.rsv1();
-      }
-    }
-    if !should_compress || frame.op_code().is_control() {
-      _debug!(
-        "{:<5} - {:<5} - {:<25}: {:?}, {:?}",
-        <&str>::from(crate::misc::Role::from_is_client(IS_CLIENT)),
-        "Write",
-        "Unmasked",
-        misc::_truncated_slice(frame.fb().lease().frame(), 0..32),
-        frame.op_code()
-      );
-      Self::mask_frame(frame, rng);
-      _debug!(
-        "{:<5} - {:<5} - {:<25}: {:?}, {:?}",
-        <&str>::from(crate::misc::Role::from_is_client(IS_CLIENT)),
-        "Write",
-        "Masked",
-        misc::_truncated_slice(frame.fb().lease().frame(), 0..32),
-        frame.op_code()
-      );
-      stream.write_all(frame.fb().lease().frame()).await?;
-    } else {
-      _debug!(
-        "{:<5} - {:<5} - {:<25}: {:?}, {:?}",
-        <&str>::from(crate::misc::Role::from_is_client(IS_CLIENT)),
-        "Write",
-        "Uncompressed, Unmasked",
-        misc::_truncated_slice(frame.fb().lease().frame(), 0..32),
-        frame.op_code()
-      );
-      let mut compressed_frame = Self::compress_frame(frame, nc, pb)?;
-      _debug!(
-        "{:<5} - {:<5} - {:<25}: {:?}, {:?}",
-        <&str>::from(crate::misc::Role::from_is_client(IS_CLIENT)),
-        "Write",
-        "Compressed, Unmasked",
-        misc::_truncated_slice(compressed_frame.fb().frame(), 0..32),
-        frame.op_code()
-      );
-      Self::mask_frame(&mut compressed_frame, rng);
-      _debug!(
-        "{:<5} - {:<5} - {:<25}: {:?}, {:?}",
-        <&str>::from(crate::misc::Role::from_is_client(IS_CLIENT)),
-        "Write",
-        "Compressed, Masked",
-        misc::_truncated_slice(compressed_frame.fb().frame(), 0..32),
-        frame.op_code()
-      );
-      stream.write_all(compressed_frame.fb().frame()).await?;
-    };
-    Ok(())
-  }
-
-  fn expand_fb<'fb, B>(
-    buffer_len: &mut Option<usize>,
-    fb: &'fb mut FrameBuffer<B>,
-    payload_start_idx: usize,
-    written: usize,
-  ) -> crate::Result<&'fb mut [u8]>
-  where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
-  {
-    *buffer_len = buffer_len.and_then(|el| el.checked_mul(15)?.checked_div(10));
-    fb.expand_buffer(buffer_len.unwrap_or(usize::MAX))?;
-    let start = payload_start_idx.wrapping_add(written);
-    Ok(Self::begin_fb_bytes_mut(fb, start))
+      WebSocketWriterPart { phantom: PhantomData, writer_buffer },
+    )
   }
 
-  async fn fetch_frame_from_stream(&mut self) -> crate::Result<ReadFrameInfo> {
-    let mut read = self.wsb.lease_mut().nb._following_len();
-    let rfi = Self::fetch_header_from_stream(
-      self.max_payload_len,
-      &self.nc,
-      &mut self.wsb.lease_mut().nb,
-      &mut read,
-      &mut self.stream,
-    )
-    .await?;
-    if self.ct.is_closed() && rfi.op_code != OpCode::Close {
-      return Err(WebSocketError::ConnectionClosed.into());
-    }
-    Self::fetch_payload_from_stream(
-      &mut self.wsb.lease_mut().nb,
-      &mut read,
-      &rfi,
-      &mut self.stream,
+  /// Reads a frame from the stream.
+  ///
+  /// If a frame is made up of other sub-frames or continuations, then everything is collected
+  /// until all fragments are received.
+  #[inline]
+  pub async fn read_frame(&mut self) -> crate::Result<FrameMut<'_, IS_CLIENT>> {
+    let WebSocket { connection_state, curr_payload, max_payload_len, nc, rng, stream, wsb } = self;
+    let WebSocketBuffer {
+      network_buffer,
+      reader_buffer_first,
+      reader_buffer_second,
+      writer_buffer: _,
+    } = wsb.lease_mut();
+    let (frame, payload_ty) = web_socket_reader::read_frame_from_stream(
+      connection_state,
+      *max_payload_len,
+      nc,
+      network_buffer,
+      reader_buffer_first,
+      reader_buffer_second,
+      rng,
+      stream,
     )
     .await?;
-    let current_end_idx = self.wsb.lease().nb._current_end_idx();
-    self.wsb.lease_mut().nb._set_indices(
-      current_end_idx,
-      rfi.frame_len,
-      read.wrapping_sub(rfi.frame_len),
-    )?;
-    Ok(rfi)
-  }
-
-  async fn fetch_header_from_stream(
-    max_payload_len: usize,
-    nc: &NC,
-    pb: &mut PartitionedFilledBuffer,
-    read: &mut usize,
-    stream: &mut S,
-  ) -> crate::Result<ReadFrameInfo> {
-    let buffer = pb._following_trail_mut();
-
-    let first_two = _read_until::<2, S>(buffer, read, 0, stream).await?;
-
-    let rsv1 = first_two[0] & 0b0100_0000;
-    let rsv2 = first_two[0] & 0b0010_0000;
-    let rsv3 = first_two[0] & 0b0001_0000;
-
-    if rsv2 != 0 || rsv3 != 0 {
-      return Err(WebSocketError::InvalidCompressionHeaderParameter.into());
-    }
-
-    let should_decompress = if nc.rsv1() == 0 {
-      if rsv1 != 0 {
-        return Err(WebSocketError::InvalidCompressionHeaderParameter.into());
-      }
-      false
-    } else {
-      rsv1 != 0
-    };
-
-    let fin = first_two[0] & 0b1000_0000 != 0;
-    let length_code = first_two[1] & 0b0111_1111;
-    let op_code = op_code(first_two[0])?;
-
-    let (mut header_len, payload_len) = match length_code {
-      126 => (4, u16::from_be_bytes(_read_until::<2, S>(buffer, read, 2, stream).await?).into()),
-      127 => {
-        let payload_len = _read_until::<8, S>(buffer, read, 2, stream).await?;
-        (10, u64::from_be_bytes(payload_len).try_into()?)
-      }
-      _ => (2, length_code.into()),
-    };
-
-    let mut mask = None;
-    if !IS_CLIENT {
-      mask = Some(_read_until::<4, S>(buffer, read, header_len, stream).await?);
-      header_len = header_len.wrapping_add(4);
-    }
-
-    if op_code.is_control() && !fin {
-      return Err(WebSocketError::UnexpectedFragmentedControlFrame.into());
-    }
-    if op_code == OpCode::Ping && payload_len > MAX_CONTROL_FRAME_PAYLOAD_LEN {
-      return Err(WebSocketError::VeryLargeControlFrame.into());
-    }
-    if payload_len >= max_payload_len {
-      return Err(WebSocketError::VeryLargePayload.into());
-    }
-
-    Ok(ReadFrameInfo {
-      fin,
-      frame_len: header_len.wrapping_add(payload_len),
-      header_end_idx: header_len,
-      mask,
-      op_code,
-      payload_len,
-      should_decompress,
-    })
-  }
-
-  async fn fetch_payload_from_stream(
-    pb: &mut PartitionedFilledBuffer,
-    read: &mut usize,
-    rfi: &ReadFrameInfo,
-    stream: &mut S,
-  ) -> crate::Result<()> {
-    let mut is_payload_filled = false;
-    pb._expand_buffer(rfi.frame_len)?;
-    for _ in 0..=rfi.frame_len {
-      if *read >= rfi.frame_len {
-        is_payload_filled = true;
-        break;
-      }
-      *read = read.wrapping_add(
-        stream.read(pb._following_trail_mut().get_mut(*read..).unwrap_or_default()).await?,
-      );
-    }
-    if !is_payload_filled {
-      return Err(crate::Error::UnexpectedBufferState);
-    }
-    Ok(())
-  }
-
-  /// If this method returns `false`, then a `ping` frame was received and the caller should fetch
-  /// more external data in order to get the desired frame.
-  async fn manage_auto_reply(
-    ct: &mut ConnectionState,
-    curr_payload: &[u8],
-    nc: &mut NC,
-    op_code: OpCode,
-    pb: &mut PartitionedFilledBuffer,
-    rng: &mut RNG,
-    stream: &mut S,
-  ) -> crate::Result<bool> {
-    match op_code {
-      OpCode::Close if ct.is_open() => {
-        match curr_payload {
-          [] => {}
-          [_] => return Err(WebSocketError::InvalidCloseFrame.into()),
-          [a, b, rest @ ..] => {
-            let _ = from_utf8_basic(rest)?;
-            let is_not_allowed = !CloseCode::try_from(u16::from_be_bytes([*a, *b]))?.is_allowed();
-            if is_not_allowed || rest.len() > MAX_CONTROL_FRAME_PAYLOAD_LEN - 2 {
-              Self::write_control_frame(
-                ct,
-                &mut FrameControlArray::close_from_params(
-                  CloseCode::Protocol,
-                  FrameBuffer::default(),
-                  rest,
-                )?,
-                nc,
-                pb,
-                rng,
-                stream,
-              )
-              .await?;
-              return Err(WebSocketError::InvalidCloseFrame.into());
-            }
-          }
-        }
-        Self::write_control_frame(
-          ct,
-          &mut FrameControlArray::new_fin(FrameBuffer::default(), OpCode::Close, curr_payload)?,
-          nc,
-          pb,
-          rng,
-          stream,
-        )
-        .await?;
-        Ok(true)
-      }
-      OpCode::Ping => {
-        Self::write_control_frame(
-          ct,
-          &mut FrameControlArray::new_fin(FrameBuffer::default(), OpCode::Pong, curr_payload)?,
-          nc,
-          pb,
-          rng,
-          stream,
-        )
-        .await?;
-        Ok(false)
-      }
-      OpCode::Continuation | OpCode::Binary | OpCode::Close | OpCode::Pong | OpCode::Text => {
-        Ok(true)
-      }
-    }
+    *curr_payload = payload_ty;
+    Ok(frame)
   }
 
-  fn manage_continuation_text(
-    curr_payload: &[u8],
-    iuc: &mut Option<IncompleteUtf8Char>,
-  ) -> crate::Result<()> {
-    let tail = if let Some(mut incomplete) = iuc.take() {
-      let (rslt, remaining) = incomplete.complete(curr_payload);
-      match rslt {
-        Err(CompletionErr::HasInvalidBytes) => {
-          return Err(crate::Error::InvalidUTF8);
-        }
-        Err(CompletionErr::InsufficientInput) => {
-          let _ = iuc.replace(incomplete);
-          &[]
-        }
-        Ok(_) => remaining,
-      }
-    } else {
-      curr_payload
-    };
-    match from_utf8_ext(tail) {
-      Err(ExtUtf8Error::Incomplete { incomplete_ending_char, .. }) => {
-        *iuc = Some(incomplete_ending_char);
-      }
-      Err(ExtUtf8Error::Invalid { .. }) => {
-        return Err(crate::Error::InvalidUTF8);
-      }
-      Ok(_) => {}
-    }
-    Ok(())
-  }
-
-  fn mask_frame<B, FB>(frame: &mut Frame<FB, IS_CLIENT>, rng: &mut RNG)
-  where
-    B: LeaseMut<[u8]>,
-    FB: LeaseMut<FrameBuffer<B>>,
-  {
-    if IS_CLIENT {
-      if let [_, second_byte, .., a, b, c, d] = frame.fb_mut().lease_mut().header_mut() {
-        if !has_masked_frame(*second_byte) {
-          *second_byte |= 0b1000_0000;
-          let mask = rng.u8_4();
-          *a = mask[0];
-          *b = mask[1];
-          *c = mask[2];
-          *d = mask[3];
-          unmask(frame.fb_mut().lease_mut().payload_mut(), mask);
-        }
-      }
-    }
-  }
-
-  async fn read_continuation_frames<B>(
-    &mut self,
-    fb: &mut FrameBuffer<B>,
-    first_rfi: &ReadFrameInfo,
-    payload_start_idx: usize,
-    total_frame_len: &mut usize,
-    (first_text_cb, continuation_cb, copy_cb): ReadContinuationFramesCbs<B>,
-  ) -> crate::Result<()>
-  where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
-  {
-    let mut iuc = {
-      let (use_db, payload_len) = copy_cb(fb, first_rfi, *total_frame_len, self.wsb.lease_mut())?;
-      *total_frame_len = total_frame_len.wrapping_add(payload_len);
-      match first_rfi.op_code {
-        OpCode::Binary => None,
-        OpCode::Text => first_text_cb(Self::curr_payload_bytes(
-          &self.wsb.lease().db,
-          fb,
-          payload_start_idx..*total_frame_len,
-          use_db,
-        ))?,
-        OpCode::Close | OpCode::Continuation | OpCode::Ping | OpCode::Pong => {
-          return Err(WebSocketError::UnexpectedMessageFrame.into());
-        }
-      }
-    };
-    'continuation_frames: loop {
-      let (curr_payload, fin, op_code) = 'auto_reply: loop {
-        let prev = *total_frame_len;
-        let mut rfi = self.fetch_frame_from_stream().await?;
-        rfi.should_decompress = first_rfi.should_decompress;
-        let (should_use_db, payload_len) =
-          copy_cb(fb, &rfi, *total_frame_len, self.wsb.lease_mut())?;
-        *total_frame_len = total_frame_len.wrapping_add(payload_len);
-        let (db, nb) = self.wsb.lease_mut()._parts_mut();
-        let curr_payload = Self::curr_payload_bytes(db, fb, prev..*total_frame_len, should_use_db);
-        if Self::manage_auto_reply(
-          &mut self.ct,
-          curr_payload,
-          &mut self.nc,
-          rfi.op_code,
-          nb,
-          &mut self.rng,
-          &mut self.stream,
-        )
-        .await?
-        {
-          break 'auto_reply (curr_payload, rfi.fin, rfi.op_code);
-        }
-        *total_frame_len = prev;
-      };
-      match op_code {
-        OpCode::Continuation => {
-          continuation_cb(curr_payload, &mut iuc)?;
-          if fin {
-            break 'continuation_frames;
-          }
-        }
-        OpCode::Binary | OpCode::Close | OpCode::Ping | OpCode::Pong | OpCode::Text => {
-          return Err(WebSocketError::UnexpectedMessageFrame.into());
-        }
-      }
-    }
-    Ok(())
-  }
-
-  /// Returns `None` if the frame is single, otherwise, returns the necessary information to
-  /// continue fetching from the stream.
+  /// Writes a frame to the stream.
   #[inline]
-  async fn read_first_frame<B>(
-    &mut self,
-    fb: &mut FrameBuffer<B>,
-    header_buffer_len: u8,
-    payload_start_idx: usize,
-  ) -> crate::Result<Option<ReadFrameInfo>>
+  pub async fn write_frame<P>(&mut self, frame: &mut Frame<P, IS_CLIENT>) -> crate::Result<()>
   where
-    B: LeaseMut<[u8]> + LeaseMut<Vector<u8>>,
+    P: LeaseMut<[u8]>,
   {
-    let first_rfi = 'auto_reply: loop {
-      let rfi = self.fetch_frame_from_stream().await?;
-      if !rfi.fin {
-        break 'auto_reply rfi;
-      }
-      let pb = &mut self.wsb.lease_mut().nb;
-      let payload_len = if rfi.should_decompress {
-        Self::copy_from_compressed_pb_to_fb(fb, &mut self.nc, payload_start_idx, pb, &rfi)?
-      } else {
-        Self::copy_from_uncompressed_pb_to_fb(fb, payload_start_idx, pb, &rfi)?
-      };
-      define_fb_from_header_params::<_, IS_CLIENT>(
-        fb,
-        rfi.fin,
-        Some(header_buffer_len),
-        rfi.op_code,
-        payload_len,
-        self.nc.rsv1(),
-      )?;
-      let should_stop = Self::manage_auto_reply(
-        &mut self.ct,
-        fb.payload(),
-        &mut self.nc,
-        rfi.op_code,
-        &mut self.wsb.lease_mut().nb,
-        &mut self.rng,
-        &mut self.stream,
-      )
-      .await?;
-      if should_stop {
-        match rfi.op_code {
-          OpCode::Continuation => {
-            return Err(WebSocketError::UnexpectedMessageFrame.into());
-          }
-          OpCode::Text => {
-            let _ = from_utf8_basic(fb.payload())?;
-          }
-          OpCode::Binary | OpCode::Close | OpCode::Ping | OpCode::Pong => {}
-        }
-        return Ok(None);
-      }
-    };
-    Ok(Some(first_rfi))
-  }
-
-  async fn write_control_frame(
-    ct: &mut ConnectionState,
-    frame: &mut FrameControlArray<IS_CLIENT>,
-    nc: &mut NC,
-    pb: &mut PartitionedFilledBuffer,
-    rng: &mut RNG,
-    stream: &mut S,
-  ) -> crate::Result<()> {
-    Self::do_write_frame(ct, frame, nc, pb, rng, stream).await?;
+    let WebSocket { connection_state, nc, rng, stream, wsb, .. } = self;
+    let WebSocketBuffer { writer_buffer, .. } = wsb.lease_mut();
+    web_socket_writer::write_frame(connection_state, frame, nc, rng, stream, writer_buffer).await?;
     Ok(())
   }
 }
-
-/// Parameters of the frame read from a stream
-#[derive(Debug)]
-struct ReadFrameInfo {
-  fin: bool,
-  frame_len: usize,
-  header_end_idx: usize,
-  mask: Option<[u8; 4]>,
-  op_code: OpCode,
-  payload_len: usize,
-  should_decompress: bool,
-}
-
-const fn has_masked_frame(second_header_byte: u8) -> bool {
-  second_header_byte & 0b1000_0000 != 0
-}
-
-const fn header_placeholder<const IS_CLIENT: bool>() -> u8 {
-  if IS_CLIENT {
-    MAX_HDR_LEN_U8
-  } else {
-    MAX_HDR_LEN_U8 - 4
-  }
-}
-
-fn lease_as_slice<T, U>(instance: &T) -> &[U]
-where
-  T: Lease<[U]>,
-{
-  instance.lease()
-}
diff --git a/wtx/src/web_socket/compression.rs b/wtx/src/web_socket/compression.rs
index 869325a2..af96e0cb 100644
--- a/wtx/src/web_socket/compression.rs
+++ b/wtx/src/web_socket/compression.rs
@@ -51,13 +51,16 @@ impl<const IS_CLIENT: bool> Compression<IS_CLIENT> for () {
 
 /// Final compression parameters defined after a handshake.
 pub trait NegotiatedCompression {
+  /// If the implementation does nothing
+  const IS_NOOP: bool = false;
+
   /// Compress
   fn compress<O>(
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
-    rem_cb: impl FnMut(&mut O, usize) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
+    rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize>;
 
   /// Decompress
@@ -65,7 +68,7 @@ pub trait NegotiatedCompression {
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
     rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize>;
 
@@ -80,13 +83,15 @@ impl<T> NegotiatedCompression for &mut T
 where
   T: NegotiatedCompression,
 {
+  const IS_NOOP: bool = T::IS_NOOP;
+
   #[inline]
   fn compress<O>(
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
-    rem_cb: impl FnMut(&mut O, usize) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
+    rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     (**self).compress(input, output, begin_cb, rem_cb)
   }
@@ -96,7 +101,7 @@ where
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
     rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     (**self).decompress(input, output, begin_cb, rem_cb)
@@ -114,13 +119,15 @@ where
 }
 
 impl NegotiatedCompression for () {
+  const IS_NOOP: bool = true;
+
   #[inline]
   fn compress<O>(
     &mut self,
     _: &[u8],
     _: &mut O,
-    _: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
-    _: impl FnMut(&mut O, usize) -> Result<&mut [u8], VectorError>,
+    _: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
+    _: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     Ok(0)
   }
@@ -130,7 +137,7 @@ impl NegotiatedCompression for () {
     &mut self,
     _: &[u8],
     _: &mut O,
-    _: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
+    _: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
     _: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     Ok(0)
@@ -151,13 +158,15 @@ impl<T> NegotiatedCompression for Option<T>
 where
   T: NegotiatedCompression,
 {
+  const IS_NOOP: bool = T::IS_NOOP;
+
   #[inline]
   fn compress<O>(
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
-    rem_cb: impl FnMut(&mut O, usize) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
+    rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     match self {
       Some(el) => el.compress(input, output, begin_cb, rem_cb),
@@ -170,7 +179,7 @@ where
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
     rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     match self {
diff --git a/wtx/src/web_socket/compression/flate2.rs b/wtx/src/web_socket/compression/flate2.rs
index 0422f10d..896c31a4 100644
--- a/wtx/src/web_socket/compression/flate2.rs
+++ b/wtx/src/web_socket/compression/flate2.rs
@@ -121,8 +121,8 @@ impl NegotiatedCompression for NegotiatedFlate2 {
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
-    mut rem_cb: impl FnMut(&mut O, usize) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
+    mut rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     compress_or_decompress(
       input,
@@ -146,7 +146,7 @@ impl NegotiatedCompression for NegotiatedFlate2 {
     &mut self,
     input: &[u8],
     output: &mut O,
-    begin_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
+    begin_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
     rem_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   ) -> crate::Result<usize> {
     compress_or_decompress(
@@ -189,7 +189,7 @@ fn compress_or_decompress<NC, O>(
   nc: &mut NC,
   output: &mut O,
   reset: bool,
-  mut begin_output_cb: impl FnMut(&mut O) -> Result<&mut [u8], VectorError>,
+  mut begin_output_cb: impl FnMut(&mut O) -> crate::Result<&mut [u8]>,
   mut call_cb: impl FnMut(&mut NC, &[u8], &mut [u8]) -> crate::Result<()>,
   mut expand_output_cb: impl FnMut(&mut O, usize) -> crate::Result<&mut [u8]>,
   mut reset_cb: impl FnMut(&mut NC),
diff --git a/wtx/src/web_socket/frame.rs b/wtx/src/web_socket/frame.rs
index 0e591b3a..192f0413 100644
--- a/wtx/src/web_socket/frame.rs
+++ b/wtx/src/web_socket/frame.rs
@@ -1,63 +1,38 @@
 use crate::{
-  misc::{Lease, LeaseMut, SingleTypeStorage},
+  misc::{Lease, Vector},
   web_socket::{
-    close_code::CloseCode,
-    frame_buffer::{
-      FrameBufferControlArray, FrameBufferControlArrayMut, FrameBufferMut, FrameBufferVecMut,
-    },
-    misc::{define_fb_from_header_params, op_code, Expand},
-    FrameBuffer, FrameBufferVec, OpCode, WebSocketError, MAX_CONTROL_FRAME_PAYLOAD_LEN,
-    MAX_HDR_LEN_USIZE, MIN_HEADER_LEN_USIZE,
+    misc::fill_header_from_params, OpCode, MAX_CONTROL_PAYLOAD_LEN, MAX_HEADER_LEN_USIZE,
   },
 };
 use core::str;
 
-/// Composed by a [`FrameBufferControlArray`].
-pub type FrameControlArray<const IS_CLIENT: bool> = Frame<FrameBufferControlArray, IS_CLIENT>;
-/// Composed by a [`FrameBufferControlArrayMut`].
+/// Composed by an array with the maximum allowed size of a frame control.
+pub type FrameControlArray<const IS_CLIENT: bool> = Frame<[u8; MAX_CONTROL_PAYLOAD_LEN], IS_CLIENT>;
+/// Composed by an mutable array reference with the maximum allowed size of a frame control.
 pub type FrameControlArrayMut<'bytes, const IS_CLIENT: bool> =
-  Frame<FrameBufferControlArrayMut<'bytes>, IS_CLIENT>;
-/// Composed by a [`FrameBufferMut`].
-pub type FrameMut<'bytes, const IS_CLIENT: bool> = Frame<FrameBufferMut<'bytes>, IS_CLIENT>;
-/// Composed by a [`FrameBufferVec`].
-pub type FrameVec<const IS_CLIENT: bool> = Frame<FrameBufferVec, IS_CLIENT>;
-/// Composed by an mutable [`FrameBufferVecMut`] reference.
-pub type FrameVecMut<'bytes, const IS_CLIENT: bool> = Frame<FrameBufferVecMut<'bytes>, IS_CLIENT>;
-
-/// Composed by an mutable [`FrameBufferControlArray`] reference.
-pub type FrameMutControlArray<'fb, const IS_CLIENT: bool> =
-  Frame<&'fb mut FrameBufferControlArray, IS_CLIENT>;
-/// Composed by an mutable [`FrameBufferControlArrayMut`] reference.
-pub type FrameMutControlArrayMut<'fb, const IS_CLIENT: bool> =
-  Frame<&'fb mut FrameBufferControlArray, IS_CLIENT>;
-/// Composed by an mutable [`FrameBufferMut`] reference.
-pub type FrameMutMut<'bytes, 'fb, const IS_CLIENT: bool> =
-  Frame<&'fb mut FrameBufferMut<'bytes>, IS_CLIENT>;
-/// Composed by an mutable [`FrameBufferVec`] reference.
-pub type FrameMutVec<'fb, const IS_CLIENT: bool> = Frame<&'fb mut FrameBufferVec, IS_CLIENT>;
-/// Composed by an mutable [`FrameBufferVecMut`] reference.
-pub type FrameMutVecMut<'bytes, 'fb, const IS_CLIENT: bool> =
-  Frame<&'fb mut FrameBufferVecMut<'bytes>, IS_CLIENT>;
+  Frame<&'bytes mut [u8; MAX_CONTROL_PAYLOAD_LEN], IS_CLIENT>;
+/// Composed by a sequence of mutable bytes.
+pub type FrameMut<'bytes, const IS_CLIENT: bool> = Frame<&'bytes mut [u8], IS_CLIENT>;
+/// Composed by a sequence of immutable bytes.
+pub type FrameRef<'bytes, const IS_CLIENT: bool> = Frame<&'bytes [u8], IS_CLIENT>;
+/// Composed by an owned vector.
+pub type FrameVector<const IS_CLIENT: bool> = Frame<Vector<u8>, IS_CLIENT>;
+/// Composed by a mutable vector reference.
+pub type FrameVectorMut<'bytes, const IS_CLIENT: bool> = Frame<&'bytes mut Vector<u8>, IS_CLIENT>;
+/// Composed by a immutable vector reference.
+pub type FrameVectorRef<'bytes, const IS_CLIENT: bool> = Frame<&'bytes Vector<u8>, IS_CLIENT>;
 
 /// Unit of generic data used for communication.
 #[derive(Debug)]
-pub struct Frame<FB, const IS_CLIENT: bool> {
-  fb: FB,
+pub struct Frame<P, const IS_CLIENT: bool> {
   fin: bool,
+  header: [u8; MAX_HEADER_LEN_USIZE],
+  header_len: u8,
   op_code: OpCode,
+  payload: P,
 }
 
-impl<FB, const IS_CLIENT: bool> Frame<FB, IS_CLIENT> {
-  /// Contains the raw bytes that compose this frame.
-  #[inline]
-  pub fn fb(&self) -> &FB {
-    &self.fb
-  }
-
-  pub(crate) fn fb_mut(&mut self) -> &mut FB {
-    &mut self.fb
-  }
-
+impl<P, const IS_CLIENT: bool> Frame<P, IS_CLIENT> {
   /// Indicates if this is the final frame in a message.
   #[inline]
   pub fn fin(&self) -> bool {
@@ -69,106 +44,84 @@ impl<FB, const IS_CLIENT: bool> Frame<FB, IS_CLIENT> {
   pub fn op_code(&self) -> OpCode {
     self.op_code
   }
-}
 
-impl<B, FB, const IS_CLIENT: bool> Frame<FB, IS_CLIENT>
-where
-  B: Lease<[u8]>,
-  FB: Lease<FrameBuffer<B>> + SingleTypeStorage<Item = B>,
-{
-  /// Creates a new instance based on the contained bytes of `fb`.
+  /// Frame's content.
   #[inline]
-  pub fn from_fb(fb: FB) -> crate::Result<Self> {
-    let header = fb.lease().header();
-    let len = header.len();
-    let has_valid_header = (MIN_HEADER_LEN_USIZE..=MAX_HDR_LEN_USIZE).contains(&len);
-    let (true, Some(first_header_byte)) = (has_valid_header, header.first().copied()) else {
-      return Err(WebSocketError::InvalidFrameHeaderBounds.into());
-    };
-    Ok(Self { fb, fin: first_header_byte & 0b1000_0000 != 0, op_code: op_code(first_header_byte)? })
+  pub fn payload(&self) -> &P {
+    &self.payload
   }
 
-  /// If the frame is of type [`OpCode::Text`], returns its payload interpreted as a string.
+  /// Mutable version of [`Self::payload`].
   #[inline]
-  pub fn text_payload<'this>(&'this self) -> Option<&'this str>
-  where
-    B: 'this,
-  {
-    self.op_code.is_text().then(|| {
-      // SAFETY: UTF-8 data is always verified when read from a stream.
-      unsafe { str::from_utf8_unchecked(self.fb.lease().payload()) }
-    })
+  pub fn payload_mut(&mut self) -> &mut P {
+    &mut self.payload
   }
-}
 
-impl<B, FB, const IS_CLIENT: bool> Frame<FB, IS_CLIENT>
-where
-  B: Expand + LeaseMut<[u8]>,
-  FB: LeaseMut<FrameBuffer<B>> + SingleTypeStorage<Item = B>,
-{
-  /// Creates based on the individual parameters that compose a close frame.
-  ///
-  /// `reason` is capped based on the maximum allowed size of a control frame minus 2.
   #[inline]
-  pub fn close_from_params(code: CloseCode, fb: FB, reason: &[u8]) -> crate::Result<Self> {
-    let reason_len = reason.len().min(MAX_CONTROL_FRAME_PAYLOAD_LEN - 2);
-    let payload_len = reason_len.wrapping_add(2);
-    Self::build_frame(fb, true, OpCode::Close, payload_len, |local_fb| {
-      let payload = local_fb.lease_mut().payload_mut();
-      payload.get_mut(..2).unwrap_or_default().copy_from_slice(&u16::from(code).to_be_bytes());
-      payload
-        .get_mut(2..)
-        .unwrap_or_default()
-        .copy_from_slice(reason.get(..reason_len).unwrap_or_default());
-      Ok(())
-    })
+  pub(crate) fn header(&self) -> &[u8] {
+    // SAFETY: `header_len` is always less or equal to `MAX_HEADER_LEN_USIZE`
+    unsafe { self.header.get(..self.header_len.into()).unwrap_unchecked() }
+  }
+
+  /// Header and payload bytes
+  #[inline]
+  pub fn header_and_payload(&self) -> (&[u8], &P) {
+    (self.header(), &self.payload)
+  }
+
+  #[inline]
+  pub(crate) fn header_and_payload_mut(&mut self) -> (&mut [u8], &mut P) {
+    // SAFETY: `header_len` is always less or equal to `MAX_HEADER_LEN_USIZE`
+    let header = unsafe { self.header.get_mut(..self.header_len.into()).unwrap_unchecked() };
+    (header, &mut self.payload)
+  }
+
+  #[inline]
+  pub(crate) fn header_mut(&mut self) -> &mut [u8] {
+    self.header_and_payload_mut().0
+  }
+
+  #[inline]
+  pub(crate) fn header_first_two_mut(&mut self) -> [&mut u8; 2] {
+    let [a, b, ..] = &mut self.header;
+    [a, b]
   }
+}
 
+impl<P, const IS_CLIENT: bool> Frame<P, IS_CLIENT>
+where
+  P: Lease<[u8]>,
+{
   /// Creates a new instance that is considered final.
   #[inline]
-  pub fn new_fin(fb: FB, op_code: OpCode, payload: &[u8]) -> crate::Result<Self> {
-    Self::new(fb, true, op_code, payload)
+  pub fn new_fin(op_code: OpCode, payload: P) -> Self {
+    Self::new(true, op_code, payload, 0)
   }
 
   /// Creates a new instance that is meant to be a continuation of previous frames.
   #[inline]
-  pub fn new_unfin(fb: FB, op_code: OpCode, payload: &[u8]) -> crate::Result<Self> {
-    Self::new(fb, false, op_code, payload)
+  pub fn new_unfin(op_code: OpCode, payload: P) -> Self {
+    Self::new(false, op_code, payload, 0)
   }
 
-  fn build_frame(
-    mut fb: FB,
-    fin: bool,
-    op_code: OpCode,
-    payload_len: usize,
-    cb: impl FnOnce(&mut FB) -> crate::Result<()>,
-  ) -> crate::Result<Self> {
-    fb.lease_mut().clear();
-    fb.lease_mut().buffer_mut().expand(MAX_HDR_LEN_USIZE.saturating_add(payload_len))?;
-    define_fb_from_header_params::<_, IS_CLIENT>(
-      fb.lease_mut(),
-      fin,
-      None,
-      op_code,
-      payload_len,
-      0,
-    )?;
-    cb(&mut fb)?;
-    Ok(Self { fb, fin, op_code })
+  /// If the frame is of type [`OpCode::Text`], returns its payload interpreted as a string.
+  #[inline]
+  pub fn text_payload(&self) -> Option<&str> {
+    self.op_code.is_text().then(|| {
+      // SAFETY: UTF-8 data is always verified when read from a stream.
+      unsafe { str::from_utf8_unchecked(self.payload.lease()) }
+    })
   }
 
-  fn new(fb: FB, fin: bool, op_code: OpCode, payload: &[u8]) -> crate::Result<Self> {
+  #[inline]
+  pub(crate) fn new(fin: bool, op_code: OpCode, payload: P, rsv1: u8) -> Self {
+    let mut header = [0; MAX_HEADER_LEN_USIZE];
     let payload_len = if op_code.is_control() {
-      payload.len().min(MAX_CONTROL_FRAME_PAYLOAD_LEN)
+      payload.lease().len().min(MAX_CONTROL_PAYLOAD_LEN)
     } else {
-      payload.len()
+      payload.lease().len()
     };
-    Self::build_frame(fb, fin, op_code, payload_len, |local_fb| {
-      local_fb
-        .lease_mut()
-        .payload_mut()
-        .copy_from_slice(payload.get(..payload_len).unwrap_or_default());
-      Ok(())
-    })
+    let len = fill_header_from_params::<IS_CLIENT>(fin, &mut header, op_code, payload_len, rsv1);
+    Self { fin, header, header_len: len, op_code, payload }
   }
 }
diff --git a/wtx/src/web_socket/frame_buffer.rs b/wtx/src/web_socket/frame_buffer.rs
deleted file mode 100644
index ad6841de..00000000
--- a/wtx/src/web_socket/frame_buffer.rs
+++ /dev/null
@@ -1,262 +0,0 @@
-use crate::{
-  misc::{BufferParam, Lease, LeaseMut, SingleTypeStorage, Vector, VectorError, _unreachable},
-  web_socket::{WebSocketError, DFLT_FRAME_BUFFER_VEC_LEN, MAX_CONTROL_FRAME_LEN, MAX_HDR_LEN_U8},
-};
-
-/// Composed by an array with the maximum allowed size of a frame control.
-pub type FrameBufferControlArray = FrameBuffer<[u8; MAX_CONTROL_FRAME_LEN]>;
-/// Composed by an mutable array reference with the maximum allowed size of a frame control.
-pub type FrameBufferControlArrayMut<'bytes> = FrameBuffer<&'bytes mut [u8; MAX_CONTROL_FRAME_LEN]>;
-/// Composed by a sequence of mutable bytes.
-pub type FrameBufferMut<'bytes> = FrameBuffer<&'bytes mut [u8]>;
-/// Composed by an owned vector.
-pub type FrameBufferVec = FrameBuffer<Vector<u8>>;
-/// Composed by a mutable vector reference.
-pub type FrameBufferVecMut<'bytes> = FrameBuffer<&'bytes mut Vector<u8>>;
-
-/// Concentrates all data necessary to read or write to a stream.
-//
-// ```
-// [ prefix | header | payload | suffix ]
-// ```
-#[derive(Debug)]
-pub struct FrameBuffer<B> {
-  header_begin_idx: u8,
-  header_end_idx: u8,
-  payload_end_idx: usize,
-  // Tail field to hopefully help transforms
-  buffer: B,
-}
-
-impl<B> FrameBuffer<B> {
-  /// The underlying byte collection.
-  #[inline]
-  pub fn buffer(&self) -> &B {
-    &self.buffer
-  }
-
-  /// The indices that represent all frame parts contained in the underlying byte collection.
-  ///
-  /// ```rust
-  /// let fb = wtx::web_socket::FrameBufferVec::default();
-  /// let (header_begin_idx, header_end_idx, payload_end_idx) = fb.indcs();
-  /// assert_eq!(
-  ///   fb.buffer().get(header_begin_idx.into()..header_end_idx.into()),
-  ///   Some(fb.header())
-  /// );
-  /// assert_eq!(fb.buffer().get(header_end_idx.into()..payload_end_idx), Some(fb.payload()));
-  /// ```
-  #[inline]
-  pub fn indcs(&self) -> (u8, u8, usize) {
-    (self.header_begin_idx, self.header_end_idx, self.payload_end_idx)
-  }
-
-  pub(crate) fn buffer_mut(&mut self) -> &mut B {
-    &mut self.buffer
-  }
-
-  pub(crate) fn clear(&mut self) {
-    self.header_begin_idx = 0;
-    self.header_end_idx = 0;
-    self.payload_end_idx = 0;
-  }
-
-  pub(crate) fn header_len(&self) -> u8 {
-    self.header_end_idx.saturating_sub(self.header_begin_idx)
-  }
-
-  fn header_end_idx_from_parts(header_begin_idx: u8, header_len: u8) -> u8 {
-    header_begin_idx.saturating_add(header_len)
-  }
-
-  fn payload_end_idx_from_parts(header_end: u8, payload_len: usize) -> usize {
-    usize::from(header_end).wrapping_add(payload_len)
-  }
-}
-
-impl<B> FrameBuffer<B>
-where
-  B: Lease<[u8]>,
-{
-  /// Creates a new instance from the given `buffer`.
-  #[inline]
-  pub fn new(buffer: B) -> Self {
-    Self { header_begin_idx: 0, header_end_idx: 0, payload_end_idx: 0, buffer }
-  }
-
-  /// Sequence of bytes that composes the frame header.
-  #[inline]
-  pub fn header(&self) -> &[u8] {
-    if let Some(el) =
-      self.buffer.lease().get(self.header_begin_idx.into()..self.header_end_idx.into())
-    {
-      el
-    } else {
-      _unreachable()
-    }
-  }
-
-  /// Sequence of bytes that composes the frame payload.
-  #[inline]
-  pub fn payload(&self) -> &[u8] {
-    if let Some(el) = self.buffer.lease().get(self.header_end_idx.into()..self.payload_end_idx) {
-      el
-    } else {
-      _unreachable()
-    }
-  }
-
-  pub(crate) fn frame(&self) -> &[u8] {
-    if let Some(el) = self.buffer.lease().get(self.header_begin_idx.into()..self.payload_end_idx) {
-      el
-    } else {
-      _unreachable()
-    }
-  }
-
-  pub(crate) fn set_indices(
-    &mut self,
-    header_begin_idx: u8,
-    header_len: u8,
-    payload_len: usize,
-  ) -> crate::Result<()> {
-    let header_end_idx = Self::header_end_idx_from_parts(header_begin_idx, header_len);
-    let payload_end_idx = Self::payload_end_idx_from_parts(header_end_idx, payload_len);
-    if header_len > MAX_HDR_LEN_U8 || payload_end_idx > self.buffer.lease().len() {
-      return Err(WebSocketError::InvalidPayloadBounds.into());
-    }
-    self.header_begin_idx = header_begin_idx;
-    self.header_end_idx = header_end_idx;
-    self.payload_end_idx = payload_end_idx;
-    Ok(())
-  }
-}
-
-impl<B> FrameBuffer<B>
-where
-  B: LeaseMut<[u8]>,
-{
-  pub(crate) fn header_mut(&mut self) -> &mut [u8] {
-    let range = self.header_begin_idx.into()..self.header_end_idx.into();
-    if let Some(el) = self.buffer.lease_mut().get_mut(range) {
-      el
-    } else {
-      _unreachable()
-    }
-  }
-
-  pub(crate) fn payload_mut(&mut self) -> &mut [u8] {
-    let range = self.header_end_idx.into()..self.payload_end_idx;
-    if let Some(el) = self.buffer.lease_mut().get_mut(range) {
-      el
-    } else {
-      _unreachable()
-    }
-  }
-}
-
-impl<B> FrameBuffer<B>
-where
-  B: LeaseMut<Vector<u8>>,
-{
-  pub(crate) fn expand_buffer(&mut self, new_len: usize) -> Result<(), VectorError> {
-    if new_len > self.buffer.lease_mut().len() {
-      self.buffer.lease_mut().expand(BufferParam::Len(new_len), 0)?;
-    }
-    Ok(())
-  }
-}
-
-impl FrameBufferVec {
-  /// Creates a new instance with pre-allocated bytes.
-  #[inline]
-  pub fn with_capacity(n: usize) -> Self {
-    Self { header_begin_idx: 0, header_end_idx: 0, payload_end_idx: 0, buffer: _vector![0; n] }
-  }
-}
-
-impl<B> SingleTypeStorage for FrameBuffer<B> {
-  type Item = B;
-}
-
-impl Default for FrameBufferControlArray {
-  #[inline]
-  fn default() -> Self {
-    Self {
-      header_begin_idx: 0,
-      header_end_idx: 0,
-      payload_end_idx: 0,
-      buffer: [0; MAX_CONTROL_FRAME_LEN],
-    }
-  }
-}
-
-impl Default for FrameBufferVec {
-  #[inline]
-  fn default() -> Self {
-    Self {
-      header_begin_idx: 0,
-      header_end_idx: 0,
-      payload_end_idx: 0,
-      buffer: _vector![0; DFLT_FRAME_BUFFER_VEC_LEN],
-    }
-  }
-}
-
-impl<'fb, B> From<&'fb mut FrameBuffer<B>> for FrameBufferMut<'fb>
-where
-  B: LeaseMut<[u8]>,
-{
-  #[inline]
-  fn from(from: &'fb mut FrameBuffer<B>) -> Self {
-    Self {
-      header_begin_idx: from.header_begin_idx,
-      header_end_idx: from.header_end_idx,
-      payload_end_idx: from.payload_end_idx,
-      buffer: from.buffer.lease_mut(),
-    }
-  }
-}
-
-impl<'bytes, 'fb> From<&'fb mut FrameBufferVec> for FrameBufferVecMut<'bytes>
-where
-  'fb: 'bytes,
-{
-  #[inline]
-  fn from(from: &'fb mut FrameBufferVec) -> Self {
-    Self {
-      header_begin_idx: from.header_begin_idx,
-      header_end_idx: from.header_end_idx,
-      payload_end_idx: from.payload_end_idx,
-      buffer: &mut from.buffer,
-    }
-  }
-}
-
-impl From<Vector<u8>> for FrameBufferVec {
-  #[inline]
-  fn from(from: Vector<u8>) -> Self {
-    Self::new(from)
-  }
-}
-
-impl<'bytes> From<&'bytes mut Vector<u8>> for FrameBufferVecMut<'bytes> {
-  #[inline]
-  fn from(from: &'bytes mut Vector<u8>) -> Self {
-    Self::new(from)
-  }
-}
-
-impl<B> Lease<FrameBuffer<B>> for FrameBuffer<B> {
-  #[inline]
-  fn lease(&self) -> &FrameBuffer<B> {
-    self
-  }
-}
-
-impl<B> LeaseMut<FrameBuffer<B>> for FrameBuffer<B> {
-  #[inline]
-  fn lease_mut(&mut self) -> &mut FrameBuffer<B> {
-    self
-  }
-}
diff --git a/wtx/src/web_socket/handshake.rs b/wtx/src/web_socket/handshake.rs
index 8866caf1..696344bd 100644
--- a/wtx/src/web_socket/handshake.rs
+++ b/wtx/src/web_socket/handshake.rs
@@ -3,7 +3,9 @@ mod tests;
 
 use crate::{
   http::{GenericHeader as _, GenericRequest as _, HttpError, KnownHeaderName, Method},
-  misc::{bytes_split1, FilledBufferWriter, LeaseMut, Rng, Stream, UriRef, VectorError},
+  misc::{
+    bytes_split1, FilledBufferWriter, LeaseMut, Rng, Stream, UriRef, VectorError, Xorshift64,
+  },
   web_socket::{
     compression::NegotiatedCompression, misc::_trim_bytes, Compression, WebSocketBuffer,
     WebSocketClient, WebSocketError, WebSocketServer,
@@ -16,10 +18,9 @@ use sha1::{Digest, Sha1};
 const MAX_READ_LEN: usize = 2 * 1024;
 const MAX_READ_HEADER_LEN: usize = 64;
 
-impl<NC, RNG, S, WSB> WebSocketServer<NC, RNG, S, WSB>
+impl<NC, S, WSB> WebSocketServer<NC, S, WSB>
 where
   NC: NegotiatedCompression,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
@@ -27,7 +28,7 @@ where
   #[inline]
   pub async fn accept<C, E>(
     compression: C,
-    rng: RNG,
+    rng: Xorshift64,
     mut stream: S,
     mut wsb: WSB,
     req_cb: impl FnOnce(&Request<'_, '_>) -> Result<(), E>,
@@ -37,8 +38,8 @@ where
     E: From<crate::Error>,
   {
     wsb.lease_mut()._clear();
-    let nb = &mut wsb.lease_mut().nb;
-    nb._expand_buffer(MAX_READ_LEN).map_err(From::from)?;
+    let nb = &mut wsb.lease_mut().network_buffer;
+    nb._reserve(MAX_READ_LEN).map_err(From::from)?;
     let mut read = 0;
     loop {
       let read_buffer = nb._buffer_mut().get_mut(read..).unwrap_or_default();
@@ -93,10 +94,9 @@ where
   }
 }
 
-impl<NC, RNG, S, WSB> WebSocketClient<NC, RNG, S, WSB>
+impl<NC, S, WSB> WebSocketClient<NC, S, WSB>
 where
   NC: NegotiatedCompression,
-  RNG: Rng,
   S: Stream,
   WSB: LeaseMut<WebSocketBuffer>,
 {
@@ -105,12 +105,12 @@ where
   pub async fn connect<'headers, C, E>(
     compression: C,
     headers: impl IntoIterator<Item = (&'headers [u8], &'headers [u8])>,
-    mut rng: RNG,
+    mut rng: Xorshift64,
     mut stream: S,
     uri: &UriRef<'_>,
     mut wsb: WSB,
     res_cb: impl FnOnce(&Response<'_, '_>) -> Result<(), E>,
-  ) -> Result<WebSocketClient<C::NegotiatedCompression, RNG, S, WSB>, E>
+  ) -> Result<WebSocketClient<C::NegotiatedCompression, S, WSB>, E>
   where
     C: Compression<true, NegotiatedCompression = NC>,
     E: From<crate::Error>,
@@ -118,8 +118,8 @@ where
     wsb.lease_mut()._clear();
     let key_buffer = &mut [0; 26];
     let key = {
-      let nb = &mut wsb.lease_mut().nb;
-      nb._expand_buffer(MAX_READ_LEN).map_err(From::from)?;
+      let nb = &mut wsb.lease_mut().network_buffer;
+      nb._reserve(MAX_READ_LEN).map_err(From::from)?;
       {
         let fbw = &mut nb.into();
         let key =
@@ -130,7 +130,7 @@ where
     };
     let mut read = 0;
     let (compression, len) = loop {
-      let nb = &mut wsb.lease_mut().nb;
+      let nb = &mut wsb.lease_mut().network_buffer;
       let local_read = stream.read(nb._buffer_mut().get_mut(read..).unwrap_or_default()).await?;
       if local_read == 0 {
         return Err(crate::Error::UnexpectedStreamReadEOF.into());
@@ -158,7 +158,7 @@ where
       }
       break (compression.negotiate(res.headers.iter())?, len);
     };
-    wsb.lease_mut().nb._set_indices(0, len, read.wrapping_sub(len))?;
+    wsb.lease_mut().network_buffer._set_indices(0, len, read.wrapping_sub(len))?;
     Ok(WebSocketClient::new(compression, rng, stream, wsb)?)
   }
 }
diff --git a/wtx/src/web_socket/misc.rs b/wtx/src/web_socket/misc.rs
index cf43aeac..b3065eeb 100644
--- a/wtx/src/web_socket/misc.rs
+++ b/wtx/src/web_socket/misc.rs
@@ -1,70 +1,38 @@
-pub(crate) mod expand;
-
-use crate::{
-  misc::LeaseMut,
-  web_socket::{FrameBuffer, OpCode, WebSocketError},
-};
+use crate::web_socket::{CloseCode, OpCode, MAX_HEADER_LEN_USIZE};
 use core::ops::Range;
-pub use expand::Expand;
 
-pub(crate) fn define_fb_from_header_params<B, const IS_CLIENT: bool>(
-  fb: &mut FrameBuffer<B>,
-  fin: bool,
-  header_buffer_len: Option<u8>,
-  op_code: OpCode,
-  payload_len: usize,
-  rsv1: u8,
-) -> crate::Result<()>
-where
-  B: LeaseMut<[u8]>,
-{
-  let new_header_len = header_len_from_payload_len::<IS_CLIENT>(payload_len);
-  let (buffer, header_begin_idx) = if let Some(el) = header_buffer_len {
-    let header_begin_idx = el.saturating_sub(new_header_len);
-    let buffer = fb.buffer_mut().lease_mut().get_mut(header_begin_idx.into()..).unwrap_or_default();
-    (buffer, header_begin_idx)
-  } else {
-    (fb.buffer_mut().lease_mut(), 0)
+/// The first two bytes of `payload` are filled with `code`. Does nothing if `payload` is
+/// less than 2 bytes.
+#[inline]
+pub fn fill_with_close_code(code: CloseCode, payload: &mut [u8]) {
+  let [a, b, ..] = payload else {
+    return;
   };
-  let _ = copy_header_params_to_buffer::<IS_CLIENT>(buffer, fin, op_code, payload_len, rsv1)?;
-  fb.set_indices(header_begin_idx, new_header_len, payload_len)?;
-  Ok(())
-}
-
-pub(crate) fn op_code(first_header_byte: u8) -> crate::Result<OpCode> {
-  OpCode::try_from(first_header_byte & 0b0000_1111)
-}
-
-pub(crate) fn _trim_bytes(bytes: &[u8]) -> &[u8] {
-  _trim_bytes_end(_trim_bytes_begin(bytes))
-}
-
-pub(crate) fn _truncated_slice<T>(slice: &[T], range: Range<usize>) -> &[T] {
-  let start = range.start;
-  let end = range.end.min(slice.len());
-  slice.get(start..end).unwrap_or_default()
+  let [c, d] = u16::from(code).to_be_bytes();
+  *a = c;
+  *b = d;
 }
 
-fn copy_header_params_to_buffer<const IS_CLIENT: bool>(
-  buffer: &mut [u8],
+#[inline]
+pub(crate) fn fill_header_from_params<const IS_CLIENT: bool>(
   fin: bool,
+  header: &mut [u8; MAX_HEADER_LEN_USIZE],
   op_code: OpCode,
   payload_len: usize,
   rsv1: u8,
-) -> crate::Result<u8> {
+) -> u8 {
+  #[inline]
   fn first_header_byte(fin: bool, op_code: OpCode, rsv1: u8) -> u8 {
     u8::from(fin) << 7 | rsv1 | u8::from(op_code)
   }
 
+  #[inline]
   fn manage_mask<const IS_CLIENT: bool, const N: u8>(
-    rest: &mut [u8],
     second_byte: &mut u8,
-  ) -> crate::Result<u8> {
-    Ok(if IS_CLIENT {
+    [a, b, c, d]: [&mut u8; 4],
+  ) -> u8 {
+    if IS_CLIENT {
       *second_byte &= 0b0111_1111;
-      let [a, b, c, d, ..] = rest else {
-        return Err(WebSocketError::InvalidFrameHeaderBounds.into());
-      };
       *a = 0;
       *b = 0;
       *c = 0;
@@ -72,61 +40,62 @@ fn copy_header_params_to_buffer<const IS_CLIENT: bool>(
       N.wrapping_add(4)
     } else {
       N
-    })
+    }
   }
 
   match payload_len {
     0..=125 => {
-      if let ([a, b, rest @ ..], Ok(u8_len)) = (buffer, u8::try_from(payload_len)) {
-        *a = first_header_byte(fin, op_code, rsv1);
-        *b = u8_len;
-        return manage_mask::<IS_CLIENT, 2>(rest, b);
-      }
+      let [a, b, c, d, e, f, ..] = header;
+      *a = first_header_byte(fin, op_code, rsv1);
+      *b = u8::try_from(payload_len).unwrap_or_default();
+      manage_mask::<IS_CLIENT, 2>(b, [c, d, e, f])
     }
     126..=0xFFFF => {
-      let rslt = u16::try_from(payload_len).map(u16::to_be_bytes);
-      if let ([a, b, c, d, rest @ ..], Ok([len_c, len_d])) = (buffer, rslt) {
-        *a = first_header_byte(fin, op_code, rsv1);
-        *b = 126;
-        *c = len_c;
-        *d = len_d;
-        return manage_mask::<IS_CLIENT, 4>(rest, b);
-      }
+      let [len_c, len_d] = u16::try_from(payload_len).map(u16::to_be_bytes).unwrap_or_default();
+      let [a, b, c, d, e, f, g, h, ..] = header;
+      *a = first_header_byte(fin, op_code, rsv1);
+      *b = 126;
+      *c = len_c;
+      *d = len_d;
+      manage_mask::<IS_CLIENT, 4>(b, [e, f, g, h])
     }
     _ => {
-      if let (
-        [a, b, c, d, e, f, g, h, i, j, rest @ ..],
-        Ok([len_c, len_d, len_e, len_f, len_g, len_h, len_i, len_j]),
-      ) = (buffer, u64::try_from(payload_len).map(u64::to_be_bytes))
-      {
-        *a = first_header_byte(fin, op_code, rsv1);
-        *b = 127;
-        *c = len_c;
-        *d = len_d;
-        *e = len_e;
-        *f = len_f;
-        *g = len_g;
-        *h = len_h;
-        *i = len_i;
-        *j = len_j;
-        return manage_mask::<IS_CLIENT, 10>(rest, b);
-      }
+      let len = u64::try_from(payload_len).map(u64::to_be_bytes).unwrap_or_default();
+      let [len_c, len_d, len_e, len_f, len_g, len_h, len_i, len_j] = len;
+      let [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = header;
+      *a = first_header_byte(fin, op_code, rsv1);
+      *b = 127;
+      *c = len_c;
+      *d = len_d;
+      *e = len_e;
+      *f = len_f;
+      *g = len_g;
+      *h = len_h;
+      *i = len_i;
+      *j = len_j;
+      manage_mask::<IS_CLIENT, 10>(b, [k, l, m, n])
     }
   }
+}
 
-  Err(WebSocketError::InvalidFrameHeaderBounds.into())
+#[inline]
+pub(crate) fn op_code(first_header_byte: u8) -> crate::Result<OpCode> {
+  OpCode::try_from(first_header_byte & 0b0000_1111)
 }
 
-fn header_len_from_payload_len<const IS_CLIENT: bool>(payload_len: usize) -> u8 {
-  let mask_len = if IS_CLIENT { 4 } else { 0 };
-  let n: u8 = match payload_len {
-    0..=125 => 2,
-    126..=0xFFFF => 4,
-    _ => 10,
-  };
-  n.wrapping_add(mask_len)
+#[inline]
+pub(crate) fn _trim_bytes(bytes: &[u8]) -> &[u8] {
+  _trim_bytes_end(_trim_bytes_begin(bytes))
+}
+
+#[inline]
+pub(crate) fn _truncated_slice<T>(slice: &[T], range: Range<usize>) -> &[T] {
+  let start = range.start;
+  let end = range.end.min(slice.len());
+  slice.get(start..end).unwrap_or_default()
 }
 
+#[inline]
 fn _trim_bytes_begin(mut bytes: &[u8]) -> &[u8] {
   while let [first, rest @ ..] = bytes {
     if first.is_ascii_whitespace() {
@@ -138,6 +107,7 @@ fn _trim_bytes_begin(mut bytes: &[u8]) -> &[u8] {
   bytes
 }
 
+#[inline]
 fn _trim_bytes_end(mut bytes: &[u8]) -> &[u8] {
   while let [rest @ .., last] = bytes {
     if last.is_ascii_whitespace() {
diff --git a/wtx/src/web_socket/misc/expand.rs b/wtx/src/web_socket/misc/expand.rs
deleted file mode 100644
index e90ec8bb..00000000
--- a/wtx/src/web_socket/misc/expand.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use crate::misc::{BufferParam, Vector};
-
-/// Internal trait not intended for public usage
-pub trait Expand {
-  /// Internal method not intended for public usage
-  fn expand(&mut self, len: usize) -> crate::Result<()>;
-}
-
-impl<T> Expand for &mut T
-where
-  T: Expand,
-{
-  #[inline]
-  fn expand(&mut self, len: usize) -> crate::Result<()> {
-    (*self).expand(len)
-  }
-}
-
-impl<T> Expand for Vector<T>
-where
-  T: Clone + Default,
-{
-  #[inline]
-  fn expand(&mut self, len: usize) -> crate::Result<()> {
-    self.expand(BufferParam::Len(len), T::default())?;
-    Ok(())
-  }
-}
-
-impl<T> Expand for &mut [T] {
-  #[inline]
-  fn expand(&mut self, _: usize) -> crate::Result<()> {
-    Ok(())
-  }
-}
-
-impl<T, const N: usize> Expand for [T; N] {
-  #[inline]
-  fn expand(&mut self, _: usize) -> crate::Result<()> {
-    Ok(())
-  }
-}
diff --git a/wtx/src/web_socket/payload_ty.rs b/wtx/src/web_socket/payload_ty.rs
new file mode 100644
index 00000000..732476a9
--- /dev/null
+++ b/wtx/src/web_socket/payload_ty.rs
@@ -0,0 +1,7 @@
+#[derive(Debug)]
+pub(crate) enum PayloadTy {
+  FirstReader,
+  Network,
+  None,
+  SecondReader,
+}
diff --git a/wtx/src/web_socket/read_frame_info.rs b/wtx/src/web_socket/read_frame_info.rs
new file mode 100644
index 00000000..e52d1f6b
--- /dev/null
+++ b/wtx/src/web_socket/read_frame_info.rs
@@ -0,0 +1,151 @@
+use crate::{
+  misc::{PartitionedFilledBuffer, Stream, _read_until},
+  web_socket::{
+    compression::NegotiatedCompression, misc::op_code, OpCode, WebSocketError,
+    MAX_CONTROL_PAYLOAD_LEN,
+  },
+};
+
+/// Parameters of an WebSocket frame.
+#[derive(Debug)]
+pub struct ReadFrameInfo {
+  pub(crate) fin: bool,
+  pub(crate) header_len: u8,
+  pub(crate) mask: Option<[u8; 4]>,
+  pub(crate) op_code: OpCode,
+  pub(crate) payload_len: usize,
+  pub(crate) should_decompress: bool,
+}
+
+impl ReadFrameInfo {
+  /// Creates a new instance based on a sequence of bytes.
+  #[inline]
+  pub fn from_bytes<NC, const IS_CLIENT: bool>(
+    bytes: &mut &[u8],
+    max_payload_len: usize,
+    nc: &NC,
+  ) -> crate::Result<Self>
+  where
+    NC: NegotiatedCompression,
+  {
+    let first_two = {
+      let [a, b, rest @ ..] = bytes else {
+        return Err(crate::Error::UnexpectedBufferState);
+      };
+      *bytes = rest;
+      [*a, *b]
+    };
+    let tuple = Self::manage_first_two_bytes(first_two, nc)?;
+    let (fin, length_code, op_code, should_decompress) = tuple;
+    let (mut header_len, payload_len) = match length_code {
+      126 => {
+        let [a, b, rest @ ..] = bytes else {
+          return Err(crate::Error::UnexpectedBufferState);
+        };
+        *bytes = rest;
+        (4u8, u16::from_be_bytes([*a, *b]).into())
+      }
+      127 => {
+        let [a, b, c, d, e, f, g, h, rest @ ..] = bytes else {
+          return Err(crate::Error::UnexpectedBufferState);
+        };
+        *bytes = rest;
+        (10, u64::from_be_bytes([*a, *b, *c, *d, *e, *f, *g, *h]).try_into()?)
+      }
+      _ => (2, length_code.into()),
+    };
+    let mut mask = None;
+    if !IS_CLIENT {
+      let [a, b, c, d, rest @ ..] = bytes else {
+        return Err(crate::Error::UnexpectedBufferState);
+      };
+      *bytes = rest;
+      mask = Some([*a, *b, *c, *d]);
+      header_len = header_len.wrapping_add(4);
+    }
+    Self::manage_final_params(fin, op_code, max_payload_len, payload_len)?;
+    Ok(ReadFrameInfo { fin, header_len, mask, op_code, payload_len, should_decompress })
+  }
+
+  #[inline]
+  pub(crate) async fn from_stream<NC, S, const IS_CLIENT: bool>(
+    max_payload_len: usize,
+    nc: &NC,
+    network_buffer: &mut PartitionedFilledBuffer,
+    read: &mut usize,
+    stream: &mut S,
+  ) -> crate::Result<Self>
+  where
+    NC: NegotiatedCompression,
+    S: Stream,
+  {
+    let buffer = network_buffer._following_rest_mut();
+    let first_two = _read_until::<2, S>(buffer, read, 0, stream).await?;
+    let tuple = Self::manage_first_two_bytes(first_two, nc)?;
+    let (fin, length_code, op_code, should_decompress) = tuple;
+    let (mut header_len, payload_len) = match length_code {
+      126 => {
+        let payload_len = _read_until::<2, S>(buffer, read, 2, stream).await?;
+        (4u8, u16::from_be_bytes(payload_len).into())
+      }
+      127 => {
+        let payload_len = _read_until::<8, S>(buffer, read, 2, stream).await?;
+        (10, u64::from_be_bytes(payload_len).try_into()?)
+      }
+      _ => (2, length_code.into()),
+    };
+    let mut mask = None;
+    if !IS_CLIENT {
+      mask = Some(_read_until::<4, S>(buffer, read, header_len.into(), stream).await?);
+      header_len = header_len.wrapping_add(4);
+    }
+    Self::manage_final_params(fin, op_code, max_payload_len, payload_len)?;
+    Ok(ReadFrameInfo { fin, header_len, mask, op_code, payload_len, should_decompress })
+  }
+
+  #[inline]
+  fn manage_final_params(
+    fin: bool,
+    op_code: OpCode,
+    max_payload_len: usize,
+    payload_len: usize,
+  ) -> crate::Result<()> {
+    if op_code.is_control() && !fin {
+      return Err(WebSocketError::UnexpectedFragmentedControlFrame.into());
+    }
+    if op_code == OpCode::Ping && payload_len > MAX_CONTROL_PAYLOAD_LEN {
+      return Err(WebSocketError::VeryLargeControlFrame.into());
+    }
+    if payload_len >= max_payload_len {
+      return Err(WebSocketError::VeryLargePayload.into());
+    }
+    Ok(())
+  }
+
+  #[inline]
+  fn manage_first_two_bytes<NC>([a, b]: [u8; 2], nc: &NC) -> crate::Result<(bool, u8, OpCode, bool)>
+  where
+    NC: NegotiatedCompression,
+  {
+    let rsv1 = a & 0b0100_0000;
+    let rsv2 = a & 0b0010_0000;
+    let rsv3 = a & 0b0001_0000;
+    if rsv2 != 0 || rsv3 != 0 {
+      return Err(WebSocketError::InvalidCompressionHeaderParameter.into());
+    }
+    let should_decompress = if NC::IS_NOOP {
+      false
+    } else if nc.rsv1() == 0 {
+      if rsv1 != 0 {
+        return Err(WebSocketError::InvalidCompressionHeaderParameter.into());
+      }
+      false
+    } else {
+      rsv1 != 0
+    };
+    let fin = a & 0b1000_0000 != 0;
+    let length_code = b & 0b0111_1111;
+    let op_code = op_code(a)?;
+    Ok((fin, length_code, op_code, should_decompress))
+  }
+}
diff --git a/wtx/src/web_socket/unmask.rs b/wtx/src/web_socket/unmask.rs
index abec64b6..15e78e5c 100644
--- a/wtx/src/web_socket/unmask.rs
+++ b/wtx/src/web_socket/unmask.rs
@@ -1,31 +1,12 @@
 #[doc = _internal_doc!()]
 #[inline]
 pub(crate) fn unmask(bytes: &mut [u8], mut mask: [u8; 4]) {
-  #[cfg(target_feature = "avx512f")]
-  let (is_128, unmask_chunks_slice) = (false, _unmask_chunks_slice_512);
-
-  #[cfg(all(target_feature = "avx2", not(target_feature = "avx512f")))]
-  let (is_128, unmask_chunks_slice) = (false, _unmask_chunks_slice_256);
-
-  #[cfg(all(
-    target_feature = "neon",
-    not(any(target_feature = "avx2", target_feature = "avx512f"))
-  ))]
-  let (is_128, unmask_chunks_slice) = (true, _unmask_chunks_slice_128);
-
-  #[cfg(all(
-    target_feature = "sse2",
-    not(any(target_feature = "avx2", target_feature = "avx512f", target_feature = "neon"))
-  ))]
-  let (is_128, unmask_chunks_slice) = (true, _unmask_chunks_slice_128);
-
-  #[cfg(not(any(
-    target_feature = "avx2",
-    target_feature = "avx512f",
-    target_feature = "neon",
-    target_feature = "sse2"
-  )))]
-  let (is_128, unmask_chunks_slice) = (false, _unmask_chunks_slice_fallback);
+  let (is_128, unmask_chunks_slice) = _simd!(
+    512 => (false, _unmask_chunks_slice_512),
+    256 => (false, _unmask_chunks_slice_256),
+    128 => (true, _unmask_chunks_slice_128),
+    _ => (false, _unmask_chunks_slice_fallback)
+  );
 
   // SAFETY: Changing a sequence of `u8` should be fine
   let (prefix, chunks, suffix) = unsafe { bytes.align_to_mut() };
@@ -75,24 +56,23 @@ fn unmask_u8_slice(bytes: &mut [u8], mask: [u8; 4], shift: usize) {
 
 #[cfg(all(feature = "_bench", test))]
 mod bench {
-  use crate::{bench::_data, web_socket::unmask};
+  use crate::bench::_data;
 
   #[bench]
-  fn bench_unmask(b: &mut test::Bencher) {
+  fn unmask(b: &mut test::Bencher) {
     let mut data = _data(1024 * 1024 * 8);
-    b.iter(|| unmask(&mut data, [3, 5, 7, 11]));
+    b.iter(|| crate::web_socket::unmask::unmask(&mut data, [3, 5, 7, 11]));
   }
 }
 
-#[cfg(test)]
-#[cfg(feature = "_proptest")]
+#[cfg(all(feature = "_proptest", test))]
 mod proptest {
   use crate::misc::Vector;
 
   #[test_strategy::proptest]
   fn unmask(mut payload: Vector<u8>, mask: [u8; 4]) {
     payload.fill(0);
-    crate::web_socket::unmask(&mut payload, mask);
+    crate::web_socket::unmask::unmask(&mut payload, mask);
     let expected = Vector::from_iter((0..payload.len()).map(|idx| mask[idx & 3])).unwrap();
     assert_eq!(payload, expected);
   }
diff --git a/wtx/src/web_socket/web_socket_buffer.rs b/wtx/src/web_socket/web_socket_buffer.rs
index 6961f9f5..0de9b383 100644
--- a/wtx/src/web_socket/web_socket_buffer.rs
+++ b/wtx/src/web_socket/web_socket_buffer.rs
@@ -1,35 +1,54 @@
-use crate::misc::{FilledBuffer, Lease, LeaseMut, PartitionedFilledBuffer, VectorError};
+use crate::misc::{Lease, LeaseMut, PartitionedFilledBuffer, Vector, VectorError};
 
-#[derive(Debug, Default)]
+#[derive(Debug)]
 #[doc = _internal_buffer_doc!()]
 pub struct WebSocketBuffer {
-  /// Decompression buffer
-  pub(crate) db: FilledBuffer,
-  /// Network buffer
-  pub(crate) nb: PartitionedFilledBuffer,
+  pub(crate) network_buffer: PartitionedFilledBuffer,
+  pub(crate) writer_buffer: Vector<u8>,
+  pub(crate) reader_buffer_first: Vector<u8>,
+  pub(crate) reader_buffer_second: Vector<u8>,
 }
 
 impl WebSocketBuffer {
+  /// New empty instance
+  #[inline]
+  pub const fn new() -> Self {
+    Self {
+      network_buffer: PartitionedFilledBuffer::new(),
+      reader_buffer_first: Vector::new(),
+      reader_buffer_second: Vector::new(),
+      writer_buffer: Vector::new(),
+    }
+  }
+
   /// The elements used internally will be able to hold at least the specified amounts.
   #[inline]
   pub fn with_capacity(
-    decompression_buffer_cap: usize,
     network_buffer_cap: usize,
+    reader_buffer_cap: usize,
+    writer_buffer_cap: usize,
   ) -> Result<Self, VectorError> {
     Ok(Self {
-      db: FilledBuffer::_with_capacity(decompression_buffer_cap)?,
-      nb: PartitionedFilledBuffer::_with_capacity(network_buffer_cap)?,
+      network_buffer: PartitionedFilledBuffer::_with_capacity(network_buffer_cap)?,
+      reader_buffer_first: Vector::with_capacity(reader_buffer_cap)?,
+      reader_buffer_second: Vector::with_capacity(reader_buffer_cap)?,
+      writer_buffer: Vector::with_capacity(writer_buffer_cap)?,
     })
   }
 
   pub(crate) fn _clear(&mut self) {
-    let Self { db, nb } = self;
-    db._clear();
-    nb._clear();
+    let Self { network_buffer, reader_buffer_first, reader_buffer_second, writer_buffer } = self;
+    network_buffer._clear();
+    reader_buffer_first.clear();
+    reader_buffer_second.clear();
+    writer_buffer.clear();
   }
+}
 
-  pub(crate) fn _parts_mut(&mut self) -> (&mut FilledBuffer, &mut PartitionedFilledBuffer) {
-    (&mut self.db, &mut self.nb)
+impl Default for WebSocketBuffer {
+  #[inline]
+  fn default() -> Self {
+    Self::new()
   }
 }
 
diff --git a/wtx/src/web_socket/web_socket_parts.rs b/wtx/src/web_socket/web_socket_parts.rs
new file mode 100644
index 00000000..29193045
--- /dev/null
+++ b/wtx/src/web_socket/web_socket_parts.rs
@@ -0,0 +1,97 @@
+use crate::{
+  misc::{ConnectionState, LeaseMut, PartitionedFilledBuffer, Stream, Vector, Xorshift64},
+  web_socket::{
+    compression::NegotiatedCompression, payload_ty::PayloadTy, web_socket_reader,
+    web_socket_writer, Frame, FrameMut,
+  },
+};
+use core::marker::PhantomData;
+
+/// Auxiliary structure used by [`WebSocketReaderStub`] and [`WebSocketWriterStub`]
+#[derive(Debug)]
+pub struct WebSocketCommonPart<'instance, NC, S, const IS_CLIENT: bool> {
+  pub(crate) connection_state: &'instance mut ConnectionState,
+  pub(crate) curr_payload: &'instance mut PayloadTy,
+  pub(crate) nc: &'instance mut NC,
+  pub(crate) rng: &'instance mut Xorshift64,
+  pub(crate) stream: &'instance mut S,
+}
+
+/// Auxiliary structure that can be used when it is necessary to write a received frame that belongs
+/// to the same instance.
+#[derive(Debug)]
+pub struct WebSocketReaderPart<'instance, NC, S, const IS_CLIENT: bool> {
+  pub(crate) max_payload_len: usize,
+  pub(crate) network_buffer: &'instance mut PartitionedFilledBuffer,
+  pub(crate) phantom: PhantomData<(NC, S)>,
+  pub(crate) reader_buffer_first: &'instance mut Vector<u8>,
+  pub(crate) reader_buffer_second: &'instance mut Vector<u8>,
+}
+
+impl<'instance, NC, S, const IS_CLIENT: bool> WebSocketReaderPart<'instance, NC, S, IS_CLIENT>
+where
+  NC: NegotiatedCompression,
+  S: Stream,
+{
+  /// Reads a frame from the stream.
+  ///
+  /// If a frame is made up of other sub-frames or continuations, then everything is collected
+  /// until all fragments are received.
+  #[inline]
+  pub async fn read_frame(
+    &mut self,
+    common: &mut WebSocketCommonPart<'instance, NC, S, IS_CLIENT>,
+  ) -> crate::Result<FrameMut<'_, IS_CLIENT>> {
+    let WebSocketCommonPart { connection_state, curr_payload, nc, rng, stream } = common;
+    let Self {
+      max_payload_len,
+      network_buffer,
+      phantom: _,
+      reader_buffer_first,
+      reader_buffer_second,
+    } = self;
+    let (frame, payload_ty) = web_socket_reader::read_frame_from_stream(
+      connection_state,
+      *max_payload_len,
+      nc,
+      network_buffer,
+      reader_buffer_first,
+      reader_buffer_second,
+      rng,
+      stream,
+    )
+    .await?;
+    **curr_payload = payload_ty;
+    Ok(frame)
+  }
+}
+
+/// Auxiliary structure that can be used when it is necessary to write a received frame that belongs
+/// to the same instance.
+#[derive(Debug)]
+pub struct WebSocketWriterPart<'instance, NC, S, const IS_CLIENT: bool> {
+  pub(crate) phantom: PhantomData<(NC, S)>,
+  pub(crate) writer_buffer: &'instance mut Vector<u8>,
+}
+
+impl<'instance, NC, S, const IS_CLIENT: bool> WebSocketWriterPart<'instance, NC, S, IS_CLIENT>
+where
+  NC: NegotiatedCompression,
+  S: Stream,
+{
+  /// Writes a frame to the stream.
+  #[inline]
+  pub async fn write_frame<P>(
+    &mut self,
+    common: &mut WebSocketCommonPart<'instance, NC, S, IS_CLIENT>,
+    frame: &mut Frame<P, IS_CLIENT>,
+  ) -> crate::Result<()>
+  where
+    P: LeaseMut<[u8]>,
+  {
+    let WebSocketCommonPart { connection_state, curr_payload: _, nc, rng, stream } = common;
+    let Self { phantom: _, writer_buffer } = self;
+    web_socket_writer::write_frame(connection_state, frame, nc, rng, stream, writer_buffer).await?;
+    Ok(())
+  }
+}
diff --git a/wtx/src/web_socket/web_socket_reader.rs b/wtx/src/web_socket/web_socket_reader.rs
new file mode 100644
index 00000000..32e07c13
--- /dev/null
+++ b/wtx/src/web_socket/web_socket_reader.rs
@@ -0,0 +1,547 @@
+// |    Frame   |   With Decompression     | Without Decompression |
+// |------------|--------------------------|-----------------------|
+// |Single      |(NB -> RB1)¹              |(NB)¹                  |
+// |Continuation|(NB -> RB1)* (RB1 -> RB2)¹|(NB -> RB2)*           |
+
+use crate::{
+  misc::{
+    from_utf8_basic, from_utf8_ext, BufferMode, CompletionErr, ConnectionState, ExtUtf8Error,
+    FnMutFut, IncompleteUtf8Char, LeaseMut, PartitionedFilledBuffer, Rng, Stream, Vector,
+  },
+  web_socket::{
+    compression::NegotiatedCompression, fill_with_close_code, payload_ty::PayloadTy,
+    read_frame_info::ReadFrameInfo, unmask::unmask, web_socket_writer::manage_normal_frame,
+    CloseCode, Frame, FrameMut, OpCode, WebSocketError, MAX_CONTROL_PAYLOAD_LEN,
+  },
+};
+
+const DECOMPRESSION_SUFFIX: [u8; 4] = [0, 0, 255, 255];
+
+type ReadContinuationFramesCb = (
+  fn(&[u8]) -> crate::Result<Option<IncompleteUtf8Char>>,
+  fn(&[u8], &mut Option<IncompleteUtf8Char>) -> crate::Result<()>,
+);
+
+/// If this method returns `false`, then a `ping` frame was received and the caller should fetch
+/// more external data in order to get the desired frame.
+#[inline]
+pub(crate) async fn manage_auto_reply<A, RNG, const IS_CLIENT: bool>(
+  aux: &mut A,
+  connection_state: &mut ConnectionState,
+  op_code: OpCode,
+  payload: &mut [u8],
+  rng: &mut RNG,
+  write_control_frame_cb: &mut impl for<'any> FnMutFut<
+    (&'any mut A, &'any [u8], &'any [u8]),
+    Result = crate::Result<()>,
+  >,
+) -> crate::Result<bool>
+where
+  RNG: Rng,
+{
+  match op_code {
+    OpCode::Close => {
+      if connection_state.is_closed() {
+        return Err(WebSocketError::ConnectionClosed.into());
+      }
+      *connection_state = ConnectionState::Closed;
+      match payload {
+        [] => {}
+        [_] => return Err(WebSocketError::InvalidCloseFrame.into()),
+        [a, b, rest @ ..] => {
+          let _ = from_utf8_basic(rest)?;
+          let close_code = CloseCode::try_from(u16::from_be_bytes([*a, *b]))?;
+          if !close_code.is_allowed() || rest.len() > MAX_CONTROL_PAYLOAD_LEN - 2 {
+            fill_with_close_code(CloseCode::Protocol, payload);
+            let payload_ret = payload.get_mut(..MAX_CONTROL_PAYLOAD_LEN).unwrap_or_default();
+            write_control_frame::<_, _, _, IS_CLIENT>(
+              aux,
+              connection_state,
+              &mut Frame::new_fin(OpCode::Close, payload_ret),
+              rng,
+              write_control_frame_cb,
+            )
+            .await?;
+            return Err(WebSocketError::InvalidCloseFrame.into());
+          }
+        }
+      }
+      write_control_frame::<_, _, _, IS_CLIENT>(
+        aux,
+        connection_state,
+        &mut Frame::new_fin(OpCode::Close, payload),
+        rng,
+        write_control_frame_cb,
+      )
+      .await?;
+      Ok(true)
+    }
+    OpCode::Ping => {
+      write_control_frame::<_, _, _, IS_CLIENT>(
+        aux,
+        connection_state,
+        &mut Frame::new_fin(OpCode::Pong, payload),
+        rng,
+        write_control_frame_cb,
+      )
+      .await?;
+      Ok(false)
+    }
+    OpCode::Continuation | OpCode::Binary | OpCode::Pong | OpCode::Text => Ok(true),
+  }
+}
+
+/// Returns `true` if `op_code` is a continuation frame and `fin` is also `true`.
+#[inline]
+pub(crate) fn manage_op_code_of_continuation_frames(
+  fin: bool,
+  first_op_code: OpCode,
+  iuc: &mut Option<IncompleteUtf8Char>,
+  op_code: OpCode,
+  payload: &[u8],
+  cb: fn(&[u8], &mut Option<IncompleteUtf8Char>) -> crate::Result<()>,
+) -> crate::Result<bool> {
+  match op_code {
+    OpCode::Continuation => {
+      if first_op_code.is_text() {
+        cb(payload, iuc)?;
+      }
+      if fin {
+        return Ok(true);
+      }
+    }
+    OpCode::Binary | OpCode::Close | OpCode::Ping | OpCode::Pong | OpCode::Text => {
+      return Err(WebSocketError::UnexpectedMessageFrame.into());
+    }
+  }
+  Ok(false)
+}
+
+#[inline]
+pub(crate) fn manage_op_code_of_first_continuation_frame(
+  op_code: OpCode,
+  payload: &[u8],
+  cb: fn(&[u8]) -> crate::Result<Option<IncompleteUtf8Char>>,
+) -> crate::Result<Option<IncompleteUtf8Char>> {
+  match op_code {
+    OpCode::Binary => Ok(None),
+    OpCode::Text => cb(payload),
+    OpCode::Close | OpCode::Continuation | OpCode::Ping | OpCode::Pong => {
+      Err(WebSocketError::UnexpectedMessageFrame.into())
+    }
+  }
+}
+
+#[inline]
+pub(crate) fn manage_op_code_of_first_final_frame(
+  op_code: OpCode,
+  payload: &[u8],
+) -> crate::Result<()> {
+  match op_code {
+    OpCode::Close => {
+      return Ok(());
+    }
+    OpCode::Continuation => {
+      return Err(WebSocketError::UnexpectedMessageFrame.into());
+    }
+    OpCode::Text => {
+      let _str_validation = from_utf8_basic(payload)?;
+    }
+    OpCode::Binary | OpCode::Ping | OpCode::Pong => {}
+  }
+  Ok(())
+}
+
+#[inline]
+pub(crate) fn manage_text_of_first_continuation_frame(
+  payload: &[u8],
+) -> crate::Result<Option<IncompleteUtf8Char>> {
+  Ok(match from_utf8_ext(payload) {
+    Err(ExtUtf8Error::Incomplete { incomplete_ending_char, .. }) => Some(incomplete_ending_char),
+    Err(ExtUtf8Error::Invalid { .. }) => {
+      return Err(crate::Error::InvalidUTF8);
+    }
+    Ok(_) => None,
+  })
+}
+
+#[inline]
+pub(crate) fn manage_text_of_recurrent_continuation_frames(
+  curr_payload: &[u8],
+  iuc: &mut Option<IncompleteUtf8Char>,
+) -> crate::Result<()> {
+  let tail = if let Some(mut incomplete) = iuc.take() {
+    let (rslt, remaining) = incomplete.complete(curr_payload);
+    match rslt {
+      Err(CompletionErr::HasInvalidBytes) => {
+        return Err(crate::Error::InvalidUTF8);
+      }
+      Err(CompletionErr::InsufficientInput) => {
+        let _ = iuc.replace(incomplete);
+        &[]
+      }
+      Ok(_) => remaining,
+    }
+  } else {
+    curr_payload
+  };
+  match from_utf8_ext(tail) {
+    Err(ExtUtf8Error::Incomplete { incomplete_ending_char, .. }) => {
+      *iuc = Some(incomplete_ending_char);
+    }
+    Err(ExtUtf8Error::Invalid { .. }) => {
+      return Err(crate::Error::InvalidUTF8);
+    }
+    Ok(_) => {}
+  }
+  Ok(())
+}
+
+#[inline]
+pub(crate) fn unmask_nb<const IS_CLIENT: bool>(
+  network_buffer: &mut [u8],
+  rfi: &ReadFrameInfo,
+) -> crate::Result<()> {
+  if !IS_CLIENT {
+    unmask(network_buffer, rfi.mask.ok_or(WebSocketError::MissingFrameMask)?);
+  }
+  Ok(())
+}
+
+#[inline]
+pub(crate) async fn read_frame_from_stream<'nb, 'rb, 'rslt, NC, RNG, S, const IS_CLIENT: bool>(
+  connection_state: &mut ConnectionState,
+  max_payload_len: usize,
+  nc: &mut NC,
+  network_buffer: &'nb mut PartitionedFilledBuffer,
+  reader_buffer_first: &'rb mut Vector<u8>,
+  reader_buffer_second: &'rb mut Vector<u8>,
+  rng: &mut RNG,
+  stream: &mut S,
+) -> crate::Result<(FrameMut<'rslt, IS_CLIENT>, PayloadTy)>
+where
+  'nb: 'rslt,
+  'rb: 'rslt,
+  NC: NegotiatedCompression,
+  RNG: Rng,
+  S: Stream,
+{
+  reader_buffer_second.clear();
+  let first_rfi = loop {
+    network_buffer._clear_if_following_is_empty();
+    reader_buffer_first.clear();
+    let rfi =
+      fetch_frame_from_stream::<_, _, IS_CLIENT>(max_payload_len, nc, network_buffer, stream)
+        .await?;
+    if !rfi.fin {
+      break rfi;
+    }
+    let (payload, payload_ty) = if rfi.should_decompress {
+      copy_from_compressed_nb_to_rb1::<NC, IS_CLIENT>(
+        nc,
+        network_buffer,
+        reader_buffer_first,
+        &rfi,
+      )?;
+      (reader_buffer_first.as_slice_mut(), PayloadTy::FirstReader)
+    } else {
+      let current_mut = network_buffer._current_mut();
+      unmask_nb::<IS_CLIENT>(current_mut, &rfi)?;
+      (current_mut, PayloadTy::Network)
+    };
+    if manage_auto_reply::<_, _, IS_CLIENT>(
+      stream,
+      connection_state,
+      rfi.op_code,
+      payload,
+      rng,
+      &mut write_control_frame_cb,
+    )
+    .await?
+    {
+      manage_op_code_of_first_final_frame(rfi.op_code, payload)?;
+      // FIXME(STABLE): Use `payload` with polonius
+      let borrow_checker = if rfi.should_decompress {
+        reader_buffer_first.as_slice_mut()
+      } else {
+        network_buffer._current_mut()
+      };
+      return Ok((Frame::new(true, rfi.op_code, borrow_checker, nc.rsv1()), payload_ty));
+    }
+  };
+  if first_rfi.should_decompress {
+    read_continuation_frames::<_, _, _, IS_CLIENT>(
+      connection_state,
+      &first_rfi,
+      max_payload_len,
+      nc,
+      network_buffer,
+      reader_buffer_first,
+      rng,
+      stream,
+      (|_| Ok(None), |_, _| Ok(())),
+    )
+    .await?;
+    copy_from_compressed_rb1_to_rb2(&first_rfi, nc, reader_buffer_first, reader_buffer_second)?;
+    Ok((
+      Frame::new(true, first_rfi.op_code, reader_buffer_second, nc.rsv1()),
+      PayloadTy::SecondReader,
+    ))
+  } else {
+    read_continuation_frames::<_, _, _, IS_CLIENT>(
+      connection_state,
+      &first_rfi,
+      max_payload_len,
+      nc,
+      network_buffer,
+      reader_buffer_first,
+      rng,
+      stream,
+      (manage_text_of_first_continuation_frame, manage_text_of_recurrent_continuation_frames),
+    )
+    .await?;
+    Ok((
+      Frame::new(true, first_rfi.op_code, reader_buffer_first, nc.rsv1()),
+      PayloadTy::FirstReader,
+    ))
+  }
+}
+
+#[inline]
+fn copy_from_arbitrary_nb_to_rb1<const IS_CLIENT: bool>(
+  network_buffer: &mut PartitionedFilledBuffer,
+  reader_buffer_first: &mut Vector<u8>,
+  rfi: &ReadFrameInfo,
+) -> crate::Result<()> {
+  let current_mut = network_buffer._current_mut();
+  unmask_nb::<IS_CLIENT>(current_mut, rfi)?;
+  reader_buffer_first.extend_from_copyable_slice(current_mut)?;
+  network_buffer._clear_if_following_is_empty();
+  Ok(())
+}
+
+#[inline]
+fn copy_from_compressed_nb_to_rb1<NC, const IS_CLIENT: bool>(
+  nc: &mut NC,
+  network_buffer: &mut PartitionedFilledBuffer,
+  reader_buffer_first: &mut Vector<u8>,
+  rfi: &ReadFrameInfo,
+) -> crate::Result<()>
+where
+  NC: NegotiatedCompression,
+{
+  unmask_nb::<IS_CLIENT>(network_buffer._current_mut(), rfi)?;
+  network_buffer._reserve(4)?;
+  let curr_end_idx = network_buffer._current().len();
+  let curr_end_idx_p4 = curr_end_idx.wrapping_add(4);
+  let has_following = network_buffer._has_following();
+  let input = network_buffer._current_rest_mut().get_mut(..curr_end_idx_p4).unwrap_or_default();
+  let original = if let [.., a, b, c, d] = input {
+    let original = [*a, *b, *c, *d];
+    *a = DECOMPRESSION_SUFFIX[0];
+    *b = DECOMPRESSION_SUFFIX[1];
+    *c = DECOMPRESSION_SUFFIX[2];
+    *d = DECOMPRESSION_SUFFIX[3];
+    original
+  } else {
+    [0, 0, 0, 0]
+  };
+  let before = reader_buffer_first.len();
+  let additional = input.len().saturating_mul(2);
+  let payload_len_rslt = nc.decompress(
+    input,
+    reader_buffer_first,
+    |local_rb| expand_rb(additional, local_rb, before),
+    |local_rb, written| expand_rb(additional, local_rb, before.wrapping_add(written)),
+  );
+  if has_following {
+    if let [.., a, b, c, d] = input {
+      *a = original[0];
+      *b = original[1];
+      *c = original[2];
+      *d = original[3];
+    }
+  }
+  let payload_len = payload_len_rslt?;
+  reader_buffer_first.truncate(before.wrapping_add(payload_len));
+  Ok(())
+}
+
+#[inline]
+fn copy_from_compressed_rb1_to_rb2<NC>(
+  first_rfi: &ReadFrameInfo,
+  nc: &mut NC,
+  reader_buffer_first: &mut Vector<u8>,
+  reader_buffer_second: &mut Vector<u8>,
+) -> crate::Result<()>
+where
+  NC: NegotiatedCompression,
+{
+  reader_buffer_first.extend_from_copyable_slice(&DECOMPRESSION_SUFFIX)?;
+  let additional = reader_buffer_first.len().saturating_mul(2);
+  let payload_len = nc.decompress(
+    reader_buffer_first,
+    reader_buffer_second,
+    |local_rb| expand_rb(additional, local_rb, 0),
+    |local_rb, written| expand_rb(additional, local_rb, written),
+  )?;
+  reader_buffer_second.truncate(payload_len);
+  if matches!(first_rfi.op_code, OpCode::Text) && from_utf8_basic(reader_buffer_second).is_err() {
+    return Err(crate::Error::InvalidUTF8);
+  }
+  Ok(())
+}
+
+#[inline]
+fn expand_rb(
+  additional: usize,
+  reader_buffer_first: &mut Vector<u8>,
+  written: usize,
+) -> crate::Result<&mut [u8]> {
+  reader_buffer_first.expand(BufferMode::Additional(additional), 0)?;
+  Ok(reader_buffer_first.get_mut(written..).unwrap_or_default())
+}
+
+#[inline]
+async fn fetch_frame_from_stream<NC, S, const IS_CLIENT: bool>(
+  max_payload_len: usize,
+  nc: &NC,
+  network_buffer: &mut PartitionedFilledBuffer,
+  stream: &mut S,
+) -> crate::Result<ReadFrameInfo>
+where
+  NC: NegotiatedCompression,
+  S: Stream,
+{
+  let mut read = network_buffer._following_len();
+  let rfi = ReadFrameInfo::from_stream::<_, _, IS_CLIENT>(
+    max_payload_len,
+    nc,
+    network_buffer,
+    &mut read,
+    stream,
+  )
+  .await?;
+  let frame_len = rfi.payload_len.wrapping_add(rfi.header_len.into());
+  fetch_payload_from_stream(frame_len, network_buffer, &mut read, stream).await?;
+  network_buffer._set_indices(
+    network_buffer._current_end_idx().wrapping_add(rfi.header_len.into()),
+    rfi.payload_len,
+    read.wrapping_sub(frame_len),
+  )?;
+  Ok(rfi)
+}
+
+#[inline]
+async fn fetch_payload_from_stream<S>(
+  frame_len: usize,
+  network_buffer: &mut PartitionedFilledBuffer,
+  read: &mut usize,
+  stream: &mut S,
+) -> crate::Result<()>
+where
+  S: Stream,
+{
+  network_buffer._reserve(frame_len)?;
+  for _ in 0..=frame_len {
+    if *read >= frame_len {
+      return Ok(());
+    }
+    *read = read.wrapping_add(
+      stream
+        .read(network_buffer._following_rest_mut().get_mut(*read..).unwrap_or_default())
+        .await?,
+    );
+  }
+  Err(crate::Error::UnexpectedBufferState)
+}
+
+#[inline]
+async fn read_continuation_frames<NC, RNG, S, const IS_CLIENT: bool>(
+  connection_state: &mut ConnectionState,
+  first_rfi: &ReadFrameInfo,
+  max_payload_len: usize,
+  nc: &mut NC,
+  network_buffer: &mut PartitionedFilledBuffer,
+  reader_buffer_first: &mut Vector<u8>,
+  rng: &mut RNG,
+  stream: &mut S,
+  (first_text_cb, recurrent_text_cb): ReadContinuationFramesCb,
+) -> crate::Result<()>
+where
+  NC: NegotiatedCompression,
+  RNG: Rng,
+  S: Stream,
+{
+  copy_from_arbitrary_nb_to_rb1::<IS_CLIENT>(network_buffer, reader_buffer_first, first_rfi)?;
+  let mut iuc = manage_op_code_of_first_continuation_frame(
+    first_rfi.op_code,
+    reader_buffer_first,
+    first_text_cb,
+  )?;
+  loop {
+    let mut rfi =
+      fetch_frame_from_stream::<_, _, IS_CLIENT>(max_payload_len, nc, network_buffer, stream)
+        .await?;
+    let begin = reader_buffer_first.len();
+    rfi.should_decompress = first_rfi.should_decompress;
+    copy_from_arbitrary_nb_to_rb1::<IS_CLIENT>(network_buffer, reader_buffer_first, &rfi)?;
+    let payload = reader_buffer_first.get_mut(begin..).unwrap_or_default();
+    if !manage_auto_reply::<_, _, IS_CLIENT>(
+      stream,
+      connection_state,
+      rfi.op_code,
+      payload,
+      rng,
+      &mut write_control_frame_cb,
+    )
+    .await?
+    {
+      reader_buffer_first.truncate(begin);
+      continue;
+    }
+    if manage_op_code_of_continuation_frames(
+      rfi.fin,
+      first_rfi.op_code,
+      &mut iuc,
+      rfi.op_code,
+      payload,
+      recurrent_text_cb,
+    )? {
+      return Ok(());
+    }
+  }
+}
+
+#[inline]
+async fn write_control_frame<A, P, RNG, const IS_CLIENT: bool>(
+  aux: &mut A,
+  connection_state: &mut ConnectionState,
+  frame: &mut Frame<P, IS_CLIENT>,
+  rng: &mut RNG,
+  wsc_cb: &mut impl for<'any> FnMutFut<
+    (&'any mut A, &'any [u8], &'any [u8]),
+    Result = crate::Result<()>,
+  >,
+) -> crate::Result<()>
+where
+  P: LeaseMut<[u8]>,
+  RNG: Rng,
+{
+  manage_normal_frame(connection_state, frame, rng);
+  wsc_cb.call((aux, frame.header(), frame.payload().lease())).await?;
+  Ok(())
+}
+
+#[inline]
+async fn write_control_frame_cb<S>(
+  stream: &mut S,
+  header: &[u8],
+  payload: &[u8],
+) -> crate::Result<()>
+where
+  S: Stream,
+{
+  stream.write_all_vectored(&[header, payload]).await?;
+  Ok(())
+}
diff --git a/wtx/src/web_socket/web_socket_writer.rs b/wtx/src/web_socket/web_socket_writer.rs
new file mode 100644
index 00000000..2aecb986
--- /dev/null
+++ b/wtx/src/web_socket/web_socket_writer.rs
@@ -0,0 +1,146 @@
+use crate::{
+  misc::{BufferMode, ConnectionState, Lease, LeaseMut, Rng, Stream, Vector, Xorshift64},
+  web_socket::{compression::NegotiatedCompression, unmask::unmask, Frame, FrameMut, OpCode},
+};
+
+#[inline]
+pub(crate) fn manage_compression<NC, P, const IS_CLIENT: bool>(
+  frame: &mut Frame<P, IS_CLIENT>,
+  nc: &NC,
+) -> bool
+where
+  NC: NegotiatedCompression,
+  P: Lease<[u8]>,
+{
+  if NC::IS_NOOP {
+    return false;
+  }
+  let mut should_compress = false;
+  if !frame.op_code().is_control() {
+    let [first, _] = frame.header_first_two_mut();
+    should_compress = nc.rsv1() != 0;
+    *first |= nc.rsv1();
+  }
+  should_compress
+}
+
+#[inline]
+pub(crate) fn manage_frame_compression<'cb, P, NC, const IS_CLIENT: bool>(
+  connection_state: &mut ConnectionState,
+  nc: &mut NC,
+  frame: &mut Frame<P, IS_CLIENT>,
+  rng: &mut Xorshift64,
+  writer_buffer: &'cb mut Vector<u8>,
+) -> crate::Result<FrameMut<'cb, IS_CLIENT>>
+where
+  P: LeaseMut<[u8]>,
+  NC: NegotiatedCompression,
+{
+  if frame.op_code() == OpCode::Close {
+    *connection_state = ConnectionState::Closed;
+  }
+  let mut compressed_frame = compress_frame(frame, nc, writer_buffer)?;
+  mask_frame(&mut compressed_frame, rng);
+  Ok(compressed_frame)
+}
+
+#[inline]
+pub(crate) fn manage_normal_frame<P, RNG, const IS_CLIENT: bool>(
+  connection_state: &mut ConnectionState,
+  frame: &mut Frame<P, IS_CLIENT>,
+  rng: &mut RNG,
+) where
+  P: LeaseMut<[u8]>,
+  RNG: Rng,
+{
+  if frame.op_code() == OpCode::Close {
+    *connection_state = ConnectionState::Closed;
+  }
+  mask_frame(frame, rng);
+}
+
+#[inline]
+pub(crate) async fn write_frame<NC, P, S, const IS_CLIENT: bool>(
+  connection_state: &mut ConnectionState,
+  frame: &mut Frame<P, IS_CLIENT>,
+  nc: &mut NC,
+  rng: &mut Xorshift64,
+  stream: &mut S,
+  writer_buffer: &mut Vector<u8>,
+) -> crate::Result<()>
+where
+  NC: NegotiatedCompression,
+  P: LeaseMut<[u8]>,
+  S: Stream,
+{
+  if manage_compression(frame, nc) {
+    let nframe = manage_frame_compression(connection_state, nc, frame, rng, writer_buffer)?;
+    stream.write_all_vectored(&[nframe.header(), nframe.payload()]).await?;
+  } else {
+    manage_normal_frame::<_, _, IS_CLIENT>(connection_state, frame, rng);
+    let (header, payload) = frame.header_and_payload_mut();
+    stream.write_all_vectored(&[header, payload.lease()]).await?;
+  }
+  Ok(())
+}
+
+#[inline]
+fn compress_frame<'cb, P, NC, const IS_CLIENT: bool>(
+  frame: &mut Frame<P, IS_CLIENT>,
+  nc: &mut NC,
+  writer_buffer: &'cb mut Vector<u8>,
+) -> crate::Result<FrameMut<'cb, IS_CLIENT>>
+where
+  P: LeaseMut<[u8]>,
+  NC: NegotiatedCompression,
+{
+  let additional = frame.payload().lease().len().wrapping_add(128);
+  writer_buffer.clear();
+  let mut payload_len = nc.compress(
+    frame.payload().lease(),
+    writer_buffer,
+    |local_writer_buffer| {
+      local_writer_buffer.expand(BufferMode::Additional(additional), 0)?;
+      Ok(local_writer_buffer)
+    },
+    |local_writer_buffer, written| {
+      local_writer_buffer.expand(BufferMode::Additional(additional), 0)?;
+      Ok(local_writer_buffer.get_mut(written..).unwrap_or_default())
+    },
+  )?;
+  if frame.fin() {
+    payload_len = payload_len.saturating_sub(4);
+  }
+  Ok(FrameMut::new(
+    frame.fin(),
+    frame.op_code(),
+    writer_buffer.get_mut(..payload_len).unwrap_or_default(),
+    nc.rsv1(),
+  ))
+}
+
+#[inline]
+const fn has_masked_frame(second_header_byte: u8) -> bool {
+  second_header_byte & 0b1000_0000 != 0
+}
+
+#[inline]
+fn mask_frame<P, RNG, const IS_CLIENT: bool>(frame: &mut Frame<P, IS_CLIENT>, rng: &mut RNG)
+where
+  P: LeaseMut<[u8]>,
+  RNG: Rng,
+{
+  if IS_CLIENT {
+    if let [_, second_byte, .., a, b, c, d] = frame.header_mut() {
+      if !has_masked_frame(*second_byte) {
+        *second_byte |= 0b1000_0000;
+        let mask = rng.u8_4();
+        *a = mask[0];
+        *b = mask[1];
+        *c = mask[2];
+        *d = mask[3];
+        unmask(frame.payload_mut().lease_mut(), mask);
+      }
+    }
+  }
+}


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 1351bbcf..e60bab61 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -44,7 +44,7 @@ jobs:
           use-tool-cache: true
       - run: .scripts/fuzz.sh
 
-  h2spec:
+  h2spec-high:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
@@ -54,7 +54,19 @@ jobs:
           profile: minimal
           toolchain: nightly-2024-09-01
       - uses: Swatinem/rust-cache@v2
-      - run: .scripts/h2spec.sh ci
+      - run: .scripts/h2spec.sh high ci
+
+  h2spec-low:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions-rs/toolchain@v1
+        with:
+          override: true
+          profile: minimal
+          toolchain: nightly-2024-09-01
+      - uses: Swatinem/rust-cache@v2
+      - run: .scripts/h2spec.sh low ci
 
   integration-tests:
     runs-on: ubuntu-latest
diff --git a/wtx/src/database/client/postgres/integration_tests.rs b/wtx/src/database/client/postgres/integration_tests.rs
index 49f32e23..e7692149 100644
--- a/wtx/src/database/client/postgres/integration_tests.rs
+++ b/wtx/src/database/client/postgres/integration_tests.rs
@@ -69,7 +69,7 @@ async fn custom_composite_type() {
         CREATE TYPE custom_composite_type AS (int_value INT, varchar_value VARCHAR);
         CREATE TABLE custom_composite_table (id INT, type custom_composite_type);
       ",
-      |_| {},
+      drop,
     )
     .await
     .unwrap();
diff --git a/wtx/src/http2/tests/connections.rs b/wtx/src/http2/tests/connections.rs
index 943cf35b..fa36962c 100644
--- a/wtx/src/http2/tests/connections.rs
+++ b/wtx/src/http2/tests/connections.rs
@@ -39,12 +39,12 @@ async fn client(uri: &UriString) {
   _1(rrb.body(), rrb.headers());
 
   rrb.clear();
-  rrb.data.extend_from_slice(b"123").unwrap();
+  rrb.body.extend_from_copyable_slice(b"123").unwrap();
   rrb = stream_client(&mut http2, rrb, &uri_ref).await;
   _2(rrb.body(), rrb.headers());
 
   rrb.clear();
-  rrb.data.extend_from_slice(b"123").unwrap();
+  rrb.body.extend_from_copyable_slice(b"123").unwrap();
   rrb.headers.push_from_iter(Header::from_name_and_value(b"123", ["456".as_bytes()])).unwrap();
   rrb = stream_client(&mut http2, rrb, &uri_ref).await;
   _3(rrb.body(), rrb.headers());
@@ -88,31 +88,29 @@ async fn server(uri: &UriString) {
 }
 
 async fn stream_server(
-  server: &mut Http2Tokio<Http2Buffer<ReqResBuffer>, ReqResBuffer, OwnedWriteHalf, false>,
+  server: &mut Http2Tokio<Http2Buffer, OwnedWriteHalf, false>,
   rrb: ReqResBuffer,
   mut cb: impl FnMut(Request<&mut ReqResBuffer>),
 ) -> ReqResBuffer {
   loop {
-    let Either::Right(mut stream) = server.stream(rrb).await.unwrap() else {
+    let Either::Right((mut stream, _)) = server.stream(rrb, |_, _, _| {}).await.unwrap() else {
       panic!();
     };
-    let (mut req_rrb, Some(method)) = stream.recv_req().await.unwrap() else {
-      panic!();
-    };
-    cb(req_rrb.as_http2_request_mut(method));
-    stream.send_res(req_rrb.as_http2_response(StatusCode::Ok)).await.unwrap().unwrap();
+    let (_, mut req_rrb) = stream.recv_req().await.unwrap();
+    cb(req_rrb.as_http2_request_mut(stream.method()));
+    let _ = stream.send_res(req_rrb.as_http2_response(StatusCode::Ok)).await.unwrap();
     break req_rrb;
   }
 }
 
 async fn stream_client(
-  client: &mut Http2Tokio<Http2Buffer<ReqResBuffer>, ReqResBuffer, OwnedWriteHalf, true>,
+  client: &mut Http2Tokio<Http2Buffer, OwnedWriteHalf, true>,
   rrb: ReqResBuffer,
   uri: &UriRef<'_>,
 ) -> ReqResBuffer {
   let mut stream = client.stream().await.unwrap();
-  stream.send_req(rrb.as_http2_request(Method::Get), uri).await.unwrap().unwrap();
-  stream.recv_res(rrb).await.unwrap().0
+  let _ = stream.send_req(rrb.as_http2_request(Method::Get), uri).await.unwrap();
+  stream.recv_res(rrb).await.unwrap().1
 }
 
 #[track_caller]
diff --git a/wtx/src/http2/tests/hpack.rs b/wtx/src/http2/tests/hpack.rs
index c069cbc9..ab914055 100644
--- a/wtx/src/http2/tests/hpack.rs
+++ b/wtx/src/http2/tests/hpack.rs
@@ -1,6 +1,9 @@
 use crate::{
   http::{Header, StatusCode},
-  http2::{HpackDecoder, HpackEncoder, HpackHeaderBasic, MAX_HPACK_LEN},
+  http2::{
+    hpack_decoder::HpackDecoder, hpack_encoder::HpackEncoder, hpack_header::HpackHeaderBasic,
+    MAX_HPACK_LEN,
+  },
   misc::{from_utf8_basic, simple_seed, Vector, Xorshift64},
 };
 use alloc::string::String;
diff --git a/wtx/src/misc/blocks_queue/tests.rs b/wtx/src/misc/blocks_queue/tests.rs
new file mode 100644
index 00000000..57eead99
--- /dev/null
+++ b/wtx/src/misc/blocks_queue/tests.rs
@@ -0,0 +1,198 @@
+// H = Head (Inclusive)
+// LF = Left Free
+// LO = Left Occupied
+// RF = Right Free
+// RO = Right Occupied
+// T = Tail (Exclusive)
+
+use crate::misc::{blocks_queue::BlockRef, BlocksQueue};
+
+// [. . . . . . . .]: Empty - (LF=8, LO=0,RF=0, RO=0) - (H=0, T=0)
+// [. . . . . . . H]: Push front - (LF=7, LO=0, RF=0, RO=1) - (H=7, T=8)
+// [. . . . . H * *]: Push front - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
+// [. . H * * * * *]: Push front - (LF=2, LO=0, RF=0, RO=6) - (H=2, T=8)
+// [H * * * * * * *]: Push front - (LF=0, LO=0, RF=0, RO=8) - (H=0, T=8)
+// [H * * * * * * .]: Pop back - (LF=0, LO=0, RF=2, RO=6) - (H=0, T=7)
+// [* * * * * * * H]: Push front - (LF=0, LO=7, RF=0, RO=0) - (H=7, T=7)
+// [* * * * * . . H]: Pop back - (LF=2, LO=5, RF=0, RO=1) - (H=7, T=5)
+// [* * . . . . . H]: Pop back - (LF=5, LO=2, RF=0, RO=1) - (H=7, T=2)
+// [* * . . H * * *]: Push front - (LF=2, LO=2, RF=0, RO=4) - (H=4, T=2)
+// [* * H * * * * *]: Push front - (LF=0, LO=2, RF=0, RO=6) - (H=2, T=2)
+// [. . H * * * * *]: Pop back - (LF=2, LO=0, RF=0, RO=6) - (H=2, T=8)
+// [. . H * * * * .]: Pop back - (LF=2, LO=0, RF=1, RO=5) - (H=2, T=7)
+// [. . H * . . . .]: Pop back - (LF=1, LO=0, RF=4, RO=3) - (H=2, T=4)
+// [. H * * . . . .]: Push front - (LF=1, LO=0, RF=4, RO=3) - (H=2, T=4)
+// [H * * * . . . .]: Push front - (LF=0, LO=0, RF=4, RO=4) - (H=0, T=4)
+// [H . . . . . . .]: Pop back - (LF=0, LO=0, RF=7, RO=1) - (H=0, T=1)
+// [. . . . . . . .]: Pop back - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
+#[test]
+fn pop_back() {
+  let mut bq = BlocksQueue::with_exact_capacity(4, 8).unwrap();
+  check_state(&bq, 0, 0, &[], &[]);
+
+  bq.push_front([&[1][..]], ()).unwrap();
+  check_state(&bq, 1, 1, &[1], &[]);
+
+  bq.push_front([&[2, 3][..]], ()).unwrap();
+  check_state(&bq, 2, 3, &[2, 3, 1], &[]);
+
+  bq.push_front([&[4, 5], &[6][..]], ()).unwrap();
+  check_state(&bq, 3, 6, &[4, 5, 6, 2, 3, 1], &[]);
+
+  bq.push_front([&[7, 8][..]], ()).unwrap();
+  check_state(&bq, 4, 8, &[7, 8, 4, 5, 6, 2, 3, 1], &[]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 3, 7, &[7, 8, 4, 5, 6, 2, 3], &[]);
+
+  bq.push_front([&[9][..]], ()).unwrap();
+  check_state(&bq, 4, 8, &[9], &[7, 8, 4, 5, 6, 2, 3]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 3, 6, &[9], &[7, 8, 4, 5, 6]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 2, 3, &[9], &[7, 8]);
+
+  bq.push_front([&[10], &[11, 12][..]], ()).unwrap();
+  check_state(&bq, 3, 6, &[10, 11, 12, 9], &[7, 8]);
+
+  bq.push_front([&[13, 14][..]], ()).unwrap();
+  check_state(&bq, 4, 8, &[13, 14, 10, 11, 12, 9], &[7, 8]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 3, 6, &[13, 14, 10, 11, 12, 9], &[]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 2, 5, &[13, 14, 10, 11, 12], &[]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 1, 2, &[13, 14], &[]);
+
+  bq.push_front([&[15][..]], ()).unwrap();
+  check_state(&bq, 2, 3, &[15, 13, 14], &[]);
+
+  bq.push_front([&[16][..]], ()).unwrap();
+  check_state(&bq, 3, 4, &[16, 15, 13, 14], &[]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 2, 2, &[16, 15], &[]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 1, 1, &[16], &[]);
+
+  let _ = bq.pop_back();
+  check_state(&bq, 0, 0, &[], &[]);
+}
+
+// [. . . . . . . .]: Empty - (LF=8, LO=0,RF=0, RO=0) - (H=0, T=0)
+// [. . . . . H * *]: Push front - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
+// [H * * * * * * *]: Push front - (LF=0, LO=0, RF=0, RO=8) - (H=0, T=8)
+// [. . . . . H * *]: Push front - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
+// [. . . . . . . .]: Pop back - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
+#[test]
+fn pop_front() {
+  let mut bq = BlocksQueue::with_exact_capacity(2, 8).unwrap();
+  check_state(&bq, 0, 0, &[], &[]);
+
+  bq.push_front([&[1, 2, 3][..]], ()).unwrap();
+  check_state(&bq, 1, 3, &[1, 2, 3], &[]);
+
+  bq.push_front([&[4, 5], &[6, 7, 8][..]], ()).unwrap();
+  check_state(&bq, 2, 8, &[4, 5, 6, 7, 8, 1, 2, 3], &[]);
+
+  let _ = bq.pop_front();
+  check_state(&bq, 1, 3, &[1, 2, 3], &[]);
+
+  let _ = bq.pop_front();
+  check_state(&bq, 0, 0, &[], &[]);
+}
+
+// []: Empty - (LF=0, LO=0,RF=0, RO=0) - (H=0, T=0)
+// [H * * *]: Push front - (LF=0, LO=0, RF=0, RO=4) - (H=0, T=4)
+#[test]
+fn push_reserve_and_push() {
+  let mut bq = BlocksQueue::new();
+  bq.reserve_front(1, 4).unwrap();
+  bq.push_front([&[0, 1, 2, 3][..]], ()).unwrap();
+  check_state(&bq, 1, 4, &[0, 1, 2, 3], &[]);
+  assert_eq!(bq.get(0), Some(BlockRef { data: &[0, 1, 2, 3], misc: &(), range: 0..4 }));
+  assert_eq!(bq.get(1), None);
+  bq.reserve_front(1, 6).unwrap();
+  bq.push_front([&[4, 5, 6, 7, 8, 9][..]], ()).unwrap();
+  check_state(&bq, 2, 10, &[4, 5, 6, 7, 8, 9, 0, 1, 2, 3], &[]);
+  assert_eq!(bq.get(0), Some(BlockRef { data: &[4, 5, 6, 7, 8, 9], misc: &(), range: 0..6 }));
+  assert_eq!(bq.get(1), Some(BlockRef { data: &[0, 1, 2, 3], misc: &(), range: 6..10 }));
+  assert_eq!(bq.get(2), None);
+}
+
+// [. . . H * * . . ]: Pop back - (LF=5, LO=0, RF=0, RO=3) - (H=5, T=8)
+// [. . . . . . . . ]: Pop back - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
+#[test]
+fn wrap_pop_back() {
+  let mut bq = wrap_initial();
+  let _ = bq.pop_back();
+  let _ = bq.pop_back();
+  check_state(&bq, 1, 3, &[1, 2, 3], &[]);
+  assert_eq!(bq.get(0).unwrap().data, &[1, 2, 3]);
+  let _ = bq.pop_back();
+  check_state(&bq, 0, 0, &[], &[]);
+}
+
+// [. . . . . . H * ]: Pop front - (LF=2, LO=0, RF=4, RO=0) - (H=2, T=4)
+// [. . . . . . . . ]: Pop front - (LF=8, LO=0, RF=0, RO=0) - (H=0, T=0)
+#[test]
+fn wrap_pop_front() {
+  let mut bq = wrap_initial();
+  let _ = bq.pop_front();
+  check_state(&bq, 2, 2, &[0, 0], &[]);
+  assert_eq!(bq.get(0).unwrap().data, &[0]);
+  assert_eq!(bq.get(1).unwrap().data, &[0]);
+  let _ = bq.pop_front();
+  let _ = bq.pop_front();
+  check_state(&bq, 0, 0, &[], &[]);
+}
+
+// [. . . . . . . . ]: Empty - (LF=8, LO=0, RF=0, RO=0)
+// [. . H * * * * * ]: Push front - (LF=2, LO=0, RF=0, RO=6)
+// [. . H * . . . . ]: Pop back - (LF=2, LO=0, RF=4, RO=0)
+// [. . . H * * * * ]: Push front - (LF=3, LO=0, RF=0, RO=5)
+fn wrap_initial() -> BlocksQueue<i32, ()> {
+  let mut bq = BlocksQueue::with_exact_capacity(6, 8).unwrap();
+  check_state(&bq, 0, 0, &[], &[]);
+  for _ in 0..6 {
+    bq.push_front([&[0][..]], ()).unwrap();
+  }
+  check_state(&bq, 6, 6, &[0, 0, 0, 0, 0, 0], &[]);
+  for idx in 0..6 {
+    assert_eq!(bq.get(idx).unwrap().data, &[0]);
+  }
+  let _ = bq.pop_back();
+  let _ = bq.pop_back();
+  let _ = bq.pop_back();
+  let _ = bq.pop_back();
+  check_state(&bq, 2, 2, &[0, 0], &[]);
+  assert_eq!(bq.get(0).unwrap().data, &[0]);
+  assert_eq!(bq.get(1).unwrap().data, &[0]);
+  bq.push_front([&[1, 2, 3][..]], ()).unwrap();
+  check_state(&bq, 3, 5, &[1, 2, 3, 0, 0], &[]);
+  assert_eq!(bq.get(0).unwrap().data, &[1, 2, 3]);
+  assert_eq!(bq.get(1).unwrap().data, &[0]);
+  assert_eq!(bq.get(2).unwrap().data, &[0]);
+  bq
+}
+
+#[track_caller]
+fn check_state(
+  bq: &BlocksQueue<i32, ()>,
+  blocks_len: usize,
+  elements_len: usize,
+  front: &[i32],
+  back: &[i32],
+) {
+  let (local_front, local_back) = bq.as_slices();
+  assert_eq!(bq.blocks_len(), blocks_len);
+  assert_eq!(bq.elements_len(), elements_len);
+  assert_eq!(front, local_front);
+  assert_eq!(back, local_back);
+}
diff --git a/wtx/src/misc/queue/proptest.rs b/wtx/src/misc/queue/proptest.rs
new file mode 100644
index 00000000..0616fd1c
--- /dev/null
+++ b/wtx/src/misc/queue/proptest.rs
@@ -0,0 +1,42 @@
+use crate::misc::Queue;
+use alloc::{collections::VecDeque, vec::Vec};
+
+#[test_strategy::proptest]
+fn queue(bytes: Vec<u8>) {
+  let mut queue = Queue::with_capacity(bytes.len()).unwrap();
+  let mut vec_deque = VecDeque::with_capacity(bytes.len());
+
+  for byte in bytes.iter().copied() {
+    queue.push_front(byte).unwrap();
+    vec_deque.push_front(byte);
+  }
+  assert_eq!((queue.capacity(), queue.len()), (vec_deque.capacity(), vec_deque.len()));
+  for _ in 0..(bytes.len() / 2) {
+    assert_eq!(queue.as_slices(), vec_deque.as_slices());
+    assert_eq!(queue.get(0), vec_deque.get(0));
+    assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
+    assert_eq!(queue.pop_back(), vec_deque.pop_back());
+    assert_eq!(queue.as_slices(), vec_deque.as_slices());
+    assert_eq!(queue.get(0), vec_deque.get(0));
+    assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
+    assert_eq!(queue.pop_front(), vec_deque.pop_front());
+  }
+  loop {
+    if queue.len() == 0 {
+      break;
+    }
+    assert_eq!(queue.as_slices(), vec_deque.as_slices());
+    assert_eq!(queue.get(0), vec_deque.get(0));
+    assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
+    assert_eq!(queue.pop_back(), vec_deque.pop_back());
+    if queue.len() == 0 {
+      break;
+    }
+    assert_eq!(queue.as_slices(), vec_deque.as_slices());
+    assert_eq!(queue.get(0), vec_deque.get(0));
+    assert_eq!(queue.get_mut(0), vec_deque.get_mut(0));
+    assert_eq!(queue.pop_front(), vec_deque.pop_front());
+  }
+  assert_eq!((queue.capacity(), queue.len()), (vec_deque.capacity(), vec_deque.len()));
+  assert_eq!((queue.len(), vec_deque.len()), (0, 0));
+}
diff --git a/wtx/src/misc/queue/tests.rs b/wtx/src/misc/queue/tests.rs
new file mode 100644
index 00000000..2c541d49
--- /dev/null
+++ b/wtx/src/misc/queue/tests.rs
@@ -0,0 +1,225 @@
+use crate::misc::{queue::is_wrapping, Queue};
+
+#[test]
+fn as_slices() {
+  let mut queue = Queue::with_capacity(4).unwrap();
+  queue.push_front(1).unwrap();
+  queue.push_back(5).unwrap();
+  assert_eq!(queue.as_slices(), (&[1][..], &[5][..]));
+}
+
+#[test]
+fn clear() {
+  let mut queue = Queue::with_capacity(1).unwrap();
+  assert_eq!(queue.len(), 0);
+  queue.push_front(1).unwrap();
+  assert_eq!(queue.len(), 1);
+  queue.clear();
+  assert_eq!(queue.len(), 0);
+}
+
+#[test]
+fn get() {
+  let mut queue = Queue::with_capacity(1).unwrap();
+  assert_eq!(queue.get(0), None);
+  assert_eq!(queue.get_mut(0), None);
+  queue.push_front(1).unwrap();
+  assert_eq!(queue.get(0), Some(&1i32));
+  assert_eq!(queue.get_mut(0), Some(&mut 1i32));
+}
+
+#[test]
+fn heads_tails_and_slices() {
+  instances(
+    |_| (0, 1, &[1][..], &[][..]),
+    |_| (4, 0, &[1][..], &[][..]),
+    |_| (4, 1, &[1][..], &[2][..]),
+    |_| (0, 0, &[1, 2, 3, 4, 5][..], &[][..]),
+    |_| (4, 4, &[1][..], &[2, 3, 4, 5][..]),
+  );
+}
+
+#[test]
+fn impossible_instances() {
+  // . . . . H (4-5)
+  {
+    let mut queue = Queue::with_exact_capacity(5).unwrap();
+    queue.push_back(1).unwrap();
+    queue.push_back(1).unwrap();
+    queue.push_back(1).unwrap();
+    queue.push_back(1).unwrap();
+    queue.push_back(1).unwrap();
+    let _ = queue.pop_front().unwrap();
+    let _ = queue.pop_front().unwrap();
+    let _ = queue.pop_front().unwrap();
+    let _ = queue.pop_front().unwrap();
+    assert_eq!((queue.head, queue.tail, queue.as_slices()), (4, 0, (&[1][..], &[][..])));
+  }
+  // H * * * T (0-5)
+  {
+    let mut queue = Queue::with_exact_capacity(5).unwrap();
+    queue.push_back(1).unwrap();
+    queue.push_back(2).unwrap();
+    queue.push_back(3).unwrap();
+    queue.push_back(4).unwrap();
+    queue.push_back(5).unwrap();
+    assert_eq!(
+      (queue.head, queue.tail, queue.as_slices()),
+      (0, 0, (&[1, 2, 3, 4, 5][..], &[][..]))
+    );
+  }
+}
+
+#[test]
+fn pop_back() {
+  instances(
+    |queue| {
+      let _ = queue.pop_back().unwrap();
+      (0, 0, &[], &[])
+    },
+    |queue| {
+      let _ = queue.pop_back().unwrap();
+      (4, 4, &[], &[])
+    },
+    |queue| {
+      let _ = queue.pop_back().unwrap();
+      (4, 0, &[1], &[])
+    },
+    |queue| {
+      let _ = queue.pop_back().unwrap();
+      (0, 4, &[1, 2, 3, 4], &[])
+    },
+    |queue| {
+      let _ = queue.pop_back().unwrap();
+      (4, 3, &[1], &[2, 3, 4])
+    },
+  );
+}
+
+#[test]
+fn pop_front() {
+  instances(
+    |queue| {
+      let _ = queue.pop_front().unwrap();
+      (1, 1, &[], &[])
+    },
+    |queue| {
+      let _ = queue.pop_front().unwrap();
+      (0, 0, &[], &[])
+    },
+    |queue| {
+      let _ = queue.pop_front().unwrap();
+      (0, 1, &[2], &[])
+    },
+    |queue| {
+      let _ = queue.pop_front().unwrap();
+      (1, 0, &[2, 3, 4, 5], &[])
+    },
+    |queue| {
+      let _ = queue.pop_front().unwrap();
+      (0, 4, &[2, 3, 4, 5], &[])
+    },
+  );
+}
+
+#[test]
+fn push_front() {
+  let mut queue = Queue::with_capacity(1).unwrap();
+  assert_eq!(queue.len(), 0);
+  queue.push_front(1).unwrap();
+  assert_eq!(queue.len(), 1);
+}
+
+#[test]
+fn push_when_full() {
+  let mut bq = Queue::with_capacity(5).unwrap();
+  bq.push_front(0).unwrap();
+  bq.push_front(1).unwrap();
+  bq.push_front(2).unwrap();
+  bq.push_front(3).unwrap();
+  bq.push_front(4).unwrap();
+  let _ = bq.pop_back();
+  let _ = bq.pop_back();
+  bq.push_front(5).unwrap();
+  bq.push_front(6).unwrap();
+  assert_eq!(bq.as_slices(), (&[6, 5][..], &[4, 3, 2][..]));
+}
+
+#[test]
+fn reserve() {
+  let mut queue = Queue::<u8>::new();
+  assert_eq!(queue.capacity(), 0);
+  let _ = queue.reserve_back(10).unwrap();
+  assert!(queue.capacity() >= 10);
+  let _ = queue.reserve_front(20).unwrap();
+  assert!(queue.capacity() >= 20);
+}
+
+fn instances(
+  single_begin: impl FnOnce(&mut Queue<i32>) -> (usize, usize, &'static [i32], &'static [i32]),
+  single_end: impl FnOnce(&mut Queue<i32>) -> (usize, usize, &'static [i32], &'static [i32]),
+  single_both_sides: impl FnOnce(&mut Queue<i32>) -> (usize, usize, &'static [i32], &'static [i32]),
+  full_begin: impl FnOnce(&mut Queue<i32>) -> (usize, usize, &'static [i32], &'static [i32]),
+  full_end: impl FnOnce(&mut Queue<i32>) -> (usize, usize, &'static [i32], &'static [i32]),
+) {
+  // H . . . . (0-1)
+  {
+    let mut queue = Queue::with_exact_capacity(5).unwrap();
+    queue.push_back(1).unwrap();
+    let (head, tail, front, back) = single_begin(&mut queue);
+    verify_instance(&queue, head, tail, front, back);
+  }
+  // . . . . H (4-0)
+  {
+    let mut queue = Queue::with_exact_capacity(5).unwrap();
+    queue.push_front(1).unwrap();
+    let (head, tail, front, back) = single_end(&mut queue);
+    verify_instance(&queue, head, tail, front, back);
+  }
+  // T . . . H (4-1)
+  {
+    let mut queue = Queue::with_exact_capacity(5).unwrap();
+    queue.push_back(2).unwrap();
+    queue.push_front(1).unwrap();
+    let (head, tail, front, back) = single_both_sides(&mut queue);
+    verify_instance(&queue, head, tail, front, back);
+    // |_| (4, 1, &[1][..], &[2][..]),
+  }
+  // H * * * T (0-0)
+  {
+    let mut queue = Queue::with_exact_capacity(5).unwrap();
+    queue.push_front(5).unwrap();
+    queue.push_front(4).unwrap();
+    queue.push_front(3).unwrap();
+    queue.push_front(2).unwrap();
+    queue.push_front(1).unwrap();
+    let _ = queue.pop_front().unwrap();
+    queue.push_back(1).unwrap();
+    let _ = queue.pop_back().unwrap();
+    queue.push_front(1).unwrap();
+    let (head, tail, front, back) = full_begin(&mut queue);
+    verify_instance(&queue, head, tail, front, back);
+  }
+  // * * * T H (4-4)
+  {
+    let mut queue = Queue::with_exact_capacity(5).unwrap();
+    queue.push_front(1).unwrap();
+    queue.push_back(2).unwrap();
+    queue.push_back(3).unwrap();
+    queue.push_back(4).unwrap();
+    queue.push_back(5).unwrap();
+    let (head, tail, front, back) = full_end(&mut queue);
+    verify_instance(&queue, head, tail, front, back);
+  }
+}
+
+#[track_caller]
+fn verify_instance(queue: &Queue<i32>, head: usize, tail: usize, front: &[i32], back: &[i32]) {
+  assert_eq!((queue.head, queue.tail, queue.as_slices()), (head, tail, (front, back)));
+  assert_eq!(queue.len(), front.len() + back.len());
+  if is_wrapping(queue.head, queue.data.len(), queue.tail) {
+    assert!(!front.is_empty());
+  } else {
+    assert!(back.is_empty());
+  }
+}
diff --git a/wtx/src/web_socket/handshake/tests.rs b/wtx/src/web_socket/handshake/tests.rs
index a8dc26a5..339bcc3a 100644
--- a/wtx/src/web_socket/handshake/tests.rs
+++ b/wtx/src/web_socket/handshake/tests.rs
@@ -1,7 +1,7 @@
 macro_rules! call_tests {
-  (($ty:ident, $fb:expr, $ws:expr), $($struct:ident),+ $(,)?) => {
+  (($method:ident, $ws:expr), $($struct:ident),+ $(,)?) => {
     $(
-      $struct::$ty($fb, $ws).await;
+      $struct::$method($ws).await;
       tokio::time::sleep(Duration::from_millis(200)).await;
     )+
   };
@@ -11,9 +11,8 @@ use crate::{
   misc::{simple_seed, Xorshift64},
   tests::_uri,
   web_socket::{
-    compression::NegotiatedCompression, frame::FrameMutVec, Compression, FrameBufferVec, OpCode,
-    WebSocket, WebSocketBuffer, WebSocketClient, WebSocketClientOwned, WebSocketServer,
-    WebSocketServerOwned,
+    compression::NegotiatedCompression, Compression, Frame, OpCode, WebSocketBuffer,
+    WebSocketClient, WebSocketClientOwned, WebSocketServer, WebSocketServerOwned,
   },
 };
 use alloc::vec;
@@ -25,16 +24,9 @@ use tokio::net::{TcpListener, TcpStream};
 
 static HAS_SERVER_FINISHED: AtomicBool = AtomicBool::new(false);
 
-#[tokio::test]
-async fn client_and_server_frames() {
-  #[cfg(feature = "_tracing-tree")]
-  let _rslt = crate::misc::tracing_tree_init(None);
-  do_test_client_and_server_frames((), ()).await;
-}
-
 #[cfg(feature = "flate2")]
 #[tokio::test]
-async fn client_and_server_frames_compression() {
+async fn client_and_server_compressed() {
   use crate::web_socket::compression::Flate2;
   #[cfg(feature = "_tracing-tree")]
   let _rslt = crate::misc::tracing_tree_init(None);
@@ -45,6 +37,13 @@ async fn client_and_server_frames_compression() {
   do_test_client_and_server_frames(Flate2::default(), Flate2::default()).await;
 }
 
+#[tokio::test]
+async fn client_and_server_uncompressed() {
+  #[cfg(feature = "_tracing-tree")]
+  let _rslt = crate::misc::tracing_tree_init(None);
+  do_test_client_and_server_frames((), ()).await;
+}
+
 async fn do_test_client_and_server_frames<CC, SC>(client_compression: CC, server_compression: SC)
 where
   CC: Compression<true> + Send,
@@ -58,18 +57,17 @@ where
   let listener = TcpListener::bind(uri.hostname_with_implied_port()).await.unwrap();
   let _server_jh = tokio::spawn(async move {
     let (stream, _) = listener.accept().await.unwrap();
-    let mut fb = FrameBufferVec::with_capacity(0);
     let mut ws = WebSocketServer::accept(
       server_compression,
       Xorshift64::from(simple_seed()),
       stream,
-      WebSocketBuffer::with_capacity(0, 0).unwrap(),
+      WebSocketBuffer::new(),
       |_| crate::Result::Ok(()),
     )
     .await
     .unwrap();
     call_tests!(
-      (server, &mut fb, &mut ws),
+      (server, &mut ws),
       FragmentedText,
       LargeFragmentedText,
       PingAndText,
@@ -82,20 +80,19 @@ where
     HAS_SERVER_FINISHED.store(true, Ordering::Relaxed);
   });
 
-  let mut fb = FrameBufferVec::with_capacity(0);
   let mut ws = WebSocketClient::connect(
     client_compression,
     [],
     Xorshift64::from(simple_seed()),
     TcpStream::connect(uri.hostname_with_implied_port()).await.unwrap(),
     &uri.to_ref(),
-    WebSocketBuffer::with_capacity(0, 0).unwrap(),
+    WebSocketBuffer::new(),
     |_| crate::Result::Ok(()),
   )
   .await
   .unwrap();
   call_tests!(
-    (client, &mut fb, &mut ws),
+    (client, &mut ws),
     FragmentedText,
     LargeFragmentedText,
     PingAndText,
@@ -121,15 +118,9 @@ where
 }
 
 trait Test<NC> {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  );
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>);
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  );
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>);
 }
 
 struct FragmentedText;
@@ -137,21 +128,15 @@ impl<NC> Test<NC> for FragmentedText
 where
   NC: NegotiatedCompression,
 {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    write(FrameMutVec::new_unfin(fb, OpCode::Text, b"1").unwrap(), ws).await;
-    write(FrameMutVec::new_fin(fb, OpCode::Continuation, b"23").unwrap(), ws).await;
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>) {
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Text, &mut [b'1'])).await.unwrap();
+    ws.write_frame(&mut Frame::new_fin(OpCode::Continuation, &mut [b'2', b'3'])).await.unwrap();
   }
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    let text = ws.read_frame(fb).await.unwrap();
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>) {
+    let text = ws.read_frame().await.unwrap();
     assert_eq!(OpCode::Text, text.op_code());
-    assert_eq!(b"123", text.fb().payload());
+    assert_eq!(&[b'1', b'2', b'3'], text.payload());
   }
 }
 
@@ -160,24 +145,28 @@ impl<NC> Test<NC> for HelloAndGoodbye
 where
   NC: NegotiatedCompression,
 {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    let hello = ws.read_frame(fb).await.unwrap();
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>) {
+    let hello = ws.read_frame().await.unwrap();
     assert_eq!(OpCode::Text, hello.op_code());
-    assert_eq!(b"Hello!", hello.fb().payload());
-    write(FrameMutVec::new_fin(fb, OpCode::Text, b"Goodbye!").unwrap(), ws).await;
-    assert_eq!(OpCode::Close, ws.read_frame(fb).await.unwrap().op_code());
+    assert_eq!(b"Hello!", hello.payload());
+    ws.write_frame(&mut Frame::new_fin(
+      OpCode::Text,
+      &mut [b'G', b'o', b'o', b'd', b'b', b'y', b'e', b'!'],
+    ))
+    .await
+    .unwrap();
+    assert_eq!(OpCode::Close, ws.read_frame().await.unwrap().op_code());
   }
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    write(FrameMutVec::new_fin(fb, OpCode::Text, b"Hello!").unwrap(), ws).await;
-    assert_eq!(ws.read_frame(&mut *fb).await.unwrap().fb().payload(), b"Goodbye!");
-    write(FrameMutVec::new_fin(fb, OpCode::Close, &[]).unwrap(), ws).await;
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>) {
+    ws.write_frame(&mut Frame::new_fin(OpCode::Text, &mut [b'H', b'e', b'l', b'l', b'o', b'!']))
+      .await
+      .unwrap();
+    assert_eq!(
+      ws.read_frame().await.unwrap().payload(),
+      &mut [b'G', b'o', b'o', b'd', b'b', b'y', b'e', b'!']
+    );
+    ws.write_frame(&mut Frame::new_fin(OpCode::Close, &mut [])).await.unwrap();
   }
 }
 
@@ -186,30 +175,24 @@ impl<NC> Test<NC> for LargeFragmentedText
 where
   NC: NegotiatedCompression,
 {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    let bytes = vec![51; 256 * 1024];
-    write(FrameMutVec::new_unfin(fb, OpCode::Text, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
-    write(FrameMutVec::new_fin(fb, OpCode::Continuation, &bytes).unwrap(), ws).await;
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>) {
+    let bytes = || vec![b'1'; 256 * 1024];
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Text, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut bytes())).await.unwrap();
+    ws.write_frame(&mut Frame::new_fin(OpCode::Continuation, &mut bytes())).await.unwrap();
   }
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    let text = ws.read_frame(fb).await.unwrap();
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>) {
+    let text = ws.read_frame().await.unwrap();
     assert_eq!(OpCode::Text, text.op_code());
-    assert_eq!(&vec![51; 10 * 256 * 1024], text.fb().payload());
+    assert_eq!(&vec![b'1'; 10 * 256 * 1024], text.payload());
   }
 }
 
@@ -218,20 +201,14 @@ impl<NC> Test<NC> for PingAndText
 where
   NC: NegotiatedCompression,
 {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    write(FrameMutVec::new_fin(fb, OpCode::Ping, b"123").unwrap(), ws).await;
-    write(FrameMutVec::new_fin(fb, OpCode::Text, b"ipat").unwrap(), ws).await;
-    assert_eq!(OpCode::Pong, ws.read_frame(fb).await.unwrap().op_code());
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>) {
+    ws.write_frame(&mut Frame::new_fin(OpCode::Ping, &mut [1, 2, 3])).await.unwrap();
+    ws.write_frame(&mut Frame::new_fin(OpCode::Text, &mut [b'i', b'p', b'a', b't'])).await.unwrap();
+    assert_eq!(OpCode::Pong, ws.read_frame().await.unwrap().op_code());
   }
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    assert_eq!(b"ipat", ws.read_frame(fb).await.unwrap().fb().payload());
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>) {
+    assert_eq!(b"ipat", ws.read_frame().await.unwrap().payload());
   }
 }
 
@@ -240,21 +217,17 @@ impl<NC> Test<NC> for PingBetweenFragmentedText
 where
   NC: NegotiatedCompression,
 {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    write(FrameMutVec::new_unfin(fb, OpCode::Text, b"1").unwrap(), ws).await;
-    write(FrameMutVec::new_fin(fb, OpCode::Ping, b"9").unwrap(), ws).await;
-    write(FrameMutVec::new_fin(fb, OpCode::Continuation, b"23").unwrap(), ws).await;
-    assert_eq!(OpCode::Pong, ws.read_frame(fb).await.unwrap().op_code());
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>) {
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Text, &mut [b'1'])).await.unwrap();
+    ws.write_frame(&mut Frame::new_fin(OpCode::Ping, &mut [b'9'])).await.unwrap();
+    ws.write_frame(&mut Frame::new_fin(OpCode::Continuation, &mut [b'2', b'3'])).await.unwrap();
+    assert_eq!(OpCode::Pong, ws.read_frame().await.unwrap().op_code());
   }
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    assert_eq!(OpCode::Text, ws.read_frame(fb).await.unwrap().op_code());
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>) {
+    let text = ws.read_frame().await.unwrap();
+    assert_eq!(OpCode::Text, text.op_code());
+    assert_eq!(&[b'1', b'2', b'3'], text.payload());
   }
 }
 
@@ -263,31 +236,25 @@ impl<NC> Test<NC> for SeveralBytes
 where
   NC: NegotiatedCompression,
 {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    write(FrameMutVec::new_unfin(fb, OpCode::Text, &[206]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[186]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[225]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[189]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[185]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[207]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[131]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[206]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[188]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[206]).unwrap(), ws).await;
-    write(FrameMutVec::new_unfin(fb, OpCode::Continuation, &[181]).unwrap(), ws).await;
-    write(FrameMutVec::new_fin(fb, OpCode::Continuation, &[]).unwrap(), ws).await;
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>) {
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Text, &mut [206])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [186])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [225])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [189])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [185])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [207])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [131])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [206])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [188])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [206])).await.unwrap();
+    ws.write_frame(&mut Frame::new_unfin(OpCode::Continuation, &mut [181])).await.unwrap();
+    ws.write_frame(&mut Frame::new_fin(OpCode::Continuation, &mut [])).await.unwrap();
   }
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    let text = ws.read_frame(fb).await.unwrap();
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>) {
+    let text = ws.read_frame().await.unwrap();
     assert_eq!(OpCode::Text, text.op_code());
-    assert_eq!("κόσμε".as_bytes(), text.fb().payload());
+    assert_eq!("κόσμε".as_bytes(), *text.payload());
   }
 }
 
@@ -296,36 +263,21 @@ impl<NC> Test<NC> for TwoPings
 where
   NC: NegotiatedCompression,
 {
-  async fn client(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketClientOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    write(FrameMutVec::new_fin(fb, OpCode::Ping, b"0").unwrap(), ws).await;
-    write(FrameMutVec::new_fin(fb, OpCode::Ping, b"1").unwrap(), ws).await;
-    let _0 = ws.read_frame(fb).await.unwrap();
+  async fn client(ws: &mut WebSocketClientOwned<NC, TcpStream>) {
+    ws.write_frame(&mut Frame::new_fin(OpCode::Ping, &mut [b'0'])).await.unwrap();
+    ws.write_frame(&mut Frame::new_fin(OpCode::Ping, &mut [b'1'])).await.unwrap();
+    let _0 = ws.read_frame().await.unwrap();
     assert_eq!(OpCode::Pong, _0.op_code());
-    assert_eq!(b"0", _0.fb().payload());
-    let _1 = ws.read_frame(fb).await.unwrap();
+    assert_eq!(b"0", _0.payload());
+    let _1 = ws.read_frame().await.unwrap();
     assert_eq!(OpCode::Pong, _1.op_code());
-    assert_eq!(b"1", _1.fb().payload());
-    write(FrameMutVec::new_fin(fb, OpCode::Text, b"").unwrap(), ws).await;
+    assert_eq!(b"1", _1.payload());
+    ws.write_frame(&mut Frame::new_fin(OpCode::Text, &mut [])).await.unwrap();
   }
 
-  async fn server(
-    fb: &mut FrameBufferVec,
-    ws: &mut WebSocketServerOwned<NC, Xorshift64, TcpStream>,
-  ) {
-    let _0 = ws.read_frame(fb).await.unwrap();
+  async fn server(ws: &mut WebSocketServerOwned<NC, TcpStream>) {
+    let _0 = ws.read_frame().await.unwrap();
     assert_eq!(OpCode::Text, _0.op_code());
-    assert_eq!(b"", _0.fb().payload());
+    assert_eq!(b"", _0.payload());
   }
 }
-
-async fn write<NC, const IS_CLIENT: bool>(
-  mut frame: FrameMutVec<'_, IS_CLIENT>,
-  ws: &mut WebSocket<NC, Xorshift64, TcpStream, WebSocketBuffer, IS_CLIENT>,
-) where
-  NC: NegotiatedCompression,
-{
-  ws.write_frame(&mut frame).await.unwrap();
-}