天天看点

golang net之http server

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/