http学习 | 青训营

127 阅读3分钟

Go 语言的 HTTP 框架笔记

Go 语言的 net/http 包是 Go 语言标准库中最常用的一个包,它实现了 HTTP 协议的客户端和服务器功能,支持 HTTP/1.1 和 HTTP/2 协议。在使用 net/http 包时,我们需要了解以下几个重要的概念和接口:

http.Client

HTTP 客户端,用于发送 HTTP 请求和接收 HTTP 响应。http.Client 可以设置一些属性,如超时时间、重定向策略、代理设置等,来控制客户端的行为。http.Client 的核心方法是 Do,它接受一个 http.Request 参数,返回一个 http.Response 结果和一个错误值。http.Client 还提供了一些便捷的方法,如 Get、Post、PostForm 等,来简化常见的 HTTP 请求。

http.Request

HTTP 请求,包含请求方法、URL、头部、正文等信息。http.Request 可以通过 http.NewRequest 方法来创建,也可以通过 http.ReadRequest 方法从 io.Reader 中读取。http.Request 的核心方法是 Write,它将请求写入 io.Writer 中,通常用于发送给服务器或者存储在文件中。

http.Response

HTTP 响应,包含状态码、头部、正文等信息。http.Response 可以通过 http.Client 的 Do 方法或者 http.Get 等方法来获取,也可以通过 http.ReadResponse 方法从 io.Reader 中读取。http.Response 的核心方法是 Write,它将响应写入 io.Writer 中,通常用于返回给客户端或者存储在文件中。

http.RoundTripper

HTTP 传输层接口,用于执行 HTTP 请求并返回 HTTP 响应。http.RoundTripper 是一个抽象的接口,它可以有不同的实现,如 http.Transport、http2.Transport 等。http.RoundTripper 的核心方法是 RoundTrip,它接受一个 http.Request 参数,返回一个 http.Response 结果和一个错误值。http.Client 使用 http.RoundTripper 来执行 HTTP 请求,并且默认使用 http.DefaultTransport 作为传输层。

http.Handler

HTTP 处理器接口,用于处理 HTTP 请求并生成 HTTP 响应。http.Handler 是一个抽象的接口,它可以有不同的实现,如 http.HandlerFunc、http.ServeMux 等。http.Handler 的核心方法是 ServeHTTP,它接受一个 http.ResponseWriter 参数和一个 http.Request 参数,并且将响应写入到 http.ResponseWriter 中。

http.ResponseWriter

HTTP 响应写入器接口,用于向客户端发送 HTTP 响应。http.ResponseWriter 提供了一些方法,如 Write、WriteHeader、Header 等,来控制响应的状态码、头部、正文等信息。

http.Server

HTTP 服务器,用于监听网络地址并接收客户端的请求。http.Server 可以设置一些属性,如地址、处理器、超时时间、TLS 配置等,来控制服务器的行为。http.Server 的核心方法是 ListenAndServe 和 ListenAndServeTLS,它们分别用于启动非加密和加密的 HTTP 服务器,并且循环处理每个请求。

基于以上概念和接口,我们可以使用 net/http 包来实现各种复杂度的 HTTP 客户端和服务器。下面是一些简单的示例:

  • 使用 http.Get 方法发送一个 GET 请求,并打印响应的状态码和正文:
package main
​
import (
    "fmt"
    "io"
    "log"
    "net/http"
)
​
func main() {
    resp, err := http.Get("http://example.com")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    fmt.Println("Status:", resp.Status)
    io.Copy(os.Stdout, resp.Body)
}
  • 使用 http.NewRequest 和 http.Client 的 Do 方法发送一个带有自定义头部的 POST 请求,并打印响应的状态码和正文:
package main
​
import (
    "bytes"
    "fmt"
    "io"
    "log"
    "net/http"
)func main() {
    data := []byte(`{"name":"Alice","age":25}`)
    req, err := http.NewRequest("POST", "http://example.com", bytes.NewReader(data))
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    fmt.Println("Status:", resp.Status)
    io.Copy(os.Stdout, resp.Body)
}
  • 使用 http.HandlerFunc 和 http.Server 的 ListenAndServe 方法创建一个简单的 HTTP 服务器,并返回一个欢迎信息:
package main
​
import (
    "fmt"
    "log"
    "net/http"
)
​
func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, world!")
}
​
func main() {
    handler := http.HandlerFunc(hello)
    server := &http.Server{
        Addr:    ":8080",
        Handler: handler,
    }
    log.Fatal(server.ListenAndServe())
}