英文:
How to use gorilla mux with http.TimeoutHandler
问题
在使用Go编写的HTTP服务器中,我使用gorilla/mux进行路由。我想使用http.TimeoutHandler
(和/或其他"中间件"),但我不知道在哪里插入它们。
为了明确起见:
- 我通过
gorillaMux := mux.NewRouter()
创建一个新的路由器。 - 通过像
gorillaMux.HandleFunc("/", rootHandler)
这样的调用添加我的路由。 - 我通过
server := &http.Server{Addr:":1234"}
和server.ListenAndServe()
创建服务器。
我应该在哪里插入http.TimeoutHandler
或其他任何中间件?
英文:
In an HTTP server written in go, I use gorilla/mux for routing,
I want to use http.TimeoutHandler
(and/or other "middleware") but I can't understand where I can fit them.
To make it clear:
- I create a new Router by
gorillaMux := mux.NewRouter()
- add my routes by calls like
gorillaMux.HandleFunc("/", rootHandler)
- I create the server by
server := &http.Server{Addr:":1234"}
andserver.ListenAndServe()
Where can I insert the http.TimeoutHandler
or any other middleware for that matter?
答案1
得分: 11
以下是翻译好的内容:
这是你可以完成这个任务的方法:
package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
"time"
)
func rootHandler(w http.ResponseWriter, r *http.Request) {
time.Sleep(5 * time.Second)
fmt.Fprintf(w, "Hello!")
}
func main() {
mux := mux.NewRouter()
mux.HandleFunc("/", rootHandler)
muxWithMiddlewares := http.TimeoutHandler(mux, time.Second*3, "Timeout!")
http.ListenAndServe(":8080", muxWithMiddlewares)
}
如果你有多个HTTP处理程序,你可以将它们堆叠起来:
// 这只是一个合成且不太美观的示例,但它说明了处理程序的工作原理
muxWithMiddlewares := http.StripPrefix("/api", http.TimeoutHandler(mux, time.Second*3, "Timeout!"))
英文:
Here is how you can do this:
package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
"time"
)
func rootHandler(w http.ResponseWriter, r *http.Request) {
time.Sleep(5 * time.Second)
fmt.Fprintf(w, "Hello!")
}
func main() {
mux := mux.NewRouter()
mux.HandleFunc("/", rootHandler)
muxWithMiddlewares := http.TimeoutHandler(mux, time.Second*3, "Timeout!")
http.ListenAndServe(":8080", muxWithMiddlewares)
}
If you have more than one HTTP handler, you can stack them up:
// this is quite synthetic and ugly example, but it illustrates how Handlers works
muxWithMiddlewares := http.StripPrefix("/api", http.TimeoutHandler(mux, time.Second*3, "Timeout!"))
答案2
得分: 2
这个解决方案没有使用TimeoutHandler。我在这里发布这个解决方案,以防有人想要对服务器超时进行精细控制。如果需要的话,这个替代方案允许定义IdleTimeout和RequestHeaderTimeout。在这个示例中,我同时使用了gorilla/mux和gorilla/handlers。希望能对你有所帮助。
// ReadTimeout是服务器对客户端HTTP请求施加的时间限制,从初始连接到整个请求体被读取完成。
// [接受] --> [TLS握手] --> [请求头] --> [请求体] --> [响应]
// WriteTimeout是服务器对通过HTTP连接到服务器的客户端施加的时间限制,从服务器完成读取请求头到完成写入响应的时间。
// [接受] --> [TLS握手] --> [请求头] --> [请求体] --> [响应]
func main() {
mux := router.EpicMux()
srv := &http.Server{
Handler: handlers.LoggingHandler(os.Stdout, mux),
Addr: "localhost:8080",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
func EpicMux() http.Handler {
r := mux.NewRouter()
r.HandleFunc("/", BaseURLRouter).Methods(http.MethodGet)
// 创建v1和v2的子路由
v1 := r.PathPrefix("api/v1").Subrouter()
// 将处理程序注册到相应的版本
v1.HandleFunc("/person", PersonHandlerV1).Methods(http.MethodPost)
v2 := r.PathPrefix("api/v2").Subrouter()
v2.HandleFunc("/person", PersonHandlerV2).Methods(http.MethodPost)
return r
}
英文:
This solution does not answer the use TimeoutHandler. I posted this here in case anybody wants fine-grain control of their server timeout. This alternative will allow one to define the IdleTimeout and RequestHeaderTimeout if necessary. I am using both gorilla/mux and gorilla/handlers in this example. Hope it helps.
// ReadTimeout is a timing constraint on the client http request imposed by the server from the moment
// of initial connection up to the time the entire request body has been read.
// [Accept] --> [TLS Handshake] --> [Request Headers] --> [Request Body] --> [Response]
// WriteTimeout is a time limit imposed on client connecting to the server via http from the
// time the server has completed reading the request header up to the time it has finished writing the response.
// [Accept] --> [TLS Handshake] --> [Request Headers] --> [Request Body] --> [Response]
func main() {
mux := router.EpicMux()
srv := &http.Server{
Handler: handlers.LoggingHandler(os.Stdout, mux),
Addr: "localhost:8080",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
func EpicMux() http.Handler {
r := mux.NewRouter()
r.HandleFunc("/", BaseURLRouter).Methods(http.MethodGet)
// create the subroutes for v1 and v2
v1 := r.PathPrefix("api/v1").Subrouter()
// register handlers to appropriate version
v1.HandleFunc("/person", PersonHandlerV1).Methods(http.MethodPost)
v2 := r.PathPrefix("api/v2").Subrouter()
v2.HandleFunc("/person", PersonHandlerV2).Methods(http.MethodPost)
return r
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论