itsi-scheduler 0.2.13 → 0.2.14
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.
- checksums.yaml +4 -4
- data/Cargo.lock +1 -1
- data/ext/itsi_scheduler/Cargo.toml +1 -1
- data/ext/itsi_server/Cargo.toml +2 -1
- data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +46 -5
- data/lib/itsi/scheduler/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8805c01ab4ea4fd6224589792a871b59a3c71495ee4763d8b326d071e0c5d054
|
4
|
+
data.tar.gz: ce752eefa1e8df13c891dcad689af2ee82d683373643f18af2c2daa9031dd7cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce0bac7a7ea61036b0b58befccad25c1722521a92ddcfb8b6a538c6cac01f0928feb0d8b0a4b0fd089cae0dd95ab14f22137f96aa289450dd6fe958afc6745b7
|
7
|
+
data.tar.gz: 465b97224aa75c8e7ae1085adab18231fa6b852f431fe5562ae56dc6fd30e2024b04db48323d609cb5d4b9ba589c6bc336cd1ddd1da7f3aa8a50c00381dba918
|
data/Cargo.lock
CHANGED
data/ext/itsi_server/Cargo.toml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[package]
|
2
2
|
name = "itsi-server"
|
3
|
-
version = "0.2.
|
3
|
+
version = "0.2.14"
|
4
4
|
edition = "2021"
|
5
5
|
authors = ["Wouter Coppieters <wc@pico.net.nz>"]
|
6
6
|
license = "MIT"
|
@@ -88,3 +88,4 @@ percent-encoding = "2.3.1"
|
|
88
88
|
sha-crypt = "0.5.0"
|
89
89
|
argon2 = "0.5.3"
|
90
90
|
core_affinity = "0.8.3"
|
91
|
+
memchr = "2.7.4"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
use bytes::{Bytes, BytesMut};
|
1
|
+
use bytes::{Buf, Bytes, BytesMut};
|
2
2
|
use derive_more::Debug;
|
3
3
|
use futures::stream::{unfold, StreamExt};
|
4
4
|
use http::{
|
@@ -12,6 +12,7 @@ use hyper_util::rt::TokioIo;
|
|
12
12
|
use itsi_error::Result;
|
13
13
|
use itsi_tracing::error;
|
14
14
|
use magnus::error::Result as MagnusResult;
|
15
|
+
use memchr::{memchr, memchr_iter};
|
15
16
|
use parking_lot::RwLock;
|
16
17
|
use std::{
|
17
18
|
collections::HashMap,
|
@@ -345,13 +346,54 @@ impl ItsiHttpResponse {
|
|
345
346
|
let header_name: HeaderName = HeaderName::from_bytes(&name).map_err(|e| {
|
346
347
|
itsi_error::ItsiError::InvalidInput(format!("Invalid header name {:?}: {:?}", name, e))
|
347
348
|
})?;
|
348
|
-
let header_value = unsafe { HeaderValue::from_maybe_shared_unchecked(value) };
|
349
349
|
if let Some(ref mut resp) = *self.data.response.write() {
|
350
|
-
resp.headers_mut()
|
350
|
+
let headers_mut = resp.headers_mut();
|
351
|
+
self.insert_header(headers_mut, &header_name, value);
|
351
352
|
}
|
352
353
|
Ok(())
|
353
354
|
}
|
354
355
|
|
356
|
+
pub fn insert_header(
|
357
|
+
&self,
|
358
|
+
headers_mut: &mut HeaderMap,
|
359
|
+
header_name: &HeaderName,
|
360
|
+
value: Bytes,
|
361
|
+
) {
|
362
|
+
static MAX_SPLIT_HEADERS: usize = 100;
|
363
|
+
|
364
|
+
let mut start = 0usize;
|
365
|
+
let mut emitted = 0usize;
|
366
|
+
|
367
|
+
for idx in memchr_iter(b'\n', &value).chain(std::iter::once(value.len())) {
|
368
|
+
if idx == start {
|
369
|
+
start += 1;
|
370
|
+
continue;
|
371
|
+
}
|
372
|
+
|
373
|
+
let mut part = value.slice(start..idx);
|
374
|
+
if part.ends_with(b"\r") {
|
375
|
+
part.truncate(part.len() - 1);
|
376
|
+
}
|
377
|
+
if let Some(&(b' ' | b'\t')) = part.first() {
|
378
|
+
part.advance(1);
|
379
|
+
}
|
380
|
+
if memchr(0, &part).is_some() || part.iter().any(|&b| b < 0x20) {
|
381
|
+
warn!("stripped control char from header {:?}", header_name);
|
382
|
+
start = idx + 1;
|
383
|
+
continue;
|
384
|
+
}
|
385
|
+
|
386
|
+
emitted += 1;
|
387
|
+
if emitted > MAX_SPLIT_HEADERS {
|
388
|
+
break;
|
389
|
+
}
|
390
|
+
|
391
|
+
let hv = unsafe { HeaderValue::from_maybe_shared_unchecked(part) };
|
392
|
+
headers_mut.append(header_name, hv);
|
393
|
+
start = idx + 1;
|
394
|
+
}
|
395
|
+
}
|
396
|
+
|
355
397
|
pub fn add_headers(&self, headers: HashMap<Bytes, Vec<Bytes>>) -> MagnusResult<()> {
|
356
398
|
if let Some(ref mut resp) = *self.data.response.write() {
|
357
399
|
let headers_mut = resp.headers_mut();
|
@@ -363,8 +405,7 @@ impl ItsiHttpResponse {
|
|
363
405
|
))
|
364
406
|
})?;
|
365
407
|
for value in values {
|
366
|
-
|
367
|
-
headers_mut.append(&header_name, header_value);
|
408
|
+
self.insert_header(headers_mut, &header_name, value);
|
368
409
|
}
|
369
410
|
}
|
370
411
|
}
|