Skip to content

Conversation

@gocanto
Copy link
Collaborator

@gocanto gocanto commented Oct 22, 2025

Summary

  • allow both local and production Caddy configurations to emit HTTP 103 Early Hints when EARLY_HINTS_LINKS is defined
  • document how to configure the new environment variable for preload links

Testing

  • make format

Summary by CodeRabbit

  • New Features

    • Introduced Early Hints support enabling clients to preload linked resources while the server prepares responses. GET and HEAD requests now receive HTTP 103 Early Hints responses with resource links when configured, improving perceived performance and reducing wait times.
  • Documentation

    • Added Early Hints configuration and usage documentation.

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The pull request introduces an HTTP 103 Early Hints response mechanism to Caddy configurations. When the EARLY_HINTS_LINKS environment variable is set and the request method is GET or HEAD, Caddy emits a 103 response with a Link header before proxying the request upstream, enabling clients to preemptively fetch referenced assets.

Changes

Cohort / File(s) Change Summary
Caddy configuration files
caddy/Caddyfile.local, caddy/Caddyfile.prod
Add @early_hints matcher (GET/HEAD methods + non-empty EARLY_HINTS_LINKS environment variable) and wrap reverse_proxy handlers in route blocks that conditionally emit HTTP 103 Early Hints response with Link header before proxying upstream.
Documentation
caddy/readme.md
Add "Early Hints" section documenting the EARLY_HINTS_LINKS environment variable, its format, and the behavior of emitting 103 Early Hints responses for eligible requests.

Sequence Diagram

sequenceDiagram
    actor Client
    participant Caddy
    participant Upstream

    Client->>Caddy: GET /path
    
    rect rgb(200, 220, 255)
    Note over Caddy: @early_hints match:<br/>GET/HEAD + EARLY_HINTS_LINKS set
    Caddy->>Caddy: Evaluate matcher
    end
    
    alt Early Hints Eligible
        rect rgb(220, 240, 220)
        Note over Caddy: Emit Early Hints
        Caddy->>Client: 103 Early Hints<br/>(Link header)
        Client->>Client: Start fetching<br/>linked resources
        end
    end
    
    Caddy->>Upstream: Forward request
    Upstream->>Caddy: Response
    Caddy->>Client: Final response
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

The changes introduce a consistent pattern (Early Hints mechanism) applied homogeneously across two configuration files, with supporting documentation. The underlying logic is straightforward—matcher conditions and response header injection—making this a low-complexity review focused on verifying configuration syntax and documentation accuracy.

Possibly related PRs

Poem

🐰 A rabbit hops through Caddy's gate,
With hints sent early, none too late!
Link headers leap before the rest,
Assets fetch—a speedy quest! ⚡

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "chore: Add optional 103 Early Hints support to Caddy proxy" accurately reflects the main change across all modified files. The title clearly identifies the core feature being implemented (HTTP 103 Early Hints support), specifies that it is optional (enabled via the EARLY_HINTS_LINKS environment variable), and indicates the scope (Caddy proxy). The title is concise, avoids vague terms or noise, and provides enough specificity that a teammate scanning through version history would immediately understand the primary change without reading the full PR description.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch gus/add-support-for-103-early-hints-with-caddy-2025-10-22

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 and usage tips.

@gocanto gocanto marked this pull request as draft October 22, 2025 01:56
@gemini-code-assist
Copy link

Summary of Changes

Hello @gocanto, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces support for HTTP 103 Early Hints within the Caddy proxy setup. By leveraging an environment variable, Caddy can now send preliminary Link headers to clients for GET and HEAD requests, enabling browsers to start fetching critical assets earlier. This enhancement aims to improve the perceived performance and loading speed of web applications by optimizing resource delivery before the main response is fully prepared.

Highlights

  • Early Hints Support: Added optional HTTP 103 Early Hints support to both local and production Caddy configurations, allowing Caddy to emit Link headers for preloading assets.
  • Configuration via Environment Variable: The Early Hints functionality is controlled by the EARLY_HINTS_LINKS environment variable, which, when defined, triggers the 103 response.
  • Documentation: Updated the readme.md file to document how to configure the new EARLY_HINTS_LINKS environment variable for preload links.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gocanto gocanto removed the codex label Oct 22, 2025
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for HTTP 103 Early Hints in both local and production Caddy configurations, controlled by the EARLY_HINTS_LINKS environment variable. The implementation in the Caddyfiles is sound, correctly using a named matcher and a route block to conditionally send the 103 response before proxying the request. The new documentation in caddy/readme.md clearly explains the feature.

I have a couple of suggestions for the documentation to improve clarity and add an important security consideration. Overall, this is a great addition for improving frontend performance.

caddy/readme.md Outdated
When this variable is defined Caddy will emit an HTTP `103 Early Hints`
response for eligible GET and HEAD requests before proxying traffic, allowing
clients to start fetching the referenced assets while the upstream response is
prepared.

Choose a reason for hiding this comment

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

high

