[PR #4931] [MERGED] fix(relay): avoid override with header passthrough #4991

Closed
opened 2026-03-17 02:28:55 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/hoppscotch/hoppscotch/pull/4931
Author: @CuriousCorrelation
Created: 3/24/2025
Status: Merged
Merged: 3/25/2025
Merged by: @jamesgeorge007

Base: nextHead: fix-relay-temp-avoid-content-type-override


📝 Commits (1)

  • d8f4f63 fix(relay): avoid override with header passthrough

📊 Changes

6 files changed (+30 additions, -36 deletions)

View changed files

📝 packages/hoppscotch-agent/src-tauri/Cargo.lock (+2 -2)
📝 packages/hoppscotch-desktop/plugin-workspace/relay/src/content.rs (+21 -19)
📝 packages/hoppscotch-desktop/plugin-workspace/relay/src/header.rs (+0 -8)
📝 packages/hoppscotch-desktop/plugin-workspace/tauri-plugin-relay/Cargo.lock (+1 -1)
📝 packages/hoppscotch-desktop/src-tauri/Cargo.lock (+2 -2)
📝 pnpm-lock.yaml (+4 -4)

📄 Description

The prior implementation caused duplicate Content-Type headers when users override headers in the UI or use OAuth2 authentication with the agent. Web servers receive multiple Content-Type headers which causes undefined behavior and 400 errors for backends that don't accept duplicate headers. This duplicate headers part has been fixed in https://github.com/hoppscotch/hoppscotch/pull/4911, this is a followup that fixes inconsistent behavior when overriding the Content-Type header with custom values (e.g., application/json;v=2).

Closes #4905
Closes HFE-790

This patch removes the automatic content-type header insertion, allowing user-defined headers to take precedence without duplication. The is a temporary workaround until we implement a HTTP/2-compliant solution with proper normalization.

This was implemented initially to support moving lower level handling towards the kernel, although since the larger refactor has been slightly deferred in favor of stability, this change is suitable for current state.

While HTTP/1.1 headers are case-insensitive per RFC 7230, inconsistent handling across server implementations can treat differently-cased variations (e.g., "Content-Type" vs "content-type") as distinct headers. HTTP/2 (RFC 7540) mandates converting all header field names to lowercase, which would prevent this issue.

This will be revisited when we implement HTTP/2 compliant header handling in the kernel layer as part of our upcoming kernel efforts.

Notes to reviewers

Use the following request to test this out on Desktop app and Agent and override Content-Type header to application/json;=v2:

curl --request POST \
  --url 'https://echo.qubit.codes/?qp=1' \
  --header 'Content-Type: application/json;v=2' \
  --data '{ "test-key": "test-value" }'
Before After
image image

Notice Content-Type (sometimes) being set to application/json instead of application/json;v=2.

The core issue is inconsistencies in the current version, see the following truncated server logs mentioned in https://github.com/hoppscotch/hoppscotch/issues/4905#issuecomment-2739623601 that describe how the Content-Type is received by the server, where override only works half of the time. With this fix, the override will always work.

... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]
... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"]

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/hoppscotch/hoppscotch/pull/4931 **Author:** [@CuriousCorrelation](https://github.com/CuriousCorrelation) **Created:** 3/24/2025 **Status:** ✅ Merged **Merged:** 3/25/2025 **Merged by:** [@jamesgeorge007](https://github.com/jamesgeorge007) **Base:** `next` ← **Head:** `fix-relay-temp-avoid-content-type-override` --- ### 📝 Commits (1) - [`d8f4f63`](https://github.com/hoppscotch/hoppscotch/commit/d8f4f6320b8f42c891847e1f379278ac0486467e) fix(relay): avoid override with header passthrough ### 📊 Changes **6 files changed** (+30 additions, -36 deletions) <details> <summary>View changed files</summary> 📝 `packages/hoppscotch-agent/src-tauri/Cargo.lock` (+2 -2) 📝 `packages/hoppscotch-desktop/plugin-workspace/relay/src/content.rs` (+21 -19) 📝 `packages/hoppscotch-desktop/plugin-workspace/relay/src/header.rs` (+0 -8) 📝 `packages/hoppscotch-desktop/plugin-workspace/tauri-plugin-relay/Cargo.lock` (+1 -1) 📝 `packages/hoppscotch-desktop/src-tauri/Cargo.lock` (+2 -2) 📝 `pnpm-lock.yaml` (+4 -4) </details> ### 📄 Description The prior implementation caused duplicate `Content-Type` headers when users override headers in the UI or use OAuth2 authentication with the agent. Web servers receive multiple `Content-Type` headers which causes undefined behavior and 400 errors for backends that don't accept duplicate headers. This _duplicate headers_ part has been fixed in https://github.com/hoppscotch/hoppscotch/pull/4911, this is a followup that fixes inconsistent behavior when overriding the `Content-Type` header with custom values (e.g., `application/json;v=2`). Closes #4905 Closes HFE-790 This patch removes the automatic content-type header insertion, allowing user-defined headers to take precedence without duplication. The is a temporary workaround until we implement a HTTP/2-compliant solution with proper normalization. This was implemented initially to support moving lower level handling towards the kernel, although since the larger refactor has been slightly deferred in favor of stability, this change is suitable for current state. While HTTP/1.1 headers are case-insensitive per [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230), inconsistent handling across server implementations can treat differently-cased variations (e.g., "Content-Type" vs "content-type") as distinct headers. HTTP/2 ([RFC 7540](https://datatracker.ietf.org/doc/html/rfc7540)) [mandates converting all header field names to lowercase](https://datatracker.ietf.org/doc/html/rfc9113#name-http-fields), which would prevent this issue. This will be revisited when we implement HTTP/2 compliant header handling in the kernel layer as part of our upcoming kernel efforts. #### Notes to reviewers Use the following request to test this out on Desktop app and Agent and override `Content-Type` header to `application/json;=v2`: ``` curl --request POST \ --url 'https://echo.qubit.codes/?qp=1' \ --header 'Content-Type: application/json;v=2' \ --data '{ "test-key": "test-value" }' ``` | Before | After | | ------ | ------ | | ![image](https://github.com/user-attachments/assets/e61a9889-5901-4fd9-bc71-67a762dfcae3) | ![image](https://github.com/user-attachments/assets/17f06bef-efd1-489f-b64b-1e43f53c5cc8) | Notice `Content-Type` (sometimes) being set to `application/json` instead of `application/json;v=2`. The core issue is inconsistencies in the current version, see the following truncated server logs mentioned in https://github.com/hoppscotch/hoppscotch/issues/4905#issuecomment-2739623601 that describe how the `Content-Type` is received by the server, where override only works half of the time. With this fix, the override will always work. ``` ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json;v=2]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ... headers: ["[Accept, */*]", ... , "[Content-Type, application/json]", "[Content-Length, 16]"] ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-17 02:28:55 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hoppscotch#4991
No description provided.