Skip to content

Add rudimentary support for 103 responses#550

Merged
bahamat merged 1 commit into
mainfrom
brie/early-hints/jenkins
Nov 7, 2025
Merged

Add rudimentary support for 103 responses#550
bahamat merged 1 commit into
mainfrom
brie/early-hints/jenkins

Conversation

@bahamat
Copy link
Copy Markdown
Member

@bahamat bahamat commented Nov 7, 2025

This adds minimal support for 103 responses.

Currently, the version of hyper we use does not support 103s, which prior to now would cause hyper to return an error.

This change will catch, log, and drop 103s so that they are displayed in the output, but will not be sent down to hyper, and thus to the client. The end result is that guests can test their 103 support, and see that the 103s were generated and transmitted out of the guest. But they will be elided from the response stream sent back to the client. The client will receive the final response.

This allows users to continue to use Viceroy in their testing pipeline to ensure that the stack is working. They will be able to assert the status of the final response, but not the existence of the 103 frames. This ensures that Viceroy is not outright broken when presented with 103s, but it does not yet provide full 103 support.

Adding full 103 support would require adding support to hyper (and h2, on which hyper depends), but that's not as straightforward as we would like. This is also complicated by the fact that we're pinned to hyper 0.14, while hyper main is 1.6 (as of this writing).

@bahamat
Copy link
Copy Markdown
Member Author

bahamat commented Nov 7, 2025

Current behavior

Client output

$ curl -i http://127.0.0.1:7676/hintme
HTTP/1.1 500 Internal Server Error
content-length: 0
date: Fri, 07 Nov 2025 21:17:00 GMT

Server output

  2025-11-07T21:17:00.669612Z  INFO  handling request GET http://127.0.0.1:7676/hintme
    at src/execute.rs:610
    in request with id: 1

FASTLY_SERVICE_VERSION: 0

thread 'main' panicked at /Users/bbennett/.cargo/git/checkouts/fst-compute-sdk-rs-f2611ee8c7a07c2a/51c248c/fastly/src/http/response/handle.rs:472:10:
fastly_http_resp::send_downstream failed: FastlyStatus::ERROR
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  2025-11-07T21:17:00.675556Z ERROR  WebAssembly trapped: error while executing at wasm backtrace:
    0:  0x3f556 - panic_abort::__rust_start_panic::abort::hacf84a10c30c5d5b
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/panic_abort/src/lib.rs:113:17
                - __rustc[4794b31dd7191200]::__rust_start_panic
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/panic_abort/src/lib.rs:49:9
                - __rustc[4794b31dd7191200]::rust_panic
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/std/src/panicking.rs:894:25
    1:  0x3eed1 - std::panicking::rust_panic_with_hook::hd6db915a7ab98bd5
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/std/src/panicking.rs:858:5
    2:  0x43200 - std::panicking::begin_panic_handler::{{closure}}::h03e6674a89ab6ac2
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/std/src/panicking.rs:706:13
    3:  0x4316c - std::sys::backtrace::__rust_end_short_backtrace::heed88f70267ff169
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/std/src/sys/backtrace.rs:168:18
    4:  0x1727c - __rustc[4794b31dd7191200]::rust_begin_unwind
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/std/src/panicking.rs:697:5
    5:   0x2e67 - core::panicking::panic_fmt::h127b5c782bf342d9
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/core/src/panicking.rs:75:14
    6:   0x158e - core::result::unwrap_failed::h398ddd55d54bb216
                    at /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/core/src/result.rs:1732:5
    7:  0x12420 - core::result::Result<T,E>::expect::h2cdc3acfaec027e0
                    at /Users/bbennett/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:1089:23
                - fastly::http::response::handle::ResponseHandle::send_to_client::hd5c6f6261565caf2
                    at /Users/bbennett/.cargo/git/checkouts/fst-compute-sdk-rs-f2611ee8c7a07c2a/51c248c/fastly/src/http/response/handle.rs:472:10
                - fastly::http::response::Response::send_to_client_impl::hedb1eed021c62e02
                    at /Users/bbennett/.cargo/git/checkouts/fst-compute-sdk-rs-f2611ee8c7a07c2a/51c248c/fastly/src/http/response.rs:1792:13
                - fastly::http::response::Response::send_to_client::h9a9f28ac1f19f507
                    at /Users/bbennett/.cargo/git/checkouts/fst-compute-sdk-rs-f2611ee8c7a07c2a/51c248c/fastly/src/http/response.rs:1711:19
    8:   0xd922 - fastly_compute_project::main::main::h39cc97fbd7b5cfc6
                    at /Users/bbennett/src/fastly-early-hints/src/main.rs:70:13
                - fastly_compute_project::main::hc41fa7bb5e038e2d
                    at /Users/bbennett/src/fastly-early-hints/src/main.rs:13:1
    9:   0x168f - core::ops::function::FnOnce::call_once::h8d99d111fa8f1863
                    at /Users/bbennett/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
                - std::sys::backtrace::__rust_begin_short_backtrace::ha0b381606cc69e98
                    at /Users/bbennett/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/backtrace.rs:152:18
   10:  0x1294b - fastly_compute_project-f1b576b0fe8ec547.wasm!__main_void
   11:    0xeb3 - _start
                    at wasisdk://v25.0/build/sysroot/wasi-libc-wasm32-wasip1/libc-bottom-half/crt/crt1-command.c:43:13

