nginx配置参数解释:client_header_buffer_size、large_client_header_buffers

环境

nginx/1.17.2


client_header_buffer_size

Syntax: client_header_buffer_size size;
Default: client_header_buffer_size 1k;
Context: http, server

假设client_header_buffer_size的配置为1k,如果(请求行+请求头)的大小如果没超过1k,放行请求。如果(请求行+请求头)的大小如果超过1k,则以large_client_header_buffers配置为准

large_client_header_buffers

Syntax: large_client_header_buffers number size;
Default: large_client_header_buffers 4 8k;
Context: http, server

假设large_client_header_buffers的配置为4 8k,则对请求有如下要求

  1. 请求行(request line)的大小不能超过8k,否则返回414错误
  2. 请求头(request header)中的每一个头部字段的大小不能超过8k,否则返回400错误(实际是494错误,但nginx统一返回400了)
    curl -H "header1=aaa" -H "header2=bbb" -v http://127.0.0.1/,这里的header1=xxx和header2=xxx就是请求头中的头部字段
  3. (请求行+请求头)的大小不能超过32k(4 * 8k)

实验

  1. 修改nginx配置
    vi nginx.conf
    http {
    	# 声明日志格式,request_length用来输出每一个请求的大小(请求行+请求头+请求体)
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" $request_length '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
        # 指定访问日志的格式和存放路径
        access_log  /usr/local/var/log/nginx/access.log  main;
    
    	# 请求行+请求头的标准大小为1k
        client_header_buffer_size 1k;
        # 请求行+请求头的最大大小为2k
    	large_client_header_buffers 2 1k;
    }
    
  2. 使用curl模拟http请求
    • 414错误
      bash执行

      foo=''; for i in {1..1008}; do foo=${foo}"a"; done
      curl -v http://127.0.0.1:18080\?$foo
      

      curl请求明细

      > GET /?1008个a HTTP/1.1
      > Host: 127.0.0.1:18080
      > User-Agent: curl/7.64.1
      > Accept: */*
      >
      < HTTP/1.1 414 Request-URI Too Large
      < Server: nginx/1.17.2
      < Date: Sat, 02 May 2020 01:45:57 GMT
      < Content-Type: text/html
      < Content-Length: 177
      < Connection: close
      <
      
      414 Request-URI Too Large
      
      

      414 Request-URI Too Large


      nginx/1.17.2

      nginx日志
      这里显示的是0,但请求行的大小已超过1k了

      127.0.0.1 - - [02/May/2020:09:45:57 +0800] "GET /?1008个a HTTP/1.1\x0D" 0 414 177 "-" "-" "-"
      
    • 494错误
      bash执行

      foo='';bar=''; for i in {1..1012}; do foo=${foo}"a"; bar=${bar}"a"; done
      curl -H "header1: $foo" -H "header2: $bar" -v http://127.0.0.1:18080
      

      curl请求明细

      > GET / HTTP/1.1
      > Host: 127.0.0.1:18080
      > User-Agent: curl/7.64.1
      > Accept: */*
      > header1: 1012个a
      > header2: 1012个a
      >
      < HTTP/1.1 400 Bad Request
      < Server: nginx/1.17.2
      < Date: Sat, 02 May 2020 01:48:45 GMT
      < Content-Type: text/html
      < Content-Length: 233
      < Connection: close
      <
      
      400 Request Header Or Cookie Too Large
      
      

      400 Bad Request

      Request Header Or Cookie Too Large

      nginx/1.17.2

      nginx日志

      127.0.0.1 - - [02/May/2020:09:48:45 +0800] "GET / HTTP/1.1" 2123 400 233 "-" "curl/7.64.1" "-"
      

源码及流程图

git tag: release-1.17.2

核心代码文件所在路径: src/http/ngx_http_request.c
nginx配置参数解释:client_header_buffer_size、large_client_header_buffers_第1张图片

[nginx处理请求行和请求头流程]

参考资料

  • Nginx官方文档 http://nginx.org/en/docs/http/ngx_http_log_module.html http://nginx.org/en/docs/http/ngx_http_core_module.html
  • Nginx的client_header_buffer_size和large_client_header_buffers学习 https://www.jianshu.com/p/20a687873bf0
  • Nginx 源码学习(一) nginx的跟踪与调试 https://blog.csdn.net/daniel_ustc/article/details/10282103
  • gdb基本命令(非常详细) https://blog.csdn.net/q1449516487/article/details/95331292

你可能感兴趣的:(nginx)