1 /* 2 * Zed Attack Proxy (ZAP) and its related class files. 3 * 4 * ZAP is an HTTP/HTTPS proxy for assessing web application security. 5 * 6 * Copyright 2016 The ZAP Development Team 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package org.apache.commons.httpclient; 21 22 import static org.hamcrest.MatcherAssert.assertThat; 23 import static org.hamcrest.Matchers.arrayContaining; 24 import static org.hamcrest.Matchers.hasSize; 25 import static org.hamcrest.Matchers.is; 26 import static org.junit.jupiter.params.provider.Arguments.arguments; 27 import static org.mockito.BDDMockito.given; 28 import static org.mockito.Mockito.mock; 29 30 import java.util.List; 31 import java.util.stream.Stream; 32 import org.apache.commons.httpclient.protocol.Protocol; 33 import org.junit.jupiter.api.Test; 34 import org.junit.jupiter.params.ParameterizedTest; 35 import org.junit.jupiter.params.provider.Arguments; 36 import org.junit.jupiter.params.provider.MethodSource; 37 38 class HttpMethodBaseUnitTest { 39 40 private static final Header EXPECTED_HOST_HEADER = header("Host", "example.com"); 41 42 @ParameterizedTest 43 @MethodSource("cookieHeaderProvider") testParseCookieHeader(String cookieHeaderValue, int numberOfCookies)44 void testParseCookieHeader(String cookieHeaderValue, int numberOfCookies) { 45 List<Cookie> cookies = HttpMethodBase.parseCookieHeader("example.com", cookieHeaderValue); 46 assertThat(cookies, hasSize(numberOfCookies)); 47 } 48 cookieHeaderProvider()49 static Stream<Arguments> cookieHeaderProvider() { 50 return Stream.of( 51 arguments("", 0), 52 arguments("JSESSIONID=5DFA94B903A0063839E0440118808875", 1), 53 arguments("has_js=1;JSESSIONID=5DFA94B903A0063839E0440118808875", 2), 54 arguments("has_js=1; JSESSIONID=5DFA94B903A0063839E0440118808875", 2), 55 arguments("has_js=;JSESSIONID=5DFA94B903A0063839E0440118808875", 2)); 56 } 57 58 @Test shouldAddHostHeaderIfNotPresent()59 void shouldAddHostHeaderIfNotPresent() throws Exception { 60 // Given 61 HttpMethodBase methodBase = new TestHttpMethodBase(); 62 Header headerA = header("A", "Value A"); 63 methodBase.addRequestHeader(headerA); 64 HttpConnection conn = connection("example.com", 443); 65 // When 66 methodBase.addHostRequestHeader(null, conn); 67 // Then 68 assertThat( 69 methodBase.getRequestHeaders(), is(arrayContaining(headerA, EXPECTED_HOST_HEADER))); 70 } 71 72 @Test shouldKeepHostHeaderIfValueMatch()73 void shouldKeepHostHeaderIfValueMatch() throws Exception { 74 // Given 75 HttpMethodBase methodBase = new TestHttpMethodBase(); 76 Header hostHeader = header("Host", "example.com"); 77 methodBase.addRequestHeader(hostHeader); 78 Header headerA = header("A", "Value A"); 79 methodBase.addRequestHeader(headerA); 80 HttpConnection conn = connection("example.com", 443); 81 // When 82 methodBase.addHostRequestHeader(null, conn); 83 // Then 84 assertThat( 85 methodBase.getRequestHeaders(), is(arrayContaining(EXPECTED_HOST_HEADER, headerA))); 86 } 87 88 @Test shouldUpdateHostHeaderIfValueMismatch()89 void shouldUpdateHostHeaderIfValueMismatch() throws Exception { 90 // Given 91 HttpMethodBase methodBase = new TestHttpMethodBase(); 92 methodBase.addRequestHeader(header("Host", "example2.com")); 93 HttpConnection conn = connection("example.com", 443); 94 // When 95 methodBase.addHostRequestHeader(null, conn); 96 // Then 97 assertThat(methodBase.getRequestHeaders(), is(arrayContaining(EXPECTED_HOST_HEADER))); 98 } 99 100 @Test shouldUpdateHostHeaderInPlace()101 void shouldUpdateHostHeaderInPlace() throws Exception { 102 // Given 103 HttpMethodBase methodBase = new TestHttpMethodBase(); 104 Header headerA = header("A", "Value A"); 105 methodBase.addRequestHeader(headerA); 106 Header hostHeader = header("Host", "example2.com"); 107 methodBase.addRequestHeader(hostHeader); 108 Header headerB = header("B", "Value B"); 109 methodBase.addRequestHeader(headerB); 110 HttpConnection conn = connection("example.com", 443); 111 // When 112 methodBase.addHostRequestHeader(null, conn); 113 // Then 114 assertThat( 115 methodBase.getRequestHeaders(), 116 is(arrayContaining(headerA, EXPECTED_HOST_HEADER, headerB))); 117 } 118 119 @Test shouldKeepOnlyOneHostHeader()120 void shouldKeepOnlyOneHostHeader() throws Exception { 121 // Given 122 HttpMethodBase methodBase = new TestHttpMethodBase(); 123 Header headerA = header("A", "Value A"); 124 methodBase.addRequestHeader(headerA); 125 Header hostHeader1 = header("Host", "example.com"); 126 methodBase.addRequestHeader(hostHeader1); 127 Header headerB = header("B", "Value B"); 128 methodBase.addRequestHeader(headerB); 129 Header headerHost2 = header("Host", "Should Remove 1"); 130 methodBase.addRequestHeader(headerHost2); 131 Header headerHost3 = header("Host", "Should Remove 2"); 132 methodBase.addRequestHeader(headerHost3); 133 HttpConnection conn = connection("example.com", 443); 134 // When 135 methodBase.addHostRequestHeader(null, conn); 136 // Then 137 assertThat( 138 methodBase.getRequestHeaders(), 139 is(arrayContaining(headerA, EXPECTED_HOST_HEADER, headerB))); 140 } 141 142 @Test shouldUpdateAndKeepOnlyOneHostHeader()143 void shouldUpdateAndKeepOnlyOneHostHeader() throws Exception { 144 // Given 145 HttpMethodBase methodBase = new TestHttpMethodBase(); 146 Header headerA = header("A", "Value A"); 147 methodBase.addRequestHeader(headerA); 148 Header hostHeader1 = header("Host", "example2.com"); 149 methodBase.addRequestHeader(hostHeader1); 150 Header headerB = header("B", "Value B"); 151 methodBase.addRequestHeader(headerB); 152 Header headerHost2 = header("Host", "Should Remove 1"); 153 methodBase.addRequestHeader(headerHost2); 154 Header headerHost3 = header("Host", "Should Remove 2"); 155 methodBase.addRequestHeader(headerHost3); 156 HttpConnection conn = connection("example.com", 443); 157 // When 158 methodBase.addHostRequestHeader(null, conn); 159 // Then 160 assertThat( 161 methodBase.getRequestHeaders(), 162 is(arrayContaining(headerA, EXPECTED_HOST_HEADER, headerB))); 163 } 164 connection(String host, int port)165 private static HttpConnection connection(String host, int port) { 166 HttpConnection connection = mock(HttpConnection.class); 167 given(connection.getHost()).willReturn(host); 168 given(connection.getPort()).willReturn(port); 169 Protocol protocol = mock(Protocol.class); 170 given(protocol.getDefaultPort()).willReturn(port); 171 given(connection.getProtocol()).willReturn(protocol); 172 return connection; 173 } 174 header(String name, String value)175 private static Header header(String name, String value) { 176 return new Header(name, value); 177 } 178 179 private static class TestHttpMethodBase extends HttpMethodBase { 180 181 @Override getName()182 public String getName() { 183 return "TEST"; 184 } 185 } 186 } 187