I'm building an HTTP server and parsing request headers. My current code fails when the Host header includes a port number because I'm splitting on :.

Current Code:

String[] header = line.split(":");
String key = header[0].trim();
String value = header[1].trim();
if (key.equals("Host")) {
    value = value + ":" + header[2]; // ArrayIndexOutOfBoundsException!
}

Problem:

  • Works for Host: example.com:8080

  • Fails for Host: example.com (no port)

Question:

What's the best way to rejoin header values that may contain colons?

What I've tried:

  • Checking header.length but feels clunky

  • Using indexOf(':') instead of split()

Which approach is more robust for HTTP header parsing?

2 Replies 2

Definitely do not use split(). You don't need to extract an array of delimited strings for a single header. Using indexOf() with substring() will suffice.

Also, HTTP header names are case-insensitive.

Try this:

int index = line.indexOf(':');
String key = line.substring(0, index).trim();
String value = line.substring(index+1).trim();
if (key.compareToIgnoreCase("Host") == 0) {
    ...
}

.split(":", 2) will do exactly what you want:

String[] parts = "Host: foobar.com:1234".split("\\s*:\\s*", 2);
assert parts.length == 2;
assert parts[0].equals("Host");
assert parts[1].equals("foobar.com:1234");

I'm sure folks have told you this, but note that whatever you end up with, if you open it up to the internet, someone will hack it. The HTTP protocol is unbelievably complicated and the spec is essentially useless (you have to process and emit what existing user agents actually send and expect; following the spec has no meaningful purpose if e.g. your webserver does not interact well with chrome or safari, for example).

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.