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) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?