{"record":{"id":"ca42eb463271b030","repo":"txthinking/brook","slug":"http-header-too-long","errorCode":null,"errorMessage":"HTTP header too long","messagePattern":"HTTP header too long","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"socks5tohttp.go","lineNumber":108,"sourceCode":"\t\t\t}\n\t\t}(c)\n\t}\n}\n\nfunc (s *Socks5ToHTTP) Handle(c *net.TCPConn) error {\n\tb := make([]byte, 0, 1024)\n\tfor {\n\t\tvar b1 [1024]byte\n\t\tn, err := c.Read(b1[:])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tb = append(b, b1[:n]...)\n\t\tif bytes.Contains(b, []byte{0x0d, 0x0a, 0x0d, 0x0a}) {\n\t\t\tbreak\n\t\t}\n\t\tif len(b) >= 2083+18 {\n\t\t\treturn errors.New(\"HTTP header too long\")\n\t\t}\n\t}\n\n\tbb := bytes.SplitN(b, []byte(\" \"), 3)\n\tif len(bb) != 3 {\n\t\treturn errors.New(\"Invalid Request\")\n\t}\n\tmethod, address := string(bb[0]), string(bb[1])\n\tvar addr string\n\tif method == \"CONNECT\" {\n\t\taddr = address\n\t}\n\tif method != \"CONNECT\" {\n\t\tvar err error\n\t\taddr, err = GetAddressFromURL(address)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/txthinking/brook/blob/5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8/socks5tohttp.go#L90-L126","documentation":"The SOCKS5-to-HTTP bridge reads the client's HTTP request header byte-by-byte until it sees the CRLFCRLF terminator, but aborts if the accumulated header reaches 2083+18 (2101) bytes. This enforces a practical bound on HTTP request-line/header size before parsing. It protects the parser from unbounded memory growth on never-terminated or hostile input.","triggerScenarios":"Handle() reads from the client and the buffered bytes reach 2101 bytes without containing '\\r\\n\\r\\n'; typically an HTTP request with an extremely long URL/query string, huge Cookie headers, or a client that never terminates the header block.","commonSituations":"Browsers or clients putting very long tokens/URLs (>2KB request line) through the proxy; a non-HTTP client speaking garbage that never emits CRLFCRLF; a client sending headers with bare LF line endings that the CRLFCRLF check misses.","solutions":["Shorten the request URL and headers (e.g. trim query strings, cookies) to keep the header under ~2101 bytes","Ensure the client terminates headers with a proper CRLFCRLF sequence","Verify the client actually speaks HTTP/1.x with CRLF line endings","If long URLs are unavoidable, route them without this proxy or use a variant with a larger header limit"],"exampleFix":"// before: 4KB Cookie header causes the limit to trip\nreq.Header.Set(\"Cookie\", giantCookie)\n\n// after: send only the needed cookie\nreq.Header.Set(\"Cookie\", essentialCookie)","handlingStrategy":"validation","validationCode":"func headerFits(req *http.Request) bool {\n\tvar n int\n\tfor k, v := range req.Header {\n\t\tn += len(k) + len(v[0]) + 4\n\t}\n\treturn n+len(req.URL.String()) < 2083\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep request URLs under ~2KB","Trim unnecessary headers and cookies before proxying","Always terminate headers with CRLFCRLF","Never send non-HTTP/1.x traffic through the bridge"],"tags":["http","proxy","header-size"],"backgroundTag":"payload-too-large","analyzedSha":"5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8","analyzedAt":"2026-09-06T04:35:00.432Z","contentChangedAt":"2026-09-06T04:35:00.432Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}