golang 版本:1.12.9
简单的HTTP服务器代码:
在浏览器输入“http://127.0.0.1:8000”得到输出“Hi,Stranger,welcome”;输入“http://127.0.0.1:8000/test”得到输出“Hi,Tester”
handler的注册
handler的相关方法如下:
http使用handler定义请求的路径以及请求的处理。每个handler都必须实现ServeHTTP方法,该方法将请求分发到不同的handler进行处理,每个handler处理一条请求路径。有两种注册handler的方式:http.Handle和http.HandleFunc,两种实现本质上是一致的,前者需要明确写出ServeHTTP方法的实现,后者由内置方法实现(见下文)。
Handler的接口定义如下:
http.HandleFunc的第二个参数被定义为HandlerFunc,实现了Handler接口。
当http.ListenAndServe的第二个参数为nil,则使用http.Handle和http.HandleFunc方法注册的handler,默认保存在http.DefaultServeMux.m中(注册方法为ServeMux.Handle/ServeMux.HandleFunc)。当http server接收到一个request时,会在serverHandler.ServeHTTP中调用DefaultServeMux.ServeHTTP来处理接收到的request,分为两步:
调用ServeMux.Handler函数,在ServeMux.m中根据pattern遍历查合适的handler
调用handler的ServeHTTP方法
serverHandler.ServeHTTP的源码如下:
DefaultServeMux的结构体定义如下:
默认的handler的ServeHTTP方法实现如下,主要实现查找handler并处理请求
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=utf-8
< Location: /test/
< Date: Fri, 06 Dec 2019 03:35:59 GMT
< Content-Length: 41
<
<a href="/test/">Moved Permanently</a>.
*/
通常使用http.HandleFunc注册handler,使用DefaultServeMux的方法分发处理请求即可。也可以通过http.NewServeMux()创建一个自定义的serverHandler,并实现Serve HTTP方法。
http.server
调用下面函数进行监听,主要创建监听socket并接收该socket上的连接。通常调用如下接口即可:
一个Server结构体表示一个启用监听端口的真实服务
ListenAndServe在创建监听socket后调用Serve等待连接
ListenAndServeTLS与ListenAndServe类似,只是入参多了证书参数
ServeTLS函数中会调用tls.NewListener创建一个tls类型的监听socket,后续会调用tls的Accetp函数接收客户端连接
Serve主要实现如下。通过Accept与客户端创建连接后,通过newConn函数初始化一个HTTP连接,该连接包含HTTP的描述(监听地址,URL等)和一个TCP连接,然后处理来自客户的HTTP请求。
Accept返回的底层的连接结构如下
实现如上接口的有tcpsock的TCPConn以及unixsock的UnixConn,通常使用TCPConn
newConn生成的HTTP结构体如下,它表示一条基于TCP的HTTP连接,封装了3个重要的数据结构:server表示HTTP server的"server";rwc表示底层连接结构体rwc net.Conn;r用于读取http数据的connReader(从rwc读取数据)。后续的request和response都基于该结构体
connReader中的conn就是上面表示http连接的结构体
在下面的server函数中处理请求并返回响应
readRequest函数处理http请求
读取HTTP请求,并将其结构化为http.Request
http.transport
参见详解transport
NetPoll
参见详解golang net之netpoll
参考:
https://golang.org/pkg/net/http/
https://lanre.wtf/blog/2017/07/24/roundtripper-go/
https://lanre.wtf/blog/2017/04/03/http-in-go/