小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

【Nginx09】Nginx學(xué)習(xí):HTTP核心模塊(六)請求頭處理

 硬核項目經(jīng)理 2023-07-17 發(fā)布于湖南

Nginx學(xué)習(xí):HTTP核心模塊(六)請求頭處理

對于一個 HTTP 應(yīng)用來說,最重要的其實(shí)就是 HTTP 的兩個核心功能,一個是請求,一個就是響應(yīng)。而對于一個 Web 應(yīng)用服務(wù)器來說,響應(yīng)通常是靜態(tài)文件或者是動態(tài)程序代碼來完成,圍繞響應(yīng)的配置指令大部分以緩存優(yōu)化為主。從這里也能看出,在 Nginx 這種應(yīng)用服務(wù)中,請求相關(guān)的內(nèi)容會更多一些,因?yàn)槲覀円鎸Φ?,要對接的,就是從外部不斷發(fā)過來的請求。

今天,我們先了解一下請求頭相關(guān)的配置指令。

請求頭

通用的 HTTP 請求頭相關(guān)的配置主要也是大小、超時時間等等。它們都可以配置在 http、server 下面,我們一個一個來看下。

client_header_buffer_size

用于設(shè)置讀取客戶端請求頭部的緩沖容量。

client_header_buffer_size size;

默認(rèn)值是 1k ,對于大多數(shù)請求,1K的緩沖足矣。但如果請求中含有的cookie很長,或者請求來自WAP的客戶端,可能請求頭不能放在1K的緩沖中。 如果從請求行,或者某個請求頭開始不能完整的放在這塊空間中,那么 Nginx 將按照 large_client_header_buffers 指令的配置分配更多更大的緩沖來存放。

注意哦,這里和請求體不同的是,請求體會往文件里放,但請求頭不會,不夠了再根據(jù)其它配置申請更大的內(nèi)存。畢竟請求頭的內(nèi)容再大也大不到像需要上傳文件的請求體一樣。最終它的配置其實(shí)不會導(dǎo)致什么影響,因?yàn)樽罱K如果不夠了它會根據(jù) large_client_header_buffers 的配置進(jìn)行申請分配,因此,我們緊接著就看看 large_client_header_buffers 的配置。

large_client_header_buffers

這個配置是設(shè)置讀取客戶端請求超大請求的緩沖最大 number(數(shù)量) 和每塊緩沖的 size(容量) 。

large_client_header_buffers number size;

它的默認(rèn)值是 4 8k 。條件包括這么幾點(diǎn):

  • HTTP 請求行的長度不能超過一塊緩沖的容量,否則nginx返回錯誤414 (Request-URI Too Large)到客戶端。
  • 每個請求頭的長度也不能超過一塊緩沖的容量,否則nginx返回錯誤400 (Bad Request)到客戶端。
  • (請求行+請求頭) 的大小不能超過 32k(4 * 8k) 。

即使 Nginx 處理完請求后與客戶端保持長連接,Nginx 也會釋放這些緩沖。如果在服務(wù)器級別指定該指令,則可以使用默認(rèn)服務(wù)器的值。好了,咱們來測試一下。首先配置一下 Nginx 。

// nginx.conf
……
server {
 client_header_buffer_size 256;
 large_client_header_buffers 1 512;
 ……
}
……

注意,large_client_header_buffers 第二個參數(shù)必須要大于等于 connection_pool_size 這個配置項的大小,我這里默認(rèn)是 512 ,所以這里只能配置為 512 ;第一個參數(shù)也不能設(shè)置為 0 ,必須是大于 0 的數(shù)字。

接下來進(jìn)行測試,現(xiàn)在這個情況,其實(shí)只要頭部有一個大字符的參數(shù),或者請求行(就是 URL 行)比較長,就會出 400 的錯誤。

GET http://192.168.56.88/?bigparams=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnop

