一、简介
Go语言的net/http包是Go语言内置的一个HTTP处理包,使用该包可以方便地搭建HTTP服务器或者HTTP客户端。本文将从请求处理流程入手,对golang http包进行全面解析。
二、请求处理流程
golang http的请求处理包括:路由、处理函数、中间件等,整个处理流程如下:
http.ListenAndServe(addr string, handler http.Handler) error
ListenAndServe函数负责创建一个http.Server对象,监听网络端口,并接受来自客户端的请求,并分配给handler处理。handler可以是一个自定义的类型,只要实现了Handler接口。因此,我们可以使用http包默认提供的Mux类型,或者自己实现一个类型来处理请求。
type HandlerFunc func(w ResponseWriter, r *Request)
HandlerFunc是一个函数类型,用于处理请求的回调函数。函数类型需要满足Handler接口才能作为服务处理函数传给ListenAndServe,具体接口如下:
type Handler interface { ServeHTTP(ResponseWriter, *Request) }
该接口只有一个ServeHTTP方法,负责接收ResponseWriter和Request,其中ResponseWriter为写回客户端的对象,也就是Response,Request则是从客户端发来的请求。一旦接收到请求并将函数转发给ServeHTTP,就会按照golang默认的处理链路:路由 -> 处理函数 -> 中间件 -> 响应返回给客户端。
三、路由
http包提供了一个方便的mux,或多路复用HTTP请求router,称为http.ServeMux。通过使用mux,可以为HTTP服务提供多条处理链路,以便同时处理不同的URI和HTTP方法。下面是一个代码示例
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello") }) http.HandleFunc("/world", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "World") }) http.ListenAndServe(":8080", nil) }
在上面的代码中,使用了`http.HandleFunc()`函数,它接收两个参数:路由地址和一个回调函数来处理该路由。在这个例子中,我们设置了两条路由地址`/hello`和`/world`,并为它们各自设置了一个回调函数。最后,通过调用`http.ListenAndServe()`函数来启动服务,并监听端口`8080`。
四、处理函数
对于每个请求`/hello`和`/world`的回调函数,都需要一个ResponseWriter,由该函数将处理结果返回给客户端。ResponseWriter对象有很多可用的方法,例如Write(), WriteString(), Header() 等。这些方法可以用来向客户端发送数据,设置响应头,或者配置响应状态等。下面是一个处理函数的例子:
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello") })
在上面的代码中,我们通过`http.HandleFunc()`函数为`/hello`路由地址设置了一个回调函数。这个函数在收到客户端的请求时,将输出`Hello`字符串。
五、中间件
golang http包的中间件是指在进入处理函数之前,对请求和响应进行预处理的插件,包括日志、压缩、请求超时等。中间件可以接受一些参数和可选的行为,比如跳过某些请求、或者直接终止请求处理。中间件函数需要接收一个Handler类型函数并返回一个新的Handler类型函数。以下是一个代码示例:
func Logger(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() h.ServeHTTP(w, r) log.Printf("[%s] %s %s", r.Method, r.URL.Path, time.Since(start)) }) } func Hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello") } func main() { http.Handle("/hello", Logger(http.HandlerFunc(Hello))) http.ListenAndServe(":8080", nil) }
在上面的代码中,通过实现中间件Logger函数,我们实现了对服务请求的记录。在正式的处理函数处理完请求之后(h.ServeHTTP(w, r)),记录请求的信息(r.Method, r.URL.Path, time.Since(start))。
六、HTTPS和TLS
HTTPS是HTTP的加密版,采用TLS协议来加密通讯数据。尽管golang不支持对HTTP的TLS,但是它提供了一个轻量级的加密TLS库crypto/tls,可以帮助我们实现HTTPS的功能,如下面的代码所示:
func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "Hello, TLS") }) // 生成tls配置 cert, err := tls.LoadX509KeyPair("server.crt", "server.key") if err != nil { log.Fatal(err) } tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} srv := &http.Server{ Addr: ":8443", Handler: mux, TLSConfig: tlsConfig, } log.Fatal(srv.ListenAndServeTLS("", "")) }
在上面的代码中,我们创建了一个http.ServeMux对象,并为根URL`/`设置了回调函数。为了启用TLS,我们使用tls.LoadX509KeyPair() 方法加载证书和密钥,它们将用于加密通信。然后,我们将TLS配置传递给http.Server,并将其用作secureconnection。listen 并serve TLS的HTTPS处理链路就这样形成了。
七、总结
本篇文章详细介绍了golang http包的各种使用方法,包括请求处理流程、路由、处理函数、中间件、HTTPS、TLS等方面。通过掌握这些知识点,可以帮助开发人员更好地掌握Http原理,并在实际工作中运用golang http包来搭建Web服务器及开发REST API等。