diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java index 902ae4c91d..e6d0b01f39 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java @@ -15,6 +15,8 @@ */ package io.netty.handler.codec.http; +import io.netty.buffer.ByteBuf; + import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -31,31 +33,12 @@ public class DefaultHttpHeaders extends HttpHeaders { private static final int BUCKET_SIZE = 17; - private static int hash(String name) { - int h = 0; - for (int i = name.length() - 1; i >= 0; i --) { - char c = name.charAt(i); - if (c >= 'A' && c <= 'Z') { - c += 32; - } - h = 31 * h + c; - } - - if (h > 0) { - return h; - } else if (h == Integer.MIN_VALUE) { - return Integer.MAX_VALUE; - } else { - return -h; - } - } - private static int index(int hash) { return hash % BUCKET_SIZE; } private final HeaderEntry[] entries = new HeaderEntry[BUCKET_SIZE]; - private final HeaderEntry head = new HeaderEntry(-1, null, null); + private final HeaderEntry head = new HeaderEntry(); protected final boolean validate; public DefaultHttpHeaders() { @@ -67,19 +50,50 @@ public class DefaultHttpHeaders extends HttpHeaders { head.before = head.after = head; } - void validateHeaderName0(String headerName) { + void validateHeaderName0(CharSequence headerName) { validateHeaderName(headerName); } @Override - public HttpHeaders add(final String name, final Object value) { - String strVal; + public HttpHeaders add(HttpHeaders headers) { + if (headers instanceof DefaultHttpHeaders) { + DefaultHttpHeaders defaultHttpHeaders = (DefaultHttpHeaders) headers; + HeaderEntry e = defaultHttpHeaders.head.after; + while (e != defaultHttpHeaders.head) { + add(e.key, e.value); + e = e.after; + } + return this; + } else { + return super.add(headers); + } + } + + @Override + public HttpHeaders set(HttpHeaders headers) { + if (headers instanceof DefaultHttpHeaders) { + clear(); + DefaultHttpHeaders defaultHttpHeaders = (DefaultHttpHeaders) headers; + HeaderEntry e = defaultHttpHeaders.head.after; + while (e != defaultHttpHeaders.head) { + add(e.key, e.value); + e = e.after; + } + return this; + } else { + return super.set(headers); + } + } + + @Override + public HttpHeaders add(final CharSequence name, final Object value) { + CharSequence strVal; if (validate) { validateHeaderName0(name); - strVal = toString(value); + strVal = toCharsequence(value); validateHeaderValue(strVal); } else { - strVal = toString(value); + strVal = toCharsequence(value); } int h = hash(name); int i = index(h); @@ -88,14 +102,14 @@ public class DefaultHttpHeaders extends HttpHeaders { } @Override - public HttpHeaders add(String name, Iterable values) { + public HttpHeaders add(CharSequence name, Iterable values) { if (validate) { validateHeaderName0(name); } int h = hash(name); int i = index(h); for (Object v: values) { - String vstr = toString(v); + CharSequence vstr = toCharsequence(v); if (validate) { validateHeaderValue(vstr); } @@ -104,7 +118,7 @@ public class DefaultHttpHeaders extends HttpHeaders { return this; } - private void add0(int h, int i, final String name, final String value) { + private void add0(int h, int i, final CharSequence name, final CharSequence value) { // Update the hash table. HeaderEntry e = entries[i]; HeaderEntry newEntry; @@ -116,7 +130,7 @@ public class DefaultHttpHeaders extends HttpHeaders { } @Override - public HttpHeaders remove(final String name) { + public HttpHeaders remove(final CharSequence name) { if (name == null) { throw new NullPointerException("name"); } @@ -126,7 +140,7 @@ public class DefaultHttpHeaders extends HttpHeaders { return this; } - private void remove0(int h, int i, String name) { + private void remove0(int h, int i, CharSequence name) { HeaderEntry e = entries[i]; if (e == null) { return; @@ -163,14 +177,14 @@ public class DefaultHttpHeaders extends HttpHeaders { } @Override - public HttpHeaders set(final String name, final Object value) { - String strVal; + public HttpHeaders set(final CharSequence name, final Object value) { + CharSequence strVal; if (validate) { validateHeaderName0(name); - strVal = toString(value); + strVal = toCharsequence(value); validateHeaderValue(strVal); } else { - strVal = toString(value); + strVal = toCharsequence(value); } int h = hash(name); int i = index(h); @@ -180,7 +194,7 @@ public class DefaultHttpHeaders extends HttpHeaders { } @Override - public HttpHeaders set(final String name, final Iterable values) { + public HttpHeaders set(final CharSequence name, final Iterable values) { if (values == null) { throw new NullPointerException("values"); } @@ -196,7 +210,7 @@ public class DefaultHttpHeaders extends HttpHeaders { if (v == null) { break; } - String strVal = toString(v); + CharSequence strVal = toCharsequence(v); if (validate) { validateHeaderValue(strVal); } @@ -214,7 +228,7 @@ public class DefaultHttpHeaders extends HttpHeaders { } @Override - public String get(final String name) { + public String get(final CharSequence name) { if (name == null) { throw new NullPointerException("name"); } @@ -222,7 +236,7 @@ public class DefaultHttpHeaders extends HttpHeaders { int h = hash(name); int i = index(h); HeaderEntry e = entries[i]; - String value = null; + CharSequence value = null; // loop until the first header was found while (e != null) { if (e.hash == h && equalsIgnoreCase(name, e.key)) { @@ -231,11 +245,14 @@ public class DefaultHttpHeaders extends HttpHeaders { e = e.next; } - return value; + if (value != null) { + return value.toString(); + } + return null; } @Override - public List getAll(final String name) { + public List getAll(final CharSequence name) { if (name == null) { throw new NullPointerException("name"); } @@ -247,7 +264,7 @@ public class DefaultHttpHeaders extends HttpHeaders { HeaderEntry e = entries[i]; while (e != null) { if (e.hash == h && equalsIgnoreCase(name, e.key)) { - values.addFirst(e.value); + values.addFirst(e.getValue()); } e = e.next; } @@ -273,7 +290,7 @@ public class DefaultHttpHeaders extends HttpHeaders { } @Override - public boolean contains(String name) { + public boolean contains(CharSequence name) { return get(name) != null; } @@ -283,7 +300,7 @@ public class DefaultHttpHeaders extends HttpHeaders { } @Override - public boolean contains(String name, String value, boolean ignoreCaseValue) { + public boolean contains(CharSequence name, CharSequence value, boolean ignoreCaseValue) { if (name == null) { throw new NullPointerException("name"); } @@ -315,18 +332,26 @@ public class DefaultHttpHeaders extends HttpHeaders { HeaderEntry e = head.after; while (e != head) { - names.add(e.key); + names.add(e.getKey()); e = e.after; } return names; } - private static String toString(Object value) { + void encode(ByteBuf buf) { + HeaderEntry e = head.after; + while (e != head) { + e.encode(buf); + e = e.after; + } + } + + private static CharSequence toCharsequence(Object value) { if (value == null) { return null; } - if (value instanceof String) { - return (String) value; + if (value instanceof CharSequence) { + return (CharSequence) value; } if (value instanceof Number) { return value.toString(); @@ -368,17 +393,23 @@ public class DefaultHttpHeaders extends HttpHeaders { private final class HeaderEntry implements Map.Entry { final int hash; - final String key; - String value; + final CharSequence key; + CharSequence value; HeaderEntry next; HeaderEntry before, after; - HeaderEntry(int hash, String key, String value) { + HeaderEntry(int hash, CharSequence key, CharSequence value) { this.hash = hash; this.key = key; this.value = value; } + HeaderEntry() { + hash = -1; + key = null; + value = null; + } + void remove() { before.after = after; after.before = before; @@ -393,12 +424,12 @@ public class DefaultHttpHeaders extends HttpHeaders { @Override public String getKey() { - return key; + return key.toString(); } @Override public String getValue() { - return value; + return value.toString(); } @Override @@ -407,14 +438,18 @@ public class DefaultHttpHeaders extends HttpHeaders { throw new NullPointerException("value"); } validateHeaderValue(value); - String oldValue = this.value; + CharSequence oldValue = this.value; this.value = value; - return oldValue; + return oldValue.toString(); } @Override public String toString() { - return key + '=' + value; + return key.toString() + '=' + value.toString(); + } + + void encode(ByteBuf buf) { + HttpHeaders.encode(key, value, buf); } } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultLastHttpContent.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultLastHttpContent.java index 5c50f42a49..cd88d58f0b 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultLastHttpContent.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultLastHttpContent.java @@ -100,11 +100,11 @@ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHt } @Override - void validateHeaderName0(String name) { + void validateHeaderName0(CharSequence name) { super.validateHeaderName0(name); - if (name.equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH) || - name.equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING) || - name.equalsIgnoreCase(HttpHeaders.Names.TRAILER)) { + if (equalsIgnoreCase(name, HttpHeaders.Names.CONTENT_LENGTH) || + equalsIgnoreCase(name, HttpHeaders.Names.TRANSFER_ENCODING) || + equalsIgnoreCase(name, HttpHeaders.Names.TRAILER)) { throw new IllegalArgumentException( "prohibited trailing header: " + name); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentCompressor.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentCompressor.java index 5fcef790d0..1fa4ac593c 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentCompressor.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentCompressor.java @@ -93,10 +93,10 @@ public class HttpContentCompressor extends HttpContentEncoder { } @Override - protected Result beginEncode(HttpResponse headers, String acceptEncoding) throws Exception { + protected Result beginEncode(HttpResponse headers, CharSequence acceptEncoding) throws Exception { String contentEncoding = headers.headers().get(HttpHeaders.Names.CONTENT_ENCODING); if (contentEncoding != null && - !HttpHeaders.Values.IDENTITY.equalsIgnoreCase(contentEncoding)) { + !HttpHeaders.equalsIgnoreCase(HttpHeaders.Values.IDENTITY, contentEncoding)) { return null; } @@ -123,11 +123,11 @@ public class HttpContentCompressor extends HttpContentEncoder { wrapper, compressionLevel, windowBits, memLevel))); } - protected ZlibWrapper determineWrapper(String acceptEncoding) { + protected ZlibWrapper determineWrapper(CharSequence acceptEncoding) { float starQ = -1.0f; float gzipQ = -1.0f; float deflateQ = -1.0f; - for (String encoding: StringUtil.split(acceptEncoding, ',')) { + for (String encoding: StringUtil.split(acceptEncoding.toString(), ',')) { float q = 1.0f; int equalsPos = encoding.indexOf('='); if (equalsPos != -1) { diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java index 789e829b00..3e795c758d 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecoder.java @@ -91,13 +91,13 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder'Content-Encoding' header * is set to the target content encoding, as returned by - * {@link #beginEncode(HttpResponse, String)}. + * {@link #beginEncode(HttpResponse, CharSequence)}. * Also, the 'Content-Length' header is updated to the length of the * encoded content. If there is no supported or allowed encoding in the * corresponding {@link HttpRequest}'s {@code "Accept-Encoding"} header, - * {@link #beginEncode(HttpResponse, String)} should return {@code null} so that + * {@link #beginEncode(HttpResponse, CharSequence)} should return {@code null} so that * no encoding occurs (i.e. pass-through). *

* Please note that this is an abstract class. You have to extend this class - * and implement {@link #beginEncode(HttpResponse, String)} properly to make + * and implement {@link #beginEncode(HttpResponse, CharSequence)} properly to make * this class functional. For example, refer to the source code of * {@link HttpContentCompressor}. *

@@ -58,8 +58,8 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec acceptEncodingQueue = new ArrayDeque(); - private String acceptEncoding; + private final Queue acceptEncodingQueue = new ArrayDeque(); + private CharSequence acceptEncoding; private EmbeddedChannel encoder; private State state = State.AWAIT_HEADERS; @@ -71,7 +71,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec out) throws Exception { - String acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); + CharSequence acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); if (acceptedEncoding == null) { acceptedEncoding = HttpHeaders.Values.IDENTITY; } @@ -228,7 +228,7 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec> { + private static final byte[] HEADER_SEPERATOR = { HttpConstants.COLON, HttpConstants.SP }; + private static final byte[] CRLF = { CR, LF }; + public static final HttpHeaders EMPTY_HEADERS = new HttpHeaders() { @Override - public String get(String name) { + public String get(CharSequence name) { return null; } @Override - public List getAll(String name) { + public List getAll(CharSequence name) { return Collections.emptyList(); } @@ -49,7 +57,7 @@ public abstract class HttpHeaders implements Iterable> } @Override - public boolean contains(String name) { + public boolean contains(CharSequence name) { return false; } @@ -64,27 +72,27 @@ public abstract class HttpHeaders implements Iterable> } @Override - public HttpHeaders add(String name, Object value) { + public HttpHeaders add(CharSequence name, Object value) { throw new UnsupportedOperationException("read only"); } @Override - public HttpHeaders add(String name, Iterable values) { + public HttpHeaders add(CharSequence name, Iterable values) { throw new UnsupportedOperationException("read only"); } @Override - public HttpHeaders set(String name, Object value) { + public HttpHeaders set(CharSequence name, Object value) { throw new UnsupportedOperationException("read only"); } @Override - public HttpHeaders set(String name, Iterable values) { + public HttpHeaders set(CharSequence name, Iterable values) { throw new UnsupportedOperationException("read only"); } @Override - public HttpHeaders remove(String name) { + public HttpHeaders remove(CharSequence name) { throw new UnsupportedOperationException("read only"); } @@ -106,295 +114,302 @@ public abstract class HttpHeaders implements Iterable> /** * {@code "Accept"} */ - public static final String ACCEPT = "Accept"; + public static final CharSequence ACCEPT = newEntity("Accept"); /** * {@code "Accept-Charset"} */ - public static final String ACCEPT_CHARSET = "Accept-Charset"; + public static final CharSequence ACCEPT_CHARSET = newEntity("Accept-Charset"); /** * {@code "Accept-Encoding"} */ - public static final String ACCEPT_ENCODING = "Accept-Encoding"; + public static final CharSequence ACCEPT_ENCODING = newEntity("Accept-Encoding"); /** * {@code "Accept-Language"} */ - public static final String ACCEPT_LANGUAGE = "Accept-Language"; + public static final CharSequence ACCEPT_LANGUAGE = newEntity("Accept-Language"); /** * {@code "Accept-Ranges"} */ - public static final String ACCEPT_RANGES = "Accept-Ranges"; + public static final CharSequence ACCEPT_RANGES = newEntity("Accept-Ranges"); /** * {@code "Accept-Patch"} */ - public static final String ACCEPT_PATCH = "Accept-Patch"; + public static final CharSequence ACCEPT_PATCH = newEntity("Accept-Patch"); /** * {@code "Access-Control-Allow-Credentials"} */ - public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"; + public static final CharSequence ACCESS_CONTROL_ALLOW_CREDENTIALS = + newEntity("Access-Control-Allow-Credentials"); /** * {@code "Access-Control-Allow-Headers"} */ - public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"; + public static final CharSequence ACCESS_CONTROL_ALLOW_HEADERS = + newEntity("Access-Control-Allow-Headers"); /** * {@code "Access-Control-Allow-Methods"} */ - public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"; + public static final CharSequence ACCESS_CONTROL_ALLOW_METHODS = + newEntity("Access-Control-Allow-Methods"); /** * {@code "Access-Control-Allow-Origin"} */ - public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; + public static final CharSequence ACCESS_CONTROL_ALLOW_ORIGIN = + newEntity("Access-Control-Allow-Origin"); /** * {@code "Access-Control-Expose-Headers"} */ - public static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers"; + public static final CharSequence ACCESS_CONTROL_EXPOSE_HEADERS = + newEntity("Access-Control-Expose-Headers"); /** * {@code "Access-Control-Max-Age"} */ - public static final String ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age"; + public static final CharSequence ACCESS_CONTROL_MAX_AGE = newEntity("Access-Control-Max-Age"); /** * {@code "Access-Control-Request-Headers"} */ - public static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers"; + public static final CharSequence ACCESS_CONTROL_REQUEST_HEADERS = + newEntity("Access-Control-Request-Headers"); /** * {@code "Access-Control-Request-Method"} */ - public static final String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method"; + public static final CharSequence ACCESS_CONTROL_REQUEST_METHOD = + newEntity("Access-Control-Request-Method"); /** * {@code "Age"} */ - public static final String AGE = "Age"; + public static final CharSequence AGE = newEntity("Age"); /** * {@code "Allow"} */ - public static final String ALLOW = "Allow"; + public static final CharSequence ALLOW = newEntity("Allow"); /** * {@code "Authorization"} */ - public static final String AUTHORIZATION = "Authorization"; + public static final CharSequence AUTHORIZATION = newEntity("Authorization"); /** * {@code "Cache-Control"} */ - public static final String CACHE_CONTROL = "Cache-Control"; + public static final CharSequence CACHE_CONTROL = newEntity("Cache-Control"); /** * {@code "Connection"} */ - public static final String CONNECTION = "Connection"; + public static final CharSequence CONNECTION = newEntity("Connection"); /** * {@code "Content-Base"} */ - public static final String CONTENT_BASE = "Content-Base"; + public static final CharSequence CONTENT_BASE = newEntity("Content-Base"); /** * {@code "Content-Encoding"} */ - public static final String CONTENT_ENCODING = "Content-Encoding"; + public static final CharSequence CONTENT_ENCODING = newEntity("Content-Encoding"); /** * {@code "Content-Language"} */ - public static final String CONTENT_LANGUAGE = "Content-Language"; + public static final CharSequence CONTENT_LANGUAGE = newEntity("Content-Language"); /** * {@code "Content-Length"} */ - public static final String CONTENT_LENGTH = "Content-Length"; + public static final CharSequence CONTENT_LENGTH = newEntity("Content-Length"); /** * {@code "Content-Location"} */ - public static final String CONTENT_LOCATION = "Content-Location"; + public static final CharSequence CONTENT_LOCATION = newEntity("Content-Location"); /** * {@code "Content-Transfer-Encoding"} */ - public static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding"; + public static final CharSequence CONTENT_TRANSFER_ENCODING = newEntity("Content-Transfer-Encoding"); /** * {@code "Content-MD5"} */ - public static final String CONTENT_MD5 = "Content-MD5"; + public static final CharSequence CONTENT_MD5 = newEntity("Content-MD5"); /** * {@code "Content-Range"} */ - public static final String CONTENT_RANGE = "Content-Range"; + public static final CharSequence CONTENT_RANGE = newEntity("Content-Range"); /** * {@code "Content-Type"} */ - public static final String CONTENT_TYPE = "Content-Type"; + public static final CharSequence CONTENT_TYPE = newEntity("Content-Type"); /** * {@code "Cookie"} */ - public static final String COOKIE = "Cookie"; + public static final CharSequence COOKIE = newEntity("Cookie"); /** * {@code "Date"} */ - public static final String DATE = "Date"; + public static final CharSequence DATE = newEntity("Date"); /** * {@code "ETag"} */ - public static final String ETAG = "ETag"; + public static final CharSequence ETAG = newEntity("ETag"); /** * {@code "Expect"} */ - public static final String EXPECT = "Expect"; + public static final CharSequence EXPECT = newEntity("Expect"); /** * {@code "Expires"} */ - public static final String EXPIRES = "Expires"; + public static final CharSequence EXPIRES = newEntity("Expires"); /** * {@code "From"} */ - public static final String FROM = "From"; + public static final CharSequence FROM = newEntity("From"); /** * {@code "Host"} */ - public static final String HOST = "Host"; + public static final CharSequence HOST = newEntity("Host"); /** * {@code "If-Match"} */ - public static final String IF_MATCH = "If-Match"; + public static final CharSequence IF_MATCH = newEntity("If-Match"); /** * {@code "If-Modified-Since"} */ - public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; + public static final CharSequence IF_MODIFIED_SINCE = newEntity("If-Modified-Since"); /** * {@code "If-None-Match"} */ - public static final String IF_NONE_MATCH = "If-None-Match"; + public static final CharSequence IF_NONE_MATCH = newEntity("If-None-Match"); /** * {@code "If-Range"} */ - public static final String IF_RANGE = "If-Range"; + public static final CharSequence IF_RANGE = newEntity("If-Range"); /** * {@code "If-Unmodified-Since"} */ - public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; + public static final CharSequence IF_UNMODIFIED_SINCE = newEntity("If-Unmodified-Since"); /** * {@code "Last-Modified"} */ - public static final String LAST_MODIFIED = "Last-Modified"; + public static final CharSequence LAST_MODIFIED = newEntity("Last-Modified"); /** * {@code "Location"} */ - public static final String LOCATION = "Location"; + public static final CharSequence LOCATION = newEntity("Location"); /** * {@code "Max-Forwards"} */ - public static final String MAX_FORWARDS = "Max-Forwards"; + public static final CharSequence MAX_FORWARDS = newEntity("Max-Forwards"); /** * {@code "Origin"} */ - public static final String ORIGIN = "Origin"; + public static final CharSequence ORIGIN = newEntity("Origin"); /** * {@code "Pragma"} */ - public static final String PRAGMA = "Pragma"; + public static final CharSequence PRAGMA = newEntity("Pragma"); /** * {@code "Proxy-Authenticate"} */ - public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate"; + public static final CharSequence PROXY_AUTHENTICATE = newEntity("Proxy-Authenticate"); /** * {@code "Proxy-Authorization"} */ - public static final String PROXY_AUTHORIZATION = "Proxy-Authorization"; + public static final CharSequence PROXY_AUTHORIZATION = newEntity("Proxy-Authorization"); /** * {@code "Range"} */ - public static final String RANGE = "Range"; + public static final CharSequence RANGE = newEntity("Range"); /** * {@code "Referer"} */ - public static final String REFERER = "Referer"; + public static final CharSequence REFERER = newEntity("Referer"); /** * {@code "Retry-After"} */ - public static final String RETRY_AFTER = "Retry-After"; + public static final CharSequence RETRY_AFTER = newEntity("Retry-After"); /** * {@code "Sec-WebSocket-Key1"} */ - public static final String SEC_WEBSOCKET_KEY1 = "Sec-WebSocket-Key1"; + public static final CharSequence SEC_WEBSOCKET_KEY1 = newEntity("Sec-WebSocket-Key1"); /** * {@code "Sec-WebSocket-Key2"} */ - public static final String SEC_WEBSOCKET_KEY2 = "Sec-WebSocket-Key2"; + public static final CharSequence SEC_WEBSOCKET_KEY2 = newEntity("Sec-WebSocket-Key2"); /** * {@code "Sec-WebSocket-Location"} */ - public static final String SEC_WEBSOCKET_LOCATION = "Sec-WebSocket-Location"; + public static final CharSequence SEC_WEBSOCKET_LOCATION = newEntity("Sec-WebSocket-Location"); /** * {@code "Sec-WebSocket-Origin"} */ - public static final String SEC_WEBSOCKET_ORIGIN = "Sec-WebSocket-Origin"; + public static final CharSequence SEC_WEBSOCKET_ORIGIN = newEntity("Sec-WebSocket-Origin"); /** * {@code "Sec-WebSocket-Protocol"} */ - public static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol"; + public static final CharSequence SEC_WEBSOCKET_PROTOCOL = newEntity("Sec-WebSocket-Protocol"); /** * {@code "Sec-WebSocket-Version"} */ - public static final String SEC_WEBSOCKET_VERSION = "Sec-WebSocket-Version"; + public static final CharSequence SEC_WEBSOCKET_VERSION = newEntity("Sec-WebSocket-Version"); /** * {@code "Sec-WebSocket-Key"} */ - public static final String SEC_WEBSOCKET_KEY = "Sec-WebSocket-Key"; + public static final CharSequence SEC_WEBSOCKET_KEY = newEntity("Sec-WebSocket-Key"); /** * {@code "Sec-WebSocket-Accept"} */ - public static final String SEC_WEBSOCKET_ACCEPT = "Sec-WebSocket-Accept"; + public static final CharSequence SEC_WEBSOCKET_ACCEPT = newEntity("Sec-WebSocket-Accept"); /** * {@code "Server"} */ - public static final String SERVER = "Server"; + public static final CharSequence SERVER = newEntity("Server"); /** * {@code "Set-Cookie"} */ - public static final String SET_COOKIE = "Set-Cookie"; + public static final CharSequence SET_COOKIE = newEntity("Set-Cookie"); /** * {@code "Set-Cookie2"} */ - public static final String SET_COOKIE2 = "Set-Cookie2"; + public static final CharSequence SET_COOKIE2 = newEntity("Set-Cookie2"); /** * {@code "TE"} */ - public static final String TE = "TE"; + public static final CharSequence TE = newEntity("TE"); /** * {@code "Trailer"} */ - public static final String TRAILER = "Trailer"; + public static final CharSequence TRAILER = newEntity("Trailer"); /** * {@code "Transfer-Encoding"} */ - public static final String TRANSFER_ENCODING = "Transfer-Encoding"; + public static final CharSequence TRANSFER_ENCODING = newEntity("Transfer-Encoding"); /** * {@code "Upgrade"} */ - public static final String UPGRADE = "Upgrade"; + public static final CharSequence UPGRADE = newEntity("Upgrade"); /** * {@code "User-Agent"} */ - public static final String USER_AGENT = "User-Agent"; + public static final CharSequence USER_AGENT = newEntity("User-Agent"); /** * {@code "Vary"} */ - public static final String VARY = "Vary"; + public static final CharSequence VARY = newEntity("Vary"); /** * {@code "Via"} */ - public static final String VIA = "Via"; + public static final CharSequence VIA = newEntity("Via"); /** * {@code "Warning"} */ - public static final String WARNING = "Warning"; + public static final CharSequence WARNING = newEntity("Warning"); /** * {@code "WebSocket-Location"} */ - public static final String WEBSOCKET_LOCATION = "WebSocket-Location"; + public static final CharSequence WEBSOCKET_LOCATION = newEntity("WebSocket-Location"); /** * {@code "WebSocket-Origin"} */ - public static final String WEBSOCKET_ORIGIN = "WebSocket-Origin"; + public static final CharSequence WEBSOCKET_ORIGIN = newEntity("WebSocket-Origin"); /** * {@code "WebSocket-Protocol"} */ - public static final String WEBSOCKET_PROTOCOL = "WebSocket-Protocol"; + public static final CharSequence WEBSOCKET_PROTOCOL = newEntity("WebSocket-Protocol"); /** * {@code "WWW-Authenticate"} */ - public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + public static final CharSequence WWW_AUTHENTICATE = newEntity("WWW-Authenticate"); private Names() { } @@ -407,132 +422,132 @@ public abstract class HttpHeaders implements Iterable> /** * {@code "application/x-www-form-urlencoded"} */ - public static final String APPLICATION_X_WWW_FORM_URLENCODED = - "application/x-www-form-urlencoded"; + public static final CharSequence APPLICATION_X_WWW_FORM_URLENCODED = + newEntity("application/x-www-form-urlencoded"); /** * {@code "base64"} */ - public static final String BASE64 = "base64"; + public static final CharSequence BASE64 = newEntity("base64"); /** * {@code "binary"} */ - public static final String BINARY = "binary"; + public static final CharSequence BINARY = newEntity("binary"); /** * {@code "boundary"} */ - public static final String BOUNDARY = "boundary"; + public static final CharSequence BOUNDARY = newEntity("boundary"); /** * {@code "bytes"} */ - public static final String BYTES = "bytes"; + public static final CharSequence BYTES = newEntity("bytes"); /** * {@code "charset"} */ - public static final String CHARSET = "charset"; + public static final CharSequence CHARSET = newEntity("charset"); /** * {@code "chunked"} */ - public static final String CHUNKED = "chunked"; + public static final CharSequence CHUNKED = newEntity("chunked"); /** * {@code "close"} */ - public static final String CLOSE = "close"; + public static final CharSequence CLOSE = newEntity("close"); /** * {@code "compress"} */ - public static final String COMPRESS = "compress"; + public static final CharSequence COMPRESS = newEntity("compress"); /** * {@code "100-continue"} */ - public static final String CONTINUE = "100-continue"; + public static final CharSequence CONTINUE = newEntity("100-continue"); /** * {@code "deflate"} */ - public static final String DEFLATE = "deflate"; + public static final CharSequence DEFLATE = newEntity("deflate"); /** * {@code "gzip"} */ - public static final String GZIP = "gzip"; + public static final CharSequence GZIP = newEntity("gzip"); /** * {@code "identity"} */ - public static final String IDENTITY = "identity"; + public static final CharSequence IDENTITY = newEntity("identity"); /** * {@code "keep-alive"} */ - public static final String KEEP_ALIVE = "keep-alive"; + public static final CharSequence KEEP_ALIVE = newEntity("keep-alive"); /** * {@code "max-age"} */ - public static final String MAX_AGE = "max-age"; + public static final CharSequence MAX_AGE = newEntity("max-age"); /** * {@code "max-stale"} */ - public static final String MAX_STALE = "max-stale"; + public static final CharSequence MAX_STALE = newEntity("max-stale"); /** * {@code "min-fresh"} */ - public static final String MIN_FRESH = "min-fresh"; + public static final CharSequence MIN_FRESH = newEntity("min-fresh"); /** * {@code "multipart/form-data"} */ - public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + public static final CharSequence MULTIPART_FORM_DATA = newEntity("multipart/form-data"); /** * {@code "must-revalidate"} */ - public static final String MUST_REVALIDATE = "must-revalidate"; + public static final CharSequence MUST_REVALIDATE = newEntity("must-revalidate"); /** * {@code "no-cache"} */ - public static final String NO_CACHE = "no-cache"; + public static final CharSequence NO_CACHE = newEntity("no-cache"); /** * {@code "no-store"} */ - public static final String NO_STORE = "no-store"; + public static final CharSequence NO_STORE = newEntity("no-store"); /** * {@code "no-transform"} */ - public static final String NO_TRANSFORM = "no-transform"; + public static final CharSequence NO_TRANSFORM = newEntity("no-transform"); /** * {@code "none"} */ - public static final String NONE = "none"; + public static final CharSequence NONE = newEntity("none"); /** * {@code "only-if-cached"} */ - public static final String ONLY_IF_CACHED = "only-if-cached"; + public static final CharSequence ONLY_IF_CACHED = newEntity("only-if-cached"); /** * {@code "private"} */ - public static final String PRIVATE = "private"; + public static final CharSequence PRIVATE = newEntity("private"); /** * {@code "proxy-revalidate"} */ - public static final String PROXY_REVALIDATE = "proxy-revalidate"; + public static final CharSequence PROXY_REVALIDATE = newEntity("proxy-revalidate"); /** * {@code "public"} */ - public static final String PUBLIC = "public"; + public static final CharSequence PUBLIC = newEntity("public"); /** * {@code "quoted-printable"} */ - public static final String QUOTED_PRINTABLE = "quoted-printable"; + public static final CharSequence QUOTED_PRINTABLE = newEntity("quoted-printable"); /** * {@code "s-maxage"} */ - public static final String S_MAXAGE = "s-maxage"; + public static final CharSequence S_MAXAGE = newEntity("s-maxage"); /** * {@code "trailers"} */ - public static final String TRAILERS = "trailers"; + public static final CharSequence TRAILERS = newEntity("trailers"); /** * {@code "Upgrade"} */ - public static final String UPGRADE = "Upgrade"; + public static final CharSequence UPGRADE = newEntity("Upgrade"); /** * {@code "WebSocket"} */ - public static final String WEBSOCKET = "WebSocket"; + public static final CharSequence WEBSOCKET = newEntity("WebSocket"); private Values() { } @@ -600,7 +615,7 @@ public abstract class HttpHeaders implements Iterable> * * @return the header value or {@code null} if there is no such header */ - public static String getHeader(HttpMessage message, String name) { + public static String getHeader(HttpMessage message, CharSequence name) { return message.headers().get(name); } @@ -612,7 +627,7 @@ public abstract class HttpHeaders implements Iterable> * @return the header value or the {@code defaultValue} if there is no such * header */ - public static String getHeader(HttpMessage message, String name, String defaultValue) { + public static String getHeader(HttpMessage message, CharSequence name, String defaultValue) { String value = message.headers().get(name); if (value == null) { return defaultValue; @@ -628,7 +643,7 @@ public abstract class HttpHeaders implements Iterable> * and {@link Calendar} which are formatted to the date format defined in * RFC2616. */ - public static void setHeader(HttpMessage message, String name, Object value) { + public static void setHeader(HttpMessage message, CharSequence name, Object value) { message.headers().set(name, value); } @@ -646,7 +661,7 @@ public abstract class HttpHeaders implements Iterable> * } * */ - public static void setHeader(HttpMessage message, String name, Iterable values) { + public static void setHeader(HttpMessage message, CharSequence name, Iterable values) { message.headers().set(name, values); } @@ -657,14 +672,14 @@ public abstract class HttpHeaders implements Iterable> * and {@link Calendar} which are formatted to the date format defined in * RFC2616. */ - public static void addHeader(HttpMessage message, String name, Object value) { + public static void addHeader(HttpMessage message, CharSequence name, Object value) { message.headers().add(name, value); } /** * Removes the header with the specified name. */ - public static void removeHeader(HttpMessage message, String name) { + public static void removeHeader(HttpMessage message, CharSequence name) { message.headers().remove(name); } @@ -684,7 +699,7 @@ public abstract class HttpHeaders implements Iterable> * @throws NumberFormatException * if there is no such header or the header value is not a number */ - public static int getIntHeader(HttpMessage message, String name) { + public static int getIntHeader(HttpMessage message, CharSequence name) { String value = getHeader(message, name); if (value == null) { throw new NumberFormatException("header not found: " + name); @@ -700,7 +715,7 @@ public abstract class HttpHeaders implements Iterable> * @return the header value or the {@code defaultValue} if there is no such * header or the header value is not a number */ - public static int getIntHeader(HttpMessage message, String name, int defaultValue) { + public static int getIntHeader(HttpMessage message, CharSequence name, int defaultValue) { String value = getHeader(message, name); if (value == null) { return defaultValue; @@ -717,7 +732,7 @@ public abstract class HttpHeaders implements Iterable> * Sets a new integer header with the specified name and value. If there * is an existing header with the same name, the existing header is removed. */ - public static void setIntHeader(HttpMessage message, String name, int value) { + public static void setIntHeader(HttpMessage message, CharSequence name, int value) { message.headers().set(name, value); } @@ -725,14 +740,14 @@ public abstract class HttpHeaders implements Iterable> * Sets a new integer header with the specified name and values. If there * is an existing header with the same name, the existing header is removed. */ - public static void setIntHeader(HttpMessage message, String name, Iterable values) { + public static void setIntHeader(HttpMessage message, CharSequence name, Iterable values) { message.headers().set(name, values); } /** * Adds a new integer header with the specified name and value. */ - public static void addIntHeader(HttpMessage message, String name, int value) { + public static void addIntHeader(HttpMessage message, CharSequence name, int value) { message.headers().add(name, value); } @@ -745,7 +760,7 @@ public abstract class HttpHeaders implements Iterable> * @throws ParseException * if there is no such header or the header value is not a formatted date */ - public static Date getDateHeader(HttpMessage message, String name) throws ParseException { + public static Date getDateHeader(HttpMessage message, CharSequence name) throws ParseException { String value = getHeader(message, name); if (value == null) { throw new ParseException("header not found: " + name, 0); @@ -761,7 +776,7 @@ public abstract class HttpHeaders implements Iterable> * @return the header value or the {@code defaultValue} if there is no such * header or the header value is not a formatted date */ - public static Date getDateHeader(HttpMessage message, String name, Date defaultValue) { + public static Date getDateHeader(HttpMessage message, CharSequence name, Date defaultValue) { final String value = getHeader(message, name); if (value == null) { return defaultValue; @@ -780,7 +795,7 @@ public abstract class HttpHeaders implements Iterable> * The specified value is formatted as defined in * RFC2616 */ - public static void setDateHeader(HttpMessage message, String name, Date value) { + public static void setDateHeader(HttpMessage message, CharSequence name, Date value) { if (value != null) { message.headers().set(name, HttpHeaderDateFormat.get().format(value)); } else { @@ -794,7 +809,7 @@ public abstract class HttpHeaders implements Iterable> * The specified values are formatted as defined in * RFC2616 */ - public static void setDateHeader(HttpMessage message, String name, Iterable values) { + public static void setDateHeader(HttpMessage message, CharSequence name, Iterable values) { message.headers().set(name, values); } @@ -803,7 +818,7 @@ public abstract class HttpHeaders implements Iterable> * value is formatted as defined in * RFC2616 */ - public static void addDateHeader(HttpMessage message, String name, Date value) { + public static void addDateHeader(HttpMessage message, CharSequence name, Date value) { message.headers().add(name, value); } @@ -1010,7 +1025,7 @@ public abstract class HttpHeaders implements Iterable> * * @param headerName The header name being validated */ - static void validateHeaderName(String headerName) { + static void validateHeaderName(CharSequence headerName) { //Check to see if the name is null if (headerName == null) { throw new NullPointerException("Header names cannot be null"); @@ -1042,7 +1057,7 @@ public abstract class HttpHeaders implements Iterable> * * @param headerValue The value being validated */ - static void validateHeaderValue(String headerValue) { + static void validateHeaderValue(CharSequence headerValue) { //Check to see if the value is null if (headerValue == null) { throw new NullPointerException("Header values cannot be null"); @@ -1183,6 +1198,72 @@ public abstract class HttpHeaders implements Iterable> } return true; } + + static int hash(CharSequence name) { + if (name instanceof HttpHeaderEntity) { + return ((HttpHeaderEntity) name).hash(); + } + int h = 0; + for (int i = name.length() - 1; i >= 0; i --) { + char c = name.charAt(i); + if (c >= 'A' && c <= 'Z') { + c += 32; + } + h = 31 * h + c; + } + + if (h > 0) { + return h; + } else if (h == Integer.MIN_VALUE) { + return Integer.MAX_VALUE; + } else { + return -h; + } + } + + static void encode(HttpHeaders headers, ByteBuf buf) { + if (headers instanceof DefaultHttpHeaders) { + ((DefaultHttpHeaders) headers).encode(buf); + } else { + for (Entry header: headers) { + encode(header.getKey(), header.getValue(), buf); + } + } + } + + static void encode(CharSequence key, CharSequence value, ByteBuf buf) { + encodeAscii(key, buf); + buf.writeBytes(HEADER_SEPERATOR); + encodeAscii(value, buf); + buf.writeBytes(CRLF); + } + + public static void encodeAscii(CharSequence seq, ByteBuf buf) { + if (seq instanceof HttpHeaderEntity) { + ((HttpHeaderEntity) seq).encode(buf); + } else { + encodeAscii0(seq, buf); + } + } + + static void encodeAscii0(CharSequence seq, ByteBuf buf) { + int length = seq.length(); + for (int i = 0 ; i < length; i++) { + buf.writeByte((byte) seq.charAt(i)); + } + } + + /** + * Create a new {@link CharSequence} which is optimized for reuse as {@link HttpHeaders} name or value. + * So if you have a Header name or value that you want to reuse you should make use of this. + */ + public static CharSequence newEntity(String name) { + if (name == null) { + throw new NullPointerException("name"); + } + return new HttpHeaderEntity(name); + } + protected HttpHeaders() { } /** @@ -1192,7 +1273,7 @@ public abstract class HttpHeaders implements Iterable> * @param name The name of the header to search * @return The first header value or {@code null} if there is no such header */ - public abstract String get(String name); + public abstract String get(CharSequence name); /** * Returns the values of headers with the specified name @@ -1201,7 +1282,7 @@ public abstract class HttpHeaders implements Iterable> * @return A {@link List} of header values which will be empty if no values * are found */ - public abstract List getAll(String name); + public abstract List getAll(CharSequence name); /** * Returns the all headers that this message contains. @@ -1217,7 +1298,7 @@ public abstract class HttpHeaders implements Iterable> * @param name The name of the header to search for * @return True if at least one header is found */ - public abstract boolean contains(String name); + public abstract boolean contains(CharSequence name); /** * Checks if no header exists. @@ -1244,7 +1325,7 @@ public abstract class HttpHeaders implements Iterable> * * @return {@code this} */ - public abstract HttpHeaders add(String name, Object value); + public abstract HttpHeaders add(CharSequence name, Object value); /** * Adds a new header with the specified name and values. @@ -1263,7 +1344,7 @@ public abstract class HttpHeaders implements Iterable> * @param values The values of the headers being set * @return {@code this} */ - public abstract HttpHeaders add(String name, Iterable values); + public abstract HttpHeaders add(CharSequence name, Iterable values); /** * Adds all header entries of the specified {@code headers}. @@ -1293,7 +1374,7 @@ public abstract class HttpHeaders implements Iterable> * @param value The value of the header being set * @return {@code this} */ - public abstract HttpHeaders set(String name, Object value); + public abstract HttpHeaders set(CharSequence name, Object value); /** * Sets a header with the specified name and values. @@ -1314,7 +1395,7 @@ public abstract class HttpHeaders implements Iterable> * @param values The values of the headers being set * @return {@code this} */ - public abstract HttpHeaders set(String name, Iterable values); + public abstract HttpHeaders set(CharSequence name, Iterable values); /** * Cleans the current header entries and copies all header entries of the specified {@code headers}. @@ -1338,7 +1419,7 @@ public abstract class HttpHeaders implements Iterable> * @param name The name of the header to remove * @return {@code this} */ - public abstract HttpHeaders remove(String name); + public abstract HttpHeaders remove(CharSequence name); /** * Removes all headers from this {@link HttpMessage}. @@ -1355,7 +1436,7 @@ public abstract class HttpHeaders implements Iterable> * @param ignoreCaseValue {@code true} if case should be ignored * @return contains {@code true} if it contains it {@code false} otherwise */ - public boolean contains(String name, String value, boolean ignoreCaseValue) { + public boolean contains(CharSequence name, CharSequence value, boolean ignoreCaseValue) { List values = getAll(name); if (values.isEmpty()) { return false; diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpMethod.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpMethod.java index 908abe11a7..b55bde822f 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpMethod.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpMethod.java @@ -15,6 +15,9 @@ */ package io.netty.handler.codec.http; +import io.netty.buffer.ByteBuf; +import io.netty.util.CharsetUtil; + import java.util.HashMap; import java.util.Map; @@ -31,7 +34,7 @@ public class HttpMethod implements Comparable { * capabilities of a server, without implying a resource action or initiating a resource * retrieval. */ - public static final HttpMethod OPTIONS = new HttpMethod("OPTIONS"); + public static final HttpMethod OPTIONS = new HttpMethod("OPTIONS", true); /** * The GET getMethod means retrieve whatever information (in the form of an entity) is identified @@ -39,49 +42,49 @@ public class HttpMethod implements Comparable { * produced data which shall be returned as the entity in the response and not the source text * of the process, unless that text happens to be the output of the process. */ - public static final HttpMethod GET = new HttpMethod("GET"); + public static final HttpMethod GET = new HttpMethod("GET", true); /** * The HEAD getMethod is identical to GET except that the server MUST NOT return a message-body * in the response. */ - public static final HttpMethod HEAD = new HttpMethod("HEAD"); + public static final HttpMethod HEAD = new HttpMethod("HEAD", true); /** * The POST getMethod is used to request that the origin server accept the entity enclosed in the * request as a new subordinate of the resource identified by the Request-URI in the * Request-Line. */ - public static final HttpMethod POST = new HttpMethod("POST"); + public static final HttpMethod POST = new HttpMethod("POST", true); /** * The PUT getMethod requests that the enclosed entity be stored under the supplied Request-URI. */ - public static final HttpMethod PUT = new HttpMethod("PUT"); + public static final HttpMethod PUT = new HttpMethod("PUT", true); /** * The PATCH getMethod requests that a set of changes described in the * request entity be applied to the resource identified by the Request-URI. */ - public static final HttpMethod PATCH = new HttpMethod("PATCH"); + public static final HttpMethod PATCH = new HttpMethod("PATCH", true); /** * The DELETE getMethod requests that the origin server delete the resource identified by the * Request-URI. */ - public static final HttpMethod DELETE = new HttpMethod("DELETE"); + public static final HttpMethod DELETE = new HttpMethod("DELETE", true); /** * The TRACE getMethod is used to invoke a remote, application-layer loop- back of the request * message. */ - public static final HttpMethod TRACE = new HttpMethod("TRACE"); + public static final HttpMethod TRACE = new HttpMethod("TRACE", true); /** * This specification reserves the getMethod name CONNECT for use with a proxy that can dynamically * switch to being a tunnel */ - public static final HttpMethod CONNECT = new HttpMethod("CONNECT"); + public static final HttpMethod CONNECT = new HttpMethod("CONNECT", true); private static final Map methodMap = new HashMap(); @@ -122,6 +125,7 @@ public class HttpMethod implements Comparable { } private final String name; + private final byte[] bytes; /** * Creates a new HTTP getMethod with the specified name. You will not need to @@ -131,6 +135,10 @@ public class HttpMethod implements Comparable { * ICAP */ public HttpMethod(String name) { + this(name, false); + } + + private HttpMethod(String name, boolean bytes) { if (name == null) { throw new NullPointerException("name"); } @@ -142,12 +150,17 @@ public class HttpMethod implements Comparable { for (int i = 0; i < name.length(); i ++) { if (Character.isISOControl(name.charAt(i)) || - Character.isWhitespace(name.charAt(i))) { + Character.isWhitespace(name.charAt(i))) { throw new IllegalArgumentException("invalid character in name"); } } this.name = name; + if (bytes) { + this.bytes = name.getBytes(CharsetUtil.US_ASCII); + } else { + this.bytes = null; + } } /** @@ -181,4 +194,12 @@ public class HttpMethod implements Comparable { public int compareTo(HttpMethod o) { return name().compareTo(o.name()); } + + void encode(ByteBuf buf) { + if (bytes == null) { + HttpHeaders.encodeAscii0(name, buf); + } else { + buf.writeBytes(bytes); + } + } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectEncoder.java index 35312ab5f4..1d064dcddd 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectEncoder.java @@ -23,7 +23,6 @@ import io.netty.util.CharsetUtil; import io.netty.util.internal.StringUtil; import java.util.List; -import java.util.Map; import static io.netty.buffer.Unpooled.*; import static io.netty.handler.codec.http.HttpConstants.*; @@ -45,7 +44,6 @@ public abstract class HttpObjectEncoder extends MessageTo private static final byte[] CRLF = { CR, LF }; private static final byte[] ZERO_CRLF = { '0', CR, LF }; private static final byte[] ZERO_CRLF_CRLF = { '0', CR, LF, CR, LF }; - private static final byte[] HEADER_SEPARATOR = { COLON, SP }; private static final ByteBuf CRLF_BUF = unreleasableBuffer(directBuffer(CRLF.length).writeBytes(CRLF)); private static final ByteBuf ZERO_CRLF_CRLF_BUF = unreleasableBuffer(directBuffer(ZERO_CRLF_CRLF.length) .writeBytes(ZERO_CRLF_CRLF)); @@ -70,7 +68,7 @@ public abstract class HttpObjectEncoder extends MessageTo ByteBuf buf = ctx.alloc().buffer(); // Encode the message. encodeInitialLine(buf, m); - encodeHeaders(buf, m.headers()); + HttpHeaders.encode(m.headers(), buf); buf.writeBytes(CRLF); out.add(buf); state = HttpHeaders.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK; @@ -119,7 +117,7 @@ public abstract class HttpObjectEncoder extends MessageTo } else { ByteBuf buf = ctx.alloc().buffer(); buf.writeBytes(ZERO_CRLF); - encodeHeaders(buf, headers); + HttpHeaders.encode(headers, buf); buf.writeBytes(CRLF); out.add(buf); } @@ -165,24 +163,5 @@ public abstract class HttpObjectEncoder extends MessageTo throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg)); } - private static void encodeHeaders(ByteBuf buf, HttpHeaders headers) { - for (Map.Entry h: headers) { - encodeHeader(buf, h.getKey(), h.getValue()); - } - } - - private static void encodeHeader(ByteBuf buf, String header, String value) { - encodeAscii(header, buf); - buf.writeBytes(HEADER_SEPARATOR); - encodeAscii(value, buf); - buf.writeBytes(CRLF); - } - - protected static void encodeAscii(String s, ByteBuf buf) { - for (int i = 0; i < s.length(); i++) { - buf.writeByte(s.charAt(i)); - } - } - protected abstract void encodeInitialLine(ByteBuf buf, H message) throws Exception; } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java index 3dc959bd1d..52bb90fa86 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java @@ -35,7 +35,7 @@ public class HttpRequestEncoder extends HttpObjectEncoder { @Override protected void encodeInitialLine(ByteBuf buf, HttpRequest request) throws Exception { - encodeAscii(request.getMethod().toString(), buf); + request.getMethod().encode(buf); buf.writeByte(SP); // Add / as absolute path if no is present. @@ -57,7 +57,7 @@ public class HttpRequestEncoder extends HttpObjectEncoder { buf.writeBytes(uri.getBytes(CharsetUtil.UTF_8)); buf.writeByte(SP); - encodeAscii(request.getProtocolVersion().toString(), buf); + request.getProtocolVersion().encode(buf); buf.writeBytes(CRLF); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseEncoder.java index f4af2f5365..07e2414998 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseEncoder.java @@ -33,11 +33,9 @@ public class HttpResponseEncoder extends HttpObjectEncoder { @Override protected void encodeInitialLine(ByteBuf buf, HttpResponse response) throws Exception { - encodeAscii(response.getProtocolVersion().toString(), buf); + response.getProtocolVersion().encode(buf); buf.writeByte(SP); - encodeAscii(String.valueOf(response.getStatus().code()), buf); - buf.writeByte(SP); - encodeAscii(String.valueOf(response.getStatus().reasonPhrase()), buf); + response.getStatus().encode(buf); buf.writeBytes(CRLF); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseStatus.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseStatus.java index ca6d48c86e..4559e7672a 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseStatus.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseStatus.java @@ -15,6 +15,11 @@ */ package io.netty.handler.codec.http; +import io.netty.buffer.ByteBuf; +import io.netty.util.CharsetUtil; + +import static io.netty.handler.codec.http.HttpConstants.SP; + /** * The response code and its description of HTTP or its derived protocols, such as * RTSP and @@ -25,282 +30,290 @@ public class HttpResponseStatus implements Comparable { /** * 100 Continue */ - public static final HttpResponseStatus CONTINUE = new HttpResponseStatus(100, "Continue"); + public static final HttpResponseStatus CONTINUE = new HttpResponseStatus(100, "Continue", true); /** * 101 Switching Protocols */ - public static final HttpResponseStatus SWITCHING_PROTOCOLS = new HttpResponseStatus(101, "Switching Protocols"); + public static final HttpResponseStatus SWITCHING_PROTOCOLS = + new HttpResponseStatus(101, "Switching Protocols", true); /** * 102 Processing (WebDAV, RFC2518) */ - public static final HttpResponseStatus PROCESSING = new HttpResponseStatus(102, "Processing"); + public static final HttpResponseStatus PROCESSING = new HttpResponseStatus(102, "Processing", true); /** * 200 OK */ - public static final HttpResponseStatus OK = new HttpResponseStatus(200, "OK"); + public static final HttpResponseStatus OK = new HttpResponseStatus(200, "OK", true); /** * 201 Created */ - public static final HttpResponseStatus CREATED = new HttpResponseStatus(201, "Created"); + public static final HttpResponseStatus CREATED = new HttpResponseStatus(201, "Created", true); /** * 202 Accepted */ - public static final HttpResponseStatus ACCEPTED = new HttpResponseStatus(202, "Accepted"); + public static final HttpResponseStatus ACCEPTED = new HttpResponseStatus(202, "Accepted", true); /** * 203 Non-Authoritative Information (since HTTP/1.1) */ public static final HttpResponseStatus NON_AUTHORITATIVE_INFORMATION = - new HttpResponseStatus(203, "Non-Authoritative Information"); + new HttpResponseStatus(203, "Non-Authoritative Information", true); /** * 204 No Content */ - public static final HttpResponseStatus NO_CONTENT = new HttpResponseStatus(204, "No Content"); + public static final HttpResponseStatus NO_CONTENT = new HttpResponseStatus(204, "No Content", true); /** * 205 Reset Content */ - public static final HttpResponseStatus RESET_CONTENT = new HttpResponseStatus(205, "Reset Content"); + public static final HttpResponseStatus RESET_CONTENT = new HttpResponseStatus(205, "Reset Content", true); /** * 206 Partial Content */ - public static final HttpResponseStatus PARTIAL_CONTENT = new HttpResponseStatus(206, "Partial Content"); + public static final HttpResponseStatus PARTIAL_CONTENT = new HttpResponseStatus(206, "Partial Content", true); /** * 207 Multi-Status (WebDAV, RFC2518) */ - public static final HttpResponseStatus MULTI_STATUS = new HttpResponseStatus(207, "Multi-Status"); + public static final HttpResponseStatus MULTI_STATUS = new HttpResponseStatus(207, "Multi-Status", true); /** * 300 Multiple Choices */ - public static final HttpResponseStatus MULTIPLE_CHOICES = new HttpResponseStatus(300, "Multiple Choices"); + public static final HttpResponseStatus MULTIPLE_CHOICES = new HttpResponseStatus(300, "Multiple Choices", true); /** * 301 Moved Permanently */ - public static final HttpResponseStatus MOVED_PERMANENTLY = new HttpResponseStatus(301, "Moved Permanently"); + public static final HttpResponseStatus MOVED_PERMANENTLY = new HttpResponseStatus(301, "Moved Permanently", true); /** * 302 Found */ - public static final HttpResponseStatus FOUND = new HttpResponseStatus(302, "Found"); + public static final HttpResponseStatus FOUND = new HttpResponseStatus(302, "Found", true); /** * 303 See Other (since HTTP/1.1) */ - public static final HttpResponseStatus SEE_OTHER = new HttpResponseStatus(303, "See Other"); + public static final HttpResponseStatus SEE_OTHER = new HttpResponseStatus(303, "See Other", true); /** * 304 Not Modified */ - public static final HttpResponseStatus NOT_MODIFIED = new HttpResponseStatus(304, "Not Modified"); + public static final HttpResponseStatus NOT_MODIFIED = new HttpResponseStatus(304, "Not Modified", true); /** * 305 Use Proxy (since HTTP/1.1) */ - public static final HttpResponseStatus USE_PROXY = new HttpResponseStatus(305, "Use Proxy"); + public static final HttpResponseStatus USE_PROXY = new HttpResponseStatus(305, "Use Proxy", true); /** * 307 Temporary Redirect (since HTTP/1.1) */ - public static final HttpResponseStatus TEMPORARY_REDIRECT = new HttpResponseStatus(307, "Temporary Redirect"); + public static final HttpResponseStatus TEMPORARY_REDIRECT = new HttpResponseStatus(307, "Temporary Redirect", true); /** * 400 Bad Request */ - public static final HttpResponseStatus BAD_REQUEST = new HttpResponseStatus(400, "Bad Request"); + public static final HttpResponseStatus BAD_REQUEST = new HttpResponseStatus(400, "Bad Request", true); /** * 401 Unauthorized */ - public static final HttpResponseStatus UNAUTHORIZED = new HttpResponseStatus(401, "Unauthorized"); + public static final HttpResponseStatus UNAUTHORIZED = new HttpResponseStatus(401, "Unauthorized", true); /** * 402 Payment Required */ - public static final HttpResponseStatus PAYMENT_REQUIRED = new HttpResponseStatus(402, "Payment Required"); + public static final HttpResponseStatus PAYMENT_REQUIRED = new HttpResponseStatus(402, "Payment Required", true); /** * 403 Forbidden */ - public static final HttpResponseStatus FORBIDDEN = new HttpResponseStatus(403, "Forbidden"); + public static final HttpResponseStatus FORBIDDEN = new HttpResponseStatus(403, "Forbidden", true); /** * 404 Not Found */ - public static final HttpResponseStatus NOT_FOUND = new HttpResponseStatus(404, "Not Found"); + public static final HttpResponseStatus NOT_FOUND = new HttpResponseStatus(404, "Not Found", true); /** * 405 Method Not Allowed */ - public static final HttpResponseStatus METHOD_NOT_ALLOWED = new HttpResponseStatus(405, "Method Not Allowed"); + public static final HttpResponseStatus METHOD_NOT_ALLOWED = new HttpResponseStatus(405, "Method Not Allowed", true); /** * 406 Not Acceptable */ - public static final HttpResponseStatus NOT_ACCEPTABLE = new HttpResponseStatus(406, "Not Acceptable"); + public static final HttpResponseStatus NOT_ACCEPTABLE = new HttpResponseStatus(406, "Not Acceptable", true); /** * 407 Proxy Authentication Required */ public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = - new HttpResponseStatus(407, "Proxy Authentication Required"); + new HttpResponseStatus(407, "Proxy Authentication Required", true); /** * 408 Request Timeout */ - public static final HttpResponseStatus REQUEST_TIMEOUT = new HttpResponseStatus(408, "Request Timeout"); + public static final HttpResponseStatus REQUEST_TIMEOUT = new HttpResponseStatus(408, "Request Timeout", true); /** * 409 Conflict */ - public static final HttpResponseStatus CONFLICT = new HttpResponseStatus(409, "Conflict"); + public static final HttpResponseStatus CONFLICT = new HttpResponseStatus(409, "Conflict", true); /** * 410 Gone */ - public static final HttpResponseStatus GONE = new HttpResponseStatus(410, "Gone"); + public static final HttpResponseStatus GONE = new HttpResponseStatus(410, "Gone", true); /** * 411 Length Required */ - public static final HttpResponseStatus LENGTH_REQUIRED = new HttpResponseStatus(411, "Length Required"); + public static final HttpResponseStatus LENGTH_REQUIRED = new HttpResponseStatus(411, "Length Required", true); /** * 412 Precondition Failed */ - public static final HttpResponseStatus PRECONDITION_FAILED = new HttpResponseStatus(412, "Precondition Failed"); + public static final HttpResponseStatus PRECONDITION_FAILED = + new HttpResponseStatus(412, "Precondition Failed", true); /** * 413 Request Entity Too Large */ public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = - new HttpResponseStatus(413, "Request Entity Too Large"); + new HttpResponseStatus(413, "Request Entity Too Large", true); /** * 414 Request-URI Too Long */ - public static final HttpResponseStatus REQUEST_URI_TOO_LONG = new HttpResponseStatus(414, "Request-URI Too Long"); + public static final HttpResponseStatus REQUEST_URI_TOO_LONG = + new HttpResponseStatus(414, "Request-URI Too Long", true); /** * 415 Unsupported Media Type */ public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = - new HttpResponseStatus(415, "Unsupported Media Type"); + new HttpResponseStatus(415, "Unsupported Media Type", true); /** * 416 Requested Range Not Satisfiable */ public static final HttpResponseStatus REQUESTED_RANGE_NOT_SATISFIABLE = - new HttpResponseStatus(416, "Requested Range Not Satisfiable"); + new HttpResponseStatus(416, "Requested Range Not Satisfiable", true); /** * 417 Expectation Failed */ - public static final HttpResponseStatus EXPECTATION_FAILED = new HttpResponseStatus(417, "Expectation Failed"); + public static final HttpResponseStatus EXPECTATION_FAILED = new HttpResponseStatus(417, "Expectation Failed", true); /** * 422 Unprocessable Entity (WebDAV, RFC4918) */ - public static final HttpResponseStatus UNPROCESSABLE_ENTITY = new HttpResponseStatus(422, "Unprocessable Entity"); + public static final HttpResponseStatus UNPROCESSABLE_ENTITY = + new HttpResponseStatus(422, "Unprocessable Entity", true); /** * 423 Locked (WebDAV, RFC4918) */ - public static final HttpResponseStatus LOCKED = new HttpResponseStatus(423, "Locked"); + public static final HttpResponseStatus LOCKED = new HttpResponseStatus(423, "Locked", true); /** * 424 Failed Dependency (WebDAV, RFC4918) */ - public static final HttpResponseStatus FAILED_DEPENDENCY = new HttpResponseStatus(424, "Failed Dependency"); + public static final HttpResponseStatus FAILED_DEPENDENCY = new HttpResponseStatus(424, "Failed Dependency", true); /** * 425 Unordered Collection (WebDAV, RFC3648) */ - public static final HttpResponseStatus UNORDERED_COLLECTION = new HttpResponseStatus(425, "Unordered Collection"); + public static final HttpResponseStatus UNORDERED_COLLECTION = + new HttpResponseStatus(425, "Unordered Collection", true); /** * 426 Upgrade Required (RFC2817) */ - public static final HttpResponseStatus UPGRADE_REQUIRED = new HttpResponseStatus(426, "Upgrade Required"); + public static final HttpResponseStatus UPGRADE_REQUIRED = new HttpResponseStatus(426, "Upgrade Required", true); /** * 428 Precondition Required (RFC6585) */ - public static final HttpResponseStatus PRECONDITION_REQUIRED = new HttpResponseStatus(428, "Precondition Required"); + public static final HttpResponseStatus PRECONDITION_REQUIRED = + new HttpResponseStatus(428, "Precondition Required", true); /** * 429 Too Many Requests (RFC6585) */ - public static final HttpResponseStatus TOO_MANY_REQUESTS = new HttpResponseStatus(429, "Too Many Requests"); + public static final HttpResponseStatus TOO_MANY_REQUESTS = new HttpResponseStatus(429, "Too Many Requests", true); /** * 431 Request Header Fields Too Large (RFC6585) */ public static final HttpResponseStatus REQUEST_HEADER_FIELDS_TOO_LARGE = - new HttpResponseStatus(431, "Request Header Fields Too Large"); + new HttpResponseStatus(431, "Request Header Fields Too Large", true); /** * 500 Internal Server Error */ public static final HttpResponseStatus INTERNAL_SERVER_ERROR = - new HttpResponseStatus(500, "Internal Server Error"); + new HttpResponseStatus(500, "Internal Server Error", true); /** * 501 Not Implemented */ - public static final HttpResponseStatus NOT_IMPLEMENTED = new HttpResponseStatus(501, "Not Implemented"); + public static final HttpResponseStatus NOT_IMPLEMENTED = new HttpResponseStatus(501, "Not Implemented", true); /** * 502 Bad Gateway */ - public static final HttpResponseStatus BAD_GATEWAY = new HttpResponseStatus(502, "Bad Gateway"); + public static final HttpResponseStatus BAD_GATEWAY = new HttpResponseStatus(502, "Bad Gateway", true); /** * 503 Service Unavailable */ - public static final HttpResponseStatus SERVICE_UNAVAILABLE = new HttpResponseStatus(503, "Service Unavailable"); + public static final HttpResponseStatus SERVICE_UNAVAILABLE = + new HttpResponseStatus(503, "Service Unavailable", true); /** * 504 Gateway Timeout */ - public static final HttpResponseStatus GATEWAY_TIMEOUT = new HttpResponseStatus(504, "Gateway Timeout"); + public static final HttpResponseStatus GATEWAY_TIMEOUT = new HttpResponseStatus(504, "Gateway Timeout", true); /** * 505 HTTP Version Not Supported */ public static final HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED = - new HttpResponseStatus(505, "HTTP Version Not Supported"); + new HttpResponseStatus(505, "HTTP Version Not Supported", true); /** * 506 Variant Also Negotiates (RFC2295) */ public static final HttpResponseStatus VARIANT_ALSO_NEGOTIATES = - new HttpResponseStatus(506, "Variant Also Negotiates"); + new HttpResponseStatus(506, "Variant Also Negotiates", true); /** * 507 Insufficient Storage (WebDAV, RFC4918) */ - public static final HttpResponseStatus INSUFFICIENT_STORAGE = new HttpResponseStatus(507, "Insufficient Storage"); + public static final HttpResponseStatus INSUFFICIENT_STORAGE = + new HttpResponseStatus(507, "Insufficient Storage", true); /** * 510 Not Extended (RFC2774) */ - public static final HttpResponseStatus NOT_EXTENDED = new HttpResponseStatus(510, "Not Extended"); + public static final HttpResponseStatus NOT_EXTENDED = new HttpResponseStatus(510, "Not Extended", true); /** * 511 Network Authentication Required (RFC6585) */ public static final HttpResponseStatus NETWORK_AUTHENTICATION_REQUIRED = - new HttpResponseStatus(511, "Network Authentication Required"); + new HttpResponseStatus(511, "Network Authentication Required", true); /** * Returns the {@link HttpResponseStatus} represented by the specified code. @@ -443,12 +456,17 @@ public class HttpResponseStatus implements Comparable { private final int code; private final String reasonPhrase; + private final byte[] bytes; /** * Creates a new instance with the specified {@code code} and its * {@code reasonPhrase}. */ public HttpResponseStatus(int code, String reasonPhrase) { + this(code, reasonPhrase, false); + } + + private HttpResponseStatus(int code, String reasonPhrase, boolean bytes) { if (code < 0) { throw new IllegalArgumentException( "code: " + code + " (expected: 0+)"); @@ -462,15 +480,20 @@ public class HttpResponseStatus implements Comparable { char c = reasonPhrase.charAt(i); // Check prohibited characters. switch (c) { - case '\n': case '\r': - throw new IllegalArgumentException( - "reasonPhrase contains one of the following prohibited characters: " + - "\\r\\n: " + reasonPhrase); + case '\n': case '\r': + throw new IllegalArgumentException( + "reasonPhrase contains one of the following prohibited characters: " + + "\\r\\n: " + reasonPhrase); } } this.code = code; this.reasonPhrase = reasonPhrase; + if (bytes) { + this.bytes = (code + " " + reasonPhrase).getBytes(CharsetUtil.US_ASCII); + } else { + this.bytes = null; + } } /** @@ -514,4 +537,14 @@ public class HttpResponseStatus implements Comparable { buf.append(reasonPhrase); return buf.toString(); } + + void encode(ByteBuf buf) { + if (bytes == null) { + HttpHeaders.encodeAscii0(String.valueOf(code()), buf); + buf.writeByte(SP); + HttpHeaders.encodeAscii0(String.valueOf(reasonPhrase()), buf); + } else { + buf.writeBytes(bytes); + } + } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpVersion.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpVersion.java index 934f5022c8..4fd66d42de 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpVersion.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpVersion.java @@ -15,6 +15,9 @@ */ package io.netty.handler.codec.http; +import io.netty.buffer.ByteBuf; +import io.netty.util.CharsetUtil; + import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -34,12 +37,12 @@ public class HttpVersion implements Comparable { /** * HTTP/1.0 */ - public static final HttpVersion HTTP_1_0 = new HttpVersion("HTTP", 1, 0, false); + public static final HttpVersion HTTP_1_0 = new HttpVersion("HTTP", 1, 0, false, true); /** * HTTP/1.1 */ - public static final HttpVersion HTTP_1_1 = new HttpVersion("HTTP", 1, 1, true); + public static final HttpVersion HTTP_1_1 = new HttpVersion("HTTP", 1, 1, true, true); /** * Returns an existing or new {@link HttpVersion} instance which matches to @@ -90,6 +93,7 @@ public class HttpVersion implements Comparable { private final int minorVersion; private final String text; private final boolean keepAliveDefault; + private final byte[] bytes; /** * Creates a new HTTP version with the specified version string. You will @@ -122,6 +126,7 @@ public class HttpVersion implements Comparable { minorVersion = Integer.parseInt(m.group(3)); this.text = protocolName + '/' + majorVersion + '.' + minorVersion; this.keepAliveDefault = keepAliveDefault; + bytes = null; } /** @@ -138,6 +143,12 @@ public class HttpVersion implements Comparable { public HttpVersion( String protocolName, int majorVersion, int minorVersion, boolean keepAliveDefault) { + this(protocolName, majorVersion, minorVersion, keepAliveDefault, false); + } + + private HttpVersion( + String protocolName, int majorVersion, int minorVersion, + boolean keepAliveDefault, boolean bytes) { if (protocolName == null) { throw new NullPointerException("protocolName"); } @@ -149,7 +160,7 @@ public class HttpVersion implements Comparable { for (int i = 0; i < protocolName.length(); i ++) { if (Character.isISOControl(protocolName.charAt(i)) || - Character.isWhitespace(protocolName.charAt(i))) { + Character.isWhitespace(protocolName.charAt(i))) { throw new IllegalArgumentException("invalid character in protocolName"); } } @@ -166,6 +177,11 @@ public class HttpVersion implements Comparable { this.minorVersion = minorVersion; text = protocolName + '/' + majorVersion + '.' + minorVersion; this.keepAliveDefault = keepAliveDefault; + if (bytes) { + this.bytes = text.getBytes(CharsetUtil.US_ASCII); + } else { + this.bytes = null; + } } /** @@ -244,4 +260,12 @@ public class HttpVersion implements Comparable { return minorVersion() - o.minorVersion(); } + + void encode(ByteBuf buf) { + if (bytes == null) { + HttpHeaders.encodeAscii0(text, buf); + } else { + buf.writeBytes(bytes); + } + } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/CaseIgnoringComparator.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/CaseIgnoringComparator.java index afccf26079..3c24234ac7 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/CaseIgnoringComparator.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/CaseIgnoringComparator.java @@ -18,7 +18,7 @@ package io.netty.handler.codec.http.multipart; import java.io.Serializable; import java.util.Comparator; -final class CaseIgnoringComparator implements Comparator, Serializable { +final class CaseIgnoringComparator implements Comparator, Serializable { private static final long serialVersionUID = 4582133183775373862L; @@ -28,8 +28,26 @@ final class CaseIgnoringComparator implements Comparator, Serializable { } @Override - public int compare(String o1, String o2) { - return o1.compareToIgnoreCase(o2); + public int compare(CharSequence o1, CharSequence o2) { + int o1Length = o1.length(); + int o2Length = o2.length(); + int min = Math.min(o1Length, o2Length); + for (int i = 0; i < min; i++) { + char c1 = o1.charAt(i); + char c2 = o2.charAt(i); + if (c1 != c2) { + c1 = Character.toUpperCase(c1); + c2 = Character.toUpperCase(c2); + if (c1 != c2) { + c1 = Character.toLowerCase(c1); + c2 = Character.toLowerCase(c2); + if (c1 != c2) { + return c1 - c2; + } + } + } + } + return o1Length - o2Length; } @SuppressWarnings("MethodMayBeStatic") diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java index 564dcb1e5e..20f0653bd1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java @@ -152,9 +152,9 @@ public class HttpPostRequestDecoder implements InterfaceHttpPostRequestDecoder { // Check if Post using "multipart/form-data; boundary=--89421926422648" String[] headerContentType = splitHeaderContentType(contentType); if (headerContentType[0].toLowerCase().startsWith( - HttpHeaders.Values.MULTIPART_FORM_DATA) && + HttpHeaders.Values.MULTIPART_FORM_DATA.toString()) && headerContentType[1].toLowerCase().startsWith( - HttpHeaders.Values.BOUNDARY)) { + HttpHeaders.Values.BOUNDARY.toString())) { String[] boundary = StringUtil.split(headerContentType[1], '='); if (boundary.length != 2) { throw new ErrorDataDecoderException("Needs a boundary value"); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java index 58b53a6cc6..bbc87ae57b 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostRequestEncoder.java @@ -663,9 +663,10 @@ public class HttpPostRequestEncoder implements ChunkedInput { headers.remove(HttpHeaders.Names.CONTENT_TYPE); for (String contentType : contentTypes) { // "multipart/form-data; boundary=--89421926422648" - if (contentType.toLowerCase().startsWith(HttpHeaders.Values.MULTIPART_FORM_DATA)) { + if (contentType.toLowerCase().startsWith(HttpHeaders.Values.MULTIPART_FORM_DATA.toString())) { // ignore - } else if (contentType.toLowerCase().startsWith(HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED)) { + } else if (contentType.toLowerCase().startsWith( + HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED.toString())) { // ignore } else { headers.add(HttpHeaders.Names.CONTENT_TYPE, contentType); @@ -694,7 +695,7 @@ public class HttpPostRequestEncoder implements ChunkedInput { if (transferEncoding != null) { headers.remove(HttpHeaders.Names.TRANSFER_ENCODING); for (String v : transferEncoding) { - if (v.equalsIgnoreCase(HttpHeaders.Values.CHUNKED)) { + if (HttpHeaders.equalsIgnoreCase(v, HttpHeaders.Values.CHUNKED)) { // ignore } else { headers.add(HttpHeaders.Names.TRANSFER_ENCODING, v); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java index 4ec7833e66..c472d528c1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker00.java @@ -198,13 +198,13 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker { HttpHeaders headers = response.headers(); String upgrade = headers.get(Names.UPGRADE); - if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { + if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); - if (!Values.UPGRADE.equalsIgnoreCase(connection)) { + if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java index a012055469..ffc11f7b04 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java @@ -40,7 +40,7 @@ import java.net.URI; public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker { private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker07.class); - + private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toString().toLowerCase()); public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; private String expectedChallengeResponseString; @@ -118,7 +118,7 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker { FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); HttpHeaders headers = request.headers(); - headers.add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()) + headers.add(Names.UPGRADE, WEBSOCKET) .add(Names.CONNECTION, Values.UPGRADE) .add(Names.SEC_WEBSOCKET_KEY, key) .add(Names.HOST, wsURL.getHost()); @@ -172,12 +172,12 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker { } String upgrade = headers.get(Names.UPGRADE); - if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { + if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); - if (!Values.UPGRADE.equalsIgnoreCase(connection)) { + if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java index d376721ac5..3045201106 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java @@ -40,6 +40,8 @@ import java.net.URI; public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker08.class); + private static final CharSequence WEBSOCKET = HttpHeaders.newEntity( + HttpHeaders.Values.WEBSOCKET.toString().toLowerCase()); public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -118,7 +120,7 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); HttpHeaders headers = request.headers(); - headers.add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()) + headers.add(Names.UPGRADE, WEBSOCKET) .add(Names.CONNECTION, Values.UPGRADE) .add(Names.SEC_WEBSOCKET_KEY, key) .add(Names.HOST, wsURL.getHost()); @@ -172,12 +174,12 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { } String upgrade = headers.get(Names.UPGRADE); - if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { + if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); - if (!Values.UPGRADE.equalsIgnoreCase(connection)) { + if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java index ef18fca213..a6f5e87682 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java @@ -40,6 +40,7 @@ import java.net.URI; public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketClientHandshaker13.class); + private static final CharSequence WEBSOCKET = HttpHeaders.newEntity(Values.WEBSOCKET.toString().toLowerCase()); public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -129,7 +130,7 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); HttpHeaders headers = request.headers(); - headers.add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()) + headers.add(Names.UPGRADE, WEBSOCKET) .add(Names.CONNECTION, Values.UPGRADE) .add(Names.SEC_WEBSOCKET_KEY, key) .add(Names.HOST, wsURL.getHost() + ':' + wsPort); @@ -182,12 +183,12 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { } String upgrade = headers.get(Names.UPGRADE); - if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { + if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); - if (!Values.UPGRADE.equalsIgnoreCase(connection)) { + if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java index 0200b30b4e..76825a573f 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java @@ -109,8 +109,8 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker { protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) { // Serve the WebSocket handshake request. - if (!Values.UPGRADE.equalsIgnoreCase(req.headers().get(CONNECTION)) - || !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) { + if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, req.headers().get(CONNECTION)) + || !HttpHeaders.equalsIgnoreCase(WEBSOCKET, req.headers().get(Names.UPGRADE))) { throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade"); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker07.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker07.java index 4dd231845b..45c8f2e4a0 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker07.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker07.java @@ -23,7 +23,6 @@ import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.util.CharsetUtil; -import static io.netty.handler.codec.http.HttpHeaders.Values.*; import static io.netty.handler.codec.http.HttpVersion.*; /** @@ -35,6 +34,9 @@ import static io.netty.handler.codec.http.HttpVersion.*; */ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker { + private static final CharSequence WEBSOCKET = HttpHeaders.newEntity( + HttpHeaders.Values.WEBSOCKET.toString().toLowerCase()); + public static final String WEBSOCKET_07_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; private final boolean allowExtensions; @@ -114,7 +116,7 @@ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker { logger.debug(String.format("WS Version 7 Server Handshake key: %s. Response: %s.", key, accept)); } - res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase()); + res.headers().add(Names.UPGRADE, WEBSOCKET); res.headers().add(Names.CONNECTION, Names.UPGRADE); res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept); String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java index ec7848ef40..30ca2bc18b 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08.java @@ -23,7 +23,6 @@ import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.util.CharsetUtil; -import static io.netty.handler.codec.http.HttpHeaders.Values.*; import static io.netty.handler.codec.http.HttpVersion.*; /** @@ -35,6 +34,9 @@ import static io.netty.handler.codec.http.HttpVersion.*; */ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker { + private static final CharSequence WEBSOCKET = HttpHeaders.newEntity( + HttpHeaders.Values.WEBSOCKET.toString().toLowerCase()); + public static final String WEBSOCKET_08_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; private final boolean allowExtensions; @@ -113,7 +115,7 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker { logger.debug(String.format("WS Version 8 Server Handshake key: %s. Response: %s.", key, accept)); } - res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase()); + res.headers().add(Names.UPGRADE, WEBSOCKET); res.headers().add(Names.CONNECTION, Names.UPGRADE); res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept); String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java index afd3a7d7b1..27192b964c 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java @@ -23,7 +23,6 @@ import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.util.CharsetUtil; -import static io.netty.handler.codec.http.HttpHeaders.Values.*; import static io.netty.handler.codec.http.HttpVersion.*; /** @@ -33,6 +32,8 @@ import static io.netty.handler.codec.http.HttpVersion.*; *

*/ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker { + private static final CharSequence WEBSOCKET = HttpHeaders.newEntity( + HttpHeaders.Values.WEBSOCKET.toString().toLowerCase()); public static final String WEBSOCKET_13_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -111,7 +112,7 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker { logger.debug(String.format("WS Version 13 Server Handshake key: %s. Response: %s.", key, accept)); } - res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase()); + res.headers().add(Names.UPGRADE, WEBSOCKET); res.headers().add(Names.CONNECTION, Names.UPGRADE); res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept); String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); diff --git a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspHeaders.java b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspHeaders.java index 82b5682146..989779d105 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspHeaders.java +++ b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspHeaders.java @@ -30,179 +30,179 @@ public final class RtspHeaders { /** * {@code "Accept"} */ - public static final String ACCEPT = HttpHeaders.Names.ACCEPT; + public static final CharSequence ACCEPT = HttpHeaders.Names.ACCEPT; /** * {@code "Accept-Encoding"} */ - public static final String ACCEPT_ENCODING = HttpHeaders.Names.ACCEPT_ENCODING; + public static final CharSequence ACCEPT_ENCODING = HttpHeaders.Names.ACCEPT_ENCODING; /** * {@code "Accept-Lanugage"} */ - public static final String ACCEPT_LANGUAGE = HttpHeaders.Names.ACCEPT_LANGUAGE; + public static final CharSequence ACCEPT_LANGUAGE = HttpHeaders.Names.ACCEPT_LANGUAGE; /** * {@code "Allow"} */ - public static final String ALLOW = "Allow"; + public static final CharSequence ALLOW = HttpHeaders.newEntity("Allow"); /** * {@code "Authorization"} */ - public static final String AUTHORIZATION = HttpHeaders.Names.AUTHORIZATION; + public static final CharSequence AUTHORIZATION = HttpHeaders.Names.AUTHORIZATION; /** * {@code "Bandwidth"} */ - public static final String BANDWIDTH = "Bandwidth"; + public static final CharSequence BANDWIDTH = HttpHeaders.newEntity("Bandwidth"); /** * {@code "Blocksize"} */ - public static final String BLOCKSIZE = "Blocksize"; + public static final CharSequence BLOCKSIZE = HttpHeaders.newEntity("Blocksize"); /** * {@code "Cache-Control"} */ - public static final String CACHE_CONTROL = HttpHeaders.Names.CACHE_CONTROL; + public static final CharSequence CACHE_CONTROL = HttpHeaders.Names.CACHE_CONTROL; /** * {@code "Conference"} */ - public static final String CONFERENCE = "Conference"; + public static final CharSequence CONFERENCE = HttpHeaders.newEntity("Conference"); /** * {@code "Connection"} */ - public static final String CONNECTION = HttpHeaders.Names.CONNECTION; + public static final CharSequence CONNECTION = HttpHeaders.Names.CONNECTION; /** * {@code "Content-Base"} */ - public static final String CONTENT_BASE = HttpHeaders.Names.CONTENT_BASE; + public static final CharSequence CONTENT_BASE = HttpHeaders.Names.CONTENT_BASE; /** * {@code "Content-Encoding"} */ - public static final String CONTENT_ENCODING = HttpHeaders.Names.CONTENT_ENCODING; + public static final CharSequence CONTENT_ENCODING = HttpHeaders.Names.CONTENT_ENCODING; /** * {@code "Content-Language"} */ - public static final String CONTENT_LANGUAGE = HttpHeaders.Names.CONTENT_LANGUAGE; + public static final CharSequence CONTENT_LANGUAGE = HttpHeaders.Names.CONTENT_LANGUAGE; /** * {@code "Content-Length"} */ - public static final String CONTENT_LENGTH = HttpHeaders.Names.CONTENT_LENGTH; + public static final CharSequence CONTENT_LENGTH = HttpHeaders.Names.CONTENT_LENGTH; /** * {@code "Content-Location"} */ - public static final String CONTENT_LOCATION = HttpHeaders.Names.CONTENT_LOCATION; + public static final CharSequence CONTENT_LOCATION = HttpHeaders.Names.CONTENT_LOCATION; /** * {@code "Content-Type"} */ - public static final String CONTENT_TYPE = HttpHeaders.Names.CONTENT_TYPE; + public static final CharSequence CONTENT_TYPE = HttpHeaders.Names.CONTENT_TYPE; /** * {@code "CSeq"} */ - public static final String CSEQ = "CSeq"; + public static final CharSequence CSEQ = HttpHeaders.newEntity("CSeq"); /** * {@code "Date"} */ - public static final String DATE = HttpHeaders.Names.DATE; + public static final CharSequence DATE = HttpHeaders.Names.DATE; /** * {@code "Expires"} */ - public static final String EXPIRES = HttpHeaders.Names.EXPIRES; + public static final CharSequence EXPIRES = HttpHeaders.Names.EXPIRES; /** * {@code "From"} */ - public static final String FROM = HttpHeaders.Names.FROM; + public static final CharSequence FROM = HttpHeaders.Names.FROM; /** * {@code "Host"} */ - public static final String HOST = HttpHeaders.Names.HOST; + public static final CharSequence HOST = HttpHeaders.Names.HOST; /** * {@code "If-Match"} */ - public static final String IF_MATCH = HttpHeaders.Names.IF_MATCH; + public static final CharSequence IF_MATCH = HttpHeaders.Names.IF_MATCH; /** * {@code "If-Modified-Since"} */ - public static final String IF_MODIFIED_SINCE = HttpHeaders.Names.IF_MODIFIED_SINCE; + public static final CharSequence IF_MODIFIED_SINCE = HttpHeaders.Names.IF_MODIFIED_SINCE; /** * {@code "KeyMgmt"} */ - public static final String KEYMGMT = "KeyMgmt"; + public static final CharSequence KEYMGMT = HttpHeaders.newEntity("KeyMgmt"); /** * {@code "Last-Modified"} */ - public static final String LAST_MODIFIED = HttpHeaders.Names.LAST_MODIFIED; + public static final CharSequence LAST_MODIFIED = HttpHeaders.Names.LAST_MODIFIED; /** * {@code "Proxy-Authenticate"} */ - public static final String PROXY_AUTHENTICATE = HttpHeaders.Names.PROXY_AUTHENTICATE; + public static final CharSequence PROXY_AUTHENTICATE = HttpHeaders.Names.PROXY_AUTHENTICATE; /** * {@code "Proxy-Require"} */ - public static final String PROXY_REQUIRE = "Proxy-Require"; + public static final CharSequence PROXY_REQUIRE = HttpHeaders.newEntity("Proxy-Require"); /** * {@code "Public"} */ - public static final String PUBLIC = "Public"; + public static final CharSequence PUBLIC = HttpHeaders.newEntity("Public"); /** * {@code "Range"} */ - public static final String RANGE = HttpHeaders.Names.RANGE; + public static final CharSequence RANGE = HttpHeaders.Names.RANGE; /** * {@code "Referer"} */ - public static final String REFERER = HttpHeaders.Names.REFERER; + public static final CharSequence REFERER = HttpHeaders.Names.REFERER; /** * {@code "Require"} */ - public static final String REQUIRE = "Require"; + public static final CharSequence REQUIRE = HttpHeaders.newEntity("Require"); /** * {@code "Retry-After"} */ - public static final String RETRT_AFTER = HttpHeaders.Names.RETRY_AFTER; + public static final CharSequence RETRT_AFTER = HttpHeaders.Names.RETRY_AFTER; /** * {@code "RTP-Info"} */ - public static final String RTP_INFO = "RTP-Info"; + public static final CharSequence RTP_INFO = HttpHeaders.newEntity("RTP-Info"); /** * {@code "Scale"} */ - public static final String SCALE = "Scale"; + public static final CharSequence SCALE = HttpHeaders.newEntity("Scale"); /** * {@code "Session"} */ - public static final String SESSION = "Session"; + public static final CharSequence SESSION = HttpHeaders.newEntity("Session"); /** * {@code "Server"} */ - public static final String SERVER = HttpHeaders.Names.SERVER; + public static final CharSequence SERVER = HttpHeaders.Names.SERVER; /** * {@code "Speed"} */ - public static final String SPEED = "Speed"; + public static final CharSequence SPEED = HttpHeaders.newEntity("Speed"); /** * {@code "Timestamp"} */ - public static final String TIMESTAMP = "Timestamp"; + public static final CharSequence TIMESTAMP = HttpHeaders.newEntity("Timestamp"); /** * {@code "Transport"} */ - public static final String TRANSPORT = "Transport"; + public static final CharSequence TRANSPORT = HttpHeaders.newEntity("Transport"); /** * {@code "Unsupported"} */ - public static final String UNSUPPORTED = "Unsupported"; + public static final CharSequence UNSUPPORTED = HttpHeaders.newEntity("Unsupported"); /** * {@code "User-Agent"} */ - public static final String USER_AGENT = HttpHeaders.Names.USER_AGENT; + public static final CharSequence USER_AGENT = HttpHeaders.Names.USER_AGENT; /** * {@code "Vary"} */ - public static final String VARY = HttpHeaders.Names.VARY; + public static final CharSequence VARY = HttpHeaders.Names.VARY; /** * {@code "Via"} */ - public static final String VIA = HttpHeaders.Names.VIA; + public static final CharSequence VIA = HttpHeaders.Names.VIA; /** * {@code "WWW-Authenticate"} */ - public static final String WWW_AUTHENTICATE = HttpHeaders.Names.WWW_AUTHENTICATE; + public static final CharSequence WWW_AUTHENTICATE = HttpHeaders.Names.WWW_AUTHENTICATE; private Names() { } @@ -215,171 +215,171 @@ public final class RtspHeaders { /** * {@code "append"} */ - public static final String APPEND = "append"; + public static final CharSequence APPEND = HttpHeaders.newEntity("append"); /** * {@code "AVP"} */ - public static final String AVP = "AVP"; + public static final CharSequence AVP = HttpHeaders.newEntity("AVP"); /** * {@code "bytes"} */ - public static final String BYTES = HttpHeaders.Values.BYTES; + public static final CharSequence BYTES = HttpHeaders.Values.BYTES; /** * {@code "charset"} */ - public static final String CHARSET = HttpHeaders.Values.CHARSET; + public static final CharSequence CHARSET = HttpHeaders.Values.CHARSET; /** * {@code "client_port"} */ - public static final String CLIENT_PORT = "client_port"; + public static final CharSequence CLIENT_PORT = HttpHeaders.newEntity("client_port"); /** * {@code "clock"} */ - public static final String CLOCK = "clock"; + public static final CharSequence CLOCK = HttpHeaders.newEntity("clock"); /** * {@code "close"} */ - public static final String CLOSE = HttpHeaders.Values.CLOSE; + public static final CharSequence CLOSE = HttpHeaders.Values.CLOSE; /** * {@code "compress"} */ - public static final String COMPRESS = HttpHeaders.Values.COMPRESS; + public static final CharSequence COMPRESS = HttpHeaders.Values.COMPRESS; /** * {@code "100-continue"} */ - public static final String CONTINUE = HttpHeaders.Values.CONTINUE; + public static final CharSequence CONTINUE = HttpHeaders.Values.CONTINUE; /** * {@code "deflate"} */ - public static final String DEFLATE = HttpHeaders.Values.DEFLATE; + public static final CharSequence DEFLATE = HttpHeaders.Values.DEFLATE; /** * {@code "destination"} */ - public static final String DESTINATION = "destination"; + public static final CharSequence DESTINATION = HttpHeaders.newEntity("destination"); /** * {@code "gzip"} */ - public static final String GZIP = HttpHeaders.Values.GZIP; + public static final CharSequence GZIP = HttpHeaders.Values.GZIP; /** * {@code "identity"} */ - public static final String IDENTITY = HttpHeaders.Values.IDENTITY; + public static final CharSequence IDENTITY = HttpHeaders.Values.IDENTITY; /** * {@code "interleaved"} */ - public static final String INTERLEAVED = "interleaved"; + public static final CharSequence INTERLEAVED = HttpHeaders.newEntity("interleaved"); /** * {@code "keep-alive"} */ - public static final String KEEP_ALIVE = HttpHeaders.Values.KEEP_ALIVE; + public static final CharSequence KEEP_ALIVE = HttpHeaders.Values.KEEP_ALIVE; /** * {@code "layers"} */ - public static final String LAYERS = "layers"; + public static final CharSequence LAYERS = HttpHeaders.newEntity("layers"); /** * {@code "max-age"} */ - public static final String MAX_AGE = HttpHeaders.Values.MAX_AGE; + public static final CharSequence MAX_AGE = HttpHeaders.Values.MAX_AGE; /** * {@code "max-stale"} */ - public static final String MAX_STALE = HttpHeaders.Values.MAX_STALE; + public static final CharSequence MAX_STALE = HttpHeaders.Values.MAX_STALE; /** * {@code "min-fresh"} */ - public static final String MIN_FRESH = HttpHeaders.Values.MIN_FRESH; + public static final CharSequence MIN_FRESH = HttpHeaders.Values.MIN_FRESH; /** * {@code "mode"} */ - public static final String MODE = "mode"; + public static final CharSequence MODE = HttpHeaders.newEntity("mode"); /** * {@code "multicast"} */ - public static final String MULTICAST = "multicast"; + public static final CharSequence MULTICAST = HttpHeaders.newEntity("multicast"); /** * {@code "must-revalidate"} */ - public static final String MUST_REVALIDATE = HttpHeaders.Values.MUST_REVALIDATE; + public static final CharSequence MUST_REVALIDATE = HttpHeaders.Values.MUST_REVALIDATE; /** * {@code "none"} */ - public static final String NONE = HttpHeaders.Values.NONE; + public static final CharSequence NONE = HttpHeaders.Values.NONE; /** * {@code "no-cache"} */ - public static final String NO_CACHE = HttpHeaders.Values.NO_CACHE; + public static final CharSequence NO_CACHE = HttpHeaders.Values.NO_CACHE; /** * {@code "no-transform"} */ - public static final String NO_TRANSFORM = HttpHeaders.Values.NO_TRANSFORM; + public static final CharSequence NO_TRANSFORM = HttpHeaders.Values.NO_TRANSFORM; /** * {@code "only-if-cached"} */ - public static final String ONLY_IF_CACHED = HttpHeaders.Values.ONLY_IF_CACHED; + public static final CharSequence ONLY_IF_CACHED = HttpHeaders.Values.ONLY_IF_CACHED; /** * {@code "port"} */ - public static final String PORT = "port"; + public static final CharSequence PORT = HttpHeaders.newEntity("port"); /** * {@code "private"} */ - public static final String PRIVATE = HttpHeaders.Values.PRIVATE; + public static final CharSequence PRIVATE = HttpHeaders.Values.PRIVATE; /** * {@code "proxy-revalidate"} */ - public static final String PROXY_REVALIDATE = HttpHeaders.Values.PROXY_REVALIDATE; + public static final CharSequence PROXY_REVALIDATE = HttpHeaders.Values.PROXY_REVALIDATE; /** * {@code "public"} */ - public static final String PUBLIC = HttpHeaders.Values.PUBLIC; + public static final CharSequence PUBLIC = HttpHeaders.Values.PUBLIC; /** * {@code "RTP"} */ - public static final String RTP = "RTP"; + public static final CharSequence RTP = HttpHeaders.newEntity("RTP"); /** * {@code "rtptime"} */ - public static final String RTPTIME = "rtptime"; + public static final CharSequence RTPTIME = HttpHeaders.newEntity("rtptime"); /** * {@code "seq"} */ - public static final String SEQ = "seq"; + public static final CharSequence SEQ = HttpHeaders.newEntity("seq"); /** * {@code "server_port"} */ - public static final String SERVER_PORT = "server_port"; + public static final CharSequence SERVER_PORT = HttpHeaders.newEntity("server_port"); /** * {@code "ssrc"} */ - public static final String SSRC = "ssrc"; + public static final CharSequence SSRC = HttpHeaders.newEntity("ssrc"); /** * {@code "TCP"} */ - public static final String TCP = "TCP"; + public static final CharSequence TCP = HttpHeaders.newEntity("TCP"); /** * {@code "time"} */ - public static final String TIME = "time"; + public static final CharSequence TIME = HttpHeaders.newEntity("time"); /** * {@code "timeout"} */ - public static final String TIMEOUT = "timeout"; + public static final CharSequence TIMEOUT = HttpHeaders.newEntity("timeout"); /** * {@code "ttl"} */ - public static final String TTL = "ttl"; + public static final CharSequence TTL = HttpHeaders.newEntity("ttl"); /** * {@code "UDP"} */ - public static final String UDP = "UDP"; + public static final CharSequence UDP = HttpHeaders.newEntity("UDP"); /** * {@code "unicast"} */ - public static final String UNICAST = "unicast"; + public static final CharSequence UNICAST = HttpHeaders.newEntity("unicast"); /** * {@code "url"} */ - public static final String URL = "url"; + public static final CharSequence URL = HttpHeaders.newEntity("url"); private Values() { } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestEncoder.java index c1ae1c206d..1daf0fb7a4 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestEncoder.java @@ -17,6 +17,7 @@ package io.netty.handler.codec.rtsp; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpRequest; import io.netty.util.CharsetUtil; @@ -38,11 +39,11 @@ public class RtspRequestEncoder extends RtspObjectEncoder { @Override protected void encodeInitialLine(ByteBuf buf, HttpRequest request) throws Exception { - encodeAscii(request.getMethod().toString(), buf); + HttpHeaders.encodeAscii(request.getMethod().toString(), buf); buf.writeByte(SP); buf.writeBytes(request.getUri().getBytes(CharsetUtil.UTF_8)); buf.writeByte(SP); - encodeAscii(request.getProtocolVersion().toString(), buf); + HttpHeaders.encodeAscii(request.getProtocolVersion().toString(), buf); buf.writeBytes(CRLF); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseEncoder.java index 3474901267..a18db8127f 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseEncoder.java @@ -17,6 +17,7 @@ package io.netty.handler.codec.rtsp; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpResponse; import io.netty.util.CharsetUtil; @@ -38,11 +39,11 @@ public class RtspResponseEncoder extends RtspObjectEncoder { @Override protected void encodeInitialLine(ByteBuf buf, HttpResponse response) throws Exception { - encodeAscii(response.getProtocolVersion().toString(), buf); + HttpHeaders.encodeAscii(response.getProtocolVersion().toString(), buf); buf.writeByte(SP); buf.writeBytes(String.valueOf(response.getStatus().code()).getBytes(CharsetUtil.US_ASCII)); buf.writeByte(SP); - encodeAscii(String.valueOf(response.getStatus().reasonPhrase()), buf); + HttpHeaders.encodeAscii(String.valueOf(response.getStatus().reasonPhrase()), buf); buf.writeBytes(CRLF); } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentEncoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentEncoderTest.java index 742dcc43c4..83de1bd174 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentEncoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentEncoderTest.java @@ -33,7 +33,7 @@ public class HttpContentEncoderTest { private static final class TestEncoder extends HttpContentEncoder { @Override - protected Result beginEncode(HttpResponse headers, String acceptEncoding) { + protected Result beginEncode(HttpResponse headers, CharSequence acceptEncoding) { return new Result("test", new EmbeddedChannel(new MessageToByteEncoder() { @Override protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception { diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketRequestBuilder.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketRequestBuilder.java index 71e22adaf9..588e5710d6 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketRequestBuilder.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketRequestBuilder.java @@ -127,7 +127,7 @@ public class WebSocketRequestBuilder { .method(HttpMethod.GET) .uri("/test") .host("server.example.com") - .upgrade(WEBSOCKET.toLowerCase()) + .upgrade(WEBSOCKET.toString().toLowerCase()) .key("dGhlIHNhbXBsZSBub25jZQ==") .origin("http://example.com") .version13() diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00Test.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00Test.java index 492e5cc877..d35b6f3985 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00Test.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00Test.java @@ -45,7 +45,7 @@ public class WebSocketServerHandshaker00Test { HTTP_1_1, HttpMethod.GET, "/chat", Unpooled.copiedBuffer("^n:ds[4U", CharsetUtil.US_ASCII)); req.headers().set(Names.HOST, "server.example.com"); - req.headers().set(Names.UPGRADE, WEBSOCKET.toLowerCase()); + req.headers().set(Names.UPGRADE, WEBSOCKET.toString().toLowerCase()); req.headers().set(Names.CONNECTION, "Upgrade"); req.headers().set(Names.ORIGIN, "http://example.com"); req.headers().set(Names.SEC_WEBSOCKET_KEY1, "4 @1 46546xW%0l 1 5"); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08Test.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08Test.java index 6b6d3c7aca..dfe1ff8664 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08Test.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker08Test.java @@ -41,7 +41,7 @@ public class WebSocketServerHandshaker08Test { FullHttpRequest req = new DefaultFullHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"); req.headers().set(Names.HOST, "server.example.com"); - req.headers().set(Names.UPGRADE, WEBSOCKET.toLowerCase()); + req.headers().set(Names.UPGRADE, WEBSOCKET.toString().toLowerCase()); req.headers().set(Names.CONNECTION, "Upgrade"); req.headers().set(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); req.headers().set(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java index aacc460a26..16f2b918fc 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13Test.java @@ -41,7 +41,7 @@ public class WebSocketServerHandshaker13Test { FullHttpRequest req = new DefaultFullHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"); req.headers().set(Names.HOST, "server.example.com"); - req.headers().set(Names.UPGRADE, WEBSOCKET.toLowerCase()); + req.headers().set(Names.UPGRADE, WEBSOCKET.toString().toLowerCase()); req.headers().set(Names.CONNECTION, "Upgrade"); req.headers().set(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); req.headers().set(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandlerTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandlerTest.java index df37a8671f..a201beda3b 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandlerTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandlerTest.java @@ -93,7 +93,7 @@ public class WebSocketServerProtocolHandlerTest { .uri("/test") .key(null) .connection("Upgrade") - .upgrade(WEBSOCKET.toLowerCase()) + .upgrade(WEBSOCKET.toString().toLowerCase()) .version13() .build(); diff --git a/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java b/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java index 93c6587d18..4818476c75 100644 --- a/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java +++ b/example/src/main/java/io/netty/example/http/upload/HttpUploadClient.java @@ -188,8 +188,8 @@ public class HttpUploadClient { HttpHeaders headers = request.headers(); headers.set(HttpHeaders.Names.HOST, host); headers.set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); - headers.set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP + ',' - + HttpHeaders.Values.DEFLATE); + headers.set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP.toString() + ',' + + HttpHeaders.Values.DEFLATE.toString()); headers.set(HttpHeaders.Names.ACCEPT_CHARSET, "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); headers.set(HttpHeaders.Names.ACCEPT_LANGUAGE, "fr"); diff --git a/example/src/main/java/io/netty/example/http/upload/HttpUploadServerHandler.java b/example/src/main/java/io/netty/example/http/upload/HttpUploadServerHandler.java index 12b7e880d2..4ad93afa84 100644 --- a/example/src/main/java/io/netty/example/http/upload/HttpUploadServerHandler.java +++ b/example/src/main/java/io/netty/example/http/upload/HttpUploadServerHandler.java @@ -286,9 +286,9 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler