lỗi 411 Length Required: Content-Length, chunked và proxy
lỗi 411 Length Required là mã HTTP máy chủ trả khi nhận request có body mà không có header Content-Length, và máy chủ đó không chịu đọc body theo kiểu khác. Lỗi hay xuất hiện khi script gửi dữ liệu dạng luồng, chưa biết trước tổng độ dài, hoặc khi một công cụ gửi POST rỗng mà quên khai độ dài bằng 0. ProxyVN dựng một endpoint lab chỉ nhận Content-Length, gửi cùng một body 300.000 byte theo nhiều cách qua hai kiểu proxy, rồi đối soát sha256 của body ở hai đầu để chỉ ra cách sửa nào giữ nguyên dữ liệu.
Nhận diện lỗi 411 Length Required trong response thật
Nghĩa của mã theo tài liệu
Theo RFC 9110, 411 nghĩa là máy chủ từ chối request không có Content-Length. Client có thể gửi lại nếu thêm header Content-Length hợp lệ chứa độ dài thân request. Trang 411 Length Required trên MDN mô tả gọn cùng nội dung.
Mã này thuộc nhóm 4xx: lỗi nằm ở cách request được đóng khung, không phải ở dữ liệu bên trong. Body có thể đúng từng byte, nhưng máy chủ không chấp nhận cách client báo body kết thúc ở đâu.
Hai cách báo độ dài body trong HTTP/1.1
HTTP/1.1 có hai cách để bên nhận biết body dài bao nhiêu, được mô tả trong RFC 9112:
- Content-Length: client ghi tổng số byte vào header trước khi gửi body. Bên nhận đọc đúng số byte đó.
- Transfer-Encoding: chunked: client chia body thành nhiều khúc, mỗi khúc có độ dài ở đầu, khúc độ dài 0 đánh dấu hết. Client không cần biết tổng trước.
Cách thứ hai hợp với dữ liệu sinh dần như đọc từ ống, nén trên đường hay tạo từ generator. Nhưng không phải máy chủ nào cũng nhận chunked cho request. Máy chủ chỉ hiểu HTTP/1.0, một số framework cũ, một số API gateway và vài dịch vụ lưu trữ đòi Content-Length. Khi nhận chunked, chúng trả 411.
Hai request dưới đây gửi cùng chuỗi hello world, một bằng Content-Length, một bằng chunked. Đây là văn bản thô đi trên dây, mỗi dòng kết thúc bằng CRLF:
POST /length-required HTTP/1.1
Host: api.test
Content-Type: text/plain
Content-Length: 11
hello world
POST /length-required HTTP/1.1
Host: api.test
Content-Type: text/plain
Transfer-Encoding: chunked
b
hello world
0
Ở request thứ hai, chữ b là số 11 viết theo hệ mười sáu, độ dài của khúc đầu. Dòng 0 và dòng trống cuối báo body đã hết. Máy chủ chỉ hiểu Content-Length sẽ đọc header của request thứ hai, không thấy độ dài và trả 411 trước khi đọc tới chữ b.
Nhìn văn bản thô cũng giúp hiểu vì sao không được gửi cả hai header cùng lúc. Nếu hai hop đọc theo hai header khác nhau, chúng thấy ranh giới request ở hai chỗ khác nhau, và phần thừa bị hiểu thành request khác.
Response 411 trông như thế nào
Thân response 411 thường ngắn. Có nơi trả trang HTML mặc định ghi Length Required, có nơi trả JSON với thông báo cần Content-Length. Lab của bài trả JSON có trường need bằng Content-Length và header X-Hop cho biết hop nào sinh ra response.
Khi gặp 411, câu hỏi đầu tiên là request đã gửi đi theo cách đóng khung nào, chứ chưa phải body sai ở đâu.
Xử lý lỗi 411 Length Required khi server cần Content-Length và luồng không biết trước độ dài

