{"record":{"id":"baaf1e2e9edce246","repo":"AlexxIT/go2rtc","slug":"wrong-request-s","errorCode":null,"errorMessage":"wrong request: %s","messagePattern":"wrong request: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tcp/textproto.go","lineNumber":122,"sourceCode":"\treturn s\n}\n\nfunc (r *Request) Write(w io.Writer) (err error) {\n\t_, err = w.Write([]byte(r.String()))\n\treturn\n}\n\nfunc ReadRequest(r *bufio.Reader) (*Request, error) {\n\ttp := textproto.NewReader(r)\n\n\tline, err := tp.ReadLine()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tss := strings.SplitN(line, \" \", 3)\n\tif len(ss) != 3 {\n\t\treturn nil, fmt.Errorf(\"wrong request: %s\", line)\n\t}\n\n\treq := &Request{\n\t\tMethod: ss[0],\n\t\tProto:  ss[2],\n\t}\n\n\treq.URL, err = url.Parse(ss[1])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq.Header, err = tp.ReadMIMEHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif val := req.Header.Get(\"Content-Length\"); val != \"\" {","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/tcp/textproto.go#L104-L140","documentation":"ReadRequest parses an incoming RTSP request line and requires exactly three space-separated fields: method, URL, and protocol version. When the line does not split into 3 parts the library reports 'wrong request' instead of constructing a Request. It is the server-side counterpart of the malformed-response check.","triggerScenarios":"Using ReadResponse/ReadRequest in a server loop when a client sends a request line with wrong field count — e.g. 'OPTIONS *' without RTSP/1.0, a truncated line, or non-RTSP junk like an HTTP probe ('GET / HTTP/1.1' splits fine, but 'HELP' does not).","commonSituations":"Port scanners or monitoring probes hitting the RTSP server port; clients using an unimplemented or malformed request syntax; tools sending bare methods without URL or protocol version.","solutions":["Inspect the echoed line and fix the client so it sends 'METHOD URL RTSP/1.0' with all three fields.","Reject or skip malformed lines in your accept loop before calling ReadRequest (e.g. peek the line and validate 3 tokens).","Ensure the port is reserved for RTSP — move other protocols or health probes off that listener.","If the line is intentionally non-standard (e.g. 'OPTIONS *'), patch the parser to normalize it to 3 fields before parsing."],"exampleFix":"// before\nreq, err := conn.ReadRequest()\n// after\nline := peekLine(conn)\nif len(strings.SplitN(line, \" \", 3)) != 3 {\n\tlog.Printf(\"skipping malformed request line: %q\", line)\n\tio.WriteString(conn, \"RTSP/1.0 400 Bad Request\\r\\n\\r\\n\")\n\treturn\n}\nreq, err := conn.ReadRequest()","handlingStrategy":"validation","validationCode":"line := peekRequestLine(conn)\nif len(strings.SplitN(line, \" \", 3)) != 3 {\n\tio.WriteString(conn, \"RTSP/1.0 400 Bad Request\\r\\n\\r\\n\")\n\treturn\n}","typeGuard":"func isWellFormedRequestLine(line string) bool {\n\tparts := strings.SplitN(line, \" \", 3)\n\treturn len(parts) == 3 && parts[0] != \"\" && strings.HasPrefix(parts[2], \"RTSP/\")\n}","tryCatchPattern":"req, err := conn.ReadRequest()\nif err != nil {\n\tif strings.Contains(err.Error(), \"wrong request\") {\n\t\tio.WriteString(conn, \"RTSP/1.0 400 Bad Request\\r\\n\\r\\n\")\n\t\treturn\n\t}\n\treturn err\n}","preventionTips":["Validate request lines at the accept loop before parsing","Return a 400 response to malformed clients instead of dropping the connection","Keep scanners/probes off the RTSP port","Test clients against standard RTSP syntax (METHOD URL RTSP/1.0)"],"tags":["rtsp","parsing","protocol","server"],"backgroundTag":"unexpected-response-shape","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}