diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 91d219a..0000000 --- a/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM golang:1.5-onbuild -ENV PORT=8000 -ENV INSECURE_PORT=8001 diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..9f9e584 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: senatus \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index ba34d56..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,5 +0,0 @@ -senatus: - build: . - ports: - - 80:8001 - - 443:8000 diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 0000000..92f4e12 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,12 @@ +package: senatus +import: +- package: github.com/cozmo/senatus + subpackages: + - db + - handler +- package: github.com/gorilla/mux +- package: github.com/gorilla/sessions +- package: github.com/segmentio/go-env +- package: gopkg.in/mgo.v2 + subpackages: + - bson diff --git a/main.go b/main.go index 1c1ad0e..18e448a 100644 --- a/main.go +++ b/main.go @@ -2,16 +2,45 @@ package main import ( "fmt" + "net/http" + "os" + "runtime" + "strings" + "github.com/cozmo/senatus/db" "github.com/cozmo/senatus/handler" "github.com/gorilla/mux" "github.com/gorilla/sessions" env "github.com/segmentio/go-env" - "net/http" - "os" - "runtime" ) +func isHttps(r *http.Request) bool { + if r.URL.Scheme == "https" { + return true + } + if strings.HasPrefix(r.Proto, "HTTPS") { + return true + } + if r.Header.Get("X-Forwarded-Proto") == "https" { + return true + } + return false +} + +func ensureHttpsMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + if !isHttps(req) { + hostToSend := req.Host + if req.Header.Get("X-Forwarded-Host") != "" { + hostToSend = req.Header.Get("X-Forwarded-Host") + } + http.Redirect(res, req, "https://"+hostToSend+req.URL.String(), 301) + } else { + next.ServeHTTP(res, req) + } + }) +} + func sessionMiddleware(h *handler.Handler, store sessions.Store, routeHandler func(http.ResponseWriter, *http.Request, *db.User)) func(http.ResponseWriter, *http.Request) { return func(res http.ResponseWriter, req *http.Request) { session, err := store.Get(req, "session") @@ -40,15 +69,6 @@ func main() { runtime.GOMAXPROCS(runtime.NumCPU()) - // If we get an INSECURE_PORT env var we forward all requests on that port to HTTPs. This allows us to get - // around routing systems that don't forward the x-forwarded-proto headers correctly (like https://convox.com/) - if os.Getenv("INSECURE_PORT") != "" { - fmt.Println("Serving Senatus HTTPs redirector on port " + os.Getenv("INSECURE_PORT")) - go http.ListenAndServe(":"+os.Getenv("INSECURE_PORT"), http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { - http.Redirect(res, req, "https://"+req.Host+req.URL.String(), 301) - })) - } - database, err := db.NewMongoDB(os.Getenv("MONGO_URL")) if err != nil { panic("Error connecting to mongo") @@ -78,7 +98,11 @@ func main() { r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("./public")))) r.HandleFunc("/{url:.*}", h.NotFoundHandler) - http.Handle("/", r) + if os.Getenv("ENFORCE_HTTPS") != "" { + http.Handle("/", ensureHttpsMiddleware(r)) + } else { + http.Handle("/", r) + } fmt.Println("Serving Senatus on port " + os.Getenv("PORT")) http.ListenAndServe(":"+os.Getenv("PORT"), nil) }