码流解析http如何发送二进制文件
几乎所有的web项目都会使用http的协议,在日常工作中最常用的还是使用http处理文本信息,在处理常见的文本请求及文件格式例如png、gif、脚本等,各个浏览器都能够通过开发者工具看到内容信息。
碰到上传或者下载文件时,浏览器通常无法看到内容信息。例如使用Chrome浏览器上传文件时:

本文将从底层码流的角度解析上传文件是如何处理http本身的文本数据和文件的二进制数据的。
结论:
http上传文件时,将文件的二进制码流混在http请求报文的二进制码流中一并发送。服务器解析时,http原有的部分(如请求行、请求头部字段等)按文本解析,文件部分码流直接写入到目标文件中。
环境搭建
常见的方式是通过mime的方式上传文件。通过spring-boot搭建基本的文件上传页面(源代码)。关键代码如下:
java部分:
@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
html部分:
<form method="POST" enctype="multipart/form-data" action="/">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>
页面效果 :
本地环境搭建完成后,启动工程,浏览器这输入localhost:8080

获取上传文件的码流:
上传只包含一字节[6]的文件使用java构建二进制文件,在服务端将会收到如下的码流(不同环境可能存在一定的差别,不影响分析过程)获取http码流:
[80, 79, 83, 84, 32, 47, 32, 72, 84, 84, 80, 47, 49, 46, 49,13, 10, 72, 111, 115, 116, 58, 32, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48, 13, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 107, 101, 101, 112, 45, 97, 108, 105, 118, 101, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32, 50, 49, 51, 13, 10, 67, 97, 99, 104, 101, 45, 67, 111, 110, 116, 114, 111, 108, 58, 32, 109, 97, 120, 45, 97, 103, 101, 61, 48, 13, 10, 79, 114, 105, 103, 105, 110, 58, 32, 104, 116, 116, 112, 58, 47, 47, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48, 13, 10, 85, 112, 103, 114, 97, 100, 101, 45, 73, 110, 115, 101, 99, 117, 114, 101, 45, 82, 101, 113, 117, 101, 115, 116, 115, 58, 32, 49, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 109, 117, 108, 116, 105, 112, 97, 114, 116, 47, 102, 111, 114, 109, 45, 100, 97, 116, 97, 59, 32, 98, 111, 117, 110, 100, 97, 114, 121, 61, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 55, 79, 82, 67, 87, 104, 88, 111, 66, 77, 75, 99, 86, 121, 88, 122, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 77, 111, 122, 105, 108, 108, 97, 47, 53, 46, 48, 32, 40, 77, 97, 99, 105, 110, 116, 111, 115, 104, 59, 32, 73, 110, 116, 101, 108, 32, 77, 97, 99, 32, 79, 83, 32, 88, 32, 49, 48, 95, 49, 51, 95, 54, 41, 32, 65, 112, 112, 108, 101, 87, 101, 98, 75, 105, 116, 47, 53, 51, 55, 46, 51, 54, 32, 40, 75, 72, 84, 77, 76, 44, 32, 108, 105, 107, 101, 32, 71, 101, 99, 107, 111, 41, 32, 67, 104, 114, 111, 109, 101, 47, 55, 51, 46, 48, 46, 51, 54, 56, 51, 46, 56, 54, 32, 83, 97, 102, 97, 114, 105, 47, 53, 51, 55, 46, 51, 54, 13, 10, 65, 99, 99, 101, 112, 116, 58, 32, 116, 101, 120, 116, 47, 104, 116, 109, 108, 44, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 120, 104, 116, 109, 108, 43, 120, 109, 108, 44, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 120, 109, 108, 59, 113, 61, 48, 46, 57, 44, 105, 109, 97, 103, 101, 47, 119, 101, 98, 112, 44, 105, 109, 97, 103, 101, 47, 97, 112, 110, 103, 44, 42, 47, 42, 59, 113, 61, 48, 46, 56, 44, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 115, 105, 103, 110, 101, 100, 45, 101, 120, 99, 104, 97, 110, 103, 101, 59, 118, 61, 98, 51, 13, 10, 82, 101, 102, 101, 114, 101, 114, 58, 32, 104, 116, 116, 112, 58, 47, 47, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48, 47, 13, 10, 65, 99, 99, 101, 112, 116, 45, 69, 110, 99, 111, 100, 105, 110, 103, 58, 32, 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 44, 32, 98, 114, 13, 10, 65, 99, 99, 101, 112, 116, 45, 76, 97, 110, 103, 117, 97, 103, 101, 58, 32, 122, 104, 44, 122, 104, 45, 67, 78, 59, 113, 61, 48, 46, 57, 44, 101, 110, 59, 113, 61, 48, 46, 56, 13, 10, 67, 111, 111, 107, 105, 101, 58, 32, 73, 100, 101, 97, 45, 50, 48, 102, 102, 57, 50, 53, 48, 61, 53, 101, 55, 53, 57, 99, 97, 50, 45, 57, 101, 53, 54, 45, 52, 97, 48, 48, 45, 57, 99, 100, 53, 45, 52, 100, 50, 100, 100, 50, 102, 101, 100, 55, 97, 97, 59, 32, 74, 83, 69, 83, 83, 73, 79, 78, 73, 68, 61, 49, 70, 51, 51, 65, 66, 50, 49, 67, 56, 48, 66, 70, 56, 66, 49, 49, 65, 65, 48, 66, 48, 54, 48, 56, 50, 48, 56, 69, 55, 52, 68, 13, 10, 13, 10, 45, 45, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 55, 79, 82, 67, 87, 104, 88, 111, 66, 77, 75, 99, 86, 121, 88, 122, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 68, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 58, 32, 102, 111, 114, 109, 45, 100, 97, 116, 97, 59, 32, 110, 97, 109, 101, 61, 34, 102, 105, 108, 101, 34, 59, 32, 102, 105, 108, 101, 110, 97, 109, 101, 61, 34, 102, 105, 120, 101, 100, 95, 115, 105, 122, 101, 95, 102, 105, 108, 101, 95, 115, 105, 110, 103, 108, 101, 95, 54, 34, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 111, 99, 116, 101, 116, 45, 115, 116, 114, 101, 97, 109, 13, 10, 13, 10, 6, 13, 10, 45, 45, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 55, 79, 82, 67, 87, 104, 88, 111, 66, 77, 75, 99, 86, 121, 88, 122, 45, 45, 13, 10]
解析码流
根据http头部字符集规定,头部解析采用ISO-8859-1字符集,此字符集中[13,10]为ASCII中的“回车,换行”,上述码流按[13,10]拆分呈现如下:
[80, 79, 83, 84, 32, 47, 32, 72, 84, 84, 80, 47, 49, 46, 49,
13, 10,
72, 111, 115, 116, 58, 32, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48,
13, 10,
67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 107, 101, 101, 112, 45, 97, 108, 105, 118, 101,
13, 10,
67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32, 50, 49, 51,
13, 10,
67, 97, 99, 104, 101, 45, 67, 111, 110, 116, 114, 111, 108, 58, 32, 109, 97, 120, 45, 97, 103, 101, 61, 48,
13, 10,
79, 114, 105, 103, 105, 110, 58, 32, 104, 116, 116, 112, 58, 47, 47, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48,
13, 10,
85, 112, 103, 114, 97, 100, 101, 45, 73, 110, 115, 101, 99, 117, 114, 101, 45, 82, 101, 113, 117, 101, 115, 116, 115, 58, 32, 49,
13, 10,
67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 109, 117, 108, 116, 105, 112, 97, 114, 116, 47, 102, 111, 114, 109, 45, 100, 97, 116, 97, 59, 32, 98, 111, 117, 110, 100, 97, 114, 121, 61, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 55, 79, 82, 67, 87, 104, 88, 111, 66, 77, 75, 99, 86, 121, 88, 122,
13, 10,
85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 77, 111, 122, 105, 108, 108, 97, 47, 53, 46, 48, 32, 40, 77, 97, 99, 105, 110, 116, 111, 115, 104, 59, 32, 73, 110, 116, 101, 108, 32, 77, 97, 99, 32, 79, 83, 32, 88, 32, 49, 48, 95, 49, 51, 95, 54, 41, 32, 65, 112, 112, 108, 101, 87, 101, 98, 75, 105, 116, 47, 53, 51, 55, 46, 51, 54, 32, 40, 75, 72, 84, 77, 76, 44, 32, 108, 105, 107, 101, 32, 71, 101, 99, 107, 111, 41, 32, 67, 104, 114, 111, 109, 101, 47, 55, 51, 46, 48, 46, 51, 54, 56, 51, 46, 56, 54, 32, 83, 97, 102, 97, 114, 105, 47, 53, 51, 55, 46, 51, 54,
13, 10,
65, 99, 99, 101, 112, 116, 58, 32, 116, 101, 120, 116, 47, 104, 116, 109, 108, 44, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 120, 104, 116, 109, 108, 43, 120, 109, 108, 44, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 120, 109, 108, 59, 113, 61, 48, 46, 57, 44, 105, 109, 97, 103, 101, 47, 119, 101, 98, 112, 44, 105, 109, 97, 103, 101, 47, 97, 112, 110, 103, 44, 42, 47, 42, 59, 113, 61, 48, 46, 56, 44, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 115, 105, 103, 110, 101, 100, 45, 101, 120, 99, 104, 97, 110, 103, 101, 59, 118, 61, 98, 51,
13, 10,
82, 101, 102, 101, 114, 101, 114, 58, 32, 104, 116, 116, 112, 58, 47, 47, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48, 47,
13, 10,
65, 99, 99, 101, 112, 116, 45, 69, 110, 99, 111, 100, 105, 110, 103, 58, 32, 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 44, 32, 98, 114,
13, 10,
65, 99, 99, 101, 112, 116, 45, 76, 97, 110, 103, 117, 97, 103, 101, 58, 32, 122, 104, 44, 122, 104, 45, 67, 78, 59, 113, 61, 48, 46, 57, 44, 101, 110, 59, 113, 61, 48, 46, 56,
13, 10,
67, 111, 111, 107, 105, 101, 58, 32, 73, 100, 101, 97, 45, 50, 48, 102, 102, 57, 50, 53, 48, 61, 53, 101, 55, 53, 57, 99, 97, 50, 45, 57, 101, 53, 54, 45, 52, 97, 48, 48, 45, 57, 99, 100, 53, 45, 52, 100, 50, 100, 100, 50, 102, 101, 100, 55, 97, 97, 59, 32, 74, 83, 69, 83, 83, 73, 79, 78, 73, 68, 61, 49, 70, 51, 51, 65, 66, 50, 49, 67, 56, 48, 66, 70, 56, 66, 49, 49, 65, 65, 48, 66, 48, 54, 48, 56, 50, 48, 56, 69, 55, 52, 68,
13, 10,
13, 10,
45, 45, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 55, 79, 82, 67, 87, 104, 88, 111, 66, 77, 75, 99, 86, 121, 88, 122,
13, 10,
67, 111, 110, 116, 101, 110, 116, 45, 68, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 58, 32, 102, 111, 114, 109, 45, 100, 97, 116, 97, 59, 32, 110, 97, 109, 101, 61, 34, 102, 105, 108, 101, 34, 59, 32, 102, 105, 108, 101, 110, 97, 109, 101, 61, 34, 102, 105, 120, 101, 100, 95, 115, 105, 122, 101, 95, 102, 105, 108, 101, 95, 115, 105, 110, 103, 108, 101, 95, 54, 34,
13, 10,
67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 111, 99, 116, 101, 116, 45, 115, 116, 114, 101, 97, 109,
13, 10,
13, 10,
6,
13, 10,
45, 45, 45, 45, 45, 45, 87, 101, 98, 75, 105, 116, 70, 111, 114, 109, 66, 111, 117, 110, 100, 97, 114, 121, 55, 79, 82, 67, 87, 104, 88, 111, 66, 77, 75, 99, 86, 121, 88, 122, 45, 45,
13, 10]
上述标红的字节[6]便是上传的文件的二进制码。除上述标红的字节[6]外其他部分按“ISO-8859-1”解析成字符串呈现如下:
POST / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 213
Cache-Control: max-age=0
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7ORCWhXoBMKcVyXz
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,zh-CN;q=0.9,en;q=0.8
Cookie: Idea-20ff9250=5e759ca2-9e56-4a00-9cd5-4d2dd2fed7aa; JSESSIONID=1F33AB21C80BF8B11AA0B0608208E74D
------WebKitFormBoundary7ORCWhXoBMKcVyXz
Content-Disposition: form-data; name="file"; filename="fixed_size_file_single_6"
Content-Type: application/octet-stream
6 实际无法呈现,放在此处保持与码流的对应关系
------WebKitFormBoundary7ORCWhXoBMKcVyXz--
http服务器根据“Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7ORCWhXoBMKcVyXz”确定请求报文的范围然后解析内部的细节信息。“----WebKitFormBoundary7ORCWhXoBMKcVyXz--”为结束符。
最终将字节[6]写入到目标文件中。
参考链接:
The encapsulation boundary following the last body part is a distinguished delimiter that indicates that no further body parts will follow. Such a delimiter is identical to the previous delimiters, with the addition of two more hyphens at the end of the line
2.mime参考
更多推荐


所有评论(0)