Content-Length hay chunked
Những cách gửi sinh ra chunked mà anh em không để ý
Nhiều thư viện tự chọn cách đóng khung theo kiểu dữ liệu được truyền vào. Với requests của Python, lab ghi nhận:
- Truyền bytes: requests đặt Content-Length bằng độ dài. Origin nhận 200.
- Truyền tệp mở chế độ rb: requests đo độ dài tệp và đặt Content-Length. Origin nhận 200.
- Truyền BytesIO: requests đo được độ dài, đặt Content-Length. Origin nhận 200.
- Truyền generator: requests không biết độ dài nên gửi Transfer-Encoding: chunked. Origin trả 411.
- POST không body: requests gửi Content-Length: 0. Origin nhận 200.
Tài liệu requests phần nâng cao có mục chunk-encoded requests xác nhận hành vi với generator. Một thay đổi tưởng vô hại, như đổi từ đọc cả tệp sang đọc từng khúc bằng generator để đỡ tốn RAM, là đủ biến request 200 thành 411.
curl và http.client
Với curl 8.21.0 trong lab, kết quả theo tùy chọn:
- -X POST không kèm dữ liệu: curl gửi POST không có Content-Length, origin trả 411.
- -d với chuỗi rỗng: curl gửi Content-Length: 0, origin trả 200.
- Thêm header Transfer-Encoding: chunked: curl gửi chunked, origin trả 411.
- -T - đọc từ stdin: curl không biết độ dài, gửi PUT chunked kèm Expect: 100-continue, origin trả 411.
Lớp http.client của Python, khi gọi putrequest và endheaders mà không gửi header độ dài, cũng tạo request POST trống không có Content-Length. Origin trả 411. Trường hợp này hay gặp trong code tự viết ở tầng thấp hoặc client SOAP cũ.
Đừng tự bịa độ dài

Không bịa độ dài
Cách sửa nhanh sai là tự ghi một con số vào Content-Length. Nếu số nhỏ hơn body thật, bên nhận cắt body và phần còn lại bị hiểu thành request kế tiếp trên cùng kết nối. Nếu số lớn hơn, bên nhận ngồi chờ byte không bao giờ tới cho tới khi hết giờ. RFC 9112 coi framing sai là một nguồn của lỗi bảo mật kiểu request smuggling, khi hai hop hiểu ranh giới request khác nhau.
Content-Length phải là độ dài thật của chuỗi byte gửi đi, sau mọi bước nén hay mã hóa nội dung. Nếu đo trước khi nén rồi gửi body đã nén, con số sai.
Ba cách có độ dài thật
- Gom body vào bộ nhớ: hợp với body vừa phải. Gom generator thành bytes rồi gửi.
- Ghi ra tệp tạm: hợp với body lớn. Ghi luồng ra đĩa, đo cỡ tệp, mở lại chế độ rb để thư viện tự đặt Content-Length.
- Để proxy gom giúp: một số reverse proxy đọc hết body chunked rồi chuyển cho máy chủ phía sau với Content-Length. Cách này cần quyền cấu hình proxy đó.
Đoạn code dưới minh họa cách thứ hai, dùng tệp tạm và đo sha256 trong lúc ghi để đối soát sau:
import hashlib, tempfile, requests
def send_stream(url, chunks, proxies=None):
h = hashlib.sha256()
with tempfile.TemporaryFile() as tmp:
for c in chunks:
tmp.write(c)
h.update(c)
size = tmp.tell()
tmp.seek(0)
r = requests.post(url, data=tmp, proxies=proxies, timeout=60)
return r, size, h.hexdigest()[:16]
requests đọc được độ dài của tệp tạm nên gửi Content-Length bằng size. Hàm trả về cả độ dài và sha256 để so với giá trị mà máy chủ ghi nhận, nếu máy chủ có trả.
Dựng endpoint lab để tái lập lỗi 411 Length Required
Thành phần
Lab chạy trên Windows 10, Python 3.12.10, requests 2.34.2 và curl 8.21.0 đi kèm Git for Windows. Origin và proxy là một tệp Python viết bằng socket thô để đọc đúng từng byte header và body.
- Origin cổng 9510: đường dẫn /length-required trả 411 nếu request không có Content-Length. Khi nhận được body, origin trả JSON ghi cách đóng khung, số byte và 16 ký tự đầu của sha256 body.
- Proxy chuyển tiếp cổng 9514: nhận body chunked thì gửi tiếp cho origin cũng bằng chunked.
- Proxy gom body cổng 9515: đọc hết body chunked, đếm byte, rồi gửi cho origin với Content-Length.
Hai proxy cùng ghi nhật ký mỗi request: cách đóng khung nhận vào, cách đóng khung gửi đi, số byte và sha256. Body thử là 300.000 byte ngẫu nhiên, sha256 bắt đầu bằng 02881ebfdd59ddfc.
Kết quả theo cách gửi
Cách gửi |
Đường đi |
Mã |
Origin nhận |
|---|---|---|---|
bytes |
thẳng |
200 |
Content-Length 300000 |
generator |
thẳng |
411 |
Transfer-Encoding chunked |
generator |
proxy chuyển tiếp 9514 |
411, có Via |
chunked |
generator |
proxy gom body 9515 |
200, có Via |
Content-Length 300000 |
tệp mở rb |
thẳng |
200 |
Content-Length 300000 |
BytesIO |
thẳng |
200 |
Content-Length 300000 |
POST không body bằng requests |
thẳng |
200 |
Content-Length 0 |
http.client POST trống |
thẳng |
411 |
không header độ dài |
curl -X POST |
thẳng |
411 |
không header độ dài |
curl -d rỗng |
thẳng |
200 |
Content-Length 0 |
curl -T - |
thẳng |
411 |
chunked kèm Expect |
Mọi ca 200 có sha256 ở origin trùng với 02881ebfdd59ddfc, kể cả ca đi qua proxy gom body. Proxy đổi cách đóng khung nhưng không đổi dữ liệu.
Vì sao proxy chuyển tiếp vẫn cho ra 411
Proxy 9514 nhận chunked và gửi tiếp chunked, đúng hành vi của nhiều proxy chuyển tiếp. Origin vẫn thấy request không có Content-Length nên trả 411. Response mang header Via của proxy và X-Hop của origin, cho biết mã do origin sinh ra rồi đi qua proxy.
Đổi sang proxy khác cùng kiểu không thay đổi gì. Chỉ hop chịu gom body hoặc client tự có độ dài mới sửa được.
Đối chiếu header, body và timeline của lỗi 411 Length Required

