From bb5764b6311129e2c82babf0a0fc920a43bd813c Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Mon, 9 Nov 2015 08:48:15 -0800 Subject: [PATCH] Remove HttpHeadersUtil Motivation: HttpHeadersUtil methods were previously moved to HttpUtils in 4.1. However this class was not removed when merging from 4.1 to master. Modifications: - Remove HttpHeadersUtil Result: Less duplicate code. --- .../handler/codec/http/HttpHeaderUtil.java | 277 ------------------ .../io/netty/handler/codec/http/HttpUtil.java | 8 +- ...bSocketServerProtocolHandshakeHandler.java | 4 +- .../codec/http/HttpContentCompressorTest.java | 2 +- .../spdy/server/SpdyServerHandler.java | 15 +- .../autobahn/AutobahnServerHandler.java | 13 +- 6 files changed, 22 insertions(+), 297 deletions(-) delete mode 100644 codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderUtil.java diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderUtil.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderUtil.java deleted file mode 100644 index 667d7ba09e..0000000000 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderUtil.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2014 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 java.util.Iterator; -import java.util.List; - -public final class HttpHeaderUtil { - - /** - * Returns {@code true} if and only if the connection can remain open and - * thus 'kept alive'. This methods respects the value of the - * {@code "Connection"} header first and then the return value of - * {@link HttpVersion#isKeepAliveDefault()}. - */ - public static boolean isKeepAlive(HttpMessage message) { - CharSequence connection = message.headers().get(HttpHeaderNames.CONNECTION); - if (connection != null && HttpHeaderValues.CLOSE.contentEqualsIgnoreCase(connection)) { - return false; - } - - if (message.protocolVersion().isKeepAliveDefault()) { - return !HttpHeaderValues.CLOSE.contentEqualsIgnoreCase(connection); - } else { - return HttpHeaderValues.KEEP_ALIVE.contentEqualsIgnoreCase(connection); - } - } - - /** - * Sets the value of the {@code "Connection"} header depending on the - * protocol version of the specified message. This getMethod sets or removes - * the {@code "Connection"} header depending on what the default keep alive - * mode of the message's protocol version is, as specified by - * {@link HttpVersion#isKeepAliveDefault()}. - * - */ - public static void setKeepAlive(HttpMessage message, boolean keepAlive) { - HttpHeaders h = message.headers(); - if (message.protocolVersion().isKeepAliveDefault()) { - if (keepAlive) { - h.remove(HttpHeaderNames.CONNECTION); - } else { - h.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE); - } - } else { - if (keepAlive) { - h.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); - } else { - h.remove(HttpHeaderNames.CONNECTION); - } - } - } - - /** - * Returns the length of the content. Please note that this value is - * not retrieved from {@link HttpContent#content()} but from the - * {@code "Content-Length"} header, and thus they are independent from each - * other. - * - * @return the content length - * - * @throws NumberFormatException - * if the message does not have the {@code "Content-Length"} header - * or its value is not a number - */ - public static long getContentLength(HttpMessage message) { - Long value = message.headers().getLong(HttpHeaderNames.CONTENT_LENGTH); - if (value != null) { - return value; - } - - // We know the content length if it's a Web Socket message even if - // Content-Length header is missing. - long webSocketContentLength = getWebSocketContentLength(message); - if (webSocketContentLength >= 0) { - return webSocketContentLength; - } - - // Otherwise we don't. - throw new NumberFormatException("header not found: " + HttpHeaderNames.CONTENT_LENGTH); - } - - /** - * Returns the length of the content. Please note that this value is - * not retrieved from {@link HttpContent#content()} but from the - * {@code "Content-Length"} header, and thus they are independent from each - * other. - * - * @return the content length or {@code defaultValue} if this message does - * not have the {@code "Content-Length"} header or its value is not - * a number - */ - public static long getContentLength(HttpMessage message, long defaultValue) { - Long value = message.headers().getLong(HttpHeaderNames.CONTENT_LENGTH); - if (value != null) { - return value; - } - - // We know the content length if it's a Web Socket message even if - // Content-Length header is missing. - long webSocketContentLength = getWebSocketContentLength(message); - if (webSocketContentLength >= 0) { - return webSocketContentLength; - } - - // Otherwise we don't. - return defaultValue; - } - - /** - * Get an {@code int} representation of {@link #getContentLength(HttpMessage, long)}. - * @return the content length or {@code defaultValue} if this message does - * not have the {@code "Content-Length"} header or its value is not - * a number. Not to exceed the boundaries of integer. - */ - public static int getContentLength(HttpMessage message, int defaultValue) { - return (int) Math.min(Integer.MAX_VALUE, HttpHeaderUtil.getContentLength(message, (long) defaultValue)); - } - - /** - * 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(HttpMessage message) { - // WebSockset messages have constant content-lengths. - HttpHeaders h = message.headers(); - if (message instanceof HttpRequest) { - HttpRequest req = (HttpRequest) message; - if (HttpMethod.GET.equals(req.method()) && - h.contains(HttpHeaderNames.SEC_WEBSOCKET_KEY1) && - h.contains(HttpHeaderNames.SEC_WEBSOCKET_KEY2)) { - return 8; - } - } else if (message instanceof HttpResponse) { - HttpResponse res = (HttpResponse) message; - if (res.status().code() == 101 && - h.contains(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN) && - h.contains(HttpHeaderNames.SEC_WEBSOCKET_LOCATION)) { - return 16; - } - } - - // Not a web socket message - return -1; - } - - /** - * Sets the {@code "Content-Length"} header. - */ - public static void setContentLength(HttpMessage message, long length) { - message.headers().setLong(HttpHeaderNames.CONTENT_LENGTH, length); - } - - public static boolean isContentLengthSet(HttpMessage m) { - return m.headers().contains(HttpHeaderNames.CONTENT_LENGTH); - } - - /** - * Returns {@code true} if and only if the specified message contains the - * {@code "Expect: 100-continue"} header. - */ - public static boolean is100ContinueExpected(HttpMessage message) { - // Expect: 100-continue is for requests only. - if (!(message instanceof HttpRequest)) { - return false; - } - - // It works only on HTTP/1.1 or later. - if (message.protocolVersion().compareTo(HttpVersion.HTTP_1_1) < 0) { - return false; - } - - // In most cases, there will be one or zero 'Expect' header. - CharSequence value = message.headers().get(HttpHeaderNames.EXPECT); - if (value == null) { - return false; - } - if (HttpHeaderValues.CONTINUE.contentEqualsIgnoreCase(value)) { - return true; - } - - // Multiple 'Expect' headers. Search through them. - return message.headers().contains(HttpHeaderNames.EXPECT, HttpHeaderValues.CONTINUE, true); - } - - /** - * Sets or removes the {@code "Expect: 100-continue"} header to / from the - * specified message. If the specified {@code value} is {@code true}, - * the {@code "Expect: 100-continue"} header is set and all other previous - * {@code "Expect"} headers are removed. Otherwise, all {@code "Expect"} - * headers are removed completely. - */ - public static void set100ContinueExpected(HttpMessage message, boolean expected) { - if (expected) { - message.headers().set(HttpHeaderNames.EXPECT, HttpHeaderValues.CONTINUE); - } else { - message.headers().remove(HttpHeaderNames.EXPECT); - } - } - - /** - * 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(HttpMessage message) { - return message.headers().contains(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED, true); - } - - public static void setTransferEncodingChunked(HttpMessage m, boolean chunked) { - if (chunked) { - m.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); - m.headers().remove(HttpHeaderNames.CONTENT_LENGTH); - } else { - List values = m.headers().getAll(HttpHeaderNames.TRANSFER_ENCODING); - if (values.isEmpty()) { - return; - } - Iterator valuesIt = values.iterator(); - while (valuesIt.hasNext()) { - CharSequence value = valuesIt.next(); - if (HttpHeaderValues.CHUNKED.contentEqualsIgnoreCase(value)) { - valuesIt.remove(); - } - } - if (values.isEmpty()) { - m.headers().remove(HttpHeaderNames.TRANSFER_ENCODING); - } else { - m.headers().set(HttpHeaderNames.TRANSFER_ENCODING, values); - } - } - } - - static void encodeAscii0(CharSequence seq, ByteBuf buf) { - int length = seq.length(); - for (int i = 0 ; i < length; i++) { - buf.writeByte(c2b(seq.charAt(i))); - } - } - - private static byte c2b(char c) { - if (c > 255) { - return '?'; - } - return (byte) c; - } - - private HttpHeaderUtil() { } -} diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java index 2ea6196fe5..ebc33ffb58 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java @@ -21,6 +21,8 @@ import java.net.URI; import java.util.Iterator; import java.util.List; +import static io.netty.util.AsciiString.c2b; + /** * Utility methods useful in the HTTP context. */ @@ -188,7 +190,7 @@ public final class HttpUtil { * a number. Not to exceed the boundaries of integer. */ public static int getContentLength(HttpMessage message, int defaultValue) { - return (int) Math.min(Integer.MAX_VALUE, HttpHeaderUtil.getContentLength(message, (long) defaultValue)); + return (int) Math.min(Integer.MAX_VALUE, HttpUtil.getContentLength(message, (long) defaultValue)); } /** @@ -319,8 +321,4 @@ public final class HttpUtil { buf.writeByte(c2b(seq.charAt(i))); } } - - private static byte c2b(char c) { - return c > 255 ? (byte) '?' : (byte) c; - } } 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 fef101f0cd..c410848180 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 @@ -23,9 +23,9 @@ import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaderUtil; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpUtil; import io.netty.handler.ssl.SslHandler; import static io.netty.handler.codec.http.HttpMethod.*; @@ -91,7 +91,7 @@ class WebSocketServerProtocolHandshakeHandler extends ChannelHandlerAdapter { private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) { ChannelFuture f = ctx.channel().writeAndFlush(res); - if (!HttpHeaderUtil.isKeepAlive(req) || res.status().code() != 200) { + if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) { f.addListener(ChannelFutureListener.CLOSE); } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentCompressorTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentCompressorTest.java index d72d01ec6f..2229cb94e5 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentCompressorTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentCompressorTest.java @@ -296,7 +296,7 @@ public class HttpContentCompressorTest { @Test public void test100Continue() throws Exception { FullHttpRequest request = newRequest(); - HttpHeaderUtil.set100ContinueExpected(request, true); + HttpUtil.set100ContinueExpected(request, true); EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor()); ch.writeInbound(request); diff --git a/example/src/main/java/io/netty/example/spdy/server/SpdyServerHandler.java b/example/src/main/java/io/netty/example/spdy/server/SpdyServerHandler.java index bf2710377f..6a2effad92 100644 --- a/example/src/main/java/io/netty/example/spdy/server/SpdyServerHandler.java +++ b/example/src/main/java/io/netty/example/spdy/server/SpdyServerHandler.java @@ -22,16 +22,19 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpHeaderUtil; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpUtil; import io.netty.util.CharsetUtil; import java.util.Date; -import static io.netty.handler.codec.http.HttpHeaderNames.*; -import static io.netty.handler.codec.http.HttpResponseStatus.*; -import static io.netty.handler.codec.http.HttpVersion.*; +import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; +import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; +import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; +import static io.netty.handler.codec.http.HttpResponseStatus.CONTINUE; +import static io.netty.handler.codec.http.HttpResponseStatus.OK; +import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * HTTP handler that responds with a "Hello World" @@ -43,10 +46,10 @@ public class SpdyServerHandler extends SimpleChannelInboundHandler { if (msg instanceof HttpRequest) { HttpRequest req = (HttpRequest) msg; - if (HttpHeaderUtil.is100ContinueExpected(req)) { + if (HttpUtil.is100ContinueExpected(req)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } - boolean keepAlive = HttpHeaderUtil.isKeepAlive(req); + boolean keepAlive = HttpUtil.isKeepAlive(req); ByteBuf content = Unpooled.copiedBuffer("Hello World " + new Date(), CharsetUtil.UTF_8); diff --git a/testsuite/src/main/java/io/netty/testsuite/websockets/autobahn/AutobahnServerHandler.java b/testsuite/src/main/java/io/netty/testsuite/websockets/autobahn/AutobahnServerHandler.java index 4253a5c3a6..8754f62e56 100644 --- a/testsuite/src/main/java/io/netty/testsuite/websockets/autobahn/AutobahnServerHandler.java +++ b/testsuite/src/main/java/io/netty/testsuite/websockets/autobahn/AutobahnServerHandler.java @@ -24,8 +24,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpHeaderUtil; import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpUtil; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame; @@ -41,9 +41,10 @@ import io.netty.util.internal.StringUtil; import java.util.logging.Level; import java.util.logging.Logger; -import static io.netty.handler.codec.http.HttpMethod.*; -import static io.netty.handler.codec.http.HttpResponseStatus.*; -import static io.netty.handler.codec.http.HttpVersion.*; +import static io.netty.handler.codec.http.HttpMethod.GET; +import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST; +import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN; +import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * Handles handshakes and messages @@ -124,12 +125,12 @@ public class AutobahnServerHandler extends ChannelHandlerAdapter { ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(), CharsetUtil.UTF_8); res.content().writeBytes(buf); buf.release(); - HttpHeaderUtil.setContentLength(res, res.content().readableBytes()); + HttpUtil.setContentLength(res, res.content().readableBytes()); } // Send the response and close the connection if necessary. ChannelFuture f = ctx.channel().writeAndFlush(res); - if (!HttpHeaderUtil.isKeepAlive(req) || res.status().code() != 200) { + if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) { f.addListener(ChannelFutureListener.CLOSE); } }