| /* |
| * Copyright 2008 Google Inc. |
| * |
| * Licensed 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 com.google.gwt.user.server.rpc; |
| |
| import com.google.gwt.user.client.rpc.UnicodeEscapingTest; |
| |
| import junit.framework.TestCase; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.UnsupportedEncodingException; |
| |
| import javax.servlet.ServletException; |
| import javax.servlet.ServletInputStream; |
| import javax.servlet.http.HttpServletRequest; |
| |
| /** |
| * Tests some of the methods in {@link RPCServletUtils}. |
| * |
| */ |
| public class RPCServletUtilsTest extends TestCase { |
| |
| /** |
| * Mocks a request with the specified Content-Type. |
| */ |
| class MockReqContentType extends MockHttpServletRequest { |
| final String mockContent; |
| final String mockContentType; |
| |
| |
| public MockReqContentType(String contentType) { |
| this(contentType, "abcdefg"); |
| } |
| |
| public MockReqContentType(String contentType, String content) { |
| this.mockContentType = contentType; |
| this.mockContent = content; |
| } |
| |
| @Override |
| public String getCharacterEncoding() { |
| return "utf-8"; |
| } |
| |
| @Override |
| public int getContentLength() { |
| return mockContent.length(); |
| } |
| |
| @Override |
| public String getContentType() { |
| return mockContentType; |
| } |
| |
| @Override |
| public String getHeader(String name) { |
| return null; |
| } |
| |
| @SuppressWarnings("unused") |
| @Override |
| public ServletInputStream getInputStream() throws IOException { |
| return new MockServletInputStream(mockContent); |
| } |
| } |
| |
| static class MockServletInputStream extends ServletInputStream { |
| private ByteArrayInputStream realStream; |
| |
| MockServletInputStream(String mockContent) throws UnsupportedEncodingException { |
| realStream = new ByteArrayInputStream(mockContent.getBytes("UTF-8")); |
| } |
| |
| @Override |
| public int read() throws IOException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public int read(byte[] b, int off, int len) throws IOException { |
| return realStream.read(b, off, len); |
| } |
| } |
| |
| /** |
| * Large content length should be read correctly. |
| */ |
| public void testContentLengthLarge() throws IOException, ServletException { |
| // Choose a non trivial size RPC payload |
| int contentLength = 50000; |
| String content = UnicodeEscapingTest.getStringContainingCharacterRange(0, contentLength); |
| String result = readContentAsUtf8(content); |
| assertEquals(content, result); |
| } |
| |
| /** |
| * Content length smaller than the buffer size should be read correctly. |
| */ |
| public void testContentLengthLessThanBufferSize() throws IOException, ServletException { |
| // Choose a value smaller than the buffer |
| int contentLength = RPCServletUtils.BUFFER_SIZE - 1; |
| String content = UnicodeEscapingTest.getStringContainingCharacterRange(0, contentLength); |
| String result = readContentAsUtf8(content); |
| assertEquals(content, result); |
| } |
| |
| /** |
| * Content length which is an integer multiple of buffer size should be read |
| * correctly. |
| */ |
| public void testContentLengthMultipleOfBufferSize() throws IOException, ServletException { |
| // Choose a value which is not a multiple of the buffer size |
| int contentLength = RPCServletUtils.BUFFER_SIZE * 3; |
| String content = UnicodeEscapingTest.getStringContainingCharacterRange(0, contentLength); |
| String result = readContentAsUtf8(content); |
| assertEquals(content, result); |
| } |
| |
| /** |
| * Content length which is not an integer multiple of buffer size should be |
| * read correctly. |
| */ |
| public void testContentLengthNotMultipleOfBufferSize() throws IOException, ServletException { |
| // Choose a value which is not a multiple of the buffer size |
| int contentLength = RPCServletUtils.BUFFER_SIZE * 3 + 1; |
| String content = UnicodeEscapingTest.getStringContainingCharacterRange(0, contentLength); |
| String result = readContentAsUtf8(content); |
| assertEquals(content, result); |
| } |
| |
| /** |
| * Content length smaller than the buffer size should be read correctly. |
| */ |
| public void testContentLengthSlightlyLargerThanBufferSize() throws IOException, ServletException { |
| // Choose a value slightly larger than the buffer |
| int contentLength = RPCServletUtils.BUFFER_SIZE + 1; |
| String content = UnicodeEscapingTest.getStringContainingCharacterRange(0, contentLength); |
| String result = readContentAsUtf8(content); |
| assertEquals(content, result); |
| } |
| |
| /** |
| * Zero content length is never expected, but being able to correctly read |
| * zero length content is a useful boundary condition test. |
| */ |
| public void testContentLengthZero() throws IOException, ServletException { |
| // While zero content length is not actually useful, a test |
| int contentLength = 0; |
| String content = UnicodeEscapingTest.getStringContainingCharacterRange(0, contentLength); |
| String result = readContentAsUtf8(content); |
| assertEquals(content, result); |
| } |
| |
| /** |
| * Character type doesn't match UTF-8, but ignore it. |
| */ |
| public void testIgnoreCharacterEncoding() throws IOException, |
| ServletException { |
| HttpServletRequest m = new MockReqContentType("text/x-gwt-rpc") { |
| |
| @Override |
| public String getCharacterEncoding() { |
| return "EBCDIC-US"; |
| } |
| }; |
| |
| RPCServletUtils.readContent(m, null, null); |
| } |
| |
| /** |
| * Content type doesn't match x-gwt-rpc, but ignore it. |
| */ |
| public void testIgnoreContentType() throws IOException, ServletException { |
| HttpServletRequest m = new MockReqContentType("application/www-form-encoded"); |
| RPCServletUtils.readContent(m, null, null); |
| } |
| |
| /** |
| * A non UTF-8 character encoding should be rejected. |
| */ |
| public void testReadBadCharacterEncoding() throws IOException { |
| HttpServletRequest m = new MockReqContentType("text/x-gwt-rpc") { |
| |
| @Override |
| public String getCharacterEncoding() { |
| return "EBCDIC-US"; |
| } |
| }; |
| boolean gotException = false; |
| |
| try { |
| RPCServletUtils.readContentAsGwtRpc(m); |
| } catch (ServletException se) { |
| if (se.getMessage().indexOf("Character Encoding") != 0) { |
| fail(" Unexpected exception " + se); |
| } |
| gotException = true; |
| } |
| |
| if (!gotException) { |
| fail("Expected exception from illegal character encoding"); |
| } |
| } |
| |
| /** |
| * Implement a content type other than text/x-gwt-rpc. |
| */ |
| public void testReadBadContentType() throws IOException { |
| HttpServletRequest m = new MockReqContentType( |
| "application/www-form-encoded"); |
| boolean gotException = false; |
| try { |
| RPCServletUtils.readContentAsGwtRpc(m); |
| } catch (ServletException se) { |
| if (se.getMessage().indexOf("Content-Type") != 0) { |
| fail(" Unexpected exception " + se); |
| } |
| gotException = true; |
| } |
| if (!gotException) { |
| fail("Expected exception from illegal content type"); |
| } |
| } |
| |
| /** |
| * Implement a test that returns content-type text/x-gwt-rpc. |
| */ |
| public void testReadGoodContentType() throws IOException, ServletException { |
| HttpServletRequest m = new MockReqContentType("text/x-gwt-rpc"); |
| RPCServletUtils.readContentAsGwtRpc(m); |
| } |
| |
| /** |
| * Content-Type validation should ignore case. |
| */ |
| public void testReadGoodContentTypeIgnoreCase() |
| throws IOException, ServletException { |
| HttpServletRequest m = new MockReqContentType("tExt/X-gwt-rPc"); |
| RPCServletUtils.readContentAsGwtRpc(m); |
| } |
| |
| /** |
| * A null character encoding should be rejected. |
| */ |
| public void testReadNullCharacterEncoding() throws IOException { |
| HttpServletRequest m = new MockReqContentType("text/x-gwt-rpc") { |
| |
| @Override |
| public String getCharacterEncoding() { |
| return null; |
| } |
| }; |
| boolean gotException = false; |
| try { |
| RPCServletUtils.readContentAsGwtRpc(m); |
| } catch (ServletException se) { |
| if (se.getMessage().indexOf("Character Encoding") != 0) { |
| fail(" Unexpected exception " + se); |
| } |
| gotException = true; |
| } |
| if (!gotException) { |
| fail("Expected exception from null character encoding"); |
| } |
| } |
| |
| /** |
| * A null content type should be rejected. |
| */ |
| public void testReadNullContentType() throws IOException { |
| HttpServletRequest m = new MockReqContentType(null); |
| boolean gotException = false; |
| try { |
| RPCServletUtils.readContentAsGwtRpc(m); |
| } catch (ServletException se) { |
| if (se.getMessage().indexOf("Content-Type") != 0) { |
| fail(" Unexpected exception " + se); |
| } |
| gotException = true; |
| } |
| if (!gotException) { |
| fail("Expected exception from null content type"); |
| } |
| } |
| |
| private String readContentAsUtf8(String content) throws IOException, ServletException { |
| HttpServletRequest m = new MockReqContentType(null, content); |
| // ignore Content-Type, read as UTF-8 |
| return RPCServletUtils.readContent(m, null, null); |
| } |
| } |