/* * Copyright 2015 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.CharsetUtil; import io.netty.util.ReferenceCountUtil; import org.junit.Test; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static io.netty.handler.codec.http.HttpHeadersTestUtils.of; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class HttpUtilTest { @Test public void testRemoveTransferEncodingIgnoreCase() { HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); message.headers().set(HttpHeaderNames.TRANSFER_ENCODING, "Chunked"); assertFalse(message.headers().isEmpty()); HttpUtil.setTransferEncodingChunked(message, false); assertTrue(message.headers().isEmpty()); } // Test for https://github.com/netty/netty/issues/1690 @Test public void testGetOperations() { HttpHeaders headers = new DefaultHttpHeaders(); headers.add(of("Foo"), of("1")); headers.add(of("Foo"), of("2")); assertEquals("1", headers.get(of("Foo"))); List<String> values = headers.getAll(of("Foo")); assertEquals(2, values.size()); assertEquals("1", values.get(0)); assertEquals("2", values.get(1)); } @Test public void testGetCharsetAsRawCharSequence() { String QUOTES_CHARSET_CONTENT_TYPE = "text/html; charset=\"utf8\""; String SIMPLE_CONTENT_TYPE = "text/html"; HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); message.headers().set(HttpHeaderNames.CONTENT_TYPE, QUOTES_CHARSET_CONTENT_TYPE); assertEquals("\"utf8\"", HttpUtil.getCharsetAsSequence(message)); assertEquals("\"utf8\"", HttpUtil.getCharsetAsSequence(QUOTES_CHARSET_CONTENT_TYPE)); message.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html"); assertNull(HttpUtil.getCharsetAsSequence(message)); assertNull(HttpUtil.getCharsetAsSequence(SIMPLE_CONTENT_TYPE)); } @Test public void testGetCharset() { String NORMAL_CONTENT_TYPE = "text/html; charset=utf-8"; String UPPER_CASE_NORMAL_CONTENT_TYPE = "TEXT/HTML; CHARSET=UTF-8"; HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); message.headers().set(HttpHeaderNames.CONTENT_TYPE, NORMAL_CONTENT_TYPE); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(message)); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(NORMAL_CONTENT_TYPE)); message.headers().set(HttpHeaderNames.CONTENT_TYPE, UPPER_CASE_NORMAL_CONTENT_TYPE); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(message)); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(UPPER_CASE_NORMAL_CONTENT_TYPE)); } @Test public void testGetCharset_defaultValue() { final String SIMPLE_CONTENT_TYPE = "text/html"; final String CONTENT_TYPE_WITH_INCORRECT_CHARSET = "text/html; charset=UTFFF"; HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); message.headers().set(HttpHeaderNames.CONTENT_TYPE, SIMPLE_CONTENT_TYPE); assertEquals(CharsetUtil.ISO_8859_1, HttpUtil.getCharset(message)); assertEquals(CharsetUtil.ISO_8859_1, HttpUtil.getCharset(SIMPLE_CONTENT_TYPE)); message.headers().set(HttpHeaderNames.CONTENT_TYPE, SIMPLE_CONTENT_TYPE); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(message, StandardCharsets.UTF_8)); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(SIMPLE_CONTENT_TYPE, StandardCharsets.UTF_8)); message.headers().set(HttpHeaderNames.CONTENT_TYPE, CONTENT_TYPE_WITH_INCORRECT_CHARSET); assertEquals(CharsetUtil.ISO_8859_1, HttpUtil.getCharset(message)); assertEquals(CharsetUtil.ISO_8859_1, HttpUtil.getCharset(CONTENT_TYPE_WITH_INCORRECT_CHARSET)); message.headers().set(HttpHeaderNames.CONTENT_TYPE, CONTENT_TYPE_WITH_INCORRECT_CHARSET); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(message, StandardCharsets.UTF_8)); assertEquals(CharsetUtil.UTF_8, HttpUtil.getCharset(CONTENT_TYPE_WITH_INCORRECT_CHARSET, StandardCharsets.UTF_8)); } @Test public void testGetMimeType() { final String SIMPLE_CONTENT_TYPE = "text/html"; final String NORMAL_CONTENT_TYPE = "text/html; charset=utf-8"; HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); assertNull(HttpUtil.getMimeType(message)); message.headers().set(HttpHeaderNames.CONTENT_TYPE, ""); assertNull(HttpUtil.getMimeType(message)); assertNull(HttpUtil.getMimeType("")); message.headers().set(HttpHeaderNames.CONTENT_TYPE, SIMPLE_CONTENT_TYPE); assertEquals("text/html", HttpUtil.getMimeType(message)); assertEquals("text/html", HttpUtil.getMimeType(SIMPLE_CONTENT_TYPE)); message.headers().set(HttpHeaderNames.CONTENT_TYPE, NORMAL_CONTENT_TYPE); assertEquals("text/html", HttpUtil.getMimeType(message)); assertEquals("text/html", HttpUtil.getMimeType(NORMAL_CONTENT_TYPE)); } @Test public void testGetContentLengthDefaultValue() { HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); assertNull(message.headers().get(HttpHeaderNames.CONTENT_LENGTH)); message.headers().set(HttpHeaderNames.CONTENT_LENGTH, "bar"); assertEquals("bar", message.headers().get(HttpHeaderNames.CONTENT_LENGTH)); assertEquals(1L, HttpUtil.getContentLength(message, 1L)); } @Test public void testDoubleChunkedHeader() { HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); message.headers().add(HttpHeaderNames.TRANSFER_ENCODING, "chunked"); HttpUtil.setTransferEncodingChunked(message, true); List<String> expected = Collections.singletonList("chunked"); assertEquals(expected, message.headers().getAll(HttpHeaderNames.TRANSFER_ENCODING)); } private static List<String> allPossibleCasesOfContinue() { final List<String> cases = new ArrayList<String>(); final String c = "continue"; for (int i = 0; i < Math.pow(2, c.length()); i++) { final StringBuilder sb = new StringBuilder(c.length()); int j = i; int k = 0; while (j > 0) { if ((j & 1) == 1) { sb.append(Character.toUpperCase(c.charAt(k++))); } else { sb.append(c.charAt(k++)); } j >>= 1; } for (; k < c.length(); k++) { sb.append(c.charAt(k)); } cases.add(sb.toString()); } return cases; } @Test public void testIs100Continue() { // test all possible cases of 100-continue for (final String continueCase : allPossibleCasesOfContinue()) { run100ContinueTest(HttpVersion.HTTP_1_1, "100-" + continueCase, true); } run100ContinueTest(HttpVersion.HTTP_1_1, null, false); run100ContinueTest(HttpVersion.HTTP_1_1, "chocolate=yummy", false); run100ContinueTest(HttpVersion.HTTP_1_0, "100-continue", false); final HttpMessage message = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); message.headers().set(HttpHeaderNames.EXPECT, "100-continue"); run100ContinueTest(message, false); } private void run100ContinueTest(final HttpVersion version, final String expectations, boolean expect) { final HttpMessage message = new DefaultFullHttpRequest(version, HttpMethod.GET, "/"); if (expectations != null) { message.headers().set(HttpHeaderNames.EXPECT, expectations); } run100ContinueTest(message, expect); } private void run100ContinueTest(final HttpMessage message, final boolean expected) { assertEquals(expected, HttpUtil.is100ContinueExpected(message)); ReferenceCountUtil.release(message); } @Test public void testContainsUnsupportedExpectation() { // test all possible cases of 100-continue for (final String continueCase : allPossibleCasesOfContinue()) { runUnsupportedExpectationTest(HttpVersion.HTTP_1_1, "100-" + continueCase, false); } runUnsupportedExpectationTest(HttpVersion.HTTP_1_1, null, false); runUnsupportedExpectationTest(HttpVersion.HTTP_1_1, "chocolate=yummy", true); runUnsupportedExpectationTest(HttpVersion.HTTP_1_0, "100-continue", false); final HttpMessage message = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); message.headers().set("Expect", "100-continue"); runUnsupportedExpectationTest(message, false); } private void runUnsupportedExpectationTest(final HttpVersion version, final String expectations, boolean expect) { final HttpMessage message = new DefaultFullHttpRequest(version, HttpMethod.GET, "/"); if (expectations != null) { message.headers().set("Expect", expectations); } runUnsupportedExpectationTest(message, expect); } private void runUnsupportedExpectationTest(final HttpMessage message, final boolean expected) { assertEquals(expected, HttpUtil.isUnsupportedExpectation(message)); ReferenceCountUtil.release(message); } }