mux源码分析

本文深入分析Go中的mux源码,探讨http服务的运作,特别是路由函数的匹配与处理,包括客户端请求的细节,如客户端的创建与工作原理,以及服务端的响应机制,如ServeMux的请求分发功能。
摘要由CSDN通过智能技术生成

mux源码分析

http服务

http相关的网络服务,我们需要关注的都是客户端请求和服务端应答。在客户端请求(request)的过程中,重要的是路由。在服务端当接收到路由请求的时候,需要通过处理,再进行应答(response)。在接收request的过程中,路由是很重要的,这相当于是一个Multiplexer,Go中有内置的DefaultServerMux,也可以自定义Multiplexer。这里的Multiplexer的目的就是为了找到一个处理器函数(Handler),这样就可以对客户端进行响应了。
 

路由函数

func main() {
  r := mux.NewRouter()
  r.HandleFunc("/", HomeHandler)
  r.HandleFunc("/products", ProductsHandler)
  r.HandleFunc("/articles", ArticlesHandler)
  http.Handle("/", r)
}

 

匹配部分

r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler)
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

读取变量

func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) {
  vars := mux.Vars(r)
  w.WriteHeader(http.StatusOK)
  fmt.Fprintf(w, "Category: %v\n", vars["category"])
}

筛选条件

r.Headers("X-Requested-With", "XMLHttpRequest")
r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
  return r.ProtoMajor == 0
})
r.HandleFunc("/products", ProductsHandler).
	Host("www.example.com").
	Methods("GET").
	Schemes("http")

子路由

r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()
s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

中间件

func loggingMiddleware(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // Do stuff here
    log.Println(r.RequestURI)
    // Call the next handler, which can be another middleware in the chain, or the final handler.
    next.ServeHTTP(w, r)
  })
}

r := mux.NewRouter()
r.HandleFunc("/", handler)
r.Use(loggingMiddleware)

使用 Router 的 HandleFunc 、Host 、 Methods 、 Schemes 、 Headers 等方法会创建一个路由并且为其添加相应类型 matcher,当然你也可以使用 MatcherFunc 来创建自己的 matcher。

gorilla/mux 会查找 Router 下的 Route 列表,找到是否有无匹配的路由,而 Route 会遍历其 matchers 列表来看看是否满足所有的 matchers,只要一个不匹配,则失败。

 

客户端

net/http包在编写golang web应用中有很重要的作用,它主要提供了基于HTTP协议进行工作的client实现和server实现,可用于编写HTTP服务端和客户端。

首先来看一下客户端代码:

// 用http包中默认的Client进行请求(因为没有指定Client)
resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
	url.Values{"key": {"Value"}, "id": {"123"}})


// 用自定义的Client进行请求
client := &http.Client{
	CheckRedirect: redirectPolicyFunc,
}

resp, err := client.Get("http://example.com")
// ...

req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

可以有两种方式,第一种比较直接,用默认即可;第二种比较复杂一点,是分布来完成的。

客户端的定义:

type Client stru
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值