这篇文章出现的理由是业务上需要创建一个Web Server。创建web是所有语言出现必须实现的功能之一了。在Nginx+fastcgi+PHP广为使用的今天,这里我们不妨使用Go来进行web服务器的搭建。
前言
使用Go搭建Web服务器的包有很多,大致有下面几种方法,直接使用net包,使用net.http包,使用第三方包(比如gorilla)。使用net包就需要从tcp层开始封装,耗费人力物力极大,果断舍弃。直接使用封装好的net.http和第三方包才是上策。这里我们就选择了使用官方提供的net.http包来搭建web服务。另外附带一句,gorilla的第三方包现在使用还是非常广的,文档也是比较全的,有兴趣的同学可以考虑使用一下。
建议看这篇文章前先看一下net/http文档http://golang.org/pkg/net/http/
net.http包里面有很多文件,都是和http协议相关的,比如设置cookie,header等。其中最重要的一个文件就是server.go了,这里我们阅读的就是这个文件。
几个重要概念
ResponseWriter: 生成Response的接口
Handler: 处理请求和生成返回的接口
ServeMux: 路由,后面会说到ServeMux也是一种Handler
Conn : 网络连接
具体分析
(具体的说明直接以注释形式放在代码中)
几个接口:
Handler
1
2
3
|
实现了handler接口的对象就意味着往server端添加了处理请求的逻辑。
下面是三个接口(ResponseWriter,Flusher,Hijacker):
ResponseWriter,Hijacker
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
// ResponseWriter的作用是被Handler调用来组装返回的Response的
type ResponseWriter
interface
{
// 这个方法返回Response返回的Header供读写
Header() Header
// 这个方法写Response的Body
Write([]
byte
) (
int
,error)
// 这个方法根据HTTP State Code来写Response的Header
WriteHeader(
)
}
// Flusher的作用是被Handler调用来将写缓存中的数据推给客户端
type Flusher
{
// 这个方法将写缓存中数据推送给客户端
Flush()
}
type Hijacker
{
Hijack() (net.Conn,*bufio.ReadWriter,error)
}
|
response
实现这三个接口的结构是response(这个结构是http包私有的,在文档中并没有显示,需要去看源码)
// response包含了所有server端的http返回信息
type response
struct
{
conn *conn
// 保存此次HTTP连接的信息
req *Request
// 对应请求信息
chunking
bool
// 是否使用chunk
wroteHeader
// header是否已经执行过写操作
wroteContinue
// 100 Continue response was written
header Header
// 返回的http的Header
written int64
// Body的字节数
contentLength int64
// Content长度
status
int
// HTTP状态
needSniff
// 是否需要使用sniff。(当没有设置Content-Type的时候,开启sniff能根据HTTP body来确定Content-Type)
closeAfterReply
//是否保持长链接。如果客户端发送的请求中connection有keep-alive,这个字段就设置为false。
requestBodyLimitHit
//是否requestBody太大了(当requestBody太大的时候,response是会返回411状态的,并把连接关闭)
在response中是可以看到
|