multipart/form-data
通常是多部分實體,需要一直阻塞到數據讀取到和 Content-Length
大小一樣爲止。
一個簡單的multipart/form-data
請求:
第一次收到的實體數據信息:
[src\lib.rs:225] &packet.len() = 333
[src\lib.rs:226] String::from_utf8_lossy(&packet) = "POST / HTTP/1.1\r\nPostman-Token: e648a765-7e9f-46dc-bde9-2e61e3febc24\r\nContent-Type: multipart/form-data; boundary=--------------------------626641272837121778176158\r\nContent-Length: 460\r\n\r\n----------------------------626641272837121778176158\r\nContent-Disposition: form-data; name=\"img\"; filename=\"a.txt\"\r\nContent-Type: text/plain\r\n\r\n"
這裏我一次讀取了1024
字節,但是第一個實體讀到333
字節就已經返回了。
但是可以看到Content-Length
的大小爲460
現在讀取到的http body
還沒有這麼大。
[src\lib.rs:180] &req.body.len() = 144
[src\lib.rs:181] String::from_utf8_lossy(&req.body) = "----------------------------626641272837121778176158\r\nContent-Disposition: form-data; name=\"img\"; filename=\"a.txt\"\r\nContent-Type: text/plain\r\n\r\n"
Content-Length
的大小爲460
現在只收到144
,所以接下來需要繼續阻塞讀取,將剩下的316
字節全部讀取出來
讀取剩下的316
字節:
[src\lib.rs:178] &entity.len() = 316
[src\lib.rs:179] String::from_utf8_lossy(&entity) = "a\r\n----------------------------626641272837121778176158\r\nContent-Disposition: form-data; name=\"img2\"; filename=\"b.txt\"\r\nContent-Type: text/plain\r\n\r\nb\r\n----------------------------626641272837121778176158\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\najanuw\r\n----------------------------626641272837121778176158--\r\n"
現在將第一次讀取的數據與之後的拼接起來大概就像這樣:
----------------------------626641272837121778176158\r\n
Content-Disposition: form-data; name=\"img\"; filename=\"a.txt\"\r\n
Content-Type: text/plain\r\n\r\n
a\r\n
----------------------------626641272837121778176158\r\n
Content-Disposition: form-data; name=\"img2\"; filename=\"b.txt\"\r\n
Content-Type: text/plain\r\n\r\n
b\r\n
----------------------------626641272837121778176158\r\n
Content-Disposition: form-data; name=\"name\"\r\n\r\n
ajanuw\r\n
----------------------------626641272837121778176158--\r\n
每段數據之間使用----------------------------626641272837121778176158
分割,注意這裏的626641272837121778176158
是在客戶端發送時隨機生成的,所以每次請求都不一樣。
如果接下來沒有數據,則用--\r\n
表示,可以停止讀取
在----------------------------626641272837121778176158\r\n
行之後是當前節數據的信息,一直到\r\n\r\n
之後開始讀取當前節的數據,直到\r\n
爲止,然後開始讀取下一節。
如果當前節是文件,通常會有filename
和Content-Type
等信息。
在header
頭中的Content-Type: multipart/form-data; boundary=--------------------------626641272837121778176158\r\n
,消息邊界是--------------------------626641272837121778176158
這和實體中的邊界少了--
,可以對比下。
注意控制檯打印的反斜槓:
Content-Disposition: form-data; name=\"img\"; filename=\"a.txt\"\r\n
實際上是:
Content-Disposition: form-data; name="img"; filename="a.txt"\r\n
See alse: