mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 00:51:01 +03:00
[FIX][CRITICAL] Замена SimpleDateFormat на thread-safe DateTimeFormatter
This commit is contained in:
parent
92df57e491
commit
d7519688ee
2 changed files with 17 additions and 13 deletions
|
@ -17,9 +17,9 @@ public static void setUsingEpoll(boolean value) {
|
||||||
|
|
||||||
public static EventLoopGroup newEventLoopGroup(int threads, String poolName) {
|
public static EventLoopGroup newEventLoopGroup(int threads, String poolName) {
|
||||||
if (epoll)
|
if (epoll)
|
||||||
return new EpollEventLoopGroup(threads, new NettyThreadFactory(poolName));
|
return new EpollEventLoopGroup(threads);
|
||||||
else
|
else
|
||||||
return new NioEventLoopGroup(threads, new NettyThreadFactory(poolName));
|
return new NioEventLoopGroup(threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChannelFactory<? extends ServerChannel> getServerSocketChannelFactory() {
|
public static ChannelFactory<? extends ServerChannel> getServerSocketChannelFactory() {
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.Clock;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -26,7 +32,7 @@
|
||||||
|
|
||||||
public class FileServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
public class FileServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
||||||
|
|
||||||
public static final SimpleDateFormat dateFormatter;
|
public static final DateTimeFormatter dateFormatter;
|
||||||
public static final String READ = "r";
|
public static final String READ = "r";
|
||||||
public static final int HTTP_CACHE_SECONDS = VerifyHelper.verifyInt(Integer.parseInt(System.getProperty("launcher.fileserver.cachesec", "60")), VerifyHelper.NOT_NEGATIVE, "HttpCache seconds should be positive");
|
public static final int HTTP_CACHE_SECONDS = VerifyHelper.verifyInt(Integer.parseInt(System.getProperty("launcher.fileserver.cachesec", "60")), VerifyHelper.NOT_NEGATIVE, "HttpCache seconds should be positive");
|
||||||
private static final boolean OLD_ALGO = Boolean.parseBoolean(System.getProperty("launcher.fileserver.oldalgo", "true"));
|
private static final boolean OLD_ALGO = Boolean.parseBoolean(System.getProperty("launcher.fileserver.oldalgo", "true"));
|
||||||
|
@ -34,8 +40,7 @@ public class FileServerHandler extends SimpleChannelInboundHandler<FullHttpReque
|
||||||
private static final Pattern ALLOWED_FILE_NAME = Pattern.compile("[^-\\._]?[^<>&\\\"]*");
|
private static final Pattern ALLOWED_FILE_NAME = Pattern.compile("[^-\\._]?[^<>&\\\"]*");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
dateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
|
dateFormatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US).withZone(ZoneId.of("UTC"));
|
||||||
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Path base;
|
private final Path base;
|
||||||
|
@ -128,7 +133,7 @@ private static void sendNotModified(ChannelHandlerContext ctx) {
|
||||||
* @param response HTTP response
|
* @param response HTTP response
|
||||||
*/
|
*/
|
||||||
private static void setDateHeader(FullHttpResponse response) {
|
private static void setDateHeader(FullHttpResponse response) {
|
||||||
response.headers().set(HttpHeaderNames.DATE, dateFormatter.format(new Date(System.currentTimeMillis())));
|
response.headers().set(HttpHeaderNames.DATE, dateFormatter.format(Instant.ofEpochMilli(System.currentTimeMillis())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,15 +144,14 @@ private static void setDateHeader(FullHttpResponse response) {
|
||||||
*/
|
*/
|
||||||
private static void setDateAndCacheHeaders(HttpResponse response, File fileToCache) {
|
private static void setDateAndCacheHeaders(HttpResponse response, File fileToCache) {
|
||||||
// Date header
|
// Date header
|
||||||
Calendar time = new GregorianCalendar();
|
LocalDateTime time = LocalDateTime.now(Clock.systemUTC());
|
||||||
response.headers().set(HttpHeaderNames.DATE, dateFormatter.format(time.getTime()));
|
response.headers().set(HttpHeaderNames.DATE, dateFormatter.format(time));
|
||||||
|
|
||||||
// Add cache headers
|
// Add cache headers
|
||||||
time.add(Calendar.SECOND, HTTP_CACHE_SECONDS);
|
response.headers().set(HttpHeaderNames.EXPIRES, dateFormatter.format(time.plus(HTTP_CACHE_SECONDS, ChronoUnit.SECONDS)));
|
||||||
response.headers().set(HttpHeaderNames.EXPIRES, dateFormatter.format(time.getTime()));
|
|
||||||
response.headers().set(HttpHeaderNames.CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS);
|
response.headers().set(HttpHeaderNames.CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS);
|
||||||
response.headers().set(
|
response.headers().set(
|
||||||
HttpHeaderNames.LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified())));
|
HttpHeaderNames.LAST_MODIFIED, dateFormatter.format(Instant.ofEpochMilli(fileToCache.lastModified())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,11 +213,11 @@ public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) thr
|
||||||
// Cache Validation
|
// Cache Validation
|
||||||
String ifModifiedSince = request.headers().get(HttpHeaderNames.IF_MODIFIED_SINCE);
|
String ifModifiedSince = request.headers().get(HttpHeaderNames.IF_MODIFIED_SINCE);
|
||||||
if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
|
if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
|
||||||
Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);
|
TemporalAccessor ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);
|
||||||
|
|
||||||
// Only compare up to the second because the datetime format we send to the client
|
// Only compare up to the second because the datetime format we send to the client
|
||||||
// does not have milliseconds
|
// does not have milliseconds
|
||||||
long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
|
long ifModifiedSinceDateSeconds = ifModifiedSinceDate.get(ChronoField.INSTANT_SECONDS);
|
||||||
long fileLastModifiedSeconds = file.lastModified() / 1000;
|
long fileLastModifiedSeconds = file.lastModified() / 1000;
|
||||||
if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
|
if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
|
||||||
sendNotModified(ctx);
|
sendNotModified(ctx);
|
||||||
|
|
Loading…
Reference in a new issue