NodeJS请求431 Request Header Fields Too Large 错误

nodejs

公司使用verdaccio-gitlab搭建了私有的NPM Registry,并使用Gitlab服务做授权,一直运行稳定。

【国内直连ChatGPT 29元起】
国内直连ChatGPT,Plus会员每月29元起,支持最新o1模型探索更多领域,无需注册OpenAI账号。

直到最近升级了NodeJS版本之后,陆续发现有一些问题:

  • 固定一部分用户在请求packages接口时总是400错误
  • 部分用户不受影响

从问题上分析,大概判断是跟用户数据相关引发的错误,但verdaccio-gitlab这个包只给出了400错误,很不好确定具体错误。于是直接在测试环境启动了一个Verdaccio然后发现其实有问题的那一部分用户状态码其实是431 Request Header Fields Too Large,意思就是请求头太大。

以下是httpstatuses.com的描述

431 REQUEST HEADER FIELDS TOO LARGE
The server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields.

这里我们要先铺垫一下关于HTTP请求,HTTP是目前网络上使用最广泛的协议,尤其是BS架构,当然很多HTTP API接口也很流行使用这种协议对外开放存取数据的接口。它基于TCP协议之上,总共分header和body两部分,下图OSI七层模型很好的表达了这一点

full

431说明header的字段信息超长了,然后研究了一下Verdaccio的源码,发现是它直接使用http.createServer()这个方法监听的http服务,http包是NodeJS自带的包,所以问题应该出在http这个包了。通过查询NodeJS changelog发现有这一段重要信息

2018-12-26-version-10150-dubnium-lts-mylesborins

full

原来从10.14版本开始头大小被限制不能超过8192字节

Headers received by HTTP servers must not exceed 8192 bytes in total to prevent possible Denial of Service attacks. Reported by Trevor Norris. (CVE-2018-12121 / Matteo Collina)

而在10.15版本里提供了修改这一限制的方式,通过cli参数--max-http-header-size来修改默认的头大小限制。

确定了以上两个信息之后,我开始排查看看是不是我的头信息超过了8192字节。重新登录verdaccio-gitlab服务,使用抓包工具测试发现在请求packages接口时其中一个authorization字段就已经达到8992字节了,这还没包括其它字段的值。为什么这个字段会这么大呢?经过研究发现verdaccio-gitlab这个包为了记住用户登录会话而生成的一串超长的token在cookie里,每次请求一些都会被附带到服务器端做校验。

那么问题来了,为什么部分用户可以用,而一部分用户却受影响呢?原来verdaccio-gitlab这个程序在通过Gitlab校验之后叠加了很多信息使用sha256生成的token,这是一个变长token,也就是说用户信息越多,这个token越长,所以有一部分用户生成的token加其它头字段小于8192字节就没有431错误,而其它用户生成的token加其它头字段大于8192就有431错误限制。定位了问题,解决就好办了

  • 看verdaccio-gitlab程序,把token生成限制在7000字节左右,因为其它字段也要占用一些字节
  • 启动verdaccio程序时添加cli参数--max-http-header-size,给一个较大的值

由于verdaccio-gitlab是第三方程序,做了改动怕更新升级麻烦,所以我就选择了--max-http-header-size方式解决这个问题。

node --max-http-header-size 20000 $VERDACCIO_APPDIR/bin/verdaccio --config /verdaccio/conf/config.yaml --listen $VERDACCIO_PROTOCOL://0.0.0.0:$VERDACCIO_PORT

启动服务后431问题消除

分享

TITLE: NodeJS请求431 Request Header Fields Too Large 错误

LINK: https://www.qttc.net/496-nodejs-431-header-too-large.html

NOTE: 原创内容,转载请注明出自琼台博客