Skip to content

Commit bdd3f22

Browse files
authored
Add cloudfront CDN and CORS filter (#84)
1 parent 379046a commit bdd3f22

File tree

9 files changed

+62
-14
lines changed

9 files changed

+62
-14
lines changed

stubbornjava-common/src/main/java/com/stubbornjava/common/TemplateHelpers.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.time.format.DateTimeFormatter;
55

66
import com.github.jknack.handlebars.Options;
7+
import com.google.common.base.Strings;
8+
import com.typesafe.config.Config;
79

810
public class TemplateHelpers {
911
static final DateTimeFormatter MMMddyyyyFmt = DateTimeFormatter.ofPattern("MMM dd, yyyy");
@@ -12,4 +14,16 @@ public static CharSequence dateFormat(String dateString, Options options) {
1214
LocalDateTime date = LocalDateTime.parse(dateString);
1315
return MMMddyyyyFmt.format(date);
1416
}
17+
18+
private static final String cdnHost = Configs.<String>getOrDefault(Configs.properties(),
19+
"cdn.host",
20+
Config::getString,
21+
() -> null);
22+
// This expects the url to be relative (eg. /static/img.jpg)
23+
public static CharSequence cdn(String url) {
24+
if (Strings.isNullOrEmpty(cdnHost)) {
25+
return url;
26+
}
27+
return cdnHost + url;
28+
}
1529
}

stubbornjava-common/src/main/java/com/stubbornjava/common/Templating.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class Templating {
3131
static {
3232
Templating.Builder builder =
3333
new Templating.Builder()
34-
.withHelper("dateFormat", TemplateHelpers::dateFormat)
34+
.withHelpers(new TemplateHelpers())
3535
.withHelper("md", new MarkdownHelper())
3636
.withHelper(AssignHelper.NAME, AssignHelper.INSTANCE)
3737
.register(HumanizeHelper::register);
@@ -148,6 +148,12 @@ public <T> Builder withHelper(String helperName, Helper<T> helper) {
148148
return this;
149149
}
150150

151+
public <T> Builder withHelpers(Object helpers) {
152+
log.debug("using template helpers {}" , helpers.getClass());
153+
handlebars.registerHelpers(helpers);
154+
return this;
155+
}
156+
151157
public <T> Builder register(Consumer<Handlebars> consumer) {
152158
log.debug("registering helpers");
153159
consumer.accept(handlebars);

stubbornjava-common/src/main/java/com/stubbornjava/common/undertow/Headers.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,12 @@ default Optional<String> getHeader(HttpServerExchange exchange, String header) {
1717
RequestHeaderAttribute reqHeader = new RequestHeaderAttribute(new HttpString(header));
1818
return Optional.ofNullable(reqHeader.readAttribute(exchange));
1919
}
20+
21+
default void setHeader(HttpServerExchange exchange, HttpString header, String value) {
22+
exchange.getResponseHeaders().add(header, value);
23+
}
24+
25+
default void setHeader(HttpServerExchange exchange, String header, String value) {
26+
exchange.getResponseHeaders().add(new HttpString(header), value);
27+
}
2028
}

stubbornjava-common/src/main/java/com/stubbornjava/common/undertow/handlers/CustomHandlers.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import java.io.File;
55
import java.nio.file.Paths;
6+
import java.util.Set;
67
import java.util.SortedMap;
78

89
import org.slf4j.Logger;
@@ -168,4 +169,18 @@ public static HttpHandler securityHeaders(HttpHandler next, ReferrerPolicy polic
168169
return security.complete(next);
169170
}
170171
// {{end:securityHeaders}}
172+
173+
public static HttpHandler corsOriginWhitelist(HttpHandler next, Set<String> originWhitelist) {
174+
return exchange -> {
175+
String origin = Exchange.headers()
176+
.getHeader(exchange, Headers.ORIGIN)
177+
.orElse("");
178+
log.debug("Origin: {} Whitelist: {}", origin, originWhitelist);
179+
if (originWhitelist.contains(origin)) {
180+
log.debug("Origin whitelist matched adding CORS header");
181+
Exchange.headers().setHeader(exchange, "Access-Control-Allow-Origin", origin);
182+
}
183+
next.handleRequest(exchange);
184+
};
185+
}
171186
}

stubbornjava-webapp/src/main/java/com/stubbornjava/webapp/StubbornJavaWebApp.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
99

10+
import com.google.common.collect.Sets;
1011
import com.stubbornjava.common.seo.SitemapRoutes;
1112
import com.stubbornjava.common.undertow.SimpleServer;
1213
import com.stubbornjava.common.undertow.handlers.CustomHandlers;
@@ -37,27 +38,28 @@ private static HttpHandler exceptionHandler(HttpHandler next) {
3738
// {{start:csp}}
3839
private static HttpHandler contentSecurityPolicy(HttpHandler delegate) {
3940
return new ContentSecurityPolicyHandler.Builder()
40-
.defaultSrc(ContentSecurityPolicy.SELF)
41-
.scriptSrc(ContentSecurityPolicy.SELF.getValue(), "https://www.google-analytics.com")
41+
.defaultSrc(ContentSecurityPolicy.SELF.getValue(), "https://*.stubbornjava.com")
42+
.scriptSrc(ContentSecurityPolicy.SELF.getValue(), "https://*.stubbornjava.com", "https://www.google-analytics.com", "data:")
4243
// Drop the wildcard when we host our own images.
43-
.imgSrc(ContentSecurityPolicy.SELF.getValue(), "https://www.google-analytics.com", "*")
44-
.connectSrc(ContentSecurityPolicy.SELF.getValue(), "https://www.google-analytics.com")
45-
.fontSrc(ContentSecurityPolicy.SELF.getValue(), "data:")
46-
.styleSrc(ContentSecurityPolicy.SELF.getValue(), ContentSecurityPolicy.UNSAFE_INLINE.getValue())
44+
.imgSrc(ContentSecurityPolicy.SELF.getValue(), "https://*.stubbornjava.com", "https://www.google-analytics.com", "data:")
45+
.connectSrc(ContentSecurityPolicy.SELF.getValue(), "https://*.stubbornjava.com", "https://www.google-analytics.com")
46+
.fontSrc(ContentSecurityPolicy.SELF.getValue(), "https://*.stubbornjava.com", "data:")
47+
.styleSrc(ContentSecurityPolicy.SELF.getValue(), ContentSecurityPolicy.UNSAFE_INLINE.getValue(), "https://*.stubbornjava.com")
4748
.build(delegate);
4849
}
4950
// {{end:csp}}
5051

5152
// {{start:middleware}}
5253
private static HttpHandler wrapWithMiddleware(HttpHandler next) {
53-
return MiddlewareBuilder.begin(PageRoutes::redirector)
54+
return MiddlewareBuilder.begin(ex -> CustomHandlers.accessLog(ex, logger))
55+
.next(StubbornJavaWebApp::exceptionHandler)
56+
.next(CustomHandlers::statusCodeMetrics)
5457
.next(handler -> CustomHandlers.securityHeaders(handler, ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN))
5558
.next(StubbornJavaWebApp::contentSecurityPolicy)
5659
.next(CustomHandlers::gzip)
60+
.next(h -> CustomHandlers.corsOriginWhitelist(next, Sets.newHashSet("https://www.stubbornjava.com")))
61+
.next(PageRoutes::redirector)
5762
.next(BlockingHandler::new)
58-
.next(ex -> CustomHandlers.accessLog(ex, logger))
59-
.next(CustomHandlers::statusCodeMetrics)
60-
.next(StubbornJavaWebApp::exceptionHandler)
6163
.complete(next);
6264
}
6365
// {{end:middleware}}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
cdn {
2+
host="https://cdn.stubbornjava.com"
3+
}

stubbornjava-webapp/ui/src/common/head.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
44
<meta name="description" content="{{#if metaDesc }}{{metaDesc}}{{/if}}"/>
55
{{!-- <link rel="stylesheet" href="/css/3rdparty.css"/>--}}
6-
<link rel="stylesheet" href="/assets/css/common.css"/>
6+
<link rel="stylesheet" href="{{cdn "/assets/css/common.css"}}"/>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{{!-- <script async type="text/javascript" src="/js/3rdparty.js"></script> --}}
22
{{!-- Making this script async breaks the jump to id functionality :( --}}
3-
<script type="text/javascript" src="/assets/js/common.js"></script>
3+
<script type="text/javascript" src="{{cdn "/assets/js/common.js"}}"></script>

stubbornjava-webapp/ui/src/widgets/nav/header.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<nav class="navbar navbar-inverse navbar-expand fixed-top" role="navigation">
22
<a class="navbar-brand logo" href="/">
3-
<span class="align-middle"><img src="/assets/images/PenguinHQ_compressed.png" height="40px"> Stubborn<span class="java">Java</span></span>
3+
<span class="align-middle"><img src="{{cdn "/assets/images/PenguinHQ_compressed.png"}}" height="40px"> Stubborn<span class="java">Java</span></span>
44
{{!-- Add this SVG instead later. I can't get CSS to work --}}
55
{{!-- <span>{{> templates/src/widgets/nav/logo }} Stubborn<span class="java">Java</span></span> --}}
66
</a>

0 commit comments

Comments
 (0)