Vendor code using godep.

For 3rd parties building binary packages, and for build consistency in
general, it is very helpful to have the same set of dependencies at
any time the product is built.

See [tools/godep](https://github.com/tools/godep) for further details.
This commit is contained in:
Stefan Bethke 2017-10-09 20:05:32 +02:00
parent e748910b6a
commit b663783717
286 changed files with 156785 additions and 0 deletions

1
vendor/github.com/codegangsta/negroni/.gitignore generated vendored Normal file
View file

@ -0,0 +1 @@
/coverage.txt

27
vendor/github.com/codegangsta/negroni/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,27 @@
language: go
sudo: false
dist: trusty
go:
- 1.x
- 1.2.x
- 1.3.x
- 1.4.x
- 1.5.x
- 1.6.x
- 1.7.x
- 1.8.x
- master
before_install:
- find "${GOPATH%%:*}" -name '*.a' -delete
- rm -rf "${GOPATH%%:*}/src/golang.org"
- go get golang.org/x/tools/cover
- go get golang.org/x/tools/cmd/cover
script:
- go test -race -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s "https://codecov.io/bash")

37
vendor/github.com/codegangsta/negroni/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,37 @@
# Change Log
**ATTN**: This project uses [semantic versioning](http://semver.org/).
## [Unreleased]
### Added
- `Recovery.ErrorHandlerFunc` for custom error handling during recovery
- `With()` helper for building a new `Negroni` struct chaining handlers from
existing `Negroni` structs
### Fixed
- `Written()` correct returns `false` if no response header has been written
### Changed
- Set default status to `0` in the case that no handler writes status -- was
previously `200` (in 0.2.0, before that it was `0` so this reestablishes that
behavior)
- Catch `panic`s thrown by callbacks provided to the `Recovery` handler
## [0.2.0] - 2016-05-10
### Added
- Support for variadic handlers in `New()`
- Added `Negroni.Handlers()` to fetch all of the handlers for a given chain
- Allowed size in `Recovery` handler was bumped to 8k
- `Negroni.UseFunc` to push another handler onto the chain
### Changed
- Set the status before calling `beforeFuncs` so the information is available to them
- Set default status to `200` in the case that no handler writes status -- was previously `0`
- Panic if `nil` handler is given to `negroni.Use`
## 0.1.0 - 2013-07-22
### Added
- Initial implementation.
[Unreleased]: https://github.com/urfave/negroni/compare/v0.2.0...HEAD
[0.2.0]: https://github.com/urfave/negroni/compare/v0.1.0...v0.2.0

21
vendor/github.com/codegangsta/negroni/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Jeremy Saenz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

546
vendor/github.com/codegangsta/negroni/README.md generated vendored Normal file
View file

@ -0,0 +1,546 @@
# Negroni
[![GoDoc](https://godoc.org/github.com/urfave/negroni?status.svg)](http://godoc.org/github.com/urfave/negroni)
[![Build Status](https://travis-ci.org/urfave/negroni.svg?branch=master)](https://travis-ci.org/urfave/negroni)
[![codebeat](https://codebeat.co/badges/47d320b1-209e-45e8-bd99-9094bc5111e2)](https://codebeat.co/projects/github-com-urfave-negroni)
[![codecov](https://codecov.io/gh/urfave/negroni/branch/master/graph/badge.svg)](https://codecov.io/gh/urfave/negroni)
**Notice:** This is the library formerly known as
`github.com/codegangsta/negroni` -- Github will automatically redirect requests
to this repository, but we recommend updating your references for clarity.
Negroni is an idiomatic approach to web middleware in Go. It is tiny,
non-intrusive, and encourages use of `net/http` Handlers.
If you like the idea of [Martini](https://github.com/go-martini/martini), but
you think it contains too much magic, then Negroni is a great fit.
Language Translations:
* [Deutsch (de_DE)](translations/README_de_de.md)
* [Português Brasileiro (pt_BR)](translations/README_pt_br.md)
* [简体中文 (zh_cn)](translations/README_zh_cn.md)
* [繁體中文 (zh_tw)](translations/README_zh_tw.md)
* [日本語 (ja_JP)](translations/README_ja_JP.md)
* [Français (fr_FR)](translations/README_fr_FR.md)
## Getting Started
After installing Go and setting up your
[GOPATH](http://golang.org/doc/code.html#GOPATH), create your first `.go` file.
We'll call it `server.go`.
<!-- { "interrupt": true } -->
``` go
package main
import (
"fmt"
"net/http"
"github.com/urfave/negroni"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
})
n := negroni.Classic() // Includes some default middlewares
n.UseHandler(mux)
http.ListenAndServe(":3000", n)
}
```
Then install the Negroni package (**NOTE**: &gt;= **go 1.1** is required):
```
go get github.com/urfave/negroni
```
Then run your server:
```
go run server.go
```
You will now have a Go `net/http` webserver running on `localhost:3000`.
### Packaging
If you are on Debian, `negroni` is also available as [a
package](https://packages.debian.org/sid/golang-github-urfave-negroni-dev) that
you can install via `apt install golang-github-urfave-negroni-dev` (at the time
of writing, it is in the `sid` repositories).
## Is Negroni a Framework?
Negroni is **not** a framework. It is a middleware-focused library that is
designed to work directly with `net/http`.
## Routing?
Negroni is BYOR (Bring your own Router). The Go community already has a number
of great http routers available, and Negroni tries to play well with all of them
by fully supporting `net/http`. For instance, integrating with [Gorilla Mux]
looks like so:
``` go
router := mux.NewRouter()
router.HandleFunc("/", HomeHandler)
n := negroni.New(Middleware1, Middleware2)
// Or use a middleware with the Use() function
n.Use(Middleware3)
// router goes last
n.UseHandler(router)
http.ListenAndServe(":3001", n)
```
## `negroni.Classic()`
`negroni.Classic()` provides some default middleware that is useful for most
applications:
* [`negroni.Recovery`](#recovery) - Panic Recovery Middleware.
* [`negroni.Logger`](#logger) - Request/Response Logger Middleware.
* [`negroni.Static`](#static) - Static File serving under the "public"
directory.
This makes it really easy to get started with some useful features from Negroni.
## Handlers
Negroni provides a bidirectional middleware flow. This is done through the
`negroni.Handler` interface:
``` go
type Handler interface {
ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}
```
If a middleware hasn't already written to the `ResponseWriter`, it should call
the next `http.HandlerFunc` in the chain to yield to the next middleware
handler. This can be used for great good:
``` go
func MyMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
// do some stuff before
next(rw, r)
// do some stuff after
}
```
And you can map it to the handler chain with the `Use` function:
``` go
n := negroni.New()
n.Use(negroni.HandlerFunc(MyMiddleware))
```
You can also map plain old `http.Handler`s:
``` go
n := negroni.New()
mux := http.NewServeMux()
// map your routes
n.UseHandler(mux)
http.ListenAndServe(":3000", n)
```
## `With()`
Negroni has a convenience function called `With`. `With` takes one or more
`Handler` instances and returns a new `Negroni` with the combination of the
receiver's handlers and the new handlers.
```go
// middleware we want to reuse
common := negroni.New()
common.Use(MyMiddleware1)
common.Use(MyMiddleware2)
// `specific` is a new negroni with the handlers from `common` combined with the
// the handlers passed in
specific := common.With(
SpecificMiddleware1,
SpecificMiddleware2
)
```
## `Run()`
Negroni has a convenience function called `Run`. `Run` takes an addr string
identical to [`http.ListenAndServe`](https://godoc.org/net/http#ListenAndServe).
<!-- { "interrupt": true } -->
``` go
package main
import (
"github.com/urfave/negroni"
)
func main() {
n := negroni.Classic()
n.Run(":8080")
}
```
If no address is provided, the `PORT` environment variable is used instead.
If the `PORT` environment variable is not defined, the default address will be used.
See [Run](https://godoc.org/github.com/urfave/negroni#Negroni.Run) for a complete description.
In general, you will want to use `net/http` methods and pass `negroni` as a
`Handler`, as this is more flexible, e.g.:
<!-- { "interrupt": true } -->
``` go
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/urfave/negroni"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
})
n := negroni.Classic() // Includes some default middlewares
n.UseHandler(mux)
s := &http.Server{
Addr: ":8080",
Handler: n,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
}
```
## Route Specific Middleware
If you have a route group of routes that need specific middleware to be
executed, you can simply create a new Negroni instance and use it as your route
handler.
``` go
router := mux.NewRouter()
adminRoutes := mux.NewRouter()
// add admin routes here
// Create a new negroni for the admin middleware
router.PathPrefix("/admin").Handler(negroni.New(
Middleware1,
Middleware2,
negroni.Wrap(adminRoutes),
))
```
If you are using [Gorilla Mux], here is an example using a subrouter:
``` go
router := mux.NewRouter()
subRouter := mux.NewRouter().PathPrefix("/subpath").Subrouter().StrictSlash(true)
subRouter.HandleFunc("/", someSubpathHandler) // "/subpath/"
subRouter.HandleFunc("/:id", someSubpathHandler) // "/subpath/:id"
// "/subpath" is necessary to ensure the subRouter and main router linkup
router.PathPrefix("/subpath").Handler(negroni.New(
Middleware1,
Middleware2,
negroni.Wrap(subRouter),
))
```
`With()` can be used to eliminate redundancy for middlewares shared across
routes.
``` go
router := mux.NewRouter()
apiRoutes := mux.NewRouter()
// add api routes here
webRoutes := mux.NewRouter()
// add web routes here
// create common middleware to be shared across routes
common := negroni.New(
Middleware1,
Middleware2,
)
// create a new negroni for the api middleware
// using the common middleware as a base
router.PathPrefix("/api").Handler(common.With(
APIMiddleware1,
negroni.Wrap(apiRoutes),
))
// create a new negroni for the web middleware
// using the common middleware as a base
router.PathPrefix("/web").Handler(common.With(
WebMiddleware1,
negroni.Wrap(webRoutes),
))
```
## Bundled Middleware
### Static
This middleware will serve files on the filesystem. If the files do not exist,
it proxies the request to the next middleware. If you want the requests for
non-existent files to return a `404 File Not Found` to the user you should look
at using [http.FileServer](https://golang.org/pkg/net/http/#FileServer) as
a handler.
Example:
<!-- { "interrupt": true } -->
``` go
package main
import (
"fmt"
"net/http"
"github.com/urfave/negroni"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
})
// Example of using a http.FileServer if you want "server-like" rather than "middleware" behavior
// mux.Handle("/public", http.FileServer(http.Dir("/home/public")))
n := negroni.New()
n.Use(negroni.NewStatic(http.Dir("/tmp")))
n.UseHandler(mux)
http.ListenAndServe(":3002", n)
}
```
Will serve files from the `/tmp` directory first, but proxy calls to the next
handler if the request does not match a file on the filesystem.
### Recovery
This middleware catches `panic`s and responds with a `500` response code. If
any other middleware has written a response code or body, this middleware will
fail to properly send a 500 to the client, as the client has already received
the HTTP response code. Additionally, an `ErrorHandlerFunc` can be attached
to report 500's to an error reporting service such as Sentry or Airbrake.
Example:
<!-- { "interrupt": true } -->
``` go
package main
import (
"net/http"
"github.com/urfave/negroni"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
panic("oh no")
})
n := negroni.New()
n.Use(negroni.NewRecovery())
n.UseHandler(mux)
http.ListenAndServe(":3003", n)
}
```
Will return a `500 Internal Server Error` to each request. It will also log the
stack traces as well as print the stack trace to the requester if `PrintStack`
is set to `true` (the default).
Example with error handler:
``` go
package main
import (
"net/http"
"github.com/urfave/negroni"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
panic("oh no")
})
n := negroni.New()
recovery := negroni.NewRecovery()
recovery.ErrorHandlerFunc = reportToSentry
n.Use(recovery)
n.UseHandler(mux)
http.ListenAndServe(":3003", n)
}
func reportToSentry(error interface{}) {
// write code here to report error to Sentry
}
```
The middleware simply output the informations on STDOUT by default.
You can customize the output process by using the `SetFormatter()` function.
You can use also the `HTMLPanicFormatter` to display a pretty HTML when a crash occurs.
<!-- { "interrupt": true } -->
``` go
package main
import (
"net/http"
"github.com/urfave/negroni"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
panic("oh no")
})
n := negroni.New()
recovery := negroni.NewRecovery()
recovery.Formatter = &negroni.HTMLPanicFormatter{}
n.Use(recovery)
n.UseHandler(mux)
http.ListenAndServe(":3003", n)
}
```
## Logger
This middleware logs each incoming request and response.
Example:
<!-- { "interrupt": true } -->
``` go
package main
import (
"fmt"
"net/http"
"github.com/urfave/negroni"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
})
n := negroni.New()
n.Use(negroni.NewLogger())
n.UseHandler(mux)
http.ListenAndServe(":3004", n)
}
```
Will print a log similar to:
```
[negroni] 2017-10-04T14:56:25+02:00 | 200 | 378µs | localhost:3004 | GET /
```
on each request.
You can also set your own log format by calling the `SetFormat` function. The format is a template string with fields as mentioned in the `LoggerEntry` struct. So, as an example -
```go
l.SetFormat("[{{.Status}} {{.Duration}}] - {{.Request.UserAgent}}")
```
will show something like - `[200 18.263µs] - Go-User-Agent/1.1 `
## Third Party Middleware
Here is a current list of Negroni compatible middlware. Feel free to put up a PR
linking your middleware if you have built one:
| Middleware | Author | Description |
| -----------|--------|-------------|
| [authz](https://github.com/casbin/negroni-authz) | [Yang Luo](https://github.com/hsluoyz) | ACL, RBAC, ABAC Authorization middlware based on [Casbin](https://github.com/casbin/casbin) |
| [binding](https://github.com/mholt/binding) | [Matt Holt](https://github.com/mholt) | Data binding from HTTP requests into structs |
| [cloudwatch](https://github.com/cvillecsteele/negroni-cloudwatch) | [Colin Steele](https://github.com/cvillecsteele) | AWS cloudwatch metrics middleware |
| [cors](https://github.com/rs/cors) | [Olivier Poitrey](https://github.com/rs) | [Cross Origin Resource Sharing](http://www.w3.org/TR/cors/) (CORS) support |
| [csp](https://github.com/awakenetworks/csp) | [Awake Networks](https://github.com/awakenetworks) | [Content Security Policy](https://www.w3.org/TR/CSP2/) (CSP) support |
| [delay](https://github.com/jeffbmartinez/delay) | [Jeff Martinez](https://github.com/jeffbmartinez) | Add delays/latency to endpoints. Useful when testing effects of high latency |
| [New Relic Go Agent](https://github.com/yadvendar/negroni-newrelic-go-agent) | [Yadvendar Champawat](https://github.com/yadvendar) | Official [New Relic Go Agent](https://github.com/newrelic/go-agent) (currently in beta) |
| [gorelic](https://github.com/jingweno/negroni-gorelic) | [Jingwen Owen Ou](https://github.com/jingweno) | New Relic agent for Go runtime |
| [Graceful](https://github.com/tylerb/graceful) | [Tyler Bunnell](https://github.com/tylerb) | Graceful HTTP Shutdown |
| [gzip](https://github.com/phyber/negroni-gzip) | [phyber](https://github.com/phyber) | GZIP response compression |
| [JWT Middleware](https://github.com/auth0/go-jwt-middleware) | [Auth0](https://github.com/auth0) | Middleware checks for a JWT on the `Authorization` header on incoming requests and decodes it|
| [logrus](https://github.com/meatballhat/negroni-logrus) | [Dan Buch](https://github.com/meatballhat) | Logrus-based logger |
| [oauth2](https://github.com/goincremental/negroni-oauth2) | [David Bochenski](https://github.com/bochenski) | oAuth2 middleware |
| [onthefly](https://github.com/xyproto/onthefly) | [Alexander Rødseth](https://github.com/xyproto) | Generate TinySVG, HTML and CSS on the fly |
| [permissions2](https://github.com/xyproto/permissions2) | [Alexander Rødseth](https://github.com/xyproto) | Cookies, users and permissions |
| [prometheus](https://github.com/zbindenren/negroni-prometheus) | [Rene Zbinden](https://github.com/zbindenren) | Easily create metrics endpoint for the [prometheus](http://prometheus.io) instrumentation tool |
| [render](https://github.com/unrolled/render) | [Cory Jacobsen](https://github.com/unrolled) | Render JSON, XML and HTML templates |
| [RestGate](https://github.com/pjebs/restgate) | [Prasanga Siripala](https://github.com/pjebs) | Secure authentication for REST API endpoints |
| [secure](https://github.com/unrolled/secure) | [Cory Jacobsen](https://github.com/unrolled) | Middleware that implements a few quick security wins |
| [sessions](https://github.com/goincremental/negroni-sessions) | [David Bochenski](https://github.com/bochenski) | Session Management |
| [stats](https://github.com/thoas/stats) | [Florent Messa](https://github.com/thoas) | Store information about your web application (response time, etc.) |
| [VanGoH](https://github.com/auroratechnologies/vangoh) | [Taylor Wrobel](https://github.com/twrobel3) | Configurable [AWS-Style](http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) HMAC authentication middleware |
| [xrequestid](https://github.com/pilu/xrequestid) | [Andrea Franz](https://github.com/pilu) | Middleware that assigns a random X-Request-Id header to each request |
| [mgo session](https://github.com/joeljames/nigroni-mgo-session) | [Joel James](https://github.com/joeljames) | Middleware that handles creating and closing mgo sessions per request |
| [digits](https://github.com/bamarni/digits) | [Bilal Amarni](https://github.com/bamarni) | Middleware that handles [Twitter Digits](https://get.digits.com/) authentication |
## Examples
[Alexander Rødseth](https://github.com/xyproto) created
[mooseware](https://github.com/xyproto/mooseware), a skeleton for writing a
Negroni middleware handler.
[Prasanga Siripala](https://github.com/pjebs) created an effective skeleton structure for web-based Go/Negroni projects: [Go-Skeleton](https://github.com/pjebs/go-skeleton)
## Live code reload?
[gin](https://github.com/codegangsta/gin) and
[fresh](https://github.com/pilu/fresh) both live reload negroni apps.
## Essential Reading for Beginners of Go & Negroni
* [Using a Context to pass information from middleware to end handler](http://elithrar.github.io/article/map-string-interface/)
* [Understanding middleware](https://mattstauffer.co/blog/laravel-5.0-middleware-filter-style)
## About
Negroni is obsessively designed by none other than the [Code
Gangsta](https://codegangsta.io/)
[Gorilla Mux]: https://github.com/gorilla/mux
[`http.FileSystem`]: https://godoc.org/net/http#FileSystem

25
vendor/github.com/codegangsta/negroni/doc.go generated vendored Normal file
View file

@ -0,0 +1,25 @@
// Package negroni is an idiomatic approach to web middleware in Go. It is tiny, non-intrusive, and encourages use of net/http Handlers.
//
// If you like the idea of Martini, but you think it contains too much magic, then Negroni is a great fit.
//
// For a full guide visit http://github.com/urfave/negroni
//
// package main
//
// import (
// "github.com/urfave/negroni"
// "net/http"
// "fmt"
// )
//
// func main() {
// mux := http.NewServeMux()
// mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// fmt.Fprintf(w, "Welcome to the home page!")
// })
//
// n := negroni.Classic()
// n.UseHandler(mux)
// n.Run(":3000")
// }
package negroni

82
vendor/github.com/codegangsta/negroni/logger.go generated vendored Normal file
View file

@ -0,0 +1,82 @@
package negroni
import (
"bytes"
"log"
"net/http"
"os"
"text/template"
"time"
)
// LoggerEntry is the structure
// passed to the template.
type LoggerEntry struct {
StartTime string
Status int
Duration time.Duration
Hostname string
Method string
Path string
Request *http.Request
}
// LoggerDefaultFormat is the format
// logged used by the default Logger instance.
var LoggerDefaultFormat = "{{.StartTime}} | {{.Status}} | \t {{.Duration}} | {{.Hostname}} | {{.Method}} {{.Path}} \n"
// LoggerDefaultDateFormat is the
// format used for date by the
// default Logger instance.
var LoggerDefaultDateFormat = time.RFC3339
// ALogger interface
type ALogger interface {
Println(v ...interface{})
Printf(format string, v ...interface{})
}
// Logger is a middleware handler that logs the request as it goes in and the response as it goes out.
type Logger struct {
// ALogger implements just enough log.Logger interface to be compatible with other implementations
ALogger
dateFormat string
template *template.Template
}
// NewLogger returns a new Logger instance
func NewLogger() *Logger {
logger := &Logger{ALogger: log.New(os.Stdout, "[negroni] ", 0), dateFormat: LoggerDefaultDateFormat}
logger.SetFormat(LoggerDefaultFormat)
return logger
}
func (l *Logger) SetFormat(format string) {
l.template = template.Must(template.New("negroni_parser").Parse(format))
}
func (l *Logger) SetDateFormat(format string) {
l.dateFormat = format
}
func (l *Logger) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
start := time.Now()
next(rw, r)
res := rw.(ResponseWriter)
log := LoggerEntry{
StartTime: start.Format(l.dateFormat),
Status: res.Status(),
Duration: time.Since(start),
Hostname: r.Host,
Method: r.Method,
Path: r.URL.Path,
Request: r,
}
buff := &bytes.Buffer{}
l.template.Execute(buff, log)
l.Printf(buff.String())
}

169
vendor/github.com/codegangsta/negroni/negroni.go generated vendored Normal file
View file

@ -0,0 +1,169 @@
package negroni
import (
"log"
"net/http"
"os"
)
const (
// DefaultAddress is used if no other is specified.
DefaultAddress = ":8080"
)
// Handler handler is an interface that objects can implement to be registered to serve as middleware
// in the Negroni middleware stack.
// ServeHTTP should yield to the next middleware in the chain by invoking the next http.HandlerFunc
// passed in.
//
// If the Handler writes to the ResponseWriter, the next http.HandlerFunc should not be invoked.
type Handler interface {
ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}
// HandlerFunc is an adapter to allow the use of ordinary functions as Negroni handlers.
// If f is a function with the appropriate signature, HandlerFunc(f) is a Handler object that calls f.
type HandlerFunc func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func (h HandlerFunc) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
h(rw, r, next)
}
type middleware struct {
handler Handler
next *middleware
}
func (m middleware) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
m.handler.ServeHTTP(rw, r, m.next.ServeHTTP)
}
// Wrap converts a http.Handler into a negroni.Handler so it can be used as a Negroni
// middleware. The next http.HandlerFunc is automatically called after the Handler
// is executed.
func Wrap(handler http.Handler) Handler {
return HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
handler.ServeHTTP(rw, r)
next(rw, r)
})
}
// WrapFunc converts a http.HandlerFunc into a negroni.Handler so it can be used as a Negroni
// middleware. The next http.HandlerFunc is automatically called after the Handler
// is executed.
func WrapFunc(handlerFunc http.HandlerFunc) Handler {
return HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
handlerFunc(rw, r)
next(rw, r)
})
}
// Negroni is a stack of Middleware Handlers that can be invoked as an http.Handler.
// Negroni middleware is evaluated in the order that they are added to the stack using
// the Use and UseHandler methods.
type Negroni struct {
middleware middleware
handlers []Handler
}
// New returns a new Negroni instance with no middleware preconfigured.
func New(handlers ...Handler) *Negroni {
return &Negroni{
handlers: handlers,
middleware: build(handlers),
}
}
// With returns a new Negroni instance that is a combination of the negroni
// receiver's handlers and the provided handlers.
func (n *Negroni) With(handlers ...Handler) *Negroni {
return New(
append(n.handlers, handlers...)...,
)
}
// Classic returns a new Negroni instance with the default middleware already
// in the stack.
//
// Recovery - Panic Recovery Middleware
// Logger - Request/Response Logging
// Static - Static File Serving
func Classic() *Negroni {
return New(NewRecovery(), NewLogger(), NewStatic(http.Dir("public")))
}
func (n *Negroni) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
n.middleware.ServeHTTP(NewResponseWriter(rw), r)
}
// Use adds a Handler onto the middleware stack. Handlers are invoked in the order they are added to a Negroni.
func (n *Negroni) Use(handler Handler) {
if handler == nil {
panic("handler cannot be nil")
}
n.handlers = append(n.handlers, handler)
n.middleware = build(n.handlers)
}
// UseFunc adds a Negroni-style handler function onto the middleware stack.
func (n *Negroni) UseFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)) {
n.Use(HandlerFunc(handlerFunc))
}
// UseHandler adds a http.Handler onto the middleware stack. Handlers are invoked in the order they are added to a Negroni.
func (n *Negroni) UseHandler(handler http.Handler) {
n.Use(Wrap(handler))
}
// UseHandlerFunc adds a http.HandlerFunc-style handler function onto the middleware stack.
func (n *Negroni) UseHandlerFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request)) {
n.UseHandler(http.HandlerFunc(handlerFunc))
}
// Run is a convenience function that runs the negroni stack as an HTTP
// server. The addr string, if provided, takes the same format as http.ListenAndServe.
// If no address is provided but the PORT environment variable is set, the PORT value is used.
// If neither is provided, the address' value will equal the DefaultAddress constant.
func (n *Negroni) Run(addr ...string) {
l := log.New(os.Stdout, "[negroni] ", 0)
finalAddr := detectAddress(addr...)
l.Printf("listening on %s", finalAddr)
l.Fatal(http.ListenAndServe(finalAddr, n))
}
func detectAddress(addr ...string) string {
if len(addr) > 0 {
return addr[0]
}
if port := os.Getenv("PORT"); port != "" {
return ":" + port
}
return DefaultAddress
}
// Returns a list of all the handlers in the current Negroni middleware chain.
func (n *Negroni) Handlers() []Handler {
return n.handlers
}
func build(handlers []Handler) middleware {
var next middleware
if len(handlers) == 0 {
return voidMiddleware()
} else if len(handlers) > 1 {
next = build(handlers[1:])
} else {
next = voidMiddleware()
}
return middleware{handlers[0], &next}
}
func voidMiddleware() middleware {
return middleware{
HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {}),
&middleware{},
}
}

179
vendor/github.com/codegangsta/negroni/recovery.go generated vendored Normal file
View file

@ -0,0 +1,179 @@
package negroni
import (
"fmt"
"log"
"net/http"
"os"
"runtime"
"runtime/debug"
"text/template"
)
const (
panicText = "PANIC: %s\n%s"
panicHTML = `<html>
<head><title>PANIC: {{.RecoveredPanic}}</title></head>
<style type="text/css">
html, body {
font-family: Helvetica, Arial, Sans;
color: #333333;
background-color: #ffffff;
margin: 0px;
}
h1 {
color: #ffffff;
background-color: #f14c4c;
padding: 20px;
border-bottom: 1px solid #2b3848;
}
.block {
margin: 2em;
}
.panic-interface {
}
.panic-stack-raw pre {
padding: 1em;
background: #f6f8fa;
border: dashed 1px;
}
.panic-interface-title {
font-weight: bold;
}
</style>
<body>
<h1>Negroni - PANIC</h1>
<div class="panic-interface block">
<h3>{{.RequestDescription}}</h3>
<span class="panic-interface-title">Runtime error:</span> <span class="panic-interface-element">{{.RecoveredPanic}}</span>
</div>
{{ if .Stack }}
<div class="panic-stack-raw block">
<h3>Runtime Stack</h3>
<pre>{{.StackAsString}}</pre>
</div>
{{ end }}
</body>
</html>`
nilRequestMessage = "Request is nil"
)
var panicHTMLTemplate = template.Must(template.New("PanicPage").Parse(panicHTML))
// PanicInformation contains all
// elements for printing stack informations.
type PanicInformation struct {
RecoveredPanic interface{}
Stack []byte
Request *http.Request
}
// StackAsString returns a printable version of the stack
func (p *PanicInformation) StackAsString() string {
return string(p.Stack)
}
// RequestDescription returns a printable description of the url
func (p *PanicInformation) RequestDescription() string {
if p.Request == nil {
return nilRequestMessage
}
var queryOutput string
if p.Request.URL.RawQuery != "" {
queryOutput = "?" + p.Request.URL.RawQuery
}
return fmt.Sprintf("%s %s%s", p.Request.Method, p.Request.URL.Path, queryOutput)
}
// PanicFormatter is an interface on object can implement
// to be able to output the stack trace
type PanicFormatter interface {
// FormatPanicError output the stack for a given answer/response.
// In case the the middleware should not output the stack trace,
// the field `Stack` of the passed `PanicInformation` instance equals `[]byte{}`.
FormatPanicError(rw http.ResponseWriter, r *http.Request, infos *PanicInformation)
}
// TextPanicFormatter output the stack
// as simple text on os.Stdout. If no `Content-Type` is set,
// it will output the data as `text/plain; charset=utf-8`.
// Otherwise, the origin `Content-Type` is kept.
type TextPanicFormatter struct{}
func (t *TextPanicFormatter) FormatPanicError(rw http.ResponseWriter, r *http.Request, infos *PanicInformation) {
if rw.Header().Get("Content-Type") == "" {
rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
}
fmt.Fprintf(rw, panicText, infos.RecoveredPanic, infos.Stack)
}
// HTMLPanicFormatter output the stack inside
// an HTML page. This has been largely inspired by
// https://github.com/go-martini/martini/pull/156/commits.
type HTMLPanicFormatter struct{}
func (t *HTMLPanicFormatter) FormatPanicError(rw http.ResponseWriter, r *http.Request, infos *PanicInformation) {
if rw.Header().Get("Content-Type") == "" {
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
}
panicHTMLTemplate.Execute(rw, infos)
}
// Recovery is a Negroni middleware that recovers from any panics and writes a 500 if there was one.
type Recovery struct {
Logger ALogger
PrintStack bool
ErrorHandlerFunc func(interface{})
StackAll bool
StackSize int
Formatter PanicFormatter
}
// NewRecovery returns a new instance of Recovery
func NewRecovery() *Recovery {
return &Recovery{
Logger: log.New(os.Stdout, "[negroni] ", 0),
PrintStack: true,
StackAll: false,
StackSize: 1024 * 8,
Formatter: &TextPanicFormatter{},
}
}
func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
defer func() {
if err := recover(); err != nil {
rw.WriteHeader(http.StatusInternalServerError)
stack := make([]byte, rec.StackSize)
stack = stack[:runtime.Stack(stack, rec.StackAll)]
infos := &PanicInformation{RecoveredPanic: err, Request: r}
if rec.PrintStack {
infos.Stack = stack
}
rec.Logger.Printf(panicText, err, stack)
rec.Formatter.FormatPanicError(rw, r, infos)
if rec.ErrorHandlerFunc != nil {
func() {
defer func() {
if err := recover(); err != nil {
rec.Logger.Printf("provided ErrorHandlerFunc panic'd: %s, trace:\n%s", err, debug.Stack())
rec.Logger.Printf("%s\n", debug.Stack())
}
}()
rec.ErrorHandlerFunc(err)
}()
}
}
}()
next(rw, r)
}

View file

@ -0,0 +1,113 @@
package negroni
import (
"bufio"
"fmt"
"net"
"net/http"
)
// ResponseWriter is a wrapper around http.ResponseWriter that provides extra information about
// the response. It is recommended that middleware handlers use this construct to wrap a responsewriter
// if the functionality calls for it.
type ResponseWriter interface {
http.ResponseWriter
http.Flusher
// Status returns the status code of the response or 0 if the response has
// not been written
Status() int
// Written returns whether or not the ResponseWriter has been written.
Written() bool
// Size returns the size of the response body.
Size() int
// Before allows for a function to be called before the ResponseWriter has been written to. This is
// useful for setting headers or any other operations that must happen before a response has been written.
Before(func(ResponseWriter))
}
type beforeFunc func(ResponseWriter)
// NewResponseWriter creates a ResponseWriter that wraps an http.ResponseWriter
func NewResponseWriter(rw http.ResponseWriter) ResponseWriter {
nrw := &responseWriter{
ResponseWriter: rw,
}
if _, ok := rw.(http.CloseNotifier); ok {
return &responseWriterCloseNotifer{nrw}
}
return nrw
}
type responseWriter struct {
http.ResponseWriter
status int
size int
beforeFuncs []beforeFunc
}
func (rw *responseWriter) WriteHeader(s int) {
rw.status = s
rw.callBefore()
rw.ResponseWriter.WriteHeader(s)
}
func (rw *responseWriter) Write(b []byte) (int, error) {
if !rw.Written() {
// The status will be StatusOK if WriteHeader has not been called yet
rw.WriteHeader(http.StatusOK)
}
size, err := rw.ResponseWriter.Write(b)
rw.size += size
return size, err
}
func (rw *responseWriter) Status() int {
return rw.status
}
func (rw *responseWriter) Size() int {
return rw.size
}
func (rw *responseWriter) Written() bool {
return rw.status != 0
}
func (rw *responseWriter) Before(before func(ResponseWriter)) {
rw.beforeFuncs = append(rw.beforeFuncs, before)
}
func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
hijacker, ok := rw.ResponseWriter.(http.Hijacker)
if !ok {
return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface")
}
return hijacker.Hijack()
}
func (rw *responseWriter) callBefore() {
for i := len(rw.beforeFuncs) - 1; i >= 0; i-- {
rw.beforeFuncs[i](rw)
}
}
func (rw *responseWriter) Flush() {
flusher, ok := rw.ResponseWriter.(http.Flusher)
if ok {
if !rw.Written() {
// The status will be StatusOK if WriteHeader has not been called yet
rw.WriteHeader(http.StatusOK)
}
flusher.Flush()
}
}
type responseWriterCloseNotifer struct {
*responseWriter
}
func (rw *responseWriterCloseNotifer) CloseNotify() <-chan bool {
return rw.ResponseWriter.(http.CloseNotifier).CloseNotify()
}

View file

@ -0,0 +1,16 @@
//+build go1.8
package negroni
import (
"fmt"
"net/http"
)
func (rw *responseWriter) Push(target string, opts *http.PushOptions) error {
pusher, ok := rw.ResponseWriter.(http.Pusher)
if ok {
return pusher.Push(target, opts)
}
return fmt.Errorf("the ResponseWriter doesn't support the Pusher interface")
}

88
vendor/github.com/codegangsta/negroni/static.go generated vendored Normal file
View file

@ -0,0 +1,88 @@
package negroni
import (
"net/http"
"path"
"strings"
)
// Static is a middleware handler that serves static files in the given
// directory/filesystem. If the file does not exist on the filesystem, it
// passes along to the next middleware in the chain. If you desire "fileserver"
// type behavior where it returns a 404 for unfound files, you should consider
// using http.FileServer from the Go stdlib.
type Static struct {
// Dir is the directory to serve static files from
Dir http.FileSystem
// Prefix is the optional prefix used to serve the static directory content
Prefix string
// IndexFile defines which file to serve as index if it exists.
IndexFile string
}
// NewStatic returns a new instance of Static
func NewStatic(directory http.FileSystem) *Static {
return &Static{
Dir: directory,
Prefix: "",
IndexFile: "index.html",
}
}
func (s *Static) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
if r.Method != "GET" && r.Method != "HEAD" {
next(rw, r)
return
}
file := r.URL.Path
// if we have a prefix, filter requests by stripping the prefix
if s.Prefix != "" {
if !strings.HasPrefix(file, s.Prefix) {
next(rw, r)
return
}
file = file[len(s.Prefix):]
if file != "" && file[0] != '/' {
next(rw, r)
return
}
}
f, err := s.Dir.Open(file)
if err != nil {
// discard the error?
next(rw, r)
return
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
next(rw, r)
return
}
// try to serve index file
if fi.IsDir() {
// redirect if missing trailing slash
if !strings.HasSuffix(r.URL.Path, "/") {
http.Redirect(rw, r, r.URL.Path+"/", http.StatusFound)
return
}
file = path.Join(file, s.IndexFile)
f, err = s.Dir.Open(file)
if err != nil {
next(rw, r)
return
}
defer f.Close()
fi, err = f.Stat()
if err != nil || fi.IsDir() {
next(rw, r)
return
}
}
http.ServeContent(rw, r, file, fi.ModTime(), f)
}