Proxy gom body
Đọc header request ở mỗi hop
Với 411, header quan trọng nằm ở request, không phải response. Cần biết request rời client với header gì và tới hop cuối với header gì:
- Ở client: bật log debug của thư viện, hoặc dùng curl -v để xem dòng Content-Length hay Transfer-Encoding gửi đi.
- Ở proxy: đọc nhật ký nếu có. Lab ghi kind_in và frame_out cho từng request, ví dụ chunked vào và Content-Length ra ở proxy 9515.
- Ở origin: log truy cập của nhiều máy chủ ghi được header request khi bật mức chi tiết. Lab ghi giá trị cl và te.
Nếu client gửi Content-Length mà origin vẫn nhận chunked, một hop ở giữa đã đổi cách đóng khung, thường do hop đó nén lại body hoặc sửa nội dung.
Đối soát byte body

Đối soát sha256 hai đầu
Đối soát gồm hai số: số byte và sha256. Số byte cho biết body tới nơi có đủ độ dài không. sha256 cho biết nội dung có bị đổi không. Trong lab, proxy 9515 ghi bytes 300000 và sha 02881ebfdd59ddfc, origin ghi cùng hai giá trị. Đó là bằng chứng việc đổi chunked sang Content-Length không làm sai dữ liệu.
Khi làm việc với API thật, thường không có cách đọc sha256 ở phía máy chủ. Thay vào đó, đọc lại tài nguyên vừa tạo, ví dụ tải về tệp đã upload, và tính sha256 ở client. Nhiều dịch vụ lưu trữ trả về giá trị băm hoặc ETag sau khi upload, có thể dùng để so.
Timeline
411 thường trả rất nhanh, ngay sau khi máy chủ đọc xong header. Máy chủ không đọc body nên client có thể còn đang đẩy dữ liệu khi response tới. Với body lớn qua mạng thật, client có thể thấy kết nối bị đóng thay vì đọc được 411. Lab trên localhost không gặp tình huống này vì hệ điều hành đệm đủ body.
Khi request có kèm Expect: 100-continue như ca curl -T -, máy chủ có thể trả 411 thay vì 100, và client không phải đẩy body. Bài lỗi 417 Expectation Failed trong cùng loạt bài mã lỗi nói rõ hơn về header Expect.
Sửa lỗi 411 Length Required đúng điều kiện và chạy đối chứng
Sửa ở client
Hướng sửa phổ biến nhất nằm ở client vì client sinh ra request. Theo từng trường hợp:
- Body đã có trong bộ nhớ: truyền bytes thay vì generator.
- Body đọc từ tệp: truyền đối tượng tệp mở chế độ rb để thư viện tự đo độ dài.
- Body sinh dần, cỡ vừa: gom thành bytes rồi gửi. Kiểm RAM nếu body có thể lớn.
- Body sinh dần, cỡ lớn: ghi ra tệp tạm như đoạn code ở trên.
- POST hay PUT không body: gửi body rỗng tường minh để thư viện đặt Content-Length: 0. Với curl, dùng -d rỗng thay vì chỉ -X POST.
Mỗi hướng phải đi kèm phép thử đối chứng: cùng body, cùng đường đi, so mã và số byte trước và sau.
Sửa ở proxy phía trước máy chủ
Nếu anh em quản lý reverse proxy đứng trước một máy chủ cũ chỉ nhận Content-Length, có thể để proxy gom body. Với nginx, thiết lập proxy_request_buffering bật theo mặc định. Theo tài liệu nginx, khi bật, nginx đọc hết body của client trước khi gửi cho máy chủ phía sau. Bài cấu hình nginx làm reverse proxy có cách dựng khối proxy_pass cơ bản.
Tài liệu nginx còn ghi một chi tiết đáng nhớ: khi client gửi body chunked, nginx vẫn gom body dù đã tắt proxy_request_buffering, trừ khi bật HTTP/1.1 cho kết nối tới máy chủ phía sau bằng proxy_http_version 1.1. Lý do là HTTP/1.0 không có chunked, nên nginx phải biết độ dài trước khi chuyển. Nếu ai đó tắt gom body để giảm độ trễ upload và bật HTTP/1.1 phía sau, request chunked sẽ đi thẳng xuống máy chủ. Máy chủ cũ chỉ nhận Content-Length lúc đó bắt đầu trả 411, dù trước đó vẫn chạy bình thường.
Gom body tốn bộ nhớ hoặc đĩa ở proxy và làm request đến máy chủ phía sau chậm hơn một nhịp. Cần đặt giới hạn kích thước body tương ứng ở proxy để không gom request khổng lồ, nếu không lỗi sẽ đổi từ 411 sang 413. Bài lỗi 413 Content Too Large trong cùng loạt bài giải thích cách tìm hop giới hạn kích thước.
Không sửa bằng proxy dịch vụ
Proxy chuyển tiếp phía client, kể cả proxy dịch vụ thuê ngoài, không có lý do gì để đổi cách đóng khung body. Với URL https qua CONNECT, proxy thậm chí không thấy header của request. Đổi proxy không sửa được 411.
Chạy đối chứng
Sau khi sửa, chạy lại đúng các ca đã lỗi. Bảng mong đợi tối thiểu:
- Ca đã lỗi giờ thành 200, origin ghi Content-Length bằng độ dài thật.
- sha256 hai đầu trùng nhau.
- Ca đã đúng trước đó vẫn đúng, để chắc thay đổi không làm hỏng đường khác.
Lưu bảng này cùng phiên bản thư viện. Hành vi tự chọn chunked hay Content-Length có thể đổi qua các bản của thư viện HTTP.
411 không nói body sai. Nó nói máy chủ không biết body dừng ở đâu theo cách nó chịu đọc. Cách sửa đúng là cung cấp độ dài thật, không phải một con số cho qua.
Gửi lại request sau lỗi 411 Length Required: an toàn hay không
Gửi lại nguyên request
Gửi lại đúng request chunked đó sẽ nhận lại 411. Script không nên đưa 411 vào danh sách thử lại tự động. Cần sửa cách đóng khung trước.
Máy chủ đã xử lý gì chưa
Máy chủ trả 411 sau khi đọc header, trước khi đọc body. Theo nghĩa của mã, request chưa được xử lý. Vì vậy gửi lại sau khi thêm Content-Length thường an toàn cả với POST. Ngoại lệ là khi một hop ở giữa đã nhận và lưu body trước khi chuyển tiếp, như hàng đợi upload. Trường hợp đó hiếm nhưng nên kiểm tài liệu của hệ thống.
Generator không gửi lại được
Một vấn đề thực tế: generator đã chạy một lần thì đã cạn. Nếu code gửi generator, nhận 411 rồi gửi lại cùng generator đó, lần sau sẽ gửi body rỗng. Body rỗng có Content-Length 0 có thể được chấp nhận, tạo ra một bản ghi rỗng ở máy chủ. Lỗi này khó thấy vì lần thứ hai trả 200.
Cách tránh là luôn tạo lại nguồn dữ liệu cho mỗi lần gửi, hoặc dùng tệp tạm có thể tua lại đầu. Đoạn code ở phần trên trả về số byte nên dễ kiểm: nếu size bằng 0 với body lẽ ra có dữ liệu thì dừng.
Khóa idempotency
Với API tạo mới có hỗ trợ khóa idempotency trong header, gắn khóa vào mọi request POST. Khi phải gửi lại vì bất kỳ lý do gì, máy chủ dùng khóa để nhận ra request trùng.
Lỗi 411 Length Required trong các công cụ thường dùng với proxy
Trình duyệt
Trình duyệt luôn biết độ dài khi gửi biểu mẫu hay tệp qua fetch với body đã có, nên ít gặp 411. Fetch với body là ReadableStream gửi theo kiểu luồng và yêu cầu tùy chọn duplex trong các trình duyệt hỗ trợ. Máy chủ chỉ nhận Content-Length sẽ từ chối kiểu gửi đó.
Thư viện HTTP khác của Python
httpx cũng gửi chunked khi body là iterator không biết độ dài, theo tài liệu của thư viện. Bài httpx proxy nói về cách đặt proxy cho httpx. Kiểm cùng nguyên tắc: truyền bytes hoặc tệp để thư viện tự đặt Content-Length.
curl trong script shell
Lệnh curl đọc dữ liệu từ ống thường dùng -T - hoặc --data-binary @- . Với -T -, lab cho thấy curl gửi chunked. Nếu máy chủ đòi Content-Length, ghi dữ liệu ra tệp trước rồi dùng --data-binary @tệp. Bài cURL proxy là gì có các tùy chọn đặt proxy cho curl.
SDK của dịch vụ lưu trữ
Một số SDK lưu trữ đối tượng tự chia upload lớn thành nhiều phần, mỗi phần có độ dài rõ. Khi dùng API thô thay vì SDK, phải tự đặt Content-Length cho từng phần. Đọc tài liệu của dịch vụ để biết có nhận chunked không.
Xem request thật để tránh lỗi 411 Length Required trước khi gửi máy chủ đích
Một máy chủ echo cục bộ
Cách nhanh nhất để biết thư viện sẽ gửi Content-Length hay chunked là cho nó gửi tới một máy chủ cục bộ in lại header. Đoạn dưới dùng thư viện chuẩn của Python, nghe ở cổng 9519 và in phương thức, Content-Length, Transfer-Encoding của từng request. Đoạn này chỉ để quan sát, không đọc body chunked:
from http.server import BaseHTTPRequestHandler, HTTPServer
class Echo(BaseHTTPRequestHandler):
def do_POST(self):
print(self.command, "CL=", self.headers.get("Content-Length"),
"TE=", self.headers.get("Transfer-Encoding"))
self.send_response(204)
self.send_header("Connection", "close")
self.end_headers()
do_PUT = do_POST
HTTPServer(("127.0.0.1", 9519), Echo).serve_forever()
Chạy máy chủ này trong một cửa sổ, rồi trỏ script về http://127.0.0.1:9519 thay cho URL thật. Dòng in ra cho biết ngay kiểu đóng khung. Làm phép thử này mỗi khi đổi cách đọc dữ liệu, đổi thư viện hay nâng phiên bản, trước khi chạy trên máy chủ đích.
Phép thử cục bộ không cần proxy và không gửi dữ liệu ra ngoài. Nó tách được câu hỏi client gửi gì khỏi câu hỏi proxy và máy chủ làm gì, nên chẩn đoán gọn hơn hẳn.
Nén body trước khi gửi
Một số API nhận body nén gzip với header Content-Encoding: gzip. Khi tự nén trong code, phải đo độ dài sau khi nén. Cách an toàn là nén ra bytes rồi truyền bytes cho thư viện, để thư viện tự đặt Content-Length:
import gzip, json, requests
payload = json.dumps(records).encode("utf-8")
body = gzip.compress(payload)
r = requests.post(url, data=body, timeout=60,
headers={"Content-Type": "application/json", "Content-Encoding": "gzip"})
Nếu nén bằng luồng, ví dụ đọc tệp lớn qua một generator nén từng khúc, độ dài không biết trước và thư viện sẽ quay lại chunked. Với máy chủ đòi Content-Length, lại phải ghi kết quả nén ra tệp tạm như đã nói ở phần trên. Chỉ dùng nén khi tài liệu API ghi rõ nhận request nén, vì máy chủ không nhận sẽ trả 415 hoặc 400.
Khi client nằm sau proxy công ty
Proxy công ty đôi khi chạy phần mềm quét nội dung, đọc body để kiểm virus hay rò rỉ dữ liệu rồi gửi tiếp. Loại proxy này có thể đổi cách đóng khung khi gửi tiếp. Nếu request rời máy với Content-Length mà máy chủ báo nhận chunked, hoặc ngược lại, nghi ngờ hop quét nội dung ở giữa. Chạy cùng request qua một đường khác, ví dụ mạng điện thoại, để so.
Quy trình chẩn đoán lỗi 411 Length Required từng bước
Các bước
- Bước 1: ghi lại request lỗi: phương thức, URL, kiểu dữ liệu truyền vào thư viện, phiên bản thư viện, đường đi qua proxy nào.
- Bước 2: xem request thật gửi đi bằng log debug hoặc curl -v: có Content-Length hay Transfer-Encoding không.
- Bước 3: đọc response: mã, X-Hop hoặc Server, Via. Xác định hop nào sinh ra 411.
- Bước 4: thử cùng body với kiểu dữ liệu có độ dài rõ, như bytes hoặc tệp. Nếu thành 200, nguyên nhân ở cách đóng khung.
- Bước 5: nếu có quyền, đọc log hop cuối để xem header request nhận được.
- Bước 6: sửa ở client bằng cách cung cấp độ dài thật, hoặc ở reverse proxy bằng cách gom body.
- Bước 7: chạy đối chứng, so số byte và sha256, lưu bảng trước và sau.
Bảng tra nhanh
Dấu hiệu |
Nguyên nhân khả dĩ |
Việc nên làm |
|---|---|---|
Lỗi sau khi đổi sang generator |
Thư viện chuyển sang chunked |
Truyền bytes hoặc tệp |
POST rỗng bị 411 |
Không gửi Content-Length: 0 |
Gửi body rỗng tường minh |
curl -T - bị 411 |
curl gửi chunked |
Ghi ra tệp rồi gửi |
Chỉ lỗi với máy chủ cũ |
Máy chủ không nhận chunked |
Gom body ở client hoặc reverse proxy |
Lần gửi lại trả 200 nhưng dữ liệu rỗng |
Generator đã cạn |
Tạo lại nguồn dữ liệu |
Content-Length ghi tay, request treo |
Độ dài sai |
Bỏ số ghi tay, để thư viện đo |
Ghi lại phiên bản
Hành vi đóng khung phụ thuộc thư viện và phiên bản. Ghi phiên bản requests, httpx, curl hay SDK vào bảng kết quả để người sau biết kết luận áp dụng cho bản nào.
Chọn proxy khi xử lý lỗi 411 Length Required
Proxy không phải nơi sửa
Như phần trên, proxy chuyển tiếp không đổi cách đóng khung, và với https không thấy request. Vai trò của proxy khi gặp 411 là một hop cần ghi trong đường đi, để loại trừ khi chẩn đoán.
Khi cần đường đi ổn định
Upload lớn qua proxy cần kết nối giữ nguyên trong suốt lượt gửi. Proxy IP tĩnh hợp với upload một tệp lớn hơn proxy xoay đổi IP theo request. Kiểm tài khoản và định dạng proxy trước, vì proxy sai tài khoản trả 407, dễ lẫn khi đang chẩn đoán.
ProxyVN có proxy dân cư tĩnh, datacenter và proxy xoay, hỗ trợ HTTP và SOCKS5, cấp tài khoản user và mật khẩu hoặc xác thực theo IP. Cần một đường đi cố định để chạy lại bảng đối chứng ở trên, anh em có thể mua proxy Việt Nam tại trang chủ ProxyVN. Bài định dạng proxy giúp viết đúng chuỗi proxy cho script, bài no_proxy là gì giúp loại máy chủ nội bộ khỏi proxy khi cần đi thẳng để so.
Câu hỏi thường gặp về lỗi 411 Length Required
HTTP/2 có bị 411 không?
HTTP/2 đóng khung bằng frame nên không dùng chunked. Client HTTP/2 có thể gửi body không có Content-Length. Khi một proxy chuyển request HTTP/2 xuống máy chủ HTTP/1.1 chỉ nhận Content-Length, proxy phải gom body hoặc máy chủ sẽ trả 411. Bài chưa thử trường hợp này trong lab.
GET có body có bị 411 không?
GET thường không có body. Nếu client gửi GET có body theo kiểu chunked tới máy chủ đòi độ dài, máy chủ có thể trả 411. Nhiều máy chủ bỏ qua body của GET, nên tốt nhất không gửi body với GET.
Đặt cả Content-Length và Transfer-Encoding có được không?
Không nên. RFC 9112 quy định khi có cả hai thì Transfer-Encoding thắng, và việc gửi cả hai là dấu hiệu của request bất thường. Một số hop từ chối request đó.
Content-Length: 0 có khác không gửi header không?
Có khác. Content-Length: 0 nói rõ body rỗng. Không gửi header với POST có thể bị máy chủ coi là thiếu thông tin và trả 411, như ca curl -X POST trong lab.
Vì sao máy chủ lại đòi Content-Length?
Có vài lý do hay gặp. Máy chủ lưu trữ cần biết trước dung lượng để cấp chỗ và kiểm hạn mức trước khi nhận dữ liệu. API có chữ ký request thường đưa độ dài body vào chuỗi được ký, nên body không có độ dài thì không kiểm được chữ ký. Một số phần mềm cũ có bộ đọc HTTP viết từ thời HTTP/1.0, chưa bao giờ hỗ trợ chunked cho request. Có nơi chặn chunked có chủ ý để giảm rủi ro từ request mơ hồ về ranh giới.
Biết lý do giúp chọn cách sửa. Với máy chủ lưu trữ và API có chữ ký, chỉ có cách gửi độ dài thật từ client. Với phần mềm cũ đứng sau reverse proxy anh em quản lý, gom body ở proxy là đủ.
Proxy có thể tự sinh 411 không?
Có thể, nếu proxy đó đòi Content-Length cho request đi qua nó. Khi đó response 411 mang dấu vết của proxy, như header Server của proxy và không có Via, giống cách lab phân biệt bằng X-Hop. Proxy chuyển tiếp trong lab của bài không làm vậy, nó chuyển chunked đi tiếp. Nếu gặp 411 chỉ khi đi qua một proxy nhất định với URL http, hãy thử cùng request đi thẳng để xác nhận.
Lỗi 411 có liên quan tới mật khẩu proxy hay chuỗi proxy sai không?
Không. Proxy sai tài khoản trả 407, proxy sai địa chỉ thì không kết nối được. 411 chỉ liên quan tới header độ dài của request mà hop cuối nhận.
Giới hạn của bài
Lab dùng origin và proxy tự viết trên localhost. Chưa thử máy chủ thật chỉ nhận HTTP/1.0, chưa thử nginx gom body, chưa thử HTTP/2 xuống HTTP/1.1. Kết quả theo thư viện áp dụng cho requests 2.34.2 và curl 8.21.0.
Lỗi 411 Length Required và những điều cần nhớ
lỗi 411 Length Required xuất hiện khi body đi theo kiểu chunked hoặc thiếu header độ dài tới một máy chủ chỉ nhận Content-Length. Sửa bằng cách cung cấp độ dài thật từ bytes, tệp hay tệp tạm, hoặc để reverse proxy gom body, rồi đối soát số byte và sha256. Cần proxy ổn định để chạy đối chứng khi gặp lỗi 411 Length Required, liên hệ Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam.