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) }

 

posted @ 2021-08-25 16:41  小匡程序员  阅读(109)  评论(0编辑  收藏  举报