Since the value of the EARLY_HINTS_LINKS environment variable is directly injected into the Link response header, it's important to be aware of potential security risks like HTTP response splitting if the variable could be controlled by an untrusted source. While environment variables are generally considered trusted, it would be good practice to add a security note to the documentation to warn users about this.

For example, you could add:

> **Security Note:** The value of this variable is used directly in the HTTP response. Ensure it is a properly formatted `Link` header value and does not contain untrusted data or newline characters to prevent security vulnerabilities like HTTP response splitting.

caddy/readme.md Outdated
Comment on lines 12 to 14
Set the `EARLY_HINTS_LINKS` environment variable to a comma-separated list of
[`Link` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link)
values (for example: `</assets/app.css>; rel=preload; as=style, </assets/app.js>; rel=modulepreload`).

Choose a reason for hiding this comment

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

medium

The current phrasing "a comma-separated list of Link header values" could be slightly ambiguous. A user might interpret this as providing values that will be individually formatted, rather than providing the complete, single string for the Link header value. To improve clarity and prevent potential misconfiguration, I suggest rephrasing to make it explicit that the environment variable's content is used directly as the header's value.

Suggested change
Set the `EARLY_HINTS_LINKS` environment variable to a comma-separated list of
[`Link` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link)
values (for example: `</assets/app.css>; rel=preload; as=style, </assets/app.js>; rel=modulepreload`).
Set the `EARLY_HINTS_LINKS` environment variable to the full string for the
[`Link` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link)
value (for example: `</assets/app.css>; rel=preload; as=style, </assets/app.js>; rel=modulepreload`).

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 88 to 100
@early_hints {
method GET HEAD
expression {env.EARLY_HINTS_LINKS} != ""
}

# --- Default handler: optional Early Hints before proxying to web
route {
respond @early_hints 103 {
header Link {env.EARLY_HINTS_LINKS}
}

reverse_proxy web:80 {
header_up Host {host}

Choose a reason for hiding this comment

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

P1 Badge Production Caddyfile also short-circuits requests at 103

The same respond @early_hints 103 pattern appears in the production configuration, which means that as soon as EARLY_HINTS_LINKS is defined, any eligible GET or HEAD request will terminate with status 103 and the reverse_proxy web:80 block is skipped. This breaks all normal traffic behind the proxy whenever early hints are enabled. The early-hints response should be emitted without aborting the route so the request can still be proxied.

Useful? React with 👍 / 👎.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
caddy/Caddyfile.prod (1)

94-105: Early Hints (103) responses are not being sent in production; verify the @early_hints matcher configuration.

The verification reveals that Early Hints are not being sent to the frontend path, despite the Caddyfile configuration. The expected 103 informational response before the final 200 response is absent. This indicates the @early_hints matcher is either undefined, misconfigured, or not matching requests.

Verify that:

  • The @early_hints matcher is properly defined elsewhere in the Caddyfile
  • The matcher correctly identifies requests that should receive Early Hints
  • The {env.EARLY_HINTS_LINKS} environment variable is set and contains valid Link header values

The local/prod architectural inconsistency noted earlier is secondary; resolve the Early Hints deployment issue first.

🧹 Nitpick comments (1)
caddy/readme.md (1)

10-18: Documentation is clear; consider minor enhancements.

The Early Hints documentation effectively explains the feature and provides a helpful example.

For additional clarity, you might consider:

  1. Explicitly stating that "eligible" means GET/HEAD requests when EARLY_HINTS_LINKS is set and non-empty.
  2. Noting that in production, Early Hints currently apply only to web frontend traffic (not /api/* paths), while in local development they apply to all traffic.
  3. Mentioning that multiple Link header values should be comma-separated in the single env var string (as shown in the example).
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18de921 and a91a21f.

📒 Files selected for processing (3)
  • caddy/Caddyfile.local (1 hunks)
  • caddy/Caddyfile.prod (1 hunks)
  • caddy/readme.md (1 hunks)
🔇 Additional comments (3)
caddy/Caddyfile.local (2)

38-41: Matcher syntax looks correct.

The @early_hints matcher appropriately checks for GET/HEAD methods and a non-empty EARLY_HINTS_LINKS environment variable. The expression syntax is valid for Caddy.


46-52: The configuration is correct; Caddy properly handles 103 Early Hints in route blocks.

When Caddy responds with status 103 (Early Hints), the response is written without a body and the handler chain will continue. This means the respond @early_hints 103 directive sends the informational response with the Link header, then the reverse_proxy directive executes normally as the final handler in the chain.

The pattern you've implemented—combining respond with 103 and reverse_proxy in the same route—is the documented and supported way to use Early Hints in Caddy. No changes are needed.

caddy/Caddyfile.prod (1)

88-91: Matcher definition is consistent with local config.

The @early_hints matcher uses the same logic as in Caddyfile.local, ensuring consistency across environments.

@gocanto gocanto changed the title Add optional 103 Early Hints support to Caddy proxy chore: Add optional 103 Early Hints support to Caddy proxy Oct 22, 2025
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.

1 participant