diff --git a/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java index db48953da5..46f49bca27 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java @@ -936,6 +936,10 @@ public abstract class AbstractByteBuf implements ByteBuf { @Override public String toString() { + if (isFreed()) { + return getClass().getSimpleName() + "(freed)"; + } + return getClass().getSimpleName() + '(' + "ridx=" + readerIndex + ", " + "widx=" + writerIndex + ", " + diff --git a/buffer/src/main/java/io/netty/buffer/DefaultByteBufHolder.java b/buffer/src/main/java/io/netty/buffer/DefaultByteBufHolder.java index 6410209c5d..29dabfb1af 100644 --- a/buffer/src/main/java/io/netty/buffer/DefaultByteBufHolder.java +++ b/buffer/src/main/java/io/netty/buffer/DefaultByteBufHolder.java @@ -57,9 +57,6 @@ public class DefaultByteBufHolder implements ByteBufHolder { @Override public String toString() { - if (isFreed()) { - return "Message{data=(FREED)}"; - } - return "Message{data=" + ByteBufUtil.hexDump(data()) + '}'; + return getClass().getSimpleName() + '(' + data().toString() + ')'; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/ClientCookieEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/ClientCookieEncoder.java index 82979d3b04..b21cf174e7 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/ClientCookieEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/ClientCookieEncoder.java @@ -22,7 +22,7 @@ import static io.netty.handler.codec.http.CookieEncoderUtil.*; * the HTTP cookie version 0, 1, and 2. *
  * // Example
- * {@link HttpRequestHeader} req = ...;
+ * {@link HttpRequest} req = ...;
  * res.setHeader("Cookie", {@link ClientCookieEncoder}.encode("JSESSIONID", "1234"));
  * 
* diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/CookieDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/CookieDecoder.java index 236cc23b81..82eec65ed5 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/CookieDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/CookieDecoder.java @@ -29,7 +29,7 @@ import java.util.TreeSet; * the HTTP cookie version 0, 1, and 2. * *
- * {@link HttpRequestHeader} req = ...;
+ * {@link HttpRequest} req = ...;
  * String value = req.getHeader("Cookie");
  * Set<{@link Cookie}> cookies = new {@link CookieDecoder}().decode(value);
  * 
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultFullHttpRequest.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultFullHttpRequest.java new file mode 100644 index 0000000000..1110756eae --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultFullHttpRequest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +/** + * Default implementation of {@link FullHttpRequest}. + */ +public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHttpRequest { + private final ByteBuf content; + private final HttpHeaders trailingHeader = new DefaultHttpHeaders(); + + public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri) { + this(httpVersion, method, uri, Unpooled.buffer(0)); + } + + public DefaultFullHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, ByteBuf content) { + super(httpVersion, method, uri); + if (content == null) { + throw new NullPointerException("content"); + } + this.content = content; + } + + @Override + public HttpHeaders trailingHeaders() { + return trailingHeader; + } + + @Override + public ByteBuf data() { + return content; + } + + @Override + public boolean isFreed() { + return content.isFreed(); + } + + @Override + public void free() { + content.free(); + } + + @Override + public FullHttpRequest copy() { + DefaultFullHttpRequest copy = new DefaultFullHttpRequest(protocolVersion(), method(), uri(), data().copy()); + copy.headers().set(headers()); + copy.trailingHeaders().set(trailingHeaders()); + return copy; + } +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultFullHttpResponse.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultFullHttpResponse.java new file mode 100644 index 0000000000..a76451b956 --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultFullHttpResponse.java @@ -0,0 +1,69 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + + +/** + * Default implementation of a {@link FullHttpResponse}. + */ +public class DefaultFullHttpResponse extends DefaultHttpResponse implements FullHttpResponse { + + private final ByteBuf content; + private final HttpHeaders trailingHeaders = new DefaultHttpHeaders(); + + public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status) { + this(version, status, Unpooled.buffer(0)); + } + + public DefaultFullHttpResponse(HttpVersion version, HttpResponseStatus status, ByteBuf content) { + super(version, status); + if (content == null) { + throw new NullPointerException("content"); + } + this.content = content; + } + + @Override + public HttpHeaders trailingHeaders() { + return trailingHeaders; + } + + @Override + public ByteBuf data() { + return content; + } + + @Override + public boolean isFreed() { + return content.isFreed(); + } + + @Override + public void free() { + content.free(); + } + + @Override + public FullHttpResponse copy() { + DefaultFullHttpResponse copy = new DefaultFullHttpResponse(protocolVersion(), status(), data().copy()); + copy.headers().set(headers()); + copy.trailingHeaders().set(trailingHeaders()); + return copy; + } +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpContent.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpContent.java index 65fbdd34bd..0759eecd1e 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpContent.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpContent.java @@ -22,40 +22,40 @@ import io.netty.buffer.ByteBuf; */ public class DefaultHttpContent extends DefaultHttpObject implements HttpContent { - private ByteBuf content; + private final ByteBuf content; /** * Creates a new instance with the specified chunk content. */ public DefaultHttpContent(ByteBuf content) { - setContent(content); - } - - @Override - public ByteBuf getContent() { - return content; - } - - @Override - public void setContent(ByteBuf content) { if (content == null) { throw new NullPointerException("content"); } this.content = content; } + @Override + public ByteBuf data() { + return content; + } + + @Override + public HttpContent copy() { + return new DefaultHttpContent(data().copy()); + } + + @Override + public boolean isFreed() { + return content.isFreed(); + } + + @Override + public void free() { + content.free(); + } + @Override public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append(getClass().getSimpleName()); - - buf.append(" size: "); - buf.append(getContent().readableBytes()); - - buf.append(", decodeResult: "); - buf.append(getDecoderResult()); - buf.append(')'); - - return buf.toString(); + return getClass().getSimpleName() + "(data: " + data() + ", decoderResult: " + decoderResult() + ')'; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeader.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeader.java deleted file mode 100644 index e58c7c81eb..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeader.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.http; - -import io.netty.util.internal.StringUtil; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * The default {@link HttpHeader} implementation. - */ -public abstract class DefaultHttpHeader extends DefaultHttpObject implements HttpHeader { - - private final HttpHeaders headers = new HttpHeaders(); - private HttpVersion version; - - /** - * Creates a new instance. - */ - protected DefaultHttpHeader(final HttpVersion version) { - setProtocolVersion(version); - } - - @Override - public void addHeader(final String name, final Object value) { - headers.addHeader(name, value); - } - - @Override - public void setHeader(final String name, final Object value) { - headers.setHeader(name, value); - } - - @Override - public void setHeader(final String name, final Iterable values) { - headers.setHeader(name, values); - } - - @Override - public void removeHeader(final String name) { - headers.removeHeader(name); - } - - @Override - public void clearHeaders() { - headers.clearHeaders(); - } - - @Override - public String getHeader(final String name) { - return headers.getHeader(name); - } - - @Override - public List getHeaders(final String name) { - return headers.getHeaders(name); - } - - @Override - public List> getHeaders() { - return headers.getHeaders(); - } - - @Override - public boolean containsHeader(final String name) { - return headers.containsHeader(name); - } - - @Override - public Set getHeaderNames() { - return headers.getHeaderNames(); - } - - @Override - public HttpVersion getProtocolVersion() { - return version; - } - - @Override - public void setProtocolVersion(HttpVersion version) { - if (version == null) { - throw new NullPointerException("version"); - } - this.version = version; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append(getClass().getSimpleName()); - buf.append("(version: "); - buf.append(getProtocolVersion().getText()); - buf.append(", keepAlive: "); - buf.append(HttpHeaders.isKeepAlive(this)); - buf.append(')'); - buf.append(StringUtil.NEWLINE); - appendHeaders(buf); - - // Remove the last newline. - buf.setLength(buf.length() - StringUtil.NEWLINE.length()); - return buf.toString(); - } - - void appendHeaders(StringBuilder buf) { - for (Map.Entry e: getHeaders()) { - buf.append(e.getKey()); - buf.append(": "); - buf.append(e.getValue()); - buf.append(StringUtil.NEWLINE); - } - } -} 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 new file mode 100644 index 0000000000..a7f2783980 --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java @@ -0,0 +1,359 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.http; + +import java.util.Calendar; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +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 boolean eq(String name1, String name2) { + int nameLen = name1.length(); + if (nameLen != name2.length()) { + return false; + } + + for (int i = nameLen - 1; i >= 0; i --) { + char c1 = name1.charAt(i); + char c2 = name2.charAt(i); + if (c1 != c2) { + if (c1 >= 'A' && c1 <= 'Z') { + c1 += 32; + } + if (c2 >= 'A' && c2 <= 'Z') { + c2 += 32; + } + if (c1 != c2) { + return false; + } + } + } + return true; + } + + 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); + + public DefaultHttpHeaders() { + head.before = head.after = head; + } + + void validateHeaderName0(String headerName) { + validateHeaderName(headerName); + } + + @Override + public void add(final String name, final Object value) { + validateHeaderName0(name); + String strVal = toString(value); + validateHeaderValue(strVal); + int h = hash(name); + int i = index(h); + add0(h, i, name, strVal); + } + + @Override + public void add(String name, Iterable values) { + validateHeaderName0(name); + int h = hash(name); + int i = index(h); + for (Object v: values) { + String vstr = toString(v); + validateHeaderValue(vstr); + add0(h, i, name, vstr); + } + } + + private void add0(int h, int i, final String name, final String value) { + // Update the hash table. + HeaderEntry e = entries[i]; + HeaderEntry newEntry; + entries[i] = newEntry = new HeaderEntry(h, name, value); + newEntry.next = e; + + // Update the linked list. + newEntry.addBefore(head); + } + + @Override + public void remove(final String name) { + if (name == null) { + throw new NullPointerException("name"); + } + int h = hash(name); + int i = index(h); + remove0(h, i, name); + } + + private void remove0(int h, int i, String name) { + HeaderEntry e = entries[i]; + if (e == null) { + return; + } + + for (;;) { + if (e.hash == h && eq(name, e.key)) { + e.remove(); + HeaderEntry next = e.next; + if (next != null) { + entries[i] = next; + e = next; + } else { + entries[i] = null; + return; + } + } else { + break; + } + } + + for (;;) { + HeaderEntry next = e.next; + if (next == null) { + break; + } + if (next.hash == h && eq(name, next.key)) { + e.next = next.next; + next.remove(); + } else { + e = next; + } + } + } + + @Override + public void set(final String name, final Object value) { + validateHeaderName0(name); + String strVal = toString(value); + validateHeaderValue(strVal); + int h = hash(name); + int i = index(h); + remove0(h, i, name); + add0(h, i, name, strVal); + } + + @Override + public void set(final String name, final Iterable values) { + if (values == null) { + throw new NullPointerException("values"); + } + + validateHeaderName0(name); + + int h = hash(name); + int i = index(h); + + remove0(h, i, name); + for (Object v: values) { + if (v == null) { + break; + } + String strVal = toString(v); + validateHeaderValue(strVal); + add0(h, i, name, strVal); + } + } + + @Override + public void clear() { + for (int i = 0; i < entries.length; i ++) { + entries[i] = null; + } + head.before = head.after = head; + } + + @Override + public String get(final String name) { + if (name == null) { + throw new NullPointerException("name"); + } + + int h = hash(name); + int i = index(h); + HeaderEntry e = entries[i]; + while (e != null) { + if (e.hash == h && eq(name, e.key)) { + return e.value; + } + + e = e.next; + } + return null; + } + + @Override + public List getAll(final String name) { + if (name == null) { + throw new NullPointerException("name"); + } + + LinkedList values = new LinkedList(); + + int h = hash(name); + int i = index(h); + HeaderEntry e = entries[i]; + while (e != null) { + if (e.hash == h && eq(name, e.key)) { + values.addFirst(e.value); + } + e = e.next; + } + return values; + } + + @Override + public List> entries() { + List> all = + new LinkedList>(); + + HeaderEntry e = head.after; + while (e != head) { + all.add(e); + e = e.after; + } + return all; + } + + @Override + public Iterator> iterator() { + return entries().iterator(); + } + + @Override + public boolean contains(String name) { + return get(name) != null; + } + + @Override + public boolean isEmpty() { + return head == head.after; + } + + @Override + public Set names() { + + Set names = new TreeSet(String.CASE_INSENSITIVE_ORDER); + + HeaderEntry e = head.after; + while (e != head) { + names.add(e.key); + e = e.after; + } + return names; + } + + private static String toString(Object value) { + if (value == null) { + return null; + } + if (value instanceof String) { + return (String) value; + } + if (value instanceof Number) { + return value.toString(); + } + if (value instanceof Date) { + return new HttpHeaderDateFormat().format((Date) value); + } + if (value instanceof Calendar) { + return new HttpHeaderDateFormat().format(((Calendar) value).getTime()); + } + return value.toString(); + } + + private static final class HeaderEntry implements Map.Entry { + final int hash; + final String key; + String value; + HeaderEntry next; + HeaderEntry before, after; + + HeaderEntry(int hash, String key, String value) { + this.hash = hash; + this.key = key; + this.value = value; + } + + void remove() { + before.after = after; + after.before = before; + } + + void addBefore(HeaderEntry e) { + after = e; + before = e.before; + before.after = this; + after.before = this; + } + + @Override + public String getKey() { + return key; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String setValue(String value) { + if (value == null) { + throw new NullPointerException("value"); + } + validateHeaderValue(value); + String oldValue = this.value; + this.value = value; + return oldValue; + } + + @Override + public String toString() { + return key + '=' + value; + } + } +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpMessage.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpMessage.java index a3da4709a2..677d3d4e85 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpMessage.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpMessage.java @@ -15,31 +15,61 @@ */ package io.netty.handler.codec.http; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; +import io.netty.util.internal.StringUtil; + +import java.util.Map; /** - * Combination of {@link HttpHeader} and {@link LastHttpContent} which can be used to combine the headers and - * the actual content. {@link HttpObjectAggregator} makes use of this. - * + * The default {@link HttpMessage} implementation. */ -public abstract class DefaultHttpMessage extends DefaultHttpHeader implements LastHttpContent { - private ByteBuf content = Unpooled.EMPTY_BUFFER; +public abstract class DefaultHttpMessage extends DefaultHttpObject implements HttpMessage { - public DefaultHttpMessage(HttpVersion version) { - super(version); - } + private final HttpVersion version; + private final HttpHeaders headers = new DefaultHttpHeaders(); - @Override - public ByteBuf getContent() { - return content; - } - - @Override - public void setContent(ByteBuf content) { - if (content == null) { - throw new NullPointerException("content"); + /** + * Creates a new instance. + */ + protected DefaultHttpMessage(final HttpVersion version) { + if (version == null) { + throw new NullPointerException("version"); + } + this.version = version; + } + + @Override + public HttpHeaders headers() { + return headers; + } + + @Override + public HttpVersion protocolVersion() { + return version; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(getClass().getSimpleName()); + buf.append("(version: "); + buf.append(protocolVersion().getText()); + buf.append(", keepAlive: "); + buf.append(HttpHeaders.isKeepAlive(this)); + buf.append(')'); + buf.append(StringUtil.NEWLINE); + appendHeaders(buf); + + // Remove the last newline. + buf.setLength(buf.length() - StringUtil.NEWLINE.length()); + return buf.toString(); + } + + void appendHeaders(StringBuilder buf) { + for (Map.Entry e: headers().entries()) { + buf.append(e.getKey()); + buf.append(": "); + buf.append(e.getValue()); + buf.append(StringUtil.NEWLINE); } - this.content = content; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpObject.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpObject.java index 232eeecea1..4c67531516 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpObject.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpObject.java @@ -19,22 +19,22 @@ import io.netty.handler.codec.DecoderResult; public class DefaultHttpObject implements HttpObject { - private DecoderResult decodeResult = DecoderResult.SUCCESS; + private DecoderResult decoderResult = DecoderResult.SUCCESS; protected DefaultHttpObject() { // Disallow direct instantiation } @Override - public DecoderResult getDecoderResult() { - return decodeResult; + public DecoderResult decoderResult() { + return decoderResult; } @Override - public void setDecoderResult(DecoderResult result) { - if (result == null) { - throw new NullPointerException("result"); + public void updateDecoderResult(DecoderResult decoderResult) { + if (decoderResult == null) { + throw new NullPointerException("decoderResult"); } - decodeResult = result; + this.decoderResult = decoderResult; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpRequest.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpRequest.java index 6e06e32f4c..4465a6668d 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpRequest.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 The Netty Project + * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -15,34 +15,63 @@ */ package io.netty.handler.codec.http; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; +import io.netty.util.internal.StringUtil; /** - * Default implementation of {@link HttpRequest}. + * The default {@link HttpRequest} implementation. */ -public class DefaultHttpRequest extends DefaultHttpRequestHeader implements HttpRequest { - private ByteBuf content = Unpooled.EMPTY_BUFFER; +public class DefaultHttpRequest extends DefaultHttpMessage implements HttpRequest { + private final HttpMethod method; + private final String uri; + + /** + * Creates a new instance. + * + * @param httpVersion the HTTP version of the request + * @param method the HTTP method of the request + * @param uri the URI or path of the request + */ public DefaultHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri) { - this(httpVersion, method, uri, Unpooled.EMPTY_BUFFER); - } - - public DefaultHttpRequest(HttpVersion httpVersion, HttpMethod method, String uri, ByteBuf content) { - super(httpVersion, method, uri); - setContent(content); - } - - @Override - public ByteBuf getContent() { - return content; - } - - @Override - public void setContent(ByteBuf content) { - if (content == null) { - throw new NullPointerException("content"); + super(httpVersion); + if (method == null) { + throw new NullPointerException("method"); } - this.content = content; + if (uri == null) { + throw new NullPointerException("uri"); + } + this.method = method; + this.uri = uri; + } + + @Override + public HttpMethod method() { + return method; + } + + @Override + public String uri() { + return uri; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(getClass().getSimpleName()); + buf.append(", decodeResult: "); + buf.append(decoderResult()); + buf.append(')'); + buf.append(StringUtil.NEWLINE); + buf.append(method().toString()); + buf.append(' '); + buf.append(uri()); + buf.append(' '); + buf.append(protocolVersion().getText()); + buf.append(StringUtil.NEWLINE); + appendHeaders(buf); + + // Remove the last newline. + buf.setLength(buf.length() - StringUtil.NEWLINE.length()); + return buf.toString(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpRequestHeader.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpRequestHeader.java deleted file mode 100644 index 04a2c990d2..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpRequestHeader.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.http; - -import io.netty.util.internal.StringUtil; - -/** - * The default {@link HttpRequestHeader} implementation. - */ -public class DefaultHttpRequestHeader extends DefaultHttpHeader implements HttpRequestHeader { - - private HttpMethod method; - private String uri; - - /** - * Creates a new instance. - * - * @param httpVersion the HTTP version of the request - * @param method the HTTP method of the request - * @param uri the URI or path of the request - */ - public DefaultHttpRequestHeader(HttpVersion httpVersion, HttpMethod method, String uri) { - super(httpVersion); - setMethod(method); - setUri(uri); - } - - @Override - public HttpMethod getMethod() { - return method; - } - - @Override - public void setMethod(HttpMethod method) { - if (method == null) { - throw new NullPointerException("method"); - } - this.method = method; - } - - @Override - public String getUri() { - return uri; - } - - @Override - public void setUri(String uri) { - if (uri == null) { - throw new NullPointerException("uri"); - } - this.uri = uri; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append(getClass().getSimpleName()); - buf.append(", decodeResult: "); - buf.append(getDecoderResult()); - buf.append(')'); - buf.append(StringUtil.NEWLINE); - buf.append(getMethod().toString()); - buf.append(' '); - buf.append(getUri()); - buf.append(' '); - buf.append(getProtocolVersion().getText()); - buf.append(StringUtil.NEWLINE); - appendHeaders(buf); - - // Remove the last newline. - buf.setLength(buf.length() - StringUtil.NEWLINE.length()); - return buf.toString(); - } -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java index e4de06a86f..fd7e99855e 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 The Netty Project + * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -15,35 +15,50 @@ */ package io.netty.handler.codec.http; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - +import io.netty.util.internal.StringUtil; /** - * Default implementation of a {@link HttpResponse}. + * The default {@link HttpResponse} implementation. */ -public class DefaultHttpResponse extends DefaultHttpResponseHeader implements HttpResponse { - private ByteBuf content = Unpooled.EMPTY_BUFFER; +public class DefaultHttpResponse extends DefaultHttpMessage implements HttpResponse { + private final HttpResponseStatus status; + + /** + * Creates a new instance. + * + * @param version the HTTP version of this response + * @param status the status of this response + */ public DefaultHttpResponse(HttpVersion version, HttpResponseStatus status) { - this(version, status, Unpooled.EMPTY_BUFFER); - } - - public DefaultHttpResponse(HttpVersion version, HttpResponseStatus status, ByteBuf content) { - super(version, status); - setContent(content); - } - - @Override - public ByteBuf getContent() { - return content; - } - - @Override - public void setContent(ByteBuf content) { - if (content == null) { - throw new NullPointerException("content"); + super(version); + if (status == null) { + throw new NullPointerException("status"); } - this.content = content; + this.status = status; + } + + @Override + public HttpResponseStatus status() { + return status; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(getClass().getSimpleName()); + buf.append(", decodeResult: "); + buf.append(decoderResult()); + buf.append(')'); + buf.append(StringUtil.NEWLINE); + buf.append(protocolVersion().getText()); + buf.append(' '); + buf.append(status().toString()); + buf.append(StringUtil.NEWLINE); + appendHeaders(buf); + + // Remove the last newline. + buf.setLength(buf.length() - StringUtil.NEWLINE.length()); + return buf.toString(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponseHeader.java b/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponseHeader.java deleted file mode 100644 index 6a4819957c..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpResponseHeader.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.http; - -import io.netty.util.internal.StringUtil; - -/** - * The default {@link HttpResponseHeader} implementation. - */ -public class DefaultHttpResponseHeader extends DefaultHttpHeader implements HttpResponseHeader { - - private HttpResponseStatus status; - - /** - * Creates a new instance. - * - * @param version the HTTP version of this response - * @param status the status of this response - */ - public DefaultHttpResponseHeader(HttpVersion version, HttpResponseStatus status) { - super(version); - setStatus(status); - } - - @Override - public HttpResponseStatus getStatus() { - return status; - } - - @Override - public void setStatus(HttpResponseStatus status) { - if (status == null) { - throw new NullPointerException("status"); - } - this.status = status; - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append(getClass().getSimpleName()); - buf.append(", decodeResult: "); - buf.append(getDecoderResult()); - buf.append(')'); - buf.append(StringUtil.NEWLINE); - buf.append(getProtocolVersion().getText()); - buf.append(' '); - buf.append(getStatus().toString()); - buf.append(StringUtil.NEWLINE); - appendHeaders(buf); - - // Remove the last newline. - buf.setLength(buf.length() - StringUtil.NEWLINE.length()); - return buf.toString(); - } -} 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 83fe4466c1..260512b2ac 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 @@ -19,16 +19,14 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.util.internal.StringUtil; -import java.util.List; import java.util.Map; -import java.util.Set; /** * The default {@link LastHttpContent} implementation. */ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHttpContent { - private final HttpHeaders headers = new HttpHeaders() { + private final HttpHeaders trailingHeaders = new DefaultHttpHeaders() { @Override void validateHeaderName0(String name) { super.validateHeaderName0(name); @@ -42,7 +40,7 @@ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHt }; public DefaultLastHttpContent() { - this(Unpooled.EMPTY_BUFFER); + this(Unpooled.buffer(0)); } public DefaultLastHttpContent(ByteBuf content) { @@ -50,64 +48,20 @@ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHt } @Override - public void addHeader(final String name, final Object value) { - headers.addHeader(name, value); + public LastHttpContent copy() { + DefaultLastHttpContent copy = new DefaultLastHttpContent(data().copy()); + copy.trailingHeaders().set(trailingHeaders()); + return copy; } @Override - public void setHeader(final String name, final Object value) { - headers.setHeader(name, value); - } - - @Override - public void setHeader(final String name, final Iterable values) { - headers.setHeader(name, values); - } - - @Override - public void removeHeader(final String name) { - headers.removeHeader(name); - } - - @Override - public void clearHeaders() { - headers.clearHeaders(); - } - - @Override - public String getHeader(final String name) { - return headers.getHeader(name); - } - - @Override - public List getHeaders(final String name) { - return headers.getHeaders(name); - } - - @Override - public List> getHeaders() { - return headers.getHeaders(); - } - - @Override - public boolean containsHeader(final String name) { - return headers.containsHeader(name); - } - - @Override - public Set getHeaderNames() { - return headers.getHeaderNames(); + public HttpHeaders trailingHeaders() { + return trailingHeaders; } @Override public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append(getClass().getSimpleName()); - buf.append(", size: "); - buf.append(getContent().readableBytes()); - buf.append(", decodeResult: "); - buf.append(getDecoderResult()); - buf.append(')'); + StringBuilder buf = new StringBuilder(super.toString()); buf.append(StringUtil.NEWLINE); appendHeaders(buf); @@ -117,7 +71,7 @@ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHt } private void appendHeaders(StringBuilder buf) { - for (Map.Entry e: getHeaders()) { + for (Map.Entry e: trailingHeaders()) { buf.append(e.getKey()); buf.append(": "); buf.append(e.getValue()); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpMessage.java b/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpMessage.java new file mode 100644 index 0000000000..6fe09de77d --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpMessage.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.http; + +/** + * Combines {@link FullHttpMessage} and {@link LastHttpContent} into one + * message. So it represent a complete http message. + */ +public interface FullHttpMessage extends HttpMessage, LastHttpContent { + @Override + FullHttpMessage copy(); +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpRequest.java b/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpRequest.java new file mode 100644 index 0000000000..eba8224a2f --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpRequest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.http; + +/** + * Combinate the {@link HttpRequest} and {@link FullHttpMessage}, so the request is a complete HTTP + * request. + */ +public interface FullHttpRequest extends HttpRequest, FullHttpMessage { + @Override + FullHttpRequest copy(); +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpResponse.java b/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpResponse.java new file mode 100644 index 0000000000..132292663e --- /dev/null +++ b/codec-http/src/main/java/io/netty/handler/codec/http/FullHttpResponse.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.codec.http; + +/** + * Combination of a {@link HttpResponse} and {@link FullHttpMessage}. + * So it represent a complete http response. + */ +public interface FullHttpResponse extends HttpResponse, FullHttpMessage { + @Override + FullHttpResponse copy(); +} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java index 112fb12f29..cf21e72abc 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpClientCodec.java @@ -84,8 +84,8 @@ public class HttpClientCodec extends CombinedChannelHandler { @Override protected void encode( ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception { - if (msg instanceof HttpRequestHeader && !done) { - queue.offer(((HttpRequestHeader) msg).getMethod()); + if (msg instanceof HttpRequest && !done) { + queue.offer(((HttpRequest) msg).method()); } super.encode(ctx, msg, out); @@ -137,8 +137,8 @@ public class HttpClientCodec extends CombinedChannelHandler { } @Override - protected boolean isContentAlwaysEmpty(HttpHeader msg) { - final int statusCode = ((HttpResponseHeader) msg).getStatus().getCode(); + protected boolean isContentAlwaysEmpty(HttpMessage msg) { + final int statusCode = ((HttpResponse) msg).status().code(); if (statusCode == 100) { // 100-continue response should be excluded from paired comparison. return true; @@ -148,7 +148,7 @@ public class HttpClientCodec extends CombinedChannelHandler { // current response. HttpMethod method = queue.poll(); - char firstChar = method.getName().charAt(0); + char firstChar = method.name().charAt(0); switch (firstChar) { case 'H': // According to 4.3, RFC2616: diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContent.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContent.java index 76a74b6dbe..7f43752c17 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContent.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContent.java @@ -15,134 +15,19 @@ */ package io.netty.handler.codec.http; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; +import io.netty.buffer.ByteBufHolder; import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.DecoderResult; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; /** * An HTTP chunk which is used for HTTP chunked transfer-encoding. * {@link HttpObjectDecoder} generates {@link HttpContent} after - * {@link HttpHeader} when the content is large or the encoding of the content + * {@link HttpMessage} when the content is large or the encoding of the content * is 'chunked. If you prefer not to receive {@link HttpContent} in your handler, - * please {@link HttpObjectAggregator} after {@link HttpObjectDecoder} in the + * place {@link HttpObjectAggregator} after {@link HttpObjectDecoder} in the * {@link ChannelPipeline}. * @apiviz.landmark */ -public interface HttpContent extends HttpObject { - - HttpContent EMPTY = new HttpContent() { - - @Override - public ByteBuf getContent() { - return Unpooled.EMPTY_BUFFER; - } - - @Override - public void setContent(ByteBuf content) { - throw new IllegalStateException("read-only"); - } - - @Override - public DecoderResult getDecoderResult() { - return DecoderResult.SUCCESS; - } - - @Override - public void setDecoderResult(DecoderResult result) { - throw new IllegalStateException("read-only"); - } - }; - - /** - * The 'end of content' marker in chunked encoding. - */ - LastHttpContent LAST_CONTENT = new LastHttpContent() { - @Override - public ByteBuf getContent() { - return Unpooled.EMPTY_BUFFER; - } - - @Override - public void setContent(ByteBuf content) { - throw new IllegalStateException("read-only"); - } - - @Override - public void addHeader(String name, Object value) { - throw new IllegalStateException("read-only"); - } - - @Override - public void clearHeaders() { - // NOOP - } - - @Override - public boolean containsHeader(String name) { - return false; - } - - @Override - public String getHeader(String name) { - return null; - } - - @Override - public Set getHeaderNames() { - return Collections.emptySet(); - } - - @Override - public List getHeaders(String name) { - return Collections.emptyList(); - } - - @Override - public List> getHeaders() { - return Collections.emptyList(); - } - - @Override - public void removeHeader(String name) { - // NOOP - } - - @Override - public void setHeader(String name, Object value) { - throw new IllegalStateException("read-only"); - } - - @Override - public void setHeader(String name, Iterable values) { - throw new IllegalStateException("read-only"); - } - - @Override - public DecoderResult getDecoderResult() { - return DecoderResult.SUCCESS; - } - - @Override - public void setDecoderResult(DecoderResult result) { - throw new IllegalStateException("read-only"); - } - }; - - /** - * Returns the content of this chunk. If this is the 'end of content' - * marker, {@link Unpooled#EMPTY_BUFFER} will be returned. - */ - ByteBuf getContent(); - - /** - * Sets the content of this chunk. If an empty buffer is specified, - * this chunk becomes the 'end of content' marker. - */ - void setContent(ByteBuf content); +public interface HttpContent extends HttpObject, ByteBufHolder { + @Override + HttpContent copy(); } 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 77d73451ba..82cca50f3c 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 @@ -21,7 +21,7 @@ import io.netty.handler.codec.compression.ZlibWrapper; import io.netty.util.internal.StringUtil; /** - * Compresses an {@link HttpHeader} and an {@link HttpContent} in {@code gzip} or + * Compresses an {@link HttpMessage} and an {@link HttpContent} in {@code gzip} or * {@code deflate} encoding while respecting the {@code "Accept-Encoding"} header. * If there is no matching encoding, no compression is done. For more * information on how this handler modifies the message, please refer to @@ -93,8 +93,8 @@ public class HttpContentCompressor extends HttpContentEncoder { } @Override - protected Result beginEncode(HttpHeader header, HttpContent msg, String acceptEncoding) throws Exception { - String contentEncoding = header.getHeader(HttpHeaders.Names.CONTENT_ENCODING); + protected Result beginEncode(HttpMessage header, HttpContent msg, String acceptEncoding) throws Exception { + String contentEncoding = header.headers().get(HttpHeaders.Names.CONTENT_ENCODING); if (contentEncoding != null && !HttpHeaders.Values.IDENTITY.equalsIgnoreCase(contentEncoding)) { return null; 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 201c6fc9dc..cdc4685262 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 @@ -16,13 +16,14 @@ package io.netty.handler.codec.http; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufHolder; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedByteChannel; import io.netty.handler.codec.MessageToMessageDecoder; /** - * Decodes the content of the received {@link HttpRequestHeader} and {@link HttpContent}. + * Decodes the content of the received {@link HttpRequest} and {@link HttpContent}. * The original content is replaced with the new content decoded by the * {@link EmbeddedByteChannel}, which is created by {@link #newContentDecoder(String)}. * Once decoding is finished, the value of the 'Content-Encoding' @@ -43,7 +44,7 @@ import io.netty.handler.codec.MessageToMessageDecoder; public abstract class HttpContentDecoder extends MessageToMessageDecoder { private EmbeddedByteChannel decoder; - private HttpHeader header; + private HttpMessage header; private boolean decodeStarted; /** @@ -55,13 +56,13 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder @Override protected Object decode(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpResponseHeader && ((HttpResponseHeader) msg).getStatus().getCode() == 100) { + if (msg instanceof HttpResponse && ((HttpResponse) msg).status().code() == 100) { // 100-continue response must be passed through. return msg; } - if (msg instanceof HttpHeader) { + if (msg instanceof HttpMessage) { assert header == null; - header = (HttpHeader) msg; + header = (HttpMessage) msg; cleanup(); } @@ -71,11 +72,11 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder if (!decodeStarted) { decodeStarted = true; - HttpHeader header = this.header; + HttpMessage header = this.header; this.header = null; // Determine the content encoding. - String contentEncoding = header.getHeader(HttpHeaders.Names.CONTENT_ENCODING); + String contentEncoding = header.headers().get(HttpHeaders.Names.CONTENT_ENCODING); if (contentEncoding != null) { contentEncoding = contentEncoding.trim(); } else { @@ -89,17 +90,17 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder if (HttpHeaders.Values.IDENTITY.equals(targetContentEncoding)) { // Do NOT set the 'Content-Encoding' header if the target encoding is 'identity' // as per: http://tools.ietf.org/html/rfc2616#section-14.11 - header.removeHeader(HttpHeaders.Names.CONTENT_ENCODING); + header.headers().remove(HttpHeaders.Names.CONTENT_ENCODING); } else { - header.setHeader(HttpHeaders.Names.CONTENT_ENCODING, targetContentEncoding); + header.headers().set(HttpHeaders.Names.CONTENT_ENCODING, targetContentEncoding); } Object[] decoded = decodeContent(header, c); // Replace the content. - if (header.containsHeader(HttpHeaders.Names.CONTENT_LENGTH)) { - header.setHeader( + if (header.headers().contains(HttpHeaders.Names.CONTENT_LENGTH)) { + header.headers().set( HttpHeaders.Names.CONTENT_LENGTH, - Integer.toString(((HttpContent) decoded[1]).getContent().readableBytes())); + Integer.toString(((ByteBufHolder) decoded[1]).data().readableBytes())); } return decoded; } @@ -108,13 +109,13 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder return decodeContent(null, c); } - // Because HttpMessage and HttpChunk is a mutable object, we can simply forward it. + // Because FullHttpMessage and HttpChunk is a mutable object, we can simply forward it. return msg; } - private Object[] decodeContent(HttpHeader header, HttpContent c) { + private Object[] decodeContent(HttpMessage header, HttpContent c) { ByteBuf newContent = Unpooled.buffer(); - ByteBuf content = c.getContent(); + ByteBuf content = c.data(); decode(content, newContent); if (c instanceof LastHttpContent) { diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecompressor.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecompressor.java index 7bc476f28a..254a483dae 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecompressor.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentDecompressor.java @@ -20,7 +20,7 @@ import io.netty.handler.codec.compression.ZlibCodecFactory; import io.netty.handler.codec.compression.ZlibWrapper; /** - * Decompresses an {@link HttpHeader} and an {@link HttpContent} compressed in + * Decompresses an {@link HttpMessage} and an {@link HttpContent} compressed in * {@code gzip} or {@code deflate} encoding. For more information on how this * handler modifies the message, please refer to {@link HttpContentDecoder}. */ diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java index bab3233fec..c084528e66 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java @@ -16,6 +16,7 @@ package io.netty.handler.codec.http; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufHolder; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedByteChannel; @@ -25,20 +26,20 @@ import java.util.ArrayDeque; import java.util.Queue; /** - * Encodes the content of the outbound {@link HttpResponseHeader} and {@link HttpContent}. + * Encodes the content of the outbound {@link HttpResponse} and {@link HttpContent}. * The original content is replaced with the new content encoded by the - * {@link EmbeddedByteChannel}, which is created by {@link #beginEncode(HttpHeader, HttpContent, String)}. + * {@link EmbeddedByteChannel}, which is created by {@link #beginEncode(HttpMessage, HttpContent, String)}. * Once encoding is finished, the value of the 'Content-Encoding' header * is set to the target content encoding, as returned by - * {@link #beginEncode(HttpHeader, HttpContent, String)}. + * {@link #beginEncode(HttpMessage, HttpContent, String)}. * 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 HttpRequestHeader}'s {@code "Accept-Encoding"} header, - * {@link #beginEncode(HttpHeader, HttpContent, String)} should return {@code null} so that + * corresponding {@link HttpRequest}'s {@code "Accept-Encoding"} header, + * {@link #beginEncode(HttpMessage, HttpContent, String)} 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(HttpHeader, HttpContent, String)} properly to make + * and implement {@link #beginEncode(HttpMessage, HttpContent, String)} properly to make * this class functional. For example, refer to the source code of * {@link HttpContentCompressor}. *

@@ -46,11 +47,11 @@ import java.util.Queue; * so that this handler can intercept HTTP responses before {@link HttpObjectEncoder} * converts them into {@link ByteBuf}s. */ -public abstract class HttpContentEncoder extends MessageToMessageCodec { +public abstract class HttpContentEncoder extends MessageToMessageCodec { private final Queue acceptEncodingQueue = new ArrayDeque(); private EmbeddedByteChannel encoder; - private HttpHeader header; + private HttpMessage header; private boolean encodeStarted; /** @@ -58,14 +59,14 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec[] { HttpHeader.class }, + new Class[] { HttpMessage.class }, new Class[] { HttpObject.class }); } @Override - protected Object decode(ChannelHandlerContext ctx, HttpHeader msg) + protected Object decode(ChannelHandlerContext ctx, HttpMessage msg) throws Exception { - String acceptedEncoding = msg.getHeader(HttpHeaders.Names.ACCEPT_ENCODING); + String acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); if (acceptedEncoding == null) { acceptedEncoding = HttpHeaders.Values.IDENTITY; } @@ -78,31 +79,31 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec getHeaders(String name); - - /** - * Returns the all headers that this message contains. - * - * @return A {@link List} of the header name-value entries, which will be - * empty if no pairs are found - */ - List> getHeaders(); - - /** - * Checks to see if there is a header with the specified name - * - * @param name The name of the header to search for - * @return True if at least one header is found - */ - boolean containsHeader(String name); - - /** - * Gets a {@link Set} of all header names that this message contains - * - * @return A {@link Set} of all header names - */ - Set getHeaderNames(); - - /** - * Returns the protocol version of this {@link HttpHeader} - * - * @return The protocol version - */ - HttpVersion getProtocolVersion(); - - /** - * Sets the protocol version of this {@link HttpHeader} - * - * @param version The version to set - */ - void setProtocolVersion(HttpVersion version); - - /** - * Adds a new header with the specified name and value. - * - * If the specified value is not a {@link String}, it is converted - * into a {@link String} by {@link Object#toString()}, except in the cases - * of {@link Date} and {@link Calendar}, which are formatted to the date - * format defined in RFC2616. - * - * @param name The name of the header being added - * @param value The value of the header being added - */ - void addHeader(String name, Object value); - - /** - * Sets a header with the specified name and value. - * - * If there is an existing header with the same name, it is removed. - * If the specified value is not a {@link String}, it is converted into a - * {@link String} by {@link Object#toString()}, except for {@link Date} - * and {@link Calendar}, which are formatted to the date format defined in - * RFC2616. - * - * @param name The name of the header being set - * @param value The value of the header being set - */ - void setHeader(String name, Object value); - - /** - * Sets a header with the specified name and values. - * - * If there is an existing header with the same name, it is removed. - * This method can be represented approximately as the following code: - *

-     * m.removeHeader(name);
-     * for (Object v: values) {
-     *     if (v == null) {
-     *         break;
-     *     }
-     *     m.addHeader(name, v);
-     * }
-     * 
- * - * @param name The name of the headers being set - * @param values The values of the headers being set - */ - void setHeader(String name, Iterable values); - - /** - * Removes the header with the specified name. - * - * @param name The name of the header to remove - */ - void removeHeader(String name); - - /** - * Removes all headers from this {@link HttpHeader}. - */ - void clearHeaders(); -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaders.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaders.java index f150382c03..d46d25e4b8 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaders.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaders.java @@ -17,21 +17,89 @@ package io.netty.handler.codec.http; import java.text.ParseException; import java.util.Calendar; +import java.util.Collections; import java.util.Date; -import java.util.LinkedList; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; -import java.util.TreeSet; /** * Provides the constants for the standard HTTP header names and values and - * commonly used utility methods that accesses an {@link HttpHeader}. + * commonly used utility methods that accesses an {@link HttpMessage}. * @apiviz.landmark * @apiviz.stereotype static */ -public class HttpHeaders { +public abstract class HttpHeaders implements Iterable> { + + public static final HttpHeaders EMPTY_HEADERS = new HttpHeaders() { + @Override + public String get(String name) { + return null; + } + + @Override + public List getAll(String name) { + return Collections.emptyList(); + } + + @Override + public List> entries() { + return Collections.emptyList(); + } + + @Override + public boolean contains(String name) { + return false; + } + + @Override + public boolean isEmpty() { + return true; + } + + @Override + public Set names() { + return Collections.emptySet(); + } + + @Override + public void add(String name, Object value) { + throw new UnsupportedOperationException("read only"); + } + + @Override + public void add(String name, Iterable values) { + throw new UnsupportedOperationException("read only"); + } + + @Override + public void set(String name, Object value) { + throw new UnsupportedOperationException("read only"); + } + + @Override + public void set(String name, Iterable values) { + throw new UnsupportedOperationException("read only"); + } + + @Override + public void remove(String name) { + throw new UnsupportedOperationException("read only"); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("read only"); + } + + @Override + public Iterator> iterator() { + return entries().iterator(); + } + }; /** * Standard and CORS HTTP header names. @@ -483,13 +551,13 @@ public class HttpHeaders { * {@code "Connection"} header first and then the return value of * {@link HttpVersion#isKeepAliveDefault()}. */ - public static boolean isKeepAlive(HttpHeader message) { - String connection = message.getHeader(Names.CONNECTION); + public static boolean isKeepAlive(HttpMessage message) { + String connection = message.headers().get(Names.CONNECTION); if (Values.CLOSE.equalsIgnoreCase(connection)) { return false; } - if (message.getProtocolVersion().isKeepAliveDefault()) { + if (message.protocolVersion().isKeepAliveDefault()) { return !Values.CLOSE.equalsIgnoreCase(connection); } else { return Values.KEEP_ALIVE.equalsIgnoreCase(connection); @@ -515,18 +583,18 @@ public class HttpHeaders { * * */ - public static void setKeepAlive(HttpHeader message, boolean keepAlive) { - if (message.getProtocolVersion().isKeepAliveDefault()) { + public static void setKeepAlive(HttpMessage message, boolean keepAlive) { + if (message.protocolVersion().isKeepAliveDefault()) { if (keepAlive) { - message.removeHeader(Names.CONNECTION); + message.headers().remove(Names.CONNECTION); } else { - message.setHeader(Names.CONNECTION, Values.CLOSE); + message.headers().set(Names.CONNECTION, Values.CLOSE); } } else { if (keepAlive) { - message.setHeader(Names.CONNECTION, Values.KEEP_ALIVE); + message.headers().set(Names.CONNECTION, Values.KEEP_ALIVE); } else { - message.removeHeader(Names.CONNECTION); + message.headers().remove(Names.CONNECTION); } } } @@ -538,8 +606,8 @@ public class HttpHeaders { * * @return the header value or {@code null} if there is no such header */ - public static String getHeader(HttpHeader message, String name) { - return message.getHeader(name); + public static String getHeader(HttpMessage message, String name) { + return message.headers().get(name); } /** @@ -550,8 +618,8 @@ public class HttpHeaders { * @return the header value or the {@code defaultValue} if there is no such * header */ - public static String getHeader(HttpHeader message, String name, String defaultValue) { - String value = message.getHeader(name); + public static String getHeader(HttpMessage message, String name, String defaultValue) { + String value = message.headers().get(name); if (value == null) { return defaultValue; } @@ -566,8 +634,8 @@ public class HttpHeaders { * and {@link Calendar} which are formatted to the date format defined in * RFC2616. */ - public static void setHeader(HttpHeader message, String name, Object value) { - message.setHeader(name, value); + public static void setHeader(HttpMessage message, String name, Object value) { + message.headers().set(name, value); } /** @@ -584,8 +652,8 @@ public class HttpHeaders { * } * */ - public static void setHeader(HttpHeader message, String name, Iterable values) { - message.setHeader(name, values); + public static void setHeader(HttpMessage message, String name, Iterable values) { + message.headers().set(name, values); } /** @@ -595,22 +663,22 @@ public class HttpHeaders { * and {@link Calendar} which are formatted to the date format defined in * RFC2616. */ - public static void addHeader(HttpHeader message, String name, Object value) { - message.addHeader(name, value); + public static void addHeader(HttpMessage message, String name, Object value) { + message.headers().add(name, value); } /** * Removes the header with the specified name. */ - public static void removeHeader(HttpHeader message, String name) { - message.removeHeader(name); + public static void removeHeader(HttpMessage message, String name) { + message.headers().remove(name); } /** * Removes all headers from the specified message. */ - public static void clearHeaders(HttpHeader message) { - message.clearHeaders(); + public static void clearHeaders(HttpMessage message) { + message.headers().clear(); } /** @@ -622,7 +690,7 @@ public class HttpHeaders { * @throws NumberFormatException * if there is no such header or the header value is not a number */ - public static int getIntHeader(HttpHeader message, String name) { + public static int getIntHeader(HttpMessage message, String name) { String value = getHeader(message, name); if (value == null) { throw new NumberFormatException("header not found: " + name); @@ -638,7 +706,7 @@ public class HttpHeaders { * @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(HttpHeader message, String name, int defaultValue) { + public static int getIntHeader(HttpMessage message, String name, int defaultValue) { String value = getHeader(message, name); if (value == null) { return defaultValue; @@ -655,23 +723,23 @@ public class HttpHeaders { * 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(HttpHeader message, String name, int value) { - message.setHeader(name, value); + public static void setIntHeader(HttpMessage message, String name, int value) { + message.headers().set(name, value); } /** * 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(HttpHeader message, String name, Iterable values) { - message.setHeader(name, values); + public static void setIntHeader(HttpMessage message, String name, Iterable values) { + message.headers().set(name, values); } /** * Adds a new integer header with the specified name and value. */ - public static void addIntHeader(HttpHeader message, String name, int value) { - message.addHeader(name, value); + public static void addIntHeader(HttpMessage message, String name, int value) { + message.headers().add(name, value); } /** @@ -683,7 +751,7 @@ public class HttpHeaders { * @throws ParseException * if there is no such header or the header value is not a formatted date */ - public static Date getDateHeader(HttpHeader message, String name) throws ParseException { + public static Date getDateHeader(HttpMessage message, String name) throws ParseException { String value = getHeader(message, name); if (value == null) { throw new ParseException("header not found: " + name, 0); @@ -699,7 +767,7 @@ public class HttpHeaders { * @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(HttpHeader message, String name, Date defaultValue) { + public static Date getDateHeader(HttpMessage message, String name, Date defaultValue) { final String value = getHeader(message, name); if (value == null) { return defaultValue; @@ -718,11 +786,11 @@ public class HttpHeaders { * The specified value is formatted as defined in * RFC2616 */ - public static void setDateHeader(HttpHeader message, String name, Date value) { + public static void setDateHeader(HttpMessage message, String name, Date value) { if (value != null) { - message.setHeader(name, new HttpHeaderDateFormat().format(value)); + message.headers().set(name, new HttpHeaderDateFormat().format(value)); } else { - message.setHeader(name, null); + message.headers().set(name, null); } } @@ -732,8 +800,8 @@ public class HttpHeaders { * The specified values are formatted as defined in * RFC2616 */ - public static void setDateHeader(HttpHeader message, String name, Iterable values) { - message.setHeader(name, values); + public static void setDateHeader(HttpMessage message, String name, Iterable values) { + message.headers().set(name, values); } /** @@ -741,13 +809,13 @@ public class HttpHeaders { * value is formatted as defined in * RFC2616 */ - public static void addDateHeader(HttpHeader message, String name, Date value) { - message.addHeader(name, value); + public static void addDateHeader(HttpMessage message, String name, Date value) { + message.headers().add(name, value); } /** * Returns the length of the content. Please note that this value is - * not retrieved from {@link HttpContent#getContent()} but from the + * not retrieved from {@link HttpContent#data()} but from the * {@code "Content-Length"} header, and thus they are independent from each * other. * @@ -757,7 +825,7 @@ public class HttpHeaders { * if the message does not have the {@code "Content-Length"} header * or its value is not a number */ - public static long getContentLength(HttpHeader message) { + public static long getContentLength(HttpMessage message) { String value = getHeader(message, Names.CONTENT_LENGTH); if (value != null) { return Long.parseLong(value); @@ -776,7 +844,7 @@ public class HttpHeaders { /** * Returns the length of the content. Please note that this value is - * not retrieved from {@link HttpContent#getContent()} but from the + * not retrieved from {@link HttpContent#data()} but from the * {@code "Content-Length"} header, and thus they are independent from each * other. * @@ -784,8 +852,8 @@ public class HttpHeaders { * not have the {@code "Content-Length"} header or its value is not * a number */ - public static long getContentLength(HttpHeader message, long defaultValue) { - String contentLength = message.getHeader(Names.CONTENT_LENGTH); + public static long getContentLength(HttpMessage message, long defaultValue) { + String contentLength = message.headers().get(Names.CONTENT_LENGTH); if (contentLength != null) { try { return Long.parseLong(contentLength); @@ -809,20 +877,20 @@ public class HttpHeaders { * Returns the content length of the specified web socket message. If the * specified message is not a web socket message, {@code -1} is returned. */ - private static int getWebSocketContentLength(HttpHeader message) { + private static int getWebSocketContentLength(HttpMessage message) { // WebSockset messages have constant content-lengths. - if (message instanceof HttpRequestHeader) { - HttpRequestHeader req = (HttpRequestHeader) message; - if (HttpMethod.GET.equals(req.getMethod()) && - req.containsHeader(Names.SEC_WEBSOCKET_KEY1) && - req.containsHeader(Names.SEC_WEBSOCKET_KEY2)) { + if (message instanceof HttpRequest) { + HttpRequest req = (HttpRequest) message; + if (HttpMethod.GET.equals(req.method()) && + req.headers().contains(Names.SEC_WEBSOCKET_KEY1) && + req.headers().contains(Names.SEC_WEBSOCKET_KEY2)) { return 8; } - } else if (message instanceof HttpResponseHeader) { - HttpResponseHeader res = (HttpResponseHeader) message; - if (res.getStatus().getCode() == 101 && - res.containsHeader(Names.SEC_WEBSOCKET_ORIGIN) && - res.containsHeader(Names.SEC_WEBSOCKET_LOCATION)) { + } else if (message instanceof HttpResponse) { + HttpResponse res = (HttpResponse) message; + if (res.status().code() == 101 && + res.headers().contains(Names.SEC_WEBSOCKET_ORIGIN) && + res.headers().contains(Names.SEC_WEBSOCKET_LOCATION)) { return 16; } } @@ -834,30 +902,30 @@ public class HttpHeaders { /** * Sets the {@code "Content-Length"} header. */ - public static void setContentLength(HttpHeader message, long length) { - message.setHeader(Names.CONTENT_LENGTH, length); + public static void setContentLength(HttpMessage message, long length) { + message.headers().set(Names.CONTENT_LENGTH, length); } /** * Returns the value of the {@code "Host"} header. */ - public static String getHost(HttpHeader message) { - return message.getHeader(Names.HOST); + public static String getHost(HttpMessage message) { + return message.headers().get(Names.HOST); } /** * Returns the value of the {@code "Host"} header. If there is no such * header, the {@code defaultValue} is returned. */ - public static String getHost(HttpHeader message, String defaultValue) { + public static String getHost(HttpMessage message, String defaultValue) { return getHeader(message, Names.HOST, defaultValue); } /** * Sets the {@code "Host"} header. */ - public static void setHost(HttpHeader message, String value) { - message.setHeader(Names.HOST, value); + public static void setHost(HttpMessage message, String value) { + message.headers().set(Names.HOST, value); } /** @@ -866,7 +934,7 @@ public class HttpHeaders { * @throws ParseException * if there is no such header or the header value is not a formatted date */ - public static Date getDate(HttpHeader message) throws ParseException { + public static Date getDate(HttpMessage message) throws ParseException { return getDateHeader(message, Names.DATE); } @@ -875,18 +943,18 @@ public class HttpHeaders { * header or the header is not a formatted date, the {@code defaultValue} * is returned. */ - public static Date getDate(HttpHeader message, Date defaultValue) { + public static Date getDate(HttpMessage message, Date defaultValue) { return getDateHeader(message, Names.DATE, defaultValue); } /** * Sets the {@code "Date"} header. */ - public static void setDate(HttpHeader message, Date value) { + public static void setDate(HttpMessage message, Date value) { if (value != null) { - message.setHeader(Names.DATE, new HttpHeaderDateFormat().format(value)); + message.headers().set(Names.DATE, new HttpHeaderDateFormat().format(value)); } else { - message.setHeader(Names.DATE, null); + message.headers().set(Names.DATE, null); } } @@ -894,19 +962,19 @@ public class HttpHeaders { * Returns {@code true} if and only if the specified message contains the * {@code "Expect: 100-continue"} header. */ - public static boolean is100ContinueExpected(HttpHeader message) { + public static boolean is100ContinueExpected(HttpMessage message) { // Expect: 100-continue is for requests only. - if (!(message instanceof HttpRequestHeader)) { + if (!(message instanceof HttpRequest)) { return false; } // It works only on HTTP/1.1 or later. - if (message.getProtocolVersion().compareTo(HttpVersion.HTTP_1_1) < 0) { + if (message.protocolVersion().compareTo(HttpVersion.HTTP_1_1) < 0) { return false; } // In most cases, there will be one or zero 'Expect' header. - String value = message.getHeader(Names.EXPECT); + String value = message.headers().get(Names.EXPECT); if (value == null) { return false; } @@ -915,7 +983,7 @@ public class HttpHeaders { } // Multiple 'Expect' headers. Search through them. - for (String v: message.getHeaders(Names.EXPECT)) { + for (String v: message.headers().getAll(Names.EXPECT)) { if (Values.CONTINUE.equalsIgnoreCase(v)) { return true; } @@ -928,7 +996,7 @@ public class HttpHeaders { * If there is any existing {@code "Expect"} header, they are replaced with * the new one. */ - public static void set100ContinueExpected(HttpHeader message) { + public static void set100ContinueExpected(HttpMessage message) { set100ContinueExpected(message, true); } @@ -939,20 +1007,20 @@ public class HttpHeaders { * {@code "Expect"} headers are removed. Otherwise, all {@code "Expect"} * headers are removed completely. */ - public static void set100ContinueExpected(HttpHeader message, boolean set) { + public static void set100ContinueExpected(HttpMessage message, boolean set) { if (set) { - message.setHeader(Names.EXPECT, Values.CONTINUE); + message.headers().set(Names.EXPECT, Values.CONTINUE); } else { - message.removeHeader(Names.EXPECT); + message.headers().remove(Names.EXPECT); } } /** * Set the headers on the dst like they are set on the src */ - public static void setHeaders(HttpHeader src, HttpHeader dst) { - for (String name: src.getHeaderNames()) { - dst.setHeader(name, src.getHeaders(name)); + public static void setHeaders(HttpMessage src, HttpMessage dst) { + for (String name: src.headers().names()) { + dst.headers().set(name, src.headers().getAll(name)); } } /** @@ -1065,13 +1133,13 @@ public class HttpHeaders { } /** - * Checks to see if the transfer encoding in a specified {@link HttpHeader} is chunked + * Checks to see if the transfer encoding in a specified {@link HttpMessage} is chunked * * @param message The message to check * @return True if transfer encoding is chunked, otherwise false */ - public static boolean isTransferEncodingChunked(HttpHeader message) { - List transferEncodingHeaders = message.getHeaders(Names.TRANSFER_ENCODING); + public static boolean isTransferEncodingChunked(HttpMessage message) { + List transferEncodingHeaders = message.headers().getAll(Names.TRANSFER_ENCODING); if (transferEncodingHeaders.isEmpty()) { return false; } @@ -1084,322 +1152,167 @@ public class HttpHeaders { return false; } - public static void removeTransferEncodingChunked(HttpHeader m) { - List values = m.getHeaders(Names.TRANSFER_ENCODING); + public static void removeTransferEncodingChunked(HttpMessage m) { + List values = m.headers().getAll(Names.TRANSFER_ENCODING); values.remove(Values.CHUNKED); if (values.isEmpty()) { - m.removeHeader(Names.TRANSFER_ENCODING); + m.headers().remove(Names.TRANSFER_ENCODING); } else { - m.setHeader(Names.TRANSFER_ENCODING, values); + m.headers().set(Names.TRANSFER_ENCODING, values); } } - public static void setTransferEncodingChunked(HttpHeader m) { + public static void setTransferEncodingChunked(HttpMessage m) { addHeader(m, Names.TRANSFER_ENCODING, Values.CHUNKED); removeHeader(m, Names.CONTENT_LENGTH); } - public static boolean isContentLengthSet(HttpHeader m) { - List contentLength = m.getHeaders(Names.CONTENT_LENGTH); + public static boolean isContentLengthSet(HttpMessage m) { + List contentLength = m.headers().getAll(Names.CONTENT_LENGTH); return !contentLength.isEmpty(); } - private static final int BUCKET_SIZE = 17; + protected HttpHeaders() { } - 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; + /** + * Returns the value of a header with the specified name. If there are + * more than one values for the specified name, the first value is returned. + * + * @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); + + /** + * Returns the values of headers with the specified name + * + * @param name The name of the headers to search + * @return A {@link List} of header values which will be empty if no values + * are found + */ + public abstract List getAll(String name); + + /** + * Returns the all headers that this message contains. + * + * @return A {@link List} of the header name-value entries, which will be + * empty if no pairs are found + */ + public abstract List> entries(); + + /** + * Checks to see if there is a header with the specified name + * + * @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); + + /** + * Checks if no header exists. + */ + public abstract boolean isEmpty(); + + /** + * Gets a {@link Set} of all header names that this message contains + * + * @return A {@link Set} of all header names + */ + public abstract Set names(); + + /** + * Adds a new header with the specified name and value. + * + * If the specified value is not a {@link String}, it is converted + * into a {@link String} by {@link Object#toString()}, except in the cases + * of {@link Date} and {@link Calendar}, which are formatted to the date + * format defined in RFC2616. + * + * @param name The name of the header being added + * @param value The value of the header being added + */ + public abstract void add(String name, Object value); + + /** + * Adds a new header with the specified name and values. + * + * This method can be represented approximately as the following code: + *
+     * for (Object v: values) {
+     *     if (v == null) {
+     *         break;
+     *     }
+     *     headers.add(name, v);
+     * }
+     * 
+ * + * @param name The name of the headers being set + * @param values The values of the headers being set + */ + public abstract void add(String name, Iterable values); + + public void add(HttpHeaders headers) { + if (headers == null) { + throw new NullPointerException("headers"); } - - if (h > 0) { - return h; - } else if (h == Integer.MIN_VALUE) { - return Integer.MAX_VALUE; - } else { - return -h; + for (Map.Entry e: headers) { + add(e.getKey(), e.getValue()); } } - private static boolean eq(String name1, String name2) { - int nameLen = name1.length(); - if (nameLen != name2.length()) { - return false; + /** + * Sets a header with the specified name and value. + * + * If there is an existing header with the same name, it is removed. + * If the specified value is not a {@link String}, it is converted into a + * {@link String} by {@link Object#toString()}, except for {@link Date} + * and {@link Calendar}, which are formatted to the date format defined in + * RFC2616. + * + * @param name The name of the header being set + * @param value The value of the header being set + */ + public abstract void set(String name, Object value); + + /** + * Sets a header with the specified name and values. + * + * If there is an existing header with the same name, it is removed. + * This method can be represented approximately as the following code: + *
+     * headers.remove(name);
+     * for (Object v: values) {
+     *     if (v == null) {
+     *         break;
+     *     }
+     *     headers.add(name, v);
+     * }
+     * 
+ * + * @param name The name of the headers being set + * @param values The values of the headers being set + */ + public abstract void set(String name, Iterable values); + + public void set(HttpHeaders headers) { + if (headers == null) { + throw new NullPointerException("headers"); } - - for (int i = nameLen - 1; i >= 0; i --) { - char c1 = name1.charAt(i); - char c2 = name2.charAt(i); - if (c1 != c2) { - if (c1 >= 'A' && c1 <= 'Z') { - c1 += 32; - } - if (c2 >= 'A' && c2 <= 'Z') { - c2 += 32; - } - if (c1 != c2) { - return false; - } - } - } - return true; - } - - 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); - - HttpHeaders() { - head.before = head.after = head; - } - - void validateHeaderName0(String headerName) { - validateHeaderName(headerName); - } - - void addHeader(final String name, final Object value) { - validateHeaderName0(name); - String strVal = toString(value); - validateHeaderValue(strVal); - int h = hash(name); - int i = index(h); - addHeader0(h, i, name, strVal); - } - - private void addHeader0(int h, int i, final String name, final String value) { - // Update the hash table. - HeaderEntry e = entries[i]; - HeaderEntry newEntry; - entries[i] = newEntry = new HeaderEntry(h, name, value); - newEntry.next = e; - - // Update the linked list. - newEntry.addBefore(head); - } - - void removeHeader(final String name) { - if (name == null) { - throw new NullPointerException("name"); - } - int h = hash(name); - int i = index(h); - removeHeader0(h, i, name); - } - - private void removeHeader0(int h, int i, String name) { - HeaderEntry e = entries[i]; - if (e == null) { - return; - } - - for (;;) { - if (e.hash == h && eq(name, e.key)) { - e.remove(); - HeaderEntry next = e.next; - if (next != null) { - entries[i] = next; - e = next; - } else { - entries[i] = null; - return; - } - } else { - break; - } - } - - for (;;) { - HeaderEntry next = e.next; - if (next == null) { - break; - } - if (next.hash == h && eq(name, next.key)) { - e.next = next.next; - next.remove(); - } else { - e = next; - } + clear(); + for (Map.Entry e: headers) { + add(e.getKey(), e.getValue()); } } - void setHeader(final String name, final Object value) { - validateHeaderName0(name); - String strVal = toString(value); - validateHeaderValue(strVal); - int h = hash(name); - int i = index(h); - removeHeader0(h, i, name); - addHeader0(h, i, name, strVal); - } + /** + * Removes the header with the specified name. + * + * @param name The name of the header to remove + */ + public abstract void remove(String name); - void setHeader(final String name, final Iterable values) { - if (values == null) { - throw new NullPointerException("values"); - } - - validateHeaderName0(name); - - int h = hash(name); - int i = index(h); - - removeHeader0(h, i, name); - for (Object v: values) { - if (v == null) { - break; - } - String strVal = toString(v); - validateHeaderValue(strVal); - addHeader0(h, i, name, strVal); - } - } - - void clearHeaders() { - for (int i = 0; i < entries.length; i ++) { - entries[i] = null; - } - head.before = head.after = head; - } - - String getHeader(final String name) { - if (name == null) { - throw new NullPointerException("name"); - } - - int h = hash(name); - int i = index(h); - HeaderEntry e = entries[i]; - while (e != null) { - if (e.hash == h && eq(name, e.key)) { - return e.value; - } - - e = e.next; - } - return null; - } - - List getHeaders(final String name) { - if (name == null) { - throw new NullPointerException("name"); - } - - LinkedList values = new LinkedList(); - - int h = hash(name); - int i = index(h); - HeaderEntry e = entries[i]; - while (e != null) { - if (e.hash == h && eq(name, e.key)) { - values.addFirst(e.value); - } - e = e.next; - } - return values; - } - - List> getHeaders() { - List> all = - new LinkedList>(); - - HeaderEntry e = head.after; - while (e != head) { - all.add(e); - e = e.after; - } - return all; - } - - boolean containsHeader(String name) { - return getHeader(name) != null; - } - - Set getHeaderNames() { - - Set names = new TreeSet(String.CASE_INSENSITIVE_ORDER); - - HeaderEntry e = head.after; - while (e != head) { - names.add(e.key); - e = e.after; - } - return names; - } - - private static String toString(Object value) { - if (value == null) { - return null; - } - if (value instanceof String) { - return (String) value; - } - if (value instanceof Number) { - return value.toString(); - } - if (value instanceof Date) { - return new HttpHeaderDateFormat().format((Date) value); - } - if (value instanceof Calendar) { - return new HttpHeaderDateFormat().format(((Calendar) value).getTime()); - } - return value.toString(); - } - - private static final class HeaderEntry implements Map.Entry { - final int hash; - final String key; - String value; - HeaderEntry next; - HeaderEntry before, after; - - HeaderEntry(int hash, String key, String value) { - this.hash = hash; - this.key = key; - this.value = value; - } - - void remove() { - before.after = after; - after.before = before; - } - - void addBefore(HeaderEntry e) { - after = e; - before = e.before; - before.after = this; - after.before = this; - } - - @Override - public String getKey() { - return key; - } - - @Override - public String getValue() { - return value; - } - - @Override - public String setValue(String value) { - if (value == null) { - throw new NullPointerException("value"); - } - validateHeaderValue(value); - String oldValue = this.value; - this.value = value; - return oldValue; - } - - @Override - public String toString() { - return key + '=' + value; - } - } + /** + * Removes all headers from this {@link HttpMessage}. + */ + public abstract void clear(); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessage.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessage.java index 6ffacf1f3e..7d05319c60 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessage.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 The Netty Project + * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -15,9 +15,28 @@ */ package io.netty.handler.codec.http; + /** - * Combines {@link HttpMessage} and {@link LastHttpContent} into one - * message. So it represent a complete http message. + * An interface that defines a HTTP message, providing common properties for + * {@link HttpRequest} and {@link HttpResponse}. + * @see HttpResponse + * @see HttpRequest + * @see HttpHeaders + * + * @apiviz.landmark + * @apiviz.has io.netty.handler.codec.http.HttpChunk oneway - - is followed by */ -public interface HttpMessage extends HttpHeader, LastHttpContent { +public interface HttpMessage extends HttpObject { + + /** + * Returns the protocol version of this {@link HttpMessage} + * + * @return The protocol version + */ + HttpVersion protocolVersion(); + + /** + * Returns the headers of this message. + */ + HttpHeaders headers(); } 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 31b3c402d6..93051dafdc 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 @@ -154,13 +154,13 @@ public class HttpMethod implements Comparable { /** * Returns the name of this method. */ - public String getName() { + public String name() { return name; } @Override public int hashCode() { - return getName().hashCode(); + return name().hashCode(); } @Override @@ -170,16 +170,16 @@ public class HttpMethod implements Comparable { } HttpMethod that = (HttpMethod) o; - return getName().equals(that.getName()); + return name().equals(that.name()); } @Override public String toString() { - return getName(); + return name(); } @Override public int compareTo(HttpMethod o) { - return getName().compareTo(o.getName()); + return name().compareTo(o.name()); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObject.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObject.java index 5261825564..f013726433 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObject.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObject.java @@ -18,6 +18,14 @@ package io.netty.handler.codec.http; import io.netty.handler.codec.DecoderResult; public interface HttpObject { - DecoderResult getDecoderResult(); - void setDecoderResult(DecoderResult result); + /** + * Returns the result of decoding this message. + */ + DecoderResult decoderResult(); + + /** + * Updates the result of decoding this message. This method is supposed to be invoked by {@link HttpObjectDecoder}. + * Do not call this method unless you know what you are doing. + */ + void updateDecoderResult(DecoderResult result); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java index da8c2b06d3..028da502ec 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java @@ -15,7 +15,6 @@ */ package io.netty.handler.codec.http; -import static io.netty.handler.codec.http.HttpHeaders.*; import io.netty.buffer.ByteBuf; import io.netty.buffer.CompositeByteBuf; import io.netty.buffer.Unpooled; @@ -29,9 +28,11 @@ import io.netty.util.CharsetUtil; import java.util.Map.Entry; +import static io.netty.handler.codec.http.HttpHeaders.*; + /** - * A {@link ChannelHandler} that aggregates an {@link HttpHeader} - * and its following {@link HttpContent}s into a single {@link HttpHeader} with + * A {@link ChannelHandler} that aggregates an {@link HttpMessage} + * and its following {@link HttpContent}s into a single {@link HttpMessage} with * no following {@link HttpContent}s. It is useful when you don't want to take * care of HTTP messages whose transfer encoding is 'chunked'. Insert this * handler after {@link HttpObjectDecoder} in the {@link ChannelPipeline}: @@ -53,7 +54,7 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { "HTTP/1.1 100 Continue\r\n\r\n", CharsetUtil.US_ASCII); private final int maxContentLength; - private HttpMessage currentMessage; + private FullHttpMessage currentMessage; private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS; private ChannelHandlerContext ctx; @@ -111,10 +112,12 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { @Override protected Object decode(ChannelHandlerContext ctx, HttpObject msg) throws Exception { - HttpMessage currentMessage = this.currentMessage; + FullHttpMessage currentMessage = this.currentMessage; - if (msg instanceof HttpHeader) { - HttpHeader m = (HttpHeader) msg; + if (msg instanceof HttpMessage) { + assert currentMessage == null; + + HttpMessage m = (HttpMessage) msg; // Handle the 'Expect: 100-continue' header if necessary. // TODO: Respond with 413 Request Entity Too Large @@ -125,41 +128,40 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { ctx.write(CONTINUE.duplicate()); } - if (!m.getDecoderResult().isSuccess()) { + if (!m.decoderResult().isSuccess()) { removeTransferEncodingChunked(m); this.currentMessage = null; return m; } - if (msg instanceof HttpRequestHeader) { - HttpRequestHeader header = (HttpRequestHeader) msg; - this.currentMessage = new DefaultHttpRequest(header.getProtocolVersion(), - header.getMethod(), header.getUri()); - } else { - HttpResponseHeader header = (HttpResponseHeader) msg; - this.currentMessage = new DefaultHttpResponse(header.getProtocolVersion(), header.getStatus()); + if (msg instanceof HttpRequest) { + HttpRequest header = (HttpRequest) msg; + this.currentMessage = currentMessage = new DefaultFullHttpRequest(header.protocolVersion(), + header.method(), header.uri(), Unpooled.compositeBuffer(maxCumulationBufferComponents)); + } else if (msg instanceof HttpResponse) { + HttpResponse header = (HttpResponse) msg; + this.currentMessage = currentMessage = new DefaultFullHttpResponse( + header.protocolVersion(), header.status(), + Unpooled.compositeBuffer(maxCumulationBufferComponents)); + } else { + throw new Error(); } - for (String name: m.getHeaderNames()) { - this.currentMessage.setHeader(name, m.getHeaders(name)); + + HttpHeaders headers = currentMessage.headers(); + for (String name: m.headers().names()) { + headers.set(name, m.headers().get(name)); } // A streamed message - initialize the cumulative buffer, and wait for incoming chunks. - removeTransferEncodingChunked(m); - this.currentMessage.setContent(Unpooled.compositeBuffer(maxCumulationBufferComponents)); + removeTransferEncodingChunked(currentMessage); return null; } else if (msg instanceof HttpContent) { - // Sanity check - if (currentMessage == null) { - throw new IllegalStateException( - "received " + HttpContent.class.getSimpleName() + - " without " + HttpHeader.class.getSimpleName() + - " or last message's transfer encoding was 'SINGLE'"); - } + assert currentMessage != null; // Merge the received chunk into the content of the current message. HttpContent chunk = (HttpContent) msg; - ByteBuf content = currentMessage.getContent(); + CompositeByteBuf content = (CompositeByteBuf) currentMessage.data(); - if (content.readableBytes() > maxContentLength - chunk.getContent().readableBytes()) { + if (content.readableBytes() > maxContentLength - chunk.data().readableBytes()) { // TODO: Respond with 413 Request Entity Too Large // and discard the traffic or close the connection. // No need to notify the upstream handlers - just log. @@ -170,12 +172,17 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { } // Append the content of the chunk - appendToCumulation(chunk.getContent()); + if (chunk.data().readable()) { + content.addComponent(chunk.data()); + content.writerIndex(content.writerIndex() + chunk.data().readableBytes()); + } else { + chunk.free(); + } final boolean last; - if (!chunk.getDecoderResult().isSuccess()) { - currentMessage.setDecoderResult( - DecoderResult.partialFailure(chunk.getDecoderResult().cause())); + if (!chunk.decoderResult().isSuccess()) { + currentMessage.updateDecoderResult( + DecoderResult.partialFailure(chunk.decoderResult().cause())); last = true; } else { last = msg instanceof LastHttpContent; @@ -187,13 +194,13 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { // Merge trailing headers into the message. if (chunk instanceof LastHttpContent) { LastHttpContent trailer = (LastHttpContent) chunk; - for (Entry header: trailer.getHeaders()) { - currentMessage.setHeader(header.getKey(), header.getValue()); + for (Entry header: trailer.trailingHeaders()) { + currentMessage.headers().add(header.getKey(), header.getValue()); } } // Set the 'Content-Length' header. - currentMessage.setHeader( + currentMessage.headers().set( HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(content.readableBytes())); @@ -203,21 +210,12 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { return null; } } else { - throw new IllegalStateException( - "Only " + HttpHeader.class.getSimpleName() + " and " + - HttpContent.class.getSimpleName() + " are accepted: " + msg.getClass().getName()); + throw new Error(); } } - private void appendToCumulation(ByteBuf input) { - CompositeByteBuf cumulation = (CompositeByteBuf) currentMessage.getContent(); - cumulation.addComponent(input); - cumulation.writerIndex(cumulation.capacity()); - } - @Override public void beforeAdd(ChannelHandlerContext ctx) throws Exception { this.ctx = ctx; } - } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java index 7b66ec459f..cc92af1b26 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java @@ -26,7 +26,7 @@ import io.netty.handler.codec.TooLongFrameException; import java.util.List; /** - * Decodes {@link ByteBuf}s into {@link HttpHeader}s and + * Decodes {@link ByteBuf}s into {@link HttpMessage}s and * {@link HttpContent}s. * *

Parameters that prevents excessive memory consumption

@@ -59,7 +59,7 @@ import java.util.List; * * If the content of an HTTP message is greater than {@code maxChunkSize} or * the transfer encoding of the HTTP message is 'chunked', this decoder - * generates one {@link HttpHeader} instance and its following + * generates one {@link HttpMessage} instance and its following * {@link HttpContent}s per single HTTP message to avoid excessive memory * consumption. For example, the following HTTP message: *
@@ -76,7 +76,7 @@ import java.util.List;
  * 
* triggers {@link HttpRequestDecoder} to generate 3 objects: *
    - *
  1. An {@link HttpRequestHeader},
  2. + *
  3. An {@link HttpRequest},
  4. *
  5. The first {@link HttpContent} whose content is {@code 'abcdefghijklmnopqrstuvwxyz'},
  6. *
  7. The second {@link LastHttpContent} whose content is {@code '1234567890abcdef'}, which marks * the end of the content.
  8. @@ -103,7 +103,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder maxChunkSize || HttpHeaders.is100ContinueExpected(message)) { - // Generate HttpMessage first. HttpChunks will follow. + // Generate FullHttpMessage first. HttpChunks will follow. checkpoint(State.READ_FIXED_LENGTH_CONTENT_AS_CHUNKS); // chunkSize will be decreased as the READ_FIXED_LENGTH_CONTENT_AS_CHUNKS // state reads data chunk by chunk. @@ -221,7 +221,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder maxChunkSize || HttpHeaders.is100ContinueExpected(message)) { - // Generate HttpMessage first. HttpChunks will follow. + // Generate FullHttpMessage first. HttpChunks will follow. checkpoint(State.READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS); return message; } @@ -396,10 +396,10 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder= 100 && code < 200) { - if (code == 101 && !res.containsHeader(HttpHeaders.Names.SEC_WEBSOCKET_ACCEPT)) { + if (code == 101 && !res.headers().contains(HttpHeaders.Names.SEC_WEBSOCKET_ACCEPT)) { // It's Hixie 76 websocket handshake response return false; } @@ -423,12 +423,12 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder current = trailer.getHeaders(lastHeader); + List current = trailer.trailingHeaders().getAll(lastHeader); if (!current.isEmpty()) { int lastPos = current.size() - 1; String newString = current.get(lastPos) + line.trim(); @@ -558,7 +558,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoderExtensibility @@ -38,9 +39,14 @@ import java.util.Map; * implement all abstract methods properly. * @apiviz.landmark */ -public abstract class HttpObjectEncoder extends MessageToByteEncoder { +public abstract class HttpObjectEncoder extends MessageToByteEncoder { - private boolean chunked; + private static final int ST_INIT = 0; + private static final int ST_CONTENT_NON_CHUNK = 1; + private static final int ST_CONTENT_CHUNK = 2; + + @SuppressWarnings("RedundantFieldInitialization") + private int state = ST_INIT; /** * Creates a new instance. @@ -49,38 +55,44 @@ public abstract class HttpObjectEncoder extends MessageToB super(HttpObject.class); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception { - if (msg instanceof HttpHeader) { - HttpHeader m = (HttpHeader) msg; - chunked = HttpHeaders.isTransferEncodingChunked(m); - // Encode the message. - out.markWriterIndex(); + if (msg instanceof HttpMessage) { + if (state != ST_INIT) { + throw new IllegalStateException("unexpected message type: " + msg.getClass().getSimpleName()); + } + HttpMessage m = (HttpMessage) msg; + + // Encode the message. encodeInitialLine(out, (H) m); encodeHeaders(out, m); out.writeByte(CR); out.writeByte(LF); + + state = HttpHeaders.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK; } if (msg instanceof HttpContent) { - HttpContent chunk = (HttpContent) msg; + if (state == ST_INIT) { + throw new IllegalStateException("unexpected message type: " + msg.getClass().getSimpleName()); + } + + HttpContent chunk = (HttpContent) msg; + ByteBuf content = chunk.data(); + int contentLength = content.readableBytes(); + + if (state == ST_CONTENT_NON_CHUNK) { + if (contentLength > 0) { + out.writeBytes(content, content.readerIndex(), content.readableBytes()); + } - if (!chunked) { - ByteBuf content = chunk.getContent(); - out.writeBytes(content, content.readerIndex(), content.readableBytes()); - } else { if (chunk instanceof LastHttpContent) { - out.writeByte((byte) '0'); - out.writeByte(CR); - out.writeByte(LF); - encodeTrailingHeaders(out, (LastHttpContent) chunk); - out.writeByte(CR); - out.writeByte(LF); - } else { - ByteBuf content = chunk.getContent(); - int contentLength = content.readableBytes(); + state = ST_INIT; + } + } else if (state == ST_CONTENT_CHUNK) { + if (contentLength > 0) { out.writeBytes(copiedBuffer(Integer.toHexString(contentLength), CharsetUtil.US_ASCII)); out.writeByte(CR); out.writeByte(LF); @@ -88,18 +100,30 @@ public abstract class HttpObjectEncoder extends MessageToB out.writeByte(CR); out.writeByte(LF); } + + if (chunk instanceof LastHttpContent) { + out.writeByte((byte) '0'); + out.writeByte(CR); + out.writeByte(LF); + encodeTrailingHeaders(out, (LastHttpContent) chunk); + out.writeByte(CR); + out.writeByte(LF); + state = ST_INIT; + } + } else { + throw new Error(); } } } - private static void encodeHeaders(ByteBuf buf, HttpHeader message) { - for (Map.Entry h: message.getHeaders()) { + private static void encodeHeaders(ByteBuf buf, HttpMessage message) { + for (Map.Entry h: message.headers()) { encodeHeader(buf, h.getKey(), h.getValue()); } } private static void encodeTrailingHeaders(ByteBuf buf, LastHttpContent trailer) { - for (Map.Entry h: trailer.getHeaders()) { + for (Map.Entry h: trailer.trailingHeaders()) { encodeHeader(buf, h.getKey(), h.getValue()); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequest.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequest.java index 1a43e3811e..555c744a3b 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequest.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 The Netty Project + * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -15,9 +15,35 @@ */ package io.netty.handler.codec.http; + /** - * Combinate the {@link HttpRequestHeader} and {@link HttpMessage}, so the request is a complete HTTP - * request. + * An HTTP request. + * + *

    Accessing Query Parameters and Cookie

    + *

    + * Unlike the Servlet API, a query string is constructed and decomposed by + * {@link QueryStringEncoder} and {@link QueryStringDecoder}. {@link Cookie} + * support is also provided separately via {@link CookieDecoder}, {@link ClientCookieEncoder}, + * and {@link @ServerCookieEncoder}. + * + * @see HttpResponse + * @see ClientCookieEncoder + * @see ServerCookieEncoder + * @see CookieDecoder */ -public interface HttpRequest extends HttpRequestHeader, HttpMessage { +public interface HttpRequest extends HttpMessage { + + /** + * Returns the {@link HttpMethod} of this {@link HttpRequest}. + * + * @return The {@link HttpMethod} of this {@link HttpRequest} + */ + HttpMethod method(); + + /** + * Returns the requested URI (or alternatively, path) + * + * @return The URI being requested + */ + String uri(); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestDecoder.java index e0355a2c3e..5b53ba28b8 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestDecoder.java @@ -21,7 +21,7 @@ import io.netty.handler.codec.TooLongFrameException; /** - * Decodes {@link ByteBuf}s into {@link HttpRequestHeader}s and {@link HttpContent}s. + * Decodes {@link ByteBuf}s into {@link HttpRequest}s and {@link HttpContent}s. * *

    Parameters that prevents excessive memory consumption

    * @@ -71,14 +71,14 @@ public class HttpRequestDecoder extends HttpObjectDecoder { } @Override - protected HttpHeader createMessage(String[] initialLine) throws Exception { - return new DefaultHttpRequestHeader( + protected HttpMessage createMessage(String[] initialLine) throws Exception { + return new DefaultHttpRequest( HttpVersion.valueOf(initialLine[2]), HttpMethod.valueOf(initialLine[0]), initialLine[1]); } @Override - protected HttpHeader createInvalidMessage() { - return new DefaultHttpRequestHeader(HttpVersion.HTTP_1_0, HttpMethod.GET, "/bad-request"); + protected HttpMessage createInvalidMessage() { + return new DefaultHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.GET, "/bad-request"); } @Override 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 56accf67f5..ae308316a1 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 @@ -15,25 +15,31 @@ */ package io.netty.handler.codec.http; -import static io.netty.handler.codec.http.HttpConstants.*; import io.netty.buffer.ByteBuf; import io.netty.util.CharsetUtil; +import static io.netty.handler.codec.http.HttpConstants.*; + /** - * Encodes an {@link HttpRequestHeader} or an {@link HttpContent} into + * Encodes an {@link HttpRequest} or an {@link HttpContent} into * a {@link ByteBuf}. */ -public class HttpRequestEncoder extends HttpObjectEncoder { +public class HttpRequestEncoder extends HttpObjectEncoder { private static final char SLASH = '/'; @Override - protected void encodeInitialLine(ByteBuf buf, HttpRequestHeader request) throws Exception { - buf.writeBytes(request.getMethod().toString().getBytes(CharsetUtil.US_ASCII)); + public boolean isEncodable(Object msg) throws Exception { + return super.isEncodable(msg) && !(msg instanceof HttpResponse); + } + + @Override + protected void encodeInitialLine(ByteBuf buf, HttpRequest request) throws Exception { + buf.writeBytes(request.method().toString().getBytes(CharsetUtil.US_ASCII)); buf.writeByte(SP); // Add / as absolute path if no is present. // See http://tools.ietf.org/html/rfc2616#section-5.1.2 - String uri = request.getUri(); + String uri = request.uri(); int start = uri.indexOf("://"); if (start != -1) { int startIndex = start + 3; @@ -44,7 +50,7 @@ public class HttpRequestEncoder extends HttpObjectEncoder { buf.writeBytes(uri.getBytes("UTF-8")); buf.writeByte(SP); - buf.writeBytes(request.getProtocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(request.protocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); buf.writeByte(CR); buf.writeByte(LF); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestHeader.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestHeader.java deleted file mode 100644 index 54d40c712e..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestHeader.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.http; - - -/** - * An HTTP request. - * - *

    Accessing Query Parameters and Cookie

    - *

    - * Unlike the Servlet API, a query string is constructed and decomposed by - * {@link QueryStringEncoder} and {@link QueryStringDecoder}. {@link Cookie} - * support is also provided separately via {@link CookieDecoder}, {@link ClientCookieEncoder}, - * and {@link @ServerCookieEncoder}. - * - * @see HttpResponseHeader - * @see ClientCookieEncoder - * @see ServerCookieEncoder - * @see CookieDecoder - */ -public interface HttpRequestHeader extends HttpHeader { - - /** - * Returns the {@link HttpMethod} of this {@link HttpRequestHeader}. - * - * @return The {@link HttpMethod} of this {@link HttpRequestHeader} - */ - HttpMethod getMethod(); - - /** - * Sets the {@link HttpMethod} of this {@link HttpRequestHeader}. - * - * @param method The {@link HttpMethod} to set - */ - void setMethod(HttpMethod method); - - /** - * Returns the requested URI (or alternatively, path) - * - * @return The URI being requested - */ - String getUri(); - - /** - * Sets the URI (or alternatively, path) being requested. - * - * @param uri The URI being requested - */ - void setUri(String uri); -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponse.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponse.java index 673b6ec842..42df39fd96 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponse.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 The Netty Project + * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -15,9 +15,26 @@ */ package io.netty.handler.codec.http; + /** - * Combination of a {@link HttpResponseHeader} and {@link HttpMessage}. - * So it represent a complete http response. + * An HTTP response. + * + *

    Accessing Cookies

    + *

    + * Unlike the Servlet API, {@link Cookie} support is provided separately via {@link CookieDecoder}, + * {@link ClientCookieEncoder}, and {@link ServerCookieEncoder}. + * + * @see HttpRequest + * @see CookieDecoder + * @see ClientCookieEncoder + * @see ServerCookieEncoder */ -public interface HttpResponse extends HttpResponseHeader, HttpMessage { +public interface HttpResponse extends HttpMessage { + + /** + * Returns the status of this {@link HttpResponse}. + * + * @return The {@link HttpResponseStatus} of this {@link HttpResponse} + */ + HttpResponseStatus status(); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseDecoder.java index 75e292e215..b9831ec282 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseDecoder.java @@ -21,7 +21,7 @@ import io.netty.handler.codec.TooLongFrameException; /** - * Decodes {@link ByteBuf}s into {@link HttpResponseHeader}s and + * Decodes {@link ByteBuf}s into {@link HttpResponse}s and * {@link HttpContent}s. * *

    Parameters that prevents excessive memory consumption

    @@ -59,7 +59,7 @@ import io.netty.handler.codec.TooLongFrameException; * request does not have any content even if there is Content-Length * header. Because {@link HttpResponseDecoder} is not able to determine if the * response currently being decoded is associated with a HEAD request, - * you must override {@link #isContentAlwaysEmpty(HttpHeader)} to return + * you must override {@link #isContentAlwaysEmpty(HttpMessage)} to return * true for the response of the HEAD request. *

    * If you are writing an HTTP client that issues a HEAD request, @@ -102,15 +102,15 @@ public class HttpResponseDecoder extends HttpObjectDecoder { } @Override - protected HttpHeader createMessage(String[] initialLine) { - return new DefaultHttpResponseHeader( + protected HttpMessage createMessage(String[] initialLine) { + return new DefaultHttpResponse( HttpVersion.valueOf(initialLine[0]), new HttpResponseStatus(Integer.valueOf(initialLine[1]), initialLine[2])); } @Override - protected HttpHeader createInvalidMessage() { - return new DefaultHttpResponseHeader(HttpVersion.HTTP_1_0, UNKNOWN_STATUS); + protected HttpMessage createInvalidMessage() { + return new DefaultHttpResponse(HttpVersion.HTTP_1_0, UNKNOWN_STATUS); } @Override 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 73b80e2beb..caf79a5c3c 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 @@ -15,23 +15,29 @@ */ package io.netty.handler.codec.http; -import static io.netty.handler.codec.http.HttpConstants.*; import io.netty.buffer.ByteBuf; import io.netty.util.CharsetUtil; +import static io.netty.handler.codec.http.HttpConstants.*; + /** - * Encodes an {@link HttpResponseHeader} or an {@link HttpContent} into + * Encodes an {@link HttpResponse} or an {@link HttpContent} into * a {@link ByteBuf}. */ -public class HttpResponseEncoder extends HttpObjectEncoder { +public class HttpResponseEncoder extends HttpObjectEncoder { @Override - protected void encodeInitialLine(ByteBuf buf, HttpResponseHeader response) throws Exception { - buf.writeBytes(response.getProtocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); + public boolean isEncodable(Object msg) throws Exception { + return super.isEncodable(msg) && !(msg instanceof HttpRequest); + } + + @Override + protected void encodeInitialLine(ByteBuf buf, HttpResponse response) throws Exception { + buf.writeBytes(response.protocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); buf.writeByte(SP); - buf.writeBytes(String.valueOf(response.getStatus().getCode()).getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(String.valueOf(response.status().code()).getBytes(CharsetUtil.US_ASCII)); buf.writeByte(SP); - buf.writeBytes(String.valueOf(response.getStatus().getReasonPhrase()).getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(String.valueOf(response.status().reasonPhrase()).getBytes(CharsetUtil.US_ASCII)); buf.writeByte(CR); buf.writeByte(LF); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseHeader.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseHeader.java deleted file mode 100644 index 86644d023d..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpResponseHeader.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.handler.codec.http; - - -/** - * An HTTP response. - * - *

    Accessing Cookies

    - *

    - * Unlike the Servlet API, {@link Cookie} support is provided separately via {@link CookieDecoder}, - * {@link ClientCookieEncoder}, and {@link ServerCookieEncoder}. - * - * @see HttpRequestHeader - * @see CookieDecoder - * @see ClientCookieEncoder - * @see ServerCookieEncoder - */ -public interface HttpResponseHeader extends HttpHeader { - - /** - * Returns the status of this {@link HttpResponseHeader}. - * - * @return The {@link HttpResponseStatus} of this {@link HttpResponseHeader} - */ - HttpResponseStatus getStatus(); - - /** - * Sets the status of this {@link HttpResponseHeader} - * - * @param status The {@link HttpResponseStatus} to use - */ - void setStatus(HttpResponseStatus status); -} 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 c74c5150a3..cd3060fd94 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 @@ -447,20 +447,20 @@ public class HttpResponseStatus implements Comparable { /** * Returns the code of this status. */ - public int getCode() { + public int code() { return code; } /** * Returns the reason phrase of this status. */ - public String getReasonPhrase() { + public String reasonPhrase() { return reasonPhrase; } @Override public int hashCode() { - return getCode(); + return code(); } @Override @@ -469,12 +469,12 @@ public class HttpResponseStatus implements Comparable { return false; } - return getCode() == ((HttpResponseStatus) o).getCode(); + return code() == ((HttpResponseStatus) o).code(); } @Override public int compareTo(HttpResponseStatus o) { - return getCode() - o.getCode(); + return code() - o.code(); } @Override diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/LastHttpContent.java b/codec-http/src/main/java/io/netty/handler/codec/http/LastHttpContent.java index 9fa53eaa16..c72b80eedf 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/LastHttpContent.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/LastHttpContent.java @@ -15,9 +15,9 @@ */ package io.netty.handler.codec.http; -import java.util.List; -import java.util.Map; -import java.util.Set; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.DecoderResult; /** * The last {@link HttpContent} which has trailing headers. @@ -25,68 +25,48 @@ import java.util.Set; public interface LastHttpContent extends HttpContent { /** - * Returns the trailing header value with the specified header name. - * If there are more than one trailing header value for the specified - * header name, the first value is returned. - * - * @return the header value or {@code null} if there is no such header + * The 'end of content' marker in chunked encoding. */ - String getHeader(String name); + LastHttpContent EMPTY_LAST_CONTENT = new LastHttpContent() { - /** - * Returns the trailing header values with the specified header name. - * - * @return the {@link List} of header values. An empty list if there is no - * such header. - */ - List getHeaders(String name); + @Override + public ByteBuf data() { + return Unpooled.EMPTY_BUFFER; + } - /** - * Returns the all header names and values that this trailer contains. - * - * @return the {@link List} of the header name-value pairs. An empty list - * if there is no header in this trailer. - */ - List> getHeaders(); + @Override + public LastHttpContent copy() { + return EMPTY_LAST_CONTENT; + } - /** - * Returns {@code true} if and only if there is a trailing header with - * the specified header name. - */ - boolean containsHeader(String name); + @Override + public HttpHeaders trailingHeaders() { + return HttpHeaders.EMPTY_HEADERS; + } - /** - * Returns the {@link Set} of all trailing header names that this trailer - * contains. - */ - Set getHeaderNames(); + @Override + public DecoderResult decoderResult() { + return DecoderResult.SUCCESS; + } - /** - * Adds a new trailing header with the specified name and value. - */ - void addHeader(String name, Object value); + @Override + public void updateDecoderResult(DecoderResult result) { + throw new UnsupportedOperationException("read only"); + } - /** - * Sets a new trailing header with the specified name and value. - * If there is an existing trailing header with the same name, the existing - * one is removed. - */ - void setHeader(String name, Object value); + @Override + public boolean isFreed() { + return false; + } - /** - * Sets a new trailing header with the specified name and values. - * If there is an existing trailing header with the same name, the existing - * one is removed. - */ - void setHeader(String name, Iterable values); + @Override + public void free() { + // NOOP + } + }; - /** - * Removes the trailing header with the specified name. - */ - void removeHeader(String name); + HttpHeaders trailingHeaders(); - /** - * Removes all trailing headers from this trailer. - */ - void clearHeaders(); + @Override + LastHttpContent copy(); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringDecoder.java index 849cc7396d..45ae7e98a6 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringDecoder.java @@ -54,7 +54,7 @@ import java.util.Map; * @see QueryStringEncoder * * @apiviz.stereotype utility - * @apiviz.has io.netty.handler.codec.http.HttpRequest oneway - - decodes + * @apiviz.has io.netty.handler.codec.http.FullHttpRequest oneway - - decodes */ public class QueryStringDecoder { diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringEncoder.java index 71d8acdb96..510948cf87 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/QueryStringEncoder.java @@ -36,7 +36,7 @@ import java.util.List; * @see QueryStringDecoder * * @apiviz.stereotype utility - * @apiviz.has io.netty.handler.codec.http.HttpRequest oneway - - encodes + * @apiviz.has io.netty.handler.codec.http.FullHttpRequest oneway - - encodes */ public class QueryStringEncoder { diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/ServerCookieEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/ServerCookieEncoder.java index a9907a673f..ad60371dd3 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/ServerCookieEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/ServerCookieEncoder.java @@ -15,19 +15,19 @@ */ package io.netty.handler.codec.http; -import static io.netty.handler.codec.http.CookieEncoderUtil.*; - import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; +import static io.netty.handler.codec.http.CookieEncoderUtil.*; + /** * Encodes server-side {@link Cookie}s into HTTP header values. This encoder can encode * the HTTP cookie version 0, 1, and 2. *

      * // Example
    - * {@link HttpRequestHeader} req = ...;
    + * {@link HttpRequest} req = ...;
      * res.setHeader("Set-Cookie", {@link ServerCookieEncoder}.encode("JSESSIONID", "1234"));
      * 
    * diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java index 208893ce14..b74d97f5b0 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java @@ -15,7 +15,7 @@ */ package io.netty.handler.codec.http.multipart; -import io.netty.handler.codec.http.HttpRequestHeader; +import io.netty.handler.codec.http.HttpRequest; import java.io.IOException; import java.nio.charset.Charset; @@ -46,8 +46,8 @@ public class DefaultHttpDataFactory implements HttpDataFactory { /** * Keep all HttpDatas until cleanAllHttpDatas() is called. */ - private final ConcurrentHashMap> requestFileDeleteMap = - new ConcurrentHashMap>(); + private final ConcurrentHashMap> requestFileDeleteMap = + new ConcurrentHashMap>(); /** * HttpData will be in memory if less than default size (16KB). * The type will be Mixed. @@ -79,7 +79,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory { /** * @return the associated list of Files for the request */ - private List getList(HttpRequestHeader request) { + private List getList(HttpRequest request) { List list = requestFileDeleteMap.get(request); if (list == null) { list = new ArrayList(); @@ -89,7 +89,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory { } @Override - public Attribute createAttribute(HttpRequestHeader request, String name) { + public Attribute createAttribute(HttpRequest request, String name) { if (useDisk) { Attribute attribute = new DiskAttribute(name); List fileToDelete = getList(request); @@ -106,7 +106,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory { } @Override - public Attribute createAttribute(HttpRequestHeader request, String name, String value) { + public Attribute createAttribute(HttpRequest request, String name, String value) { if (useDisk) { Attribute attribute; try { @@ -133,7 +133,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory { } @Override - public FileUpload createFileUpload(HttpRequestHeader request, String name, String filename, + public FileUpload createFileUpload(HttpRequest request, String name, String filename, String contentType, String contentTransferEncoding, Charset charset, long size) { if (useDisk) { @@ -155,7 +155,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory { } @Override - public void removeHttpDataFromClean(HttpRequestHeader request, InterfaceHttpData data) { + public void removeHttpDataFromClean(HttpRequest request, InterfaceHttpData data) { if (data instanceof HttpData) { List fileToDelete = getList(request); fileToDelete.remove(data); @@ -163,7 +163,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory { } @Override - public void cleanRequestHttpDatas(HttpRequestHeader request) { + public void cleanRequestHttpDatas(HttpRequest request) { List fileToDelete = requestFileDeleteMap.remove(request); if (fileToDelete != null) { for (HttpData data: fileToDelete) { @@ -175,7 +175,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory { @Override public void cleanAllHttpDatas() { - for (HttpRequestHeader request : requestFileDeleteMap.keySet()) { + for (HttpRequest request : requestFileDeleteMap.keySet()) { List fileToDelete = requestFileDeleteMap.get(request); if (fileToDelete != null) { for (HttpData data: fileToDelete) { diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpDataFactory.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpDataFactory.java index 8467bcae7f..eceee401d1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpDataFactory.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpDataFactory.java @@ -15,7 +15,7 @@ */ package io.netty.handler.codec.http.multipart; -import io.netty.handler.codec.http.HttpRequestHeader; +import io.netty.handler.codec.http.HttpRequest; import java.nio.charset.Charset; @@ -28,20 +28,20 @@ public interface HttpDataFactory { * @param request associated request * @return a new Attribute with no value */ - Attribute createAttribute(HttpRequestHeader request, String name); + Attribute createAttribute(HttpRequest request, String name); /** * @param request associated request * @return a new Attribute */ - Attribute createAttribute(HttpRequestHeader request, String name, String value); + Attribute createAttribute(HttpRequest request, String name, String value); /** * @param request associated request * @param size the size of the Uploaded file * @return a new FileUpload */ - FileUpload createFileUpload(HttpRequestHeader request, String name, String filename, + FileUpload createFileUpload(HttpRequest request, String name, String filename, String contentType, String contentTransferEncoding, Charset charset, long size); @@ -50,14 +50,14 @@ public interface HttpDataFactory { * is still a temporary one as setup at construction) * @param request associated request */ - void removeHttpDataFromClean(HttpRequestHeader request, InterfaceHttpData data); + void removeHttpDataFromClean(HttpRequest request, InterfaceHttpData data); /** * Remove all InterfaceHttpData from virtual File storage from clean list for the request * * @param request associated request */ - void cleanRequestHttpDatas(HttpRequestHeader request); + void cleanRequestHttpDatas(HttpRequest request); /** * Remove all InterfaceHttpData from virtual File storage from clean list for all requests 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 0077d2ebfb..03ceb69093 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 @@ -16,11 +16,11 @@ package io.netty.handler.codec.http.multipart; import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpConstants; +import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequestHeader; +import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.LastHttpContent; import io.netty.handler.codec.http.multipart.HttpPostBodyUtil.SeekAheadNoBackArrayException; import io.netty.handler.codec.http.multipart.HttpPostBodyUtil.SeekAheadOptimize; @@ -50,7 +50,7 @@ public class HttpPostRequestDecoder { /** * Request to decode */ - private final HttpRequestHeader request; + private final HttpRequest request; /** * Default charset to use @@ -136,7 +136,7 @@ public class HttpPostRequestDecoder { * if the default charset was wrong when decoding or other * errors */ - public HttpPostRequestDecoder(HttpRequestHeader request) throws ErrorDataDecoderException, + public HttpPostRequestDecoder(HttpRequest request) throws ErrorDataDecoderException, IncompatibleDataDecoderException { this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), request, HttpConstants.DEFAULT_CHARSET); } @@ -155,7 +155,7 @@ public class HttpPostRequestDecoder { * if the default charset was wrong when decoding or other * errors */ - public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequestHeader request) throws ErrorDataDecoderException, + public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request) throws ErrorDataDecoderException, IncompatibleDataDecoderException { this(factory, request, HttpConstants.DEFAULT_CHARSET); } @@ -176,7 +176,7 @@ public class HttpPostRequestDecoder { * if the default charset was wrong when decoding or other * errors */ - public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequestHeader request, Charset charset) + public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request, Charset charset) throws ErrorDataDecoderException, IncompatibleDataDecoderException { if (factory == null) { throw new NullPointerException("factory"); @@ -188,15 +188,15 @@ public class HttpPostRequestDecoder { throw new NullPointerException("charset"); } this.request = request; - HttpMethod method = request.getMethod(); + HttpMethod method = request.method(); if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT) || method.equals(HttpMethod.PATCH)) { bodyToDecode = true; } this.charset = charset; this.factory = factory; // Fill default values - if (this.request.containsHeader(HttpHeaders.Names.CONTENT_TYPE)) { - checkMultipart(this.request.getHeader(HttpHeaders.Names.CONTENT_TYPE)); + if (this.request.headers().contains(HttpHeaders.Names.CONTENT_TYPE)) { + checkMultipart(this.request.headers().get(HttpHeaders.Names.CONTENT_TYPE)); } else { isMultipart = false; } @@ -341,7 +341,7 @@ public class HttpPostRequestDecoder { * errors */ public void offer(HttpContent content) throws ErrorDataDecoderException { - ByteBuf chunked = content.getContent(); + ByteBuf chunked = content.data(); if (undecodedChunk == null) { undecodedChunk = chunked; } else { 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 e870385220..ab2807e153 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 @@ -18,11 +18,11 @@ package io.netty.handler.codec.http.multipart; import io.netty.buffer.ByteBuf; import io.netty.buffer.MessageBuf; import io.netty.handler.codec.http.DefaultHttpContent; -import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpConstants; +import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.stream.ChunkedMessageInput; import java.io.File; @@ -49,7 +49,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput /** * Request to encode */ - private final HttpRequest request; + private final FullHttpRequest request; /** * Default charset to use @@ -100,7 +100,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput * @throws ErrorDataEncoderException * if the request is not a POST */ - public HttpPostRequestEncoder(HttpRequest request, boolean multipart) throws ErrorDataEncoderException { + public HttpPostRequestEncoder(FullHttpRequest request, boolean multipart) throws ErrorDataEncoderException { this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), request, multipart, HttpConstants.DEFAULT_CHARSET); } @@ -118,7 +118,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput * @throws ErrorDataEncoderException * if the request is not a POST */ - public HttpPostRequestEncoder(HttpDataFactory factory, HttpRequest request, boolean multipart) + public HttpPostRequestEncoder(HttpDataFactory factory, FullHttpRequest request, boolean multipart) throws ErrorDataEncoderException { this(factory, request, multipart, HttpConstants.DEFAULT_CHARSET); } @@ -138,7 +138,8 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput * @throws ErrorDataEncoderException * if the request is not a POST */ - public HttpPostRequestEncoder(HttpDataFactory factory, HttpRequest request, boolean multipart, Charset charset) + public HttpPostRequestEncoder( + HttpDataFactory factory, FullHttpRequest request, boolean multipart, Charset charset) throws ErrorDataEncoderException { if (factory == null) { throw new NullPointerException("factory"); @@ -149,7 +150,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput if (charset == null) { throw new NullPointerException("charset"); } - if (request.getMethod() != HttpMethod.POST) { + if (request.method() != HttpMethod.POST) { throw new ErrorDataEncoderException("Cannot create a Encoder if not a POST"); } this.request = request; @@ -598,7 +599,7 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput * @throws ErrorDataEncoderException * if the encoding is in error or if the finalize were already done */ - public HttpRequest finalizeRequest() throws ErrorDataEncoderException { + public FullHttpRequest finalizeRequest() throws ErrorDataEncoderException { // Finalize the multipartHttpDatas if (!headerFinalized) { if (isMultipart) { @@ -617,10 +618,10 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput } else { throw new ErrorDataEncoderException("Header already encoded"); } - List contentTypes = request.getHeaders(HttpHeaders.Names.CONTENT_TYPE); - List transferEncoding = request.getHeaders(HttpHeaders.Names.TRANSFER_ENCODING); + List contentTypes = request.headers().getAll(HttpHeaders.Names.CONTENT_TYPE); + List transferEncoding = request.headers().getAll(HttpHeaders.Names.TRANSFER_ENCODING); if (contentTypes != null) { - request.removeHeader(HttpHeaders.Names.CONTENT_TYPE); + request.headers().remove(HttpHeaders.Names.CONTENT_TYPE); for (String contentType : contentTypes) { // "multipart/form-data; boundary=--89421926422648" if (contentType.toLowerCase().startsWith(HttpHeaders.Values.MULTIPART_FORM_DATA)) { @@ -628,17 +629,17 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput } else if (contentType.toLowerCase().startsWith(HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED)) { // ignore } else { - request.addHeader(HttpHeaders.Names.CONTENT_TYPE, contentType); + request.headers().add(HttpHeaders.Names.CONTENT_TYPE, contentType); } } } if (isMultipart) { String value = HttpHeaders.Values.MULTIPART_FORM_DATA + "; " + HttpHeaders.Values.BOUNDARY + '=' + multipartDataBoundary; - request.addHeader(HttpHeaders.Names.CONTENT_TYPE, value); + request.headers().add(HttpHeaders.Names.CONTENT_TYPE, value); } else { // Not multipart - request.addHeader(HttpHeaders.Names.CONTENT_TYPE, HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED); + request.headers().add(HttpHeaders.Names.CONTENT_TYPE, HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED); } // Now consider size for chunk or not long realSize = globalBodySize; @@ -648,25 +649,25 @@ public class HttpPostRequestEncoder implements ChunkedMessageInput realSize -= 1; // last '&' removed iterator = multipartHttpDatas.listIterator(); } - request.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(realSize)); + request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(realSize)); if (realSize > HttpPostBodyUtil.chunkSize || isMultipart) { isChunked = true; if (transferEncoding != null) { - request.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING); + request.headers().remove(HttpHeaders.Names.TRANSFER_ENCODING); for (String v : transferEncoding) { if (v.equalsIgnoreCase(HttpHeaders.Values.CHUNKED)) { // ignore } else { - request.addHeader(HttpHeaders.Names.TRANSFER_ENCODING, v); + request.headers().add(HttpHeaders.Names.TRANSFER_ENCODING, v); } } } HttpHeaders.setTransferEncodingChunked(request); - request.setContent(EMPTY_BUFFER); + request.data().clear(); } else { // get the only one body and set it to the request HttpContent chunk = nextChunk(); - request.setContent(chunk.getContent()); + request.data().clear().writeBytes(chunk.data()); } return request; } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java index c42610a0e3..33b25e5a35 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java @@ -18,7 +18,7 @@ package io.netty.handler.codec.http.websocketx; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.FullHttpResponse; import java.net.URI; import java.util.Map; @@ -148,5 +148,5 @@ public abstract class WebSocketClientHandshaker { * @param response * HTTP response containing the closing handshake details */ - public abstract void finishHandshake(Channel channel, HttpResponse response); + public abstract void finishHandshake(Channel channel, FullHttpResponse response); } 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 9749863253..1a1ddc3087 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 @@ -15,19 +15,18 @@ */ package io.netty.handler.codec.http.websocketx; -import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpHeaders.Values; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequestEncoder; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -142,10 +141,10 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker { } // Format request - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); - request.addHeader(Names.UPGRADE, Values.WEBSOCKET); - request.addHeader(Names.CONNECTION, Values.UPGRADE); - request.addHeader(Names.HOST, wsURL.getHost()); + FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); + request.headers().add(Names.UPGRADE, Values.WEBSOCKET); + request.headers().add(Names.CONNECTION, Values.UPGRADE); + request.headers().add(Names.HOST, wsURL.getHost()); int wsPort = wsURL.getPort(); String originValue = "http://" + wsURL.getHost(); @@ -155,24 +154,24 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker { originValue = originValue + ':' + wsPort; } - request.addHeader(Names.ORIGIN, originValue); - request.addHeader(Names.SEC_WEBSOCKET_KEY1, key1); - request.addHeader(Names.SEC_WEBSOCKET_KEY2, key2); + request.headers().add(Names.ORIGIN, originValue); + request.headers().add(Names.SEC_WEBSOCKET_KEY1, key1); + request.headers().add(Names.SEC_WEBSOCKET_KEY2, key2); String expectedSubprotocol = getExpectedSubprotocol(); if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) { - request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); + request.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); } if (customHeaders != null) { for (Map.Entry e : customHeaders.entrySet()) { - request.addHeader(e.getKey(), e.getValue()); + request.headers().add(e.getKey(), e.getValue()); } } // Set Content-Length to workaround some known defect. // See also: http://www.ietf.org/mail-archive/web/hybi/current/msg02149.html - request.setHeader(Names.CONTENT_LENGTH, key3.length); - request.setContent(Unpooled.copiedBuffer(key3)); + request.headers().set(Names.CONTENT_LENGTH, key3.length); + request.data().writeBytes(key3); ChannelFuture future = channel.write(request); future.addListener(new ChannelFutureListener() { @@ -217,31 +216,31 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker { * @throws WebSocketHandshakeException */ @Override - public void finishHandshake(Channel channel, HttpResponse response) { + public void finishHandshake(Channel channel, FullHttpResponse response) { final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake"); - if (!response.getStatus().equals(status)) { - throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); + if (!response.status().equals(status)) { + throw new WebSocketHandshakeException("Invalid handshake response status: " + response.status()); } - String upgrade = response.getHeader(Names.UPGRADE); + String upgrade = response.headers().get(Names.UPGRADE); if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } - String connection = response.getHeader(Names.CONNECTION); + String connection = response.headers().get(Names.CONNECTION); if (!Values.UPGRADE.equalsIgnoreCase(connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } - byte[] challenge = response.getContent().array(); + byte[] challenge = response.data().array(); if (!Arrays.equals(challenge, expectedChallengeResponseBytes)) { throw new WebSocketHandshakeException("Invalid challenge"); } - String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + String subprotocol = response.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); setActualSubprotocol(subprotocol); setHandshakeComplete(); 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 ed4a13344e..13251d1c46 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 @@ -20,13 +20,13 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpHeaders.Values; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequestEncoder; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -124,11 +124,11 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker { } // Format request - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); - request.addHeader(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); - request.addHeader(Names.CONNECTION, Values.UPGRADE); - request.addHeader(Names.SEC_WEBSOCKET_KEY, key); - request.addHeader(Names.HOST, wsURL.getHost()); + FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); + request.headers().add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); + request.headers().add(Names.CONNECTION, Values.UPGRADE); + request.headers().add(Names.SEC_WEBSOCKET_KEY, key); + request.headers().add(Names.HOST, wsURL.getHost()); int wsPort = wsURL.getPort(); String originValue = "http://" + wsURL.getHost(); @@ -137,18 +137,18 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker { // See http://tools.ietf.org/html/rfc6454#section-6.2 originValue = originValue + ':' + wsPort; } - request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue); + request.headers().add(Names.SEC_WEBSOCKET_ORIGIN, originValue); String expectedSubprotocol = getExpectedSubprotocol(); if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) { - request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); + request.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); } - request.addHeader(Names.SEC_WEBSOCKET_VERSION, "7"); + request.headers().add(Names.SEC_WEBSOCKET_VERSION, "7"); if (customHeaders != null) { for (Map.Entry e : customHeaders.entrySet()) { - request.addHeader(e.getKey(), e.getValue()); + request.headers().add(e.getKey(), e.getValue()); } } @@ -192,32 +192,32 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker { * @throws WebSocketHandshakeException */ @Override - public void finishHandshake(Channel channel, HttpResponse response) { + public void finishHandshake(Channel channel, FullHttpResponse response) { final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS; - if (!response.getStatus().equals(status)) { - throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); + if (!response.status().equals(status)) { + throw new WebSocketHandshakeException("Invalid handshake response status: " + response.status()); } - String upgrade = response.getHeader(Names.UPGRADE); + String upgrade = response.headers().get(Names.UPGRADE); if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " - + response.getHeader(Names.UPGRADE)); + + response.headers().get(Names.UPGRADE)); } - String connection = response.getHeader(Names.CONNECTION); + String connection = response.headers().get(Names.CONNECTION); if (!Values.UPGRADE.equalsIgnoreCase(connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " - + response.getHeader(Names.CONNECTION)); + + response.headers().get(Names.CONNECTION)); } - String accept = response.getHeader(Names.SEC_WEBSOCKET_ACCEPT); + String accept = response.headers().get(Names.SEC_WEBSOCKET_ACCEPT); if (accept == null || !accept.equals(expectedChallengeResponseString)) { throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString)); } - String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + String subprotocol = response.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); setActualSubprotocol(subprotocol); setHandshakeComplete(); 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 98ddcf1e2d..d3efba6213 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 @@ -20,13 +20,13 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpHeaders.Values; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequestEncoder; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -124,11 +124,11 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { } // Format request - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); - request.addHeader(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); - request.addHeader(Names.CONNECTION, Values.UPGRADE); - request.addHeader(Names.SEC_WEBSOCKET_KEY, key); - request.addHeader(Names.HOST, wsURL.getHost()); + FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); + request.headers().add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); + request.headers().add(Names.CONNECTION, Values.UPGRADE); + request.headers().add(Names.SEC_WEBSOCKET_KEY, key); + request.headers().add(Names.HOST, wsURL.getHost()); int wsPort = wsURL.getPort(); String originValue = "http://" + wsURL.getHost(); @@ -137,18 +137,18 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { // See http://tools.ietf.org/html/rfc6454#section-6.2 originValue = originValue + ':' + wsPort; } - request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue); + request.headers().add(Names.SEC_WEBSOCKET_ORIGIN, originValue); String expectedSubprotocol = getExpectedSubprotocol(); if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) { - request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); + request.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); } - request.addHeader(Names.SEC_WEBSOCKET_VERSION, "8"); + request.headers().add(Names.SEC_WEBSOCKET_VERSION, "8"); if (customHeaders != null) { for (Map.Entry e : customHeaders.entrySet()) { - request.addHeader(e.getKey(), e.getValue()); + request.headers().add(e.getKey(), e.getValue()); } } @@ -192,32 +192,32 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { * @throws WebSocketHandshakeException */ @Override - public void finishHandshake(Channel channel, HttpResponse response) { + public void finishHandshake(Channel channel, FullHttpResponse response) { final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS; - if (!response.getStatus().equals(status)) { - throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); + if (!response.status().equals(status)) { + throw new WebSocketHandshakeException("Invalid handshake response status: " + response.status()); } - String upgrade = response.getHeader(Names.UPGRADE); + String upgrade = response.headers().get(Names.UPGRADE); if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " - + response.getHeader(Names.UPGRADE)); + + response.headers().get(Names.UPGRADE)); } - String connection = response.getHeader(Names.CONNECTION); + String connection = response.headers().get(Names.CONNECTION); if (!Values.UPGRADE.equalsIgnoreCase(connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " - + response.getHeader(Names.CONNECTION)); + + response.headers().get(Names.CONNECTION)); } - String accept = response.getHeader(Names.SEC_WEBSOCKET_ACCEPT); + String accept = response.headers().get(Names.SEC_WEBSOCKET_ACCEPT); if (accept == null || !accept.equals(expectedChallengeResponseString)) { throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString)); } - String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + String subprotocol = response.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); setActualSubprotocol(subprotocol); setHandshakeComplete(); 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 01f9873823..8204677c56 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 @@ -20,13 +20,13 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpRequestHeader; +import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpHeaders.Values; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequestHeader; +import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequestEncoder; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -124,11 +124,11 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { } // Format request - HttpRequestHeader request = new DefaultHttpRequestHeader(HttpVersion.HTTP_1_1, HttpMethod.GET, path); - request.addHeader(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); - request.addHeader(Names.CONNECTION, Values.UPGRADE); - request.addHeader(Names.SEC_WEBSOCKET_KEY, key); - request.addHeader(Names.HOST, wsURL.getHost()); + HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); + request.headers().add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()); + request.headers().add(Names.CONNECTION, Values.UPGRADE); + request.headers().add(Names.SEC_WEBSOCKET_KEY, key); + request.headers().add(Names.HOST, wsURL.getHost()); int wsPort = wsURL.getPort(); String originValue = "http://" + wsURL.getHost(); @@ -137,18 +137,18 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { // See http://tools.ietf.org/html/rfc6454#section-6.2 originValue = originValue + ':' + wsPort; } - request.addHeader(Names.SEC_WEBSOCKET_ORIGIN, originValue); + request.headers().add(Names.SEC_WEBSOCKET_ORIGIN, originValue); String expectedSubprotocol = getExpectedSubprotocol(); if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) { - request.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); + request.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); } - request.addHeader(Names.SEC_WEBSOCKET_VERSION, "13"); + request.headers().add(Names.SEC_WEBSOCKET_VERSION, "13"); if (customHeaders != null) { for (Map.Entry e: customHeaders.entrySet()) { - request.addHeader(e.getKey(), e.getValue()); + request.headers().add(e.getKey(), e.getValue()); } } @@ -191,32 +191,32 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { * @throws WebSocketHandshakeException */ @Override - public void finishHandshake(Channel channel, HttpResponse response) { + public void finishHandshake(Channel channel, FullHttpResponse response) { final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS; - if (!response.getStatus().equals(status)) { - throw new WebSocketHandshakeException("Invalid handshake response status: " + response.getStatus()); + if (!response.status().equals(status)) { + throw new WebSocketHandshakeException("Invalid handshake response status: " + response.status()); } - String upgrade = response.getHeader(Names.UPGRADE); + String upgrade = response.headers().get(Names.UPGRADE); if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " - + response.getHeader(Names.UPGRADE)); + + response.headers().get(Names.UPGRADE)); } - String connection = response.getHeader(Names.CONNECTION); + String connection = response.headers().get(Names.CONNECTION); if (!Values.UPGRADE.equalsIgnoreCase(connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " - + response.getHeader(Names.CONNECTION)); + + response.headers().get(Names.CONNECTION)); } - String accept = response.getHeader(Names.SEC_WEBSOCKET_ACCEPT); + String accept = response.headers().get(Names.SEC_WEBSOCKET_ACCEPT); if (accept == null || !accept.equals(expectedChallengeResponseString)) { throw new WebSocketHandshakeException(String.format("Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString)); } - String subprotocol = response.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + String subprotocol = response.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); setActualSubprotocol(subprotocol); setHandshakeComplete(); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java index 6b89cbefe0..314a4044e9 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java @@ -18,7 +18,7 @@ package io.netty.handler.codec.http.websocketx; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.util.internal.StringUtil; import java.util.Collections; @@ -112,7 +112,7 @@ public abstract class WebSocketServerHandshaker { * @param req * HTTP Request */ - public ChannelFuture handshake(Channel channel, HttpRequest req) { + public ChannelFuture handshake(Channel channel, FullHttpRequest req) { if (channel == null) { throw new NullPointerException("channel"); } @@ -129,7 +129,7 @@ public abstract class WebSocketServerHandshaker { * @param promise * the {@link ChannelPromise} to be notified when the opening handshake is done */ - public abstract ChannelFuture handshake(Channel channel, HttpRequest req, ChannelPromise promise); + public abstract ChannelFuture handshake(Channel channel, FullHttpRequest req, ChannelPromise promise); /** * Performs the closing handshake 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 fdc9b9946a..0d65a7bb89 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 @@ -22,13 +22,13 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpHeaders.Values; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.logging.InternalLogger; @@ -119,64 +119,63 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker { * HTTP request */ @Override - public ChannelFuture handshake(Channel channel, HttpRequest req, ChannelPromise promise) { + public ChannelFuture handshake(Channel channel, FullHttpRequest req, ChannelPromise promise) { if (logger.isDebugEnabled()) { logger.debug(String.format("Channel %s WS Version 00 server handshake", channel.id())); } // Serve the WebSocket handshake request. - if (!Values.UPGRADE.equalsIgnoreCase(req.getHeader(CONNECTION)) - || !WEBSOCKET.equalsIgnoreCase(req.getHeader(Names.UPGRADE))) { + if (!Values.UPGRADE.equalsIgnoreCase(req.headers().get(CONNECTION)) + || !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) { throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade"); } // Hixie 75 does not contain these headers while Hixie 76 does - boolean isHixie76 = req.containsHeader(SEC_WEBSOCKET_KEY1) && req.containsHeader(SEC_WEBSOCKET_KEY2); + boolean isHixie76 = req.headers().contains(SEC_WEBSOCKET_KEY1) && req.headers().contains(SEC_WEBSOCKET_KEY2); // Create the WebSocket handshake response. - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101, + FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, new HttpResponseStatus(101, isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake")); - res.addHeader(Names.UPGRADE, WEBSOCKET); - res.addHeader(CONNECTION, Values.UPGRADE); + res.headers().add(Names.UPGRADE, WEBSOCKET); + res.headers().add(CONNECTION, Values.UPGRADE); // Fill in the headers and contents depending on handshake method. if (isHixie76) { // New handshake method with a challenge: - res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN)); - res.addHeader(SEC_WEBSOCKET_LOCATION, getWebSocketUrl()); - String subprotocols = req.getHeader(SEC_WEBSOCKET_PROTOCOL); + res.headers().add(SEC_WEBSOCKET_ORIGIN, req.headers().get(ORIGIN)); + res.headers().add(SEC_WEBSOCKET_LOCATION, getWebSocketUrl()); + String subprotocols = req.headers().get(SEC_WEBSOCKET_PROTOCOL); if (subprotocols != null) { String selectedSubprotocol = selectSubprotocol(subprotocols); if (selectedSubprotocol == null) { throw new WebSocketHandshakeException("Requested subprotocol(s) not supported: " + subprotocols); } else { - res.addHeader(SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); + res.headers().add(SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); setSelectedSubprotocol(selectedSubprotocol); } } // Calculate the answer of the challenge. - String key1 = req.getHeader(SEC_WEBSOCKET_KEY1); - String key2 = req.getHeader(SEC_WEBSOCKET_KEY2); + String key1 = req.headers().get(SEC_WEBSOCKET_KEY1); + String key2 = req.headers().get(SEC_WEBSOCKET_KEY2); int a = (int) (Long.parseLong(BEGINNING_DIGIT.matcher(key1).replaceAll("")) / BEGINNING_SPACE.matcher(key1).replaceAll("").length()); int b = (int) (Long.parseLong(BEGINNING_DIGIT.matcher(key2).replaceAll("")) / BEGINNING_SPACE.matcher(key2).replaceAll("").length()); - long c = req.getContent().readLong(); + long c = req.data().readLong(); ByteBuf input = Unpooled.buffer(16); input.writeInt(a); input.writeInt(b); input.writeLong(c); - ByteBuf output = Unpooled.wrappedBuffer(WebSocketUtil.md5(input.array())); - res.setContent(output); + res.data().writeBytes(WebSocketUtil.md5(input.array())); } else { // Old Hixie 75 handshake method with no challenge: - res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN)); - res.addHeader(WEBSOCKET_LOCATION, getWebSocketUrl()); - String protocol = req.getHeader(WEBSOCKET_PROTOCOL); + res.headers().add(WEBSOCKET_ORIGIN, req.headers().get(ORIGIN)); + res.headers().add(WEBSOCKET_LOCATION, getWebSocketUrl()); + String protocol = req.headers().get(WEBSOCKET_PROTOCOL); if (protocol != null) { - res.addHeader(WEBSOCKET_PROTOCOL, selectSubprotocol(protocol)); + res.headers().add(WEBSOCKET_PROTOCOL, selectSubprotocol(protocol)); } } 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 d72097c83a..abcf7f5d25 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 @@ -20,12 +20,12 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders.Names; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.logging.InternalLogger; @@ -109,15 +109,16 @@ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker { * HTTP request */ @Override - public ChannelFuture handshake(Channel channel, HttpRequest req, ChannelPromise promise) { + public ChannelFuture handshake(Channel channel, FullHttpRequest req, ChannelPromise promise) { if (logger.isDebugEnabled()) { logger.debug(String.format("Channel %s WS Version 7 server handshake", channel.id())); } - HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS); + FullHttpResponse res = + new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS); - String key = req.getHeader(Names.SEC_WEBSOCKET_KEY); + String key = req.headers().get(Names.SEC_WEBSOCKET_KEY); if (key == null) { throw new WebSocketHandshakeException("not a WebSocket request: missing key"); } @@ -129,17 +130,16 @@ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker { logger.debug(String.format("WS Version 7 Server Handshake key: %s. Response: %s.", key, accept)); } - res.setStatus(HttpResponseStatus.SWITCHING_PROTOCOLS); - res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); - res.addHeader(Names.CONNECTION, Names.UPGRADE); - res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept); - String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase()); + res.headers().add(Names.CONNECTION, Names.UPGRADE); + res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept); + String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); if (subprotocols != null) { String selectedSubprotocol = selectSubprotocol(subprotocols); if (selectedSubprotocol == null) { throw new WebSocketHandshakeException("Requested subprotocol(s) not supported: " + subprotocols); } else { - res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); + res.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); setSelectedSubprotocol(selectedSubprotocol); } } 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 396833238d..00bab36ae1 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 @@ -20,12 +20,12 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpResponseHeader; -import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.DefaultHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders.Names; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.logging.InternalLogger; @@ -110,15 +110,15 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker { * HTTP request */ @Override - public ChannelFuture handshake(Channel channel, HttpRequest req, ChannelPromise promise) { + public ChannelFuture handshake(Channel channel, FullHttpRequest req, ChannelPromise promise) { if (logger.isDebugEnabled()) { logger.debug(String.format("Channel %s WS Version 8 server handshake", channel.id())); } - HttpResponseHeader res = new DefaultHttpResponseHeader(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS); + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS); - String key = req.getHeader(Names.SEC_WEBSOCKET_KEY); + String key = req.headers().get(Names.SEC_WEBSOCKET_KEY); if (key == null) { throw new WebSocketHandshakeException("not a WebSocket request: missing key"); } @@ -130,17 +130,16 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker { logger.debug(String.format("WS Version 8 Server Handshake key: %s. Response: %s.", key, accept)); } - res.setStatus(HttpResponseStatus.SWITCHING_PROTOCOLS); - res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); - res.addHeader(Names.CONNECTION, Names.UPGRADE); - res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept); - String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase()); + res.headers().add(Names.CONNECTION, Names.UPGRADE); + res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept); + String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); if (subprotocols != null) { String selectedSubprotocol = selectSubprotocol(subprotocols); if (selectedSubprotocol == null) { throw new WebSocketHandshakeException("Requested subprotocol(s) not supported: " + subprotocols); } else { - res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); + res.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); setSelectedSubprotocol(selectedSubprotocol); } } 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 238c3dc588..df9d8cff15 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 @@ -20,12 +20,12 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.http.DefaultHttpResponseHeader; -import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.DefaultHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders.Names; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.logging.InternalLogger; @@ -109,15 +109,15 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker { * HTTP request */ @Override - public ChannelFuture handshake(Channel channel, HttpRequest req, ChannelPromise promise) { + public ChannelFuture handshake(Channel channel, FullHttpRequest req, ChannelPromise promise) { if (logger.isDebugEnabled()) { logger.debug(String.format("Channel %s WS Version 13 server handshake", channel.id())); } - HttpResponseHeader res = new DefaultHttpResponseHeader(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS); + HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS); - String key = req.getHeader(Names.SEC_WEBSOCKET_KEY); + String key = req.headers().get(Names.SEC_WEBSOCKET_KEY); if (key == null) { throw new WebSocketHandshakeException("not a WebSocket request: missing key"); } @@ -129,18 +129,17 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker { logger.debug(String.format("WS Version 13 Server Handshake key: %s. Response: %s.", key, accept)); } - res.setStatus(HttpResponseStatus.SWITCHING_PROTOCOLS); - res.addHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); - res.addHeader(Names.CONNECTION, Names.UPGRADE); - res.addHeader(Names.SEC_WEBSOCKET_ACCEPT, accept); - String subprotocols = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL); + res.headers().add(Names.UPGRADE, WEBSOCKET.toLowerCase()); + res.headers().add(Names.CONNECTION, Names.UPGRADE); + res.headers().add(Names.SEC_WEBSOCKET_ACCEPT, accept); + String subprotocols = req.headers().get(Names.SEC_WEBSOCKET_PROTOCOL); if (subprotocols != null) { String selectedSubprotocol = selectSubprotocol(subprotocols); if (selectedSubprotocol == null) { throw new WebSocketHandshakeException( "Requested subprotocol(s) not supported: " + subprotocols); } else { - res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); + res.headers().add(Names.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol); setSelectedSubprotocol(selectedSubprotocol); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java index ccd23d9232..82415157ac 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java @@ -16,10 +16,10 @@ package io.netty.handler.codec.http.websocketx; import io.netty.channel.Channel; -import io.netty.handler.codec.http.DefaultHttpResponseHeader; +import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.HttpHeaders.Names; -import io.netty.handler.codec.http.HttpRequestHeader; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -81,9 +81,9 @@ public class WebSocketServerHandshakerFactory { * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web * socket version is not supported. */ - public WebSocketServerHandshaker newHandshaker(HttpRequestHeader req) { + public WebSocketServerHandshaker newHandshaker(HttpRequest req) { - String version = req.getHeader(Names.SEC_WEBSOCKET_VERSION); + String version = req.headers().get(Names.SEC_WEBSOCKET_VERSION); if (version != null) { if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) { // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification). @@ -113,11 +113,10 @@ public class WebSocketServerHandshakerFactory { * Channel */ public static void sendUnsupportedWebSocketVersionResponse(Channel channel) { - HttpResponseHeader res = new DefaultHttpResponseHeader( + HttpResponse res = new DefaultHttpResponse( HttpVersion.HTTP_1_1, - HttpResponseStatus.SWITCHING_PROTOCOLS); - res.setStatus(HttpResponseStatus.UPGRADE_REQUIRED); - res.setHeader(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue()); + HttpResponseStatus.UPGRADE_REQUIRED); + res.headers().set(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue()); channel.write(res); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java index dee63c74e6..de4420eac1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandler.java @@ -21,8 +21,8 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.util.AttributeKey; @@ -92,8 +92,8 @@ public class WebSocketServerProtocolHandler extends ChannelInboundMessageHandler @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof WebSocketHandshakeException) { - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.BAD_REQUEST); - response.setContent(Unpooled.wrappedBuffer(cause.getMessage().getBytes())); + FullHttpResponse response = new DefaultFullHttpResponse( + HTTP_1_1, HttpResponseStatus.BAD_REQUEST, Unpooled.wrappedBuffer(cause.getMessage().getBytes())); ctx.channel().write(response).addListener(ChannelFutureListener.CLOSE); } else { ctx.close(); @@ -113,7 +113,8 @@ public class WebSocketServerProtocolHandler extends ChannelInboundMessageHandler @Override public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { if (!(msg instanceof WebSocketFrame)) { - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN); + FullHttpResponse response = + new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN); ctx.channel().write(response); } else { ctx.nextInboundMessageBuffer().add(msg); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java index 58374ac702..b1630c27c4 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java @@ -15,26 +15,28 @@ */ package io.netty.handler.codec.http.websocketx; -import static io.netty.handler.codec.http.HttpHeaders.isKeepAlive; -import static io.netty.handler.codec.http.HttpMethod.GET; -import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.http.DefaultHttpResponse; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpRequestHeader; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.ssl.SslHandler; +import static io.netty.handler.codec.http.HttpHeaders.*; +import static io.netty.handler.codec.http.HttpMethod.*; +import static io.netty.handler.codec.http.HttpResponseStatus.*; +import static io.netty.handler.codec.http.HttpVersion.*; + /** * Handles the HTTP handshake (the HTTP Upgrade request) for {@link WebSocketServerProtocolHandler}. */ -public class WebSocketServerProtocolHandshakeHandler extends ChannelInboundMessageHandlerAdapter { +public class WebSocketServerProtocolHandshakeHandler + extends ChannelInboundMessageHandlerAdapter { private final String websocketPath; private final String subprotocols; @@ -48,9 +50,9 @@ public class WebSocketServerProtocolHandshakeHandler extends ChannelInboundMessa } @Override - public void messageReceived(final ChannelHandlerContext ctx, HttpRequest req) throws Exception { - if (req.getMethod() != GET) { - sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); + public void messageReceived(final ChannelHandlerContext ctx, FullHttpRequest req) throws Exception { + if (req.method() != GET) { + sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN)); return; } @@ -75,20 +77,20 @@ public class WebSocketServerProtocolHandshakeHandler extends ChannelInboundMessa } } - private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequestHeader req, HttpResponseHeader res) { + private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { ChannelFuture f = ctx.channel().write(res); - if (!isKeepAlive(req) || res.getStatus().getCode() != 200) { + if (!isKeepAlive(req) || res.status().code() != 200) { f.addListener(ChannelFutureListener.CLOSE); } } - private static String getWebSocketLocation(ChannelPipeline cp, HttpRequestHeader req, String path) { + private static String getWebSocketLocation(ChannelPipeline cp, HttpRequest req, String path) { String protocol = "ws"; if (cp.get(SslHandler.class) != null) { // SSL in use so use Secure WebSockets protocol = "wss"; } - return protocol + "://" + req.getHeader(HttpHeaders.Names.HOST) + path; + return protocol + "://" + req.headers().get(HttpHeaders.Names.HOST) + path; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectDecoder.java index e3e24b2018..5e59a4206e 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectDecoder.java @@ -19,13 +19,13 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedMessageChannel; import io.netty.handler.codec.TooLongFrameException; -import io.netty.handler.codec.http.HttpHeader; +import io.netty.handler.codec.http.HttpMessage; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpObjectDecoder; /** * Decodes {@link ByteBuf}s into RTSP messages represented in - * {@link io.netty.handler.codec.http.HttpHeader}s. + * {@link io.netty.handler.codec.http.HttpMessage}s. *

    *

    Parameters that prevents excessive memory consumption

    *
    @@ -84,14 +84,14 @@ public abstract class RtspObjectDecoder extends HttpObjectDecoder { } @Override - protected boolean isContentAlwaysEmpty(HttpHeader msg) { + protected boolean isContentAlwaysEmpty(HttpMessage msg) { // Unlike HTTP, RTSP always assumes zero-length body if Content-Length // header is absent. boolean empty = super.isContentAlwaysEmpty(msg); if (empty) { return true; } - if (!msg.containsHeader(RtspHeaders.Names.CONTENT_LENGTH)) { + if (!msg.headers().contains(RtspHeaders.Names.CONTENT_LENGTH)) { return true; } return empty; diff --git a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectEncoder.java index b326575f5f..a0656ceef3 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspObjectEncoder.java @@ -17,20 +17,19 @@ package io.netty.handler.codec.rtsp; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.UnsupportedMessageTypeException; -import io.netty.handler.codec.http.HttpHeader; +import io.netty.handler.codec.http.FullHttpMessage; +import io.netty.handler.codec.http.HttpMessage; import io.netty.handler.codec.http.HttpObjectEncoder; /** - * Encodes an RTSP message represented in {@link HttpHeader} into + * Encodes an RTSP message represented in {@link FullHttpMessage} into * a {@link ByteBuf}. * * @apiviz.landmark */ @Sharable -public abstract class RtspObjectEncoder extends HttpObjectEncoder { +public abstract class RtspObjectEncoder extends HttpObjectEncoder { /** * Creates a new instance. @@ -39,13 +38,7 @@ public abstract class RtspObjectEncoder extends HttpObject } @Override - protected void encode(ChannelHandlerContext ctx, Object msg, - ByteBuf out) throws Exception { - // Ignore unrelated message types such as HttpChunk. - if (!(msg instanceof HttpHeader)) { - throw new UnsupportedMessageTypeException(msg, HttpHeader.class); - } - - super.encode(ctx, msg, out); + public boolean isEncodable(Object msg) throws Exception { + return msg instanceof FullHttpMessage; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestDecoder.java index 05cfa9b846..5d3d6edfe3 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspRequestDecoder.java @@ -17,12 +17,12 @@ package io.netty.handler.codec.rtsp; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.TooLongFrameException; -import io.netty.handler.codec.http.DefaultHttpRequestHeader; -import io.netty.handler.codec.http.HttpHeader; +import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.HttpMessage; /** * Decodes {@link ByteBuf}s into RTSP requests represented in - * {@link io.netty.handler.codec.http.HttpRequestHeader}s. + * {@link io.netty.handler.codec.http.HttpRequest}s. *

    *

    Parameters that prevents excessive memory consumption

    *
    @@ -65,14 +65,14 @@ public class RtspRequestDecoder extends RtspObjectDecoder { } @Override - protected HttpHeader createMessage(String[] initialLine) throws Exception { - return new DefaultHttpRequestHeader(RtspVersions.valueOf(initialLine[2]), + protected HttpMessage createMessage(String[] initialLine) throws Exception { + return new DefaultHttpRequest(RtspVersions.valueOf(initialLine[2]), RtspMethods.valueOf(initialLine[0]), initialLine[1]); } @Override - protected HttpHeader createInvalidMessage() { - return new DefaultHttpRequestHeader(RtspVersions.RTSP_1_0, RtspMethods.OPTIONS, "/bad-request"); + protected HttpMessage createInvalidMessage() { + return new DefaultHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.OPTIONS, "/bad-request"); } @Override 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 d220d1a77c..1e7ad9ed7d 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 @@ -16,24 +16,30 @@ package io.netty.handler.codec.rtsp; import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.http.HttpRequestHeader; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpRequest; import io.netty.util.CharsetUtil; /** - * Encodes an RTSP request represented in {@link HttpRequestHeader} into + * Encodes an RTSP request represented in {@link FullHttpRequest} into * a {@link ByteBuf}. */ -public class RtspRequestEncoder extends RtspObjectEncoder { +public class RtspRequestEncoder extends RtspObjectEncoder { @Override - protected void encodeInitialLine(ByteBuf buf, HttpRequestHeader request) + public boolean isEncodable(Object msg) throws Exception { + return msg instanceof FullHttpRequest; + } + + @Override + protected void encodeInitialLine(ByteBuf buf, HttpRequest request) throws Exception { - buf.writeBytes(request.getMethod().toString().getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(request.method().toString().getBytes(CharsetUtil.US_ASCII)); buf.writeByte((byte) ' '); - buf.writeBytes(request.getUri().getBytes(CharsetUtil.UTF_8)); + buf.writeBytes(request.uri().getBytes(CharsetUtil.UTF_8)); buf.writeByte((byte) ' '); - buf.writeBytes(request.getProtocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(request.protocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); buf.writeByte((byte) '\r'); buf.writeByte((byte) '\n'); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseDecoder.java index b78929d18d..00efed7852 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/rtsp/RtspResponseDecoder.java @@ -17,13 +17,13 @@ package io.netty.handler.codec.rtsp; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.TooLongFrameException; -import io.netty.handler.codec.http.DefaultHttpResponseHeader; -import io.netty.handler.codec.http.HttpHeader; +import io.netty.handler.codec.http.DefaultHttpResponse; +import io.netty.handler.codec.http.HttpMessage; import io.netty.handler.codec.http.HttpResponseStatus; /** * Decodes {@link ByteBuf}s into RTSP responses represented in - * {@link io.netty.handler.codec.http.HttpResponseHeader}s. + * {@link io.netty.handler.codec.http.HttpResponse}s. *

    *

    Parameters that prevents excessive memory consumption

    *
    @@ -69,15 +69,15 @@ public class RtspResponseDecoder extends RtspObjectDecoder { } @Override - protected HttpHeader createMessage(String[] initialLine) throws Exception { - return new DefaultHttpResponseHeader( + protected HttpMessage createMessage(String[] initialLine) throws Exception { + return new DefaultHttpResponse( RtspVersions.valueOf(initialLine[0]), new HttpResponseStatus(Integer.valueOf(initialLine[1]), initialLine[2])); } @Override - protected HttpHeader createInvalidMessage() { - return new DefaultHttpResponseHeader(RtspVersions.RTSP_1_0, UNKNOWN_STATUS); + protected HttpMessage createInvalidMessage() { + return new DefaultHttpResponse(RtspVersions.RTSP_1_0, UNKNOWN_STATUS); } @Override 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 17ceb5b072..9cd81b0f68 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 @@ -16,25 +16,30 @@ package io.netty.handler.codec.rtsp; import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.http.HttpHeader; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpResponse; import io.netty.util.CharsetUtil; /** - * Encodes an RTSP response represented in {@link HttpResponseHeader} into + * Encodes an RTSP response represented in {@link FullHttpResponse} into * a {@link ByteBuf}. */ -public class RtspResponseEncoder extends RtspObjectEncoder { +public class RtspResponseEncoder extends RtspObjectEncoder { @Override - protected void encodeInitialLine(ByteBuf buf, HttpResponseHeader response) + public boolean isEncodable(Object msg) throws Exception { + return msg instanceof FullHttpResponse; + } + + @Override + protected void encodeInitialLine(ByteBuf buf, HttpResponse response) throws Exception { - buf.writeBytes(response.getProtocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(response.protocolVersion().toString().getBytes(CharsetUtil.US_ASCII)); buf.writeByte((byte) ' '); - buf.writeBytes(String.valueOf(response.getStatus().getCode()).getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(String.valueOf(response.status().code()).getBytes(CharsetUtil.US_ASCII)); buf.writeByte((byte) ' '); - buf.writeBytes(String.valueOf(response.getStatus().getReasonPhrase()).getBytes(CharsetUtil.US_ASCII)); + buf.writeBytes(String.valueOf(response.status().reasonPhrase()).getBytes(CharsetUtil.US_ASCII)); buf.writeByte((byte) '\r'); buf.writeByte((byte) '\n'); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.java index 6cef6b7f51..cbc7f3bc12 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHeaders.java @@ -196,9 +196,9 @@ public class SpdyHeaders { */ public static void setMethod(int spdyVersion, SpdyHeaderBlock block, HttpMethod method) { if (spdyVersion < 3) { - block.setHeader(Spdy2HttpNames.METHOD, method.getName()); + block.setHeader(Spdy2HttpNames.METHOD, method.name()); } else { - block.setHeader(HttpNames.METHOD, method.getName()); + block.setHeader(HttpNames.METHOD, method.name()); } } @@ -264,7 +264,7 @@ public class SpdyHeaders { int code = Integer.parseInt(status.substring(0, space)); String reasonPhrase = status.substring(space + 1); HttpResponseStatus responseStatus = HttpResponseStatus.valueOf(code); - if (responseStatus.getReasonPhrase().equals(reasonPhrase)) { + if (responseStatus.reasonPhrase().equals(reasonPhrase)) { return responseStatus; } else { return new HttpResponseStatus(code, reasonPhrase); diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java index 305c9632f7..87af7729e3 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpDecoder.java @@ -16,18 +16,17 @@ package io.netty.handler.codec.spdy; import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.TooLongFrameException; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.HttpHeader; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpMessage; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpMessage; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -36,13 +35,13 @@ import java.util.Map; /** * Decodes {@link SpdySynStreamFrame}s, {@link SpdySynReplyFrame}s, - * and {@link SpdyDataFrame}s into {@link HttpRequest}s and {@link HttpResponse}s. + * and {@link SpdyDataFrame}s into {@link FullHttpRequest}s and {@link FullHttpResponse}s. */ public class SpdyHttpDecoder extends MessageToMessageDecoder { private final int spdyVersion; private final int maxContentLength; - private final Map messageMap = new HashMap(); + private final Map messageMap = new HashMap(); /** * Creates a new instance. @@ -98,20 +97,21 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { } try { - HttpResponse httpResponse = createHttpResponse(spdyVersion, spdySynStreamFrame); + FullHttpResponse httpResponseWithEntity = + createHttpResponse(spdyVersion, spdySynStreamFrame); // Set the Stream-ID, Associated-To-Stream-ID, Priority, and URL as headers - SpdyHttpHeaders.setStreamId(httpResponse, streamID); - SpdyHttpHeaders.setAssociatedToStreamId(httpResponse, associatedToStreamId); - SpdyHttpHeaders.setPriority(httpResponse, spdySynStreamFrame.getPriority()); - SpdyHttpHeaders.setUrl(httpResponse, URL); + SpdyHttpHeaders.setStreamId(httpResponseWithEntity, streamID); + SpdyHttpHeaders.setAssociatedToStreamId(httpResponseWithEntity, associatedToStreamId); + SpdyHttpHeaders.setPriority(httpResponseWithEntity, spdySynStreamFrame.getPriority()); + SpdyHttpHeaders.setUrl(httpResponseWithEntity, URL); if (spdySynStreamFrame.isLast()) { - HttpHeaders.setContentLength(httpResponse, 0); - return httpResponse; + HttpHeaders.setContentLength(httpResponseWithEntity, 0); + return httpResponseWithEntity; } else { // Response body will follow in a series of Data Frames - messageMap.put(Integer.valueOf(streamID), httpResponse); + messageMap.put(Integer.valueOf(streamID), httpResponseWithEntity); } } catch (Exception e) { SpdyRstStreamFrame spdyRstStreamFrame = @@ -121,16 +121,16 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { } else { // SYN_STREAM frames initiated by the client are HTTP requests try { - HttpRequest httpRequest = createHttpRequest(spdyVersion, spdySynStreamFrame); + FullHttpRequest httpRequestWithEntity = createHttpRequest(spdyVersion, spdySynStreamFrame); // Set the Stream-ID as a header - SpdyHttpHeaders.setStreamId(httpRequest, streamID); + SpdyHttpHeaders.setStreamId(httpRequestWithEntity, streamID); if (spdySynStreamFrame.isLast()) { - return httpRequest; + return httpRequestWithEntity; } else { // Request body will follow in a series of Data Frames - messageMap.put(Integer.valueOf(streamID), httpRequest); + messageMap.put(Integer.valueOf(streamID), httpRequestWithEntity); } } catch (Exception e) { // If a client sends a SYN_STREAM without all of the method, url (host and path), @@ -150,17 +150,17 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { int streamID = spdySynReplyFrame.getStreamId(); try { - HttpResponse httpResponse = createHttpResponse(spdyVersion, spdySynReplyFrame); + FullHttpResponse httpResponseWithEntity = createHttpResponse(spdyVersion, spdySynReplyFrame); // Set the Stream-ID as a header - SpdyHttpHeaders.setStreamId(httpResponse, streamID); + SpdyHttpHeaders.setStreamId(httpResponseWithEntity, streamID); if (spdySynReplyFrame.isLast()) { - HttpHeaders.setContentLength(httpResponse, 0); - return httpResponse; + HttpHeaders.setContentLength(httpResponseWithEntity, 0); + return httpResponseWithEntity; } else { // Response body will follow in a series of Data Frames - messageMap.put(Integer.valueOf(streamID), httpResponse); + messageMap.put(Integer.valueOf(streamID), httpResponseWithEntity); } } catch (Exception e) { // If a client receives a SYN_REPLY without valid status and version headers @@ -174,7 +174,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { SpdyHeadersFrame spdyHeadersFrame = (SpdyHeadersFrame) msg; Integer streamID = Integer.valueOf(spdyHeadersFrame.getStreamId()); - HttpHeader httpMessage = messageMap.get(streamID); + HttpMessage httpMessage = messageMap.get(streamID); // If message is not in map discard HEADERS frame. // SpdySessionHandler should prevent this from happening. @@ -183,22 +183,22 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { } for (Map.Entry e: spdyHeadersFrame.getHeaders()) { - httpMessage.addHeader(e.getKey(), e.getValue()); + httpMessage.headers().add(e.getKey(), e.getValue()); } } else if (msg instanceof SpdyDataFrame) { SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg; Integer streamID = Integer.valueOf(spdyDataFrame.getStreamId()); - HttpMessage httpMessage = messageMap.get(streamID); + FullHttpMessage fullHttpMessage = messageMap.get(streamID); // If message is not in map discard Data Frame. // SpdySessionHandler should prevent this from happening. - if (httpMessage == null) { + if (fullHttpMessage == null) { return null; } - ByteBuf content = httpMessage.getContent(); + ByteBuf content = fullHttpMessage.data(); if (content.readableBytes() > maxContentLength - spdyDataFrame.getData().readableBytes()) { messageMap.remove(streamID); throw new TooLongFrameException( @@ -207,18 +207,12 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { ByteBuf spdyDataFrameData = spdyDataFrame.getData(); int spdyDataFrameDataLen = spdyDataFrameData.readableBytes(); - if (content == Unpooled.EMPTY_BUFFER) { - content = Unpooled.buffer(spdyDataFrameDataLen); - content.writeBytes(spdyDataFrameData, spdyDataFrameData.readerIndex(), spdyDataFrameDataLen); - httpMessage.setContent(content); - } else { - content.writeBytes(spdyDataFrameData, spdyDataFrameData.readerIndex(), spdyDataFrameDataLen); - } + content.writeBytes(spdyDataFrameData, spdyDataFrameData.readerIndex(), spdyDataFrameDataLen); if (spdyDataFrame.isLast()) { - HttpHeaders.setContentLength(httpMessage, content.readableBytes()); + HttpHeaders.setContentLength(fullHttpMessage, content.readableBytes()); messageMap.remove(streamID); - return httpMessage; + return fullHttpMessage; } } else if (msg instanceof SpdyRstStreamFrame) { @@ -231,7 +225,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { return null; } - private static HttpRequest createHttpRequest(int spdyVersion, SpdyHeaderBlock requestFrame) + private static FullHttpRequest createHttpRequest(int spdyVersion, SpdyHeaderBlock requestFrame) throws Exception { // Create the first line of the request from the name/value pairs HttpMethod method = SpdyHeaders.getMethod(spdyVersion, requestFrame); @@ -241,7 +235,7 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { SpdyHeaders.removeUrl(spdyVersion, requestFrame); SpdyHeaders.removeVersion(spdyVersion, requestFrame); - HttpRequest httpRequest = new DefaultHttpRequest(httpVersion, method, url); + FullHttpRequest httpRequestWithEntity = new DefaultFullHttpRequest(httpVersion, method, url); // Remove the scheme header SpdyHeaders.removeScheme(spdyVersion, requestFrame); @@ -250,23 +244,23 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { // Replace the SPDY host header with the HTTP host header String host = SpdyHeaders.getHost(requestFrame); SpdyHeaders.removeHost(requestFrame); - HttpHeaders.setHost(httpRequest, host); + HttpHeaders.setHost(httpRequestWithEntity, host); } for (Map.Entry e: requestFrame.getHeaders()) { - httpRequest.addHeader(e.getKey(), e.getValue()); + httpRequestWithEntity.headers().add(e.getKey(), e.getValue()); } // The Connection and Keep-Alive headers are no longer valid - HttpHeaders.setKeepAlive(httpRequest, true); + HttpHeaders.setKeepAlive(httpRequestWithEntity, true); // Transfer-Encoding header is not valid - httpRequest.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING); + httpRequestWithEntity.headers().remove(HttpHeaders.Names.TRANSFER_ENCODING); - return httpRequest; + return httpRequestWithEntity; } - private static HttpResponse createHttpResponse(int spdyVersion, SpdyHeaderBlock responseFrame) + private static FullHttpResponse createHttpResponse(int spdyVersion, SpdyHeaderBlock responseFrame) throws Exception { // Create the first line of the response from the name/value pairs HttpResponseStatus status = SpdyHeaders.getStatus(spdyVersion, responseFrame); @@ -274,18 +268,18 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder { SpdyHeaders.removeStatus(spdyVersion, responseFrame); SpdyHeaders.removeVersion(spdyVersion, responseFrame); - HttpResponse httpResponse = new DefaultHttpResponse(version, status); + FullHttpResponse httpResponseWithEntity = new DefaultFullHttpResponse(version, status); for (Map.Entry e: responseFrame.getHeaders()) { - httpResponse.addHeader(e.getKey(), e.getValue()); + httpResponseWithEntity.headers().add(e.getKey(), e.getValue()); } // The Connection and Keep-Alive headers are no longer valid - HttpHeaders.setKeepAlive(httpResponse, true); + HttpHeaders.setKeepAlive(httpResponseWithEntity, true); // Transfer-Encoding header is not valid - httpResponse.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING); - httpResponse.removeHeader(HttpHeaders.Names.TRAILER); + httpResponseWithEntity.headers().remove(HttpHeaders.Names.TRANSFER_ENCODING); + httpResponseWithEntity.headers().remove(HttpHeaders.Names.TRAILER); - return httpResponse; + return httpResponseWithEntity; } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java index fcdc9ec17d..d7c9ce9819 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java @@ -18,26 +18,26 @@ package io.netty.handler.codec.spdy; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.UnsupportedMessageTypeException; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpHeader; import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpRequestHeader; -import io.netty.handler.codec.http.HttpResponseHeader; -import io.netty.handler.codec.http.LastHttpContent; +import io.netty.handler.codec.http.HttpMessage; import io.netty.handler.codec.http.HttpObject; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.LastHttpContent; import java.util.ArrayList; import java.util.List; import java.util.Map; /** - * Encodes {@link HttpRequestHeader}s, {@link HttpResponseHeader}s, and {@link HttpContent}s + * Encodes {@link HttpRequest}s, {@link HttpResponse}s, and {@link HttpContent}s * into {@link SpdySynStreamFrame}s and {@link SpdySynReplyFrame}s. * *

    Request Annotations

    * - * SPDY specific headers must be added to {@link HttpRequestHeader}s: + * SPDY specific headers must be added to {@link HttpRequest}s: *
    * * @@ -58,7 +58,7 @@ import java.util.Map; * *

    Response Annotations

    * - * SPDY specific headers must be added to {@link HttpResponseHeader}s: + * SPDY specific headers must be added to {@link HttpResponse}s: *
    Header NameHeader Value
    * * @@ -71,7 +71,7 @@ import java.util.Map; * *

    Pushed Resource Annotations

    * - * SPDY specific headers must be added to pushed {@link HttpResponseHeader}s: + * SPDY specific headers must be added to pushed {@link HttpResponse}s: *
    Header NameHeader Value
    * * @@ -112,8 +112,8 @@ import java.util.Map; *

    Chunked Content

    * * This encoder associates all {@link HttpContent}s that it receives - * with the most recently received 'chunked' {@link HttpRequestHeader} - * or {@link HttpResponseHeader}. + * with the most recently received 'chunked' {@link HttpRequest} + * or {@link HttpResponse}. * *

    Pushed Resources

    * @@ -144,16 +144,16 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { public Object encode(ChannelHandlerContext ctx, Object msg) throws Exception { List out = new ArrayList(); - if (msg instanceof HttpRequestHeader) { + if (msg instanceof HttpRequest) { - HttpRequestHeader httpRequest = (HttpRequestHeader) msg; + HttpRequest httpRequest = (HttpRequest) msg; SpdySynStreamFrame spdySynStreamFrame = createSynStreamFrame(httpRequest); out.add(spdySynStreamFrame); } - if (msg instanceof HttpResponseHeader) { + if (msg instanceof HttpResponse) { - HttpResponseHeader httpResponse = (HttpResponseHeader) msg; - if (httpResponse.containsHeader(SpdyHttpHeaders.Names.ASSOCIATED_TO_STREAM_ID)) { + HttpResponse httpResponse = (HttpResponse) msg; + if (httpResponse.headers().contains(SpdyHttpHeaders.Names.ASSOCIATED_TO_STREAM_ID)) { SpdySynStreamFrame spdySynStreamFrame = createSynStreamFrame(httpResponse); out.add(spdySynStreamFrame); } else { @@ -165,12 +165,12 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { HttpContent chunk = (HttpContent) msg; SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(currentStreamId); - spdyDataFrame.setData(chunk.getContent()); + spdyDataFrame.setData(chunk.data()); spdyDataFrame.setLast(chunk instanceof LastHttpContent); if (chunk instanceof LastHttpContent) { LastHttpContent trailer = (LastHttpContent) chunk; - List> trailers = trailer.getHeaders(); + List> trailers = trailer.trailingHeaders().entries(); if (trailers.isEmpty()) { out.add(spdyDataFrame); } else { @@ -194,7 +194,7 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { return out.toArray(); } - private SpdySynStreamFrame createSynStreamFrame(HttpHeader httpMessage) + private SpdySynStreamFrame createSynStreamFrame(HttpMessage httpMessage) throws Exception { // Get the Stream-ID, Associated-To-Stream-ID, Priority, URL, and scheme from the headers int streamID = SpdyHttpHeaders.getStreamId(httpMessage); @@ -210,33 +210,33 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { // The Connection, Keep-Alive, Proxy-Connection, and Transfer-Encoding // headers are not valid and MUST not be sent. - httpMessage.removeHeader(HttpHeaders.Names.CONNECTION); - httpMessage.removeHeader("Keep-Alive"); - httpMessage.removeHeader("Proxy-Connection"); - httpMessage.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING); + httpMessage.headers().remove(HttpHeaders.Names.CONNECTION); + httpMessage.headers().remove("Keep-Alive"); + httpMessage.headers().remove("Proxy-Connection"); + httpMessage.headers().remove(HttpHeaders.Names.TRANSFER_ENCODING); SpdySynStreamFrame spdySynStreamFrame = new DefaultSpdySynStreamFrame(streamID, associatedToStreamId, priority); // Unfold the first line of the message into name/value pairs - if (httpMessage instanceof HttpRequest) { - HttpRequestHeader httpRequest = (HttpRequestHeader) httpMessage; - SpdyHeaders.setMethod(spdyVersion, spdySynStreamFrame, httpRequest.getMethod()); - SpdyHeaders.setUrl(spdyVersion, spdySynStreamFrame, httpRequest.getUri()); - SpdyHeaders.setVersion(spdyVersion, spdySynStreamFrame, httpMessage.getProtocolVersion()); + if (httpMessage instanceof FullHttpRequest) { + HttpRequest httpRequest = (HttpRequest) httpMessage; + SpdyHeaders.setMethod(spdyVersion, spdySynStreamFrame, httpRequest.method()); + SpdyHeaders.setUrl(spdyVersion, spdySynStreamFrame, httpRequest.uri()); + SpdyHeaders.setVersion(spdyVersion, spdySynStreamFrame, httpMessage.protocolVersion()); } - if (httpMessage instanceof HttpResponseHeader) { - HttpResponseHeader httpResponse = (HttpResponseHeader) httpMessage; - SpdyHeaders.setStatus(spdyVersion, spdySynStreamFrame, httpResponse.getStatus()); + if (httpMessage instanceof HttpResponse) { + HttpResponse httpResponse = (HttpResponse) httpMessage; + SpdyHeaders.setStatus(spdyVersion, spdySynStreamFrame, httpResponse.status()); SpdyHeaders.setUrl(spdyVersion, spdySynStreamFrame, URL); - SpdyHeaders.setVersion(spdyVersion, spdySynStreamFrame, httpMessage.getProtocolVersion()); + SpdyHeaders.setVersion(spdyVersion, spdySynStreamFrame, httpMessage.protocolVersion()); spdySynStreamFrame.setUnidirectional(true); } // Replace the HTTP host header with the SPDY host header if (spdyVersion >= 3) { String host = HttpHeaders.getHost(httpMessage); - httpMessage.removeHeader(HttpHeaders.Names.HOST); + httpMessage.headers().remove(HttpHeaders.Names.HOST); SpdyHeaders.setHost(spdySynStreamFrame, host); } @@ -247,7 +247,7 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { SpdyHeaders.setScheme(spdyVersion, spdySynStreamFrame, scheme); // Transfer the remaining HTTP headers - for (Map.Entry entry: httpMessage.getHeaders()) { + for (Map.Entry entry: httpMessage.headers()) { spdySynStreamFrame.addHeader(entry.getKey(), entry.getValue()); } currentStreamId = spdySynStreamFrame.getStreamId(); @@ -255,7 +255,7 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { return spdySynStreamFrame; } - private SpdySynReplyFrame createSynReplyFrame(HttpResponseHeader httpResponse) + private SpdySynReplyFrame createSynReplyFrame(HttpResponse httpResponse) throws Exception { boolean chunked = HttpHeaders.isTransferEncodingChunked(httpResponse); @@ -265,19 +265,19 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { // The Connection, Keep-Alive, Proxy-Connection, and Transfer-ENcoding // headers are not valid and MUST not be sent. - httpResponse.removeHeader(HttpHeaders.Names.CONNECTION); - httpResponse.removeHeader("Keep-Alive"); - httpResponse.removeHeader("Proxy-Connection"); - httpResponse.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING); + httpResponse.headers().remove(HttpHeaders.Names.CONNECTION); + httpResponse.headers().remove("Keep-Alive"); + httpResponse.headers().remove("Proxy-Connection"); + httpResponse.headers().remove(HttpHeaders.Names.TRANSFER_ENCODING); SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamID); // Unfold the first line of the response into name/value pairs - SpdyHeaders.setStatus(spdyVersion, spdySynReplyFrame, httpResponse.getStatus()); - SpdyHeaders.setVersion(spdyVersion, spdySynReplyFrame, httpResponse.getProtocolVersion()); + SpdyHeaders.setStatus(spdyVersion, spdySynReplyFrame, httpResponse.status()); + SpdyHeaders.setVersion(spdyVersion, spdySynReplyFrame, httpResponse.protocolVersion()); // Transfer the remaining HTTP headers - for (Map.Entry entry: httpResponse.getHeaders()) { + for (Map.Entry entry: httpResponse.headers()) { spdySynReplyFrame.addHeader(entry.getKey(), entry.getValue()); } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpHeaders.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpHeaders.java index bdeccbd48c..efcde4d149 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpHeaders.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpHeaders.java @@ -15,8 +15,8 @@ */ package io.netty.handler.codec.spdy; -import io.netty.handler.codec.http.HttpHeader; import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpMessage; /** * Provides the constants for the header names and the utility methods @@ -60,29 +60,29 @@ public final class SpdyHttpHeaders { /** * Removes the {@code "X-SPDY-Stream-ID"} header. */ - public static void removeStreamId(HttpHeader message) { - message.removeHeader(Names.STREAM_ID); + public static void removeStreamId(HttpMessage message) { + message.headers().remove(Names.STREAM_ID); } /** * Returns the value of the {@code "X-SPDY-Stream-ID"} header. */ - public static int getStreamId(HttpHeader message) { + public static int getStreamId(HttpMessage message) { return HttpHeaders.getIntHeader(message, Names.STREAM_ID); } /** * Sets the {@code "X-SPDY-Stream-ID"} header. */ - public static void setStreamId(HttpHeader message, int streamId) { + public static void setStreamId(HttpMessage message, int streamId) { HttpHeaders.setIntHeader(message, Names.STREAM_ID, streamId); } /** * Removes the {@code "X-SPDY-Associated-To-Stream-ID"} header. */ - public static void removeAssociatedToStreamId(HttpHeader message) { - message.removeHeader(Names.ASSOCIATED_TO_STREAM_ID); + public static void removeAssociatedToStreamId(HttpMessage message) { + message.headers().remove(Names.ASSOCIATED_TO_STREAM_ID); } /** @@ -91,22 +91,22 @@ public final class SpdyHttpHeaders { * @return the header value or {@code 0} if there is no such header or * if the header value is not a number */ - public static int getAssociatedToStreamId(HttpHeader message) { + public static int getAssociatedToStreamId(HttpMessage message) { return HttpHeaders.getIntHeader(message, Names.ASSOCIATED_TO_STREAM_ID, 0); } /** * Sets the {@code "X-SPDY-Associated-To-Stream-ID"} header. */ - public static void setAssociatedToStreamId(HttpHeader message, int associatedToStreamId) { + public static void setAssociatedToStreamId(HttpMessage message, int associatedToStreamId) { HttpHeaders.setIntHeader(message, Names.ASSOCIATED_TO_STREAM_ID, associatedToStreamId); } /** * Removes the {@code "X-SPDY-Priority"} header. */ - public static void removePriority(HttpHeader message) { - message.removeHeader(Names.PRIORITY); + public static void removePriority(HttpMessage message) { + message.headers().remove(Names.PRIORITY); } /** @@ -115,56 +115,56 @@ public final class SpdyHttpHeaders { * @return the header value or {@code 0} if there is no such header or * if the header value is not a number */ - public static byte getPriority(HttpHeader message) { + public static byte getPriority(HttpMessage message) { return (byte) HttpHeaders.getIntHeader(message, Names.PRIORITY, 0); } /** * Sets the {@code "X-SPDY-Priority"} header. */ - public static void setPriority(HttpHeader message, byte priority) { + public static void setPriority(HttpMessage message, byte priority) { HttpHeaders.setIntHeader(message, Names.PRIORITY, priority); } /** * Removes the {@code "X-SPDY-URL"} header. */ - public static void removeUrl(HttpHeader message) { - message.removeHeader(Names.URL); + public static void removeUrl(HttpMessage message) { + message.headers().remove(Names.URL); } /** * Returns the value of the {@code "X-SPDY-URL"} header. */ - public static String getUrl(HttpHeader message) { - return message.getHeader(Names.URL); + public static String getUrl(HttpMessage message) { + return message.headers().get(Names.URL); } /** * Sets the {@code "X-SPDY-URL"} header. */ - public static void setUrl(HttpHeader message, String url) { - message.setHeader(Names.URL, url); + public static void setUrl(HttpMessage message, String url) { + message.headers().set(Names.URL, url); } /** * Removes the {@code "X-SPDY-Scheme"} header. */ - public static void removeScheme(HttpHeader message) { - message.removeHeader(Names.SCHEME); + public static void removeScheme(HttpMessage message) { + message.headers().remove(Names.SCHEME); } /** * Returns the value of the {@code "X-SPDY-Scheme"} header. */ - public static String getScheme(HttpHeader message) { - return message.getHeader(Names.SCHEME); + public static String getScheme(HttpMessage message) { + return message.headers().get(Names.SCHEME); } /** * Sets the {@code "X-SPDY-Scheme"} header. */ - public static void setScheme(HttpHeader message, String scheme) { - message.setHeader(Names.SCHEME, scheme); + public static void setScheme(HttpMessage message, String scheme) { + message.headers().set(Names.SCHEME, scheme); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpResponseStreamIdHandler.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpResponseStreamIdHandler.java index bf2d5b1630..7f6f70794a 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpResponseStreamIdHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpResponseStreamIdHandler.java @@ -15,31 +15,31 @@ */ package io.netty.handler.codec.spdy; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageCodec; +import io.netty.handler.codec.http.HttpMessage; + import java.util.LinkedList; import java.util.Queue; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToMessageCodec; -import io.netty.handler.codec.http.HttpHeader; - /** * {@link MessageToMessageCodec} that takes care of adding the right {@link SpdyHttpHeaders.Names#STREAM_ID} to the - * {@link HttpHeader} if one is not present. This makes it possible to just re-use plan handlers current used + * {@link HttpMessage} if one is not present. This makes it possible to just re-use plan handlers current used * for HTTP. */ public class SpdyHttpResponseStreamIdHandler extends - MessageToMessageCodec { + MessageToMessageCodec { private static final Integer NO_ID = -1; private final Queue ids = new LinkedList(); public SpdyHttpResponseStreamIdHandler() { - super(new Class[] { HttpHeader.class, SpdyRstStreamFrame.class }, new Class[] { HttpHeader.class }); + super(new Class[] { HttpMessage.class, SpdyRstStreamFrame.class }, new Class[] { HttpMessage.class }); } @Override - protected Object encode(ChannelHandlerContext ctx, HttpHeader msg) throws Exception { + protected Object encode(ChannelHandlerContext ctx, HttpMessage msg) throws Exception { Integer id = ids.poll(); - if (id != null && id.intValue() != NO_ID && !msg.containsHeader(SpdyHttpHeaders.Names.STREAM_ID)) { + if (id != null && id.intValue() != NO_ID && !msg.headers().contains(SpdyHttpHeaders.Names.STREAM_ID)) { SpdyHttpHeaders.setStreamId(msg, id); } return msg; @@ -47,12 +47,12 @@ public class SpdyHttpResponseStreamIdHandler extends @Override protected Object decode(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpHeader) { - boolean contains = ((HttpHeader) msg).containsHeader(SpdyHttpHeaders.Names.STREAM_ID); + if (msg instanceof HttpMessage) { + boolean contains = ((HttpMessage) msg).headers().contains(SpdyHttpHeaders.Names.STREAM_ID); if (!contains) { ids.add(NO_ID); } else { - ids.add(SpdyHttpHeaders.getStreamId((HttpHeader) msg)); + ids.add(SpdyHttpHeaders.getStreamId((HttpMessage) msg)); } } else if (msg instanceof SpdyRstStreamFrame) { ids.remove(((SpdyRstStreamFrame) msg).getStreamId()); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpRequestTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpRequestTest.java index 010c9b1fe8..4d55e55b23 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpRequestTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpRequestTest.java @@ -22,25 +22,25 @@ public class DefaultHttpRequestTest { @Test public void testHeaderRemoval() { - HttpHeader m = new DefaultHttpRequestHeader( + HttpMessage m = new DefaultHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); // Insert sample keys. for (int i = 0; i < 1000; i ++) { - m.setHeader(String.valueOf(i), ""); + m.headers().set(String.valueOf(i), ""); } // Remove in reversed order. for (int i = 999; i >= 0; i --) { - m.removeHeader(String.valueOf(i)); + m.headers().remove(String.valueOf(i)); } // Check if random access returns nothing. for (int i = 0; i < 1000; i ++) { - Assert.assertNull(m.getHeader(String.valueOf(i))); + Assert.assertNull(m.headers().get(String.valueOf(i))); } // Check if sequential access returns nothing. - Assert.assertTrue(m.getHeaders().isEmpty()); + Assert.assertTrue(m.headers().isEmpty()); } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpObjectAggregatorTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/FullHttpMessageDecoderTest.java similarity index 81% rename from codec-http/src/test/java/io/netty/handler/codec/http/HttpObjectAggregatorTest.java rename to codec-http/src/test/java/io/netty/handler/codec/http/FullHttpMessageDecoderTest.java index c6733ef4f1..f0d8a34975 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpObjectAggregatorTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/FullHttpMessageDecoderTest.java @@ -15,7 +15,6 @@ */ package io.netty.handler.codec.http; -import static org.junit.Assert.*; import io.netty.buffer.ByteBuf; import io.netty.buffer.CompositeByteBuf; import io.netty.buffer.Unpooled; @@ -23,20 +22,21 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedMessageChannel; import io.netty.handler.codec.TooLongFrameException; import io.netty.util.CharsetUtil; - -import java.util.List; - import org.easymock.EasyMock; import org.junit.Test; -public class HttpObjectAggregatorTest { +import java.util.List; + +import static org.junit.Assert.*; + +public class FullHttpMessageDecoderTest { @Test public void testAggregate() { HttpObjectAggregator aggr = new HttpObjectAggregator(1024 * 1024); EmbeddedMessageChannel embedder = new EmbeddedMessageChannel(aggr); - HttpRequestHeader message = new DefaultHttpRequestHeader(HttpVersion.HTTP_1_1, + HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost"); HttpHeaders.setHeader(message, "X-Test", true); HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); @@ -49,18 +49,18 @@ public class HttpObjectAggregatorTest { // this should trigger a messageReceived event so return true assertTrue(embedder.writeInbound(chunk3)); assertTrue(embedder.finish()); - DefaultHttpRequest aggratedMessage = (DefaultHttpRequest) embedder.readInbound(); + DefaultFullHttpRequest aggratedMessage = (DefaultFullHttpRequest) embedder.readInbound(); assertNotNull(aggratedMessage); - assertEquals(chunk1.getContent().readableBytes() + chunk2.getContent().readableBytes(), HttpHeaders.getContentLength(aggratedMessage)); - assertEquals(aggratedMessage.getHeader("X-Test"), Boolean.TRUE.toString()); + assertEquals(chunk1.data().readableBytes() + chunk2.data().readableBytes(), HttpHeaders.getContentLength(aggratedMessage)); + assertEquals(aggratedMessage.headers().get("X-Test"), Boolean.TRUE.toString()); checkContentBuffer(aggratedMessage); assertNull(embedder.readInbound()); } - private static void checkContentBuffer(DefaultHttpRequest aggregatedMessage) { - CompositeByteBuf buffer = (CompositeByteBuf) aggregatedMessage.getContent(); + private static void checkContentBuffer(DefaultFullHttpRequest aggregatedMessage) { + CompositeByteBuf buffer = (CompositeByteBuf) aggregatedMessage.data(); assertEquals(2, buffer.numComponents()); List buffers = buffer.decompose(0, buffer.capacity()); assertEquals(2, buffers.size()); @@ -74,14 +74,14 @@ public class HttpObjectAggregatorTest { public void testAggregateWithTrailer() { HttpObjectAggregator aggr = new HttpObjectAggregator(1024 * 1024); EmbeddedMessageChannel embedder = new EmbeddedMessageChannel(aggr); - HttpRequestHeader message = new DefaultHttpRequestHeader(HttpVersion.HTTP_1_1, + HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost"); HttpHeaders.setHeader(message, "X-Test", true); HttpHeaders.setTransferEncodingChunked(message); HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); LastHttpContent trailer = new DefaultLastHttpContent(); - trailer.setHeader("X-Trailer", true); + trailer.trailingHeaders().set("X-Trailer", true); assertFalse(embedder.writeInbound(message)); assertFalse(embedder.writeInbound(chunk1)); @@ -90,12 +90,12 @@ public class HttpObjectAggregatorTest { // this should trigger a messageReceived event so return true assertTrue(embedder.writeInbound(trailer)); assertTrue(embedder.finish()); - DefaultHttpRequest aggratedMessage = (DefaultHttpRequest) embedder.readInbound(); + DefaultFullHttpRequest aggratedMessage = (DefaultFullHttpRequest) embedder.readInbound(); assertNotNull(aggratedMessage); - assertEquals(chunk1.getContent().readableBytes() + chunk2.getContent().readableBytes(), HttpHeaders.getContentLength(aggratedMessage)); - assertEquals(aggratedMessage.getHeader("X-Test"), Boolean.TRUE.toString()); - assertEquals(aggratedMessage.getHeader("X-Trailer"), Boolean.TRUE.toString()); + assertEquals(chunk1.data().readableBytes() + chunk2.data().readableBytes(), HttpHeaders.getContentLength(aggratedMessage)); + assertEquals(aggratedMessage.headers().get("X-Test"), Boolean.TRUE.toString()); + assertEquals(aggratedMessage.headers().get("X-Trailer"), Boolean.TRUE.toString()); checkContentBuffer(aggratedMessage); assertNull(embedder.readInbound()); @@ -107,7 +107,7 @@ public class HttpObjectAggregatorTest { public void testTooLongFrameException() { HttpObjectAggregator aggr = new HttpObjectAggregator(4); EmbeddedMessageChannel embedder = new EmbeddedMessageChannel(aggr); - HttpRequestHeader message = new DefaultHttpRequestHeader(HttpVersion.HTTP_1_1, + HttpRequest message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost"); HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpClientCodecTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpClientCodecTest.java index f76ce4009d..7d92efffb2 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpClientCodecTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpClientCodecTest.java @@ -15,15 +15,15 @@ */ package io.netty.handler.codec.http; -import static org.junit.Assert.*; import io.netty.buffer.Unpooled; import io.netty.channel.embedded.EmbeddedByteChannel; import io.netty.handler.codec.CodecException; import io.netty.handler.codec.PrematureChannelClosureException; import io.netty.util.CharsetUtil; - import org.junit.Test; +import static org.junit.Assert.*; + public class HttpClientCodecTest { private static final String RESPONSE = "HTTP/1.0 200 OK\r\n" + "Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 28\r\n" + "\r\n" @@ -38,7 +38,7 @@ public class HttpClientCodecTest { HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true); EmbeddedByteChannel ch = new EmbeddedByteChannel(codec); - ch.writeOutbound(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")); + ch.writeOutbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")); ch.writeInbound(Unpooled.copiedBuffer(RESPONSE, CharsetUtil.ISO_8859_1)); ch.finish(); } @@ -48,7 +48,7 @@ public class HttpClientCodecTest { HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true); EmbeddedByteChannel ch = new EmbeddedByteChannel(codec); - ch.writeOutbound(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")); + ch.writeOutbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")); ch.writeInbound(Unpooled.copiedBuffer(CHUNKED_RESPONSE, CharsetUtil.ISO_8859_1)); ch.finish(); } @@ -58,7 +58,7 @@ public class HttpClientCodecTest { HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true); EmbeddedByteChannel ch = new EmbeddedByteChannel(codec); - assertTrue(ch.writeOutbound(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/"))); + assertTrue(ch.writeOutbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/"))); assertNotNull(ch.readOutbound()); try { @@ -75,7 +75,7 @@ public class HttpClientCodecTest { HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true); EmbeddedByteChannel ch = new EmbeddedByteChannel(codec); - ch.writeOutbound(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")); + ch.writeOutbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")); ch.writeInbound(Unpooled.copiedBuffer(INCOMPLETE_CHUNKED_RESPONSE, CharsetUtil.ISO_8859_1)); try { diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpInvalidMessageTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpInvalidMessageTest.java index 7344a44070..3fe0c3817f 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpInvalidMessageTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpInvalidMessageTest.java @@ -33,8 +33,8 @@ public class HttpInvalidMessageTest { public void testRequestWithBadInitialLine() throws Exception { EmbeddedByteChannel ch = new EmbeddedByteChannel(new HttpRequestDecoder()); ch.writeInbound(Unpooled.copiedBuffer("GET / HTTP/1.0 with extra\r\n", CharsetUtil.UTF_8)); - HttpRequestHeader req = (HttpRequestHeader) ch.readInbound(); - DecoderResult dr = req.getDecoderResult(); + HttpRequest req = (HttpRequest) ch.readInbound(); + DecoderResult dr = req.decoderResult(); Assert.assertFalse(dr.isSuccess()); Assert.assertFalse(dr.isPartialFailure()); ensureInboundTrafficDiscarded(ch); @@ -47,12 +47,12 @@ public class HttpInvalidMessageTest { ch.writeInbound(Unpooled.copiedBuffer("Good_Name: Good Value\r\n", CharsetUtil.UTF_8)); ch.writeInbound(Unpooled.copiedBuffer("Bad=Name: Bad Value\r\n", CharsetUtil.UTF_8)); ch.writeInbound(Unpooled.copiedBuffer("\r\n", CharsetUtil.UTF_8)); - HttpRequestHeader req = (HttpRequestHeader) ch.readInbound(); - DecoderResult dr = req.getDecoderResult(); + HttpRequest req = (HttpRequest) ch.readInbound(); + DecoderResult dr = req.decoderResult(); Assert.assertFalse(dr.isSuccess()); Assert.assertTrue(dr.isPartialFailure()); - Assert.assertEquals("Good Value", req.getHeader("Good_Name")); - Assert.assertEquals("/maybe-something", req.getUri()); + Assert.assertEquals("Good Value", req.headers().get("Good_Name")); + Assert.assertEquals("/maybe-something", req.uri()); ensureInboundTrafficDiscarded(ch); } @@ -60,8 +60,8 @@ public class HttpInvalidMessageTest { public void testResponseWithBadInitialLine() throws Exception { EmbeddedByteChannel ch = new EmbeddedByteChannel(new HttpResponseDecoder()); ch.writeInbound(Unpooled.copiedBuffer("HTTP/1.0 BAD_CODE Bad Server\r\n", CharsetUtil.UTF_8)); - HttpResponseHeader res = (HttpResponseHeader) ch.readInbound(); - DecoderResult dr = res.getDecoderResult(); + HttpResponse res = (HttpResponse) ch.readInbound(); + DecoderResult dr = res.decoderResult(); Assert.assertFalse(dr.isSuccess()); Assert.assertFalse(dr.isPartialFailure()); ensureInboundTrafficDiscarded(ch); @@ -74,12 +74,12 @@ public class HttpInvalidMessageTest { ch.writeInbound(Unpooled.copiedBuffer("Good_Name: Good Value\r\n", CharsetUtil.UTF_8)); ch.writeInbound(Unpooled.copiedBuffer("Bad=Name: Bad Value\r\n", CharsetUtil.UTF_8)); ch.writeInbound(Unpooled.copiedBuffer("\r\n", CharsetUtil.UTF_8)); - HttpResponseHeader res = (HttpResponseHeader) ch.readInbound(); - DecoderResult dr = res.getDecoderResult(); + HttpResponse res = (HttpResponse) ch.readInbound(); + DecoderResult dr = res.decoderResult(); Assert.assertFalse(dr.isSuccess()); Assert.assertTrue(dr.isPartialFailure()); - Assert.assertEquals("Maybe OK", res.getStatus().getReasonPhrase()); - Assert.assertEquals("Good Value", res.getHeader("Good_Name")); + Assert.assertEquals("Maybe OK", res.status().reasonPhrase()); + Assert.assertEquals("Good Value", res.headers().get("Good_Name")); ensureInboundTrafficDiscarded(ch); } @@ -90,11 +90,11 @@ public class HttpInvalidMessageTest { ch.writeInbound(Unpooled.copiedBuffer("Transfer-Encoding: chunked\r\n\r\n", CharsetUtil.UTF_8)); ch.writeInbound(Unpooled.copiedBuffer("BAD_LENGTH\r\n", CharsetUtil.UTF_8)); - HttpRequestHeader req = (HttpRequestHeader) ch.readInbound(); - Assert.assertTrue(req.getDecoderResult().isSuccess()); + HttpRequest req = (HttpRequest) ch.readInbound(); + Assert.assertTrue(req.decoderResult().isSuccess()); HttpContent chunk = (HttpContent) ch.readInbound(); - DecoderResult dr = chunk.getDecoderResult(); + DecoderResult dr = chunk.decoderResult(); Assert.assertFalse(dr.isSuccess()); Assert.assertFalse(dr.isPartialFailure()); ensureInboundTrafficDiscarded(ch); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java index 469d10ed54..3a6aed1616 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java @@ -15,14 +15,14 @@ */ package io.netty.handler.codec.http; -import static org.junit.Assert.*; - import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.junit.Test; import java.nio.charset.Charset; +import static org.junit.Assert.*; + /** */ public class HttpRequestEncoderTest { @@ -31,7 +31,7 @@ public class HttpRequestEncoderTest { public void testUriWithoutPath() throws Exception { HttpRequestEncoder encoder = new HttpRequestEncoder(); ByteBuf buffer = Unpooled.buffer(64); - encoder.encodeInitialLine(buffer, new DefaultHttpRequestHeader(HttpVersion.HTTP_1_1, + encoder.encodeInitialLine(buffer, new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost")); String req = buffer.toString(Charset.forName("US-ASCII")); assertEquals("GET http://localhost/ HTTP/1.1\r\n", req); @@ -42,7 +42,7 @@ public class HttpRequestEncoderTest { public void testUriWithPath() throws Exception { HttpRequestEncoder encoder = new HttpRequestEncoder(); ByteBuf buffer = Unpooled.buffer(64); - encoder.encodeInitialLine(buffer, new DefaultHttpRequestHeader(HttpVersion.HTTP_1_1, + encoder.encodeInitialLine(buffer, new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/")); String req = buffer.toString(Charset.forName("US-ASCII")); assertEquals("GET http://localhost/ HTTP/1.1\r\n", req); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerCodecTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerCodecTest.java index a37b78ea1e..5222839a43 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerCodecTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerCodecTest.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.embedded.EmbeddedByteChannel; import io.netty.util.CharsetUtil; - import org.junit.Assert; import org.junit.Test; @@ -44,8 +43,8 @@ public class HttpServerCodecTest { decoderEmbedder.writeInbound(prepareDataChunk(offeredContentLength)); decoderEmbedder.finish(); - HttpHeader httpMessage = (HttpHeader) decoderEmbedder.readInbound(); - //Assert.assertSame(HttpTransferEncoding.STREAMED, httpMessage.getTransferEncoding()); + HttpMessage httpMessage = (HttpMessage) decoderEmbedder.readInbound(); + Assert.assertNotNull(httpMessage); boolean empty = true; int totalBytesPolled = 0; @@ -55,7 +54,7 @@ public class HttpServerCodecTest { break; } empty = false; - totalBytesPolled += httpChunk.getContent().readableBytes(); + totalBytesPolled += httpChunk.data().readableBytes(); Assert.assertFalse(httpChunk instanceof LastHttpContent); } Assert.assertFalse(empty); 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 35827d3fb1..3667c51bc6 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 @@ -15,15 +15,15 @@ */ package io.netty.handler.codec.http.websocketx; -import static io.netty.handler.codec.http.HttpHeaders.Values.WEBSOCKET; -import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; - -import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpRequestHeader; import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.HttpHeaders.Names; + +import static io.netty.handler.codec.http.HttpHeaders.Values.*; +import static io.netty.handler.codec.http.HttpVersion.*; public class WebSocketRequestBuilder { @@ -96,30 +96,30 @@ public class WebSocketRequestBuilder { return this; } - public HttpRequest build() { - HttpRequest req = new DefaultHttpRequest(httpVersion, method, uri); + public FullHttpRequest build() { + FullHttpRequest req = new DefaultFullHttpRequest(httpVersion, method, uri); if (host != null) { - req.setHeader(Names.HOST, host); + req.headers().set(Names.HOST, host); } if (upgrade != null) { - req.setHeader(Names.UPGRADE, upgrade); + req.headers().set(Names.UPGRADE, upgrade); } if (connection != null) { - req.setHeader(Names.CONNECTION, connection); + req.headers().set(Names.CONNECTION, connection); } if (key != null) { - req.setHeader(Names.SEC_WEBSOCKET_KEY, key); + req.headers().set(Names.SEC_WEBSOCKET_KEY, key); } if (origin != null) { - req.setHeader(Names.SEC_WEBSOCKET_ORIGIN, origin); + req.headers().set(Names.SEC_WEBSOCKET_ORIGIN, origin); } if (version != null) { - req.setHeader(Names.SEC_WEBSOCKET_VERSION, version.toHttpHeaderValue()); + req.headers().set(Names.SEC_WEBSOCKET_VERSION, version.toHttpHeaderValue()); } return req; } - public static HttpRequestHeader sucessful() { + public static HttpRequest sucessful() { return new WebSocketRequestBuilder().httpVersion(HTTP_1_1) .method(HttpMethod.GET) .uri("/test") 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 a219521583..9ab06c183a 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 @@ -15,26 +15,26 @@ */ package io.netty.handler.codec.http.websocketx; -import static io.netty.handler.codec.http.HttpHeaders.Values.*; -import static io.netty.handler.codec.http.HttpVersion.*; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.embedded.EmbeddedByteChannel; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.codec.http.HttpResponseHeader; import io.netty.handler.codec.http.LastHttpContent; import io.netty.util.CharsetUtil; - import org.junit.Assert; import org.junit.Test; +import static io.netty.handler.codec.http.HttpHeaders.Values.*; +import static io.netty.handler.codec.http.HttpVersion.*; + public class WebSocketServerHandshaker00Test { @Test @@ -42,17 +42,16 @@ public class WebSocketServerHandshaker00Test { EmbeddedByteChannel ch = new EmbeddedByteChannel( new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder()); - HttpRequest req = new DefaultHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"); - req.setHeader(Names.HOST, "server.example.com"); - req.setHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); - req.setHeader(Names.CONNECTION, "Upgrade"); - req.setHeader(Names.ORIGIN, "http://example.com"); - req.setHeader(Names.SEC_WEBSOCKET_KEY1, "4 @1 46546xW%0l 1 5"); - req.setHeader(Names.SEC_WEBSOCKET_KEY2, "12998 5 Y3 1 .P00"); - req.setHeader(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); + FullHttpRequest req = new DefaultFullHttpRequest( + HTTP_1_1, HttpMethod.GET, "/chat", Unpooled.copiedBuffer("^n:ds[4U", CharsetUtil.US_ASCII)); - ByteBuf buffer = Unpooled.copiedBuffer("^n:ds[4U", CharsetUtil.US_ASCII); - req.setContent(buffer); + req.headers().set(Names.HOST, "server.example.com"); + req.headers().set(Names.UPGRADE, WEBSOCKET.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"); + req.headers().set(Names.SEC_WEBSOCKET_KEY2, "12998 5 Y3 1 .P00"); + req.headers().set(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); new WebSocketServerHandshaker00( "ws://example.com/chat", "chat", Integer.MAX_VALUE).handshake(ch, req); @@ -61,12 +60,12 @@ public class WebSocketServerHandshaker00Test { EmbeddedByteChannel ch2 = new EmbeddedByteChannel(new HttpResponseDecoder()); ch2.writeInbound(resBuf); - HttpResponseHeader res = (HttpResponseHeader) ch2.readInbound(); + HttpResponse res = (HttpResponse) ch2.readInbound(); - Assert.assertEquals("ws://example.com/chat", res.getHeader(Names.SEC_WEBSOCKET_LOCATION)); - Assert.assertEquals("chat", res.getHeader(Names.SEC_WEBSOCKET_PROTOCOL)); + Assert.assertEquals("ws://example.com/chat", res.headers().get(Names.SEC_WEBSOCKET_LOCATION)); + Assert.assertEquals("chat", res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL)); LastHttpContent content = (LastHttpContent) ch2.readInbound(); - Assert.assertEquals("8jKS'y:G*Co,Wxa-", content.getContent().toString(CharsetUtil.US_ASCII)); + Assert.assertEquals("8jKS'y:G*Co,Wxa-", content.data().toString(CharsetUtil.US_ASCII)); } } 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 69161c7eae..f49ac6b101 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 @@ -15,23 +15,23 @@ */ package io.netty.handler.codec.http.websocketx; -import static io.netty.handler.codec.http.HttpHeaders.Values.*; -import static io.netty.handler.codec.http.HttpVersion.*; import io.netty.buffer.ByteBuf; import io.netty.channel.embedded.EmbeddedByteChannel; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; - import org.junit.Assert; import org.junit.Test; +import static io.netty.handler.codec.http.HttpHeaders.Values.*; +import static io.netty.handler.codec.http.HttpVersion.*; + public class WebSocketServerHandshaker08Test { @Test @@ -39,14 +39,14 @@ public class WebSocketServerHandshaker08Test { EmbeddedByteChannel ch = new EmbeddedByteChannel( new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder()); - HttpRequest req = new DefaultHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"); - req.setHeader(Names.HOST, "server.example.com"); - req.setHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); - req.setHeader(Names.CONNECTION, "Upgrade"); - req.setHeader(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); - req.setHeader(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); - req.setHeader(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); - req.setHeader(Names.SEC_WEBSOCKET_VERSION, "8"); + 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.CONNECTION, "Upgrade"); + req.headers().set(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); + req.headers().set(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); + req.headers().set(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); + req.headers().set(Names.SEC_WEBSOCKET_VERSION, "8"); new WebSocketServerHandshaker08( "ws://example.com/chat", "chat", false, Integer.MAX_VALUE).handshake(ch, req); @@ -55,10 +55,10 @@ public class WebSocketServerHandshaker08Test { EmbeddedByteChannel ch2 = new EmbeddedByteChannel(new HttpResponseDecoder()); ch2.writeInbound(resBuf); - HttpResponseHeader res = (HttpResponseHeader) ch2.readInbound(); + HttpResponse res = (HttpResponse) ch2.readInbound(); Assert.assertEquals( - "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.getHeader(Names.SEC_WEBSOCKET_ACCEPT)); - Assert.assertEquals("chat", res.getHeader(Names.SEC_WEBSOCKET_PROTOCOL)); + "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.headers().get(Names.SEC_WEBSOCKET_ACCEPT)); + Assert.assertEquals("chat", res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL)); } } 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 020627e562..791de6a604 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 @@ -15,23 +15,23 @@ */ package io.netty.handler.codec.http.websocketx; -import static io.netty.handler.codec.http.HttpHeaders.Values.*; -import static io.netty.handler.codec.http.HttpVersion.*; import io.netty.buffer.ByteBuf; import io.netty.channel.embedded.EmbeddedByteChannel; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders.Names; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; - import org.junit.Assert; import org.junit.Test; +import static io.netty.handler.codec.http.HttpHeaders.Values.*; +import static io.netty.handler.codec.http.HttpVersion.*; + public class WebSocketServerHandshaker13Test { @Test @@ -39,14 +39,14 @@ public class WebSocketServerHandshaker13Test { EmbeddedByteChannel ch = new EmbeddedByteChannel( new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder()); - HttpRequest req = new DefaultHttpRequest(HTTP_1_1, HttpMethod.GET, "/chat"); - req.setHeader(Names.HOST, "server.example.com"); - req.setHeader(Names.UPGRADE, WEBSOCKET.toLowerCase()); - req.setHeader(Names.CONNECTION, "Upgrade"); - req.setHeader(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); - req.setHeader(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); - req.setHeader(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); - req.setHeader(Names.SEC_WEBSOCKET_VERSION, "13"); + 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.CONNECTION, "Upgrade"); + req.headers().set(Names.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ=="); + req.headers().set(Names.SEC_WEBSOCKET_ORIGIN, "http://example.com"); + req.headers().set(Names.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); + req.headers().set(Names.SEC_WEBSOCKET_VERSION, "13"); new WebSocketServerHandshaker13( "ws://example.com/chat", "chat", false, Integer.MAX_VALUE).handshake(ch, req); @@ -55,10 +55,10 @@ public class WebSocketServerHandshaker13Test { EmbeddedByteChannel ch2 = new EmbeddedByteChannel(new HttpResponseDecoder()); ch2.writeInbound(resBuf); - HttpResponseHeader res = (HttpResponseHeader) ch2.readInbound(); + HttpResponse res = (HttpResponse) ch2.readInbound(); Assert.assertEquals( - "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.getHeader(Names.SEC_WEBSOCKET_ACCEPT)); - Assert.assertEquals("chat", res.getHeader(Names.SEC_WEBSOCKET_PROTOCOL)); + "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", res.headers().get(Names.SEC_WEBSOCKET_ACCEPT)); + Assert.assertEquals("chat", res.headers().get(Names.SEC_WEBSOCKET_PROTOCOL)); } } 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 7b631fc686..4bf7fc0a9f 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 @@ -22,13 +22,13 @@ import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelOutboundMessageHandlerAdapter; import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedMessageChannel; -import io.netty.handler.codec.http.DefaultHttpRequestHeader; +import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpRequestHeader; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseHeader; import io.netty.handler.codec.http.HttpResponseEncoder; import org.junit.Test; @@ -46,7 +46,7 @@ public class WebSocketServerProtocolHandlerTest { writeUpgradeRequest(ch); - assertEquals(SWITCHING_PROTOCOLS, ((HttpResponseHeader) ch.outboundMessageBuffer().poll()).getStatus()); + assertEquals(SWITCHING_PROTOCOLS, ((HttpResponse) ch.outboundMessageBuffer().poll()).status()); assertNotNull(WebSocketServerProtocolHandler.getHandshaker(handshakerCtx)); } @@ -55,16 +55,16 @@ public class WebSocketServerProtocolHandlerTest { EmbeddedMessageChannel ch = createChannel(new MockOutboundHandler()); writeUpgradeRequest(ch); - assertEquals(SWITCHING_PROTOCOLS, ((HttpResponseHeader) ch.outboundMessageBuffer().poll()).getStatus()); + assertEquals(SWITCHING_PROTOCOLS, ((HttpResponse) ch.outboundMessageBuffer().poll()).status()); - ch.writeInbound(new DefaultHttpRequestHeader(HTTP_1_1, HttpMethod.GET, "/test")); - assertEquals(FORBIDDEN, ((HttpResponseHeader) ch.outboundMessageBuffer().poll()).getStatus()); + ch.writeInbound(new DefaultHttpRequest(HTTP_1_1, HttpMethod.GET, "/test")); + assertEquals(FORBIDDEN, ((HttpResponse) ch.outboundMessageBuffer().poll()).status()); } @Test public void testHttpUpgradeRequestInvalidUpgradeHeader() { EmbeddedMessageChannel ch = createChannel(); - HttpRequest httpRequest = new WebSocketRequestBuilder().httpVersion(HTTP_1_1) + FullHttpRequest httpRequestWithEntity = new WebSocketRequestBuilder().httpVersion(HTTP_1_1) .method(HttpMethod.GET) .uri("/test") .connection("Upgrade") @@ -72,10 +72,10 @@ public class WebSocketServerProtocolHandlerTest { .upgrade("BogusSocket") .build(); - ch.writeInbound(httpRequest); + ch.writeInbound(httpRequestWithEntity); - HttpResponse response = getHttpResponse(ch); - assertEquals(BAD_REQUEST, response.getStatus()); + FullHttpResponse response = getHttpResponse(ch); + assertEquals(BAD_REQUEST, response.status()); assertEquals("not a WebSocket handshake request: missing upgrade", getResponseMessage(response)); } @@ -83,7 +83,7 @@ public class WebSocketServerProtocolHandlerTest { @Test public void testHttpUpgradeRequestMissingWSKeyHeader() { EmbeddedMessageChannel ch = createChannel(); - HttpRequestHeader httpRequest = new WebSocketRequestBuilder().httpVersion(HTTP_1_1) + HttpRequest httpRequest = new WebSocketRequestBuilder().httpVersion(HTTP_1_1) .method(HttpMethod.GET) .uri("/test") .key(null) @@ -94,8 +94,8 @@ public class WebSocketServerProtocolHandlerTest { ch.writeInbound(httpRequest); - HttpResponse response = getHttpResponse(ch); - assertEquals(BAD_REQUEST, response.getStatus()); + FullHttpResponse response = getHttpResponse(ch); + assertEquals(BAD_REQUEST, response.status()); assertEquals("not a WebSocket request: missing key", getResponseMessage(response)); } @@ -129,13 +129,13 @@ public class WebSocketServerProtocolHandlerTest { ch.writeInbound(WebSocketRequestBuilder.sucessful()); } - private static String getResponseMessage(HttpResponse response) { - return new String(response.getContent().array()); + private static String getResponseMessage(FullHttpResponse response) { + return new String(response.data().array()); } - private static HttpResponse getHttpResponse(EmbeddedMessageChannel ch) { + private static FullHttpResponse getHttpResponse(EmbeddedMessageChannel ch) { MessageBuf outbound = ch.pipeline().context(MockOutboundHandler.class).outboundMessageBuffer(); - return (HttpResponse) outbound.poll(); + return (FullHttpResponse) outbound.poll(); } private static class MockOutboundHandler extends ChannelOutboundMessageHandlerAdapter { diff --git a/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java b/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java index 4f55afc02b..65848dfd21 100644 --- a/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java +++ b/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java @@ -20,10 +20,10 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; -import io.netty.handler.codec.http.DefaultHttpResponse; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.stream.ChunkedFile; import io.netty.util.CharsetUtil; @@ -94,7 +94,7 @@ import static io.netty.handler.codec.http.HttpVersion.*; * * */ -public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAdapter { +public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAdapter { public static final String HTTP_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz"; public static final String HTTP_DATE_GMT_TIMEZONE = "GMT"; @@ -102,19 +102,19 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda @Override public void messageReceived( - ChannelHandlerContext ctx, HttpRequest request) throws Exception { + ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { - if (!request.getDecoderResult().isSuccess()) { + if (!request.decoderResult().isSuccess()) { sendError(ctx, BAD_REQUEST); return; } - if (request.getMethod() != GET) { + if (request.method() != GET) { sendError(ctx, METHOD_NOT_ALLOWED); return; } - final String uri = request.getUri(); + final String uri = request.uri(); final String path = sanitizeUri(uri); if (path == null) { sendError(ctx, FORBIDDEN); @@ -142,7 +142,7 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda } // Cache Validation - String ifModifiedSince = request.getHeader(IF_MODIFIED_SINCE); + String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE); if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince); @@ -166,12 +166,12 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda } long fileLength = raf.length(); - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); + FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK); setContentLength(response, fileLength); setContentTypeHeader(response, file); setDateAndCacheHeaders(response, file); if (isKeepAlive(request)) { - response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } // Write the initial line and the header. @@ -232,8 +232,8 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda private static final Pattern ALLOWED_FILE_NAME = Pattern.compile("[A-Za-z0-9][-_A-Za-z0-9\\.]*"); private static void sendListing(ChannelHandlerContext ctx, File dir) { - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); - response.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); + FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK); + response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); StringBuilder buf = new StringBuilder(); String dirPath = dir.getPath(); @@ -270,26 +270,24 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda buf.append("\r\n"); - response.setContent(Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8)); + response.data().writeBytes(Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8)); // Close the connection as soon as the error message is sent. ctx.write(response).addListener(ChannelFutureListener.CLOSE); } private static void sendRedirect(ChannelHandlerContext ctx, String newUri) { - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, FOUND); - response.setHeader(LOCATION, newUri); + FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, FOUND); + response.headers().set(LOCATION, newUri); // Close the connection as soon as the error message is sent. ctx.write(response).addListener(ChannelFutureListener.CLOSE); } private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status); - response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); - response.setContent(Unpooled.copiedBuffer( - "Failure: " + status.toString() + "\r\n", - CharsetUtil.UTF_8)); + FullHttpResponse response = new DefaultFullHttpResponse( + HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8)); + response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); // Close the connection as soon as the error message is sent. ctx.write(response).addListener(ChannelFutureListener.CLOSE); @@ -302,7 +300,7 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda * Context */ private static void sendNotModified(ChannelHandlerContext ctx) { - HttpResponse response = new DefaultHttpResponse(HTTP_1_1, NOT_MODIFIED); + FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED); setDateHeader(response); // Close the connection as soon as the error message is sent. @@ -315,12 +313,12 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda * @param response * HTTP response */ - private static void setDateHeader(HttpResponse response) { + private static void setDateHeader(FullHttpResponse response) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); dateFormatter.setTimeZone(TimeZone.getTimeZone(HTTP_DATE_GMT_TIMEZONE)); Calendar time = new GregorianCalendar(); - response.setHeader(DATE, dateFormatter.format(time.getTime())); + response.headers().set(DATE, dateFormatter.format(time.getTime())); } /** @@ -331,19 +329,19 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda * @param fileToCache * file to extract content type */ - private static void setDateAndCacheHeaders(HttpResponse response, File fileToCache) { + private static void setDateAndCacheHeaders(FullHttpResponse response, File fileToCache) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); dateFormatter.setTimeZone(TimeZone.getTimeZone(HTTP_DATE_GMT_TIMEZONE)); // Date header Calendar time = new GregorianCalendar(); - response.setHeader(DATE, dateFormatter.format(time.getTime())); + response.headers().set(DATE, dateFormatter.format(time.getTime())); // Add cache headers time.add(Calendar.SECOND, HTTP_CACHE_SECONDS); - response.setHeader(EXPIRES, dateFormatter.format(time.getTime())); - response.setHeader(CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS); - response.setHeader( + response.headers().set(EXPIRES, dateFormatter.format(time.getTime())); + response.headers().set(CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS); + response.headers().set( LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified()))); } @@ -355,9 +353,9 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda * @param file * file to extract content type */ - private static void setContentTypeHeader(HttpResponse response, File file) { + private static void setContentTypeHeader(FullHttpResponse response, File file) { MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap(); - response.setHeader(CONTENT_TYPE, mimeTypesMap.getContentType(file.getPath())); + response.headers().set(CONTENT_TYPE, mimeTypesMap.getContentType(file.getPath())); } } diff --git a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java index ae9ff9baeb..ed3bfbfcdf 100644 --- a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java +++ b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java @@ -21,10 +21,10 @@ import io.netty.channel.socket.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.ClientCookieEncoder; import io.netty.handler.codec.http.DefaultCookie; -import io.netty.handler.codec.http.DefaultHttpRequestHeader; +import io.netty.handler.codec.http.DefaultHttpRequest; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequestHeader; +import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpVersion; import java.net.InetSocketAddress; @@ -73,14 +73,14 @@ public class HttpSnoopClient { Channel ch = b.connect().sync().channel(); // Prepare the HTTP request. - HttpRequestHeader request = new DefaultHttpRequestHeader( + HttpRequest request = new DefaultHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath()); - request.setHeader(HttpHeaders.Names.HOST, host); - request.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); - request.setHeader(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); + request.headers().set(HttpHeaders.Names.HOST, host); + request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); + request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); // Set some example cookies. - request.setHeader( + request.headers().set( HttpHeaders.Names.COOKIE, ClientCookieEncoder.encode( new DefaultCookie("my-cookie", "foo"), diff --git a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClientHandler.java b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClientHandler.java index 403d03a4e5..359af295d2 100644 --- a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClientHandler.java +++ b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClientHandler.java @@ -19,7 +19,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.LastHttpContent; import io.netty.util.CharsetUtil; @@ -27,16 +27,16 @@ public class HttpSnoopClientHandler extends ChannelInboundMessageHandlerAdapter< @Override public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpResponseHeader) { - HttpResponseHeader response = (HttpResponseHeader) msg; + if (msg instanceof HttpResponse) { + HttpResponse response = (HttpResponse) msg; - System.out.println("STATUS: " + response.getStatus()); - System.out.println("VERSION: " + response.getProtocolVersion()); + System.out.println("STATUS: " + response.status()); + System.out.println("VERSION: " + response.protocolVersion()); System.out.println(); - if (!response.getHeaderNames().isEmpty()) { - for (String name: response.getHeaderNames()) { - for (String value: response.getHeaders(name)) { + if (!response.headers().isEmpty()) { + for (String name: response.headers().names()) { + for (String value: response.headers().getAll(name)) { System.out.println("HEADER: " + name + " = " + value); } } @@ -52,7 +52,7 @@ public class HttpSnoopClientHandler extends ChannelInboundMessageHandlerAdapter< if (msg instanceof HttpContent) { HttpContent content = (HttpContent) msg; - System.out.print(content.getContent().toString(CharsetUtil.UTF_8)); + System.out.print(content.data().toString(CharsetUtil.UTF_8)); System.out.flush(); if (content instanceof LastHttpContent) { diff --git a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerHandler.java b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerHandler.java index 7eea87811d..1128e0e30a 100644 --- a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerHandler.java +++ b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerHandler.java @@ -24,15 +24,15 @@ import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.handler.codec.DecoderResult; import io.netty.handler.codec.http.Cookie; import io.netty.handler.codec.http.CookieDecoder; +import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultHttpResponse; -import io.netty.handler.codec.http.DefaultHttpResponseHeader; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpRequestHeader; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseHeader; -import io.netty.handler.codec.http.LastHttpContent; import io.netty.handler.codec.http.HttpObject; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.LastHttpContent; import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.ServerCookieEncoder; import io.netty.util.CharsetUtil; @@ -49,15 +49,14 @@ import static io.netty.handler.codec.http.HttpVersion.*; public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter { - private HttpRequestHeader request; - private boolean readingChunks; + private HttpRequest request; /** Buffer that stores the response content */ private final StringBuilder buf = new StringBuilder(); @Override public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpRequestHeader) { - HttpRequestHeader request = this.request = (HttpRequestHeader) msg; + if (msg instanceof HttpRequest) { + HttpRequest request = this.request = (HttpRequest) msg; if (is100ContinueExpected(request)) { send100Continue(ctx); @@ -67,13 +66,13 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter< buf.append("WELCOME TO THE WILD WILD WEB SERVER\r\n"); buf.append("===================================\r\n"); - buf.append("VERSION: ").append(request.getProtocolVersion()).append("\r\n"); + buf.append("VERSION: ").append(request.protocolVersion()).append("\r\n"); buf.append("HOSTNAME: ").append(getHost(request, "unknown")).append("\r\n"); - buf.append("REQUEST_URI: ").append(request.getUri()).append("\r\n\r\n"); + buf.append("REQUEST_URI: ").append(request.uri()).append("\r\n\r\n"); - List> headers = request.getHeaders(); + List> headers = request.headers().entries(); if (!headers.isEmpty()) { - for (Map.Entry h: request.getHeaders()) { + for (Map.Entry h: request.headers().entries()) { String key = h.getKey(); String value = h.getValue(); buf.append("HEADER: ").append(key).append(" = ").append(value).append("\r\n"); @@ -81,7 +80,7 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter< buf.append("\r\n"); } - QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri()); + QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.uri()); Map> params = queryStringDecoder.getParameters(); if (!params.isEmpty()) { for (Entry> p: params.entrySet()) { @@ -94,40 +93,28 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter< buf.append("\r\n"); } - if (isTransferEncodingChunked(request)) { - readingChunks = true; - } else { - appendDecoderResult(buf, request); - } + appendDecoderResult(buf, request); } + if (msg instanceof HttpContent) { HttpContent httpContent = (HttpContent) msg; - ByteBuf content = httpContent.getContent(); + ByteBuf content = httpContent.data(); if (content.readable()) { buf.append("CONTENT: "); buf.append(content.toString(CharsetUtil.UTF_8)); buf.append("\r\n"); + appendDecoderResult(buf, request); } - appendDecoderResult(buf, request); - writeResponse(ctx, request); if (msg instanceof LastHttpContent) { - if (readingChunks) { - buf.append("CHUNK: "); - } else { - buf.append("CONTENT: "); - } - buf.append(content.toString(CharsetUtil.UTF_8)).append("\r\n"); - - readingChunks = false; buf.append("END OF CONTENT\r\n"); LastHttpContent trailer = (LastHttpContent) msg; - if (!trailer.getHeaderNames().isEmpty()) { + if (!trailer.trailingHeaders().isEmpty()) { buf.append("\r\n"); - for (String name: trailer.getHeaderNames()) { - for (String value: trailer.getHeaders(name)) { + for (String name: trailer.trailingHeaders().names()) { + for (String value: trailer.trailingHeaders().getAll(name)) { buf.append("TRAILING HEADER: "); buf.append(name).append(" = ").append(value).append("\r\n"); } @@ -135,20 +122,13 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter< buf.append("\r\n"); } - appendDecoderResult(buf, trailer); writeResponse(ctx, trailer); - } else { - if (readingChunks) { - buf.append("CHUNK: "); - } - buf.append(content.toString(CharsetUtil.UTF_8)).append("\r\n"); - appendDecoderResult(buf, httpContent); } } } private static void appendDecoderResult(StringBuilder buf, HttpObject o) { - DecoderResult result = o.getDecoderResult(); + DecoderResult result = o.decoderResult(); if (result.isSuccess()) { return; } @@ -167,34 +147,34 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter< boolean keepAlive = isKeepAlive(request); // Build the response object. - HttpResponse response = new DefaultHttpResponse( - HTTP_1_1, currentObj.getDecoderResult().isSuccess()? OK : BAD_REQUEST); + FullHttpResponse response = new DefaultFullHttpResponse( + HTTP_1_1, currentObj.decoderResult().isSuccess()? OK : BAD_REQUEST, + Unpooled.copiedBuffer(buf.toString(), CharsetUtil.UTF_8)); - response.setContent(Unpooled.copiedBuffer(buf.toString(), CharsetUtil.UTF_8)); - response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); + response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); if (keepAlive) { // Add 'Content-Length' header only for a keep-alive connection. - response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes()); + response.headers().set(CONTENT_LENGTH, response.data().readableBytes()); // Add keep alive header as per: // - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection - response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } // Encode the cookie. - String cookieString = request.getHeader(COOKIE); + String cookieString = request.headers().get(COOKIE); if (cookieString != null) { Set cookies = CookieDecoder.decode(cookieString); if (!cookies.isEmpty()) { // Reset the cookies if necessary. for (Cookie cookie: cookies) { - response.addHeader(SET_COOKIE, ServerCookieEncoder.encode(cookie)); + response.headers().add(SET_COOKIE, ServerCookieEncoder.encode(cookie)); } } } else { // Browser sent no cookie. Add some. - response.addHeader(SET_COOKIE, ServerCookieEncoder.encode("key1", "value1")); - response.addHeader(SET_COOKIE, ServerCookieEncoder.encode("key2", "value2")); + response.headers().add(SET_COOKIE, ServerCookieEncoder.encode("key1", "value1")); + response.headers().add(SET_COOKIE, ServerCookieEncoder.encode("key2", "value2")); } // Write the response. @@ -207,7 +187,7 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter< } private static void send100Continue(ChannelHandlerContext ctx) { - HttpResponseHeader response = new DefaultHttpResponseHeader(HTTP_1_1, CONTINUE); + HttpResponse response = new DefaultHttpResponse(HTTP_1_1, CONTINUE); ctx.write(response); } diff --git a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerInitializer.java b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerInitializer.java index 56333b13f9..8c95cc9d4b 100644 --- a/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerInitializer.java +++ b/example/src/main/java/io/netty/example/http/snoop/HttpSnoopServerInitializer.java @@ -18,7 +18,6 @@ package io.netty.example.http.snoop; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; -import io.netty.handler.codec.http.HttpContentCompressor; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; @@ -38,7 +37,7 @@ public class HttpSnoopServerInitializer extends ChannelInitializer> headers = request.getHeaders(); - channel.write(request); + List> entries = headers.entries(); + channel.write(request).sync(); // Wait for the server to close the connection. channel.closeFuture().sync(); - return headers; + return entries; } /** @@ -220,7 +218,8 @@ public class HttpUploadClient { Channel channel = bootstrap.connect().sync().channel(); // Prepare the HTTP request. - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriSimple.toASCIIString()); + FullHttpRequest request = + new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriSimple.toASCIIString()); // Use the PostBody encoder HttpPostRequestEncoder bodyRequestEncoder = null; @@ -236,7 +235,7 @@ public class HttpUploadClient { // it is legal to add directly header or cookie into the request until finalize for (Entry entry : headers) { - request.setHeader(entry.getKey(), entry.getValue()); + request.headers().set(entry.getKey(), entry.getValue()); } // add Form attribute @@ -304,7 +303,8 @@ public class HttpUploadClient { Channel channel = bootstrap.connect().sync().channel(); // Prepare the HTTP request. - HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriFile.toASCIIString()); + FullHttpRequest request = + new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriFile.toASCIIString()); // Use the PostBody encoder HttpPostRequestEncoder bodyRequestEncoder = null; @@ -320,7 +320,7 @@ public class HttpUploadClient { // it is legal to add directly header or cookie into the request until finalize for (Entry entry : headers) { - request.setHeader(entry.getKey(), entry.getValue()); + request.headers().set(entry.getKey(), entry.getValue()); } // add Form attribute from previous request in formpost() diff --git a/example/src/main/java/io/netty/example/http/upload/HttpUploadClientHandler.java b/example/src/main/java/io/netty/example/http/upload/HttpUploadClientHandler.java index 92c3a52755..01c0d3084e 100644 --- a/example/src/main/java/io/netty/example/http/upload/HttpUploadClientHandler.java +++ b/example/src/main/java/io/netty/example/http/upload/HttpUploadClientHandler.java @@ -19,7 +19,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpResponseHeader; +import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.LastHttpContent; import io.netty.logging.InternalLogger; import io.netty.logging.InternalLoggerFactory; @@ -36,21 +36,21 @@ public class HttpUploadClientHandler extends ChannelInboundMessageHandlerAdapter @Override public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpResponseHeader) { - HttpResponseHeader response = (HttpResponseHeader) msg; + if (msg instanceof HttpResponse) { + HttpResponse response = (HttpResponse) msg; - logger.info("STATUS: " + response.getStatus()); - logger.info("VERSION: " + response.getProtocolVersion()); + logger.info("STATUS: " + response.status()); + logger.info("VERSION: " + response.protocolVersion()); - if (!response.getHeaderNames().isEmpty()) { - for (String name : response.getHeaderNames()) { - for (String value : response.getHeaders(name)) { + if (!response.headers().isEmpty()) { + for (String name : response.headers().names()) { + for (String value : response.headers().getAll(name)) { logger.info("HEADER: " + name + " = " + value); } } } - if (response.getStatus().getCode() == 200 && HttpHeaders.isTransferEncodingChunked(response)) { + if (response.status().code() == 200 && HttpHeaders.isTransferEncodingChunked(response)) { readingChunks = true; logger.info("CHUNKED CONTENT {"); } else { @@ -59,7 +59,7 @@ public class HttpUploadClientHandler extends ChannelInboundMessageHandlerAdapter } if (msg instanceof HttpContent) { HttpContent chunk = (HttpContent) msg; - logger.info(chunk.getContent().toString(CharsetUtil.UTF_8)); + logger.info(chunk.data().toString(CharsetUtil.UTF_8)); if (chunk instanceof LastHttpContent) { if (readingChunks) { @@ -69,7 +69,7 @@ public class HttpUploadClientHandler extends ChannelInboundMessageHandlerAdapter } readingChunks = false; } else { - logger.info(chunk.getContent().toString(CharsetUtil.UTF_8)); + logger.info(chunk.data().toString(CharsetUtil.UTF_8)); } } } 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 6a150eaf74..e315e0741f 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 @@ -23,11 +23,11 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.handler.codec.http.Cookie; import io.netty.handler.codec.http.CookieDecoder; -import io.netty.handler.codec.http.DefaultHttpResponse; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpRequestHeader; -import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringDecoder; @@ -64,7 +64,7 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter private static final InternalLogger logger = InternalLoggerFactory.getInstance(HttpUploadServerHandler.class); - private HttpRequestHeader request; + private HttpRequest request; private boolean readingChunks; @@ -95,15 +95,15 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter @Override public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpRequestHeader) { + if (msg instanceof HttpRequest) { // clean previous FileUpload if Any if (decoder != null) { decoder.cleanFiles(); decoder = null; } - HttpRequestHeader request = this.request = (HttpRequestHeader) msg; - URI uri = new URI(request.getUri()); + HttpRequest request = this.request = (HttpRequest) msg; + URI uri = new URI(request.uri()); if (!uri.getPath().startsWith("/form")) { // Write Menu writeMenu(ctx); @@ -113,13 +113,13 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter responseContent.append("WELCOME TO THE WILD WILD WEB SERVER\r\n"); responseContent.append("===================================\r\n"); - responseContent.append("VERSION: " + request.getProtocolVersion().getText() + "\r\n"); + responseContent.append("VERSION: " + request.protocolVersion().getText() + "\r\n"); - responseContent.append("REQUEST_URI: " + request.getUri() + "\r\n\r\n"); + responseContent.append("REQUEST_URI: " + request.uri() + "\r\n\r\n"); responseContent.append("\r\n\r\n"); // new method - List> headers = request.getHeaders(); + List> headers = request.headers().entries(); for (Entry entry : headers) { responseContent.append("HEADER: " + entry.getKey() + '=' + entry.getValue() + "\r\n"); } @@ -127,7 +127,7 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter // new method Set cookies; - String value = request.getHeader(COOKIE); + String value = request.headers().get(COOKIE); if (value == null) { cookies = Collections.emptySet(); } else { @@ -138,7 +138,7 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter } responseContent.append("\r\n\r\n"); - QueryStringDecoder decoderQuery = new QueryStringDecoder(request.getUri()); + QueryStringDecoder decoderQuery = new QueryStringDecoder(request.uri()); Map> uriAttributes = decoderQuery.getParameters(); for (Entry> attr: uriAttributes.entrySet()) { for (String attrVal: attr.getValue()) { @@ -300,23 +300,23 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter responseContent.setLength(0); // Decide whether to close the connection or not. - boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.getHeader(CONNECTION)) - || request.getProtocolVersion().equals(HttpVersion.HTTP_1_0) - && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.getHeader(CONNECTION)); + boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION)) + || request.protocolVersion().equals(HttpVersion.HTTP_1_0) + && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION)); // Build the response object. - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - response.setContent(buf); - response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); + FullHttpResponse response = new DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf); + response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); if (!close) { // There's no need to add 'Content-Length' header // if this is the last response. - response.setHeader(CONTENT_LENGTH, String.valueOf(buf.readableBytes())); + response.headers().set(CONTENT_LENGTH, String.valueOf(buf.readableBytes())); } Set cookies; - String value = request.getHeader(COOKIE); + String value = request.headers().get(COOKIE); if (value == null) { cookies = Collections.emptySet(); } else { @@ -325,7 +325,7 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter if (!cookies.isEmpty()) { // Reset the cookies if necessary. for (Cookie cookie : cookies) { - response.addHeader(SET_COOKIE, ServerCookieEncoder.encode(cookie)); + response.headers().add(SET_COOKIE, ServerCookieEncoder.encode(cookie)); } } // Write the response. @@ -410,10 +410,12 @@ public class HttpUploadServerHandler extends ChannelInboundMessageHandlerAdapter ByteBuf buf = copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8); // Build the response object. - HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - response.setContent(buf); - response.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); - response.setHeader(CONTENT_LENGTH, String.valueOf(buf.readableBytes())); + FullHttpResponse response = new DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf); + + response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); + response.headers().set(CONTENT_LENGTH, String.valueOf(buf.readableBytes())); + // Write the response. ctx.channel().write(response); } diff --git a/example/src/main/java/io/netty/example/http/websocketx/autobahn/AutobahnServerHandler.java b/example/src/main/java/io/netty/example/http/websocketx/autobahn/AutobahnServerHandler.java index dc35a6cf97..4f1a21e1d3 100644 --- a/example/src/main/java/io/netty/example/http/websocketx/autobahn/AutobahnServerHandler.java +++ b/example/src/main/java/io/netty/example/http/websocketx/autobahn/AutobahnServerHandler.java @@ -20,10 +20,10 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundMessageHandlerAdapter; -import io.netty.handler.codec.http.DefaultHttpResponse; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame; @@ -52,23 +52,23 @@ public class AutobahnServerHandler extends ChannelInboundMessageHandlerAdapter
    Header NameHeader Value