Skip to content

Instantly share code, notes, and snippets.

@bwangelme
Last active October 31, 2018 16:22
Show Gist options
  • Save bwangelme/667cbdb550317cdd69cbac03dfb9ce6b to your computer and use it in GitHub Desktop.
Save bwangelme/667cbdb550317cdd69cbac03dfb9ce6b to your computer and use it in GitHub Desktop.
package main
// HTTP `Transfer-Encoding: chunked` Header的说明
// ## 1. HTTP 持久连接和短连接
// ## 2. HTTP 的 content-length
// ## 3. HTTP 的 chunked 传输格式
// ## 4. HTTP chunked 格式的上传文件
import (
"fmt"
"log"
"net"
)
// handleClosedHttpReq 演示了短连接不需要 content-length 字段,客户端也可以自动识别响应
// >>> http :8080
// HTTP/1.1 200 OK
//
// hello, world!
//
func handleClosedHttpReq(conn net.Conn) {
//TODO: 如果请求数据没有被读出来的话,HTTP客户端将会返回reset错误
buffer := make([]byte, 1024)
n, err := conn.Read(buffer)
if err != nil {
log.Fatalln(err)
}
fmt.Println(n, string(buffer))
data := []byte("hello, world!")
conn.Write([]byte("HTTP/1.1 200 OK\r\n"))
conn.Write([]byte("\r\n"))
conn.Write(data)
conn.Close()
}
// handleKeepAliveHttpReq 演示了客户端在不关闭TCP连接的情况下,通过 content-length 字段来识别相应
// 如果没有 content-length 字段,HTTP客户端会一直处于pending的状态
//>>> http :8080
//HTTP/1.1 200 OK
//Content-Length: 18
//
//hello, keel-alive!
//
func handleKeepAliveHttpReq(conn net.Conn) {
buffer := make([]byte, 1024)
n, err := conn.Read(buffer)
if err != nil {
log.Fatalln(err)
}
fmt.Println(n, string(buffer))
data := []byte("hello, keel-alive!")
conn.Write([]byte("HTTP/1.1 200 OK\r\n"))
conn.Write([]byte(fmt.Sprintf("Content-Length: %d\r\n", len(data))))
conn.Write([]byte("\r\n"))
conn.Write(data)
}
// handleChunkedHttpResp 展示了客户端通过`Transfer-Encoding: chunked`识别HTTP响应
// HTTP响应的内容中,每个chunked由`长度\r\n`和`内容\r\n`构成,最后一个chunked是 `0\r\n\r\n` ,表示传输结束
//>>> http :8080
//HTTP/1.1 200 OK
//Transfer-Encoding: chunked
//
//hello,chunked!
//
func handleChunkedHttpResp(conn net.Conn) {
buffer := make([]byte, 1024)
n, err := conn.Read(buffer)
if err != nil {
log.Fatalln(err)
}
fmt.Println(n, string(buffer))
conn.Write([]byte("HTTP/1.1 200 OK\r\n"))
conn.Write([]byte("Transfer-Encoding: chunked\r\n"))
conn.Write([]byte("\r\n"))
conn.Write([]byte("6\r\n"))
conn.Write([]byte("hello,\r\n"))
conn.Write([]byte("8\r\n"))
conn.Write([]byte("chunked!\r\n"))
conn.Write([]byte("0\r\n"))
conn.Write([]byte("\r\n"))
}
func main() {
ln, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalln(err)
}
for {
conn, err := ln.Accept()
if err != nil {
log.Println(err)
continue
}
go handleChunkedHttpResp(conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment