0x00 前言
一般做法
如下,将整个文件读到 buf 里,不适用于大文件,使用 mime/multipart 包处理
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
defer writer.Close()
part, err := writer.CreateFormFile("myFile", "foo.txt")
if err != nil {
return err
}
file, err := os.Open(name)
if err != nil {
return err
}
defer file.Close()
if _, err = io.Copy(part, file); err != nil {
return err
}
http.Post(url, writer.FormDataContentType(), buf)
方法 2:io.Pipe()
参考前文 神奇的 Golang-IO 包 提到的 io.Pipe 方法,将文件传输强行限制在一个管道中:
r, w := io.Pipe()
m := multipart.NewWriter(w)
go func() {
defer w.Close()
defer m.Close()
part, err := m.CreateFormFile("myFile", "foo.txt")
if err != nil {
return
}
file, err := os.Open(name)
if err != nil {
return
}
defer file.Close()
if _, err = io.Copy(part, file); err != nil {
return
}
}()
http.Post(url, m.FormDataContentType(), r)
在这个示例中,io.Pipe 充当了一个同步的内存管道,它在两个 goroutine 之间传输数据。当主 goroutine 从管道的读取端读取数据时,新 goroutine 将从文件中读取数据并将数据写入管道的写入端,此方法的优点是文件数据的读取和上传是并发进行的,此外由于使用了内存管道,不需要将整个文件加载到内存中,从而减少了内存消耗
如果抓包看,客户端的 HTTP 头部可能是这样,注意 Transfer-Encoding: chunked,表示服务器将使用分块传输编码(chunked transfer encoding)来传输响应体数据。分块传输编码是一种动态生成响应内容的方法,允许服务器在不知道整个响应体大小的情况下开始发送数据。这对于处理大文件或生成内容需要很长时间的响应非常有用
POST / HTTP/1.1
...
Transfer-Encoding: chunked
Accept-Encoding: gzip
Content-Type: multipart/form-data; boundary=....
User-Agent: Go-http-client/1.1
0x02 multipart/form-data 方式
0x03 参考
FEATURED TAGS
Latex
gRPC
负载均衡
OpenSSH
Authentication
Consul
Etcd
Kubernetes
性能优化
Python
分布式锁
WebConsole
后台开发
Golang
OpenSource
Nginx
Vault
网络安全
Perl
分布式理论
Raft
正则表达式
Redis
分布式
限流
go-redis
微服务
反向代理
ReverseProxy
Cache
缓存
连接池
OpenTracing
GOMAXPROCS
GoMicro
微服务框架
日志
zap
Pool
Kratos
Hystrix
熔断
并发
Pipeline
证书
Prometheus
Metrics
PromQL
Breaker
定时器
Timer
Timeout
Kafka
Xorm
MySQL
Fasthttp
bytebufferpool
任务队列
队列
异步队列
GOIM
Pprof
errgroup
consistent-hash
Zinx
网络框架
设计模式
HTTP
Gateway
Queue
Docker
网关
Statefulset
NFS
Machinery
Teleport
Zero Trust
Oxy
存储
Confd
热更新
OAuth
SAML
OpenID
Openssl
AES
微服务网关
IM
KMS
安全
数据结构
hashtable
Sort
Asynq
基数树
Radix
Crontab
热重启
系统编程
sarama
Go-Zero
RDP
VNC
协程池
UDP
hashmap
网络编程
自适应技术
环形队列
Ring Buffer
Circular Buffer
InnoDB
timewheel
GroupCache
Jaeger
GOSSIP
CAP
Bash
websocket
事务
GC
TLS
singleflight
闭包
Helm
network
iptables
MITM
HTTPS
Tap
Tun
路由
wireguard
gvisor
Git
NAT
协议栈
Envoy
FRP
DPI
gopacket
Cgroup
Namespace
DNS
eBPF
GoZero
Gost
Clash
Tracee
gopsutil
Linux
HIDS
ELKEID
XDP
TC
Systemd
DDoS
DPDK
netlink
Kernel
BCC
rootkit
bpftrace
AI
eino