MCPcopy Create free account
hub / github.com/awslabs/llrt / append

Method append

modules/llrt_fetch/src/headers.rs:73–141  ·  view source on GitHub ↗
(&mut self, ctx: Ctx<'js>, key: String, value: Value<'js>)

Source from the content-addressed store, hash-verified

71 }
72
73 pub fn append<'js>(&mut self, ctx: Ctx<'js>, key: String, value: Value<'js>) -> Result<()> {
74 let key = lower_key(key);
75 if !is_http_header_name(&key) {
76 return Err(Exception::throw_type(&ctx, "Invalid key"));
77 }
78 if self.guard == HeadersGuard::Immutable {
79 return Err(Exception::throw_type(&ctx, "Headers are immutable"));
80 }
81 if matches!(
82 self.guard,
83 HeadersGuard::Request | HeadersGuard::RequestNoCors
84 ) && is_forbidden_request_header(&key)
85 {
86 return Ok(());
87 }
88 if self.guard == HeadersGuard::Response && key.as_ref() == SET_COOKIE.as_str() {
89 return Ok(());
90 }
91
92 let mut value = coerce_to_string(&ctx, value)?;
93 // Reject values containing null bytes or bare CR/LF;
94 // `normalize_header_value_inplace` silently strips them, but
95 // `header-setcookie` expects a TypeError for such values.
96 if value.contains('\0') || has_bare_cr_lf(&value) {
97 return Err(Exception::throw_type(&ctx, "Invalid header value"));
98 }
99 normalize_header_value_inplace(&ctx, &mut value)?;
100 // Value-based forbidden header check (must run after value normalisation).
101 if matches!(
102 self.guard,
103 HeadersGuard::Request | HeadersGuard::RequestNoCors
104 ) && is_forbidden_method_override(&key, &value)
105 {
106 return Ok(());
107 }
108 if self.guard == HeadersGuard::RequestNoCors {
109 let val = value.split(',').next().unwrap_or("").trim();
110 if !is_cors_safelisted_request_header(&key, val) {
111 return Ok(()); // silently ignore disallowed header
112 }
113 if self.headers.iter().any(|(k, _)| k == &key) {
114 return Ok(()); // silently ignore same header
115 }
116 value = val.into();
117 };
118 if !is_http_header_value(&value) {
119 return Err(Exception::throw_type(&ctx, "Invalid value of key"));
120 }
121
122 let str_key = key.as_ref();
123 if str_key == SET_COOKIE.as_str() {
124 self.headers.push((key, value.into()));
125 return Ok(());
126 }
127 if let Some((_, existing_value)) = self.headers.iter_mut().find(|(k, _)| k == &key) {
128 let mut new_value = String::with_capacity(existing_value.len() + 2 + value.len());
129 new_value.push_str(existing_value);
130 if str_key == COOKIE.as_str() {

Callers 10

test_get_headerFunction · 0.45
json_staticMethod · 0.45
redirectMethod · 0.45
openFunction · 0.45
url.test.tsFile · 0.45
console.test.tsFile · 0.45

Calls 15

lower_keyFunction · 0.85
is_http_header_nameFunction · 0.85
coerce_to_stringFunction · 0.85
has_bare_cr_lfFunction · 0.85
is_http_header_valueFunction · 0.85
anyMethod · 0.80
pushMethod · 0.80
iter_mutMethod · 0.80

Tested by 1

test_get_headerFunction · 0.36