diff options
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/web/delete.go | 4 | ||||
| -rw-r--r-- | cmd/web/index.go | 58 | ||||
| -rw-r--r-- | cmd/web/install.go | 5 | ||||
| -rw-r--r-- | cmd/web/main.go | 72 | ||||
| -rw-r--r-- | cmd/web/serve-self.go | 27 |
5 files changed, 159 insertions, 7 deletions
diff --git a/cmd/web/delete.go b/cmd/web/delete.go index 5bf747e..8edd6c6 100644 --- a/cmd/web/delete.go +++ b/cmd/web/delete.go @@ -6,6 +6,10 @@ import ( ) func gameDelete(w http.ResponseWriter, r *http.Request) { + if unauthorizedIfNotLocal(w, r) { + return + } + err := r.ParseForm() if err != nil { Logger.Printf("Installer: While parsing form: %s", err) diff --git a/cmd/web/index.go b/cmd/web/index.go index a4a91c2..87f9e25 100644 --- a/cmd/web/index.go +++ b/cmd/web/index.go @@ -20,11 +20,14 @@ var ( <body> <nav> <a href="/">Home</a> + {{ if .Local }} <div style="display: block; float: right;"> <a href="/quit">Shutdown Server / Quit</a> </div> + {{ end }} </nav> +{{ if .Local }} <h2>Library: {{.Lib.Folder}}</h2> {{ if .Info.Running }} @@ -39,6 +42,42 @@ Error {{.Info.Error}} Downloading from: {{.Info.Url}} {{ end }} </pre></code> +<h3>About</h3> +<p> +The steam exporter is designed to let you export your steam games, either to +another local hard drive or another computer on the network. +</p> +<p> +It also allows you to import games from across the network as well if you +provide an HTTP url from which to download the game file as exported +from this application. +</p> +<p> +<a href="/steam-export-web.exe"> + You can download this application from this UI as well here. +</a> +</p> + +<p> +You can give people this link to view the library remotely and download +games from your computer: +<br /><br /> +<a href="http://{{.HostIP}}:{{.Port}}/">http://{{.HostIP}}:{{.Port}}/</a> +</p> +{{ else }} +<h2>Remote Steam library access</h2> + +<a href="/steam-export-web.exe"> + If you need this program to install the games click here. +</a> + +<p> +Right click and copy the link address to paste into your local machine +if you do not wish to store the archive or have enough space for it on +your drive. +</p> +{{ end }} + <p> Installed games: @@ -54,6 +93,7 @@ an external hard drive {{ end }} </ul> +{{ if .Local }} Delete a game: ( Type out exact name, case sensitive ) <form action="/delete" method="POST"> @@ -80,7 +120,7 @@ Change library path <input type="text" name="path" /> <input type="submit" value="Update"> </form> - +{{ end }} <h3>Version information</h3> <pre><code>{{.Version}}</pre></code> @@ -97,10 +137,20 @@ func index(w http.ResponseWriter, r *http.Request) { err := Templ.ExecuteTemplate(w, "index", struct { - Lib *steam.Library - Info *statusInfo + Lib *steam.Library + Info *statusInfo + Local bool + HostIP string + Port string Version string - }{Lib, status.s, Version}) + }{ + Lib, + status.s, + isLocal(r.RemoteAddr), + getHostIP(), + getPort(), + Version, + }) if err != nil { Logger.Printf("While Rendering template: %s", err) } diff --git a/cmd/web/install.go b/cmd/web/install.go index aae4191..63faaf6 100644 --- a/cmd/web/install.go +++ b/cmd/web/install.go @@ -83,6 +83,11 @@ func installer(urls <-chan string) { } func gameInstaller(w http.ResponseWriter, r *http.Request) { + if unauthorizedIfNotLocal(w, r) { + return + } + + err := r.ParseForm() if err != nil { Logger.Printf("Installer: While parsing form: %s", err) diff --git a/cmd/web/main.go b/cmd/web/main.go index ec0704d..0f76670 100644 --- a/cmd/web/main.go +++ b/cmd/web/main.go @@ -5,8 +5,10 @@ import ( "fmt" "log" "math/rand" + "net" "net/http" "os" + "strings" "sync" "time" @@ -16,8 +18,8 @@ import ( var ( Version = "Development" - Logger = log.New(os.Stderr, "", log.LstdFlags) - Listen = ":8899" + Logger = log.New(os.Stderr, "", log.LstdFlags) + Listen = ":8899" libMu = &sync.RWMutex{} Lib *steam.Library @@ -38,6 +40,10 @@ func reloadLib() { } func setLibHandler(w http.ResponseWriter, r *http.Request) { + if unauthorizedIfNotLocal(w, r) { + return + } + err := r.ParseForm() if err != nil { Logger.Printf("Setlib: While parsing form: %s", err) @@ -51,16 +57,75 @@ func setLibHandler(w http.ResponseWriter, r *http.Request) { } func quitHandler(w http.ResponseWriter, r *http.Request) { + if unauthorizedIfNotLocal(w, r) { + return + } + Logger.Println("Quit was called, exiting") w.Header().Add("Content-type", "text/plain") w.Write([]byte("Shutting down...")) go func() { - time.Sleep(time.Second*2) + time.Sleep(time.Second * 2) os.Exit(0) }() return } +func unauthorizedIfNotLocal(w http.ResponseWriter, r *http.Request) bool { + if !isLocal(r.RemoteAddr) { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + Logger.Printf("Unauthorized request from: %s for %s", + r.RemoteAddr, r.RequestURI) + return true + } + return false +} + +func isLocal(addr string) bool { + _, localNet, _ := net.ParseCIDR("127.0.0.1/8") + return localNet.Contains(net.ParseIP(strings.Split(addr, ":")[0])) +} + +// getHostIP attempts to guess the IP address of the current machine and +// returns that. Simply bails at the first non loopback IP returning that. +// not ideal but it should work well enough most of the time +func getHostIP() string { + iFaces, err := net.Interfaces() + if err != nil { + return "127.0.0.1" + } + + for _, iFace := range iFaces { + addrs, err := iFace.Addrs() + if err != nil { + return "127.0.0.1" + } + + for _, a := range addrs { + n, ok := a.(*net.IPNet) + if !ok { + continue + } + + if n.IP.To4() != nil && !n.IP.IsLoopback() { + return n.IP.String() + } + } + } + + return "127.0.0.1" +} + +func getPort() string { + s := strings.Split(Listen, ":") + + if len(s) != 2 { + return Listen + } + + return s[1] +} + func main() { fl := flag.NewFlagSet("steam-export", flag.ExitOnError) debug := fl.Bool("d", false, "Print line numbers in log") @@ -86,6 +151,7 @@ func main() { r.HandleFunc("/setLib", setLibHandler) r.HandleFunc("/delete", gameDelete) r.HandleFunc("/install", gameInstaller) + r.HandleFunc("/steam-export-web.exe", serveSelf) r.HandleFunc("/download/{game}", gameDownloader) r.HandleFunc("/style.css", cssHandler) r.HandleFunc("/", index) diff --git a/cmd/web/serve-self.go b/cmd/web/serve-self.go new file mode 100644 index 0000000..103fbf1 --- /dev/null +++ b/cmd/web/serve-self.go @@ -0,0 +1,27 @@ +package main + +import ( + "io" + "os" + "net/http" +) + +func serveSelf(w http.ResponseWriter, r *http.Request) { + s, err := os.Executable() + if err != nil { + Logger.Println("While trying to get my executable path: ", err) + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + + fh, err := os.Open(s) + if err != nil { + Logger.Println("While opening my own executable for reading: ", err) + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + + _, err = io.Copy(w, fh) + fh.Close() + return +} |
