• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

go应用专题:net/httpserver端

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

参考:

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

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go获取函数被调用的文件即行数发布时间:2022-07-10
下一篇:
03-05-10-Go黑科技之-指针运算发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap