Golang 自制Http中间件

1. 原理部分

1.1. 类型形式

package main

import (
    "net/http"
)

type SingleHost struct {
    handler http.Handler
    allowedHost string
}

func (this *SingleHost) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    println(r.Host)
    // 只允许访问域名 == allowedHost 定义的域名
    if r.Host == this.allowedHost {
        this.handler.ServeHTTP(w, r)
    } else {
        w.WriteHeader(403)
    }
}

func myHandler(w http.ResponseWriter, r *http.Request)  {
    w.Write([]byte("hello world!"))
}

func main() {
    // 类型形式
    single := &SingleHost{
        handler:     http.HandlerFunc(myHandler),
        // allowedHost: "learnku.net",  // 只允许域名 learnku.net 访问
        allowedHost: "localhost:8888",
    }
    http.ListenAndServe(":8888", single)
}

1.2. 函数形式

package main

import "net/http"

// 返回一个 http.Handler
// allowedHost string 允许范文的域名
func SingleHost(handler http.Handler, allowedHost string) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        println(r.Host)
        // 只允许访问域名 == allowedHost 定义的域名
        if r.Host == allowedHost {
            handler.ServeHTTP(w, r)
        } else {
            w.WriteHeader(403)
        }
    }
    return http.HandlerFunc(fn)
}

func myHandler(w http.ResponseWriter, r *http.Request)  {
    w.Write([]byte("hello world!"))
}

func main()  {
    // 函数形式
    single := SingleHost(http.HandlerFunc(myHandler), "learnku.net")
    http.ListenAndServe(":8888", single)
}

1.3. 追加响应内容

package main

import "net/http"

type AppendMiddleware struct {
    handler http.Handler
    allowedHost string  // 允许访问的域名
}

// 注册一个中间件
func (this *AppendMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hey, this is a middleware !\n"))

    // 只允许访问域名 == allowedHost 定义的域名
    if r.Host == this.allowedHost {
        this.handler.ServeHTTP(w, r)
    } else {
        w.WriteHeader(403)
    }
}

func myHandler(w http.ResponseWriter, r *http.Request)  {
    w.Write([]byte("Hello World!"))
}

func main() {
    middleware := &AppendMiddleware{
        handler: http.HandlerFunc(myHandler),
        allowedHost: "localhost:8888",  // 允许访问的域名
    }
    http.ListenAndServe(":8888", middleware)
}

2. 自定义响应

package main

import (
    "net/http"
    "net/http/httptest"
)

type ModifierMiddleware struct {
    handler http.Handler
}

// 定义中间件
func (this *ModifierMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request)  {
    // 响应请求的时候先虚拟的记录下来,等全部记录完之后 再一起响应到客户端。
    // 1、如果不使用 Recorder 就会直接响应到客户端
    recorder := httptest.NewRecorder()
    // 1.1、传入 recorder(而不是 w ) 将所有的情况都记录下来
    this.handler.ServeHTTP(recorder, r)

    // 2、捕捉到 recorder 中的操作,然后设置到响应流当中
    for key, value := range recorder.Header() {
        w.Header()[key] = value
    }
    // 2.1、Header 其他自定义操作
    w.Header().Set("go-web-foundation", "vip")
    w.WriteHeader(418)
    w.Write([]byte("hi, this is middleware !\n"))

    // 3、将真正的内容返回到客户端
    // 可以理解为这里执行的是 myHandler 函数
    w.Write(recorder.Body.Bytes())
}

// 真正的响应
func myHandler(w http.ResponseWriter, r *http.Request)  {
    w.Write([]byte("Hello World!"))
}

func main() {
    // 自定义响应
    middleware := &ModifierMiddleware{
        handler: http.HandlerFunc(myHandler),
    }
    http.ListenAndServe(":8888", middleware)
}
讨论数量: 0

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!