将GoLang的http.ResponseWriter功能扩展到前/后处理响应

时间:2016-07-21 20:28:28

标签: go

我正在尝试编写一个简单的http MiddleWare处理程序来处理http响应。不幸的是,它不起作用,我无法弄清楚我正在犯的错误。任何/所有帮助表示赞赏!

我正在使用Go Gorilla多路复用路由器 以下是代码的说明部分:

import (
    "fmt"
    "log"
    "github.com/gorilla/mux"
)
:
func Start() {
    router := mux.NewRouter()
    router.HandleFunc("/", myHandler)
    :
    log.Fatal(http.ListenAndServe(":8088", Middleware(router)))
}

func myHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "myHandler called")
}
func Middleware(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        neww := NewProcessor(w)
        h.ServeHTTP(neww, r)
    })
}

type Processor struct {
    http.ResponseWriter
}
func (r *Processor) Write(b []byte) (int, error) {
    fmt.Printf("******* Processor writing...")
    log.Print(string(b)) // log it out
    return r.Write(b)    // pass it to the original ResponseWriter
}
func NewProcessor(w http.ResponseWriter) http.ResponseWriter {
    fmt.Printf("******* Creating new Processor...")
    return &Processor{ResponseWriter: w}
}

我得到的输出如下所示(为清楚起见,省略了额外的记录文本):

******* Creating new Processor 
myHandler called

但是,请注意消息" *******处理器写入..."没有显示,暗示"写"功能没有被调用。

需要进行哪些更改才能允许"写"函数被调用?

1 个答案:

答案 0 :(得分:2)

return r.Write(b)导致对处理器Write()方法的无限循环调用。用return r.ResponseWriter.Write(b)替换它修复了错误。

以下是更正后的代码:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", myHandler)
    log.Fatal(http.ListenAndServe(":8088", Middleware(mux)))
}

func myHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "myHandler called")
}

func Middleware(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        new := NewProcessor(w)
        h.ServeHTTP(new, r)
    })
}

type Processor struct {
    http.ResponseWriter
}

func (r *Processor) Write(b []byte) (int, error) {
    log.Print("******* Processor writing...")
    log.Print(string(b)) // log it out
    return r.ResponseWriter.Write(b)    // pass it to the original ResponseWriter
}

func NewProcessor(w http.ResponseWriter) http.ResponseWriter {
    log.Print("******* Creating new Processor...")
    return &Processor{ResponseWriter: w}
}

输出:

2016/07/21 22:59:08 ******* Creating new Processor...
2016/07/21 22:59:08 ******* Processor writing...
2016/07/21 22:59:08 myHandler called