/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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.alibaba.citrus.service.requestcontext.basic; import static com.alibaba.citrus.test.TestUtil.*; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; import java.io.IOException; import javax.servlet.http.Cookie; import com.alibaba.citrus.service.requestcontext.basic.impl.ResponseHeaderSecurityFilter; import com.alibaba.citrus.util.HumanReadableSize; import org.junit.Before; import org.junit.Test; public class ResponseHeaderSecurityFilterTests extends AbstractBasicResponseTests { private ResponseHeaderSecurityFilter filter; @Before public void init() { filter = new ResponseHeaderSecurityFilter(); createResponse(filter); } @Test public void checkHeaderName() { try { response.setHeader("wrong\r\nname", "value"); fail(); } catch (ResponseHeaderRejectedException e) { assertThat(e, exception("Invalid response header: wrong\\r\\nname")); } responseMock.addIntHeader("name", 123); // keep original name replayMocks(); response.addIntHeader("name", 123); verifyMocks(); } @Test public void checkHeaderValue() { responseMock.setHeader("name", "value1 value2 value3 "); replayMocks(); response.setHeader("name", "value1\r\nvalue2\rvalue3\n"); verifyMocks(); } @Test public void checkCookieName() { Cookie wrongCookie = createMock(Cookie.class); expect(wrongCookie.getName()).andReturn("wrong\r\nname").atLeastOnce(); expect(wrongCookie.getValue()).andReturn("value").atLeastOnce(); replay(wrongCookie); try { response.addCookie(wrongCookie); fail(); } catch (CookieRejectedException e) { assertThat(e, exception("Cookie rejected: wrong\\r\\nname=value")); } Cookie cookie = new Cookie("name", "value"); responseMock.addHeader("Set-Cookie", "name=value"); // keep original cookie replayMocks(); response.addCookie(cookie); verifyMocks(); } @Test public void checkCookieValue() { responseMock.addHeader("Set-Cookie", "name=\"value1 value2 value3 \"; Version=1; Discard"); replayMocks(); response.addCookie(new Cookie("name", "value1\r\nvalue2\rvalue3\n")); verifyMocks(); } @Test public void checkCookieHeaderValue_exceedsMaxSize() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 7 * 512 - 6; i++) { sb.append("x"); } String value = sb.toString(); responseMock.addHeader("Set-Cookie", "test1=" + value); responseMock.addHeader("Set-Cookie", "test2=" + value); responseMock.addHeader("Set-Cookie", ""); replayMocks(); response.addCookie(new Cookie("test1", value)); response.addCookie(new Cookie("test2", value)); response.addCookie(new Cookie("test3", "value3")); verifyMocks(); } @Test public void checkCookieHeaderValue_setMaxSetCookieSize() { filter.setMaxSetCookieSize(new HumanReadableSize(20)); assertEquals(20, filter.getMaxSetCookieSize().getValue()); responseMock.addHeader("Set-Cookie", "test=value"); responseMock.addHeader("Set-Cookie", ""); replayMocks(); response.addCookie(new Cookie("test", "value")); response.addCookie(new Cookie("test1", "value1")); verifyMocks(); } @Test public void checkRedirectLocation() throws IOException { // 正常情况下,包含crlf的location是没有机会被crlfFilter发现的,因为在此之前已经出错。 // 但为了保障安全,仍作此测试。 assertEquals("value1 value2 value3 ", new ResponseHeaderSecurityFilter().checkRedirectLocation("value1\r\nvalue2\rvalue3\n")); } @Test @SuppressWarnings("deprecation") public void checkStatusMessage() throws IOException { responseMock.setStatus(500, "hello&world"); responseMock.sendError(404, "hello&world"); replayMocks(); response.setStatus(500, "hello&world"); response.sendError(404, "hello&world"); verifyMocks(); } }