Caused by:
    wasm trap: wasm `unreachable` instruction executed
    at src/execute.rs:740
    in request with id: 1

  2025-11-07T21:17:00.675608Z  INFO  request completed using 1.2 MB of WebAssembly heap
    at src/execute.rs:760
    in request with id: 1

  2025-11-07T21:17:00.675613Z  INFO  request completed in 6ms
    at src/execute.rs:765
    in request with id: 1

  2025-11-07T21:17:00.675656Z  INFO  response status: 103
    at src/execute.rs:457
    in request with id: 1

New behavior

Client output

$ curl -i http://127.0.0.1:7676/hintme
HTTP/1.1 200 OK
x-fastly-service-version: 0
x-build-stamp: 00000000T000000Z
content-type: text/html; charset=utf-8
content-length: 26
date: Fri, 07 Nov 2025 21:18:35 GMT

Here's the real HTTP body!

Server output

  2025-11-07T21:19:01.869290Z  INFO  handling request GET http://127.0.0.1:7676/hintme
    at src/execute.rs:610
    in request with id: 1

FASTLY_SERVICE_VERSION: 0
  2025-11-07T21:19:01.869577Z  WARN  Guest returned 103 Early Hints response which will not be sent to the client
    at src/session/downstream.rs:65
    in request with id: 1

  2025-11-07T21:19:01.869581Z  INFO  Response {
    status: 103,
    version: HTTP/1.1,
    headers: {
        "x-fastly-service-version": "0",
        "x-build-stamp": "00000000T000000Z",
        "link": "</style1>; rel=preload; as=style",
        "link": "</script1.js>; rel=preload; as=scrypt",
    },
    body: Body {
        chunks: [],
        trailers: {},
        trailers_ready: false,
    },
}
    at src/session/downstream.rs:68
    in request with id: 1

  2025-11-07T21:19:01.869600Z  WARN  Guest returned 103 Early Hints response which will not be sent to the client
    at src/session/downstream.rs:65
    in request with id: 1

  2025-11-07T21:19:01.869603Z  INFO  Response {
    status: 103,
    version: HTTP/1.1,
    headers: {
        "x-fastly-service-version": "0",
        "x-build-stamp": "00000000T000000Z",
        "link": "</style2>; rel=preload; as=style",
        "link": "</script2.js>; rel=preload; as=scrypt",
    },
    body: Body {
        chunks: [],
        trailers: {},
        trailers_ready: false,
    },
}
    at src/session/downstream.rs:68
    in request with id: 1

  2025-11-07T21:19:01.869633Z  INFO  request completed using 1.3 MB of WebAssembly heap
    at src/execute.rs:760
    in request with id: 1

  2025-11-07T21:19:01.869637Z  INFO  request completed in 330µs
    at src/execute.rs:765
    in request with id: 1

  2025-11-07T21:19:01.869682Z  INFO  response status: 200
    at src/execute.rs:457
    in request with id: 1

Note: This guest is returning two 103 responses before the 200. You can see the response headers include (style1, script1.js) and (style2, script2.js) to distinguish the responses. This is not duplication of messages, responses, or headers.

@bahamat bahamat force-pushed the brie/early-hints/jenkins branch from 95e11e8 to 020b8c2 Compare November 7, 2025 21:21
@bahamat bahamat merged commit 4de1da3 into main Nov 7, 2025
13 checks passed
@bahamat bahamat deleted the brie/early-hints/jenkins branch November 7, 2025 21:45
};

viceroy_test!(early_hints, |is_component| {
let resp = Test::using_fixture("env-vars.wasm")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Noticed this after the fact, not sure if it was intentional. Should this be early-hints.wasm instead? It panics if I just switch it, but I didn't debug things further. If not, a comment here would be good.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You’re right. I’ll get that fixed.

thanks for catching it.

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