five111 opened a new issue #2620:
URL: https://github.com/apache/servicecomb-java-chassis/issues/2620
### go服务报错日志如下
{"level":"ERROR","timestamp":"2021-10-20 15:07:42.805
+08:00","file":"http/sidecar.go:184","msg":"handle request failed: Get
\"http://10.136.97.42:13096/consumer/newDownloadAdc\": net/http: HTTP/1.x
transport connection broken: too many transfer encodings: [\"chunked\"
\"chunked\"]"}
问题很清晰 response的header中有多个 chunked导致 客户端的服务依赖的go版本从1.14 升级到1.16
go在1.15及之后的版本 出于安全考虑 对请求头做了强校验, transfer encodings 只允许有一个值,细节如下
```
func (t *transferReader) parseTransferEncoding() error {
raw, present := t.Header["Transfer-Encoding"]
if !present {
return nil
}
delete(t.Header, "Transfer-Encoding")
// Issue 12785; ignore Transfer-Encoding on HTTP/1.0 requests.
if !t.protoAtLeast(1, 1) {
return nil
}
// Like nginx, we only support a single Transfer-Encoding header field,
and
// only if set to "chunked". This is one of the most security sensitive
// surfaces in HTTP/1.1 due to the risk of request smuggling, so we
keep it
// strict and simple.
if len(raw) != 1 {
return &unsupportedTEError{fmt.Sprintf("too many transfer
encodings: %q", raw)}
}
if strings.ToLower(textproto.TrimString(raw[0])) != "chunked" {
return &unsupportedTEError{fmt.Sprintf("unsupported transfer
encoding: %q", raw[0])}
}
// RFC 7230 3.3.2 says "A sender MUST NOT send a Content-Length header
field
// in any message that contains a Transfer-Encoding header field."
//
// but also: "If a message is received with both a Transfer-Encoding
and a
// Content-Length header field, the Transfer-Encoding overrides the
// Content-Length. Such a message might indicate an attempt to perform
// request smuggling (Section 9.5) or response splitting (Section 9.4)
and
// ought to be handled as an error. A sender MUST remove the received
// Content-Length field prior to forwarding such a message downstream."
//
// Reportedly, these appear in the wild.
delete(t.Header, "Content-Length")
t.Chunked = true
return nil
}
```
### 服务端代码如下,按照文档推荐的方式写的
```
@ApiResponse(code = 200, response = File.class, message = "Download file
success")
@GetMapping(path = "/downloadAdc", produces =
MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<InputStream> downloadAdc() throws IOException {
String filename = "DTS.xlsx";
File file = new File("D:\\code\\CSE\\demo-consumer2\\DTS.xlsx");
InputStream inputStream = FileUtils.openInputStream(file);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_OCTET_STREAM_VALUE)
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment;filename=" + filename)
.body(inputStream);
}
```
### 求问这个请求头是如何变多的,如何避免这个问题
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]