go get请求 404 not found_Go实战--使用之gorilla/handlers

whatever
生命不止,继续 go go go !!!

之前介绍过:
Go实战–Gorilla web toolkit使用之gorilla/sessions(iris+sessions)
Go实战–Gorilla web toolkit使用之gorilla/context

今天,继续跟大家一起学习gorilla/handlers,但是关于golang中http中间件的问题,我们之后会专门详细的介绍。

d79fa7d25e9786acd39544bd173985d6.png

gorilla/handlers

网站:
http://www.gorillatoolkit.org/pkg/handlers

获取:
go get github.com/gorilla/handlers

简介:
Package handlers is a collection of handlers (aka “HTTP middleware”) for use with Go’s net/http package (or any framework supporting http.Handler).

The package includes handlers for logging in standardised formats, compressing HTTP responses, validating content types and other useful tools for manipulating requests and responses.

API:

07e25d230f09b034fda7a46ae6a7de9a.png

LoggingHandler
for logging HTTP requests in the Apache Common Log Format.

CombinedLoggingHandler
for logging HTTP requests in the Apache Combined Log Format commonly used by both Apache and nginx.

CompressHandler
for gzipping responses.

ContentTypeHandler
for validating requests against a list of accepted content types.

MethodHandler
for matching HTTP methods against handlers in a map[string]http.Handler

ProxyHeaders
for populating r.RemoteAddr and r.URL.Scheme based on the X-Forwarded-For, X-Real-IP, X-Forwarded-Proto and RFC7239 Forwarded headers when running a Go server behind a HTTP reverse proxy.

CanonicalHost
for re-directing to the preferred host when handling multiple domains (i.e. multiple CNAME aliases).

RecoveryHandler
for recovering from unexpected panics.

应用

LoggingHandler应用
从handlers.LoggingHandler函数的参数我们可以看出,它接受一个Handler,然后返回一个Handler,其实就是对现有的Handler的一次包装,这就是中间件。

import (    "io"    "net/http"    "os"    "github.com/gorilla/handlers")func main() {    http.Handle("/", useLoggingHandler(handler()))    http.ListenAndServe(":1234", nil)}func handler() http.Handler {    return http.HandlerFunc(myHandler)}func myHandler(rw http.ResponseWriter, r *http.Request) {    rw.WriteHeader(http.StatusOK)    io.WriteString(rw, "Hello World")}func useLoggingHandler(next http.Handler) http.Handler {    return handlers.LoggingHandler(os.Stdout, next)}12345678910111213141516171819202122

访问:
curl localhost:1234
我们看日志:
::1 - - [04/Jan/2018:11:46:28 +0800] “GET / HTTP/1.1” 200 11

CombinedLoggingHandler应用
日志格式,这种日志格式输出的日志信息更详细,更全面,比如包含UA等信息,这种格式被称为Apache Combined Log Format。
CombinedLoggingHandler就是为我们提供输出一种这种格式的中间件,使用方式和LoggingHandler一样。

import (    "io"    "net/http"    "os"    "github.com/gorilla/handlers")func main() {    http.Handle("/", useLoggingHandler(handler()))    http.ListenAndServe(":1234", nil)}func handler() http.Handler {    return http.HandlerFunc(myHandler)}func myHandler(rw http.ResponseWriter, r *http.Request) {    rw.WriteHeader(http.StatusOK)    io.WriteString(rw, "Hello World")}func useLoggingHandler(next http.Handler) http.Handler {    return handlers.CombinedLoggingHandler(os.Stdout, next)}12345678910111213141516171819202122

访问:
curl localhost:1234
我们看日志:
::1 - - [04/Jan/2018:13:44:05 +0800] “GET / HTTP/1.1” 200 11 “” “curl/7.51.0”

CompressHandler应用
这是一个压缩response的中间件,支持gzip和deflate压缩。
如果客户端的请求头里包含Accept-Encoding,并且值为gzip或者deflate,该中间件就会压缩返回的response,这样就可以减少response的大小,减少响应的时间。

package mainimport (    "fmt"    "net/http"    "github.com/gorilla/handlers"    "github.com/gorilla/mux")func main() {    r := mux.NewRouter()    r.NotFoundHandler = http.HandlerFunc(NotFoundHandler)    r.HandleFunc("/", HomeHandler)    gzip := handlers.CompressHandler(r)    http.ListenAndServe(":1234", gzip)}func NotFoundHandler(w http.ResponseWriter, r *http.Request) {    w.Header().Set("Content-Type", "text/html; charset=utf-8")    w.WriteHeader(http.StatusNotFound)    fmt.Fprintf(w, "404 - not found")}func HomeHandler(w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "Hello, World!")}123456789101112131415161718192021222324252627
13b45a6f566e4d186689dc0ba31ad3ba.png

