Skip to content

Commit

Permalink
Merge pull request #147 from Lixuhuilll/compression
Browse files Browse the repository at this point in the history
启用响应体自动压缩,进一步节约服务器带宽
  • Loading branch information
dragove authored Dec 9, 2023
2 parents dcec28b + 65b895c commit 6743d06
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 47 deletions.
2 changes: 0 additions & 2 deletions src/main/java/plus/maa/backend/MainApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
Expand All @@ -18,7 +17,6 @@
@SpringBootApplication
@ConfigurationPropertiesScan
@EnableMethodSecurity
@ServletComponentScan
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public MaaResult<CopilotInfo> getCopilotById(
public MaaResult<CopilotPageInfo> queriesCopilot(
@Parameter(description = "作业查询请求") @Valid CopilotQueriesRequest parsed
) {
// 两秒防抖,缓解前端重复请求问题
response.setHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=2, must-revalidate");
// 三秒防抖,缓解前端重复请求问题
response.setHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=3, must-revalidate");
return MaaResult.success(copilotService.queriesCopilot(helper.getUserId(), parsed));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package plus.maa.backend.filter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import org.springframework.web.util.ContentCachingResponseWrapper;

import java.io.IOException;
import java.io.InputStream;

/**
* 解决了 GZIP 无法对 JSON 响应正常处理 min-response-size 的问题,
* 借助了 ETag 处理流程中的 Response 包装类包装所有响应,
* 从而正常获取 Content-Length
*
* @author lixuhuilll
*/

@Component
@ConditionalOnProperty(name = "server.compression.enabled", havingValue = "true")
public class ContentLengthRepairFilter extends ShallowEtagHeaderFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (response instanceof ContentCachingResponseWrapper) {
// 不对已包装过的响应体做处理
filterChain.doFilter(request, response);
} else {
super.doFilterInternal(request, response, filterChain);
}
}

@Override
protected boolean isEligibleForEtag(HttpServletRequest request, HttpServletResponse response, int responseStatusCode, InputStream inputStream) {
return false;
}
}
43 changes: 0 additions & 43 deletions src/main/java/plus/maa/backend/filter/MaaEtagHeaderFilter.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package plus.maa.backend.filter;

import jakarta.annotation.PostConstruct;
import jakarta.servlet.Filter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.ShallowEtagHeaderFilter;

import java.io.InputStream;
import java.util.Set;


/**
* 提供基于 Etag 机制的 HTTP 缓存,有助于降低网络传输的压力
*
* @author lixuhuilll
*/

@Component
public class MaaEtagHeaderFilterRegistrationBean extends FilterRegistrationBean<Filter> {

/**
* 配置需要使用 Etag 机制的 URI,采用 Servlet 的 URI 匹配语法
*/
private final Set<String> ETAG_URI = Set.of(
"/arknights/level",
"/copilot/query"
);

@PostConstruct
public void init() {
setFilter(new MaaEtagHeaderFilter());
setUrlPatterns(ETAG_URI);
}

private static class MaaEtagHeaderFilter extends ShallowEtagHeaderFilter {

private static final String CACHE_HEAD = "private, no-cache, max-age=0, must-revalidate";

@Override
protected void initFilterBean() {
// Etag 必须使用弱校验才能与自动压缩兼容
setWriteWeakETag(true);
}

@Override
protected boolean isEligibleForEtag(HttpServletRequest request, HttpServletResponse response,
int responseStatusCode, InputStream inputStream) {

if (super.isEligibleForEtag(request, response, responseStatusCode, inputStream)) {
// 使用 ETag 机制的 URI,若其响应中不存在缓存控制头,则配置默认值
final String cacheControl = response.getHeader(HttpHeaders.CACHE_CONTROL);
if (cacheControl == null) {
response.setHeader(HttpHeaders.CACHE_CONTROL, CACHE_HEAD);
}
return true;
}

return false;
}
}
}
4 changes: 4 additions & 0 deletions src/main/java/plus/maa/backend/filter/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@NonNullApi
package plus.maa.backend.filter;

import org.springframework.lang.NonNullApi;
2 changes: 2 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ server:
tomcat:
#限制post表单最大为30KB
max-http-form-post-size: 30KB
compression:
enabled: true

logging:
file:
Expand Down

0 comments on commit 6743d06

Please sign in to comment.