diff --git a/src/main/java/com/meterware/httpunit/WebResponse.java b/src/main/java/com/meterware/httpunit/WebResponse.java index f9540da5..0743acf9 100644 --- a/src/main/java/com/meterware/httpunit/WebResponse.java +++ b/src/main/java/com/meterware/httpunit/WebResponse.java @@ -1325,8 +1325,8 @@ private void readContentTypeHeader() { _contentHeader = _contentType + ";charset=" + _characterSet; } else { String[] parts = HttpUnitUtils.parseContentTypeHeader( contentHeader ); - if (null != _client && null != _client.getClientProperties().getOverrideContextType()) { - _contentType = _client.getClientProperties().getOverrideContextType(); + if (null != _client && null != _client.getClientProperties().getOverrideContentType()) { + _contentType = _client.getClientProperties().getOverrideContentType(); } else { _contentType = parts[0]; } diff --git a/src/main/java/com/meterware/servletunit/ServletUnitHttpResponse.java b/src/main/java/com/meterware/servletunit/ServletUnitHttpResponse.java index 643a487d..87e1cd5f 100644 --- a/src/main/java/com/meterware/servletunit/ServletUnitHttpResponse.java +++ b/src/main/java/com/meterware/servletunit/ServletUnitHttpResponse.java @@ -487,19 +487,26 @@ public String[] getHeaderFieldNames() { return result; } + /** + * Returns the headers defined for this response. + * @param name - the name of the field to get + **/ + String getHeaderFieldDirect( String name ) { + ArrayList values; + synchronized (_headers) { + values = (ArrayList) _headers.get( name.toUpperCase() ); + } + return values == null ? null : (String) values.get( 0 ); + } + /** * Returns the headers defined for this response. + * @param name **/ String getHeaderField( String name ) { if (!_headersComplete) completeHeaders(); - - ArrayList values; - synchronized (_headers) { - values = (ArrayList) _headers.get( name.toUpperCase() ); - } - - return values == null ? null : (String) values.get( 0 ); + return getHeaderFieldDirect(name); } @@ -564,7 +571,10 @@ public String getContentType() { private void completeHeaders() { if (_headersComplete) return; addCookieHeader(); - setHeader( "Content-Type", _contentType + "; charset=" + getCharacterEncoding() ); + // BR 3301056 ServletUnit handling Content-Type incorrectly + if (getHeaderFieldDirect("Content-Type")==null) { + setHeader( "Content-Type", _contentType + "; charset=" + getCharacterEncoding() ); + } _headersComplete = true; } diff --git a/src/test/java/com/meterware/servletunit/ContentTypeTest.java b/src/test/java/com/meterware/servletunit/ContentTypeTest.java new file mode 100644 index 00000000..7f95d4b9 --- /dev/null +++ b/src/test/java/com/meterware/servletunit/ContentTypeTest.java @@ -0,0 +1,158 @@ +package com.meterware.servletunit; +/******************************************************************************************************************** + * $Id: ErrorTests.java 1081 2012-09-09 17:16:39Z russgold $ + * + * Copyright (c) 2012, Russell Gold + * Copyright (c) 2011, NeoMedia Technologies, Inc.. All Rights Reserved except see below. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + *******************************************************************************************************************/ + +import static org.junit.Assert.*; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.meterware.httpunit.GetMethodWebRequest; +import com.meterware.httpunit.WebClient; +import com.meterware.httpunit.WebRequest; +import com.meterware.httpunit.WebResponse; + +/** + * Tests for BR 3301056 ServletUnit handling Content-Type incorrectly + * by Kevin Hunter + * @author wf + * + */ +public class ContentTypeTest +{ + private ServletRunner runner; + + public ContentTypeTest() + { + } + + @Before + public void setUp() + { + runner = new ServletRunner(); + runner.registerServlet("/test1", TestServlet1.class.getName()); + runner.registerServlet("/test2", TestServlet2.class.getName()); + } + + @After + public void tearDown() + { + runner.shutDown(); + } + + /* + * This test case demonstrates that ServletUnit incorrectly replaces the + * content type specified by the servlet with one of its own. + * (Expected behavior would be that ServletUnit would not alter the + * response coming back from the servlet under test.) + */ + @Test + public void testProvidedContentTypeOverwritten() throws Exception + { + WebClient client = runner.newClient(); + WebRequest request = new GetMethodWebRequest("http://localhost/test1"); + WebResponse response = client.getResponse(request); + assertEquals(200, response.getResponseCode()); + assertEquals(7, response.getContentLength()); + assertEquals("", response.getText()); + assertEquals("text/xml", response.getHeaderField("Content-Type")); + assertEquals("text/xml", response.getContentType()); + } + + /* + * This servlet returns a simple XML document, with Content-Type set + * to "text/xml" + */ + public static class TestServlet1 extends HttpServlet + { + private static final long serialVersionUID = 5434730264615105319L; + + public TestServlet1() + { + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + resp.setStatus(200); + resp.addHeader("Content-Type", "text/xml"); + resp.setContentLength(7); + resp.getWriter().write(""); + } + } + + /* + * This test case demonstrates that ServletUnit incorrectly provides + * a content type when the servlet under test doesn't provide one. + * (Expected behavior would be that ServletUnit would not alter the + * response coming back from the servlet under test.) + */ + @Test + public void testContentProvidedWhenNoneSpecified() throws Exception + { + WebClient client = runner.newClient(); + WebRequest request = new GetMethodWebRequest("http://localhost/test2"); + WebResponse response = client.getResponse(request); + assertEquals(200, response.getResponseCode()); + assertEquals(7, response.getContentLength()); + assertEquals("", response.getText()); + assertNull(response.getHeaderField("No-Such-Header")); + // the BR proposes to have a default "null" content-type + // assertNull(response.getHeaderField("Content-Type")); + // unfortunately currently the default content type is "text/plain; charset=iso-8859-1" + // whereas the HttpUnitOptions default Content Type is "text/html" ... + // we'll check for the current state for the time being 2012-09-13 + assertEquals("text/plain; charset=iso-8859-1",response.getHeaderField("Content-Type")); + } + + /* + * This servlet returns a simple XML document, but omits the + * Content-Type header. + */ + public static class TestServlet2 extends HttpServlet + { + private static final long serialVersionUID = 5434730264615105319L; + + public TestServlet2() + { + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException + { + resp.setStatus(200); + resp.setContentLength(7); + resp.getWriter().write(""); + } + } +} +