From b50fa10e12187beb0d8c3d12875bb62b33f7a39f Mon Sep 17 00:00:00 2001 From: Aurora Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:11:32 +0200 Subject: [PATCH] Reduce DDoS impact of access log transactions Made Plan skip access logging if transaction queue is larger than 500 transactions Reduced amount of objects held by access log transaction by serializing request properties to objects before passing to transaction. Affects issues: - #3486 --- .../delivery/webserver/http/AccessLogger.java | 8 ++- .../events/StoreRequestTransaction.java | 58 +++++++++---------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/http/AccessLogger.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/http/AccessLogger.java index 1730781fa..e20e5d206 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/http/AccessLogger.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/http/AccessLogger.java @@ -75,8 +75,14 @@ public class AccessLogger { } } try { + long timestamp = internalRequest.getTimestamp(); + String accessAddress = internalRequest.getAccessAddress(webserverConfiguration); + String method = internalRequest.getMethod(); + method = method != null ? method : "?"; + String url = StoreRequestTransaction.getTruncatedURI(request, internalRequest); + int responseCode = response.getCode(); dbSystem.getDatabase().executeTransaction( - new StoreRequestTransaction(webserverConfiguration, internalRequest, request, response) + new StoreRequestTransaction(timestamp, accessAddress, method, url, responseCode) ); } catch (CompletionException | DBOpException e) { errorLogger.warn(e, ErrorContext.builder() diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/StoreRequestTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/StoreRequestTransaction.java index 0f042d110..96c9f56b7 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/StoreRequestTransaction.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/StoreRequestTransaction.java @@ -16,49 +16,33 @@ */ package com.djrapitops.plan.storage.database.transactions.events; -import com.djrapitops.plan.delivery.web.resolver.Response; import com.djrapitops.plan.delivery.web.resolver.request.Request; -import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration; import com.djrapitops.plan.delivery.webserver.http.InternalRequest; import com.djrapitops.plan.storage.database.sql.tables.AccessLogTable; import com.djrapitops.plan.storage.database.transactions.ExecStatement; -import com.djrapitops.plan.storage.database.transactions.Transaction; +import com.djrapitops.plan.storage.database.transactions.ThrowawayTransaction; import org.apache.commons.lang3.StringUtils; import java.sql.PreparedStatement; import java.sql.SQLException; -public class StoreRequestTransaction extends Transaction { +public class StoreRequestTransaction extends ThrowawayTransaction { - private final WebserverConfiguration webserverConfiguration; + private final long timestamp; + private final String accessAddress; + private final String method; + private final String url; + private final int responseCode; - private final InternalRequest internalRequest; - private final Request request; // can be null - private final Response response; - - public StoreRequestTransaction(WebserverConfiguration webserverConfiguration, InternalRequest internalRequest, Request request, Response response) { - this.webserverConfiguration = webserverConfiguration; - this.internalRequest = internalRequest; - this.request = request; - this.response = response; + public StoreRequestTransaction(long timestamp, String accessAddress, String method, String url, int responseCode) { + this.timestamp = timestamp; + this.accessAddress = accessAddress; + this.method = method; + this.url = url; + this.responseCode = responseCode; } - @Override - protected void performOperations() { - execute(new ExecStatement(AccessLogTable.INSERT_NO_USER) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, internalRequest.getTimestamp()); - statement.setString(2, internalRequest.getAccessAddress(webserverConfiguration)); - String method = internalRequest.getMethod(); - statement.setString(3, method != null ? method : "?"); - statement.setString(4, getTruncatedURI()); - statement.setInt(5, response.getCode()); - } - }); - } - - private String getTruncatedURI() { + public static String getTruncatedURI(Request request, InternalRequest internalRequest) { String uri = request != null ? request.getPath().asString() + request.getQuery().asString() : internalRequest.getRequestedURIString(); if (uri == null) { @@ -66,4 +50,18 @@ public class StoreRequestTransaction extends Transaction { } return StringUtils.truncate(uri, 65000); } + + @Override + protected void performOperations() { + execute(new ExecStatement(AccessLogTable.INSERT_NO_USER) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setLong(1, timestamp); + statement.setString(2, accessAddress); + statement.setString(3, method); + statement.setString(4, url); + statement.setInt(5, responseCode); + } + }); + } }