Nginx文档。
Syntax: large_client_header_buffers number size;
Default: large_client_header_buffers 4 8k;
Context: http, server
Sets the maximum number and size of buffers used for reading large client request header.
我了解缓冲区的大小,但是我不了解缓冲区的数目。
处理过程如何根据缓冲区数量而改变?
答案 0 :(得分:0)
所以我整夜都在与一些HTTP标头长度作斗争,不得不弄清楚这一点。
TL; DR缓冲区的大小是您的缓冲区有多大,缓冲区号是您有多少。因此,您的总容量为num_buffs * buff_size + 1kb常规标头缓冲区=总容量,但要注意的是,只有在缓冲区中有足够的空间时,标头才会进入缓冲区,换句话说,标头不会在缓冲区中拆分
对于源代码,我一直在通过使用大小不一的标头发出大量卷曲请求来弄清楚过去几个小时的缓冲工作原理。
详细说明。在Nginx中,存在使用client_header_buffer_size
伪指令配置的默认头缓冲区。默认情况下,当请求进入时,首先将标头读入此缓冲区,只要请求标头的总大小不超过为large_client_header_buffers
配置的值,就不会使用client_header_buffer_size
1kb。
但是,一旦我们突破该限制,事情就会变得有趣起来。当Nginx将标头读入缓冲区时,它将继续将标头读入client_header_buffer
,直到标头到达大于缓冲区中剩余的空间为止,此时large_client_header_buffers
变为活动状态,整个标头将被读取到第一个large_client_buffer
中。然后,Nginx将继续将标头读取到client_header_buffer
中,直到遇到另一个无法容纳client_header_buffer
剩余空间的标头为止,此时它将检查是否可以将请求标头放入第一个{ {1}}。如果不能,则将检查是否可以将标头放置在第二个large_client_buffer
中,直到满足以下两个条件之一,此过程才会在每个缓冲区上进行:
或
当条件编号2发生时,Nginx将以错误表示响应,表明请求太大。
让我们通过一些例子来具体说明。
在我们的示例中,我们假设已将large_client_buffer
(称为CHB)配置为10kb的大小,并已配置了两个client_header_buffer
,其大小分别为20kb,称为LCHB1和LCHB2。
方案1香草:
卷曲https://example.com -H'h1:3kb长'-H'h2:2kb长'
h2 | |
h1 | |
CHB | LCHB1 | LCHB2
在这种情况下,我们的标头总共只有5kb,因此很容易装入主缓冲区,并且只要它们各自大小都不能超过5kb,我们就可以在主缓冲区中支持多个标头。
方案2:标头大于CHB缓冲区:
卷曲https://example.com -H'h1:14kb长'
空| h1 |
CHB | LCHB1 | LCHB2
在这种情况下,标头直接读取到大缓冲区中,因为在主缓冲区中没有足够的空间,因为单个标头超出了为主缓冲区配置的大小。
方案3使用的所有缓冲区:
卷曲https://example.com -H'h1:19kb',-H'h2:19kb'-H'h3:9kb'
h3 | h1 | h2
CHB | LCHB1 | LCHB2
在这种情况下,我们收到了一个标头,它不能进入主缓冲区,而几乎不能放入一个大缓冲区中,因此第一个标头就到达了那里。然后,下一个标头进入,也不能进入主缓冲区,但是在第二个大缓冲区中有一个插槽供其使用。然后,最终标头可以容纳在主缓冲区的范围内
方案3标头太多:
卷曲https://example.com -H'h1:19kb',-H'h2:19kb'-H'h3:9kb'-H'h4:2kb'
h4 | h3 | h1 | h2
错误| CHB | LCHB1 | LCHB2
在这种情况下,场景开始播放,类似于场景3;但是,当我们引入额外的2kb标头时,我们遇到了一个问题。因此,在每个大缓冲区中使用19kb的20kb缓冲区,在主缓冲区中剩余1kb的缓冲区时,我们还有3kb的缓冲区空间,因此我们应该能够处理最后的2kb报头吗?错,我的朋友。问题在于,当2kb标头到达时,Nginx在主缓冲区中查找并发现那里只有1kb的空间,因此标头无法到达那里,然后它检查第一个大缓冲区,但仍然只有1kb的空间,因此它不能去那里,最后它检查最后的大缓冲区,只是发现它仍然只有1kb的空间。此时Nginx返回一个错误,表明它收到了一个错误的请求,因为它没有地方读取标头。
因此,总而言之,缓冲区大小是您拥有的缓冲区的大小,但是缓冲区的数量是该数量的乘数,即要保留请求标头需要多少个不同的缓冲区。