CanonicalHost应用

    gorilla := "http://www.gorillatoolkit.org"    rr := httptest.NewRecorder()    r := newRequest("GET", "http://www.example.com/")    testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})    // Test a re-direct: should return a 302 Found.    CanonicalHost(gorilla, http.StatusFound)(testHandler).ServeHTTP(rr, r)    if rr.Code != http.StatusFound {        t.Fatalf("bad status: got %v want %v", rr.Code, http.StatusFound)    }    if rr.Header().Get("Location") != gorilla+r.URL.Path {        t.Fatalf("bad re-direct: got %q want %q", rr.Header().Get("Location"), gorilla+r.URL.Path)    }1234567891011121314151617

Allowing origins using gorilla handlers

package mainimport (    "log"    "net/http"    "os"    "github.com/gorilla/handlers"    "github.com/gorilla/mux")func main() {    router := mux.NewRouter()    log.Fatal(http.ListenAndServe(":8080",        handlers.LoggingHandler(os.Stdout, handlers.CORS(            handlers.AllowedMethods([]string{"POST"}),            handlers.AllowedOrigins([]string{"*"}),            handlers.AllowedHeaders([]string{"X-Requested-With"}))(router))))}1234567891011121314151617181920

命令行:
curl -H “Origin: http://example.com” -H “Access-Control-Request-Method: POST” -H “Access-Control-Request-Headers: X-Requested-With” -X OPTIONS –verbose localhost:8080

* STATE: INIT => CONNECT handle 0x2004a698; line 1407 (connection #-5000)* Rebuilt URL to: localhost:8080/* Added connection 0. The cache now contains 1 members*   Trying ::1...* TCP_NODELAY set* STATE: CONNECT => WAITCONNECT handle 0x2004a698; line 1460 (connection #0)* Connected to localhost (::1) port 8080 (#0)* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x2004a698; line 1567 (connection #0)* Marked for [keep alive]: HTTP default* STATE: SENDPROTOCONNECT => DO handle 0x2004a698; line 1585 (connection #0)> OPTIONS / HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.51.0> Accept: */*> Origin: http://example.com> Access-Control-Request-Method: POST> Access-Control-Request-Headers: X-Requested-With>* STATE: DO => DO_DONE handle 0x2004a698; line 1664 (connection #0)* STATE: DO_DONE => WAITPERFORM handle 0x2004a698; line 1791 (connection #0)* STATE: WAITPERFORM => PERFORM handle 0x2004a698; line 1801 (connection #0)* HTTP 1.1 or later with persistent connection, pipelining supported< HTTP/1.1 200 OK< Access-Control-Allow-Headers: X-Requested-With< Access-Control-Allow-Origin: http://example.com< Date: Thu, 04 Jan 2018 05:47:31 GMT< Content-Length: 0< Content-Type: text/plain; charset=utf-8 DONE handle 0x2004a698; line 1965 (connection #0)* multi_done* Curl_http_done: called premature == 0* Connection #0 to host localhost left intact* Expire cleared12345678910111213141516171819202122232425262728293031323334

中间件写入日志文件

package mainimport (    "fmt"    "log"    "net/http"    "os"    "github.com/gorilla/handlers")func index(w http.ResponseWriter, r *http.Request) {    log.Println("Execute index Handler")    fmt.Fprintf(w, "Welcome!")}func about(w http.ResponseWriter, r *http.Request) {    log.Println("Execute message Handler")    fmt.Fprintf(w, "Message Go!")}func main() {    indexHandler := http.HandlerFunc(index)    aboutHandler := http.HandlerFunc(about)    logFile, err := os.OpenFile("server.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)    if err != nil {        panic(err)    }    http.Handle("/", handlers.LoggingHandler(logFile, handlers.CompressHandler(indexHandler)))    http.Handle("about", handlers.LoggingHandler(logFile, handlers.CompressHandler(aboutHandler)))    server := &http.Server{        Addr: ":8080",    }    log.Println("Listening...")    server.ListenAndServe()}123456789101112131415161718192021222324252627282930313233343536373839
17fab4cd24ce163b6f2783f55920a19e.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值