• 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) }
  • 相关阅读:
    JS获取元素的子元素
    js iframe
    获取窗口句柄
    python 从PDF中提取附件
    xlwings 使用方法
    基于KNN的发票识别
    爬取漫画网站并进行图片拼接
    用python实现对元素的长截图
    Head First C 第三章总结
    Ruby on Rails Tutorial 第八章笔记 基本登陆功能
  • 原文地址:https://www.cnblogs.com/tkzc2013/p/15185736.html
Copyright © 2020-2023  润新知