/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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 org.apache.catalina.filters; import java.io.IOException; import java.util.LinkedHashSet; import java.util.Locale; import java.util.Set; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.junit.Assert; import org.junit.Test; public class TestCorsFilter { private FilterChain filterChain = new TesterFilterChain(); /** * Tests if a GET request is treated as simple request. * * @See http://www.w3.org/TR/cors/#simple-method * @throws IOException * @throws ServletException */ @Test public void testDoFilterSimpleGET() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("GET"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( "https://www.apache.org")); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } /** * Tests if a POST request is treated as simple request. * * @See http://www.w3.org/TR/cors/#simple-method * @throws IOException * @throws ServletException */ @Test public void testDoFilterSimplePOST() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setContentType("text/plain"); request.setMethod("POST"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( "https://www.apache.org")); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } /** * Tests if a HEAD request is treated as simple request. * * @See http://www.w3.org/TR/cors/#simple-method * @throws IOException * @throws ServletException */ @Test public void testDoFilterSimpleHEAD() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("HEAD"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( "https://www.apache.org")); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } /** * Test the presence of specific origin in response, when '*' is not used. * * @throws IOException * @throws ServletException */ @Test public void testDoFilterSimpleSpecificHeader() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("POST"); request.setContentType("text/plain"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } /** * Tests the presence of the origin (and not '*') in the response, when * supports credentials is enabled alongwith any origin, '*'. * * @throws IOException * @throws ServletException */ @Test public void testDoFilterSimpleAnyOriginAndSupportsCredentials() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("GET"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getFilterConfigAnyOriginAndSupportsCredentials()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS) .equals( "true")); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } /** * Tests the presence of the origin (and not '*') in the response, when * supports credentials is enabled alongwith any origin, '*'. * * @throws IOException * @throws ServletException */ @Test public void testDoFilterSimpleAnyOriginAndSupportsCredentialsDisabled() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("GET"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getFilterConfigAnyOriginAndSupportsCredentialsDisabled()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.ANY_ORIGIN)); Assert.assertNull(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } /** * Tests the presence of exposed headers in response, if configured. * * @throws IOException * @throws ServletException */ @Test public void testDoFilterSimpleWithExposedHeaders() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("POST"); request.setContentType("text/plain"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getFilterConfigWithExposedHeaders()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( "https://www.apache.org")); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS) .equals(TesterFilterConfigs.EXPOSED_HEADERS)); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } /** * Checks if an OPTIONS request is processed as pre-flight. * * @throws IOException * @throws ServletException */ @Test public void testDoFilterPreflight() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase(Locale.ENGLISH))); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( "Content-Type")); } /** * Checks if an OPTIONS request is processed as pre-flight where any origin * is enabled. * * @throws IOException * @throws ServletException */ @Test public void testDoFilterPreflightAnyOrigin() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase(Locale.ENGLISH))); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( "Content-Type")); } /** * Checks if an OPTIONS request is processed as pre-flight. * * @throws IOException * @throws ServletException */ @Test public void testDoFilterPreflightInvalidOrigin() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://www.example.com"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(response.getStatus(), HttpServletResponse.SC_FORBIDDEN); } @Test public void testDoFilterPreflightNegativeMaxAge() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfigNegativeMaxAge()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertNull(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_MAX_AGE)); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase(Locale.ENGLISH))); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( "Content-Type")); } @Test public void testDoFilterPreflightWithCredentials() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSecureFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS) .equals("true")); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase(Locale.ENGLISH))); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( "Content-Type")); } @Test public void testDoFilterPreflightWithoutCredentialsAndSpecificOrigin() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getFilterConfigSpecificOriginAndSupportsCredentialsDisabled()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertNull(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase(Locale.ENGLISH))); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( "Content-Type")); } /** * Negative test, when a CORS request arrives, with no origin header. */ @Test public void testDoFilterNoOrigin() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setMethod("POST"); request.setContentType("text/plain"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.NOT_CORS, requestType); corsFilter.doFilter(request, response, filterChain); Assert.assertFalse(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); } /* * Negative test, when a non-CORS request arrives, with an origin header. */ @Test public void testDoFilterSameHostWithOrigin01() throws IOException, ServletException { doTestDoFilterSameHostWithOrigin01( "http://localhost:8080", "http", "localhost", 8080, false); } @Test public void testDoFilterSameHostWithOrigin02() throws IOException, ServletException { doTestDoFilterSameHostWithOrigin01( "http://localhost:8080", "https", "localhost", 8080, true); } @Test public void testDoFilterSameHostWithOrigin03() throws IOException, ServletException { doTestDoFilterSameHostWithOrigin01( "http://localhost:8080", "http", "localhost", 8081, true); } @Test public void testDoFilterSameHostWithOrigin04() throws IOException, ServletException { doTestDoFilterSameHostWithOrigin01( "http://localhost:8080", "http", "foo.dev.local", 8080, true); } @Test public void testDoFilterSameHostWithOrigin05() throws IOException, ServletException { doTestDoFilterSameHostWithOrigin01( "https://localhost:8443", "https", "localhost", 8443, false); } @Test public void testDoFilterSameHostWithOrigin06() throws IOException, ServletException { doTestDoFilterSameHostWithOrigin01( "https://localhost", "https", "localhost", 443, false); } @Test public void testDoFilterSameHostWithOrigin07() throws IOException, ServletException { doTestDoFilterSameHostWithOrigin01( "http://localhost", "http", "localhost", 80, false); } private void doTestDoFilterSameHostWithOrigin01(String origin, String scheme, String host, int port, boolean isCors) throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setMethod("POST"); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, origin); request.setScheme(scheme); request.setServerName(host); request.setServerPort(port); request.setContentType("text/plain"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); if (isCors) { Assert.assertNotEquals(CorsFilter.CORSRequestType.NOT_CORS, requestType); } else { Assert.assertEquals(CorsFilter.CORSRequestType.NOT_CORS, requestType); } corsFilter.doFilter(request, response, filterChain); if (isCors) { Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); } else { Assert.assertFalse(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); } } @Test public void testDoFilterInvalidCORSOriginNotAllowed() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "www.google.com"); request.setMethod("POST"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /* * A CORS request arrives with a "null" origin which is allowed by default. */ @Test public void testDoFilterNullOriginAllowedByDefault() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setMethod("POST"); request.setContentType("text/plain"); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "null"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.SIMPLE, requestType); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); } /* * A CORS request arrives with a "null" origin which is explicitly allowed * by configuration. */ @Test public void testDoFilterNullOriginAllowedByConfiguration() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setMethod("POST"); request.setContentType("text/plain"); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "null"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init( TesterFilterConfigs.getFilterConfigSpecificOriginNullAllowed()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.SIMPLE, requestType); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); } @Test(expected = ServletException.class) public void testDoFilterNullRequestNullResponse() throws IOException, ServletException { CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); corsFilter.doFilter(null, null, filterChain); } @Test(expected = ServletException.class) public void testDoFilterNullRequestResponse() throws IOException, ServletException { TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); corsFilter.doFilter(null, response, filterChain); } @Test(expected = ServletException.class) public void testDoFilterRequestNullResponse() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); corsFilter.doFilter(request, null, filterChain); } @Test public void testInitDefaultFilterConfig() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("GET"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(null); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( "https://www.apache.org")); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( TesterFilterConfigs.HTTPS_WWW_APACHE_ORG)); Assert.assertTrue(request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( CorsFilter.CORSRequestType.SIMPLE.name().toLowerCase(Locale.ENGLISH))); } @Test(expected = ServletException.class) public void testInitInvalidFilterConfig() throws ServletException { CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getFilterConfigInvalidMaxPreflightAge()); // If we don't get an exception at this point, then all mocked objects // worked as expected. } /** * Tests if a non-simple request is given to simple request handler. * * @throws IOException * @throws ServletException */ @Test(expected = IllegalArgumentException.class) public void testNotSimple() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); corsFilter.handleSimpleCORS(request, response, filterChain); } /** * When a non-preflight request is given to a pre-flight request handler. * * @throws IOException * @throws ServletException */ @Test(expected = IllegalArgumentException.class) public void testNotPreflight() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("GET"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); corsFilter.handlePreflightCORS(request, response, filterChain); } @Test(expected = IllegalArgumentException.class) public void testDecorateCORSPropertiesNullRequestNullCORSRequestType() { CorsFilter.decorateCORSProperties(null, null); } @Test(expected = IllegalArgumentException.class) public void testDecorateCORSPropertiesNullRequestValidCORSRequestType() { CorsFilter.decorateCORSProperties(null, CorsFilter.CORSRequestType.SIMPLE); } @Test(expected = IllegalArgumentException.class) public void testDecorateCORSPropertiesValidRequestNullRequestType() { TesterHttpServletRequest request = new TesterHttpServletRequest(); CorsFilter.decorateCORSProperties(request, null); } @Test public void testDecorateCORSPropertiesCORSRequestTypeNotCORS() { TesterHttpServletRequest request = new TesterHttpServletRequest(); CorsFilter.decorateCORSProperties(request, CorsFilter.CORSRequestType.NOT_CORS); Assert.assertFalse(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); } @Test public void testDecorateCORSPropertiesCORSRequestTypeInvalidCORS() { TesterHttpServletRequest request = new TesterHttpServletRequest(); CorsFilter .decorateCORSProperties(request, CorsFilter.CORSRequestType.INVALID_CORS); Assert.assertNull(request .getAttribute(CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); } @Test public void testCheckSimpleRequestTypeAnyOrigin() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://www.w3.org"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.SIMPLE, requestType); } /** * Happy path test, when a valid CORS Simple request arrives. * * @throws ServletException */ @Test public void testCheckSimpleRequestType() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.SIMPLE, requestType); } /** * Happy path test, when a valid CORS Simple request arrives. * * @throws ServletException */ @Test public void testCheckActualRequestType() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setMethod("PUT"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.ACTUAL, requestType); } /** * Happy path test, when a valid CORS Simple request arrives. * * @throws ServletException */ @Test public void testCheckActualRequestTypeMethodPOSTNotSimpleHeaders() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setMethod("POST"); request.setContentType("application/json"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.ACTUAL, requestType); } /** * Happy path test, when a valid CORS Pre-flight request arrives. * * @throws ServletException */ @Test public void testCheckPreFlightRequestType() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Content-Type"); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.PRE_FLIGHT, requestType); } /** * when a valid CORS Pre-flight request arrives, with no * Access-Control-Request-Method * * @throws ServletException * @throws IOException */ @Test public void testCheckPreFlightRequestTypeNoACRM() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.ACTUAL, requestType); } /** * when a valid CORS Pre-flight request arrives, with empty * Access-Control-Request-Method * * @throws ServletException * @throws IOException */ @Test public void testCheckPreFlightRequestTypeEmptyACRM() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, ""); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } /** * Happy path test, when a valid CORS Pre-flight request arrives. * * @throws ServletException */ @Test public void testCheckPreFlightRequestTypeNoHeaders() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.PRE_FLIGHT, requestType); } /** * Section 6.2.3 * * @throws ServletException * @throws IOException */ @Test public void testCheckPreFlightRequestTypeInvalidRequestMethod() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "POLITE"); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * Section Section 6.2.5 * * @throws ServletException * @throws IOException */ @Test public void testCheckPreFlightRequestTypeUnsupportedRequestMethod() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "TRACE"); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * Section Section 6.2.6 * * @throws ServletException * @throws IOException */ @Test public void testCheckPreFlightRequestTypeUnsupportedRequestHeaders() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "X-ANSWER"); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSecureFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * Section Section 6.2.7 * * @throws ServletException * @throws IOException */ @Test public void testCheckPreFlightRequestTypeAnyOriginNoWithCredentials() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, "Origin"); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getFilterConfigAnyOriginAndSupportsCredentialsDisabled()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( "*")); Assert.assertNull(response .getHeader(CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); } @Test public void testCheckPreFlightRequestTypeOriginNotAllowed() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "www.ebay.com"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSecureFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * Happy path test, when a valid CORS Pre-flight request arrives. * * @throws ServletException */ @Test public void testCheckPreFlightRequestTypeEmptyHeaders() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTP_TOMCAT_APACHE_ORG); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); request.setHeader( CorsFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, ""); request.setMethod("OPTIONS"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.PRE_FLIGHT, requestType); } /** * Negative test, when a CORS request arrives, with an empty origin. * * @throws ServletException */ @Test public void testCheckNotCORSRequestTypeEmptyOrigin() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, ""); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } /** * Tests for failure, when a different domain is used, that's not in the * allowed list of origins. * * @throws ServletException * @throws IOException */ @Test public void testCheckInvalidOrigin() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "www.example.com"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * Tests for failure, when the 'null' origin is used, and it's not in the * list of allowed origins. */ @Test public void testCheckNullOriginNotAllowed() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "null"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /* * Tests for failure, when a different sub-domain is used, that's not in the * allowed list of origins. * * @throws ServletException * @throws IOException */ @Test public void testCheckInvalidOriginNotAllowedSubdomain() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://commons.apache.org"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * PUT is not an allowed request method. * * @throws ServletException * @throws IOException */ @Test public void testCheckInvalidRequestMethod() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://tomcat.apache.org"); request.setMethod("PUT"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * When requestMethod is null * * @throws ServletException */ @Test public void testCheckNullRequestMethod() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://tomcat.apache.org"); request.setMethod(null); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } /** * "http://tomcat.apache.org" is an allowed origin and * "https://tomcat.apache.org" is not, because scheme doesn't match * * @throws ServletException */ @Test public void testCheckForSchemeVariance() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "https://tomcat.apache.org"); request.setMethod("POST"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } /** * "http://tomcat.apache.org" is an allowed origin and * "http://tomcat.apache.org:8080" is not, because ports doesn't match * * @throws ServletException * @throws IOException */ @Test public void testCheckForPortVariance() throws ServletException, IOException { TesterHttpServletRequest request = new TesterHttpServletRequest(); TesterHttpServletResponse response = new TesterHttpServletResponse(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://tomcat.apache.org:8080"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getSpecificOriginFilterConfig()); corsFilter.doFilter(request, response, filterChain); Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); } /** * Tests for failure, when an invalid {@link HttpServletRequest} is * encountered. * * @throws ServletException */ @Test(expected = IllegalArgumentException.class) public void testCheckRequestTypeNull() throws ServletException { HttpServletRequest request = null; CorsFilter corsFilter = new CorsFilter(); corsFilter.checkRequestType(request); } @Test public void testJoin() { Set<String> elements = new LinkedHashSet<String>(); String separator = ","; elements.add("world"); elements.add("peace"); String join = CorsFilter.join(elements, separator); Assert.assertTrue("world,peace".equals(join)); } @Test public void testJoinSingleElement() { Set<String> elements = new LinkedHashSet<String>(); String separator = ","; elements.add("world"); String join = CorsFilter.join(elements, separator); Assert.assertTrue("world".equals(join)); } @Test public void testJoinSepNull() { Set<String> elements = new LinkedHashSet<String>(); String separator = null; elements.add("world"); elements.add("peace"); String join = CorsFilter.join(elements, separator); Assert.assertTrue("world,peace".equals(join)); } @Test public void testJoinElementsNull() { Set<String> elements = null; String separator = ","; String join = CorsFilter.join(elements, separator); Assert.assertNull(join); } @Test public void testJoinOneNullElement() { Set<String> elements = new LinkedHashSet<String>(); String separator = ","; elements.add(null); elements.add("peace"); String join = CorsFilter.join(elements, separator); Assert.assertTrue(",peace".equals(join)); } @Test public void testJoinAllNullElements() { Set<String> elements = new LinkedHashSet<String>(); String separator = ","; elements.add(null); elements.add(null); String join = CorsFilter.join(elements, separator); Assert.assertTrue("".equals(join)); } @Test public void testJoinAllEmptyElements() { Set<String> elements = new LinkedHashSet<String>(); String separator = ","; elements.add(""); elements.add(""); String join = CorsFilter.join(elements, separator); Assert.assertTrue("".equals(join)); } @Test public void testJoinPipeSeparator() { Set<String> elements = new LinkedHashSet<String>(); String separator = "|"; elements.add("world"); elements.add("peace"); String join = CorsFilter.join(elements, separator); Assert.assertTrue("world|peace".equals(join)); } @Test public void testWithFilterConfig() throws ServletException { CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); Assert.assertTrue(corsFilter.getAllowedHttpHeaders().size() == 6); Assert.assertTrue(corsFilter.getAllowedHttpMethods().size() == 4); Assert.assertTrue(corsFilter.getAllowedOrigins().size() == 0); Assert.assertTrue(corsFilter.isAnyOriginAllowed()); Assert.assertTrue(corsFilter.getExposedHeaders().size() == 0); Assert.assertTrue(corsFilter.isSupportsCredentials()); Assert.assertTrue(corsFilter.getPreflightMaxAge() == 1800); } @Test(expected = ServletException.class) public void testWithFilterConfigInvalidPreflightAge() throws ServletException { CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getFilterConfigInvalidMaxPreflightAge()); } @Test public void testWithStringParserEmpty() throws ServletException { CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getEmptyFilterConfig()); Assert.assertTrue(corsFilter.getAllowedHttpHeaders().size() == 0); Assert.assertTrue(corsFilter.getAllowedHttpMethods().size() == 0); Assert.assertTrue(corsFilter.getAllowedOrigins().size() == 0); Assert.assertTrue(corsFilter.getExposedHeaders().size() == 0); Assert.assertFalse(corsFilter.isSupportsCredentials()); Assert.assertTrue(corsFilter.getPreflightMaxAge() == 0); } /** * If an init param is null, it's default value will be used. * * @throws ServletException */ @Test public void testWithStringParserNull() throws ServletException { CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getNullFilterConfig()); Assert.assertTrue(corsFilter.getAllowedHttpHeaders().size() == 6); Assert.assertTrue(corsFilter.getAllowedHttpMethods().size() == 4); Assert.assertTrue(corsFilter.getAllowedOrigins().size() == 0); Assert.assertTrue(corsFilter.isAnyOriginAllowed()); Assert.assertTrue(corsFilter.getExposedHeaders().size() == 0); Assert.assertTrue(corsFilter.isSupportsCredentials()); Assert.assertTrue(corsFilter.getPreflightMaxAge() == 1800); } @Test public void testValidOrigin() { Assert.assertTrue(CorsFilter.isValidOrigin("http://www.w3.org")); } @Test public void testInValidOriginCRLF() { Assert.assertFalse(CorsFilter.isValidOrigin("http://www.w3.org\r\n")); } @Test public void testInValidOriginEncodedCRLF1() { Assert.assertFalse(CorsFilter.isValidOrigin("http://www.w3.org%0d%0a")); } @Test public void testInValidOriginEncodedCRLF2() { Assert.assertFalse(CorsFilter.isValidOrigin("http://www.w3.org%0D%0A")); } @Test public void testInValidOriginEncodedCRLF3() { Assert.assertFalse(CorsFilter .isValidOrigin("http://www.w3.org%0%0d%0ad%0%0d%0aa")); } @Test public void testCheckInvalidCRLF1() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://www.w3.org\r\n"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } @Test public void testCheckInvalidCRLF2() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://www.w3.org\r\n"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } @Test public void testCheckInvalidCRLF3() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://www.w3.org%0d%0a"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } @Test public void testCheckInvalidCRLF4() throws ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "http://www.w3.org%0D%0A"); request.setMethod("GET"); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs .getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.INVALID_CORS, requestType); } @Test public void testDecorateRequestDisabled() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, TesterFilterConfigs.HTTPS_WWW_APACHE_ORG); request.setMethod("GET"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getFilterConfigDecorateRequestDisabled()); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(response.getHeader( CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( "https://www.apache.org")); Assert.assertNull(request .getAttribute(CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); Assert.assertNull(request .getAttribute(CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN)); Assert.assertNull(request .getAttribute(CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS)); Assert.assertNull(request .getAttribute(CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE)); } /* * A CORS request arrives with a "null" origin which is allowed by default. */ @Test public void testContentTypeWithParameter() throws IOException, ServletException { TesterHttpServletRequest request = new TesterHttpServletRequest(); request.setMethod("POST"); request.setContentType("text/plain;charset=UTF-8"); request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, "null"); TesterHttpServletResponse response = new TesterHttpServletResponse(); CorsFilter corsFilter = new CorsFilter(); corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig()); CorsFilter.CORSRequestType requestType = corsFilter.checkRequestType(request); Assert.assertEquals(CorsFilter.CORSRequestType.SIMPLE, requestType); corsFilter.doFilter(request, response, filterChain); Assert.assertTrue(((Boolean) request.getAttribute( CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue()); } }