{"record":{"id":"f527af7a7447384d","repo":"epi052/feroxbuster","slug":"invalid-request-missing-head-body-separator","errorCode":null,"errorMessage":"Invalid request: Missing head/body separator","messagePattern":"Invalid request: Missing head/body separator","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config/utils.rs","lineNumber":457,"sourceCode":"\n    // find the first header/body separator\n    // locate both \\r\\n\\r\\n and \\n\\n and pick whichever appears earliest,\n    // so that a \\r\\n\\r\\n inside the body doesn't shadow a \\n\\n separator\n    // that terminates the headers\n    let crlf = contents.windows(4).position(|w| w == b\"\\r\\n\\r\\n\");\n    let lf = contents.windows(2).position(|w| w == b\"\\n\\n\");\n\n    let (sep_idx, sep_len) = match (crlf, lf) {\n        (Some(c), Some(l)) => {\n            if c <= l {\n                (c, 4)\n            } else {\n                (l, 2)\n            }\n        }\n        (Some(c), None) => (c, 4),\n        (None, Some(l)) => (l, 2),\n        (None, None) => bail!(\"Invalid request: Missing head/body separator\"),\n    };\n\n    // split the request head and body\n    let head_bytes = &contents[..sep_idx];\n    let body_bytes = &contents[sep_idx + sep_len..];\n\n    // decode only the head; HTTP framing is generally ascii/utf-8\n    // compatible\n    let head = std::str::from_utf8(head_bytes)\n        .map_err(|_| anyhow::anyhow!(\"Request headers contain invalid UTF-8\"))?;\n\n    // normalize line endings in the decoded head\n    let normalized = head.replace(\"\\r\\n\", \"\\n\");\n\n    // we only want to use the request's body bytes if the user hasn't\n    // overridden it on the cli\n    if config.data.is_empty() {\n        config.data = body_bytes.to_vec();","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/epi052/feroxbuster/blob/1f595dab5c76858d5a14fbc47dabf2563d729c62/src/config/utils.rs#L439-L475","documentation":"parse_request_file locates the first header/body separator (`\\r\\n\\r\\n` or `\\n\\n`) in the raw request file. If neither separator is present, the file has no way to divide headers from the body, so the request is malformed and the function throws. A valid raw HTTP request always contains a blank line ending the header section.","triggerScenarios":"Providing a `--request-file` whose contents contain neither `\\r\\n\\r\\n` nor `\\n\\n` — e.g. just a request line with headers but no terminating blank line, or a plain URL/text pasted in.","commonSituations":"Copy-pasting requests from logs where the trailing blank line was dropped, using LF-only editors that strip the final empty line, or writing a body-less request without the closing CRLF CRLF.","solutions":["Add a blank line after the headers to terminate the header section (`\\r\\n\\r\\n` or `\\n\\n`)","Re-copy the raw request from the source (e.g. browser devtools 'copy as cURL' or HAR) including the separator","Use CRLF line endings consistently when exporting the request file"],"exampleFix":"// before (request.txt)\nGET / HTTP/1.1\nHost: example.com\n// after\nGET / HTTP/1.1\nHost: example.com\n\n","handlingStrategy":"validation","validationCode":"let contents = std::fs::read(&path)?;\nif !contents.windows(4).any(|w| w == b\"\\r\\n\\r\\n\") && !contents.windows(2).any(|w| w == b\"\\n\\n\") {\n    return Err(anyhow!(\"request file has no head/body separator\"));\n}","typeGuard":null,"tryCatchPattern":"match parse_request_file(&mut config) {\n    Ok(()) => {},\n    Err(e) => eprintln!(\"bad --request-file: {e}; ensure a blank line separates headers from body\"),\n}","preventionTips":["Always end the header section with a blank line (\\r\\n\\r\\n preferred)","Copy raw requests from a source that preserves the separator (devtools, HAR)","Use an editor that does not strip trailing blank lines; save with consistent line endings"],"tags":["request-file","http","malformed-input","rust"],"backgroundTag":"invalid-argument-format","analyzedSha":"1f595dab5c76858d5a14fbc47dabf2563d729c62","analyzedAt":"2026-09-13T19:33:06.208Z","contentChangedAt":"2026-09-13T19:33:06.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}