wse-server 2.1.0__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {wse_server-2.1.0 → wse_server-2.2.0}/PKG-INFO +12 -5
  2. {wse_server-2.1.0 → wse_server-2.2.0}/README.md +11 -4
  3. {wse_server-2.1.0 → wse_server-2.2.0}/pyproject.toml +1 -1
  4. {wse_server-2.1.0 → wse_server-2.2.0}/rust/Cargo.lock +65 -122
  5. {wse_server-2.1.0 → wse_server-2.2.0}/rust/Cargo.toml +6 -5
  6. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/jwt.rs +12 -11
  7. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/cluster.rs +345 -183
  8. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/presence.rs +4 -2
  9. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/queue.rs +2 -7
  10. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/recovery.rs +6 -3
  11. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/sequencer.rs +0 -8
  12. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/server.rs +835 -305
  13. {wse_server-2.1.0 → wse_server-2.2.0}/wse_server/__init__.py +1 -1
  14. {wse_server-2.1.0 → wse_server-2.2.0}/LICENSE +0 -0
  15. {wse_server-2.1.0 → wse_server-2.2.0}/rust/.cargo/config.toml +0 -0
  16. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/lib.rs +0 -0
  17. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/compression.rs +0 -0
  18. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/filters.rs +0 -0
  19. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/mod.rs +0 -0
  20. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/rate_limiter.rs +0 -0
  21. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/reliability.rs +0 -0
  22. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/security.rs +0 -0
  23. {wse_server-2.1.0 → wse_server-2.2.0}/rust/src/wse/transformer.rs +0 -0
  24. {wse_server-2.1.0 → wse_server-2.2.0}/wse_server/_wse_accel.pyi +0 -0
  25. {wse_server-2.1.0 → wse_server-2.2.0}/wse_server/core/__init__.py +0 -0
  26. {wse_server-2.1.0 → wse_server-2.2.0}/wse_server/core/filters.py +0 -0
  27. {wse_server-2.1.0 → wse_server-2.2.0}/wse_server/core/types.py +0 -0
  28. {wse_server-2.1.0 → wse_server-2.2.0}/wse_server/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wse-server
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -216,6 +216,13 @@ token = rust_jwt_encode(
216
216
  | `presence_enabled` | False | Enable per-topic presence tracking |
217
217
  | `presence_max_data_size` | 4096 | Max bytes for a user's presence metadata |
218
218
  | `presence_max_members` | 0 | Max tracked members per topic (0 = unlimited) |
219
+ | `max_outbound_queue_bytes` | 16777216 | Per-connection outbound buffer limit (bytes, default 16 MB). Messages dropped when exceeded |
220
+ | `jwt_cookie_name` | "access_token" | Cookie name for JWT token extraction |
221
+ | `rate_limit_capacity` | 100000.0 | Token bucket capacity per connection |
222
+ | `rate_limit_refill` | 10000.0 | Token bucket refill rate per second |
223
+ | `max_message_size` | 1048576 | Maximum WebSocket frame size in bytes (default 1 MB) |
224
+ | `ping_interval` | 25 | Server-initiated ping interval in seconds |
225
+ | `idle_timeout` | 60 | Force-close connections idle for this many seconds |
219
226
 
220
227
  ---
221
228
 
@@ -444,9 +451,9 @@ Full security documentation: [docs/SECURITY.md](docs/SECURITY.md)
444
451
 
445
452
  ## Wire Protocol
446
453
 
447
- WSE uses a custom wire protocol with category-prefixed messages:
454
+ WSE uses a custom wire protocol with categorized JSON messages:
448
455
 
449
- **Text frames:** `WSE{...}` (system), `S{...}` (snapshot), `U{...}` (update) + JSON envelope
456
+ **Text frames:** JSON with `c` field for category: `"WSE"` (system), `"S"` (snapshot), `"U"` (update)
450
457
 
451
458
  **Binary frames:** `C:` (zlib compressed), `M:` (MessagePack), `E:` (AES-GCM encrypted), raw zlib (0x78 magic byte)
452
459
 
@@ -540,10 +547,10 @@ Benchmarked on AMD EPYC 7502P (32 cores / 64 threads, 128 GB RAM), Ubuntu 24.04.
540
547
 
541
548
  | Mode | Peak Throughput | Connections | Message Loss |
542
549
  |------|----------------|-------------|--------------|
543
- | Standalone (fan-out) | 5.0M deliveries/s | 500K | 0% |
550
+ | Standalone (fan-out) | 4.7M deliveries/s | 100K | 0% |
544
551
  | Standalone (inbound JSON) | 14.7M msg/s | 500K | 0% |
545
552
  | Standalone (inbound msgpack) | 30M msg/s | 500K | 0% |
546
- | Cluster (2 nodes) | 9.5M deliveries/s | 20K per node | 0% |
553
+ | Cluster (2 nodes, 50/50) | 6.6M deliveries/s | 500 per node | 0% |
547
554
 
548
555
  Sub-millisecond latency. Median 0.38ms with JWT authentication. Connection handshake: 0.53ms median (Rust JWT path).
549
556
 
@@ -175,6 +175,13 @@ token = rust_jwt_encode(
175
175
  | `presence_enabled` | False | Enable per-topic presence tracking |
176
176
  | `presence_max_data_size` | 4096 | Max bytes for a user's presence metadata |
177
177
  | `presence_max_members` | 0 | Max tracked members per topic (0 = unlimited) |
178
+ | `max_outbound_queue_bytes` | 16777216 | Per-connection outbound buffer limit (bytes, default 16 MB). Messages dropped when exceeded |
179
+ | `jwt_cookie_name` | "access_token" | Cookie name for JWT token extraction |
180
+ | `rate_limit_capacity` | 100000.0 | Token bucket capacity per connection |
181
+ | `rate_limit_refill` | 10000.0 | Token bucket refill rate per second |
182
+ | `max_message_size` | 1048576 | Maximum WebSocket frame size in bytes (default 1 MB) |
183
+ | `ping_interval` | 25 | Server-initiated ping interval in seconds |
184
+ | `idle_timeout` | 60 | Force-close connections idle for this many seconds |
178
185
 
179
186
  ---
180
187
 
@@ -403,9 +410,9 @@ Full security documentation: [docs/SECURITY.md](docs/SECURITY.md)
403
410
 
404
411
  ## Wire Protocol
405
412
 
406
- WSE uses a custom wire protocol with category-prefixed messages:
413
+ WSE uses a custom wire protocol with categorized JSON messages:
407
414
 
408
- **Text frames:** `WSE{...}` (system), `S{...}` (snapshot), `U{...}` (update) + JSON envelope
415
+ **Text frames:** JSON with `c` field for category: `"WSE"` (system), `"S"` (snapshot), `"U"` (update)
409
416
 
410
417
  **Binary frames:** `C:` (zlib compressed), `M:` (MessagePack), `E:` (AES-GCM encrypted), raw zlib (0x78 magic byte)
411
418
 
@@ -499,10 +506,10 @@ Benchmarked on AMD EPYC 7502P (32 cores / 64 threads, 128 GB RAM), Ubuntu 24.04.
499
506
 
500
507
  | Mode | Peak Throughput | Connections | Message Loss |
501
508
  |------|----------------|-------------|--------------|
502
- | Standalone (fan-out) | 5.0M deliveries/s | 500K | 0% |
509
+ | Standalone (fan-out) | 4.7M deliveries/s | 100K | 0% |
503
510
  | Standalone (inbound JSON) | 14.7M msg/s | 500K | 0% |
504
511
  | Standalone (inbound msgpack) | 30M msg/s | 500K | 0% |
505
- | Cluster (2 nodes) | 9.5M deliveries/s | 20K per node | 0% |
512
+ | Cluster (2 nodes, 50/50) | 6.6M deliveries/s | 500 per node | 0% |
506
513
 
507
514
  Sub-millisecond latency. Median 0.38ms with JWT authentication. Connection handshake: 0.53ms median (Rust JWT path).
508
515
 
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "wse-server"
7
- version = "2.1.0"
7
+ version = "2.2.0"
8
8
  description = "Rust-powered WebSocket engine for Python. Up to 5M fan-out del/s. Zero-GIL JWT."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -88,9 +88,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
88
88
 
89
89
  [[package]]
90
90
  name = "aws-lc-rs"
91
- version = "1.16.0"
91
+ version = "1.16.1"
92
92
  source = "registry+https://github.com/rust-lang/crates.io-index"
93
- checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9"
93
+ checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf"
94
94
  dependencies = [
95
95
  "aws-lc-sys",
96
96
  "zeroize",
@@ -98,9 +98,9 @@ dependencies = [
98
98
 
99
99
  [[package]]
100
100
  name = "aws-lc-sys"
101
- version = "0.37.1"
101
+ version = "0.38.0"
102
102
  source = "registry+https://github.com/rust-lang/crates.io-index"
103
- checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549"
103
+ checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e"
104
104
  dependencies = [
105
105
  "cc",
106
106
  "cmake",
@@ -485,19 +485,19 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
485
485
  dependencies = [
486
486
  "cfg-if",
487
487
  "libc",
488
- "r-efi",
488
+ "r-efi 5.3.0",
489
489
  "wasip2",
490
490
  ]
491
491
 
492
492
  [[package]]
493
493
  name = "getrandom"
494
- version = "0.4.1"
494
+ version = "0.4.2"
495
495
  source = "registry+https://github.com/rust-lang/crates.io-index"
496
- checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
496
+ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
497
497
  dependencies = [
498
498
  "cfg-if",
499
499
  "libc",
500
- "r-efi",
500
+ "r-efi 6.0.0",
501
501
  "wasip2",
502
502
  "wasip3",
503
503
  ]
@@ -659,9 +659,9 @@ dependencies = [
659
659
 
660
660
  [[package]]
661
661
  name = "js-sys"
662
- version = "0.3.90"
662
+ version = "0.3.91"
663
663
  source = "registry+https://github.com/rust-lang/crates.io-index"
664
- checksum = "14dc6f6450b3f6d4ed5b16327f38fed626d375a886159ca555bd7822c0c3a5a6"
664
+ checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c"
665
665
  dependencies = [
666
666
  "once_cell",
667
667
  "wasm-bindgen",
@@ -779,6 +779,16 @@ dependencies = [
779
779
  "sha2",
780
780
  ]
781
781
 
782
+ [[package]]
783
+ name = "parking_lot"
784
+ version = "0.12.5"
785
+ source = "registry+https://github.com/rust-lang/crates.io-index"
786
+ checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
787
+ dependencies = [
788
+ "lock_api",
789
+ "parking_lot_core",
790
+ ]
791
+
782
792
  [[package]]
783
793
  name = "parking_lot_core"
784
794
  version = "0.9.12"
@@ -813,9 +823,9 @@ dependencies = [
813
823
 
814
824
  [[package]]
815
825
  name = "pin-project-lite"
816
- version = "0.2.16"
826
+ version = "0.2.17"
817
827
  source = "registry+https://github.com/rust-lang/crates.io-index"
818
- checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
828
+ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
819
829
 
820
830
  [[package]]
821
831
  name = "pkcs8"
@@ -954,9 +964,9 @@ dependencies = [
954
964
 
955
965
  [[package]]
956
966
  name = "quote"
957
- version = "1.0.44"
967
+ version = "1.0.45"
958
968
  source = "registry+https://github.com/rust-lang/crates.io-index"
959
- checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
969
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
960
970
  dependencies = [
961
971
  "proc-macro2",
962
972
  ]
@@ -967,6 +977,12 @@ version = "5.3.0"
967
977
  source = "registry+https://github.com/rust-lang/crates.io-index"
968
978
  checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
969
979
 
980
+ [[package]]
981
+ name = "r-efi"
982
+ version = "6.0.0"
983
+ source = "registry+https://github.com/rust-lang/crates.io-index"
984
+ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
985
+
970
986
  [[package]]
971
987
  name = "rand"
972
988
  version = "0.9.2"
@@ -1288,12 +1304,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
1288
1304
 
1289
1305
  [[package]]
1290
1306
  name = "socket2"
1291
- version = "0.6.2"
1307
+ version = "0.6.3"
1292
1308
  source = "registry+https://github.com/rust-lang/crates.io-index"
1293
- checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0"
1309
+ checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
1294
1310
  dependencies = [
1295
1311
  "libc",
1296
- "windows-sys 0.60.2",
1312
+ "windows-sys 0.61.2",
1297
1313
  ]
1298
1314
 
1299
1315
  [[package]]
@@ -1370,9 +1386,9 @@ checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
1370
1386
 
1371
1387
  [[package]]
1372
1388
  name = "tokio"
1373
- version = "1.49.0"
1389
+ version = "1.50.0"
1374
1390
  source = "registry+https://github.com/rust-lang/crates.io-index"
1375
- checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
1391
+ checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
1376
1392
  dependencies = [
1377
1393
  "bytes",
1378
1394
  "libc",
@@ -1385,9 +1401,9 @@ dependencies = [
1385
1401
 
1386
1402
  [[package]]
1387
1403
  name = "tokio-macros"
1388
- version = "2.6.0"
1404
+ version = "2.6.1"
1389
1405
  source = "registry+https://github.com/rust-lang/crates.io-index"
1390
- checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
1406
+ checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
1391
1407
  dependencies = [
1392
1408
  "proc-macro2",
1393
1409
  "quote",
@@ -1489,11 +1505,11 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
1489
1505
 
1490
1506
  [[package]]
1491
1507
  name = "uuid"
1492
- version = "1.21.0"
1508
+ version = "1.22.0"
1493
1509
  source = "registry+https://github.com/rust-lang/crates.io-index"
1494
- checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb"
1510
+ checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
1495
1511
  dependencies = [
1496
- "getrandom 0.4.1",
1512
+ "getrandom 0.4.2",
1497
1513
  "js-sys",
1498
1514
  "wasm-bindgen",
1499
1515
  ]
@@ -1530,9 +1546,9 @@ dependencies = [
1530
1546
 
1531
1547
  [[package]]
1532
1548
  name = "wasm-bindgen"
1533
- version = "0.2.113"
1549
+ version = "0.2.114"
1534
1550
  source = "registry+https://github.com/rust-lang/crates.io-index"
1535
- checksum = "60722a937f594b7fde9adb894d7c092fc1bb6612897c46368d18e7a20208eff2"
1551
+ checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e"
1536
1552
  dependencies = [
1537
1553
  "cfg-if",
1538
1554
  "once_cell",
@@ -1543,9 +1559,9 @@ dependencies = [
1543
1559
 
1544
1560
  [[package]]
1545
1561
  name = "wasm-bindgen-macro"
1546
- version = "0.2.113"
1562
+ version = "0.2.114"
1547
1563
  source = "registry+https://github.com/rust-lang/crates.io-index"
1548
- checksum = "0fac8c6395094b6b91c4af293f4c79371c163f9a6f56184d2c9a85f5a95f3950"
1564
+ checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6"
1549
1565
  dependencies = [
1550
1566
  "quote",
1551
1567
  "wasm-bindgen-macro-support",
@@ -1553,9 +1569,9 @@ dependencies = [
1553
1569
 
1554
1570
  [[package]]
1555
1571
  name = "wasm-bindgen-macro-support"
1556
- version = "0.2.113"
1572
+ version = "0.2.114"
1557
1573
  source = "registry+https://github.com/rust-lang/crates.io-index"
1558
- checksum = "ab3fabce6159dc20728033842636887e4877688ae94382766e00b180abac9d60"
1574
+ checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3"
1559
1575
  dependencies = [
1560
1576
  "bumpalo",
1561
1577
  "proc-macro2",
@@ -1566,9 +1582,9 @@ dependencies = [
1566
1582
 
1567
1583
  [[package]]
1568
1584
  name = "wasm-bindgen-shared"
1569
- version = "0.2.113"
1585
+ version = "0.2.114"
1570
1586
  source = "registry+https://github.com/rust-lang/crates.io-index"
1571
- checksum = "de0e091bdb824da87dc01d967388880d017a0a9bc4f3bdc0d86ee9f9336e3bb5"
1587
+ checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16"
1572
1588
  dependencies = [
1573
1589
  "unicode-ident",
1574
1590
  ]
@@ -1672,16 +1688,7 @@ version = "0.52.0"
1672
1688
  source = "registry+https://github.com/rust-lang/crates.io-index"
1673
1689
  checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
1674
1690
  dependencies = [
1675
- "windows-targets 0.52.6",
1676
- ]
1677
-
1678
- [[package]]
1679
- name = "windows-sys"
1680
- version = "0.60.2"
1681
- source = "registry+https://github.com/rust-lang/crates.io-index"
1682
- checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
1683
- dependencies = [
1684
- "windows-targets 0.53.5",
1691
+ "windows-targets",
1685
1692
  ]
1686
1693
 
1687
1694
  [[package]]
@@ -1699,31 +1706,14 @@ version = "0.52.6"
1699
1706
  source = "registry+https://github.com/rust-lang/crates.io-index"
1700
1707
  checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
1701
1708
  dependencies = [
1702
- "windows_aarch64_gnullvm 0.52.6",
1703
- "windows_aarch64_msvc 0.52.6",
1704
- "windows_i686_gnu 0.52.6",
1705
- "windows_i686_gnullvm 0.52.6",
1706
- "windows_i686_msvc 0.52.6",
1707
- "windows_x86_64_gnu 0.52.6",
1708
- "windows_x86_64_gnullvm 0.52.6",
1709
- "windows_x86_64_msvc 0.52.6",
1710
- ]
1711
-
1712
- [[package]]
1713
- name = "windows-targets"
1714
- version = "0.53.5"
1715
- source = "registry+https://github.com/rust-lang/crates.io-index"
1716
- checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
1717
- dependencies = [
1718
- "windows-link",
1719
- "windows_aarch64_gnullvm 0.53.1",
1720
- "windows_aarch64_msvc 0.53.1",
1721
- "windows_i686_gnu 0.53.1",
1722
- "windows_i686_gnullvm 0.53.1",
1723
- "windows_i686_msvc 0.53.1",
1724
- "windows_x86_64_gnu 0.53.1",
1725
- "windows_x86_64_gnullvm 0.53.1",
1726
- "windows_x86_64_msvc 0.53.1",
1709
+ "windows_aarch64_gnullvm",
1710
+ "windows_aarch64_msvc",
1711
+ "windows_i686_gnu",
1712
+ "windows_i686_gnullvm",
1713
+ "windows_i686_msvc",
1714
+ "windows_x86_64_gnu",
1715
+ "windows_x86_64_gnullvm",
1716
+ "windows_x86_64_msvc",
1727
1717
  ]
1728
1718
 
1729
1719
  [[package]]
@@ -1732,96 +1722,48 @@ version = "0.52.6"
1732
1722
  source = "registry+https://github.com/rust-lang/crates.io-index"
1733
1723
  checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
1734
1724
 
1735
- [[package]]
1736
- name = "windows_aarch64_gnullvm"
1737
- version = "0.53.1"
1738
- source = "registry+https://github.com/rust-lang/crates.io-index"
1739
- checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
1740
-
1741
1725
  [[package]]
1742
1726
  name = "windows_aarch64_msvc"
1743
1727
  version = "0.52.6"
1744
1728
  source = "registry+https://github.com/rust-lang/crates.io-index"
1745
1729
  checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
1746
1730
 
1747
- [[package]]
1748
- name = "windows_aarch64_msvc"
1749
- version = "0.53.1"
1750
- source = "registry+https://github.com/rust-lang/crates.io-index"
1751
- checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
1752
-
1753
1731
  [[package]]
1754
1732
  name = "windows_i686_gnu"
1755
1733
  version = "0.52.6"
1756
1734
  source = "registry+https://github.com/rust-lang/crates.io-index"
1757
1735
  checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
1758
1736
 
1759
- [[package]]
1760
- name = "windows_i686_gnu"
1761
- version = "0.53.1"
1762
- source = "registry+https://github.com/rust-lang/crates.io-index"
1763
- checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
1764
-
1765
1737
  [[package]]
1766
1738
  name = "windows_i686_gnullvm"
1767
1739
  version = "0.52.6"
1768
1740
  source = "registry+https://github.com/rust-lang/crates.io-index"
1769
1741
  checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
1770
1742
 
1771
- [[package]]
1772
- name = "windows_i686_gnullvm"
1773
- version = "0.53.1"
1774
- source = "registry+https://github.com/rust-lang/crates.io-index"
1775
- checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
1776
-
1777
1743
  [[package]]
1778
1744
  name = "windows_i686_msvc"
1779
1745
  version = "0.52.6"
1780
1746
  source = "registry+https://github.com/rust-lang/crates.io-index"
1781
1747
  checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
1782
1748
 
1783
- [[package]]
1784
- name = "windows_i686_msvc"
1785
- version = "0.53.1"
1786
- source = "registry+https://github.com/rust-lang/crates.io-index"
1787
- checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
1788
-
1789
1749
  [[package]]
1790
1750
  name = "windows_x86_64_gnu"
1791
1751
  version = "0.52.6"
1792
1752
  source = "registry+https://github.com/rust-lang/crates.io-index"
1793
1753
  checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
1794
1754
 
1795
- [[package]]
1796
- name = "windows_x86_64_gnu"
1797
- version = "0.53.1"
1798
- source = "registry+https://github.com/rust-lang/crates.io-index"
1799
- checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
1800
-
1801
1755
  [[package]]
1802
1756
  name = "windows_x86_64_gnullvm"
1803
1757
  version = "0.52.6"
1804
1758
  source = "registry+https://github.com/rust-lang/crates.io-index"
1805
1759
  checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
1806
1760
 
1807
- [[package]]
1808
- name = "windows_x86_64_gnullvm"
1809
- version = "0.53.1"
1810
- source = "registry+https://github.com/rust-lang/crates.io-index"
1811
- checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
1812
-
1813
1761
  [[package]]
1814
1762
  name = "windows_x86_64_msvc"
1815
1763
  version = "0.52.6"
1816
1764
  source = "registry+https://github.com/rust-lang/crates.io-index"
1817
1765
  checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
1818
1766
 
1819
- [[package]]
1820
- name = "windows_x86_64_msvc"
1821
- version = "0.53.1"
1822
- source = "registry+https://github.com/rust-lang/crates.io-index"
1823
- checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
1824
-
1825
1767
  [[package]]
1826
1768
  name = "wit-bindgen"
1827
1769
  version = "0.51.0"
@@ -1912,7 +1854,7 @@ dependencies = [
1912
1854
 
1913
1855
  [[package]]
1914
1856
  name = "wse-accel"
1915
- version = "2.1.0"
1857
+ version = "2.2.0"
1916
1858
  dependencies = [
1917
1859
  "aes-gcm",
1918
1860
  "ahash",
@@ -1928,6 +1870,7 @@ dependencies = [
1928
1870
  "hmac",
1929
1871
  "mimalloc",
1930
1872
  "p256",
1873
+ "parking_lot",
1931
1874
  "pyo3",
1932
1875
  "rcgen",
1933
1876
  "regex",
@@ -1958,18 +1901,18 @@ dependencies = [
1958
1901
 
1959
1902
  [[package]]
1960
1903
  name = "zerocopy"
1961
- version = "0.8.39"
1904
+ version = "0.8.40"
1962
1905
  source = "registry+https://github.com/rust-lang/crates.io-index"
1963
- checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a"
1906
+ checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5"
1964
1907
  dependencies = [
1965
1908
  "zerocopy-derive",
1966
1909
  ]
1967
1910
 
1968
1911
  [[package]]
1969
1912
  name = "zerocopy-derive"
1970
- version = "0.8.39"
1913
+ version = "0.8.40"
1971
1914
  source = "registry+https://github.com/rust-lang/crates.io-index"
1972
- checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517"
1915
+ checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953"
1973
1916
  dependencies = [
1974
1917
  "proc-macro2",
1975
1918
  "quote",
@@ -1984,9 +1927,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
1984
1927
 
1985
1928
  [[package]]
1986
1929
  name = "zlib-rs"
1987
- version = "0.6.2"
1930
+ version = "0.6.3"
1988
1931
  source = "registry+https://github.com/rust-lang/crates.io-index"
1989
- checksum = "c745c48e1007337ed136dc99df34128b9faa6ed542d80a1c673cf55a6d7236c8"
1932
+ checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513"
1990
1933
 
1991
1934
  [[package]]
1992
1935
  name = "zmij"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "wse-accel"
3
- version = "2.1.0"
3
+ version = "2.2.0"
4
4
  edition = "2024"
5
5
 
6
6
  [lib]
@@ -13,7 +13,7 @@ serde = { version = "1.0.228", features = ["derive"] }
13
13
  serde_json = "1.0.149"
14
14
  flate2 = { version = "1.1.9", default-features = false, features = ["zlib-rs"] }
15
15
  rmp-serde = "1.3.1"
16
- rmpv = "1.3.0"
16
+ rmpv = "1.3.1"
17
17
  hmac = "0.12.1"
18
18
  sha2 = "0.10.9"
19
19
  hex = "0.4"
@@ -22,11 +22,11 @@ dashmap = "6"
22
22
  aes-gcm = "0.10"
23
23
  p256 = { version = "0.13", features = ["ecdh", "jwk"] }
24
24
  hkdf = "0.12"
25
- uuid = { version = "1.21.0", features = ["v7"] }
25
+ uuid = { version = "1.22.0", features = ["v7"] }
26
26
  base64 = "0.22"
27
- chrono = { version = "0.4.43", features = ["serde"] }
27
+ chrono = { version = "0.4.44", features = ["serde"] }
28
28
  regex = "1.12.3"
29
- tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros", "sync", "net", "time", "io-util"] }
29
+ tokio = { version = "1.50.0", features = ["rt-multi-thread", "macros", "sync", "net", "time", "io-util"] }
30
30
  tokio-tungstenite = "0.28.0"
31
31
  futures-util = "0.3.32"
32
32
  crossbeam-channel = "0.5"
@@ -38,6 +38,7 @@ tokio-rustls = "0.26"
38
38
  rustls = { version = "0.23", default-features = true }
39
39
  rustls-pki-types = "1"
40
40
  zstd = "0.13"
41
+ parking_lot = "0.12"
41
42
 
42
43
  [dev-dependencies]
43
44
  rcgen = "0.13"
@@ -109,17 +109,8 @@ fn jwt_decode_inner(
109
109
  }
110
110
  let (header_b64, payload_b64, sig_b64) = (parts[0], parts[1], parts[2]);
111
111
 
112
- // 2. Verify signature (HMAC-SHA256)
113
- let signing_input = format!("{}.{}", header_b64, payload_b64);
114
- let signature = URL_SAFE_NO_PAD.decode(sig_b64)?;
115
-
116
- let mut mac = <HmacSha256 as Mac>::new_from_slice(secret).expect("HMAC accepts any key length");
117
- mac.update(signing_input.as_bytes());
118
- // Constant-time comparison via hmac crate's verify_slice
119
- mac.verify_slice(&signature)
120
- .map_err(|_| JwtError::InvalidSignature)?;
121
-
122
- // 3. Decode and validate header
112
+ // 2. Decode and validate header BEFORE signature verification
113
+ // (prevents information leak about valid signatures for unsupported algorithms)
123
114
  let header_bytes = URL_SAFE_NO_PAD.decode(header_b64)?;
124
115
  let header: serde_json::Value = serde_json::from_slice(&header_bytes)?;
125
116
 
@@ -131,6 +122,16 @@ fn jwt_decode_inner(
131
122
  return Err(JwtError::UnsupportedAlgorithm);
132
123
  }
133
124
 
125
+ // 3. Verify signature (HMAC-SHA256)
126
+ let signing_input = format!("{}.{}", header_b64, payload_b64);
127
+ let signature = URL_SAFE_NO_PAD.decode(sig_b64)?;
128
+
129
+ let mut mac = <HmacSha256 as Mac>::new_from_slice(secret).expect("HMAC accepts any key length");
130
+ mac.update(signing_input.as_bytes());
131
+ // Constant-time comparison via hmac crate's verify_slice
132
+ mac.verify_slice(&signature)
133
+ .map_err(|_| JwtError::InvalidSignature)?;
134
+
134
135
  // 4. Decode payload
135
136
  let payload_bytes = URL_SAFE_NO_PAD.decode(payload_b64)?;
136
137
  let payload: serde_json::Value =