Skip to content
This repository has been archived by the owner on Nov 30, 2023. It is now read-only.

Commit

Permalink
Add URI protocol filter
Browse files Browse the repository at this point in the history
Reacts to the X-Forwarded-Host header to set the scheme of request URLs
  • Loading branch information
birkland committed Mar 14, 2018
1 parent a6768b6 commit 5b90f3d
Show file tree
Hide file tree
Showing 6 changed files with 358 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2017 Johns Hopkins University
*
* Licensed 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.dataconservancy.fcrepo.jsonld.request;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
* @author [email protected]
*/
public class UriProtocolFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Nothing to do
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {

final HttpServletRequest req = ((HttpServletRequest) request);

final Protocol proto = Protocol.of(req);

if (proto.isDefined()) {
chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {

@Override
public StringBuffer getRequestURL() {
return new StringBuffer(super.getRequestURL().toString()
.replaceFirst("^https?:", proto.getProtocol() + ":"));
}
}, response);
} else {
chain.doFilter(request, response);
}
}

@Override
public void destroy() {
// Nothing to do
}

private static class Protocol {

final String proto;

static Protocol of(HttpServletRequest request) {
if (request.getHeader("X-Forwarded-Proto") != null) {
return new Protocol(request.getHeader("X-Forwarded-Proto"));
}

return new Protocol(null);
}

private Protocol(String proto) {
this.proto = proto;
}

boolean isDefined() {
return proto != null;
}

String getProtocol() {
return proto;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2017 Johns Hopkins University
*
* Licensed 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.dataconservancy.fcrepo.jsonld.request;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

/**
* @author [email protected]
*/
@RunWith(MockitoJUnitRunner.class)
public class UriProtocolFilterTest {

final String ORIGINAL_URI = "http://example.org/original/uri";

final String HTTPS_URI = "https://example.org/original/uri";

@Mock
FilterChain chain;

@Captor
ArgumentCaptor<HttpServletRequest> requestCaptor;

@Mock
HttpServletRequest request;

@Mock
HttpServletResponse response;

@Before
public void setUp() {
when(request.getRequestURL()).thenReturn(new StringBuffer(ORIGINAL_URI));
}

@Test
public void noProtoTest() throws Exception {

final UriProtocolFilter toTest = new UriProtocolFilter();

toTest.doFilter(request, response, chain);

verify(chain).doFilter(requestCaptor.capture(), eq(response));

assertEquals(ORIGINAL_URI, requestCaptor.getValue().getRequestURL().toString());
}

@Test
public void httpsProtoTest() throws Exception {

when(request.getHeader("X-Forwarded-Proto")).thenReturn("https");

final UriProtocolFilter toTest = new UriProtocolFilter();

toTest.doFilter(request, response, chain);

verify(chain).doFilter(requestCaptor.capture(), eq(response));

assertEquals(HTTPS_URI, requestCaptor.getValue().getRequestURL().toString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

import java.net.URI;
import java.util.Arrays;
import java.util.concurrent.Callable;

import org.fcrepo.client.FcrepoClient;
import org.fcrepo.client.FcrepoClient.FcrepoClientBuilder;
Expand All @@ -37,13 +36,10 @@
/**
* @author [email protected]
*/
public class CompactionIT {
public class CompactionIT implements FcrepoIT {

static final URI SERVER_MANAGED = URI.create("http://fedora.info/definitions/v4/repository#ServerManaged");

String fcrepoBaseURI = String.format("http://localhost:%s/%s/rest/", System.getProperty(
"fcrepo.dynamic.test.port", "8080"), System.getProperty("fcrepo.cxtPath", "fcrepo"));

@Test
public void CompactionTest() throws Exception {
final FcrepoClient client = new FcrepoClientBuilder().throwExceptionOnFailure().build();
Expand All @@ -67,28 +63,5 @@ public void CompactionTest() throws Exception {

assertTrue(isCompact(body));
}

}

static <T> T attempt(final int times, final Callable<T> it) {

Throwable caught = null;

for (int tries = 0; tries < times; tries++) {
try {
return it.call();
} catch (final Throwable e) {
caught = e;
try {
Thread.sleep(1000);
System.out.println(".");
} catch (final InterruptedException i) {
Thread.currentThread().interrupt();
return null;
}
}
}
throw new RuntimeException("Failed executing task", caught);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2017 Johns Hopkins University
*
* Licensed 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.dataconservancy.fcrepo.jsonld.integration;

import java.util.concurrent.Callable;

/**
* @author [email protected]
*/
public interface FcrepoIT {

static final String fcrepoBaseURI = String.format("http://localhost:%s/%s/rest/", System.getProperty(
"fcrepo.dynamic.test.port", "8080"), System.getProperty("fcrepo.cxtPath", "fcrepo"));

default <T> T attempt(final int times, final Callable<T> it) {

Throwable caught = null;

for (int tries = 0; tries < times; tries++) {
try {
return it.call();
} catch (final Throwable e) {
caught = e;
try {
Thread.sleep(1000);
System.out.println(".");
} catch (final InterruptedException i) {
Thread.currentThread().interrupt();
return null;
}
}
}
throw new RuntimeException("Failed executing task", caught);
}
}
Loading

0 comments on commit 5b90f3d

Please sign in to comment.