mirror of https://github.com/portainer/portainer
101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
endpoint = flag.String("e", "/var/run/docker.sock", "Dockerd endpoint")
|
|
addr = flag.String("p", ":9000", "Address and port to serve dockerui")
|
|
assets = flag.String("a", ".", "Path to the assets")
|
|
)
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
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)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
return httputil.NewSingleHostReverseProxy(u)
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
if strings.Contains(e, "http") {
|
|
h = createTcpHandler(e)
|
|
} else {
|
|
if _, err := os.Stat(e); err != nil {
|
|
if os.IsNotExist(err) {
|
|
log.Fatalf("unix socket %s does not exist", e)
|
|
}
|
|
log.Fatal(err)
|
|
}
|
|
h = createUnixHandler(e)
|
|
}
|
|
|
|
mux.Handle("/dockerapi/", http.StripPrefix("/dockerapi", h))
|
|
mux.Handle("/", fileHandler)
|
|
return mux
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
handler := createHandler(*assets, *endpoint)
|
|
if err := http.ListenAndServe(*addr, handler); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|