1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.http.protocol;
29
30 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertThrows;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.when;
34
35 import java.io.IOException;
36 import java.net.InetSocketAddress;
37
38 import org.apache.hc.core5.http.ContentType;
39 import org.apache.hc.core5.http.EndpointDetails;
40 import org.apache.hc.core5.http.HttpException;
41 import org.apache.hc.core5.http.HttpRequest;
42 import org.apache.hc.core5.http.HttpRequestInterceptor;
43 import org.apache.hc.core5.http.HttpVersion;
44 import org.apache.hc.core5.http.ProtocolException;
45 import org.apache.hc.core5.http.ProtocolVersion;
46 import org.apache.hc.core5.http.impl.BasicEntityDetails;
47 import org.apache.hc.core5.http.message.BasicHeader;
48 import org.apache.hc.core5.http.message.BasicHttpRequest;
49 import org.apache.hc.core5.net.URIAuthority;
50 import org.junit.jupiter.api.Test;
51
52 public class TesForwardedRequest {
53 private final HttpRequest request = new BasicHttpRequest("GET", "/");
54 private final HttpContext context = mock(HttpContext.class);
55
56 private static final String FORWARDED_HEADER_NAME = "Forwarded";
57
58 @Test
59 public void testProcess() throws IOException, HttpException {
60 final HttpRequestInterceptor processor = new ForwardedRequest();
61
62
63 final InetSocketAddress remoteAddress = new InetSocketAddress("192.168.1.100", 12345);
64 final InetSocketAddress localAddress = new InetSocketAddress("127.0.0.1", 2263);
65
66 final EndpointDetails endpointDetails = mock(EndpointDetails.class);
67 when(endpointDetails.getRemoteAddress()).thenReturn(remoteAddress);
68 when(endpointDetails.getLocalAddress()).thenReturn(localAddress);
69
70
71 final String host = "somehost";
72 final int port = 8888;
73
74 request.setAuthority(new URIAuthority(host, port));
75
76
77 final ProtocolVersion version = HttpVersion.HTTP_1_1;
78 final HttpContext context = new BasicHttpContext();
79 context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, endpointDetails);
80
81
82 processor.process(request, new BasicEntityDetails(1, ContentType.APPLICATION_JSON), context);
83
84
85 final String expectedValue = "by=" + remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort() + ";" +
86 "for=" + localAddress.getAddress().getHostAddress() + ":" + localAddress.getPort() + ";" +
87 "host=\"" + host + "\";port=" + port + ";proto=" + version.getProtocol();
88
89 assertEquals(expectedValue, request.getFirstHeader(FORWARDED_HEADER_NAME).getValue());
90 }
91
92
93 @Test
94 public void testProcessWithIPv6() throws IOException, HttpException {
95 final HttpRequestInterceptor processor = new ForwardedRequest();
96
97
98 final InetSocketAddress remoteAddress = InetSocketAddress.createUnresolved("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", 12345);
99 final InetSocketAddress localAddress = InetSocketAddress.createUnresolved("[0:0:0:0:0:0:0:1]", 2263);
100
101 final EndpointDetails endpointDetails = mock(EndpointDetails.class);
102 when(endpointDetails.getRemoteAddress()).thenReturn(remoteAddress);
103 when(endpointDetails.getLocalAddress()).thenReturn(localAddress);
104
105
106 final String host = "somehost";
107 final int port = 8888;
108
109 request.setAuthority(new URIAuthority(host, port));
110
111
112 final ProtocolVersion version = HttpVersion.HTTP_1_1;
113 final HttpContext context = new BasicHttpContext();
114 context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, endpointDetails);
115
116
117 processor.process(request, new BasicEntityDetails(1, ContentType.APPLICATION_JSON), context);
118
119
120 final String expectedValue = "by=" + remoteAddress.getHostName() + ":" + remoteAddress.getPort() +
121 ";for=" + localAddress.getHostName() + ":" + localAddress.getPort() +
122 ";host=\"" + host + "\";port=" + port + ";proto=" + version.getProtocol();
123
124
125 assertEquals(expectedValue, request.getFirstHeader(FORWARDED_HEADER_NAME).getValue());
126 }
127
128 @Test
129 void testProcess_withNullEndpointDetails_shouldAddValidHeader() throws Exception {
130 final HttpRequestInterceptor processor = new ForwardedRequest();
131
132
133 final String host = "somehost";
134 final int port = 8888;
135
136 request.setAuthority(new URIAuthority(host, port));
137
138
139 final ProtocolVersion version = HttpVersion.HTTP_1_1;
140 final HttpContext context = new BasicHttpContext();
141 context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, null);
142
143
144 processor.process(request, new BasicEntityDetails(1, ContentType.APPLICATION_JSON), context);
145
146
147 final String expectedValue = "host=\"" + host + "\";port=" + port + ";proto=" + version.getProtocol();
148
149 assertEquals(expectedValue, request.getFirstHeader(FORWARDED_HEADER_NAME).getValue());
150 }
151
152 @Test
153 public void testWithForwardedHeader() throws Exception {
154 final HttpRequestInterceptor processor = new ForwardedRequest();
155
156
157 final String host = "newhost";
158 final int port = 8888;
159
160 request.setAuthority(new URIAuthority(host, port));
161
162
163 final ProtocolVersion version = HttpVersion.HTTP_1_1;
164 final HttpContext context = new BasicHttpContext();
165 context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, null);
166 final String forwaredHeaderValue = "host=oldhost;port=8855;proto=HTTP";
167
168 request.setHeader(new BasicHeader(FORWARDED_HEADER_NAME, forwaredHeaderValue));
169
170
171 processor.process(request, new BasicEntityDetails(1, ContentType.APPLICATION_JSON), context);
172
173
174 final String expectedValue = forwaredHeaderValue + ", " + "host=\"" + host + "\";port=" + port + ";proto=" + version.getProtocol();
175
176 assertEquals(expectedValue, request.getFirstHeader(FORWARDED_HEADER_NAME).getValue());
177 }
178
179 @Test
180 public void testProcessWithNullHttpRequest() {
181 final ForwardedRequest httpRequestModifier = new ForwardedRequest();
182 assertThrows(NullPointerException.class, () -> httpRequestModifier.process(null, null, context));
183 }
184
185 @Test
186 public void testProcessWithNullHttpContext() {
187 final ForwardedRequest httpRequestModifier = new ForwardedRequest();
188 assertThrows(NullPointerException.class, () -> httpRequestModifier.process(request, null, null));
189 }
190
191 @Test
192 public void testProcessWithNullAuthority() {
193 final ForwardedRequest httpRequestModifier = new ForwardedRequest();
194 assertThrows(ProtocolException.class, () -> httpRequestModifier.process(request, null, context));
195 }
196 }