Progress on WebServer refactoring

This commit is contained in:
Rsl1122 2018-01-12 11:02:32 +02:00
parent 11cb29f7f8
commit 4d5f2b79b9
44 changed files with 687 additions and 204 deletions

View File

@ -35,7 +35,7 @@ import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plan.system.update.VersionCheckSystem;
import com.djrapitops.plan.system.webserver.WebServer;
import com.djrapitops.plan.system.webserver.WebServerSystem;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.systems.Systems;
import com.djrapitops.plan.systems.cache.DataCache;
import com.djrapitops.plan.systems.cache.GeolocationCache;
@ -237,7 +237,7 @@ public class Plan extends BukkitPlugin implements PlanPlugin {
@Override
public void onDisable() {
//Clears the page cache
PageCache.clearCache();
ResponseCache.clearCache();
// Processes unprocessed processors
if (processingQueue != null) {

View File

@ -32,6 +32,7 @@ public interface PlanPlugin extends IPlugin {
UUID getServerUuid();
@Deprecated
InformationManager getInfoManager();
WebServer getWebServer();

View File

@ -89,7 +89,7 @@ public class API {
}
/**
* Condition if Players's Inspect page is cached to PageCache.
* Condition if Players's Inspect page is cached to ResponseCache.
*
* @param uuid UUID of the player.
* @return true/false
@ -101,10 +101,10 @@ public class API {
}
/**
* Condition if Players's Inspect page is cached to PageCache of the providing WebServer.
* Condition if Players's Inspect page is cached to ResponseCache of the providing WebServer.
* <p>
* Using BungeeCord: Will send a {@code IsCachedWebAPI} request to check if the page is in Bungee's PageCache.
* Only Bukkit: Checks PageCache for page.
* Using BungeeCord: Will send a {@code IsCachedWebAPI} request to check if the page is in Bungee's ResponseCache.
* Only Bukkit: Checks ResponseCache for page.
*
* @param uuid UUID of the player.
* @return true/false
@ -114,7 +114,7 @@ public class API {
}
/**
* Cache Players's Inspect page to the PageCache of the providing WebServer.
* Cache Players's Inspect page to the ResponseCache of the providing WebServer.
*
* @param uuid UUID of the player.
* @deprecated use {@code cachePlayerHtml}
@ -125,10 +125,10 @@ public class API {
}
/**
* Cache Players's Inspect page to the PageCache of the providing WebServer.
* Cache Players's Inspect page to the ResponseCache of the providing WebServer.
* <p>
* Using BungeeCord: Will send a {@code PostHtmlWebAPI} request after calculating the inspect page.
* Only Bukkit: Calculates inspect page and places it in the PageCache.
* Only Bukkit: Calculates inspect page and places it in the ResponseCache.
*
* @param uuid UUID of the player.
* @deprecated use {@code cachePlayerHtml}

View File

@ -0,0 +1,21 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.api;
import com.djrapitops.plan.data.plugin.PluginData;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public interface PlanAPI {
static PlanAPI getInstance() {
throw new IllegalAccessError("Not yet implemented"); // TODO
}
void registerPluginData(PluginData pluginData);
}

View File

@ -1,27 +1,31 @@
/*
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.api.exceptions;
import com.djrapitops.plan.system.webserver.auth.FailReason;
/**
* Thrown when WebUser can not be authorized (WebServer).
*
* @author Rsl1122
*/
public class WebUserAuthException extends Exception {
public WebUserAuthException() {
}
public WebUserAuthException(String message) {
super(message);
}
private final FailReason failReason;
public WebUserAuthException(String message, Throwable cause) {
super(message, cause);
public WebUserAuthException(FailReason failReason) {
super(failReason.getReason());
this.failReason = failReason;
}
public WebUserAuthException(Throwable cause) {
super(cause);
super(FailReason.ERROR.getReason(), cause);
this.failReason = FailReason.ERROR;
}
public FailReason getFailReason() {
return failReason;
}
}

View File

@ -4,10 +4,13 @@
*/
package com.djrapitops.plan.system.webserver;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.response.*;
import com.djrapitops.plan.system.webserver.response.api.BadRequestResponse;
import com.djrapitops.plan.system.webserver.response.errors.ForbiddenResponse;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.pages.DebugPageResponse;
import com.djrapitops.plan.system.webserver.webapi.WebAPI;
import com.djrapitops.plan.system.webserver.webapi.WebAPIManager;
import com.djrapitops.plan.utilities.html.Html;
@ -40,29 +43,29 @@ public class APIResponseHandler {
String[] args = target.split("/");
if ("/favicon.ico".equalsIgnoreCase(target)) {
return PageCache.loadPage(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico"));
return ResponseCache.loadResponse(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico"));
}
if ("/debug".equalsIgnoreCase(target)) {
return new DebugPageResponse();
}
if (target.endsWith(".css")) {
return PageCache.loadPage(PageId.CSS.of(target), () -> new CSSResponse(target));
return ResponseCache.loadResponse(PageId.CSS.of(target), () -> new CSSResponse(target));
}
if (target.endsWith(".js")) {
return PageCache.loadPage(PageId.JS.of(target), () -> new JavaScriptResponse(target));
return ResponseCache.loadResponse(PageId.JS.of(target), () -> new JavaScriptResponse(target));
}
if (args.length < 2 || !"api".equals(args[1])) {
String address = PlanPlugin.getInstance().getInfoManager().getWebServerAddress() + target;
String link = Html.LINK.parse(address, address);
return PageCache.loadPage(PageId.ERROR.of("Non-API Request"), () -> new NotFoundResponse("WebServer is in WebAPI-only mode, " +
return ResponseCache.loadResponse(PageId.ERROR.of("Non-API Request"), () -> new NotFoundResponse("WebServer is in WebAPI-only mode, " +
"connect to the Bungee server instead: " + link));
}
if (args.length < 3) {
String error = "API Method not specified";
return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
}
String method = args[2];
@ -74,7 +77,7 @@ public class APIResponseHandler {
if (requestBody == null) {
String error = "Error at reading the POST request." +
"Note that the Encoding must be ISO-8859-1.";
return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
}
Map<String, String> variables = WebAPI.readVariables(requestBody);
@ -93,7 +96,7 @@ public class APIResponseHandler {
if (!checkKey(sender)) {
String error = "Server Key not given or invalid";
Log.debug("Request had invalid Server key: " + sender);
return PageCache.loadPage(PageId.ERROR.of(error), () -> {
return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> {
ForbiddenResponse forbidden = new ForbiddenResponse();
forbidden.setContent(error);
return forbidden;
@ -103,7 +106,7 @@ public class APIResponseHandler {
if (!webAPI.isAuthorized(accessKey)) {
String error = "Access Key invalid";
Log.debug("Request had invalid Access key: " + accessKey);
return PageCache.loadPage(PageId.ERROR.of(error), () -> {
return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> {
ForbiddenResponse forbidden = new ForbiddenResponse();
forbidden.setContent(error);
return forbidden;
@ -117,7 +120,7 @@ public class APIResponseHandler {
if (api == null) {
String error = "API Method not found";
Log.debug(error);
return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
}
Response response = api.processRequest(PlanPlugin.getInstance(), variables);

View File

@ -4,12 +4,14 @@
*/
package com.djrapitops.plan.system.webserver;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plugin.utilities.Verify;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import java.io.InputStream;
import java.util.List;
import java.util.Optional;
/**
* Represents a HttpExchange Request.
@ -19,7 +21,7 @@ import java.util.List;
* @author Rsl1122
*/
public class Request {
private String auth;
private Authentication auth;
private final String requestMethod;
private final String target;
@ -30,27 +32,14 @@ public class Request {
this.target = exchange.getRequestURI().toString();
this.exchange = exchange;
setAuth(exchange.getRequestHeaders());
}
public String getAuth() {
return auth;
public Optional<Authentication> getAuth() {
return Optional.ofNullable(auth);
}
public void setAuth(Headers requestHeaders) {
List<String> authorization = requestHeaders.get("Authorization");
if (Verify.isEmpty(authorization)) {
return;
}
String authLine = authorization.get(0);
if (authLine.contains("Basic ")) {
auth = authLine.split(" ")[1];
}
}
public boolean hasAuth() {
return auth != null;
public void setAuth(Authentication authentication) {
auth = authentication;
}
public String getRequestMethod() {

View File

@ -5,15 +5,19 @@
package com.djrapitops.plan.system.webserver;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.auth.BasicAuthentication;
import com.djrapitops.plan.system.webserver.response.PromptAuthorizationResponse;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plugin.api.Benchmark;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Verify;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.IOException;
import java.util.List;
/**
* HttpHandler for WebServer request management.
@ -30,8 +34,11 @@ public class RequestHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) {
Headers requestHeaders = exchange.getRequestHeaders();
Headers responseHeaders = exchange.getResponseHeaders();
Request request = new Request(exchange);
request.setAuth(getAuthorization(requestHeaders));
String requestString = request.toString();
Benchmark.start("", requestString);
int responseCode = -1;
@ -55,5 +62,17 @@ public class RequestHandler implements HttpHandler {
}
}
private Authentication getAuthorization(Headers requestHeaders) {
List<String> authorization = requestHeaders.get("Authorization");
if (Verify.isEmpty(authorization)) {
return null;
}
String authLine = authorization.get(0);
if (authLine.contains("Basic ")) {
return new BasicAuthentication(authLine.split(" ")[1]);
}
return null;
}
}

View File

@ -9,49 +9,104 @@ import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.database.tables.SecurityTable;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.auth.FailReason;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.pages.*;
import com.djrapitops.plan.system.webserver.response.*;
import com.djrapitops.plan.system.webserver.response.errors.ForbiddenResponse;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.DebugPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse;
import com.djrapitops.plan.utilities.PassEncryptUtil;
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
import com.djrapitops.plugin.api.utility.log.Log;
import java.sql.SQLException;
import java.util.Base64;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
/**
* Handles choosing of the correct response to a request.
*
* @author Rsl1122
*/
public class ResponseHandler extends APIResponseHandler {
public class ResponseHandler extends TreePageHandler {
private final boolean authRequired;
private final boolean usingHttps;
public ResponseHandler(WebServer webServer) {
super();
authRequired = webServer.isAuthRequired();
this.usingHttps = webServer.isUsingHTTPS();
}
public void registerDefaultPages() {
registerPage("favicon.ico", new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico"));
registerPage("debug", new DebugPageHandler());
registerPage("players", new PlayersPageHandler());
registerPage("player", new PlayerPageHandler());
ServerPageHandler serverPageHandler = new ServerPageHandler();
registerPage("network", serverPageHandler);
registerPage("server", serverPageHandler);
}
public void registerWebAPIPages() {
}
public Response getResponse(Request request) {
String target = request.getTarget();
String[] args = target.split("/");
String targetString = request.getTarget();
List<String> target = Arrays.asList(targetString.split("/"));
target.remove(0);
try {
if ("/favicon.ico".equals(target)) {
return PageCache.loadPage(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico"));
Optional<Authentication> authentication = Optional.empty();
if (authRequired) {
authentication = request.getAuth();
if (!authentication.isPresent() && usingHttps) {
return DefaultResponses.BASIC_AUTH.get();
}
if (authentication.isPresent() && !authentication.get().isAuthorized(null)) {
return forbiddenResponse(0, 0);
}
}
PageHandler pageHandler = getPageHandler(target);
if (pageHandler == null) {
if (targetString.endsWith(".css")) {
return ResponseCache.loadResponse(PageId.CSS.of(targetString), () -> new CSSResponse(targetString));
}
if (targetString.endsWith(".js")) {
return ResponseCache.loadResponse(PageId.JS.of(targetString), () -> new JavaScriptResponse(targetString));
}
return DefaultResponses.NOT_FOUND.get();
} else {
if (authentication.isPresent() && authentication.get().isAuthorized(pageHandler.getPermission())) {
return forbiddenResponse(0, 0);
}
return pageHandler.getResponse(request, target);
}
} catch (WebUserAuthException e) {
return PromptAuthorizationResponse.getBasicAuthResponse(e);
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
return new InternalErrorResponse(e, request.getTarget());
}
try {
if ("/favicon.ico".equals(targetString)) {
return ResponseCache.loadResponse(PageId.FAVICON_REDIRECT.id(), () -> new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico"));
}
if (request.isAPIRequest()) {
return getAPIResponse(request);
}
if (target.endsWith(".css")) {
return PageCache.loadPage(PageId.CSS.of(target), () -> new CSSResponse(target));
}
if (target.endsWith(".js")) {
return PageCache.loadPage(PageId.JS.of(target), () -> new JavaScriptResponse(target));
}
UUID serverUUID = PlanPlugin.getInstance().getServerUuid();
@ -61,7 +116,7 @@ public class ResponseHandler extends APIResponseHandler {
}
WebUser user = getUser(request.getAuth());
int required = getRequiredPermLevel(target, user.getName());
int required = getRequiredPermLevel(targetString, user.getName());
int permLevel = user.getPermLevel();
if (!isAuthorized(required, permLevel)) {
@ -79,7 +134,7 @@ public class ResponseHandler extends APIResponseHandler {
case "debug":
return new DebugPageResponse();
case "players":
return PageCache.loadPage(PageId.PLAYERS.id(), PlayersPageResponse::new);
return ResponseCache.loadResponse(PageId.PLAYERS.id(), PlayersPageResponse::new);
case "player":
return playerResponse(args);
case "network":
@ -100,7 +155,7 @@ public class ResponseHandler extends APIResponseHandler {
}
} catch (WebUserAuthException e) {
return PageCache.loadPage(PageId.AUTH_PROMPT.id(), PromptAuthorizationResponse::new);
return ResponseCache.loadResponse(PageId.AUTH_PROMPT.id(), PromptAuthorizationResponse::getBasicAuthResponse);
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
return new InternalErrorResponse(e, request.getTarget());
@ -108,7 +163,7 @@ public class ResponseHandler extends APIResponseHandler {
}
private Response forbiddenResponse(int required, int permLevel) {
return PageCache.loadPage(PageId.FORBIDDEN.id(), () ->
return ResponseCache.loadResponse(PageId.FORBIDDEN.of(required + "/" + permLevel), () ->
new ForbiddenResponse("Unauthorized User.<br>"
+ "Make sure your user has the correct access level.<br>"
+ "This page requires permission level of " + required + ",<br>"
@ -119,31 +174,6 @@ public class ResponseHandler extends APIResponseHandler {
return permLevel <= requiredPermLevel;
}
private WebUser getUser(String auth) throws SQLException, PassEncryptUtil.InvalidHashException, PassEncryptUtil.CannotPerformOperationException, WebUserAuthException {
Base64.Decoder decoder = Base64.getDecoder();
byte[] decoded = decoder.decode(auth);
String[] userInfo = new String(decoded).split(":");
if (userInfo.length != 2) {
throw new WebUserAuthException("User and Password not specified");
}
String user = userInfo[0];
String passwordRaw = userInfo[1];
SecurityTable securityTable = PlanPlugin.getInstance().getDB().getSecurityTable();
if (!securityTable.userExists(user)) {
throw new WebUserAuthException("User Doesn't exist");
}
WebUser webUser = securityTable.getWebUser(user);
boolean correctPass = PassEncryptUtil.verifyPassword(passwordRaw, webUser.getSaltedPassHash());
if (!correctPass) {
throw new WebUserAuthException("User and Password do not match");
}
return webUser;
}
private int getRequiredPermLevel(String target, String user) {
String[] t = target.split("/");
if (t.length < 2) {
@ -180,7 +210,7 @@ public class ResponseHandler extends APIResponseHandler {
case 0:
return serverResponse(serverUUID);
case 1:
return PageCache.loadPage(PageId.PLAYERS.id(), PlayersPageResponse::new);
return ResponseCache.loadResponse(PageId.PLAYERS.id(), PlayersPageResponse::new);
case 2:
return playerResponse(new String[]{"", "", user.getName()});
default:
@ -189,44 +219,12 @@ public class ResponseHandler extends APIResponseHandler {
}
private Response serverResponse(UUID serverUUID) {
return PageCache.loadPage(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(plugin.getInfoManager()));
}
private Response playerResponse(String[] args) {
if (args.length < 3) {
return PageCache.loadPage(PageId.NOT_FOUND.id(), NotFoundResponse::new);
}
String playerName = args[2].trim();
UUID uuid = UUIDUtility.getUUIDOf(playerName);
if (uuid == null) {
String error = "Player has no UUID";
return PageCache.loadPage(PageId.NOT_FOUND.of(error), () -> new NotFoundResponse(error));
}
if (plugin.getDB().wasSeenBefore(uuid)) {
plugin.getInfoManager().cachePlayer(uuid);
Response response = PageCache.loadPage(PageId.PLAYER.of(uuid));
// TODO Create a new method that places NotFoundResponse to PageCache instead.
if (response == null || response.getContent().contains("No Bukkit Servers were online to process this request")) {
PageCache.cachePage(PageId.PLAYER.of(uuid), () -> {
try {
return new InspectPageResponse(plugin.getInfoManager(), uuid);
} catch (ParseException e) {
return new InternalErrorResponse(e, this.getClass().getName());
}
});
response = PageCache.loadPage(PageId.PLAYER.of(uuid));
}
return response;
}
return new NotFoundResponse("Player has not played on this server.");
return ResponseCache.loadResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(plugin.getInfoManager()));
}
private Response notFoundResponse() {
String error = "404 Not Found";
return PageCache.loadPage(PageId.NOT_FOUND.of("Wrong Page"), () -> {
return ResponseCache.loadResponse(PageId.NOT_FOUND.of("Wrong Page"), () -> {
String url = plugin.getInfoManager().getWebServerAddress();
return new NotFoundResponse("Make sure you're accessing a link given by a command, Examples:</p>"
+ "<p>" + url + "/player/Playername<br>" +

View File

@ -0,0 +1,18 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.auth;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public interface Authentication {
boolean isAuthorized(String permission) throws WebUserAuthException;
}

View File

@ -0,0 +1,67 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.auth;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.database.tables.SecurityTable;
import com.djrapitops.plan.utilities.PassEncryptUtil;
import java.util.Base64;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class BasicAuthentication implements Authentication {
private String authenticationString;
private WebUser user;
public BasicAuthentication(String authenticationString) {
this.authenticationString = authenticationString;
}
@Override
public boolean isAuthorized(String permission) throws WebUserAuthException {
if (user == null) {
user = getUser();
return user.hasPermission(permission);
}
return false;
}
public WebUser getUser() throws WebUserAuthException {
Base64.Decoder decoder = Base64.getDecoder();
byte[] decoded = decoder.decode(authenticationString);
String[] userInfo = new String(decoded).split(":");
if (userInfo.length != 2) {
throw new WebUserAuthException(FailReason.USER_AND_PASS_NOT_SPECIFIED);
}
String user = userInfo[0];
String passwordRaw = userInfo[1];
try {
SecurityTable securityTable = PlanPlugin.getInstance().getDB().getSecurityTable();
if (!securityTable.userExists(user)) {
throw new WebUserAuthException(FailReason.USER_DOES_NOT_EXIST);
}
WebUser webUser = securityTable.getWebUser(user);
boolean correctPass = PassEncryptUtil.verifyPassword(passwordRaw, webUser.getSaltedPassHash());
if (!correctPass) {
throw new WebUserAuthException(FailReason.USER_PASS_MISMATCH);
}
return webUser;
} catch (Exception e) {
throw new WebUserAuthException(e);
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.auth;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public enum FailReason {
USER_AND_PASS_NOT_SPECIFIED("User and Password not specified"),
USER_DOES_NOT_EXIST("User does not exist"),
USER_PASS_MISMATCH("User and Password did not match"),
ERROR("Authentication failed due to error");
private final String reason;
FailReason(String reason) {
this.reason = reason;
}
public String getReason() {
return reason;
}
}

View File

@ -7,7 +7,7 @@ package com.djrapitops.plan.system.webserver.pagecache;
import java.util.UUID;
/**
* Enum class for "magic" PageCache identifier values.
* Enum class for "magic" ResponseCache identifier values.
*
* @author Rsl1122
*/

View File

@ -1,6 +1,6 @@
package com.djrapitops.plan.system.webserver.pagecache;
import com.djrapitops.plan.system.webserver.response.InspectPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse;
import com.djrapitops.plan.system.webserver.response.Response;
import java.util.HashMap;
@ -17,14 +17,14 @@ import java.util.function.Predicate;
* @author Fuzzlemann
* @since 3.6.0
*/
public class PageCache {
public class ResponseCache {
private static final Map<String, Response> pageCache = new HashMap<>();
private static final Map<String, Response> cache = new HashMap<>();
/**
* Constructor used to hide the public constructor
*/
private PageCache() {
private ResponseCache() {
throw new IllegalStateException("Utility class");
}
@ -40,8 +40,8 @@ public class PageCache {
* @param loader The {@link PageLoader} (How should it load the page if it's not cached)
* @return The Response that was cached or created by the {@link PageLoader loader}
*/
public static Response loadPage(String identifier, PageLoader loader) {
Response response = loadPage(identifier);
public static Response loadResponse(String identifier, PageLoader loader) {
Response response = loadResponse(identifier);
if (response != null) {
return response;
@ -49,7 +49,7 @@ public class PageCache {
response = loader.createResponse();
pageCache.put(identifier, response);
cache.put(identifier, response);
return response;
}
@ -60,8 +60,8 @@ public class PageCache {
* @param identifier The identifier of the page
* @return The Response that was cached or {@code null} if it wasn't
*/
public static Response loadPage(String identifier) {
return pageCache.get(identifier);
public static Response loadResponse(String identifier) {
return cache.get(identifier);
}
/**
@ -70,10 +70,10 @@ public class PageCache {
* Currently supported copyable responses: InspectPageResponse
*
* @param identifier The identifier of the page
* @return Copied Response of loadPage, so that cache contents are not changed.
* @return Copied Response of loadResponse, so that cache contents are not changed.
*/
public static Response copyPage(String identifier, PageLoader loader) {
Response response = loadPage(identifier, loader);
public static Response copyResponse(String identifier, PageLoader loader) {
Response response = loadResponse(identifier, loader);
if (response instanceof InspectPageResponse) {
return InspectPageResponse.copyOf((InspectPageResponse) response);
}
@ -88,9 +88,9 @@ public class PageCache {
* @param identifier The identifier of the page
* @param loader The {@link PageLoader} (How it should load the page)
*/
public static void cachePage(String identifier, PageLoader loader) {
public static void cacheResponse(String identifier, PageLoader loader) {
Response response = loader.createResponse();
pageCache.put(identifier, response);
cache.put(identifier, response);
}
/**
@ -100,7 +100,7 @@ public class PageCache {
* @return true if the page is cached
*/
public static boolean isCached(String identifier) {
return pageCache.containsKey(identifier);
return cache.containsKey(identifier);
}
/**
@ -109,9 +109,9 @@ public class PageCache {
* @param filter a predicate which returns true for entries to be removed
*/
public static void removeIf(Predicate<String> filter) {
for (String identifier : pageCache.keySet()) {
for (String identifier : cache.keySet()) {
if (filter.test(identifier)) {
pageCache.remove(identifier);
cache.remove(identifier);
}
}
}
@ -120,6 +120,6 @@ public class PageCache {
* Clears the cache from all its contents.
*/
public static void clearCache() {
pageCache.clear();
cache.clear();
}
}

View File

@ -0,0 +1,24 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.pages;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.pages.DebugPageResponse;
import java.util.List;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class DebugPageHandler extends PageHandler {
@Override
public Response getResponse(Request request, List<String> target) {
return new DebugPageResponse();
}
}

View File

@ -0,0 +1,33 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.pages;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.PromptAuthorizationResponse;
import com.djrapitops.plan.system.webserver.response.Response;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public enum DefaultResponses {
NOT_FOUND(
new NotFoundResponse("Make sure you're accessing a link given by a command, Examples:</p>"
+ "<p>/player/PlayerName<br>" +
"/server/ServerName</p>")
),
BASIC_AUTH(PromptAuthorizationResponse.getBasicAuthResponse());
private final Response response;
DefaultResponses(Response response) {
this.response = response;
}
public Response get() {
return response;
}
}

View File

@ -0,0 +1,26 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.pages;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.response.Response;
import java.util.List;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public abstract class PageHandler {
protected String permission = "*";
public abstract Response getResponse(Request request, List<String> target);
public String getPermission() {
return permission;
}
}

View File

@ -0,0 +1,67 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.pages;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse;
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
import java.util.List;
import java.util.UUID;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class PlayerPageHandler extends PageHandler {
public PlayerPageHandler() {
permission = "special_player";
}
@Override
public Response getResponse(Request request, List<String> target) {
if (target.isEmpty()) {
return DefaultResponses.NOT_FOUND.get();
}
String playerName = target.get(0);
UUID uuid = UUIDUtility.getUUIDOf(playerName);
if (uuid == null) {
return notFound("Player has no UUID");
}
if (PlanPlugin.getInstance().getDB().wasSeenBefore(uuid)) {
PlanPlugin.getInstance().getInfoManager().cachePlayer(uuid);
Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid));
// TODO Create a new method that places NotFoundResponse to ResponseCache instead.
if (response == null || response.getContent().contains("No Bukkit Servers were online to process this request")) {
ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> {
try {
return new InspectPageResponse(PlanPlugin.getInstance().getInfoManager(), uuid);
} catch (ParseException e) {
return new InternalErrorResponse(e, this.getClass().getName());
}
});
response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid));
}
return response;
}
return notFound("Player has not played on this server.");
}
private Response notFound(String error) {
return ResponseCache.loadResponse(PageId.NOT_FOUND.of(error), () -> new NotFoundResponse(error));
}
}

View File

@ -0,0 +1,30 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.pages;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse;
import java.util.List;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class PlayersPageHandler extends PageHandler {
public PlayersPageHandler() {
permission = "players";
}
@Override
public Response getResponse(Request request, List<String> target) {
return ResponseCache.loadResponse(PageId.PLAYERS.id(), PlayersPageResponse::new);
}
}

View File

@ -0,0 +1,27 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.pages;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.response.Response;
import java.util.List;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class ServerPageHandler extends PageHandler {
public ServerPageHandler() {
permission = "server";
}
@Override
public Response getResponse(Request request, List<String> target) {
return null;
}
}

View File

@ -0,0 +1,53 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.pages;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.response.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public abstract class TreePageHandler extends PageHandler {
private Map<String, PageHandler> pages;
public TreePageHandler() {
pages = new HashMap<>();
}
public void registerPage(String targetPage, PageHandler handler) {
pages.put(targetPage, handler);
}
public void registerPage(String targetPage, Response response) {
pages.put(targetPage, new PageHandler() {
@Override
public Response getResponse(Request request, List<String> target) {
return response;
}
});
}
@Override
public Response getResponse(Request request, List<String> target) {
PageHandler pageHandler = getPageHandler(target);
return pageHandler != null
? pageHandler.getResponse(request, target)
: DefaultResponses.NOT_FOUND.get();
}
public PageHandler getPageHandler(List<String> target) {
String targetPage = target.get(0);
target.remove(0);
return pages.get(targetPage);
}
}

View File

@ -4,6 +4,7 @@
*/
package com.djrapitops.plan.system.webserver.response;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.utilities.file.FileUtil;
import com.djrapitops.plugin.utilities.Verify;

View File

@ -1,5 +1,9 @@
package com.djrapitops.plan.system.webserver.response;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.system.webserver.auth.FailReason;
import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse;
import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.html.Html;
/**
@ -8,15 +12,43 @@ import com.djrapitops.plan.utilities.html.Html;
*/
public class PromptAuthorizationResponse extends ErrorResponse {
public PromptAuthorizationResponse() {
super.setHeader("HTTP/1.1 401 Access Denied\r\n"
private PromptAuthorizationResponse() {
super.setTitle(Html.FONT_AWESOME_ICON.parse("lock") + " 401 Unauthorized");
}
public static PromptAuthorizationResponse getBasicAuthResponse() {
PromptAuthorizationResponse response = new PromptAuthorizationResponse();
response.setHeader("HTTP/1.1 401 Access Denied\r\n"
+ "WWW-Authenticate: Basic realm=\"/\";");
super.setTitle(Html.FONT_AWESOME_ICON.parse("lock")+" 401 Unauthorized");
super.setParagraph("Authentication Failed.<br>"
response.setParagraph("Authentication Failed.<br>"
+ "- Ensure you have registered a user with <b>/plan register</b><br>"
+ "- Check that the username and password are correct<br>"
+ "- Username and password are case-sensitive<br>"
+ "<br>If you have forgotten your password, ask a staff member to delete your old user and re-register.");
super.replacePlaceholders();
response.replacePlaceholders();
return response;
}
public static PromptAuthorizationResponse getBasicAuthResponse(WebUserAuthException e) {
PromptAuthorizationResponse response = new PromptAuthorizationResponse();
response.setHeader("HTTP/1.1 401 Access Denied\r\n"
+ "WWW-Authenticate: Basic realm=\"/\";");
FailReason failReason = e.getFailReason();
String reason = failReason.getReason();
if (failReason == FailReason.ERROR) {
StringBuilder errorBuilder = new StringBuilder("</p><pre>");
for (String line : FormatUtils.getStackTrace(e.getCause())) {
errorBuilder.append(line);
}
errorBuilder.append("</pre>");
reason += errorBuilder.toString();
}
response.setParagraph("Authentication Failed.<br>Reason: " + reason);
response.replacePlaceholders();
return response;
}
}

View File

@ -2,9 +2,10 @@
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.errors;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.file.FileUtil;
import com.djrapitops.plugin.api.utility.log.Log;

View File

@ -1,4 +1,4 @@
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.errors;
import com.djrapitops.plan.utilities.html.Html;

View File

@ -1,4 +1,4 @@
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.errors;
import com.djrapitops.plan.utilities.html.Html;

View File

@ -1,4 +1,4 @@
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.errors;
import com.djrapitops.plan.utilities.html.Html;

View File

@ -1,7 +1,9 @@
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.pages;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.data.AnalysisData;
import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.systems.info.BukkitInformationManager;
import com.djrapitops.plan.systems.info.InformationManager;
import com.djrapitops.plugin.task.AbsRunnable;

View File

@ -2,11 +2,12 @@
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.pages;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.ServerVariableHolder;
import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse;
import com.djrapitops.plan.systems.info.server.BungeeServerInfoManager;
import com.djrapitops.plan.systems.info.server.ServerInfo;
import com.djrapitops.plan.utilities.file.FileUtil;

View File

@ -1,7 +1,8 @@
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.pages;
import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.systems.info.InformationManager;
import org.apache.commons.lang3.text.StrSubstitutor;

View File

@ -1,4 +1,4 @@
package com.djrapitops.plan.system.webserver.response;
package com.djrapitops.plan.system.webserver.response.pages;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.container.GeoInfo;
@ -8,6 +8,8 @@ import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import com.djrapitops.plan.utilities.comparators.GeoInfoComparator;

View File

@ -7,9 +7,9 @@ package com.djrapitops.plan.system.webserver.webapi;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.*;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.response.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.api.BadRequestResponse;
import com.djrapitops.plan.system.webserver.response.api.SuccessResponse;
@ -165,11 +165,11 @@ public abstract class WebAPI {
};
protected Response success() {
return PageCache.loadPage(PageId.TRUE.id(), SuccessResponse::new);
return ResponseCache.loadResponse(PageId.TRUE.id(), SuccessResponse::new);
}
protected Response fail(String reason) {
return PageCache.loadPage(PageId.FALSE.id(), () -> {
return ResponseCache.loadResponse(PageId.FALSE.id(), () -> {
NotFoundResponse notFoundResponse = new NotFoundResponse("");
notFoundResponse.setContent(reason);
return notFoundResponse;
@ -177,7 +177,7 @@ public abstract class WebAPI {
}
protected Response badRequest(String error) {
return PageCache.loadPage(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
return ResponseCache.loadResponse(PageId.ERROR.of(error), () -> new BadRequestResponse(error));
}
private String parseVariables() {

View File

@ -7,10 +7,10 @@ package com.djrapitops.plan.system.webserver.webapi.bungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.WebAPIException;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.response.AnalysisPageResponse;
import com.djrapitops.plan.system.webserver.response.InspectPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.webapi.WebAPI;
import com.djrapitops.plan.systems.info.InformationManager;
@ -55,14 +55,14 @@ public class PostHtmlWebAPI extends WebAPI {
Map<String, String> map = new HashMap<>();
map.put("networkName", Settings.BUNGEE_NETWORK_NAME.toString());
PageCache.cachePage(PageId.PLAYER.of(uuid), () -> new InspectPageResponse(infoManager, UUID.fromString(uuid), StrSubstitutor.replace(html, map)));
ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> new InspectPageResponse(infoManager, UUID.fromString(uuid), StrSubstitutor.replace(html, map)));
if (Settings.ANALYSIS_EXPORT.isTrue()) {
HtmlExport.exportPlayer(plugin, UUID.fromString(uuid));
}
break;
case "analysisPage":
String sender = variables.get("sender");
PageCache.cachePage(PageId.SERVER.of(sender), () -> new AnalysisPageResponse(html));
ResponseCache.cacheResponse(PageId.SERVER.of(sender), () -> new AnalysisPageResponse(html));
if (Settings.ANALYSIS_EXPORT.isTrue()) {
HtmlExport.exportServer(plugin, UUID.fromString(sender));
}

View File

@ -9,7 +9,7 @@ import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.WebAPIException;
import com.djrapitops.plan.system.webserver.response.ForbiddenResponse;
import com.djrapitops.plan.system.webserver.response.errors.ForbiddenResponse;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.webapi.WebAPI;
import com.djrapitops.plan.systems.info.server.ServerInfo;

View File

@ -15,9 +15,14 @@ import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.WebServer;
import com.djrapitops.plan.system.webserver.WebServerSystem;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.response.*;
import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse;
import com.djrapitops.plan.system.webserver.webapi.WebAPIManager;
import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalysisReadyWebAPI;
import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalyzeWebAPI;
@ -41,7 +46,7 @@ import java.sql.SQLException;
import java.util.*;
/**
* Manages the Information going to the PageCache.
* Manages the Information going to the ResponseCache.
* <p>
* This means Inspect and Analysis pages as well as managing what is sent to Bungee WebServer when one is in use.
*
@ -115,7 +120,7 @@ public class BukkitInformationManager extends InformationManager {
}
}
} else {
PageCache.cachePage(PageId.PLAYER.of(uuid), () -> {
ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> {
try {
return new InspectPageResponse(this, uuid);
} catch (ParseException e) {
@ -188,7 +193,7 @@ public class BukkitInformationManager extends InformationManager {
}
} else {
pluginsTabContents.put(uuid, contents);
Response inspectResponse = PageCache.loadPage(PageId.PLAYER.of(uuid));
Response inspectResponse = ResponseCache.loadResponse(PageId.PLAYER.of(uuid));
if (inspectResponse != null && inspectResponse instanceof InspectPageResponse) {
((InspectPageResponse) inspectResponse).setInspectPagePluginsTab(contents);
}
@ -231,7 +236,7 @@ public class BukkitInformationManager extends InformationManager {
return isAnalysisCached(serverUUID);
}
}
return PageCache.isCached(PageId.SERVER.of(serverUUID));
return ResponseCache.isCached(PageId.SERVER.of(serverUUID));
}
private WebAPIManager getWebAPI() {
@ -306,7 +311,7 @@ public class BukkitInformationManager extends InformationManager {
}
} else {
UUID serverUUID = Plan.getServerUUID();
PageCache.cachePage(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(html));
ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(html));
if (Settings.ANALYSIS_EXPORT.isTrue()) {
HtmlExport.exportServer(plugin, serverUUID);
}

View File

@ -10,9 +10,13 @@ import com.djrapitops.plan.api.exceptions.WebAPIConnectionFailException;
import com.djrapitops.plan.api.exceptions.WebAPIException;
import com.djrapitops.plan.api.exceptions.WebAPINotFoundException;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.response.*;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse;
import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse;
import com.djrapitops.plan.system.webserver.webapi.WebAPIManager;
import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalysisReadyWebAPI;
import com.djrapitops.plan.system.webserver.webapi.bukkit.AnalyzeWebAPI;
@ -35,7 +39,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Manages information going to the PageCache from Bukkit servers.
* Manages information going to the ResponseCache from Bukkit servers.
*
* @author Rsl1122
*/
@ -233,7 +237,7 @@ public class BungeeInformationManager extends InformationManager {
*/
@Override
public boolean isAnalysisCached(UUID serverUUID) {
return PageCache.isCached(PageId.SERVER.of(serverUUID));
return ResponseCache.isCached(PageId.SERVER.of(serverUUID));
}
/**
@ -246,7 +250,7 @@ public class BungeeInformationManager extends InformationManager {
*/
@Override
public String getPlayerHtml(UUID uuid) {
Response response = PageCache.copyPage(PageId.PLAYER.of(uuid),
Response response = ResponseCache.copyResponse(PageId.PLAYER.of(uuid),
() -> new NotFoundResponse("No Bukkit Servers were online to process this request"));
if (response instanceof InspectPageResponse) {
((InspectPageResponse) response).setInspectPagePluginsTab(getPluginsTabContent(uuid));
@ -310,7 +314,7 @@ public class BungeeInformationManager extends InformationManager {
Map<UUID, String[]> perServerPluginsTab = pluginsTabContent.getOrDefault(uuid, new HashMap<>());
perServerPluginsTab.put(serverUUID, html);
pluginsTabContent.put(uuid, perServerPluginsTab);
Response inspectResponse = PageCache.loadPage(PageId.PLAYER.of(uuid));
Response inspectResponse = ResponseCache.loadResponse(PageId.PLAYER.of(uuid));
if (inspectResponse != null && inspectResponse instanceof InspectPageResponse) {
((InspectPageResponse) inspectResponse).setInspectPagePluginsTab(getPluginsTabContent(uuid));
}
@ -368,7 +372,7 @@ public class BungeeInformationManager extends InformationManager {
@Override
public void updateNetworkPageContent() {
UUID serverUUID = PlanPlugin.getInstance().getServerUuid();
PageCache.cachePage(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(this));
ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(this));
if (Settings.ANALYSIS_EXPORT.isTrue()) {
HtmlExport.exportServer(plugin, serverUUID);
}

View File

@ -5,7 +5,7 @@
package com.djrapitops.plan.systems.info;
import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.systems.cache.DataCache;
import com.djrapitops.plan.systems.cache.SessionCache;
@ -47,7 +47,7 @@ public abstract class InformationManager {
}
public boolean isCached(UUID uuid) {
return PageCache.isCached(PageId.PLAYER.of(uuid));
return ResponseCache.isCached(PageId.PLAYER.of(uuid));
}
public abstract String getPlayerHtml(UUID uuid) throws ParseException;

View File

@ -17,7 +17,7 @@ import com.djrapitops.plugin.command.ISender;
import java.util.UUID;
/**
* Sends a request to cache players inspect page to the PageCache on the appropriate WebServer.
* Sends a request to cache players inspect page to the ResponseCache on the appropriate WebServer.
*
* @author Rsl1122
*/

View File

@ -6,6 +6,8 @@ import org.apache.commons.lang3.StringUtils;
import org.bukkit.Location;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
/**
* @author Rsl1122
@ -241,4 +243,29 @@ public class FormatUtils {
return b.append("xx").toString();
}
/**
* Gets lines for stack trace recursively.
*
* @param throwable
* @return
*/
public static List<String> getStackTrace(Throwable throwable) {
List<String> stackTrace = new ArrayList<>();
stackTrace.add(throwable.toString());
for (StackTraceElement element : throwable.getStackTrace()) {
stackTrace.add(" " + element.toString());
}
Throwable cause = throwable.getCause();
if (cause != null) {
List<String> causeTrace = getStackTrace(cause);
if (!causeTrace.isEmpty()) {
causeTrace.set(0, "Caused by: " + causeTrace.get(0));
stackTrace.addAll(causeTrace);
}
}
return stackTrace;
}
}

View File

@ -11,8 +11,8 @@ import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.response.ErrorResponse;
import com.djrapitops.plan.system.webserver.response.InternalErrorResponse;
import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.systems.cache.DataCache;
import com.djrapitops.plan.systems.cache.SessionCache;
import com.djrapitops.plan.systems.info.BukkitInformationManager;

View File

@ -11,7 +11,7 @@ import java.util.ConcurrentModificationException;
import java.util.UUID;
/**
* Task that exports a single Analysis page if it is in PageCache.
* Task that exports a single Analysis page if it is in ResponseCache.
*
* @author Rsl1122
*/

View File

@ -8,7 +8,7 @@ import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.container.UserInfo;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.settings.theme.ThemeVal;
import com.djrapitops.plan.system.webserver.response.PlayersPageResponse;
import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse;
import com.djrapitops.plan.system.webserver.webapi.bungee.PostHtmlWebAPI;
import com.djrapitops.plan.utilities.file.FileUtil;
import com.djrapitops.plugin.api.utility.log.Log;

View File

@ -5,7 +5,7 @@
package com.djrapitops.plan.utilities.file.export;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageId;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plugin.api.Check;
@ -73,7 +73,7 @@ public abstract class SpecificExport extends AbsRunnable {
}
protected void exportAvailablePlayerPage(UUID uuid, String name) throws IOException {
Response response = PageCache.loadPage(PageId.PLAYER.of(uuid));
Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid));
if (response == null) {
return;
}
@ -90,7 +90,7 @@ public abstract class SpecificExport extends AbsRunnable {
protected void exportAvailableServerPage(UUID serverUUID, String serverName) throws IOException {
Response response = PageCache.loadPage(PageId.SERVER.of(serverUUID));
Response response = ResponseCache.loadResponse(PageId.SERVER.of(serverUUID));
if (response == null) {
return;
}

View File

@ -1,6 +1,6 @@
package com.djrapitops.plan.data.cache;
import com.djrapitops.plan.system.webserver.pagecache.PageCache;
import com.djrapitops.plan.system.webserver.pagecache.ResponseCache;
import com.djrapitops.plan.system.webserver.pagecache.PageLoader;
import com.djrapitops.plan.system.webserver.response.Response;
import org.junit.Test;
@ -11,7 +11,7 @@ import static junit.framework.TestCase.*;
/**
* @author Fuzzlemann
*/
public class PageCacheTest {
public class ResponseCacheTest {
private final String IDENTIFIER = RandomData.randomString(10);
private final String RESPONSE_STRING = RandomData.randomString(10);
private final Response RESPONSE = new Response() {
@ -34,29 +34,29 @@ public class PageCacheTest {
public void testCache() {
Response expResponse = LOADER.createResponse();
assertFalse(PageCache.isCached(IDENTIFIER));
assertFalse(ResponseCache.isCached(IDENTIFIER));
Response response = PageCache.loadPage(IDENTIFIER, LOADER);
assertTrue(PageCache.isCached(IDENTIFIER));
Response response = ResponseCache.loadResponse(IDENTIFIER, LOADER);
assertTrue(ResponseCache.isCached(IDENTIFIER));
assertEquals(expResponse, response);
}
@Test
public void testClearCache() {
PageCache.cachePage(IDENTIFIER, LOADER);
assertTrue(PageCache.isCached(IDENTIFIER));
ResponseCache.cacheResponse(IDENTIFIER, LOADER);
assertTrue(ResponseCache.isCached(IDENTIFIER));
PageCache.clearCache();
assertFalse(PageCache.isCached(IDENTIFIER));
ResponseCache.clearCache();
assertFalse(ResponseCache.isCached(IDENTIFIER));
}
@Test
public void testRemoveIf() {
PageCache.cachePage(IDENTIFIER, LOADER);
assertTrue(PageCache.isCached(IDENTIFIER));
ResponseCache.cacheResponse(IDENTIFIER, LOADER);
assertTrue(ResponseCache.isCached(IDENTIFIER));
PageCache.removeIf(identifier -> identifier.equals(IDENTIFIER));
assertFalse(PageCache.isCached(IDENTIFIER));
ResponseCache.removeIf(identifier -> identifier.equals(IDENTIFIER));
assertFalse(ResponseCache.isCached(IDENTIFIER));
}
}