Java代码
public class StatusExposingServletResponse extends HttpServletResponseWrapper {
private int httpStatus
public StatusExposingServletResponse(HttpServletResponse response) {
super(response)
}
@Override
public void sendError(int sc) throws IOException {
httpStatus = sc
super.sendError(sc)
}
@Override
public void sendError(int sc, String msg) throws IOException {
httpStatus = sc
super.sendError(sc, msg)
}
@Override
public void setStatus(int sc) {
httpStatus = sc
super.setStatus(sc)
}
public int getStatus() {
return httpStatus
}
}
2.然后实现一个Filter来替换原始的HttpServletResponse,这样你就可以在Filter里面取到statusCode了
Java代码
public class StatusReportingFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
StatusExposingServletResponse response = new StatusExposingServletResponse((HttpServletResponse)res)
chain.doFilter(req, response)
int status = response.getStatus()
// report
}
public void init(FilterConfig config) throws ServletException {
//empty
}
public void destroy() {
// empty
}
}
这是最近碰到的一个坑。
直接现象是client端发起HTTP请求之后,得到empty的返回,以curl工具为例,得到如下错误:
去查node server端的日志:没有,什么也没有,好像没有收到请求。
使用杀手锏tcpdump:
可以看到奇怪的现象:
那么可以确认两点:
Server端收到请求后,并没有向上传送给业务层,导致在server端看不到任何日志,就像没有收到一样;然后Server端直接丢弃了请求,关闭了TCP层的连接。
正巧的是把完整的request都打出来了,感觉HTTP Headers有点长,都是些什么垃圾消息;网上一阵google找到如下:
Denial of Service with large HTTP headers (CVE-2018-12121)
https://nodejs.org/en/blog/vulnerability/november-2018-security-releases/#denial-of-service-with-large-http-headers-cve-2018-12121
经过验证,删除不必要的Headers,一切恢复OK。
是Headers的大小不能超过8K字节。而且我们使用的node版本还不支持--max-http-header-size去修改大小。
涉及业务逻辑的输入是需要通过参数传递的,主要有三种方法:path, query, POST/PUT bodypath: GET /api/user/123 其中的123通过path传递
query: GET /api/search_user?userId=123
body: POST /api/user-signup {username: 'john'}
不建议通过header传参的原因:
1. proxy 和 reverse proxy会drop header
2. 不利于传输object
3. HTTP access control (CORS) API 一般会设置Access-Control-Allow-Headers,分分钟教你做人。
4. 不利于dev和debug
5. Header长度限制
然后,如果你需要传header,比如Authorization,