Update github.com/gorilla/handlers dependency
Support for exposing the CloseNotifier interface was just recently added to its logging handler wrappers. This is needed for #597. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
0b3b55e723
commit
1788ae4870
5 changed files with 106 additions and 21 deletions
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
|
@ -67,7 +67,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gorilla/handlers",
|
"ImportPath": "github.com/gorilla/handlers",
|
||||||
"Rev": "0e84b7d810c16aed432217e330206be156bafae0"
|
"Rev": "60c7bfde3e33c201519a200a4507a158cc03a17b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gorilla/mux",
|
"ImportPath": "github.com/gorilla/mux",
|
||||||
|
|
2
Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml
generated
vendored
2
Godeps/_workspace/src/github.com/gorilla/handlers/.travis.yml
generated
vendored
|
@ -1,8 +1,8 @@
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.0
|
|
||||||
- 1.1
|
- 1.1
|
||||||
- 1.2
|
- 1.2
|
||||||
- 1.3
|
- 1.3
|
||||||
|
- 1.4
|
||||||
- tip
|
- tip
|
||||||
|
|
52
Godeps/_workspace/src/github.com/gorilla/handlers/README.md
generated
vendored
52
Godeps/_workspace/src/github.com/gorilla/handlers/README.md
generated
vendored
|
@ -1,6 +1,52 @@
|
||||||
gorilla/handlers
|
gorilla/handlers
|
||||||
================
|
================
|
||||||
[![Build Status](https://travis-ci.org/gorilla/handlers.png?branch=master)](https://travis-ci.org/gorilla/handlers)
|
[![GoDoc](https://godoc.org/github.com/gorilla/handlers?status.svg)](https://godoc.org/github.com/gorilla/handlers) [![Build Status](https://travis-ci.org/gorilla/handlers.svg?branch=master)](https://travis-ci.org/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`), including:
|
||||||
|
|
||||||
|
* `LoggingHandler` for logging HTTP requests in the Apache [Common Log
|
||||||
|
Format](http://httpd.apache.org/docs/2.2/logs.html#common).
|
||||||
|
* `CombinedLoggingHandler` for logging HTTP requests in the Apache [Combined Log
|
||||||
|
Format](http://httpd.apache.org/docs/2.2/logs.html#combined) 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).
|
||||||
|
|
||||||
|
Other handlers are documented [on the Gorilla
|
||||||
|
website](http://www.gorillatoolkit.org/pkg/handlers).
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
A simple example using `handlers.LoggingHandler` and `handlers.CompressHandler`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/gorilla/handlers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := http.NewServeMux()
|
||||||
|
|
||||||
|
// Only log requests to our admin dashboard to stdout
|
||||||
|
r.Handle("/admin", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(ShowAdminDashboard)))
|
||||||
|
r.HandleFunc("/", ShowIndex)
|
||||||
|
|
||||||
|
// Wrap our server with our gzip handler to gzip compress all responses.
|
||||||
|
http.ListenAndServe(":8000", handlers.CompressHandler(r))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
BSD licensed. See the included LICENSE file for details.
|
||||||
|
|
||||||
*Warning:* This package is a work in progress and the APIs are subject to change.
|
|
||||||
Consider this a v0 project.
|
|
||||||
|
|
17
Godeps/_workspace/src/github.com/gorilla/handlers/compress.go
generated
vendored
17
Godeps/_workspace/src/github.com/gorilla/handlers/compress.go
generated
vendored
|
@ -15,6 +15,7 @@ import (
|
||||||
type compressResponseWriter struct {
|
type compressResponseWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
|
http.Hijacker
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *compressResponseWriter) Header() http.Header {
|
func (w *compressResponseWriter) Header() http.Header {
|
||||||
|
@ -30,6 +31,8 @@ func (w *compressResponseWriter) Write(b []byte) (int, error) {
|
||||||
return w.Writer.Write(b)
|
return w.Writer.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompressHandler gzip compresses HTTP responses for clients that support it
|
||||||
|
// via the 'Accept-Encoding' header.
|
||||||
func CompressHandler(h http.Handler) http.Handler {
|
func CompressHandler(h http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
L:
|
L:
|
||||||
|
@ -42,10 +45,17 @@ func CompressHandler(h http.Handler) http.Handler {
|
||||||
gw := gzip.NewWriter(w)
|
gw := gzip.NewWriter(w)
|
||||||
defer gw.Close()
|
defer gw.Close()
|
||||||
|
|
||||||
|
h, hok := w.(http.Hijacker)
|
||||||
|
if !hok { /* w is not Hijacker... oh well... */
|
||||||
|
h = nil
|
||||||
|
}
|
||||||
|
|
||||||
w = &compressResponseWriter{
|
w = &compressResponseWriter{
|
||||||
Writer: gw,
|
Writer: gw,
|
||||||
ResponseWriter: w,
|
ResponseWriter: w,
|
||||||
|
Hijacker: h,
|
||||||
}
|
}
|
||||||
|
|
||||||
break L
|
break L
|
||||||
case "deflate":
|
case "deflate":
|
||||||
w.Header().Set("Content-Encoding", "deflate")
|
w.Header().Set("Content-Encoding", "deflate")
|
||||||
|
@ -54,10 +64,17 @@ func CompressHandler(h http.Handler) http.Handler {
|
||||||
fw, _ := flate.NewWriter(w, flate.DefaultCompression)
|
fw, _ := flate.NewWriter(w, flate.DefaultCompression)
|
||||||
defer fw.Close()
|
defer fw.Close()
|
||||||
|
|
||||||
|
h, hok := w.(http.Hijacker)
|
||||||
|
if !hok { /* w is not Hijacker... oh well... */
|
||||||
|
h = nil
|
||||||
|
}
|
||||||
|
|
||||||
w = &compressResponseWriter{
|
w = &compressResponseWriter{
|
||||||
Writer: fw,
|
Writer: fw,
|
||||||
ResponseWriter: w,
|
ResponseWriter: w,
|
||||||
|
Hijacker: h,
|
||||||
}
|
}
|
||||||
|
|
||||||
break L
|
break L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
54
Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go
generated
vendored
54
Godeps/_workspace/src/github.com/gorilla/handlers/handlers.go
generated
vendored
|
@ -2,9 +2,6 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
/*
|
|
||||||
Package handlers is a collection of handlers for use with Go's net/http package.
|
|
||||||
*/
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -29,7 +26,7 @@ import (
|
||||||
// available methods.
|
// available methods.
|
||||||
//
|
//
|
||||||
// If the request's method doesn't match any of its keys the handler responds with
|
// If the request's method doesn't match any of its keys the handler responds with
|
||||||
// a status of 406, Method not allowed and sets the Allow header to a comma-separated list
|
// a status of 405, Method not allowed and sets the Allow header to a comma-separated list
|
||||||
// of available methods.
|
// of available methods.
|
||||||
type MethodHandler map[string]http.Handler
|
type MethodHandler map[string]http.Handler
|
||||||
|
|
||||||
|
@ -65,12 +62,7 @@ type combinedLoggingHandler struct {
|
||||||
|
|
||||||
func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
var logger loggingResponseWriter
|
logger := makeLogger(w)
|
||||||
if _, ok := w.(http.Hijacker); ok {
|
|
||||||
logger = &hijackLogger{responseLogger: responseLogger{w: w}}
|
|
||||||
} else {
|
|
||||||
logger = &responseLogger{w: w}
|
|
||||||
}
|
|
||||||
url := *req.URL
|
url := *req.URL
|
||||||
h.handler.ServeHTTP(logger, req)
|
h.handler.ServeHTTP(logger, req)
|
||||||
writeLog(h.writer, req, url, t, logger.Status(), logger.Size())
|
writeLog(h.writer, req, url, t, logger.Status(), logger.Size())
|
||||||
|
@ -78,19 +70,31 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
func (h combinedLoggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (h combinedLoggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
var logger loggingResponseWriter
|
logger := makeLogger(w)
|
||||||
if _, ok := w.(http.Hijacker); ok {
|
|
||||||
logger = &hijackLogger{responseLogger: responseLogger{w: w}}
|
|
||||||
} else {
|
|
||||||
logger = &responseLogger{w: w}
|
|
||||||
}
|
|
||||||
url := *req.URL
|
url := *req.URL
|
||||||
h.handler.ServeHTTP(logger, req)
|
h.handler.ServeHTTP(logger, req)
|
||||||
writeCombinedLog(h.writer, req, url, t, logger.Status(), logger.Size())
|
writeCombinedLog(h.writer, req, url, t, logger.Status(), logger.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeLogger(w http.ResponseWriter) loggingResponseWriter {
|
||||||
|
var logger loggingResponseWriter = &responseLogger{w: w}
|
||||||
|
if _, ok := w.(http.Hijacker); ok {
|
||||||
|
logger = &hijackLogger{responseLogger{w: w}}
|
||||||
|
}
|
||||||
|
h, ok1 := logger.(http.Hijacker)
|
||||||
|
c, ok2 := w.(http.CloseNotifier)
|
||||||
|
if ok1 && ok2 {
|
||||||
|
return hijackCloseNotifier{logger, h, c}
|
||||||
|
}
|
||||||
|
if ok2 {
|
||||||
|
return &closeNotifyWriter{logger, c}
|
||||||
|
}
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
type loggingResponseWriter interface {
|
type loggingResponseWriter interface {
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
|
http.Flusher
|
||||||
Status() int
|
Status() int
|
||||||
Size() int
|
Size() int
|
||||||
}
|
}
|
||||||
|
@ -130,6 +134,13 @@ func (l *responseLogger) Size() int {
|
||||||
return l.size
|
return l.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *responseLogger) Flush() {
|
||||||
|
f, ok := l.w.(http.Flusher)
|
||||||
|
if ok {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type hijackLogger struct {
|
type hijackLogger struct {
|
||||||
responseLogger
|
responseLogger
|
||||||
}
|
}
|
||||||
|
@ -144,6 +155,17 @@ func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
return conn, rw, err
|
return conn, rw, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type closeNotifyWriter struct {
|
||||||
|
loggingResponseWriter
|
||||||
|
http.CloseNotifier
|
||||||
|
}
|
||||||
|
|
||||||
|
type hijackCloseNotifier struct {
|
||||||
|
loggingResponseWriter
|
||||||
|
http.Hijacker
|
||||||
|
http.CloseNotifier
|
||||||
|
}
|
||||||
|
|
||||||
const lowerhex = "0123456789abcdef"
|
const lowerhex = "0123456789abcdef"
|
||||||
|
|
||||||
func appendQuoted(buf []byte, s string) []byte {
|
func appendQuoted(buf []byte, s string) []byte {
|
||||||
|
|
Loading…
Reference in a new issue