Spring-cloud-gateway: 当请求超过 30 headers 时 HTTP400
Spring-cloud-gateway: HTTP400 when more than 30 headers in request
我正在使用 spring-cloud-gateway 作为 API 网关,它位于负责 pre-authentication(单点登录)的 apache 层后面。这一层向我的 spring-cloud-gateway 应用程序的传入请求添加了一堆 headers,当这个数字超过 30 headers 时。我从网关返回了 HTTP 400 响应。
我有一个自定义过滤器,它与 back-end 用户服务对话以执行授权。此过滤器将更多 headers 添加到交易所的请求中。
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_JSON);
headers.set(PRINCIPAL, userId);
HttpEntity<Void> responseType = new HttpEntity<Void>(headers);
ResponseEntity<UserDto> response = restTemplate.exchange(CURRENT_USER_ENDPOINT, HttpMethod.GET, responseType, UserDto.class);
addUserDetailsToHeaders(exchange, response.getBody());
出于某种原因,此过滤器对大于 30 的任何网关请求造成干扰 headers
当 >30 headers 时,我从网关得到的响应 body 如下所示。
<html>
<head>
<title>Bad Request</title>
</head>
<body>
<h1><p>Bad Request</p></h1>
Error parsing headers: 'limit request headers fields'
</body>
</html>
我可以通过使用 curl 在本地 运行 我的网关模拟问题。例如:
curl 'http://localhost:8080/my-api-app/' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' -H 'Sec-Fetch-Mode: navigate' -H 'Sec-Fetch-User: ?1' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' -H 'Sec-Fetch-Site: none' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,ja;q=0.7' -H 'Cookie: 567583457' -H 'uid: 1234567' -H 'employee: N' -H 'x-forwarded-proto: https' -H 'x-forwarded-for: 10.45.67.65, 172.16.8.1' -H 'X-Forwarded-Host: xxxxxxxxxxxxxxx' -H 'X-Forwarded-Server: xxxxxxxxxxxxx' -H 'Ct_request_id: 11' -H 'managername: xxxxxxxx, xxxxx' -H 'Ctscuserkeywords: NotExpired,PasswordPolicy' -H 'Destinationindicator: IE' -H 'a: b' -H 'c: d' -H 'derek: test' --compressed
我还可以使用 spring-cloud-gateway-sample 项目模拟相同的 400 响应,方法是用这个 curl 击中它(因此实际限制看起来像 90)
curl 'http://localhost:8080/get' -H 'key1: val' -H 'key2: val' -H 'key3: val' -H 'key4: val' -H 'key5: val' -H 'key6: val' -H 'key7: val' -H 'key8: val' -H 'key9: val' -H 'key10: val' -H 'key11: val' -H 'key12: val' -H 'key13: val' -H 'key14: val' -H 'key15: val' -H 'key16: val' -H 'key17: val' -H 'key18: val' -H 'key19: val' -H 'key20: val' -H 'key21: val' -H 'key22: val' -H 'key23: val' -H 'key24: val' -H 'key25: val' -H 'key26: val' -H 'key27: val' -H 'key28: val' -H 'key29: val' -H 'key30: val' -H 'key31: val' -H 'key32: val' -H 'key33: val' -H 'key34: val' -H 'key35: val' -H 'key36: val' -H 'key37: val' -H 'key38: val' -H 'key39: val' -H 'key40: val' -H 'key41: val' -H 'key42: val' -H 'key43: val' -H 'key44: val' -H 'key45: val' -H 'key46: val' -H 'key47: val' -H 'key48: val' -H 'key49: val' -H 'key50: val' -H 'key51: val' -H 'key52: val' -H 'key53: val' -H 'key54: val' -H 'key55: val' -H 'key56: val' -H 'key57: val' -H 'key58: val' -H 'key59: val' -H 'key60: val' -H 'key61: val' -H 'key62: val' -H 'key63: val' -H 'key64: val' -H 'key65: val' -H 'key66: val' -H 'key67: val' -H 'key68: val' -H 'key69: val' -H 'key70: val' -H 'key71: val' -H 'key72: val' -H 'key73: val' -H 'key74: val' -H 'key75: val' -H 'key76: val' -H 'key77: val' -H 'key78: val' -H 'key79: val' -H 'key80: val' -H 'key81: val' -H 'key82: val' -H 'key83: val' -H 'key84: val' -H 'key85: val' -H 'key86: val' -H 'key87: val' -H 'key88: val' -H 'key89: val' -H 'key90: val' -H 'key91: val'
您是否使用嵌入式 Tomcat?
查看这篇关于该问题的文章:https://thewebspark.com/2017/12/06/tomcat-request-header-too-large-resolved/
To resolve this error, either check if the request made is GET or POST?
If it is GET request then change it to HTTP POST the error will get resolved in most of the cases as the URL length goes beyond 2000 characters. In this case, it’s better to use POST or split the URL.
maxHttpHeaderSize: The maximum size of the request and response HTTP header, specified in bytes. If not specified, this attribute is set to 4096 (4 KB).
You will find it in
$TOMCAT_HOME/conf/server.xml
In server.xml change the HTTP/1.1 Connector entry and set the maxHttpHeaderSize to “65536” (64Kb in bytes) as shown below:
Connector port="8080" maxHttpHeaderSize="65536" protocol="HTTP/1.1" ...
如果使用嵌入式 Tomcat,请尝试将其配置为增加最大 header 大小:
https://www.baeldung.com/spring-boot-configure-tomcat
如果不使用嵌入式 Tomcat,我还在 Pivotal 的同一主题上找到了这个:https://community.pivotal.io/s/article/spring-boot-app-rejects-http-request-with-total-header-size-larger-than-8kb
问题原来是cloudfoundry的cf router拒绝了请求。网关没有问题。令人困惑的是 cf 路由器在 returns 400 时不添加任何响应 header。
我有一个自定义过滤器,添加了一个特定的 header,其中包含一个逗号分隔的列表,该列表很长(200 到 300 个字符)。我减少了它的长度然后它起作用了。
我正在使用 spring-cloud-gateway 作为 API 网关,它位于负责 pre-authentication(单点登录)的 apache 层后面。这一层向我的 spring-cloud-gateway 应用程序的传入请求添加了一堆 headers,当这个数字超过 30 headers 时。我从网关返回了 HTTP 400 响应。
我有一个自定义过滤器,它与 back-end 用户服务对话以执行授权。此过滤器将更多 headers 添加到交易所的请求中。
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_JSON);
headers.set(PRINCIPAL, userId);
HttpEntity<Void> responseType = new HttpEntity<Void>(headers);
ResponseEntity<UserDto> response = restTemplate.exchange(CURRENT_USER_ENDPOINT, HttpMethod.GET, responseType, UserDto.class);
addUserDetailsToHeaders(exchange, response.getBody());
出于某种原因,此过滤器对大于 30 的任何网关请求造成干扰 headers 当 >30 headers 时,我从网关得到的响应 body 如下所示。
<html>
<head>
<title>Bad Request</title>
</head>
<body>
<h1><p>Bad Request</p></h1>
Error parsing headers: 'limit request headers fields'
</body>
</html>
我可以通过使用 curl 在本地 运行 我的网关模拟问题。例如:
curl 'http://localhost:8080/my-api-app/' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' -H 'Sec-Fetch-Mode: navigate' -H 'Sec-Fetch-User: ?1' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' -H 'Sec-Fetch-Site: none' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,ja;q=0.7' -H 'Cookie: 567583457' -H 'uid: 1234567' -H 'employee: N' -H 'x-forwarded-proto: https' -H 'x-forwarded-for: 10.45.67.65, 172.16.8.1' -H 'X-Forwarded-Host: xxxxxxxxxxxxxxx' -H 'X-Forwarded-Server: xxxxxxxxxxxxx' -H 'Ct_request_id: 11' -H 'managername: xxxxxxxx, xxxxx' -H 'Ctscuserkeywords: NotExpired,PasswordPolicy' -H 'Destinationindicator: IE' -H 'a: b' -H 'c: d' -H 'derek: test' --compressed
我还可以使用 spring-cloud-gateway-sample 项目模拟相同的 400 响应,方法是用这个 curl 击中它(因此实际限制看起来像 90)
curl 'http://localhost:8080/get' -H 'key1: val' -H 'key2: val' -H 'key3: val' -H 'key4: val' -H 'key5: val' -H 'key6: val' -H 'key7: val' -H 'key8: val' -H 'key9: val' -H 'key10: val' -H 'key11: val' -H 'key12: val' -H 'key13: val' -H 'key14: val' -H 'key15: val' -H 'key16: val' -H 'key17: val' -H 'key18: val' -H 'key19: val' -H 'key20: val' -H 'key21: val' -H 'key22: val' -H 'key23: val' -H 'key24: val' -H 'key25: val' -H 'key26: val' -H 'key27: val' -H 'key28: val' -H 'key29: val' -H 'key30: val' -H 'key31: val' -H 'key32: val' -H 'key33: val' -H 'key34: val' -H 'key35: val' -H 'key36: val' -H 'key37: val' -H 'key38: val' -H 'key39: val' -H 'key40: val' -H 'key41: val' -H 'key42: val' -H 'key43: val' -H 'key44: val' -H 'key45: val' -H 'key46: val' -H 'key47: val' -H 'key48: val' -H 'key49: val' -H 'key50: val' -H 'key51: val' -H 'key52: val' -H 'key53: val' -H 'key54: val' -H 'key55: val' -H 'key56: val' -H 'key57: val' -H 'key58: val' -H 'key59: val' -H 'key60: val' -H 'key61: val' -H 'key62: val' -H 'key63: val' -H 'key64: val' -H 'key65: val' -H 'key66: val' -H 'key67: val' -H 'key68: val' -H 'key69: val' -H 'key70: val' -H 'key71: val' -H 'key72: val' -H 'key73: val' -H 'key74: val' -H 'key75: val' -H 'key76: val' -H 'key77: val' -H 'key78: val' -H 'key79: val' -H 'key80: val' -H 'key81: val' -H 'key82: val' -H 'key83: val' -H 'key84: val' -H 'key85: val' -H 'key86: val' -H 'key87: val' -H 'key88: val' -H 'key89: val' -H 'key90: val' -H 'key91: val'
您是否使用嵌入式 Tomcat?
查看这篇关于该问题的文章:https://thewebspark.com/2017/12/06/tomcat-request-header-too-large-resolved/
To resolve this error, either check if the request made is GET or POST?
If it is GET request then change it to HTTP POST the error will get resolved in most of the cases as the URL length goes beyond 2000 characters. In this case, it’s better to use POST or split the URL.
maxHttpHeaderSize: The maximum size of the request and response HTTP header, specified in bytes. If not specified, this attribute is set to 4096 (4 KB).
You will find it in
$TOMCAT_HOME/conf/server.xml
In server.xml change the HTTP/1.1 Connector entry and set the maxHttpHeaderSize to “65536” (64Kb in bytes) as shown below:
Connector port="8080" maxHttpHeaderSize="65536" protocol="HTTP/1.1" ...
如果使用嵌入式 Tomcat,请尝试将其配置为增加最大 header 大小: https://www.baeldung.com/spring-boot-configure-tomcat
如果不使用嵌入式 Tomcat,我还在 Pivotal 的同一主题上找到了这个:https://community.pivotal.io/s/article/spring-boot-app-rejects-http-request-with-total-header-size-larger-than-8kb
问题原来是cloudfoundry的cf router拒绝了请求。网关没有问题。令人困惑的是 cf 路由器在 returns 400 时不添加任何响应 header。
我有一个自定义过滤器,添加了一个特定的 header,其中包含一个逗号分隔的列表,该列表很长(200 到 300 个字符)。我减少了它的长度然后它起作用了。