Compare commits

...

3 Commits

Author SHA1 Message Date
vxclutch
d18838dfee feat: share link 2026-05-28 08:25:59 -04:00
vxclutch
363c3b6c96 maint: comment source code 2026-05-28 07:55:10 -04:00
vxclutch
b436415980 feat: port flag 2026-05-28 07:44:33 -04:00
8 changed files with 56 additions and 9 deletions

5
TODO
View File

@@ -1,9 +1,6 @@
maint: clean up source code
maint: comment source code
maint: document more
maint: make the colors more cross platform
feat: improve flags
-p for port
feat: replace uuid dep with custom id generator
feat: multiple files
feat: share link
maint: make the colors more cross platform

View File

@@ -7,11 +7,14 @@ import (
"lash"
"lash/internal/app"
"lash/internal/errx"
share "lash/internal/shareLink"
"net/http"
)
var versionFlag = flag.Bool("version", false, "Print out version and exit.")
var port = flag.Int("p", 1337, "Set the port for LASH exchanges.")
func main() {
flag.Parse()
@@ -22,10 +25,12 @@ func main() {
srv := app.New()
// TODO(vxc): Make this more portable
errx.Log("Your share link is %s", share.GenerateShareLink(*port))
errx.Log("Your token is \033[1;92m%s\033[0m", lash.Token)
errx.Log("starting server at http://0.0.0.0:1337")
if err := http.ListenAndServe(":1337", srv); err != nil {
errx.Log("starting server at http://0.0.0.0:%d", *port)
if err := http.ListenAndServe(fmt.Sprintf(":%d", *port), srv); err != nil {
errx.FatalPerror(err)
}
}

View File

@@ -2,14 +2,14 @@ package app
import (
"errors"
"os"
"flag"
"strings"
)
func GetFilePath() (string, error) {
fp := ""
for _, v := range os.Args[1:] {
for _, v := range flag.Args() {
if !strings.HasPrefix(v, "-") {
fp = v
return fp, nil

View File

@@ -22,7 +22,7 @@ func New() http.Handler {
}
share := handlers.ShareData{
Version: lash.Version,
Version: lash.Version,
}
file := handlers.FileData{
@@ -32,6 +32,7 @@ func New() http.Handler {
mux.HandleFunc("/", share.Handler)
mux.HandleFunc("/api/receive-token", file.APIHandler)
mux.HandleFunc("/"+lash.ShareLinkToken, file.FileHandler)
return mux
}

View File

@@ -32,6 +32,17 @@ func (h FileData) APIHandler(w http.ResponseWriter, r *http.Request) {
return
}
// Send the file over as a stream of bytes
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", h.FileName))
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Length", strconv.Itoa(len(h.Contents)))
w.WriteHeader(http.StatusOK)
w.Write(h.Contents)
}
func (h FileData) FileHandler(w http.ResponseWriter, r *http.Request) {
// Send the file over as a stream of bytes
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", h.FileName))
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Length", strconv.Itoa(len(h.Contents)))

View File

@@ -13,6 +13,7 @@ type ShareData struct {
}
func (h *ShareData) Handler(w http.ResponseWriter, r *http.Request) {
// Although `Must` can fail since `Templates` is embeded these files will always exist.
tmpl := template.Must(template.ParseFS(lash.Templates, "templates/share.html"))
if err := tmpl.ExecuteTemplate(w, "share.html", h); err != nil {

View File

@@ -0,0 +1,29 @@
package sharelink
import (
"fmt"
"lash"
"lash/internal/errx"
"net"
)
func GenerateShareLink(port int) string {
link := "http://"
link += getLocalIP()
link += fmt.Sprintf(":%d", port)
link += "/"
link += lash.ShareLinkToken
return link
}
func getLocalIP() string {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
errx.FatalPerror(err)
}
defer conn.Close()
localAddress := conn.LocalAddr().(*net.UDPAddr)
return localAddress.IP.String()
}

View File

@@ -12,4 +12,7 @@ var Templates embed.FS
//go:embed version
var Version string
// TODO(vxc): Replace this with custom token generator
var Token string = uuid.New().String()
var ShareLinkToken string = uuid.New().String()