go语言原生http库分析 (2)
来源:互联网 发布:头皮毛囊炎 知乎 编辑:程序博客网 时间:2024/06/07 21:58
这里我们分析默认的Handler–DefaultServeMux
在所有介绍之前,我们先给出两个类:
type ServeMux struct { mu sync.RWMutex m map[string]muxEntry hosts bool // whether any patterns contain hostnames}type muxEntry struct { explicit bool h Handler pattern string}
ServeMux实现了Handler借口的ServeHTTP函数;我们知道GO语言中,实现了接口的所有函数,则实现该接口
// ServeHTTP dispatches the request to the handler whose// pattern most closely matches the request URL.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)}
。接着我们继续DefaultServeMux,我们在上篇的例子中虽然没有传入Handler对象,但是我们有这样一行代码:
http.HandleFunc("/hello", SayHello)
其实这行代码操作的就是默认的Handler对象DefaultServeMux,为特定的URL设置处理函数。我们看下该函数,具体做了哪些操作:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { DefaultServeMux.HandleFunc(pattern, handler)}
简单粗暴,直接就是调用DefaultServeMux对象的HandleFunc函数,其实DefaultServeMux是一个ServeMux对象:
// NewServeMux allocates and returns a new ServeMux.func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }// DefaultServeMux is the default ServeMux used by Serve.var DefaultServeMux = NewServeMux()
DefaultServeMux对象的HandleFunc函数,也即ServeMux的成员函数:
// HandleFunc registers the handler function for the given pattern.func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { mux.Handle(pattern, HandlerFunc(handler))}
该函数是Handle(pattern, HandlerFunc(handler))的封装:
// Handle registers the handler for the given pattern.// If a handler already exists for pattern, Handle panics.func (mux *ServeMux) Handle(pattern string, handler Handler) { mux.mu.Lock() defer mux.mu.Unlock() if pattern == "" { panic("http: invalid pattern " + pattern) } if handler == nil { panic("http: nil handler") } if mux.m[pattern].explicit { panic("http: multiple registrations for " + pattern) } mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern} if pattern[0] != '/' { mux.hosts = true } // Helpful behavior: // If pattern is /tree/, insert an implicit permanent redirect for /tree. // It can be overridden by an explicit registration. n := len(pattern) if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit { // If pattern contains a host name, strip it and use remaining // path for redirect. path := pattern if pattern[0] != '/' { // In pattern, at least the last character is a '/', so // strings.Index can't be -1. path = pattern[strings.Index(pattern, "/"):] } url := &url.URL{Path: path} mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern} }}
其实简要之,就是构建一个pattern和函数Handler的map。看来原生库中实现了路由非常简单,就是一张map,所以实际应用中局限性比较大。实际应用中,我们往往利用其它路由实现,有必要也可能自己实现。
0 0
- go语言原生http库分析 (2)
- go语言原生http库分析(1)
- GO语言HTTP代理服务器
- go http分析
- Go语言分析
- go语言 通过http包搭建简单web服务器 对http包源码的略微分析
- Go语言net/http 解读.
- go语言的http包
- go 原生http web 服务跨域restful api 写法
- 【Go】原生http get和post请求框架
- Android 原生应用开发得到Go语言支持
- golang讲解(go语言)标准库分析之strings
- go web编程-原生库实现
- GO 语言 http 服务端(简单实例)
- Go语言 简单的http服务器示例
- Go语言 如果实现http重连?
- Go语言Http Server源码阅读
- Go语言使用http下载文件
- Android MediaRecorder视频录制
- RJ45和RJ11接插件定义和有关规定
- redis之sds
- 变量的存储类别
- Linux service相关
- go语言原生http库分析 (2)
- Word2Vec Sent2Vec
- C#打印DataGridView数据
- Lucene的增删查改
- Ubuntu 16.04 SQLite3工具sqlitebrowser无法输入中文的解决方法
- 暑假复习计划
- uva-536 二叉树重建
- spring 注解 事务,声明事务共存的情况下,先后顺序 order
- 矩阵求导公式