基本上现在的golang的web库都是从http上搭建起来,golang的http包的核心如下:
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type Engine struct {
}
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
}
这里ServeHTTP的方法传递的两个参数,一个是Request,一个是ResponseWriter,Engine中的ServeHTTP的方法就是要对这两个对象进行读取或者写入操作。而且这两个对象往往是需要同时存在的,为了避免很多函数都需要写这两个参数,我们不如封装一个结构来把这两个对象放在里面:Context
type Context struct {
writermem responseWriter
Request *http.Request
Writer ResponseWriter
...
}
type responseWriter struct {
http.ResponseWriter
size int
status int
}
这里有几个需要讨论的点:
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
type ResponseWriter interface {
responseWriterBase
Pusher() http.Pusher
}
type responseWriterBase interface {
http.ResponseWriter
http.Hijacker
http.Flusher
http.CloseNotifier
Status() int
Size() int
WriteString(string) (int, error)
Written() bool
WriteHeaderNow()
}