ds342222222 2014-12-22 23:28
浏览 16
已采纳

如果已设置标头,如何使用自定义http处理程序/中间件?

I'm trying to chain HTTP handlers in go to provide some added functionality, like this:

package router

import (
    // snip
    "github.com/gorilla/mux"
    "github.com/gorilla/handlers"
    "net/http"
)

// snip

r := mux.NewRouter()
/* routing code */
var h http.Handler
h = r
if useGzip {
    h = handlers.CompressHandler(h)
}
if useLogFile {
    fn := pathToLog
    accessLog, err := os.OpenFile(fn, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
    if err != nil {
        panic(err)
    }
    h = handlers.CombinedLoggingHandler(accessLog, h)
}

// etc...

The problem is, if any HTTP headers are already set by one of the controllers that the gorilla/mux router points to (for example, w.WriteHeader(404) or w.Header().Set("Content-Type", "application/json")) - this silently breaks any "wrapper" handler trying to set or add its own headers, like the compress handler. I can't see any errors, unless I forgot to catch one somewhere, but the browser gets an invalid response.

Is there any graceful way to deal with this, short of just stashing the headers somewhere and then leaving the final handler to write them? It seems like that would mean rewriting the handlers' code, which I'd love to avoid if at all possible.

  • 写回答

2条回答 默认 最新

  • douqing0713 2014-12-22 23:45
    关注

    Once you call w.WriteHeader(404), the header goes on a wire. So you can't add to it anymore. Best way you can do is to buffer status code and write it at the end of a chain.

    For example, you can provide your own wrapper for http.ResponseWriter that would re-implement WriteHeader() to save status value. Then add method Commit() to actually write it. Call Commit() in the last handler. You have to determine somehow which handler is last, of course.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错
  • ¥15 java python或者任何一种编程语言复刻一个网页
  • ¥20 如何通过代码传输视频到亚马逊平台
  • ¥15 php查询mysql数据库并显示至下拉列表中
  • ¥15 freertos下使用外部中断失效
  • ¥15 输入的char字符转为int类型,不是对应的ascall码,如何才能使之转换为对应ascall码?或者使输入的char字符可以正常与其他字符比较?
  • ¥15 devserver配置完 启动服务 无法访问static上的资源
  • ¥15 解决websocket跟c#客户端通信