http `Content-Type: multipart/form-data`

multipart/form-data 通常是多部分实体,需要一直阻塞到数据读取到和 Content-Length 大小一样为止。

一个简单的multipart/form-data请求:

image

第一次收到的实体数据信息:

[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为止,然后开始读取下一节。

如果当前节是文件,通常会有filenameContent-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:

posted @ 2022-03-12 11:00  Ajanuw  阅读(201)  评论(0编辑  收藏  举报