Skip to content

Add custom response headers support to respond statement - #570

Merged
logbie merged 2 commits into
mainfrom
claude/ietf-rfc-10008-validation-peidge
Jul 4, 2026
Merged

Add custom response headers support to respond statement#570
logbie merged 2 commits into
mainfrom
claude/ietf-rfc-10008-validation-peidge

Conversation

@logbie

@logbie logbie commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds support for custom HTTP response headers in the respond statement via an optional and headers <map> clause. This enables WFL servers to implement RFC 10008 (HTTP QUERY method) by allowing them to set headers like Accept-Query and Content-Location.

Key Changes

  • Parser (src/parser/stmt/web.rs): Extended respond statement parsing to accept an optional and headers <map> clause that can appear in any order alongside status and content_type clauses.

  • AST (src/parser/ast.rs): Added headers: Option<Expression> field to RespondStatement to capture the optional headers map expression.

  • Interpreter (src/interpreter/mod.rs): Implemented header evaluation logic that:

    • Evaluates the headers expression to a WFL Object (map)
    • Converts header values to strings (supporting text, numbers, and booleans)
    • Filters out duplicate Content-Type entries to prevent conflicts with the content_type clause
    • Populates the response's custom headers HashMap
  • Type Checker (src/typechecker/mod.rs): Updated to handle the new headers field in pattern matching.

  • Documentation (Docs/04-advanced-features/web-servers.md):

    • Added "With Custom Headers" section explaining the new syntax and behavior
    • Added comprehensive "The QUERY Method (RFC 10008)" section with examples for both client and server usage
    • Clarified that all optional clauses can appear in any order
  • Tests (tests/respond_headers_test.rs): Added comprehensive test suite including:

    • Backward compatibility test (existing syntax still works)
    • Parser tests for header clause capture and order independence
    • End-to-end integration test demonstrating RFC 10008 QUERY flow with custom headers
  • Example Program (TestPrograms/rfc10008_query_server.wfl): Added complete RFC 10008 QUERY server demo showing practical usage.

Implementation Details

The design follows WFL's "no-unlearning" principle by mirroring the outbound client's with headers <map> syntax — same concept, same syntax, nothing new to learn. The Content-Type header is intentionally filtered from the custom headers map to maintain the authoritative role of the content_type clause, preventing response header conflicts.

Header values are coerced to strings, supporting text, numbers, and booleans, with clear error messages for unsupported types.

https://claude.ai/code/session_015YKDtPA3oVRA55g3yUbCQs


Open in Devin Review

Summary by CodeRabbit

  • New Features

    • Added support for custom HTTP response headers in respond to statements.
    • Added support for the HTTP QUERY method, including client and server examples.
  • Documentation

    • Expanded web server docs with custom header usage, header precedence rules, and updated combined examples.
    • Added guidance for handling QUERY requests.
  • Tests

    • Added coverage for parsing response headers and verifying QUERY responses include the expected headers and content type.

…respond`

WFL already sends and receives the HTTP QUERY method (RFC 10008) because
methods are plain strings end-to-end: clients use `with method "QUERY"` and
servers read `req["method"]`. The missing piece for RFC 10008 compliance was
server-side response headers — a WFL server had no way to emit `Accept-Query`,
`Content-Location`, or `Location`.

Add an optional `and headers <map>` clause to the `respond` statement,
mirroring the outbound client's `with headers` form (same "headers are a map"
concept, nothing to unlearn). The map populates the response's custom headers;
the `content_type` clause stays authoritative for Content-Type (a duplicate
`Content-Type` key is dropped).

- ast: add `headers: Option<Expression>` to `RespondStatement`
- parser: parse `and headers <map>` (incl. the merged-identifier form)
- interpreter: evaluate the map into `WflHttpResponse.headers`
- typechecker: thread the new field through
- tests: parser + end-to-end QUERY test proving Accept-Query/Content-Location
- docs: web-servers guide gains "Custom Headers" and "QUERY Method" sections
- TestPrograms: rfc10008_query_server.wfl demo (CI-SKIP, needs HTTP client)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015YKDtPA3oVRA55g3yUbCQs
Copilot AI review requested due to automatic review settings July 4, 2026 09:49
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@logbie, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0863b05e-3440-4f46-a07a-68ddc88ab814

📥 Commits

Reviewing files that changed from the base of the PR and between f05caf4 and 8263a0c.

📒 Files selected for processing (6)
  • Docs/04-advanced-features/web-servers.md
  • src/analyzer/mod.rs
  • src/analyzer/static_analyzer.rs
  • src/interpreter/mod.rs
  • src/typechecker/mod.rs
  • tests/respond_headers_test.rs
📝 Walkthrough

Walkthrough

This PR adds an optional headers clause to the respond statement, allowing custom HTTP response headers to be specified as a map while content_type remains authoritative for Content-Type. Changes span AST, parser, interpreter, typechecker, tests, and documentation, including a new RFC 10008 QUERY demo program.

Changes

Respond headers and QUERY support

Layer / File(s) Summary
AST field for headers
src/parser/ast.rs
Adds optional headers: Option<Expression> field to Statement::RespondStatement.
Parser support for 'and headers' clause
src/parser/stmt/web.rs
Parses the new and headers <expr> clause, handling merged marker/value tokens, and includes it in the constructed statement.
Interpreter evaluation of custom headers
src/interpreter/mod.rs
Evaluates headers map, validates value types, skips Content-Type overrides, and populates response headers.
Typechecker destructuring update
src/typechecker/mod.rs
Destructures the new headers field without adding validation logic.
Parser and end-to-end tests for headers
tests/respond_headers_test.rs
Unit tests for backward compatibility, headers parsing, clause ordering, and an end-to-end QUERY test validating headers and body.
Documentation and demo program
Docs/04-advanced-features/web-servers.md, TestPrograms/rfc10008_query_server.wfl
Documents custom headers, updates combined example, adds a QUERY method (RFC 10008) section, and adds a demo QUERY server program.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant WFLServer as WFL Server
    participant Interpreter
    participant HttpResponse as WflHttpResponse

    Client->>WFLServer: QUERY request with body
    WFLServer->>Interpreter: dispatch respond statement
    Interpreter->>Interpreter: evaluate headers map
    Interpreter->>Interpreter: validate header values, skip Content-Type
    Interpreter->>HttpResponse: set custom_headers + content_type
    HttpResponse-->>Client: response with Accept-Query, Content-Location headers
Loading

Possibly related PRs

  • WebFirstLanguage/wfl#261: Both PRs implement the same core change—adding an optional headers clause to respond by extending Statement::RespondStatement across parser/AST/interpreter/typechecker.
  • WebFirstLanguage/wfl#540: Both PRs modify parse_respond_statement in src/parser/stmt/web.rs affecting how respond to ... clauses are parsed.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding custom response headers support to the respond statement.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/ietf-rfc-10008-validation-peidge

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread src/typechecker/mod.rs Outdated
content,
status,
content_type,
headers: _headers,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Response headers are not validated by the type checker, allowing type errors to reach runtime

The new headers field is explicitly captured but immediately discarded (headers: _headers at src/typechecker/mod.rs:1899) without any type inference or validation, so a wrong-type value (e.g. a number instead of a map) silently passes static analysis and only fails at runtime.

Impact: Users get no compile-time warning when they pass a non-map value to the headers clause, unlike status and content_type which are both type-checked in the same block.

Mechanism: the adjacent status and content_type fields are both validated but headers is skipped

The status field is type-checked at src/typechecker/mod.rs:1919-1933 (must be Number) and content_type is type-checked at src/typechecker/mod.rs:1936-1947 (must be Text). The new headers field should similarly be checked (must be Object/map), but the underscore prefix on _headers suppresses the Rust unused-variable warning and no validation code was added.

Additionally, the semantic analyzer at src/analyzer/mod.rs:1597-1615 and the static analyzer at src/analyzer/static_analyzer.rs:848-863 both use .. to absorb the new field, so the headers expression is never semantically analyzed and variables used in it will be falsely reported as unused.

Prompt for agents
The new `headers` field on RespondStatement is bound as `_headers` in the type checker (src/typechecker/mod.rs:1899) but never validated. Three places need updating:

1. src/typechecker/mod.rs around line 1899: Change `headers: _headers` to `headers`, and after the content_type check block (around line 1947), add a block that calls `self.infer_expression_type` on the headers expression if present. The expected type would be Object (map), though the type system may not have a dedicated Map type — check how other map-typed expressions are validated in this file.

2. src/analyzer/mod.rs around line 1597-1615: The RespondStatement match arm lists request, content, status, content_type with `..` absorbing the rest. Add `headers` to the destructure and call `self.analyze_expression(headers_expr)` if Some, following the same pattern as status and content_type.

3. src/analyzer/static_analyzer.rs around line 848-863: Same pattern — add `headers` to the destructure and call `self.mark_used_in_expression(headers_expr, usages)` if Some, so the headers variable is not falsely reported as unused.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for setting custom HTTP response headers from WFL web servers via an optional and headers <map> clause on the respond statement (intended to enable RFC 10008 / HTTP QUERY flows and related headers like Accept-Query and Content-Location).

Changes:

  • Extend respond parsing/AST to capture an optional headers map expression (order-independent with status / content_type).
  • Interpret the headers map at runtime and attach resulting headers to the HTTP response (while preventing Content-Type conflicts).
  • Add docs, tests, and an RFC 10008 demo program illustrating usage.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/parser/stmt/web.rs Parses optional and headers <map> clause for respond, allowing any clause order.
src/parser/ast.rs Extends RespondStatement AST with headers: Option<Expression>.
src/interpreter/mod.rs Evaluates header map at runtime and populates response headers.
src/typechecker/mod.rs Updates pattern match for the new headers field in RespondStatement.
Docs/04-advanced-features/web-servers.md Documents custom response headers and adds an RFC 10008 QUERY section and examples.
tests/respond_headers_test.rs Adds parser/backward-compat tests and an end-to-end QUERY integration test validating headers.
TestPrograms/rfc10008_query_server.wfl Provides a runnable RFC 10008 QUERY server demo (CI-skipped).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/typechecker/mod.rs
Comment on lines 1896 to 1900
content,
status,
content_type,
headers: _headers,
line: _line,
Comment thread src/interpreter/mod.rs Outdated
Comment on lines +5793 to +5795
if name.eq_ignore_ascii_case("content-type") {
continue;
}
Comment thread src/interpreter/mod.rs Outdated
_ => {
return Err(RuntimeError::new(
format!(
"Response header '{name}' must be text, got {}",
```

**Notes:**
- The map keys are header names and the values are header values (text).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/typechecker/mod.rs (1)

1894-1948: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add a type check for the new headers field.

headers is destructured as _headers and never inspected, unlike content_type in this same match arm and headers in HttpRequestStatement (lines 545-559 above), both of which validate their expression's inferred type. As written, passing a non-map value to respond ... and headers <expr> is only caught at runtime by the interpreter instead of at type-check time.

♻️ Proposed fix
             Statement::RespondStatement {
                 request: _request,
                 content,
                 status,
                 content_type,
-                headers: _headers,
+                headers,
                 line: _line,
                 column: _column,
             } => {
                 ...
                 // Check content_type if provided (should be text)
                 if let Some(ct_expr) = content_type {
                     let ct_type = self.infer_expression_type(ct_expr);
                     if ct_type != Type::Text && ct_type != Type::Unknown && ct_type != Type::Error {
                         self.type_error(
                             "Content type must be text".to_string(),
                             Some(Type::Text),
                             Some(ct_type),
                             *_line,
                             *_column,
                         );
                     }
                 }
+
+                // Check headers if provided (should be a map)
+                if let Some(headers_expr) = headers {
+                    let headers_type = self.infer_expression_type(headers_expr);
+                    if !matches!(
+                        headers_type,
+                        Type::Map(_, _) | Type::Unknown | Type::Any | Type::Error
+                    ) {
+                        self.type_error(
+                            "Response headers must be a map of header names to values".to_string(),
+                            Some(Type::Map(Box::new(Type::Text), Box::new(Type::Text))),
+                            Some(headers_type),
+                            *_line,
+                            *_column,
+                        );
+                    }
+                }
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/typechecker/mod.rs` around lines 1894 - 1948, The RespondStatement branch
in src/typechecker/mod.rs is ignoring the new headers field because it is
destructured as _headers, so add a type check for headers in the same way
HttpRequestStatement validates its headers expression and this branch validates
content_type. Inspect the inferred type of the headers expression in the
Statement::RespondStatement match arm, emit a type_error when it is not the
expected map/object type, and keep the existing content, status, and
content_type checks unchanged.
🧹 Nitpick comments (3)
tests/respond_headers_test.rs (3)

92-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Interpreter errors are silently discarded.

let _ = interpreter.interpret(&ast).await; swallows any runtime error (e.g., a parse/typecheck/runtime failure in the WFL server script). If the server fails to start, the test only surfaces a confusing "Failed to send QUERY request" panic instead of the real cause. Consider logging the error for diagnosability.

🔧 Suggested fix
-            let _ = interpreter.interpret(&ast).await;
+            if let Err(e) = interpreter.interpret(&ast).await {
+                eprintln!("WFL server thread failed: {e:?}");
+            }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/respond_headers_test.rs` around lines 92 - 103, The start_server_thread
helper currently discards interpreter failures by assigning the result of
Interpreter::interpret to _, which hides the real server startup error. Update
the async block in start_server_thread to handle the interpret result explicitly
and log or print any error before the thread exits, so failures in Parser or
Interpreter are visible when tests fail.

109-189: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing negative-path coverage for the headers clause.

Per the interpreter behavior (src/interpreter/mod.rs), unsupported header value types should produce a runtime error, and a content-type key in the custom headers map should be silently dropped in favor of the content_type clause. Neither behavior is exercised by this test suite. Consider adding:

  • A test asserting a runtime error when a header value is a non-text/number/bool type (e.g., a list or nested map).
  • A test asserting that a Content-Type key present in the headers map does not override/duplicate the content_type clause value.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/respond_headers_test.rs` around lines 109 - 189, Add negative-path
coverage around the response headers handling in respond_headers_test.rs. Extend
the existing QUERY/header tests or add new ones that exercise the interpreter
behavior in src/interpreter/mod.rs: verify that a custom headers map with an
unsupported value type (such as a list or nested map) causes a runtime error,
and verify that when the headers map contains a Content-Type key, it is dropped
or ignored so the respond to req ... content_type clause remains the sole source
of the response Content-Type. Use the existing respond to req, query_headers,
and test_query_response_sets_custom_headers patterns to keep the new tests easy
to locate.

125-128: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Fixed sleep for server-bind sync is flaky under CI load.

Waiting a fixed 300ms for the server to bind is a common source of intermittent CI failures under load. Consider polling the port with retries/backoff instead of a flat sleep.

♻️ Suggested fix: retry-based readiness check
-    // Give the server time to bind.
-    tokio::time::sleep(Duration::from_millis(300)).await;
+    // Poll until the server is accepting connections, with a bounded timeout.
+    let mut attempts = 0;
+    loop {
+        if std::net::TcpStream::connect(format!("127.0.0.1:{port}")).is_ok() {
+            break;
+        }
+        attempts += 1;
+        assert!(attempts < 50, "Server did not bind in time");
+        tokio::time::sleep(Duration::from_millis(20)).await;
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/respond_headers_test.rs` around lines 125 - 128, The fixed 300ms sleep
in the server startup test is flaky and should be replaced with a readiness
check. Update the setup around start_server_thread in respond_headers_test to
poll the server port with retries/backoff until it is accepting connections,
then proceed with the test instead of using tokio::time::sleep. Keep the change
localized to the test helper/setup code so the bind wait becomes deterministic
under CI load.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Docs/04-advanced-features/web-servers.md`:
- Around line 220-244: The “With Custom Headers” docs describe `respond to
<request> with <content> and headers <map>` too narrowly by saying header values
are text only. Update the wording in this section so it matches the actual
behavior of `respond to` and `headers` in the parser/interpreter: supported
header value types are accepted and then stringified, while `content_type` still
controls `Content-Type`. Keep the map-key/header-name guidance, but remove any
implication that the input contract is text-only.
- Around line 264-272: The QUERY client example in the web-servers docs is
missing the explicit Content-Type header the prose already mentions. Update the
example around the sending QUERY snippet by inlining the request headers map
instead of relying on request_headers, and include the Content-Type value shown
in the text so the example is directly copy-pasteable; use the QUERY client
example and the open url call as the key anchors.

In `@src/interpreter/mod.rs`:
- Around line 5768-5810: The response header filtering in the interpreter’s
header collection logic only excludes content-type, so conflicting
computed/hop-by-hop headers can still be injected. Update the
custom_headers-building code in the response handling path in
src/interpreter/mod.rs to also reject Content-Length and Transfer-Encoding
(alongside content-type) before inserting into the map, so the downstream warp
response builder remains authoritative for those values.

---

Outside diff comments:
In `@src/typechecker/mod.rs`:
- Around line 1894-1948: The RespondStatement branch in src/typechecker/mod.rs
is ignoring the new headers field because it is destructured as _headers, so add
a type check for headers in the same way HttpRequestStatement validates its
headers expression and this branch validates content_type. Inspect the inferred
type of the headers expression in the Statement::RespondStatement match arm,
emit a type_error when it is not the expected map/object type, and keep the
existing content, status, and content_type checks unchanged.

---

Nitpick comments:
In `@tests/respond_headers_test.rs`:
- Around line 92-103: The start_server_thread helper currently discards
interpreter failures by assigning the result of Interpreter::interpret to _,
which hides the real server startup error. Update the async block in
start_server_thread to handle the interpret result explicitly and log or print
any error before the thread exits, so failures in Parser or Interpreter are
visible when tests fail.
- Around line 109-189: Add negative-path coverage around the response headers
handling in respond_headers_test.rs. Extend the existing QUERY/header tests or
add new ones that exercise the interpreter behavior in src/interpreter/mod.rs:
verify that a custom headers map with an unsupported value type (such as a list
or nested map) causes a runtime error, and verify that when the headers map
contains a Content-Type key, it is dropped or ignored so the respond to req ...
content_type clause remains the sole source of the response Content-Type. Use
the existing respond to req, query_headers, and
test_query_response_sets_custom_headers patterns to keep the new tests easy to
locate.
- Around line 125-128: The fixed 300ms sleep in the server startup test is flaky
and should be replaced with a readiness check. Update the setup around
start_server_thread in respond_headers_test to poll the server port with
retries/backoff until it is accepting connections, then proceed with the test
instead of using tokio::time::sleep. Keep the change localized to the test
helper/setup code so the bind wait becomes deterministic under CI load.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fbf1ac60-91e5-402a-ba5f-c39229f6dbab

📥 Commits

Reviewing files that changed from the base of the PR and between 0bdba18 and f05caf4.

📒 Files selected for processing (7)
  • Docs/04-advanced-features/web-servers.md
  • TestPrograms/rfc10008_query_server.wfl
  • src/interpreter/mod.rs
  • src/parser/ast.rs
  • src/parser/stmt/web.rs
  • src/typechecker/mod.rs
  • tests/respond_headers_test.rs

Comment thread Docs/04-advanced-features/web-servers.md
Comment thread Docs/04-advanced-features/web-servers.md Outdated
Comment thread src/interpreter/mod.rs
…#570 review)

Address review feedback on the `respond ... and headers <map>` clause:

- typechecker: validate the headers expression is a map (mirrors the outbound
  `open url` headers check); non-map values are now caught at type-check time
- analyzer + static_analyzer: analyze/mark-used the headers expression instead
  of absorbing it with `..`, so undefined header variables are reported and a
  map used only in the headers clause is no longer falsely flagged unused
- interpreter: also drop Content-Length and Transfer-Encoding from the custom
  headers map (not just Content-Type), so a script cannot inject duplicate or
  conflicting pipeline-computed headers (RFC 7230 §3.3.2 / response splitting);
  correct the value-type error message to name text, numbers, and booleans
- docs: note numbers/booleans are stringified; the QUERY client example now
  inlines the Content-Type request header so it is copy-pasteable
- tests: type-check + static-analysis regression tests; an end-to-end test that
  a Content-Type/Content-Length in the map is dropped (single, correct value);
  surface interpreter errors from the server thread; poll for bind readiness
  instead of a fixed sleep

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015YKDtPA3oVRA55g3yUbCQs
@logbie
logbie merged commit 8f76088 into main Jul 4, 2026
15 checks passed
@logbie
logbie deleted the claude/ietf-rfc-10008-validation-peidge branch July 4, 2026 10:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants