summaryrefslogtreecommitdiffstats
path: root/app/server.go
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2018-02-06 17:25:53 +0000
committerGeorge Goldberg <george@gberg.me>2018-02-06 17:25:53 +0000
commit7941c30117efe1b957ac0458c2f0479e3824196d (patch)
treedf791632a9dc790a6f73dec53aae3ba919ebda63 /app/server.go
parente1cd64613591cf5a990442a69ebf188258bd0cb5 (diff)
parent034dbc07e3068c482e654b6a1a8fcbe4b01c44f3 (diff)
downloadchat-7941c30117efe1b957ac0458c2f0479e3824196d.tar.gz
chat-7941c30117efe1b957ac0458c2f0479e3824196d.tar.bz2
chat-7941c30117efe1b957ac0458c2f0479e3824196d.zip
Merge branch 'master' into advanced-permissions-phase-1
Diffstat (limited to 'app/server.go')
-rw-r--r--app/server.go91
1 files changed, 51 insertions, 40 deletions
diff --git a/app/server.go b/app/server.go
index eb2fa9b32..1659908b6 100644
--- a/app/server.go
+++ b/app/server.go
@@ -10,15 +10,14 @@ import (
"io/ioutil"
"net"
"net/http"
+ "os"
"strings"
"time"
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
- "github.com/rsc/letsencrypt"
- "gopkg.in/throttled/throttled.v2"
- "gopkg.in/throttled/throttled.v2/store/memstore"
+ "golang.org/x/crypto/acme/autocert"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
@@ -31,6 +30,7 @@ type Server struct {
Router *mux.Router
Server *http.Server
ListenAddr *net.TCPAddr
+ RateLimiter *RateLimiter
didFinishListen chan struct{}
}
@@ -83,10 +83,26 @@ func (cw *CorsWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
const TIME_TO_WAIT_FOR_CONNECTIONS_TO_CLOSE_ON_SERVER_SHUTDOWN = time.Second
-type VaryBy struct{}
+type VaryBy struct {
+ useIP bool
+ useAuth bool
+}
func (m *VaryBy) Key(r *http.Request) string {
- return utils.GetIpAddress(r)
+ key := ""
+
+ if m.useAuth {
+ token, tokenLocation := ParseAuthTokenFromRequest(r)
+ if tokenLocation != TokenLocationNotFound {
+ key += token
+ } else if m.useIP { // If we don't find an authentication token and IP based is enabled, fall back to IP
+ key += utils.GetIpAddress(r)
+ }
+ } else if m.useIP { // Only if Auth based is not enabed do we use a plain IP based
+ key = utils.GetIpAddress(r)
+ }
+
+ return key
}
func redirectHTTPToHTTPS(w http.ResponseWriter, r *http.Request) {
@@ -108,33 +124,14 @@ func (a *App) StartServer() {
if *a.Config().RateLimitSettings.Enable {
l4g.Info(utils.T("api.server.start_server.rate.info"))
- store, err := memstore.New(*a.Config().RateLimitSettings.MemoryStoreSize)
+ rateLimiter, err := NewRateLimiter(&a.Config().RateLimitSettings)
if err != nil {
- l4g.Critical(utils.T("api.server.start_server.rate_limiting_memory_store"))
+ l4g.Critical(err.Error())
return
}
- quota := throttled.RateQuota{
- MaxRate: throttled.PerSec(*a.Config().RateLimitSettings.PerSec),
- MaxBurst: *a.Config().RateLimitSettings.MaxBurst,
- }
-
- rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
- if err != nil {
- l4g.Critical(utils.T("api.server.start_server.rate_limiting_rate_limiter"))
- return
- }
-
- httpRateLimiter := throttled.HTTPRateLimiter{
- RateLimiter: rateLimiter,
- VaryBy: &VaryBy{},
- DeniedHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- l4g.Error("%v: Denied due to throttling settings code=429 ip=%v", r.URL.Path, utils.GetIpAddress(r))
- throttled.DefaultDeniedHandler.ServeHTTP(w, r)
- }),
- }
-
- handler = httpRateLimiter.RateLimit(handler)
+ a.Srv.RateLimiter = rateLimiter
+ handler = rateLimiter.RateLimitHandler(handler)
}
a.Srv.Server = &http.Server{
@@ -161,18 +158,34 @@ func (a *App) StartServer() {
l4g.Info(utils.T("api.server.start_server.listening.info"), listener.Addr().String())
+ // Migration from old let's encrypt library
+ if *a.Config().ServiceSettings.UseLetsEncrypt {
+ if stat, err := os.Stat(*a.Config().ServiceSettings.LetsEncryptCertificateCacheFile); err == nil && !stat.IsDir() {
+ os.Remove(*a.Config().ServiceSettings.LetsEncryptCertificateCacheFile)
+ }
+ }
+
+ m := &autocert.Manager{
+ Cache: autocert.DirCache(*a.Config().ServiceSettings.LetsEncryptCertificateCacheFile),
+ Prompt: autocert.AcceptTOS,
+ }
+
if *a.Config().ServiceSettings.Forward80To443 {
- go func() {
- redirectListener, err := net.Listen("tcp", ":80")
- if err != nil {
- listener.Close()
- l4g.Error("Unable to setup forwarding: " + err.Error())
- return
- }
- defer redirectListener.Close()
+ if *a.Config().ServiceSettings.UseLetsEncrypt {
+ go http.ListenAndServe(":http", m.HTTPHandler(nil))
+ } else {
+ go func() {
+ redirectListener, err := net.Listen("tcp", ":80")
+ if err != nil {
+ listener.Close()
+ l4g.Error("Unable to setup forwarding: " + err.Error())
+ return
+ }
+ defer redirectListener.Close()
- http.Serve(redirectListener, http.HandlerFunc(redirectHTTPToHTTPS))
- }()
+ http.Serve(redirectListener, http.HandlerFunc(redirectHTTPToHTTPS))
+ }()
+ }
}
a.Srv.didFinishListen = make(chan struct{})
@@ -180,8 +193,6 @@ func (a *App) StartServer() {
var err error
if *a.Config().ServiceSettings.ConnectionSecurity == model.CONN_SECURITY_TLS {
if *a.Config().ServiceSettings.UseLetsEncrypt {
- var m letsencrypt.Manager
- m.CacheFile(*a.Config().ServiceSettings.LetsEncryptCertificateCacheFile)
tlsConfig := &tls.Config{
GetCertificate: m.GetCertificate,