Commit 0135904f authored by Christopher Speller's avatar Christopher Speller Committed by GitHub
Browse files

Upgrading server dependancies (#4566)

parent 0b296dd8
hash: ef894d83b32bdf0fdeaebf16b6e56a1e8e865c5ff62cef1ef9740ea68a677a41
updated: 2016-10-10T11:22:33.842051046-07:00
hash: 21760a0ad0c2c37b28af04c042b714a1f1d0370ee1959e4ec90a1168d011cb0f
updated: 2016-11-16T16:57:00.442024925-05:00
imports:
- name: github.com/alecthomas/log4go
version: e5dc62318d9bd58682f1dceb53a4b24e8253682f
......@@ -28,11 +28,11 @@ imports:
- name: github.com/gorilla/context
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
- name: github.com/gorilla/handlers
version: ee54c7b44cab12289237fb8631314790076e728b
version: e1b2144f2167de0e1042d1d35e5cba5119d4fb5d
- name: github.com/gorilla/mux
version: 0eeaf8392f5b04950925b8a69fe70f110fa7cbfc
version: 757bef944d0f21880861c2dd9c871ca543023cba
- name: github.com/gorilla/websocket
version: 1f512fc3f05332ba7117626cdfb4e07474e58e60
version: e8f0f8aaa98dfb6586cbdf2978d511e3199a960a
- name: github.com/hashicorp/golang-lru
version: 0a025b7e63adc15a622f29b0b2c4c3848243bbf6
subpackages:
......@@ -40,7 +40,7 @@ imports:
- name: github.com/jehiah/go-strftime
version: 834e15c05a45371503440cc195bbd05c9a0968d9
- name: github.com/lib/pq
version: 50761b0867bd1d9d069276790bcd4a3bccf2324a
version: d8eeeb8bae8896dd8e1b7e514ab0d396c4f12a1b
subpackages:
- oid
- name: github.com/mattermost/rsc
......@@ -50,7 +50,7 @@ imports:
- qr
- qr/coding
- name: github.com/miekg/dns
version: db96a2b759cdef4f11a34506a42eb8d1290c598e
version: 58f52c57ce9df13460ac68200cef30a008b9c468
- name: github.com/minio/minio-go
version: c040578255dbb1a1f41cbdc5bd944de4140b4149
subpackages:
......@@ -59,18 +59,18 @@ imports:
- name: github.com/mssola/user_agent
version: 85b2f5798558a46fc23443c596e781712f4b7792
- name: github.com/nicksnyder/go-i18n
version: 37e5c2de3e03e4b82693e3fcb4a6aa2cc4eb07e3
version: 1c9e01733308fe876a840a54ce7633540b182a75
subpackages:
- i18n
- i18n/bundle
- i18n/language
- i18n/translation
- name: github.com/NYTimes/gziphandler
version: f6438dbf4a82c56684964b03956aa727b0d7816b
version: 172fbbbb329cf7e031dd3ab35766186fc2081eab
- name: github.com/pborman/uuid
version: a97ce2ca70fa5a848076093f05e639a89ca34d06
- name: github.com/rsc/letsencrypt
version: 35c6e61d12298c67f1e90548d34a34585ac289da
version: 76104d26167d38b6a0010f42bfc8ec5487742e8b
- name: github.com/rwcarlsen/goexif
version: 709fab3d192d7c62f86043caff1e7e3fb0f42bd8
subpackages:
......@@ -83,19 +83,19 @@ imports:
- name: github.com/tylerb/graceful
version: 50a48b6e73fcc75b45e22c05b79629a67c79e938
- name: github.com/xenolf/lego
version: ca0bd606b23a8b50f92915772917bd187ae1491b
version: 9f86882f775f75f69617ecc160e39f4e0b7ae27f
subpackages:
- acme
- name: github.com/xtgo/uuid
version: a0b114877d4caeffbd7f87e3757c17fce570fea7
- name: golang.org/x/crypto
version: 6ab629be5e31660579425a738ba8870beb5b7404
version: 9477e0b78b9ac3d0b03822fd95422e2fe07627cd
subpackages:
- bcrypt
- blowfish
- ocsp
- name: golang.org/x/image
version: bb355ba4424d077d404aafbb59b05776b2e88fa7
version: 507b1a44bd72830c136e6ecf7c05f9089796d572
subpackages:
- bmp
- font
......@@ -103,22 +103,22 @@ imports:
- tiff
- tiff/lzw
- name: golang.org/x/net
version: f09c4662a0bd6bd8943ac7b4931e185df9471da4
version: 4971afdc2f162e82d185353533d3cf16188a9f4e
subpackages:
- context
- publicsuffix
- name: golang.org/x/sys
version: 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
version: b699b7032584f0953262cb2788a0ca19bb494703
subpackages:
- unix
- name: golang.org/x/time
version: 711ca1cb87636abec28122ef3bc6a77269d433f3
version: f51c12702a4d776e4c1fa9b0fabab841babae631
subpackages:
- rate
- name: gopkg.in/asn1-ber.v1
version: 4e86f4367175e39f69d9358a5f17b4dda270378d
- name: gopkg.in/fsnotify.v1
version: a8a77c9133d2d6fd8334f3260d06f60e8d80a5fb
version: 629574ca2a5df945712d3079857300b5e4da0236
- name: gopkg.in/square/go-jose.v1
version: aa2e30fdd1fe9dd3394119af66451ae790d50e0d
subpackages:
......
package: github.com/mattermost/platform
import:
- package: github.com/NYTimes/gziphandler
version: f6438dbf4a82c56684964b03956aa727b0d7816b
version: 172fbbbb329cf7e031dd3ab35766186fc2081eab
- package: github.com/alecthomas/log4go
version: e5dc62318d9bd58682f1dceb53a4b24e8253682f
- package: github.com/braintree/manners
......@@ -24,20 +24,21 @@ import:
- package: github.com/golang/freetype
version: 38b4c392adc5eed94207994c4848fff99f4ac234
- package: github.com/gorilla/handlers
version: v1.1
version: e1b2144f2167de0e1042d1d35e5cba5119d4fb5d
- package: github.com/gorilla/mux
version: v1.1
version: 757bef944d0f21880861c2dd9c871ca543023cba
- package: github.com/gorilla/websocket
version: v1.0.0
version: e8f0f8aaa98dfb6586cbdf2978d511e3199a960a
- package: github.com/lib/pq
version: 50761b0867bd1d9d069276790bcd4a3bccf2324a
version: d8eeeb8bae8896dd8e1b7e514ab0d396c4f12a1b
- package: github.com/mattermost/rsc
version: bbaefb05eaa0389ea712340066837c8ce4d287f9
subpackages:
- qr
- package: github.com/mssola/user_agent
version: v0.4.1
- package: github.com/nicksnyder/go-i18n
version: v1.4.0
version: v1.6.0
subpackages:
- i18n
- package: github.com/pborman/uuid
......@@ -47,15 +48,15 @@ import:
subpackages:
- exif
- package: golang.org/x/crypto
version: 6ab629be5e31660579425a738ba8870beb5b7404
version: 9477e0b78b9ac3d0b03822fd95422e2fe07627cd
subpackages:
- bcrypt
- package: golang.org/x/image
version: bb355ba4424d077d404aafbb59b05776b2e88fa7
version: 507b1a44bd72830c136e6ecf7c05f9089796d572
subpackages:
- bmp
- package: gopkg.in/fsnotify.v1
version: v1.3.1
version: v1.4.2
- package: gopkg.in/throttled/throttled.v2
version: v2.0.3
subpackages:
......@@ -63,5 +64,6 @@ import:
- package: github.com/segmentio/analytics-go
version: 2.1.1
- package: github.com/rsc/letsencrypt
version: 76104d26167d38b6a0010f42bfc8ec5487742e8b
- package: github.com/minio/minio-go
version: ^2.0.2
version: v2.0.2
......@@ -181,7 +181,7 @@ func GzipHandler(h http.Handler) http.Handler {
}
// acceptsGzip returns true if the given HTTP request indicates that it will
// accept a gzippped response.
// accept a gzipped response.
func acceptsGzip(r *http.Request) bool {
acceptedEncodings, _ := parseEncodings(r.Header.Get(acceptEncoding))
return acceptedEncodings["gzip"] > 0.0
......
......@@ -6,13 +6,13 @@ matrix:
- go: 1.4
- go: 1.5
- go: 1.6
- go: 1.7
- go: tip
allow_failures:
- go: tip
install:
- go get golang.org/x/tools/cmd/vet
script:
- go get -t -v ./...
- diff -u <(echo -n) <(gofmt -d .)
- go tool vet .
- go vet $(go list ./... | grep -v /vendor/)
- go test -v -race ./...
......@@ -56,6 +56,9 @@ func (w *compressResponseWriter) Flush() {
// CompressHandler gzip compresses HTTP responses for clients that support it
// via the 'Accept-Encoding' header.
//
// Compressing TLS traffic may leak the page contents to an attacker if the
// page contains user input: http://security.stackexchange.com/a/102015/12208
func CompressHandler(h http.Handler) http.Handler {
return CompressHandlerLevel(h, gzip.DefaultCompression)
}
......
......@@ -112,6 +112,9 @@ func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set(corsAllowOriginHeader, origin)
if r.Method == corsOptionMethod {
return
}
ch.h.ServeHTTP(w, r)
}
......
......@@ -104,6 +104,24 @@ func TestCORSHandlerInvalidRequestMethodForPreflightMethodNotAllowed(t *testing.
}
}
func TestCORSHandlerOptionsRequestMustNotBePassedToNextHandler(t *testing.T) {
r := newRequest("OPTIONS", "http://www.example.com/")
r.Header.Set("Origin", r.URL.String())
r.Header.Set(corsRequestMethodHeader, "GET")
rr := httptest.NewRecorder()
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Fatal("Options request must not be passed to next handler")
})
CORS()(testHandler).ServeHTTP(rr, r)
if status := rr.Code; status != http.StatusOK {
t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
}
}
func TestCORSHandlerAllowedMethodForPreflight(t *testing.T) {
r := newRequest("OPTIONS", "http://www.example.com/")
r.Header.Set("Origin", r.URL.String())
......
......@@ -8,9 +8,11 @@ import (
var (
// De-facto standard header keys.
xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
xRealIP = http.CanonicalHeaderKey("X-Real-IP")
xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Scheme")
xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
xForwardedHost = http.CanonicalHeaderKey("X-Forwarded-Host")
xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Proto")
xForwardedScheme = http.CanonicalHeaderKey("X-Forwarded-Scheme")
xRealIP = http.CanonicalHeaderKey("X-Real-IP")
)
var (
......@@ -28,9 +30,9 @@ var (
// ProxyHeaders inspects common reverse proxy headers and sets the corresponding
// fields in the HTTP request struct. These are X-Forwarded-For and X-Real-IP
// for the remote (client) IP address, X-Forwarded-Proto for the scheme
// (http|https) and the RFC7239 Forwarded header, which may include both client
// IPs and schemes.
// for the remote (client) IP address, X-Forwarded-Proto or X-Forwarded-Scheme
// for the scheme (http|https) and the RFC7239 Forwarded header, which may
// include both client IPs and schemes.
//
// NOTE: This middleware should only be used when behind a reverse
// proxy like nginx, HAProxy or Apache. Reverse proxies that don't (or are
......@@ -49,7 +51,10 @@ func ProxyHeaders(h http.Handler) http.Handler {
if scheme := getScheme(r); scheme != "" {
r.URL.Scheme = scheme
}
// Set the host with the value passed by the proxy
if r.Header.Get(xForwardedHost) != "" {
r.Host = r.Header.Get(xForwardedHost)
}
// Call the next handler in the chain.
h.ServeHTTP(w, r)
}
......@@ -99,7 +104,9 @@ func getScheme(r *http.Request) string {
// Retrieve the scheme from X-Forwarded-Proto.
if proto := r.Header.Get(xForwardedProto); proto != "" {
scheme = strings.ToLower(proto)
} else if proto := r.Header.Get(forwarded); proto != "" {
} else if proto = r.Header.Get(xForwardedScheme); proto != "" {
scheme = strings.ToLower(proto)
} else if proto = r.Header.Get(forwarded); proto != "" {
// match should contain at least two elements if the protocol was
// specified in the Forwarded header. The first element will always be
// the 'proto=' capture, which we ignore. In the case of multiple proto
......
......@@ -47,6 +47,9 @@ func TestGetScheme(t *testing.T) {
{xForwardedProto, "https", "https"},
{xForwardedProto, "http", "http"},
{xForwardedProto, "HTTP", "http"},
{xForwardedScheme, "https", "https"},
{xForwardedScheme, "http", "http"},
{xForwardedScheme, "HTTP", "http"},
{forwarded, `For="[2001:db8:cafe::17]:4711`, ""}, // No proto
{forwarded, `for=192.0.2.43, for=198.51.100.17;proto=https`, "https"}, // Multiple params before proto
{forwarded, `for=172.32.10.15; proto=https;by=127.0.0.1`, "https"}, // Space before proto
......@@ -74,13 +77,17 @@ func TestProxyHeaders(t *testing.T) {
r.Header.Set(xForwardedFor, "8.8.8.8")
r.Header.Set(xForwardedProto, "https")
var addr string
var proto string
r.Header.Set(xForwardedHost, "google.com")
var (
addr string
proto string
host string
)
ProxyHeaders(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
addr = r.RemoteAddr
proto = r.URL.Scheme
host = r.Host
})).ServeHTTP(rr, r)
if rr.Code != http.StatusOK {
......@@ -96,5 +103,9 @@ func TestProxyHeaders(t *testing.T) {
t.Fatalf("wrong address: got %s want %s", proto,
r.Header.Get(xForwardedProto))
}
if host != r.Header.Get(xForwardedHost) {
t.Fatalf("wrong address: got %s want %s", host,
r.Header.Get(xForwardedHost))
}
}
......@@ -8,10 +8,11 @@ matrix:
- go: 1.4
- go: 1.5
- go: 1.6
- go: 1.7
- go: tip
install:
- go get golang.org/x/tools/cmd/vet
- # Skip
script:
- go get -t -v ./...
......
mux
gorilla/mux
===
[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png)
http://www.gorillatoolkit.org/pkg/mux
Package `gorilla/mux` implements a request router and dispatcher.
Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to
their respective handler.
The name mux stands for "HTTP request multiplexer". Like the standard `http.ServeMux`, `mux.Router` matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. The main features are:
* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers.
* URL hosts and paths can have variables with an optional regular expression.
* Registered URLs can be built, or "reversed", which helps maintaining references to resources.
* Routes can be used as subrouters: nested routes are only tested if the parent route matches. This is useful to define groups of routes that share common conditions like a host, a path prefix or other repeated attributes. As a bonus, this optimizes request matching.
* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
---
* [Install](#install)
* [Examples](#examples)
* [Matching Routes](#matching-routes)
* [Static Files](#static-files)
* [Registered URLs](#registered-urls)
* [Full Example](#full-example)
---
## Install
With a [correctly configured](https://golang.org/doc/install#testing) Go toolchain:
```sh
go get -u github.com/gorilla/mux
```
## Examples
Let's start registering a couple of URL paths and handlers:
......@@ -47,6 +71,8 @@ category := vars["category"]
And this is all you need to know about the basic usage. More advanced options are explained below.
### Matching Routes
Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables:
```go
......@@ -118,7 +144,7 @@ Then register routes in the subrouter:
```go
s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
```
The three URL paths we registered above will only be tested if the domain is `www.example.com`, because the subrouter is tested first. This is not only convenient, but also optimizes request matching. You can create subrouters combining any attribute matchers accepted by a route.
......@@ -138,6 +164,37 @@ s.HandleFunc("/{key}/", ProductHandler)
s.HandleFunc("/{key}/details", ProductDetailsHandler)
```
### Static Files
Note that the path provided to `PathPrefix()` represents a "wildcard": calling
`PathPrefix("/static/").Handler(...)` means that the handler will be passed any
request that matches "/static/*". This makes it easy to serve static files with mux:
```go
func main() {
var dir string
flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
flag.Parse()
r := mux.NewRouter()
// This will serve files under http://localhost:8000/static/<filename>
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))
srv := &http.Server{
Handler: r,
Addr: "127.0.0.1:8000",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
```
### Registered URLs
Now let's see how to build registered URLs.
Routes can be named. All routes that define a name can have their URLs built, or "reversed". We define a name calling `Name()` on a route. For example:
......@@ -219,7 +276,7 @@ package main
import (
"net/http"
"log"
"github.com/gorilla/mux"
)
......@@ -233,7 +290,7 @@ func main() {
r.HandleFunc("/", YourHandler)
// Bind to a port and pass our router in
http.ListenAndServe(":8000", r)
log.Fatal(http.ListenAndServe(":8000", r))
}
```
......
// +build !go1.7
package mux
import (
"net/http"
"github.com/gorilla/context"
)
func contextGet(r *http.Request, key interface{}) interface{} {
return context.Get(r, key)
}
func contextSet(r *http.Request, key, val interface{}) *http.Request {
if val == nil {
return r
}
context.Set(r, key, val)
return r
}
func contextClear(r *http.Request) {
context.Clear(r)
}
// +build !go1.7
package mux
import (
"net/http"
"testing"
"github.com/gorilla/context"
)
// Tests that the context is cleared or not cleared properly depending on
// the configuration of the router
func TestKeepContext(t *testing.T) {
func1 := func(w http.ResponseWriter, r *http.Request) {}
r := NewRouter()
r.HandleFunc("/", func1).Name("func1")
req, _ := http.NewRequest("GET", "http://localhost/", nil)
context.Set(req, "t", 1)
res := new(http.ResponseWriter)
r.ServeHTTP(*res, req)
if _, ok := context.GetOk(req, "t"); ok {
t.Error("Context should have been cleared at end of request")
}
r.KeepContext = true
req, _ = http.NewRequest("GET", "http://localhost/", nil)
context.Set(req, "t", 1)
r.ServeHTTP(*res, req)
if _, ok := context.GetOk(req, "t"); !ok {
t.Error("Context should NOT have been cleared at end of request")
}
}
// +build go1.7
package mux
import (
"context"
"net/http"
)
func contextGet(r *http.Request, key interface{}) interface{} {
return r.Context().Value(key)
}
func contextSet(r *http.Request, key, val interface{}) *http.Request {
if val == nil {
return r
}
return r.WithContext(context.WithValue(r.Context(), key, val))
}
func contextClear(r *http.Request) {
return
}
// +build go1.7
package mux
import (
"context"
"net/http"
"testing"
"time"
)
func TestNativeContextMiddleware(t *testing.T) {
withTimeout := func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
defer cancel()
h.ServeHTTP(w, r.WithContext(ctx))
})
}
r := NewRouter()
r.Handle("/path/{foo}", withTimeout(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
vars := Vars(r)
if vars["foo"] != "bar" {
t.Fatal("Expected foo var to be set")
}
})))
rec := NewRecorder()
req := newRequest("GET", "/path/bar")
r.ServeHTTP(rec, req)
}
......@@ -47,6 +47,10 @@ variable will be anything until the next slash. For example:
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
Groups can be used inside patterns, as long as they are non-capturing (?:re). For example:
r.HandleFunc("/articles/{category}/{sort:(?:asc|desc|new)}", ArticlesCategoryHandler)
The names are used to create a map of route variables which can be retrieved
calling mux.Vars():
......@@ -136,6 +140,31 @@ the inner routes use it as base for their paths:
// "/products/{key}/details"
s.HandleFunc("/{key}/details", ProductDetailsHandler)
Note that the path provided to PathPrefix() represents a "wildcard": calling
PathPrefix("/static/").Handler(...) means that the handler will be passed any
request that matches "/static/*". This makes it easy to serve static files with mux:
func main() {
var dir string
flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
flag.Parse()