Skip to content

Commit

Permalink
[GEOS-8944] GWC fails to cache tiles if GeoFence with source IP drive…
Browse files Browse the repository at this point in the history
…n rules are used for authentication (#3126)
  • Loading branch information
aaime authored and Nuno Oliveira committed Oct 1, 2018
1 parent c172d08 commit 853119b
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 32 deletions.
76 changes: 44 additions & 32 deletions src/gwc/src/main/java/org/geoserver/gwc/FakeHttpServletRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
Expand All @@ -28,6 +28,8 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@SuppressWarnings("rawtypes")
class FakeHttpServletRequest implements HttpServletRequest {
Expand All @@ -49,10 +51,12 @@ public Object nextElement() {

private String workspace;

private Map<String, String> parameterMap = new HashMap<String, String>(10);
private Map<String, String> parameterMap;

private Cookie[] cookies;

private Optional<HttpServletRequest> original;

public FakeHttpServletRequest(Map<String, String> parameterMap, Cookie[] cookies) {
this(parameterMap, cookies, null);
}
Expand All @@ -62,6 +66,13 @@ public FakeHttpServletRequest(
this.parameterMap = parameterMap;
this.cookies = cookies;
this.workspace = workspace;
// grab the original request from Spring to forward security related attributes
// such as requests host, ports and headers
this.original =
Optional.ofNullable(
(ServletRequestAttributes)
RequestContextHolder.getRequestAttributes())
.map(ServletRequestAttributes::getRequest);
}

/** Standard interface */
Expand All @@ -77,24 +88,26 @@ public Cookie[] getCookies() {
return cookies;
}

public long getDateHeader(String arg0) {
throw new ServletDebugException();
public long getDateHeader(String name) {
return original.map(r -> r.getDateHeader(name))
.orElseThrow(() -> new ServletDebugException());
}

public String getHeader(String arg0) {
return null;
public String getHeader(String name) {
return original.map(r -> r.getHeader(name)).orElse(null);
}

public Enumeration getHeaderNames() {
return EMPTY_ENUMERATION;
return original.map(r -> r.getHeaderNames()).orElse(EMPTY_ENUMERATION);
}

public Enumeration getHeaders(String arg0) {
throw new ServletDebugException();
public Enumeration getHeaders(String name) {
return original.map(r -> r.getHeaders(name)).orElseThrow(() -> new ServletDebugException());
}

public int getIntHeader(String arg0) {
throw new ServletDebugException();
public int getIntHeader(String name) {
return original.map(r -> r.getIntHeader(name))
.orElseThrow(() -> new ServletDebugException());
}

public String getMethod() {
Expand Down Expand Up @@ -215,32 +228,31 @@ public ServletInputStream getInputStream() throws IOException {
}

public String getLocalAddr() {
throw new ServletDebugException();
return original.map(r -> r.getLocalAddr()).orElseThrow(() -> new ServletDebugException());
}

public String getLocalName() {
throw new ServletDebugException();
return original.map(r -> r.getLocalName()).orElseThrow(() -> new ServletDebugException());
}

public int getLocalPort() {
// TODO Auto-generated method stub
return 0;
return original.map(r -> r.getLocalPort()).orElse(0);
}

@Override
public ServletContext getServletContext() {
return null;
return original.map(r -> r.getServletContext()).orElse(null);
}

@Override
public AsyncContext startAsync() throws IllegalStateException {
return null;
throw new ServletDebugException();
}

@Override
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
throws IllegalStateException {
return null;
throw new ServletDebugException();
}

@Override
Expand All @@ -260,19 +272,19 @@ public AsyncContext getAsyncContext() {

@Override
public DispatcherType getDispatcherType() {
return null;
return DispatcherType.REQUEST;
}

public Locale getLocale() {
throw new ServletDebugException();
return original.map(r -> r.getLocale()).orElseThrow(() -> new ServletDebugException());
}

public Enumeration getLocales() {
throw new ServletDebugException();
}

public String getParameter(String arg0) {
return parameterMap.get(arg0);
public String getParameter(String name) {
return parameterMap.get(name);
}

public Map getParameterMap() {
Expand All @@ -283,12 +295,12 @@ public Enumeration getParameterNames() {
return Collections.enumeration(parameterMap.keySet());
}

public String[] getParameterValues(String arg0) {
throw new ServletDebugException();
public String[] getParameterValues(String name) {
return new String[] {parameterMap.get(name)};
}

public String getProtocol() {
throw new ServletDebugException();
return original.map(r -> r.getProtocol()).orElseThrow(() -> new ServletDebugException());
}

public BufferedReader getReader() throws IOException {
Expand All @@ -300,35 +312,35 @@ public String getRealPath(String arg0) {
}

public String getRemoteAddr() {
return "127.0.0.1";
return original.map(r -> r.getRemoteAddr()).orElse("127.0.0.1");
}

public String getRemoteHost() {
return "localhost";
return original.map(r -> r.getRemoteHost()).orElse("localhost");
}

public int getRemotePort() {
throw new ServletDebugException();
return original.map(r -> r.getRemotePort()).orElseThrow(() -> new ServletDebugException());
}

public RequestDispatcher getRequestDispatcher(String arg0) {
throw new ServletDebugException();
}

public String getScheme() {
return "http";
return original.map(r -> r.getScheme()).orElse("http");
}

public String getServerName() {
return "localhost";
return original.map(r -> r.getServerName()).orElse("localhost");
}

public int getServerPort() {
return 8080;
return original.map(r -> r.getServerPort()).orElse(8080);
}

public boolean isSecure() {
throw new ServletDebugException();
return original.map(r -> r.isSecure()).orElseThrow(() -> new ServletDebugException());
}

public void removeAttribute(String arg0) {
Expand Down
37 changes: 37 additions & 0 deletions src/gwc/src/test/java/org/geoserver/gwc/GWCIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static java.lang.String.format;
import static org.geoserver.data.test.MockData.BASIC_POLYGONS;
import static org.geoserver.gwc.GWC.tileLayerName;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.greaterThan;
Expand Down Expand Up @@ -39,6 +40,7 @@
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.namespace.QName;
import org.apache.commons.io.FileUtils;
Expand Down Expand Up @@ -186,6 +188,9 @@ protected void onSetUp(SystemTestData testData) throws Exception {
"BasicPolygonsNoCrs.properties",
this.getClass(),
catalog);

// clean up the recorded http requests
HttpRequestRecorderCallback.reset();
}

protected GridSet namedGridsetCopy(final String newName, final GridSet oldGridset) {
Expand Down Expand Up @@ -1068,6 +1073,38 @@ public void testDirectWMSIntegrationWithVirtualServicesHiddenLayer() throws Exce
response.getContentAsString().contains("Could not find layer cdf:BasicPolygons"));
}

@Test
public void testDirectWMSIntegrationCustomHost() throws Exception {
final GWC gwc = GWC.get();
gwc.getConfig().setDirectWMSIntegrationEnabled(true);

final String layerName = BASIC_POLYGONS.getPrefix() + ":" + BASIC_POLYGONS.getLocalPart();

String requestURL = buildGetMap(true, layerName, "EPSG:4326", null) + "&tiled=true";
MockHttpServletRequest request = createRequest(requestURL);
request.setMethod("GET");
request.setContent(new byte[] {});
final String THE_HOST = "foobar";
request.setRemoteHost(THE_HOST);
MockHttpServletResponse response = dispatch(request, null);

// check everything went as expected
assertEquals(200, response.getStatus());
assertEquals("image/png", response.getContentType());
assertEquals(layerName, response.getHeader("geowebcache-layer"));
assertEquals("[0, 0, 0]", response.getHeader("geowebcache-tile-index"));
assertEquals("-180.0,-90.0,0.0,90.0", response.getHeader("geowebcache-tile-bounds"));
assertEquals("EPSG:4326", response.getHeader("geowebcache-gridset"));
assertEquals("EPSG:4326", response.getHeader("geowebcache-crs"));

// check we have the two requests recorded, and the
ArrayList<HttpServletRequest> requests = HttpRequestRecorderCallback.getRequests();
assertEquals(2, requests.size());
assertThat(requests.get(1), instanceOf(FakeHttpServletRequest.class));
FakeHttpServletRequest fake = (FakeHttpServletRequest) requests.get(1);
assertEquals(THE_HOST, fake.getRemoteHost());
}

@Test
public void testReloadConfiguration() throws Exception {
String path = "/gwc/rest/reload";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* (c) 2018 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.gwc;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.geoserver.ows.AbstractDispatcherCallback;
import org.geoserver.ows.Request;

/** Integration tests support class that keeps track of the requests send to the dispatcher. */
public final class HttpRequestRecorderCallback extends AbstractDispatcherCallback {

static List<HttpServletRequest> requests = new ArrayList<>();

public static void reset() {
synchronized (requests) {
requests.clear();
}
}

public static ArrayList<HttpServletRequest> getRequests() {
synchronized (requests) {
return new ArrayList<>(requests);
}
}

@Override
public Request init(Request request) {
synchronized (requests) {
requests.add(request.getHttpRequest());
}
return super.init(request);
}
}
1 change: 1 addition & 0 deletions src/gwc/src/test/resources/gwc-integration-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
<beans>

<bean id="balancedRequestTester" class="org.geoserver.gwc.BalancedRequestTester"/>
<bean id="requestRecorder" class="org.geoserver.gwc.HttpRequestRecorderCallback"/>

</beans>

0 comments on commit 853119b

Please sign in to comment.