Skip to content

Commit

Permalink
Feature / Web server redirect (#297)
Browse files Browse the repository at this point in the history
* Add redirects to web server config proto

* Add redirect handling to web server content server

* Update rewrite rules in content server to the same pattern as redirects
  • Loading branch information
Martin Traverse authored Feb 2, 2023
1 parent a465175 commit 68fe389
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ message WebServerConfig {

PluginConfig contentRoot = 3;
repeated WebServerRewriteRule rewriteRules = 4;
repeated WebServerRedirect redirects = 5;
}

message WebServerRewriteRule {
Expand All @@ -88,6 +89,13 @@ message WebServerRewriteRule {
string target = 2;
}

message WebServerRedirect {

string source = 1;
string target = 2;
int32 status = 3;
}


message InstantMap {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import org.finos.tracdap.common.storage.FileType;
import org.finos.tracdap.common.storage.IFileStorage;
import org.finos.tracdap.config.WebServerConfig;
import org.finos.tracdap.config.WebServerRedirect;
import org.finos.tracdap.config.WebServerRewriteRule;

import java.net.URI;
import java.net.URISyntaxException;
Expand All @@ -51,25 +53,36 @@ public class ContentServer {
private final IFileStorage storage;

private final Map<String, String> mimeTypes;
private final List<Map.Entry<Pattern, String>> rewriteRules;
private final List<Map.Entry<Pattern, WebServerRedirect>> redirects;
private final List<Map.Entry<Pattern, WebServerRewriteRule>> rewriteRules;

public ContentServer(WebServerConfig config, IFileStorage storage) {

this.storage = storage;

this.mimeTypes = MimeTypes.loadMimeTypeMap();

this.redirects = new ArrayList<>();
this.rewriteRules = new ArrayList<>();

for (var redirect : config.getRedirectsList()) {
var source = Pattern.compile(redirect.getSource());
redirects.add(Map.entry(source, redirect));
}

for (var rule : config.getRewriteRulesList()) {
var source = Pattern.compile(rule.getSource());
var target = rule.getTarget();
rewriteRules.add(Map.entry(source, target));
rewriteRules.add(Map.entry(source, rule));
}
}

public CompletionStage<ContentResponse> headRequest(String requestUri, IExecutionContext execCtx) {

var redirect = processRedirects(requestUri);

if (redirect != null)
return CompletableFuture.completedFuture(redirect);

var storagePath = translateStoragePath(requestUri);

return headRequestForPath(storagePath, execCtx);
Expand All @@ -86,6 +99,11 @@ private CompletionStage<ContentResponse> headRequestForPath(String storagePath,

public CompletionStage<ContentResponse> getRequest(String requestUri, IDataContext dataCtx) {

var redirect = processRedirects(requestUri);

if (redirect != null)
return CompletableFuture.completedFuture(redirect);

var storagePath = translateStoragePath(requestUri);

return storage.stat(storagePath, dataCtx)
Expand All @@ -95,6 +113,28 @@ public CompletionStage<ContentResponse> getRequest(String requestUri, IDataConte
.thenApplyAsync(Function.identity(), dataCtx.eventLoopExecutor());
}

private ContentResponse processRedirects(String requestUri) {

try {
var uri = new URI(requestUri);
var path = uri.getPath();

for (var redirect : redirects) {

var pattern = redirect.getKey();
var match = pattern.matcher(path);

if (match.matches())
return buildRedirectResponse(redirect.getValue());
}

return null;
}
catch (URISyntaxException e) {
throw new ENetworkHttp(HttpResponseStatus.BAD_REQUEST.code(), "Invalid URL: " + e.getMessage(), e);
}
}

private String translateStoragePath(String requestUri) {

try {
Expand All @@ -105,10 +145,10 @@ private String translateStoragePath(String requestUri) {

var pattern = rule.getKey();
var match = pattern.matcher(path);
var replacement = rule.getValue();
var rewrite = rule.getValue();

if (match.matches())
path = match.replaceFirst(replacement);
path = match.replaceFirst(rewrite.getTarget());
}

if (path.equals("/"))
Expand Down Expand Up @@ -195,6 +235,15 @@ private ContentResponse buildErrorResponse(Throwable e) {
return response;
}

private ContentResponse buildRedirectResponse(WebServerRedirect redirect) {

var response = new ContentResponse();
response.statusCode = HttpResponseStatus.valueOf(redirect.getStatus());
response.headers.set(HttpHeaderNames.LOCATION, redirect.getTarget());

return response;
}

private void addStandardHeaders(HttpHeaders headers) {

var date = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now());
Expand Down

0 comments on commit 68fe389

Please sign in to comment.