Skip to content

POST request bodies are dropped during forwarding (Transfer-Encoding: chunked rewrite sends empty body) #749

Description

@acepace

Proxify version:

v0.0.16

Current Behavior:

I'm sort of reopening #558 , because the problem isn't just in the log but rather the actual content leaving the proxy is truncated. #656 did not solve the actual proxy behavior.

Expected Behavior:

The upstream server should receive the original POST body intact — either preserved with the original Content-Length header, or properly chunked with the body content followed by the terminator

Steps To Reproduce:

For example,

proxify -http-addr 127.0.0.1:8888 -output /tmp/proxify-test.jsonl

HTTP server code

import sys
from http.server import HTTPServer, BaseHTTPRequestHandler


class DebugHandler(BaseHTTPRequestHandler):
    def _handle(self):
        content_length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(content_length) if content_length else b""

        print(f"\n{'=' * 60}")
        print(f"{self.command} {self.path} {self.request_version}")
        for name, value in self.headers.items():
            print(f"  {name}: {value}")
        print(f"\nBody ({len(body)} bytes):")
        if body:
            print(f"  {body.decode(errors='replace')}")
        else:
            print("  <EMPTY — bug is present if a body was expected>")
        print(f"{'=' * 60}\n")
        sys.stdout.flush()

        self.send_response(200)
        self.send_header("Content-Type", "text/plain")
        self.end_headers()
        self.wfile.write(b"OK\n")

    do_GET = _handle
    do_POST = _handle
    do_PUT = _handle
    do_PATCH = _handle
    do_DELETE = _handle


if __name__ == "__main__":
    addr = ("127.0.0.1", 9999)
    print(f"Listening on {addr[0]}:{addr[1]} ...")
    HTTPServer(addr, DebugHandler).serve_forever()

Then running the following commands

curl  -X POST   -d "username=admin&password=secret"   http://127.0.0.1:9999/login
curl -x http://127.0.0.1:8888 -X POST   -d "username=admin&password=secret"   http://127.0.0.1:9999/login

Leads to the following distinct output

Good

============================================================
POST /login HTTP/1.1
  Host: 127.0.0.1:9999
  User-Agent: curl/8.5.0
  Accept: */*
  Content-Length: 30
  Content-Type: application/x-www-form-urlencoded

Body (30 bytes):
  username=admin&password=secret
============================================================

Bad

============================================================
POST /login HTTP/1.1
  Host: 127.0.0.1:9999
  User-Agent: curl/8.5.0
  Transfer-Encoding: chunked
  Accept: */*
  Accept-Encoding:
  Connection: close
  Content-Type: application/x-www-form-urlencoded
  Accept-Encoding: gzip

Body (0 bytes):
  <EMPTY — bug is present if a body was expected>
============================================================

127.0.0.1 - - [23/Feb/2026 15:16:20] "POST /login HTTP/1.1" 200 -

The logs themselves show all is good

─────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
     │ File: proxify_logs/127.0.0.1:9999-a9f52d8ff10d9119.txt
─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ POST http://127.0.0.1:9999/login HTTP/1.1
   2 │ Accept: */*
   3 │ Accept-Encoding:
   4 │ Connection: close
   5 │ Content-Length: 30
   6 │ Content-Type: application/x-www-form-urlencoded
   7 │ User-Agent: curl/8.5.0
   8 │
   9 │ username=admin&password=secret
  10 │ POST http://127.0.0.1:9999/login HTTP/1.1
  11 │ Accept: */*
  12 │ Accept-Encoding:
  13 │ Connection: close
  14 │ Content-Length: 30
  15 │ Content-Type: application/x-www-form-urlencoded
  16 │ User-Agent: curl/8.5.0
  17 │
  18 │ username=admin&password=secret
─────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
     │ File: proxify_logs/127.0.0.1:9999-aaa5bfe2bfa5acaf.txt
─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ POST http://127.0.0.1:9999/login HTTP/1.1
   2 │ Accept: */*
   3 │ Accept-Encoding:
   4 │ Connection: close
   5 │ Content-Length: 30
   6 │ Content-Type: application/x-www-form-urlencoded
   7 │ User-Agent: curl/8.5.0
   8 │
   9 │ username=admin&password=secret
  10 │ POST http://127.0.0.1:9999/login HTTP/1.1
  11 │ Accept: */*
  12 │ Accept-Encoding:
  13 │ Connection: close
  14 │ Content-Length: 30
  15 │ Content-Type: application/x-www-form-urlencoded
  16 │ User-Agent: curl/8.5.0
  17 │
  18 │ username=admin&password=secret
─────┴────────────────────────────────────────────────────────

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: BugInconsistencies or issues which will cause an issue or problem for users or implementors.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions