Skip to content

fix(http-proxy): decode chunked m3u responses#673

Merged
stackia merged 3 commits into
mainfrom
agent/fix-chunked-m3u-rewrite
Jul 14, 2026
Merged

fix(http-proxy): decode chunked m3u responses#673
stackia merged 3 commits into
mainfrom
agent/fix-chunked-m3u-rewrite

Conversation

@stackia

@stackia stackia commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • add a standalone incremental HTTP chunked-transfer decoder
  • decode chunked M3U responses before URL rewriting while leaving non-M3U passthrough unchanged
  • strip transfer framing headers and emit the rewritten playlist with an accurate Content-Length
  • reject malformed, truncated, oversized, or unsupported transfer-coded M3U responses
  • drain readable upstream data before handling a simultaneous socket error so a complete terminating chunk is not discarded

Root cause

The M3U rewrite path buffered the upstream response body without decoding HTTP chunk framing. Chunk-size lines and the terminating zero chunk were therefore treated as playlist content and rewritten as URLs.

Impact

Chunked HLS playlists are now decoded and rewritten correctly. Ordinary chunked responses continue through the existing raw passthrough path.

Validation

  • pnpm run lint:clang
  • uv run ruff check e2e
  • cmake --build build -j$(getconf _NPROCESSORS_ONLN)
  • ./scripts/run-e2e.sh -p 1 test_http_proxy_m3u_rewrite.py — 51 passed
  • ./scripts/run-e2e.sh -p 1 test_http_proxy.py — 19 passed
  • ./scripts/run-e2e.sh --co — 539 tests collected
  • git diff --check

@stackia
stackia requested a review from Copilot July 14, 2026 11:18
@stackia
stackia marked this pull request as ready for review July 14, 2026 11:18
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Documentation preview

The documentation preview has been deployed for this pull request.

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

This PR fixes HTTP-proxy M3U rewriting when the upstream response uses Transfer-Encoding: chunked, by adding an incremental chunked-transfer decoder and decoding M3U bodies before URL rewriting while keeping non-M3U chunked responses on the existing passthrough path.

Changes:

  • Added a standalone incremental HTTP chunked-transfer decoder (http_chunked_decoder.*) and wired it into the M3U rewrite buffering path.
  • Implemented Transfer-Encoding parsing to accept only supported chunked coding for M3U rewrites, stripping Transfer-Encoding/Trailer and emitting rewritten playlists with a correct Content-Length.
  • Updated e2e coverage to validate correct decoding, error handling for malformed chunked bodies, and robustness against upstream reset-after-send behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/http_proxy.h Adds chunked-decoder state to the proxy session for chunked M3U rewrite handling.
src/http_proxy.c Parses Transfer-Encoding, decodes chunked M3U bodies before rewrite, updates close/error handling to drain readable data first.
src/http_chunked_decoder.h Declares the incremental chunked-transfer decoder API and state machine.
src/http_chunked_decoder.c Implements chunk-size/trailer parsing and incremental decode/emit logic with bounds checks.
e2e/test_http_proxy_m3u_rewrite.py Adds regression + negative tests for chunked M3U decode/rewrite behavior and upstream reset edge cases.
CMakeLists.txt Includes the new decoder source in the build.

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

Comment thread src/http_proxy.c Outdated
@stackia
stackia merged commit 33a2501 into main Jul 14, 2026
11 checks passed
@stackia
stackia deleted the agent/fix-chunked-m3u-rewrite branch July 14, 2026 11:31
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.

2 participants