HTTP分為URI,HEADER村缸,Body三個部分祠肥。每個部分都可以包含請求信息,那么每個部分是否都有請求大小限制呢梯皿?剛開始以為這個問題很容易找到答案仇箱,后來發(fā)現(xiàn)這也是個挺復雜的問題。
URI
首先是URI东羹,我們知道剂桥,在GET請求中,請求參數(shù)是放在URL進行傳遞的属提,所以权逗,HTTP GET的請求最關心的一個問題:能有多長?我能放多少參數(shù)冤议?URI
從HTTP 1.1協(xié)議中開始找:(RFC 2616)
The HTTP protocol does not place any a priori limit on the length of a URI
所以明確一點的是HTTP協(xié)議是沒有顯式限制URI的長度的斟薇。理論上來說你在URI中傳遞多少參數(shù)都是可以的。
但是現(xiàn)實往往無法永遠照進陽光:
1 瀏覽器限制
所有主流瀏覽器都會對URI的長度進行限制恕酸。如果你在瀏覽器中輸入過長的URI堪滨,那么瀏覽器會自動進行截斷。各個瀏覽器對URI長度的限制各不相同蕊温,甚至不同版本也不一樣袱箱。大約一個概念,2000字符以內的URI都能符合所有主流瀏覽器的要求寿弱。
2 服務端限制
即使客戶端同意發(fā)送無限長度的URI犯眠,但是服務器一方一般都是有長度限制的。一般服務是沒有專門針對URI的參數(shù)限制的症革,但是由于URI是會包含在request header中的,所以對header的大小限制是會對URI起作用的鸯旁,比如nginx的(large_client_header_buffers)這個屬性噪矛,它默認是4k。
題外話
這里的“URI是包含在request header中的” 這句話其實是有問題的。URI在HTTP協(xié)議中是叫做request-Line的朝刊,如果具體看協(xié)議负懦,是會發(fā)現(xiàn)request-Line和request-header是兩個不一樣的,就是說request的請求其實該分為request-line, request-header, request-body三個部分的(具體可以看http://www.ietf.org/rfc/rfc2616.txt 第4和5章)缩滨。但是好像使用的時候都默認將header中理解為包含了request-line(比如這篇文章http://trafficserver.apache.org/docs/v2/sdk/HTTPHeaders.html)势就。這里估計是概念和使用的時候導致問題,不必深究了脉漏,所以我們不妨將request-line理解為包含在header中就好苞冯。
不管如何,綜上所述侧巨,這里的URI不論是客戶端還是服務端舅锄,基本是被默認限制住的。
Header
header中存放的信息非常多司忱,比如request-line皇忿,cookie,還有各種key-value的特定header字段和值坦仍。有點時候鳍烁,我們也會往header中添加一些自定義的屬性。header的長度和URI的情況是一樣的繁扎。協(xié)議中并沒有顯示限制header的大小幔荒。理論上在header中放多少屬性都是可以的。
但是實際上:
1 瀏覽器限制
各個主流瀏覽器限制幾十k~幾百M不等的限制锻离∑糖停基本上能滿足平時的需求了。但是如果這個長度對你業(yè)務有很大影響的話汽纠,建議還是親自測試下卫键。
2 服務端限制
比如nginx的large_client_header_buffers就限制了header的長度。你也可以自己設置虱朵。
可能會影響header的參數(shù)還有:
client_header_buffer_size
client_header_timeout
各參數(shù)可以參考:http://wiki.nginx.org/HttpCoreModule
Body
body和URI莉炉,header非常不一樣,不一樣的地方原因在于文件上傳碴犬。HTTP是支持request中帶文件的絮宁,那么文件的二進制數(shù)據(jù)不會放在URI或者header里面,它是放在body里面的服协。那么這個body的大小就一定不能默認限制太小绍昂,尤其是客戶端。
首先理論上,協(xié)議是沒有對body大小做任何限制的窘游。
其次唠椭,瀏覽器也沒有對body做任何大小限制,因為如果瀏覽器做了大小限制就意味著它直接影響了你的服務功能忍饰。
所以對body的限制的任務就放在了服務器上了贪嫂。這里就我最熟悉的nginx+php-fpm來看下有哪些地方可以對body進行限制:
1 nginx有一些設置會對body大小產生影響
client_max_body_size,這個參數(shù)可以限制body的大小艾蓝,默認是1m
client_body_timeout力崇,當body太大,或者網(wǎng)絡太差的時候赢织,這個也有可能會影響請求的成功率的亮靴。
2 php.ini也有一些設置會對上傳的body數(shù)據(jù)產生影響
upload_max_filesize,限制最大上傳文件大小
post_max_size 敌厘,限制post的大小
memory_limit台猴,限制內存使用大小
max_execution_time,這個是php最大執(zhí)行時間俱两,也有可能影響請求成功率的饱狂。
HTTP請求大小有什么影響
首先是安全因素考慮。
試想一下一個網(wǎng)站的服務器是不限制body大小的宪彩,那么它就是可以被黑客利用攻擊的地方了休讳。黑客利用這一點往HTTP POST的body中傳遞非常大(比如幾M)的請求。那么比如像nginx+php-fpm這樣的尿孔,就會占用了服務器一個php進程專門處理這個請求俊柔,就會導致你對外無法提供其他的服務了,你的服務就癱瘓了活合,這就是DDOS攻擊雏婶。
其次是文件上傳服務考慮。
文件上傳有兩種情況:
你可能經(jīng)常遇到為什么文件上傳失敯字浮留晚?那么大多是上文說的幾個設置沒有設置對。
其次告嘲,文件上傳大小是不是設置越大越好错维?答案必須是否定的,理由也是安全考慮橄唬。滿足需求的大小限制就夠了赋焕。
這里就可以理解為什么大都把文件上傳和業(yè)務接口分開來提供了吧。如果你的文件上傳服務和業(yè)務接口是同一個機器的話仰楚,那么就說明你的業(yè)務接口可以允許的body大小一定是很大的隆判。換句話說犬庇,在這種情境下,你的業(yè)務中的所有POST請求都是不安全的C郯薄械筛!只要進行DDOS攻擊捎泻,業(yè)務就會癱瘓飒炎。