Commit 6fcdd34c authored by Andrea Aime's avatar Andrea Aime
Browse files

[GEOS-9123] WMTS capabilities backlinks miss workspace qualification when proxy base URL is set

parent a8f3e9cf
......@@ -5,6 +5,7 @@
package org.geoserver.gwc;
import org.apache.commons.lang3.StringUtils;
import org.geoserver.gwc.dispatch.GwcServiceDispatcherCallback;
import org.geoserver.ows.URLMangler.URLType;
import org.geoserver.ows.util.ResponseUtils;
import org.geowebcache.util.URLMangler;
......@@ -13,8 +14,13 @@ public class ResponseUtilsURLMangler implements URLMangler {
@Override
public String buildURL(String baseURL, String contextPath, String path) {
String base = StringUtils.strip(baseURL, "/");
String cp = "/" + StringUtils.strip(contextPath, "/");
// In order to allow GWC to dispatch the requests the GwcServiceDispatcherCallback
// puts the local workspace in the servlet context, however to build correct backlinks we
// need to original base URL with the workspace stuck in the path so that the
// proxy base URL rewrite won't eat it away
final String originalBaseURL = GwcServiceDispatcherCallback.GWC_ORIGINAL_BASEURL.get();
String base = originalBaseURL == null ? StringUtils.strip(baseURL, "/") : originalBaseURL;
String cp = StringUtils.strip(contextPath, "/");
String rest = cp + "/" + StringUtils.stripStart(path, "/");
return ResponseUtils.buildURL(base, rest, null, URLType.SERVICE);
}
......
......@@ -23,6 +23,7 @@ import org.geoserver.ows.DispatcherCallback;
import org.geoserver.ows.LocalPublished;
import org.geoserver.ows.LocalWorkspace;
import org.geoserver.ows.Request;
import org.geoserver.ows.util.ResponseUtils;
import org.geoserver.platform.ServiceException;
/**
......@@ -42,6 +43,7 @@ public class GwcServiceDispatcherCallback extends AbstractDispatcherCallback
// contains the current gwc operation
public static final ThreadLocal<String> GWC_OPERATION = new ThreadLocal<>();
public static final ThreadLocal<String> GWC_ORIGINAL_BASEURL = new ThreadLocal<>();
private static final Pattern GWC_WS_VIRTUAL_SERVICE_PATTERN =
Pattern.compile("([^/]+)/gwc/service.*");
......@@ -67,6 +69,7 @@ public class GwcServiceDispatcherCallback extends AbstractDispatcherCallback
public void finished(Request request) {
// cleaning the current thread local operation
GWC_OPERATION.remove();
GWC_ORIGINAL_BASEURL.remove();
}
@Override
......@@ -93,6 +96,7 @@ public class GwcServiceDispatcherCallback extends AbstractDispatcherCallback
}
}
GWC_OPERATION.set(requestName);
GWC_ORIGINAL_BASEURL.set(ResponseUtils.baseURL(request.getHttpRequest()));
Map<String, String> kvp = new HashMap<>();
kvp.put("service", "gwc");
......
......@@ -153,4 +153,9 @@
</bean>
<bean id="gwcResourceServiceVoter" class="org.geoserver.gwc.wmts.GWCResourceServiceVoter"/>
<bean id="gwcLocalWorkspaceURLManger" class="org.geoserver.ows.LocalWorkspaceURLMangler">
<constructor-arg value="gwc"/>
</bean>
</beans>
......@@ -58,7 +58,9 @@ import org.geoserver.catalog.ProjectionPolicy;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerDataDirectory;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.config.GeoServerLoader;
import org.geoserver.data.test.MockData;
import org.geoserver.data.test.SystemTestData;
......@@ -95,6 +97,7 @@ import org.geowebcache.layer.TileLayer;
import org.geowebcache.layer.TileLayerDispatcher;
import org.geowebcache.service.wmts.WMTSService;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
......@@ -148,6 +151,12 @@ public class GWCIntegrationTest extends GeoServerSystemTestSupport {
springContextLocations.add("gwc-integration-test.xml");
}
@After
public void cleanupDispatcherRequest() {
// some test set the dispatcher request manually, avoid cross test contamination
Dispatcher.REQUEST.remove();
}
private void prepareDataDirectory(SystemTestData testData) throws Exception {
Catalog catalog = getCatalog();
testData.addWorkspace(TEST_WORKSPACE_NAME, TEST_WORKSPACE_URI, catalog);
......@@ -1490,6 +1499,15 @@ public class GWCIntegrationTest extends GeoServerSystemTestSupport {
@Test
public void testGetCapabilitiesWithLocalWorkspace() throws Exception {
final Document doc = assertGetCapabilitiesWithLocalWorkspace();
// print(doc);
assertThat(
WMTS_XPATH_10.evaluate("//wmts:ServiceMetadataURL[2]/@xlink:href", doc),
equalTo(
"http://localhost:8080/geoserver/cite/gwc/service/wmts/rest/WMTSCapabilities.xml"));
}
public Document assertGetCapabilitiesWithLocalWorkspace() throws Exception {
// getting capabilities document for CITE workspace
Document document =
getAsDOM(MockData.CITE_PREFIX + "/gwc/service/wmts?request=GetCapabilities");
......@@ -1510,6 +1528,31 @@ public class GWCIntegrationTest extends GeoServerSystemTestSupport {
+ "'])",
document),
is("1"));
return document;
}
@Test
public void testGetCapabilitiesWithLocalWorkspaceAndProxyBase() throws Exception {
final GeoServer gs = getGeoServer();
try {
setProxyBase(gs, "http://fooBar/geoserver");
final Document doc = assertGetCapabilitiesWithLocalWorkspace();
// print(doc);
assertThat(
WMTS_XPATH_10.evaluate("//wmts:ServiceMetadataURL[2]/@xlink:href", doc),
equalTo(
"http://fooBar/geoserver/cite/gwc/service/wmts/rest/WMTSCapabilities.xml"));
} finally {
setProxyBase(gs, null);
}
}
public void setProxyBase(GeoServer gs, String s) {
final GeoServerInfo global = gs.getGlobal();
global.getSettings().setProxyBaseUrl(s);
gs.save(global);
}
@Test
......
......@@ -33,7 +33,7 @@ public final class GwcServiceDispatcherCallbackTest {
@Test
public void testThatGwcServiceRequestsAreAccepted() {
// creating some mocks needed for the test and instantiating the dispatcher call back
HttpServletRequest httpRequest = mock(HttpServletRequest.class);
HttpServletRequest httpRequest = newMockHttpRequest();
when(httpRequest.getParameterMap()).thenReturn(Collections.emptyMap());
Request request = mock(Request.class);
when(request.getHttpRequest()).thenReturn(httpRequest);
......@@ -61,10 +61,19 @@ public final class GwcServiceDispatcherCallbackTest {
}
}
public HttpServletRequest newMockHttpRequest() {
final HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getScheme()).thenReturn("http");
when(request.getServerName()).thenReturn("http");
when(request.getServerPort()).thenReturn(8080);
when(request.getContextPath()).thenReturn("/geoserver/gwc");
return request;
}
@Test
public void testGwcVirtualServiceRequestWrapper() {
// we create a mock for the http request
HttpServletRequest httpRequest = mock(HttpServletRequest.class);
HttpServletRequest httpRequest = newMockHttpRequest();
when(httpRequest.getParameterMap()).thenReturn(new HashMap<>());
when(httpRequest.getContextPath()).thenReturn("geoserver");
// we create a mock for the geoserver request
......@@ -98,7 +107,7 @@ public final class GwcServiceDispatcherCallbackTest {
@Test
public void testThatGwcOperationIsStored() {
// creating some mocks needed for the test and instantiating the dispatcher call back
HttpServletRequest httpRequest = mock(HttpServletRequest.class);
HttpServletRequest httpRequest = newMockHttpRequest();
when(httpRequest.getParameterMap()).thenReturn(Collections.emptyMap());
Request request = new Request();
request.setKvp(Collections.singletonMap("REQUEST", "GetCapabilities"));
......
......@@ -130,6 +130,7 @@ public class GeoServerTileLayerTest {
@After
public void tearDown() throws Exception {
GWC.set(null);
Dispatcher.REQUEST.remove();
}
@Before
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment