portainer/dockerui.go

133 lines
2.7 KiB
Go
Raw Normal View History

package main // import "github.com/crosbymichael/dockerui"
import (
"flag"
2013-12-30 18:40:08 +00:00
"io"
"log"
2013-12-30 18:40:08 +00:00
"net"
"net/http"
2013-09-10 16:36:37 +00:00
"net/http/httputil"
"net/url"
2014-02-15 04:38:07 +00:00
"os"
2013-12-30 18:40:08 +00:00
"strings"
2016-04-01 04:54:12 +00:00
"github.com/gorilla/csrf"
"io/ioutil"
"fmt"
"github.com/gorilla/securecookie"
)
var (
2014-03-10 22:49:40 +00:00
endpoint = flag.String("e", "/var/run/docker.sock", "Dockerd endpoint")
2013-09-10 16:36:37 +00:00
addr = flag.String("p", ":9000", "Address and port to serve dockerui")
2013-09-03 01:55:00 +00:00
assets = flag.String("a", ".", "Path to the assets")
authKey []byte
authKeyFile = "authKey.dat"
)
2013-12-30 18:40:08 +00:00
type UnixHandler struct {
path string
}
func (h *UnixHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
conn, err := net.Dial("unix", h.path)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Println(err)
return
}
c := httputil.NewClientConn(conn, nil)
defer c.Close()
res, err := c.Do(r)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Println(err)
return
}
defer res.Body.Close()
copyHeader(w.Header(), res.Header)
if _, err := io.Copy(w, res.Body); err != nil {
log.Println(err)
}
}
2013-12-30 18:40:08 +00:00
func copyHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}
func createTcpHandler(e string) http.Handler {
u, err := url.Parse(e)
2013-09-10 16:36:37 +00:00
if err != nil {
log.Fatal(err)
}
2013-12-30 18:40:08 +00:00
return httputil.NewSingleHostReverseProxy(u)
}
2013-12-30 18:40:08 +00:00
func createUnixHandler(e string) http.Handler {
return &UnixHandler{e}
}
func createHandler(dir string, e string) http.Handler {
var (
mux = http.NewServeMux()
fileHandler = http.FileServer(http.Dir(dir))
h http.Handler
)
2013-12-30 18:40:08 +00:00
if strings.Contains(e, "http") {
h = createTcpHandler(e)
} else {
2014-02-15 04:38:07 +00:00
if _, err := os.Stat(e); err != nil {
if os.IsNotExist(err) {
log.Fatalf("unix socket %s does not exist", e)
}
log.Fatal(err)
}
2013-12-30 18:40:08 +00:00
h = createUnixHandler(e)
}
// Use existing csrf authKey if present or generate a new one.
dat, err := ioutil.ReadFile(authKeyFile)
if err != nil {
fmt.Println(err)
authKey = securecookie.GenerateRandomKey(32)
err := ioutil.WriteFile(authKeyFile, authKey, 0644)
if err != nil {
fmt.Println("unable to persist auth key", err)
}
} else {
authKey = dat
}
CSRF := csrf.Protect(
authKey,
csrf.HttpOnly(false),
csrf.Secure(false),
)
2013-12-30 18:40:08 +00:00
mux.Handle("/dockerapi/", http.StripPrefix("/dockerapi", h))
mux.Handle("/", fileHandler)
return CSRF(csrfWrapper(mux))
2016-04-01 04:54:12 +00:00
}
func csrfWrapper(h http.Handler) http.Handler {
2016-04-01 04:54:12 +00:00
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-CSRF-Token", csrf.Token(r))
h.ServeHTTP(w, r)
2016-04-01 04:54:12 +00:00
})
}
func main() {
flag.Parse()
2013-09-10 16:36:37 +00:00
handler := createHandler(*assets, *endpoint)
if err := http.ListenAndServe(*addr, handler); err != nil {
log.Fatal(err)
}
}