Skip to content

Commit

Permalink
Add extra headers for static resources
Browse files Browse the repository at this point in the history
Allow users to add extra headers when using the
`HttpResourceBinding` for static resources.

Signed-off-by: Yihong Wang <yh.wang@ibm.com>
  • Loading branch information
yhwang committed Dec 16, 2024
1 parent f039442 commit 37dd372
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public void testConnectTimeout()
}
catch (CapturedException e) {
Throwable t = e.getCause();
if (!(isConnectTimeout(t) || t instanceof ClosedChannelException)) {
if (!(isConnectTimeout(t) || t instanceof ClosedChannelException) || !(t instanceof TimeoutException)) {
fail(format("unexpected exception: [%s]", getStackTraceAsString(t)));
}
assertLessThan(nanosSince(start), new Duration(300, MILLISECONDS));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.facebook.airlift.http.server;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
import com.google.common.net.HttpHeaders;
import org.eclipse.jetty.http.HttpMethod;
Expand All @@ -31,6 +32,7 @@
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
Expand All @@ -54,13 +56,14 @@ public class ClassPathResourceHandler
private final String baseUri; // "" or "/foo"
private final String classPathResourceBase;
private final List<String> welcomeFiles;
private final Map<String, String> extraHeaders;

public ClassPathResourceHandler(String baseUri, String classPathResourceBase, String... welcomeFiles)
{
this(baseUri, classPathResourceBase, ImmutableList.copyOf(welcomeFiles));
this(baseUri, classPathResourceBase, ImmutableList.copyOf(welcomeFiles), ImmutableMap.of());
}

public ClassPathResourceHandler(String baseUri, String classPathResourceBase, List<String> welcomeFiles)
public ClassPathResourceHandler(String baseUri, String classPathResourceBase, List<String> welcomeFiles, Map<String, String> extraHeaders)
{
requireNonNull(baseUri, "baseUri is null");
requireNonNull(classPathResourceBase, "classPathResourceBase is null");
Expand All @@ -81,6 +84,7 @@ public ClassPathResourceHandler(String baseUri, String classPathResourceBase, Li
files.add(welcomeFile);
}
this.welcomeFiles = files.build();
this.extraHeaders = ImmutableMap.copyOf(extraHeaders);
}

@Override
Expand Down Expand Up @@ -129,6 +133,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques

String contentType = MIME_TYPES.getMimeByExtension(resource.toString());
response.setContentType(contentType);
extraHeaders.forEach((name, value) -> response.setHeader(name, value));

if (skipContent) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,11 @@ public HttpServer(HttpServerInfo httpServerInfo,

for (HttpResourceBinding resource : resources) {
GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(new ClassPathResourceHandler(resource.getBaseUri(), resource.getClassPathResourceBase(), resource.getWelcomeFiles()));
gzipHandler.setHandler(new ClassPathResourceHandler(
resource.getBaseUri(),
resource.getClassPathResourceBase(),
resource.getWelcomeFiles(),
resource.getExtraHeaders()));
handlers.addHandler(gzipHandler);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.facebook.airlift.http.server;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Binder;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.google.inject.multibindings.Multibinder.newSetBinder;
import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -43,6 +46,7 @@ public static class HttpResourceBinding
private final String baseUri;
private final String classPathResourceBase;
private final List<String> welcomeFiles = new ArrayList<>();
private final Map<String, String> extraHeaders = new HashMap<>();

public HttpResourceBinding(String baseUri, String classPathResourceBase)
{
Expand Down Expand Up @@ -70,5 +74,16 @@ public HttpResourceBinding withWelcomeFile(String welcomeFile)
welcomeFiles.add(welcomeFile);
return this;
}

public Map<String, String> getExtraHeaders()
{
return ImmutableMap.copyOf(extraHeaders);
}

public HttpResourceBinding withExtraHeader(String name, String value)
{
extraHeaders.put(name, value);
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ public void testServer()
binder.bind(Servlet.class).annotatedWith(TheServlet.class).to(DummyServlet.class);
newSetBinder(binder, Filter.class, TheServlet.class).addBinding().to(DummyFilter.class).in(Scopes.SINGLETON);
httpServerBinder(binder).bindResource("/", "webapp/user").withWelcomeFile("user-welcome.txt");
httpServerBinder(binder).bindResource("/", "webapp/user2");
httpServerBinder(binder).bindResource("/", "webapp/user2")
.withExtraHeader("Content-Security-Policy", "frame-ancestors 'self'");
httpServerBinder(binder).bindResource("path", "webapp/user").withWelcomeFile("user-welcome.txt");
httpServerBinder(binder).bindResource("path", "webapp/user2");
});
Expand All @@ -202,12 +203,14 @@ public void testServer()
response = client.execute(prepareGet().setUri(httpUri.resolve("/filter")).build(), createStatusResponseHandler());

assertEquals(response.getStatusCode(), HttpServletResponse.SC_PAYMENT_REQUIRED);

Map<String, String> extraHeaders = new ImmutableMap.Builder<String, String>()
.put("Content-Security-Policy", "frame-ancestors 'self'")
.build();
// test http resources
assertResource(httpUri, client, "", "welcome user!");
assertResource(httpUri, client, "user-welcome.txt", "welcome user!");
assertResource(httpUri, client, "user.txt", "user");
assertResource(httpUri, client, "user2.txt", "user2");
assertResource(httpUri, client, "user2.txt", "user2", extraHeaders);
assertRedirect(httpUri, client, "path", "/path/");
assertResource(httpUri, client, "path/", "welcome user!");
assertResource(httpUri, client, "path/user-welcome.txt", "welcome user!");
Expand All @@ -220,6 +223,11 @@ public void testServer()
}

private void assertResource(URI baseUri, HttpClient client, String path, String contents)
{
assertResource(baseUri, client, path, contents, ImmutableMap.of());
}

private void assertResource(URI baseUri, HttpClient client, String path, String contents, Map<String, String> hasHeaders)
{
HttpUriBuilder uriBuilder = uriBuilderFrom(baseUri);
StringResponse response = client.execute(prepareGet().setUri(uriBuilder.appendPath(path).build()).build(), createStringResponseHandler());
Expand All @@ -229,6 +237,10 @@ private void assertResource(URI baseUri, HttpClient client, String path, String
MediaType mediaType = MediaType.parse(contentType);
assertTrue(PLAIN_TEXT_UTF_8.is(mediaType), "Expected text/plain but got " + mediaType);
assertEquals(response.getBody().trim(), contents);
hasHeaders.forEach((name, value) -> {
assertNotNull(response.getHeader(name), name + " header is absent");
assertEquals(value, response.getHeader(name));
});
}

private void assertRedirect(URI baseUri, HttpClient client, String path, String redirect)
Expand Down

0 comments on commit 37dd372

Please sign in to comment.