(1)读取 http body 部分
(2)根据 boundary 分析出分隔符特征(这个串是唯一的,不会与body内其他数据冲突)
(3)根据实际分隔符分段获取 body 内容
(4)遍历分段内容
(5)根据 Content-Disposition 特征获取其中值
(6)根据值中 filename 或 name 区分是否是包含二进制流还是表单数据的 k-v
(7)根据 filename 获取原始文件名
(8)从连续 两个 newline 字符串为起始至当前分段完毕,按照二进制流读取上传文件流信息。
完成后即有——
- 原始文件名信息
- 原始文件类型信息
- 全部文件流信息
然后该干嘛干嘛,比如写文件到磁盘等。
具体怎么处理是服务器做的事儿,HTTP协议本身并没有死规定,以下说的只是解决问题的某一种思路。
有一个基本认识是,每一个请求都是一个流。而每一个用于传输文件的HTTP报文,都会有类似于这样的报头:
Content-Type: multipart/form-data; boundary=巴拉巴拉
如果报头定义了这样的东西,就可以判断客户端采用了multipart格式传递信息,同时我们也拿到了boundray。
再考虑文件如何处理。以问题中提到的报文为例,payload(你题干中的报文格式并不对,我根据题目意思做了相应修改)为:
-----------------------------14579331036932498511351460782
Content-Disposition: form-data; name="userfile1"; filename="å¤æ³¨è¯´æ.txt"
Content-Type: text/plain
1.±ê×¢ÒÔiPhone6s ÆÁÄ»³ß´çΪ±ê×¼£»
2.Èç¹ûÐèÒª²»Í¬³ß´çµÄicon£¬ÔÙ¸øÎÒ˵¡£
-----------------------------14579331036932498511351460782
Content-Disposition: form-data; name="hehe"
tewtw
-----------------------------14579331036932498511351460782--
1. 第一次读到定义的边界”—————————–14579331036932498511351460782″
意味着一个字段的开始;
2. 继续读入一行,发现这是个文件;再读入一行,发现定义了Content-Type,也许还会定义charset之类的信息;再读入一行发现是个 CRLF ,意味着后续的内容是文件数据,这时候可以构造一个新的临时文件对象,将后续的数据pipe到这个临时文件对象中。
3. 再一次读到边界”—————————–14579331036932498511351460782″意味着这一个字段结束,这时候可以去关闭刚刚创建的临时文件。
4. 然后开始继续下一字段解析过程。
ps:以上部分只是简单的说了解决思路,并不涉及检查、转换等工作。比如在流的pipe过程中,可能需要根据之前定义的charset进行流的转换,甚至如果发现Content-Type不是自己需要的,就压根不存而是直接pipe到黑洞中去。