castrum 0.7.0 → 0.9.0
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.
- package/LICENSE +21 -0
- package/README.md +322 -59
- package/castrum.linux-x64-gnu.node +0 -0
- package/dist/index.d.ts +3161 -0
- package/dist/index.js +7306 -0
- package/docs/ARCHITECTURE.md +415 -0
- package/docs/BENCHMARKS.md +307 -0
- package/docs/ENVIRONMENT.md +79 -0
- package/docs/GETTING_STARTED.md +209 -0
- package/docs/INGRESS.md +745 -0
- package/docs/REPO_MAP.md +259 -0
- package/docs/adr/0001-two-wire-formats.md +39 -0
- package/docs/adr/0002-zero-dom-fast-schema.md +38 -0
- package/docs/adr/0003-bun-builtins-delegation.md +42 -0
- package/docs/bun-builtins-decision-matrix.md +108 -0
- package/index.ts +51 -8
- package/package.json +73 -20
- package/src/data/json-rows.ts +13 -13
- package/src/ingress/body.ts +149 -0
- package/src/ingress/constants.ts +220 -48
- package/src/ingress/context.ts +136 -0
- package/src/ingress/decode/baked-result.ts +121 -0
- package/src/ingress/decode/fast-result.ts +160 -0
- package/src/ingress/decode/packed-sections.ts +56 -0
- package/src/ingress/decode/result-base.ts +172 -0
- package/src/ingress/errors.ts +72 -0
- package/src/ingress/fast.ts +152 -1021
- package/src/ingress/handlers.ts +563 -1001
- package/src/ingress/headers/baked-templates.ts +102 -0
- package/src/ingress/headers/cors.ts +44 -0
- package/src/ingress/headers/fast-templates.ts +238 -0
- package/src/ingress/headers/hsts.ts +83 -0
- package/src/ingress/health.ts +67 -0
- package/src/ingress/index.ts +130 -405
- package/src/ingress/metrics.ts +132 -0
- package/src/ingress/options.ts +197 -0
- package/src/ingress/packing/gather-raw-headers.ts +75 -0
- package/src/ingress/packing/header-packing.ts +75 -0
- package/src/ingress/packing/input-packer.ts +150 -0
- package/src/ingress/packing/scratch.ts +50 -0
- package/src/ingress/packing/select-headers.ts +96 -0
- package/src/ingress/response/error-bodies.ts +75 -0
- package/src/ingress/response/terminal.ts +59 -0
- package/src/ingress/routes/common.ts +38 -0
- package/src/ingress/routes/delete.ts +14 -0
- package/src/ingress/routes/echo.ts +107 -0
- package/src/ingress/routes/fallback.ts +23 -0
- package/src/ingress/routes/head.ts +37 -0
- package/src/ingress/routes/index.ts +10 -0
- package/src/ingress/routes/json-write.ts +153 -0
- package/src/ingress/routes/options.ts +36 -0
- package/src/ingress/routes/read.ts +45 -0
- package/src/ingress/server-node.ts +376 -0
- package/src/ingress/server.ts +443 -0
- package/src/ingress/shared.ts +132 -0
- package/src/ingress/status.ts +97 -0
- package/src/ingress/types.ts +157 -0
- package/src/integration/batch.ts +58 -0
- package/src/integration/index.ts +29 -0
- package/src/integration/pipeline.ts +217 -0
- package/src/integration/streaming.ts +79 -0
- package/src/integration/websocket.ts +92 -0
- package/src/loader/batch.ts +133 -0
- package/src/loader/cost.ts +104 -0
- package/src/loader/index.ts +930 -0
- package/src/loader/ops.ts +657 -0
- package/src/native/ffi.ts +1541 -0
- package/src/native/index.ts +8 -207
- package/src/native/loader.ts +194 -0
- package/src/native/types.ts +598 -0
- package/src/rust-ffi/addon.ts +10 -0
- package/src/rust-ffi/batch.ts +431 -0
- package/src/rust-ffi/client.ts +88 -0
- package/src/rust-ffi/context.ts +164 -0
- package/src/rust-ffi/index.ts +40 -541
- package/src/rust-ffi/options.ts +113 -0
- package/src/rust-ffi/packed.ts +253 -0
- package/src/rust-ffi/proven.ts +42 -0
- package/src/rust-ffi/scalar/crypto.ts +265 -0
- package/src/rust-ffi/scalar/factories.ts +233 -0
- package/src/rust-ffi/scalar/hashing.ts +72 -0
- package/src/rust-ffi/scalar/http.ts +206 -0
- package/src/rust-ffi/scalar/index.ts +31 -0
- package/src/rust-ffi/scalar/interface.ts +450 -0
- package/src/rust-ffi/scalar/json.ts +45 -0
- package/src/rust-ffi/scalar/payload.ts +124 -0
- package/src/rust-ffi/text.ts +95 -0
- package/src/selection.json +194 -0
- package/src/selection.ts +77 -0
- package/src/shared/adaptive.ts +68 -0
- package/src/shared/bench-classify.ts +209 -0
- package/src/shared/buffer-pool.ts +209 -0
- package/src/shared/bytes.ts +35 -5
- package/src/shared/env.ts +20 -0
- package/src/shared/log.ts +74 -0
- package/src/shared/metrics.ts +247 -0
- package/src/shared/packed.ts +350 -154
- package/src/shared/proven.ts +596 -0
- package/src/shared/request-id.ts +67 -0
- package/src/shared/response.ts +104 -0
- package/src/shared/runtime.ts +34 -0
- package/src/shared/trace.ts +81 -0
- package/src/shared/uuid.ts +31 -0
- package/Cargo.toml +0 -73
- package/bench.ts +0 -3
- package/rust/batch.rs +0 -195
- package/rust/cookie_parser.rs +0 -70
- package/rust/cors.rs +0 -263
- package/rust/hashing.rs +0 -164
- package/rust/headers.rs +0 -234
- package/rust/hmac_sha256.rs +0 -113
- package/rust/http_parser.rs +0 -132
- package/rust/ingress.rs +0 -616
- package/rust/ingress_constants.rs +0 -89
- package/rust/ip_trust.rs +0 -185
- package/rust/json_ops.rs +0 -66
- package/rust/json_patch_ops.rs +0 -25
- package/rust/json_schema.rs +0 -151
- package/rust/json_ser.rs +0 -429
- package/rust/lib.rs +0 -48
- package/rust/method.rs +0 -141
- package/rust/mime_lookup.rs +0 -76
- package/rust/output.rs +0 -238
- package/rust/proxy.rs +0 -90
- package/rust/query_parser.rs +0 -141
- package/rust/random_token.rs +0 -52
- package/rust/rate_limit.rs +0 -203
- package/rust/terminal.rs +0 -95
- package/rust/unit_tests.rs +0 -843
- package/rust/url_codec.rs +0 -133
- package/rust/util.rs +0 -537
- package/rust/validation.rs +0 -107
- package/rust/websocket.rs +0 -23
- package/src/baseline/index.ts +0 -12
- package/src/baseline/tasks/cookie.ts +0 -22
- package/src/baseline/tasks/hashing.ts +0 -18
- package/src/baseline/tasks/hmac.ts +0 -38
- package/src/baseline/tasks/http.ts +0 -62
- package/src/baseline/tasks/json-patch.ts +0 -12
- package/src/baseline/tasks/json.ts +0 -50
- package/src/baseline/tasks/mime.ts +0 -5
- package/src/baseline/tasks/query.ts +0 -14
- package/src/baseline/tasks/token.ts +0 -15
- package/src/baseline/tasks/url.ts +0 -11
- package/src/baseline/tasks/validation.ts +0 -19
- package/src/baseline/tasks/websocket.ts +0 -14
- package/src/bench/assert.ts +0 -70
- package/src/bench/checks.ts +0 -227
- package/src/bench/checksum.ts +0 -27
- package/src/bench/comparisons.ts +0 -70
- package/src/bench/concurrent-worker.ts +0 -135
- package/src/bench/fixtures.ts +0 -233
- package/src/bench/index.ts +0 -2
- package/src/bench/measure.ts +0 -177
- package/src/bench/now.ts +0 -3
- package/src/bench/report.ts +0 -79
- package/src/bench/run.ts +0 -57
- package/src/bench/tasks/complex.ts +0 -232
- package/src/bench/tasks/concurrent.ts +0 -213
- package/src/bench/tasks/cookie.ts +0 -44
- package/src/bench/tasks/hashing.ts +0 -33
- package/src/bench/tasks/hmac.ts +0 -36
- package/src/bench/tasks/http.ts +0 -50
- package/src/bench/tasks/index.ts +0 -52
- package/src/bench/tasks/json-patch.ts +0 -21
- package/src/bench/tasks/json.ts +0 -33
- package/src/bench/tasks/mime.ts +0 -21
- package/src/bench/tasks/query.ts +0 -44
- package/src/bench/tasks/stress.ts +0 -142
- package/src/bench/tasks/token.ts +0 -20
- package/src/bench/tasks/url.ts +0 -34
- package/src/bench/tasks/validation.ts +0 -57
- package/src/bench/tasks/websocket.ts +0 -21
- package/src/bench/types.ts +0 -60
- package/src/ingress/packed-input.ts +0 -59
- package/src/shared/json.ts +0 -18
package/rust/hmac_sha256.rs
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
use napi::bindgen_prelude::*;
|
|
2
|
-
use napi_derive::napi;
|
|
3
|
-
use aws_lc_rs::hmac;
|
|
4
|
-
use crate::util::{hex_val, trim_ascii_whitespace};
|
|
5
|
-
|
|
6
|
-
const HEX_LOWER: &[u8; 16] = b"0123456789abcdef";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
#[napi]
|
|
11
|
-
pub fn hmac_sha256(key: Uint8Array, data: Buffer) -> Buffer {
|
|
12
|
-
let key = hmac::Key::new(hmac::HMAC_SHA256, key.as_ref());
|
|
13
|
-
let tag = hmac::sign(&key, data.as_ref());
|
|
14
|
-
|
|
15
|
-
let mut out = [0u8; 64];
|
|
16
|
-
hex_encode_32(tag.as_ref(), &mut out);
|
|
17
|
-
|
|
18
|
-
Buffer::from(out.to_vec())
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
#[napi]
|
|
22
|
-
pub fn hmac_sha256_verify(key: Uint8Array, data: Buffer, sig: Buffer) -> bool {
|
|
23
|
-
let sig = trim_ascii_whitespace(sig.as_ref());
|
|
24
|
-
|
|
25
|
-
if sig.len() != 64 {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
let mut sig_bytes = [0u8; 32];
|
|
30
|
-
|
|
31
|
-
let mut i = 0;
|
|
32
|
-
while i < 32 {
|
|
33
|
-
let hi = match hex_val(sig[2 * i]) {
|
|
34
|
-
Some(v) => v,
|
|
35
|
-
None => return false,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
let lo = match hex_val(sig[2 * i + 1]) {
|
|
39
|
-
Some(v) => v,
|
|
40
|
-
None => return false,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
sig_bytes[i] = (hi << 4) | lo;
|
|
44
|
-
i += 1;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
let key = hmac::Key::new(hmac::HMAC_SHA256, key.as_ref());
|
|
48
|
-
hmac::verify(&key, data.as_ref(), &sig_bytes).is_ok()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
#[napi]
|
|
52
|
-
pub struct HmacSigner {
|
|
53
|
-
key: hmac::Key,
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
#[napi]
|
|
57
|
-
impl HmacSigner {
|
|
58
|
-
#[napi(constructor)]
|
|
59
|
-
pub fn new(key: Uint8Array) -> Self {
|
|
60
|
-
Self {
|
|
61
|
-
key: hmac::Key::new(hmac::HMAC_SHA256, key.as_ref()),
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
#[napi]
|
|
66
|
-
pub fn sign(&self, data: Buffer) -> Buffer {
|
|
67
|
-
let tag = hmac::sign(&self.key, data.as_ref());
|
|
68
|
-
|
|
69
|
-
let mut out = [0u8; 64];
|
|
70
|
-
hex_encode_32(tag.as_ref(), &mut out);
|
|
71
|
-
|
|
72
|
-
Buffer::from(out.to_vec())
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
#[napi]
|
|
76
|
-
pub fn verify(&self, data: Buffer, sig: Buffer) -> bool {
|
|
77
|
-
let sig = trim_ascii_whitespace(sig.as_ref());
|
|
78
|
-
|
|
79
|
-
if sig.len() != 64 {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let mut sig_bytes = [0u8; 32];
|
|
84
|
-
|
|
85
|
-
let mut i = 0;
|
|
86
|
-
|
|
87
|
-
while i < 32 {
|
|
88
|
-
let hi = match hex_val(sig[2 * i]) {
|
|
89
|
-
Some(v) => v,
|
|
90
|
-
None => return false,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
let lo = match hex_val(sig[2 * i + 1]) {
|
|
94
|
-
Some(v) => v,
|
|
95
|
-
None => return false,
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
sig_bytes[i] = (hi << 4) | lo;
|
|
99
|
-
i += 1;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
hmac::verify(&self.key, data.as_ref(), &sig_bytes).is_ok()
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
fn hex_encode_32(bytes: &[u8], out: &mut [u8; 64]) {
|
|
107
|
-
debug_assert_eq!(bytes.len(), 32);
|
|
108
|
-
|
|
109
|
-
for (i, b) in bytes.iter().enumerate() {
|
|
110
|
-
out[2 * i] = HEX_LOWER[(b >> 4) as usize];
|
|
111
|
-
out[2 * i + 1] = HEX_LOWER[(b & 0x0f) as usize];
|
|
112
|
-
}
|
|
113
|
-
}
|
package/rust/http_parser.rs
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
// rust/http_parser.rs
|
|
2
|
-
use crate::util::{write_bytes, write_u32_le, VecWriter};
|
|
3
|
-
use napi::bindgen_prelude::*;
|
|
4
|
-
use napi_derive::napi;
|
|
5
|
-
|
|
6
|
-
pub fn http_parse_request_packed_into_slice(input: &[u8], out: &mut [u8]) -> Result<usize> {
|
|
7
|
-
let mut headers = [httparse::EMPTY_HEADER; 64];
|
|
8
|
-
let mut req = httparse::Request::new(&mut headers);
|
|
9
|
-
|
|
10
|
-
match req.parse(input) {
|
|
11
|
-
Ok(httparse::Status::Complete(_)) => {}
|
|
12
|
-
Ok(_) => return Err(Error::new(Status::InvalidArg, "incomplete HTTP request")),
|
|
13
|
-
Err(e) => return Err(Error::new(Status::InvalidArg, e.to_string())),
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let method = req
|
|
17
|
-
.method
|
|
18
|
-
.ok_or_else(|| Error::new(Status::InvalidArg, "missing HTTP method"))?
|
|
19
|
-
.as_bytes();
|
|
20
|
-
|
|
21
|
-
let path = req
|
|
22
|
-
.path
|
|
23
|
-
.ok_or_else(|| Error::new(Status::InvalidArg, "missing HTTP path"))?
|
|
24
|
-
.as_bytes();
|
|
25
|
-
|
|
26
|
-
let version: &[u8] = match req.version {
|
|
27
|
-
Some(0) => b"HTTP/1.0",
|
|
28
|
-
Some(1) => b"HTTP/1.1",
|
|
29
|
-
_ => b"HTTP/1.1",
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
let mut pos = 0usize;
|
|
33
|
-
|
|
34
|
-
write_u32_le(out, &mut pos, method.len() as u32)?;
|
|
35
|
-
write_bytes(out, &mut pos, method)?;
|
|
36
|
-
|
|
37
|
-
write_u32_le(out, &mut pos, path.len() as u32)?;
|
|
38
|
-
write_bytes(out, &mut pos, path)?;
|
|
39
|
-
|
|
40
|
-
write_u32_le(out, &mut pos, version.len() as u32)?;
|
|
41
|
-
write_bytes(out, &mut pos, version)?;
|
|
42
|
-
|
|
43
|
-
write_u32_le(out, &mut pos, req.headers.len() as u32)?;
|
|
44
|
-
|
|
45
|
-
for header in req.headers.iter() {
|
|
46
|
-
let name = header.name.as_bytes();
|
|
47
|
-
let value = header.value;
|
|
48
|
-
|
|
49
|
-
write_u32_le(out, &mut pos, name.len() as u32)?;
|
|
50
|
-
crate::util::write_bytes_lowercase(out, &mut pos, name)?;
|
|
51
|
-
|
|
52
|
-
write_u32_le(out, &mut pos, value.len() as u32)?;
|
|
53
|
-
crate::util::write_bytes(out, &mut pos, value)?;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
Ok(pos)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/// Allocating, zero-copy-input, non-zeroing-output parser.
|
|
60
|
-
pub fn http_parse_request_packed_vec(input: &[u8]) -> Result<Vec<u8>> {
|
|
61
|
-
let mut headers = [httparse::EMPTY_HEADER; 64];
|
|
62
|
-
let mut req = httparse::Request::new(&mut headers);
|
|
63
|
-
|
|
64
|
-
match req.parse(input) {
|
|
65
|
-
Ok(httparse::Status::Complete(_)) => {}
|
|
66
|
-
Ok(_) => return Err(Error::new(Status::InvalidArg, "incomplete HTTP request")),
|
|
67
|
-
Err(e) => return Err(Error::new(Status::InvalidArg, e.to_string())),
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
let method = req
|
|
71
|
-
.method
|
|
72
|
-
.ok_or_else(|| Error::new(Status::InvalidArg, "missing HTTP method"))?
|
|
73
|
-
.as_bytes();
|
|
74
|
-
|
|
75
|
-
let path = req
|
|
76
|
-
.path
|
|
77
|
-
.ok_or_else(|| Error::new(Status::InvalidArg, "missing HTTP path"))?
|
|
78
|
-
.as_bytes();
|
|
79
|
-
|
|
80
|
-
let version: &[u8] = match req.version {
|
|
81
|
-
Some(0) => b"HTTP/1.0",
|
|
82
|
-
Some(1) => b"HTTP/1.1",
|
|
83
|
-
_ => b"HTTP/1.1",
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
// Max 64 headers.
|
|
87
|
-
// Metadata overhead:
|
|
88
|
-
// 4 bytes method len
|
|
89
|
-
// 4 bytes path len
|
|
90
|
-
// 4 bytes version len
|
|
91
|
-
// 4 bytes header count
|
|
92
|
-
// 8 bytes per header name/value length prefix
|
|
93
|
-
//
|
|
94
|
-
// 16 + 64 * 8 = 528
|
|
95
|
-
let mut w = VecWriter::with_capacity(input.len().saturating_add(528));
|
|
96
|
-
|
|
97
|
-
w.write_u32(method.len() as u32);
|
|
98
|
-
w.write_bytes(method);
|
|
99
|
-
|
|
100
|
-
w.write_u32(path.len() as u32);
|
|
101
|
-
w.write_bytes(path);
|
|
102
|
-
|
|
103
|
-
w.write_u32(version.len() as u32);
|
|
104
|
-
w.write_bytes(version);
|
|
105
|
-
|
|
106
|
-
w.write_u32(req.headers.len() as u32);
|
|
107
|
-
|
|
108
|
-
for header in req.headers.iter() {
|
|
109
|
-
let name = header.name.as_bytes();
|
|
110
|
-
let value = header.value;
|
|
111
|
-
|
|
112
|
-
w.write_u32(name.len() as u32);
|
|
113
|
-
w.write_bytes_ascii_lowercase(name);
|
|
114
|
-
|
|
115
|
-
w.write_u32(value.len() as u32);
|
|
116
|
-
w.write_bytes(value);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
Ok(w.into_bytes())
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
#[napi]
|
|
123
|
-
pub fn http_parse_request_packed(input: Uint8Array) -> Result<Buffer> {
|
|
124
|
-
Ok(Buffer::from(http_parse_request_packed_vec(
|
|
125
|
-
input.as_ref(),
|
|
126
|
-
)?))
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
#[napi]
|
|
130
|
-
pub fn http_parse_request_packed_into(input: Uint8Array, mut output: Uint8Array) -> Result<u32> {
|
|
131
|
-
crate::util::run_packed_into(&input, &mut output, http_parse_request_packed_into_slice)
|
|
132
|
-
}
|