Refactored static resource resolution

This commit is contained in:
Rsl1122 2020-02-29 12:14:17 +02:00 committed by Risto Lahtela
parent 77dbc74cc5
commit 2b1b459a37
4 changed files with 120 additions and 90 deletions

View File

@ -23,7 +23,7 @@ public final class MimeType {
public static final String JS = "application/javascript";
public static final String IMAGE = "image/gif";
public static final String FAVICON = "image/x-icon";
public static final String FONT_TFF = "application/x-font-ttf";
public static final String FONT_TTF = "application/x-font-ttf";
public static final String FONT_WOFF = "application/font-woff";
public static final String FONT_WOFF2 = "application/font-woff2";
public static final String FONT_EOT = "application/vnd.ms-fontobject";

View File

@ -27,13 +27,11 @@ import com.djrapitops.plan.delivery.webserver.pages.*;
import com.djrapitops.plan.delivery.webserver.pages.json.RootJSONResolver;
import com.djrapitops.plan.delivery.webserver.response.OptionsResponse;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import com.djrapitops.plan.delivery.webserver.response.Response_old;
import com.djrapitops.plan.exceptions.WebUserAuthException;
import com.djrapitops.plan.exceptions.connection.BadRequestException;
import com.djrapitops.plan.exceptions.connection.ForbiddenException;
import com.djrapitops.plan.exceptions.connection.NotFoundException;
import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.error.ErrorHandler;
import dagger.Lazy;
@ -60,9 +58,9 @@ public class ResponseResolver extends CompositePageResolver {
private final ServerPageResolver serverPageResolver;
private final RootPageResolver rootPageResolver;
private final RootJSONResolver rootJSONResolver;
private final StaticResourceResolver staticResourceResolver;
private final ErrorHandler errorHandler;
private final ServerInfo serverInfo;
private final ResolverService resolverService;
private final Lazy<WebServer> webServer;
@ -71,7 +69,6 @@ public class ResponseResolver extends CompositePageResolver {
ResolverSvc resolverService,
ResponseFactory responseFactory,
Lazy<WebServer> webServer,
ServerInfo serverInfo,
DebugPageResolver debugPageResolver,
PlayersPageResolver playersPageResolver,
@ -79,19 +76,20 @@ public class ResponseResolver extends CompositePageResolver {
ServerPageResolver serverPageResolver,
RootPageResolver rootPageResolver,
RootJSONResolver rootJSONResolver,
StaticResourceResolver staticResourceResolver,
ErrorHandler errorHandler
) {
super(responseFactory);
this.resolverService = resolverService;
this.webServer = webServer;
this.serverInfo = serverInfo;
this.debugPageResolver = debugPageResolver;
this.playersPageResolver = playersPageResolver;
this.playerPageResolver = playerPageResolver;
this.serverPageResolver = serverPageResolver;
this.rootPageResolver = rootPageResolver;
this.rootJSONResolver = rootJSONResolver;
this.staticResourceResolver = staticResourceResolver;
this.errorHandler = errorHandler;
}
@ -104,6 +102,7 @@ public class ResponseResolver extends CompositePageResolver {
resolverService.registerResolver(pluginName, "/network", serverPageResolver);
resolverService.registerResolver(pluginName, "/server", serverPageResolver);
resolverService.registerResolverForMatches(pluginName, Pattern.compile("^/$"), rootPageResolver);
resolverService.registerResolverForMatches(pluginName, Pattern.compile("^/(vendor|css|js|img)/.*"), staticResourceResolver);
registerPage("v1", rootJSONResolver);
}
@ -137,8 +136,7 @@ public class ResponseResolver extends CompositePageResolver {
Optional<Authentication> authentication = internalRequest.getAuth();
Optional<Resolver> foundResolver = resolverService.getResolver(internalRequest.getPath().asString());
// TODO Replace with 404 after refactoring
if (!foundResolver.isPresent()) return tryToGetResponse_old(internalRequest).toNewResponse();
if (!foundResolver.isPresent()) return responseFactory.pageNotFound404();
Resolver resolver = foundResolver.get();
@ -163,40 +161,4 @@ public class ResponseResolver extends CompositePageResolver {
return resolver.resolve(request).orElseGet(responseFactory::pageNotFound404);
}
}
private Response_old tryToGetResponse_old(RequestInternal request) throws WebException {
RequestTarget target = request.getRequestTarget();
Optional<Authentication> authentication = request.getAuth();
String resource = target.getResourceString();
// TODO Turn into resolvers
if (target.endsWith(".css")) {
return responseFactory.cssResponse_old(resource);
}
if (target.endsWith(".js")) {
return responseFactory.javaScriptResponse_old(resource);
}
if (target.endsWith(".png")) {
return responseFactory.imageResponse_old(resource);
}
if (target.endsWithAny(".woff", ".woff2", ".eot", ".ttf")) {
return responseFactory.fontResponse_old(resource);
}
boolean isAuthRequired = webServer.get().isAuthRequired();
if (isAuthRequired && !authentication.isPresent()) {
if (webServer.get().isUsingHTTPS()) {
return responseFactory.basicAuth_old();
} else {
return responseFactory.forbidden403_old();
}
}
PageResolver pageResolver = getPageResolver(target);
if (pageResolver == null) {
return responseFactory.pageNotFound404_old();
} else {
if (!isAuthRequired || pageResolver.isAuthorized(authentication.get(), target)) {
return pageResolver.resolve(request, target);
}
return responseFactory.forbidden403_old();
}
}
}

View File

@ -0,0 +1,66 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.webserver.pages;
import com.djrapitops.plan.delivery.web.resolver.NoAuthResolver;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import org.apache.commons.lang3.StringUtils;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Optional;
/**
* Resolves all static resources for the pages.
*
* @author Rsl1122
*/
@Singleton
public class StaticResourceResolver implements NoAuthResolver {
private final ResponseFactory responseFactory;
@Inject
public StaticResourceResolver(ResponseFactory responseFactory) {
this.responseFactory = responseFactory;
}
@Override
public Optional<Response> resolve(Request request) {
return Optional.ofNullable(getResponse(request));
}
private Response getResponse(Request request) {
String resource = request.getPath().asString();
String filePath = "web" + resource;
if (resource.endsWith(".css")) {
return responseFactory.cssResponse(filePath);
}
if (resource.endsWith(".js")) {
return responseFactory.javaScriptResponse(filePath);
}
if (resource.endsWith(".png")) {
return responseFactory.imageResponse(filePath);
}
if (StringUtils.endsWithAny(resource, ".woff", ".woff2", ".eot", ".ttf")) {
return responseFactory.fontResponse(filePath);
}
return null;
}
}

View File

@ -25,7 +25,6 @@ import com.djrapitops.plan.delivery.web.resolver.MimeType;
import com.djrapitops.plan.delivery.web.resolver.Response;
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
import com.djrapitops.plan.delivery.webserver.response.errors.ErrorResponse;
import com.djrapitops.plan.delivery.webserver.response.errors.ForbiddenResponse;
import com.djrapitops.plan.delivery.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.delivery.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.delivery.webserver.response.pages.RawDataResponse;
@ -33,6 +32,7 @@ import com.djrapitops.plan.exceptions.WebUserAuthException;
import com.djrapitops.plan.exceptions.connection.NotFoundException;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.ErrorPageLang;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.Database;
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
@ -48,7 +48,7 @@ import java.util.Optional;
import java.util.UUID;
/**
* Factory for creating different {@link Response_old} objects.
* Factory for creating different {@link Response} objects.
*
* @author Rsl1122
*/
@ -60,6 +60,7 @@ public class ResponseFactory {
private final PageFactory pageFactory;
private final Locale locale;
private final DBSystem dbSystem;
private final Theme theme;
@Inject
public ResponseFactory(
@ -67,13 +68,15 @@ public class ResponseFactory {
PlanFiles files,
PageFactory pageFactory,
Locale locale,
DBSystem dbSystem
DBSystem dbSystem,
Theme theme
) {
this.versionCheckSystem = versionCheckSystem;
this.files = files;
this.pageFactory = pageFactory;
this.locale = locale;
this.dbSystem = dbSystem;
this.theme = theme;
}
public Response debugPageResponse() {
@ -179,42 +182,65 @@ public class ResponseFactory {
.build();
}
@Deprecated
public Response_old javaScriptResponse_old(String fileName) {
public Response javaScriptResponse(String fileName) {
try {
return new JavaScriptResponse(fileName, files, locale);
String content = locale.replaceLanguageInJavascript(files.getCustomizableResourceOrDefault(fileName).asString());
return Response.builder()
.setMimeType(MimeType.JS)
.setContent(content)
.setStatus(200)
.build();
} catch (IOException e) {
return notFound404_old("JS File not found from jar: " + fileName + ", " + e.toString());
return notFound404("JS File not found from jar: " + fileName + ", " + e.toString());
}
}
@Deprecated
public Response_old cssResponse_old(String fileName) {
public Response cssResponse(String fileName) {
try {
return new CSSResponse(fileName, files);
String content = theme.replaceThemeColors(files.getCustomizableResourceOrDefault(fileName).asString());
return Response.builder()
.setMimeType(MimeType.CSS)
.setContent(content)
.setStatus(200)
.build();
} catch (IOException e) {
return notFound404_old("CSS File not found from jar: " + fileName + ", " + e.toString());
return notFound404("CSS File not found from jar: " + fileName + ", " + e.toString());
}
}
@Deprecated
public Response_old imageResponse_old(String fileName) {
return new ByteResponse(ResponseType.IMAGE, FileResponse.format(fileName), files);
public Response imageResponse(String fileName) {
try {
return Response.builder()
.setMimeType(MimeType.IMAGE)
.setContent(files.getCustomizableResourceOrDefault(fileName).asBytes())
.setStatus(200)
.build();
} catch (IOException e) {
return notFound404("Image File not found from jar: " + fileName + ", " + e.toString());
}
}
@Deprecated
public Response_old fontResponse_old(String fileName) {
ResponseType type = ResponseType.FONT_BYTESTREAM;
public Response fontResponse(String fileName) {
String type;
if (fileName.endsWith(".woff")) {
type = ResponseType.FONT_WOFF;
type = MimeType.FONT_WOFF;
} else if (fileName.endsWith(".woff2")) {
type = ResponseType.FONT_WOFF2;
type = MimeType.FONT_WOFF2;
} else if (fileName.endsWith(".eot")) {
type = ResponseType.FONT_EOT;
type = MimeType.FONT_EOT;
} else if (fileName.endsWith(".ttf")) {
type = ResponseType.FONT_TTF;
type = MimeType.FONT_TTF;
} else {
type = MimeType.FONT_BYTESTREAM;
}
try {
return Response.builder()
.setMimeType(type)
.setContent(files.getCustomizableResourceOrDefault(fileName).asBytes())
.build();
} catch (IOException e) {
return notFound404("Font File not found from jar: " + fileName + ", " + e.toString());
}
return new ByteResponse(type, FileResponse.format(fileName), files);
}
public Response redirectResponse(String location) {
@ -313,12 +339,6 @@ public class ResponseFactory {
return stackTrace;
}
@Deprecated
public ErrorResponse forbidden403_old() {
return forbidden403_old("Your user is not authorized to view this page.<br>"
+ "If you believe this is an error contact staff to change your access level.");
}
public Response forbidden403() {
return forbidden403("Your user is not authorized to view this page.<br>"
+ "If you believe this is an error contact staff to change your access level.");
@ -336,24 +356,6 @@ public class ResponseFactory {
}
}
@Deprecated
public ErrorResponse forbidden403_old(String message) {
try {
return new ForbiddenResponse(message, versionCheckSystem, files);
} catch (IOException e) {
return internalErrorResponse_old(e, "Failed to generate ForbiddenResponse");
}
}
@Deprecated
public ErrorResponse basicAuth_old() {
try {
return PromptAuthorizationResponse.getBasicAuthResponse(versionCheckSystem, files);
} catch (IOException e) {
return internalErrorResponse_old(e, "Failed to generate PromptAuthorizationResponse");
}
}
public Response basicAuth() {
try {
String tips = "<br>- Ensure you have registered a user with <b>/plan register</b><br>"