From b92f5cfb43c1d885c6a375332141e959cff2ed86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ken-H=C3=A5vard=20Lieng?= Date: Sun, 17 May 2020 03:55:46 +0200 Subject: [PATCH] Send download link on completion --- client/js/sw.js | 6 +++++- pkg/irc/dcc.go | 12 ++++++++---- server/irc_handler.go | 17 ++++++++++++++++- server/server.go | 28 ++++++++++++++++++++++++++++ server/websocket_handler.go | 6 ++++++ storage/directory.go | 4 ++++ 6 files changed, 67 insertions(+), 6 deletions(-) diff --git a/client/js/sw.js b/client/js/sw.js index cc70f733..d628dbdb 100644 --- a/client/js/sw.js +++ b/client/js/sw.js @@ -10,4 +10,8 @@ precacheAndRoute(self.__WB_MANIFEST, { }); const handler = createHandlerBoundToURL('/'); -registerRoute(new NavigationRoute(handler)); +registerRoute( + new NavigationRoute(handler, { + denylist: [new RegExp('/downloads/')] + }) +); diff --git a/pkg/irc/dcc.go b/pkg/irc/dcc.go index 9461cd7f..f2e269cc 100644 --- a/pkg/irc/dcc.go +++ b/pkg/irc/dcc.go @@ -73,7 +73,6 @@ func (c *Client) Download(pack *DCCSend) { defer file.Close() con, err := net.Dial("tcp", fmt.Sprintf("%s:%d", pack.IP, pack.Port)) - if err != nil { c.Progress <- DownloadProgress{ PercCompletion: -1, @@ -86,7 +85,7 @@ func (c *Client) Download(pack *DCCSend) { defer con.Close() var speed float64 - var prevPerc float64 + var prevUpdate time.Time secondsElapsed := int64(0) totalBytes := uint64(0) buf := make([]byte, 0, 4*1024) @@ -120,9 +119,12 @@ func (c *Client) Download(pack *DCCSend) { secondsElapsed = (now - start) / 1e9 speed = round2(float64(totalBytes) / (float64(secondsElapsed))) secondsToGo := round2((float64(pack.Length) - float64(totalBytes)) / speed) + con.Write(byteRead(totalBytes)) - if percentage-prevPerc >= 0.1 { - prevPerc = percentage + + if time.Since(prevUpdate) >= time.Second { + prevUpdate = time.Now() + c.Progress <- DownloadProgress{ Speed: humanReadableByteCount(speed, true), PercCompletion: percentage, @@ -134,7 +136,9 @@ func (c *Client) Download(pack *DCCSend) { } } } + con.Write(byteRead(totalBytes)) + c.Progress <- DownloadProgress{ Speed: humanReadableByteCount(speed, true), PercCompletion: 100, diff --git a/server/irc_handler.go b/server/irc_handler.go index fa793456..c5d1ab8d 100644 --- a/server/irc_handler.go +++ b/server/irc_handler.go @@ -63,8 +63,23 @@ func (i *ircHandler) run() { } else if state.Connected { i.log("Connected") } + case progress := <-i.client.Progress: - i.state.sendJSON("pm", Message{Server: i.client.Host, From: "@dcc", Content: progress.ToJSON()}) + if progress.PercCompletion == 100 { + i.state.sendJSON("pm", Message{ + Server: i.client.Host, + From: "@dcc", + Content: fmt.Sprintf("%s://%s/downloads/%s/%s", i.state.String("scheme"), + i.state.String("host"), i.state.user.Username, progress.File), + }) + } else { + i.state.sendJSON("pm", Message{ + Server: i.client.Host, + From: "@dcc", + Content: fmt.Sprintf("%s: %.2f%% %s remaining, %.2fs left", progress.File, + progress.PercCompletion, progress.BytesRemaining, progress.SecondsToGo), + }) + } } } } diff --git a/server/server.go b/server/server.go index 75c1bff2..4aec34b7 100644 --- a/server/server.go +++ b/server/server.go @@ -3,6 +3,7 @@ package server import ( "log" "net/http" + "strconv" "strings" "sync" @@ -180,6 +181,33 @@ func (d *Dispatch) ServeHTTP(w http.ResponseWriter, r *http.Request) { } d.upgradeWS(w, r, state) + } else if strings.HasPrefix(r.URL.Path, "/downloads") { + state := d.handleAuth(w, r, false, false) + if state == nil { + log.Println("[Auth] No state") + fail(w, http.StatusInternalServerError) + return + } + + params := strings.Split(strings.Trim(r.URL.Path, "/"), "/") + + if len(params) == 3 { + userID, err := strconv.ParseUint(params[1], 10, 64) + if err != nil { + fail(w, http.StatusBadRequest) + } + + if userID != state.user.ID { + fail(w, http.StatusUnauthorized) + } + + filename := params[2] + + w.Header().Set("Content-Disposition", "attachment; filename="+filename) + http.ServeFile(w, r, storage.Path.DownloadedFile(state.user.Username, filename)) + } else { + fail(w, http.StatusNotFound) + } } else { d.serveFiles(w, r) } diff --git a/server/websocket_handler.go b/server/websocket_handler.go index f6207e77..0ce34557 100644 --- a/server/websocket_handler.go +++ b/server/websocket_handler.go @@ -63,6 +63,12 @@ func (h *wsHandler) dispatchRequest(req WSRequest) { func (h *wsHandler) init(r *http.Request) { h.state.setWS(h.addr.String(), h.ws) h.state.user.SetLastIP(addrToIPBytes(h.addr)) + if r.TLS != nil { + h.state.Set("scheme", "https") + } else { + h.state.Set("scheme", "http") + } + h.state.Set("host", r.Host) log.Println(h.addr, "[State] User ID:", h.state.user.ID, "|", h.state.numIRC(), "IRC connections |", diff --git a/storage/directory.go b/storage/directory.go index 55ad3272..4b99ac83 100644 --- a/storage/directory.go +++ b/storage/directory.go @@ -56,6 +56,10 @@ func (d directory) Downloads(username string) string { return filepath.Join(d.User(username), "downloads") } +func (d directory) DownloadedFile(username string, file string) string { + return filepath.Join(d.Downloads(username), file) +} + func (d directory) Config() string { return filepath.Join(d.ConfigRoot(), "config.toml") }