{"record":{"id":"0f0c71ea28e41dc8","repo":"XX-net/XX-Net","slug":"forward-local-read-payload-failed-s","errorCode":null,"errorMessage":"forward_local read payload failed:%s","messagePattern":"forward_local read payload failed:(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"code/default/gae_proxy/local/proxy_handler.py","lineNumber":104,"sourceCode":"        self.__class__.do_PUT = self.__class__.do_METHOD\n        self.__class__.do_POST = self.__class__.do_METHOD\n        self.__class__.do_HEAD = self.__class__.do_METHOD\n        self.__class__.do_DELETE = self.__class__.do_METHOD\n        self.__class__.do_OPTIONS = self.__class__.do_METHOD\n\n    def forward_local(self):\n        \"\"\"\n        If browser send localhost:xxx request to GAE_proxy,\n        we forward it to localhost.\n        \"\"\"\n        request_headers = dict((k.title(), v) for k, v in list(self.headers.items()))\n        payload = b''\n        if b'Content-Length' in request_headers:\n            try:\n                payload_len = int(request_headers.get(b'Content-Length', 0))\n                payload = self.rfile.read(payload_len)\n            except Exception as e:\n                xlog.warn('forward_local read payload failed:%s', e)\n                return\n\n        response = simple_http_client.request(self.command, self.path, request_headers, payload)\n        if not response:\n            xlog.warn(\"forward_local fail, command:%s, path:%s, headers: %s, payload: %s\",\n                self.command, self.path, request_headers, payload)\n            return\n\n        out_list = []\n        out_list.append(b\"HTTP/1.1 %d\\r\\n\" % response.status)\n        for key in response.headers:\n            key = key.title()\n            out_list.append(b\"%s: %s\\r\\n\" % (key, response.headers[key]))\n        out_list.append(b\"\\r\\n\")\n        out_list.append(response.text)\n\n        self.wfile.write(b\"\".join(out_list))\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/gae_proxy/local/proxy_handler.py#L86-L122","documentation":"In forward_local, the proxy tried to read the request body indicated by Content-Length from the client socket (self.rfile.read) and the read raised — usually a client disconnect, invalid Content-Length, or socket timeout — so the local forwarding is aborted.","triggerScenarios":"A client sends a request with a Content-Length header but closes the connection before sending the full body; Content-Length is non-numeric so int() raises; or the socket times out mid-body. read() raises and forward_local returns without forwarding.","commonSituations":"Browsers/tools aborting requests (page navigation, cancel), misbehaving HTTP clients sending malformed Content-Length, mobile clients dropping connections, aggressive timeouts on large uploads.","solutions":["Verify the client actually sends the declared body length (curl -v / packet capture)","Increase socket timeout if large uploads are being cut off","Sanitize Content-Length (strip, validate digits) before int() to avoid ValueError on malformed headers","Retry the request — transient client disconnects are common and benign"],"exampleFix":"# before\npayload_len = int(request_headers.get(b'Content-Length', 0))\npayload = self.rfile.read(payload_len)\n\n# after\ntry:\n    payload_len = int(request_headers.get(b'Content-Length', 0))\nexcept ValueError:\n    return\npayload = self.rfile.read(payload_len)","handlingStrategy":"try-catch","validationCode":"cl = request_headers.get(b'Content-Length', b'')\nif cl and not cl.strip().isdigit():\n    respond_400(); return","typeGuard":null,"tryCatchPattern":"try:\n    payload = self.rfile.read(payload_len)\nexcept Exception as e:\n    xlog.warn('forward_local read payload failed:%s', e)\n    return  # simply drop the half-sent request; client is gone","preventionTips":["Validate Content-Length is numeric before parsing","Set a sane socket timeout so aborted clients fail fast","Send Content-Length-correct bodies from your HTTP clients"],"tags":["http-proxy","request-body","client-disconnect","content-length"],"backgroundTag":"client-disconnected-mid-request","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}