Spring cloud Spring云网关:当请求中有30个以上的头时为HTTP400

Spring cloud Spring云网关:当请求中有30个以上的头时为HTTP400,spring-cloud,spring-cloud-gateway,Spring Cloud,Spring Cloud Gateway,我使用SpringCloudGateway作为API网关,它位于负责预认证(单点登录)的apache层后面。这一层向我的SpringCloudGateway应用程序的传入请求添加了一堆头,当这个数字超过30个头时。我从网关返回HTTP 400响应 我有一个定制的过滤器,它与后端用户服务对话,以执行授权。此筛选器向exchange的请求添加更多标头 HttpHeaders=newhttpheaders(); headers.setContentType(应用程序_JSON); headers.se

我使用SpringCloudGateway作为API网关,它位于负责预认证(单点登录)的apache层后面。这一层向我的SpringCloudGateway应用程序的传入请求添加了一堆头,当这个数字超过30个头时。我从网关返回HTTP 400响应

我有一个定制的过滤器,它与后端用户服务对话,以执行授权。此筛选器向exchange的请求添加更多标头

HttpHeaders=newhttpheaders();
headers.setContentType(应用程序_JSON);
headers.set(主体、用户ID);
HttpEntity responseType=新的HttpEntity(标头);
ResponseEntity response=restemplate.exchange(当前用户端点,HttpMethod.GET,responseType,UserDto.class);
addUserDetailsToHeaders(exchange,response.getBody());
出于某种原因,此筛选器会对头数大于30的任何网关请求造成干扰 当>30个标题时,我从网关获得的响应主体如下所示

<html>
  <head>
    <title>Bad Request</title>
  </head>
  <body>
    <h1><p>Bad Request</p></h1>
    Error parsing headers: &#x27;limit request headers fields&#x27;
  </body>
</html>

我还可以使用SpringCloudGateway示例项目模拟相同的400响应,方法是使用这个旋度(因此实际限制看起来像90)


您正在使用嵌入式Tomcat吗

请查看这篇关于该问题的文章:

要解决此错误,请检查发出的请求是GET还是POST

如果是GET请求,则将其更改为HTTP POST。在大多数情况下,当URL长度超过2000个字符时,错误将得到解决。在这种情况下,最好使用POST或拆分URL

maxHttpHeaderSize:请求和响应HTTP头的最大大小,以字节为单位指定。如果未指定,则此属性设置为4096(4 KB)

你会发现它的

$TOMCAT_HOME/conf/server.xml

在server.xml中,更改HTTP/1.1连接器条目,并将maxHttpHeaderSize设置为“65536”(64Kb字节),如下所示:

连接器端口=“8080”maxHttpHeaderSize=“65536”协议=“HTTP/1.1”

如果使用嵌入式Tomcat,请尝试将其配置为增加最大标头大小:


如果不使用嵌入式Tomcat,我在Pivotal的同一主题上也发现了这一点:

问题是cloudfoundry的cf路由器拒绝了请求。网关没有问题。让人困惑的是,cf路由器在返回400时并没有添加任何响应头


我有一个自定义过滤器,添加了一个特定的标题,其中包含一个逗号分隔的列表,该列表相当长(200到300个字符)。我缩短了这个的长度,然后它就工作了。

我插入了curl命令,它对我来说很好。你用的是什么版本?你确定错误来自网关而不是下游应用程序吗?斯宾塞,是的,我100%确定它来自网关。我甚至还编写了一个特殊的下游python应用程序来记录所有请求,它从未被命中。不过我有一些自定义过滤器。还连接了一个Eureka discovery客户端。我用的是格林威治.SR2。有趣的是,请求确实通过了我的3个过滤器,我无法复制它。你能提供一个样本项目吗?斯宾塞,谢谢。原来是我的一个自定义过滤器。我的自定义筛选器正在与另一个服务通信以获取用户详细信息(授权),出于某种原因,这会干扰通过筛选器链的请求。在我的自定义过滤器中,我使用Spring的restTemplate.exchange(..)。我想如果我现在用更多的细节更新这个问题会更好。。。很难把所有细节都放在这里我更新了问题。我可以通过点击SpringCloud示例应用程序来复制它,标题>90。我知道这是不现实的,但我对PCF实例前面的层控制有限,该层正在添加头的负载。不,网关需要Netty检查Netty,然后,它似乎也是一个配置设置:看起来Netty默认值是8k
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
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'