diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java index 4af3b511f4..cef0d2cb89 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java @@ -39,7 +39,7 @@ public class HttpRequestDecoder extends HttpMessageDecoder { checkpoint(State.READ_HEADER); String[] split = splitInitial(line); message = new DefaultHttpRequest( - HttpVersion.decode(split[2]), HttpMethod.valueOf(split[0]), split[1]); + HttpVersion.valueOf(split[2]), HttpMethod.valueOf(split[0]), split[1]); } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java index 41bb9d709c..5bb4dd1189 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java @@ -48,7 +48,7 @@ public class HttpRequestEncoder extends HttpMessageEncoder { buf.writeByte(SP); buf.writeBytes(request.getUri().getBytes()); buf.writeByte(SP); - buf.writeBytes(request.getProtocolVersion().value().getBytes()); + buf.writeBytes(request.getProtocolVersion().toString().getBytes()); buf.writeBytes(CRLF); } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java index 6bc24d3350..12c9e8a11a 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java @@ -37,6 +37,6 @@ public class HttpResponseDecoder extends HttpMessageDecoder { String line = readIntoCurrentLine(buffer); checkpoint(State.READ_HEADER); String[] split = splitInitial(line); - message = new DefaultHttpResponse(HttpVersion.decode(split[0]), new HttpResponseStatus(Integer.valueOf(split[1]), split[2])); + message = new DefaultHttpResponse(HttpVersion.valueOf(split[0]), new HttpResponseStatus(Integer.valueOf(split[1]), split[2])); } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java index 7324f13048..9167c5c0f2 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java @@ -37,7 +37,7 @@ public class HttpResponseEncoder extends HttpMessageEncoder { @Override protected void encodeInitialLine(ChannelBuffer buf, HttpMessage message) { HttpResponse response = (HttpResponse) message; - buf.writeBytes(response.getProtocolVersion().value().getBytes()); + buf.writeBytes(response.getProtocolVersion().toString().getBytes()); buf.writeByte(SP); buf.writeBytes(String.valueOf(response.getStatus().getCode()).getBytes()); buf.writeByte(SP); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpVersion.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpVersion.java index 59212c09ee..2222ffe5a8 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpVersion.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpVersion.java @@ -31,33 +31,122 @@ package org.jboss.netty.handler.codec.http; * * @apiviz.exclude */ -public enum HttpVersion { - HTTP_1_0("HTTP/1.0"), - HTTP_1_1("HTTP/1.1"), - UNKNOWN("UNKNOWN"),; +public class HttpVersion implements Comparable { - private final String version; + public static final HttpVersion HTTP_1_0 = new HttpVersion("HTTP", 1, 0); + public static final HttpVersion HTTP_1_1 = new HttpVersion("HTTP", 1, 1); - private HttpVersion(String version) { - this.version = version; - } + private static final java.util.regex.Pattern VERSION_PATTERN = + java.util.regex.Pattern.compile("(\\S+)/(\\d+)\\.(\\d+)"); - public String value() { - return version; - } - - public static HttpVersion decode(String value) { - if (value == null) { - return UNKNOWN; - } - else if (value.equals(HTTP_1_0.value())) { - return HTTP_1_0; - } - else if (value.equals(HTTP_1_1.value())) { + public static HttpVersion valueOf(String value) { + value = value.toUpperCase(); + if (value.equals("HTTP/1.1")) { return HTTP_1_1; } - else { - return UNKNOWN; + if (value.equals("HTTP/1.0")) { + return HTTP_1_0; } + return new HttpVersion(value); + } + + private final String protocolName; + private final int majorVersion; + private final int minorVersion; + private final String string; + + public HttpVersion(String value) { + if (value == null) { + throw new NullPointerException("value"); + } + + java.util.regex.Matcher m = VERSION_PATTERN.matcher(value); + if (!m.matches()) { + throw new IllegalArgumentException("invalid version format: " + value); + } + + this.protocolName = m.group(1); + this.majorVersion = Integer.parseInt(m.group(2)); + this.minorVersion = Integer.parseInt(m.group(3)); + this.string = protocolName + '/' + majorVersion + '.' + minorVersion; + } + + public HttpVersion( + String protocolName, int majorVersion, int minorVersion) { + if (protocolName == null) { + throw new NullPointerException("protocolName"); + } + + protocolName = protocolName.trim().toUpperCase(); + if (protocolName.length() == 0) { + throw new IllegalArgumentException("empty protocolName"); + } + + for (int i = 0; i < protocolName.length(); i ++) { + if (Character.isWhitespace(protocolName.charAt(i))) { + throw new IllegalArgumentException("whitespace in protocolName"); + } + } + + if (majorVersion < 0) { + throw new IllegalArgumentException("negative majorVersion"); + } + if (minorVersion < 0) { + throw new IllegalArgumentException("negative minorVersion"); + } + + this.protocolName = protocolName; + this.majorVersion = majorVersion; + this.minorVersion = minorVersion; + this.string = protocolName + '/' + majorVersion + '.' + minorVersion; + } + + public String getProtocolName() { + return protocolName; + } + + public int getMajorVersion() { + return majorVersion; + } + + public int getMinorVersion() { + return minorVersion; + } + + @Override + public String toString() { + return string; + } + + @Override + public int hashCode() { + return (getProtocolName().hashCode() * 31 + getMajorVersion()) * 31 + + getMinorVersion(); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof HttpVersion)) { + return false; + } + + HttpVersion that = (HttpVersion) o; + return getMinorVersion() == that.getMinorVersion() && + getMajorVersion() == that.getMajorVersion() && + getProtocolName().equals(that.getProtocolName()); + } + + public int compareTo(HttpVersion o) { + int v = getProtocolName().compareTo(o.getProtocolName()); + if (v != 0) { + return v; + } + + v = getMajorVersion() - o.getMajorVersion(); + if (v != 0) { + return v; + } + + return getMinorVersion() - o.getMinorVersion(); } }