go应用专题:net/http server端
参考:
https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/03.4.md(谢孟军:http包详解)
核心底层方法
启动服务
//开始 http.ListenAndServe(":3000",nil) //代理server.ListenAndServe() l, err := net.Listen("tcp", addr) srv.Serve(l) //监听 for { rw, err := l.Accept() //conn句柄流 c := srv.newConn(rw) //conn结构体 go c.serve(connCtx) //每个连接对应一个协程处理 } //解析 for { w, err := c.readRequest(ctx) //创建请求和响应结构体 req := w.req //请求 serverHandler{c.server}.ServeHTTP(w, w.req) //交给http应用逻辑 }
核心接口和结构体
//tcp总连接 type TCPListener struct { fd *netFD lc ListenConfig } //连接处理函数 type Handler interface { ServeHTTP(ResponseWriter, *Request) } //构成一个服务 type Server struct { Addr string Handler Handler mu sync.Mutex } //一个具体的tcp连接 func (ln *TCPListener) accept() (*TCPConn, error) { fd, err := ln.fd.accept() if err != nil { return nil, err } tc := newTCPConn(fd) if ln.lc.KeepAlive >= 0 { setKeepAlive(fd, true) ka := ln.lc.KeepAlive if ln.lc.KeepAlive == 0 { ka = defaultTCPKeepAlive } setKeepAlivePeriod(fd, ka) } return tc, nil } //一个具体的http连接 type conn struct { server *Server cancelCtx context.CancelFunc
rwc net.Conn remoteAddr string tlsState *tls.ConnectionState werr error
r *connReader bufr *bufio.Reader bufw *bufio.Writer lastMethod string curReq atomic.Value // of *response (which has a Request in it) curState struct{ atomic uint64 } // packed (unixtime<<8|uint8(ConnState)) mu sync.Mutex hijackedv bool }
//构建一个具体的http请求 req, err := readRequest(c.bufr, keepHostHeader) readRequest(b *bufio.Reader, deleteHostHeader bool) (req *Request, err error) { tp := newTextprotoReader(b) req = new(Request) s, err = tp.ReadLine() req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s) //首行 mimeHeader, err := tp.ReadMIMEHeader()//头部 req.Header = Header(mimeHeader) readTransfer(req, b) //请求体 ,这里弄懂需要查找专门的逻辑 }
//默认http服务器 type ServeMux struct { mu sync.RWMutex m map[string]muxEntry es []muxEntry // slice of entries sorted from longest to shortest. hosts bool // whether any patterns contain hostnames } func (mux *ServeMux) Handle(pattern string, handler Handler) { mux.mu.Lock() defer mux.mu.Unlock() if _, exist := mux.m[pattern]; exist { panic("http: multiple registrations for " + pattern) } if mux.m == nil { mux.m = make(map[string]muxEntry) } e := muxEntry{h: handler, pattern: pattern} mux.m[pattern] = e if pattern[len(pattern)-1] == '/' { mux.es = appendSorted(mux.es, e) } if pattern[0] != '/' { mux.hosts = true } } func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { if r.RequestURI == "*" { if r.ProtoAtLeast(1, 1) { w.Header().Set("Connection", "close") } w.WriteHeader(StatusBadRequest) return } h, _ := mux.Handler(r) h.ServeHTTP(w, r) }
//默认兜底处理函数 type HandlerFunc func(ResponseWriter, *Request) // ServeHTTP calls f(w, r). func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) } // Helper handlers func Error(w ResponseWriter, error string, code int) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Header().Set("X-Content-Type-Options", "nosniff") w.WriteHeader(code) fmt.Fprintln(w, error) } func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) } func NotFoundHandler() Handler { return HandlerFunc(NotFound) }