-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #147 from Lixuhuilll/compression
启用响应体自动压缩,进一步节约服务器带宽
- Loading branch information
Showing
7 changed files
with
114 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
src/main/java/plus/maa/backend/filter/ContentLengthRepairFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
43
src/main/java/plus/maa/backend/filter/MaaEtagHeaderFilter.java
This file was deleted.
Oops, something went wrong.
65 changes: 65 additions & 0 deletions
65
src/main/java/plus/maa/backend/filter/MaaEtagHeaderFilterRegistrationBean.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters