affaan-m/ECC · error · anyhow::Error
Missing HTTP method
Error message
Missing HTTP method
What it means
Thrown by read_http_request when the request line is present and non-empty (it passed the blank-line filter) but split_whitespace yields no first token to use as the HTTP method. The parser needs METHOD PATH VERSION and bails if the method token is absent.
Source
Thrown at ecc2/src/main.rs:4219
if let Some(index) = buffer.windows(4).position(|window| window == b"\r\n\r\n") {
break index + 4;
}
if buffer.len() > 64 * 1024 {
anyhow::bail!("HTTP request headers too large");
}
};
let header_text = String::from_utf8(buffer[..header_end].to_vec())
.context("HTTP request headers were not valid UTF-8")?;
let mut lines = header_text.split("\r\n");
let request_line = lines
.next()
.filter(|line| !line.trim().is_empty())
.ok_or_else(|| anyhow::anyhow!("Missing HTTP request line"))?;
let mut request_parts = request_line.split_whitespace();
let method = request_parts
.next()
.ok_or_else(|| anyhow::anyhow!("Missing HTTP method"))?
.to_string();
let path = request_parts
.next()
.ok_or_else(|| anyhow::anyhow!("Missing HTTP path"))?
.to_string();
let mut headers = BTreeMap::new();
for line in lines {
if line.is_empty() {
break;
}
if let Some((key, value)) = line.split_once(':') {
headers.insert(key.trim().to_ascii_lowercase(), value.trim().to_string());
}
}
let content_length = headers
.get("content-length")View on GitHub (pinned to 01e15490f0)
Solutions
- Inspect the raw bytes the client sent (tcpdump/Wireshark or log the buffer) and fix the client to send a well-formed request line like 'GET / HTTP/1.1'.
- Treat this as a 400 Bad Request at the accept site instead of crashing the listener.
- If you control the client, validate the request line before writing it to the socket.
Example fix
// caller: classify parse failures as client errors
match read_http_request(&mut stream) {
Ok(req) => dispatch(req),
Err(e) if e.to_string().contains("Missing HTTP method") => {
let _ = write_http_response(&mut stream, 400, "text/plain", "bad request line");
}
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
fn has_method_token(request_line: &str) -> bool {
request_line.trim().split_whitespace().next().is_some()
} Try / catch
match read_http_request(&mut stream) {
Ok(req) => dispatch(req),
Err(e) if e.to_string().contains("Missing HTTP method") => {
let _ = write_http_response(&mut stream, 400, "text/plain", "bad request line");
}
Err(e) => return Err(e),
} Prevention
- Treat any header-parse failure as a client-side 400, not a server crash.
- Unit-test the parser against common malformed inputs.
When it happens
Trigger: Effectively a defensive guard: because the prior filter rejects lines that trim to empty, split_whitespace would normally yield at least one token. It can still fire if the request line is composed solely of whitespace-like characters that pass the empty check in some edge form, or if a future refactor weakens the filter. Nominal trigger is a first line with no recognizable method token.
Common situations: Malformed hand-crafted requests, buggy custom HTTP clients that emit a request line with only delimiters, or protocol probes that send non-HTTP bytes whose first line happens to be non-empty but contains no method.
Related errors
- Missing HTTP request line
- Missing HTTP path
- Unexpected EOF while reading HTTP request body
- HTTP ${res.status}
- open failed (HTTP ${res.statusCode})
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/06f41e564de95beb.
Report an issue: GitHub.