User-Agent: PostmanRuntime/7.29.2
Accept: */*
Postman-Token: 328e2a7a-84e9-4622-9c83-2bdeb67ea94a
Host: 192.168.56.88
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

上面的請求數(shù)據(jù)試一下,正好 513 個字符,直接報 400 Request Header Or Cookie Too Large 錯誤?;蛘咧苯右粋€大的請求頭。下面這樣的請求也會報錯。

GET http://192.168.56.88/

LongHeader: abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabc
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Postman-Token: 200ad116-daca-4129-81a3-c17039021865
Host: 192.168.56.88
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

上面的兩個請求其實(shí)對應(yīng)的是第三個條件,也就是請求行和請求頭的和超過了 number * size 的大小,現(xiàn)在我們設(shè)置的就是 1 * 512 ,因此現(xiàn)在最大的大小就是 512 字節(jié)。接下來我們修改一下,將 number 改為 2 ,上面的請求都可以正常訪問了,接下來我們測另外兩種情況。

large_client_header_buffers 2 512;

先測試第二個條件,請求頭中的一個請求項超過一塊緩沖的容量,也就是有一個請求頭項的大小超過 512 字節(jié)就可以了。

GET http://192.168.56.88/
....
LongHeader: abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcde
....

正好 512 個字節(jié),直接報 400 Request Header Or Cookie Too Large 錯誤。

最后,我們再測試請求行,如果超長了,會不會返回 414 錯誤。

GET http://192.168.56.88/?bigparams=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr

使用這個請求,正好卡在報錯的長度節(jié)點(diǎn)上,會返回 414 Request-URI Too Large 錯誤。

現(xiàn)在你應(yīng)該了解了吧,如果我們在日常的應(yīng)用中出現(xiàn)了 400 或者 414 的報錯信息,可以來檢查一下這兩個的配置是否有問題。

client_header_timeout

定義讀取客戶端請求頭部的超時時間。

client_header_timeout time;

默認(rèn)值是 60s 如果客戶端在這段時間內(nèi)沒有傳送完整的頭部到 Nginx ,Nginx 將返回錯誤 408 (Request Time-out) 到客戶端。和 client_body_timeout 一樣,不知道咋測,但這里給出了一個 408 的錯誤碼,如果發(fā)現(xiàn)了這個碼的錯誤信息,可以過來嘗試調(diào)大 client_header_timeout 和 client_body_timeout 數(shù)值,或者查查接收不到頭部信息的原因。

max_ranges

如果請求中含有字節(jié)范圍的請求頭,這條指令可以限制此范圍允許的最大值。

max_ranges number;

如果請求頭的值超過此限制,將按請求未攜帶此請求頭的情況處理。 默認(rèn)nginx對此不做限制。設(shè)置為 0 將使 Nginx 完全不支持 HTTP 字節(jié)范圍特性。

啥意思呢?其實(shí)我也沒看明白,那么咱們就來做實(shí)驗(yàn)。先構(gòu)造請求頭,也就是加上 Range 請求頭。

GET http://192.168.56.88/

…………
Range: bytes=0-100,100-200,200-300
…………

直接請求的話,服務(wù)器會返回 206 Partial Content 狀態(tài)碼。這個是 HTTP 的一種分段獲取部分資源的狀態(tài)碼。具體的內(nèi)容不清楚的同學(xué)可以自己查閱一下相關(guān)的資料哦。

目前是默認(rèn)的情況,接下來我們配置一下 max_ranges ,先指定為一個 0 。

// nginx.conf
……
server {
 max_ranges 0;
 ……
}
……

重載配置后我們在客戶端重新請求,會發(fā)現(xiàn)返回的狀態(tài)碼變成了 200 ,也就是說設(shè)置為 0 將使 Nginx 完全不支持 HTTP 字節(jié)范圍特性這一點(diǎn)被我們證實(shí)了。接下來,再將它設(shè)置成 2 。

max_ranges 2;

再次請求后會發(fā)現(xiàn)返回的狀態(tài)碼還是 200 ,那么我們再將它調(diào)到 3 試一下,可以看到,現(xiàn)在又正常返回 206 了?,F(xiàn)在你知道這個配置項的作用了吧。影響的就是 Range 請求頭中范圍項的數(shù)量,默認(rèn)不限制就是只要有這個頭就返回 206 ,如果設(shè)置為 0 ,就不管有沒有都返回 200 ,如果指定為具體的數(shù)字,就是根據(jù) Range 中的范圍項數(shù)量(0-100表示一項)。

underscores_in_headers

允許或禁止在客戶端請求頭中使用下劃線。

underscores_in_headers on | off;

默認(rèn)是 off ,如果禁止,含有下劃線的請求頭將被標(biāo)志為非法請求頭并接受 ignore_invalid_headers 指令的處理??梢栽谀J(rèn)主機(jī)的 server 配置級別定義此命令。這樣,指令設(shè)置將覆蓋監(jiān)聽同一地址和端口的所有虛擬主機(jī)。我們結(jié)合下面的配置指令一起看。

ignore_invalid_headers

控制是否忽略非法的請求頭字段名。

ignore_invalid_headers on | off;

默認(rèn) on ,合法的名字是由英文字母、數(shù)字和連字符組成,當(dāng)然也可以包含下劃線 (由underscores_in_headers指令控制)。本指令可以在默認(rèn)虛擬主機(jī)的 server 配置層級中定義一次,那么這個值在監(jiān)聽在相同地址和端口的所有虛擬主機(jī)上都生效。

好了,來測試一下,我們需要先把 PHP 環(huán)境配上,或者你是使用其它語言也可以配上其它語言的 Nginx 環(huán)境。然后打印一下請求頭中的信息。

// nginx.conf
……
server {
 location ~ \.php$ {
  root html;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
 }
 ……
}
……

// html/1.php
<?php 
print_r($_SEREVER);

然后,在 Postman 中構(gòu)造一個請求頭,并請求剛剛創(chuàng)建的 php 文件。

GET http://192.168.56.88/1.php

Request Headers
………………
TEST_UNDERLINE: 123
………………

目前我們還沒有修改默認(rèn)的配置,所以現(xiàn)在在響應(yīng)打印的信息中,你應(yīng)該看不到 TEST_UNDERLINE 這條新加的請求頭信息。這就是因?yàn)槟J(rèn)情況下,underscores_in_headers 設(shè)置的是 off ,不啟用下劃線請求頭,會將下劃線請求頭標(biāo)記為非法的請求頭,然后 ignore_invalid_headers 是 on ,自動忽略掉這些非常的請求頭,不會將這些請求頭繼續(xù)向下轉(zhuǎn)發(fā)。

要測試非常簡單。將 underscores_in_headers 設(shè)置為 on ,或者將 ignore_invalid_headers 設(shè)置為 off ,那么就都可以在 PHP 中看到打印出來的信息了。

// http://192.168.56.88/1.php
…………
[HTTP_TEST_UNDERLINE] => 123
…………

總結(jié)

東西其實(shí)不多,都是在圍繞著這六個配置指令在進(jìn)行測試。而且還有一些都不知道咋測,就像之前的文章中說過的,有接觸過的小伙伴記得留言評論哦。

請求的內(nèi)容還有一部分,就是請求體以及請求限流,這兩個我們合在一起下篇文章一起學(xué)習(xí)。

參考文檔:

http:///en/docs/http/ngx_http_core_module.html

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多