From 0dc4bd3c9abf33346486379db932e6591205c488 Mon Sep 17 00:00:00 2001 From: akuma06 Date: Sun, 28 May 2017 01:29:46 +0200 Subject: [PATCH] Torrent name when download New Download Torrent controller when dowloading a torrent Route download need to be set the same as in TorrentStorageLink --- router/router.go | 4 +++ router/view_torrent_handler.go | 47 ++++++++++++++++++++++++++++++++++ service/torrent/torrent.go | 15 +++++++++-- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/router/router.go b/router/router.go index 5bd83037..f2301665 100755 --- a/router/router.go +++ b/router/router.go @@ -29,6 +29,7 @@ func init() { gzipUserProfileHandler := http.HandlerFunc(UserProfileHandler) gzipUserAPIKeyResetHandler := http.HandlerFunc(UserAPIKeyResetHandler) gzipUserDetailsHandler := http.HandlerFunc(UserDetailsHandler) + downloadTorrentHandler := http.HandlerFunc(DownloadTorrent) gzipUserProfileFormHandler := http.HandlerFunc(UserProfileFormHandler) gzipUserNotificationsHandler := http.HandlerFunc(UserNotificationsHandler) gzipDumpsHandler := handlers.CompressHandler(dumpsHandler) @@ -78,6 +79,9 @@ func init() { Router.HandleFunc("/user/{id}/{username}/feed", RSSHandler).Name("feed_user") Router.HandleFunc("/user/{id}/{username}/feed/{page}", RSSHandler).Name("feed_user_page") + // !!! This line need to have the same download location as the one define in config.TorrentStorageLink !!! + Router.Handle("/download/{hash}", wrapHandler(downloadTorrentHandler)).Name("torrent_download") + // INFO Everything under /mod should be wrapped by wrapModHandler. This make // sure the page is only accessible by moderators // TODO Find a native mux way to add a 'prehook' for route /mod diff --git a/router/view_torrent_handler.go b/router/view_torrent_handler.go index 9e6d4b26..d184fc31 100644 --- a/router/view_torrent_handler.go +++ b/router/view_torrent_handler.go @@ -2,11 +2,15 @@ package router import ( "fmt" + "io" "net/http" "strconv" "strings" "time" + "os" + + "github.com/NyaaPantsu/nyaa/config" "github.com/NyaaPantsu/nyaa/db" "github.com/NyaaPantsu/nyaa/model" "github.com/NyaaPantsu/nyaa/service" @@ -242,3 +246,46 @@ func TorrentDeleteUserPanel(w http.ResponseWriter, r *http.Request) { NotFoundHandler(w, r) } } + +// DownloadTorrent : Controller for downloading a torrent +func DownloadTorrent(w http.ResponseWriter, r *http.Request) { + defer r.Body.Close() + vars := mux.Vars(r) + hash := vars["hash"] + + if hash == "" && len(config.TorrentFileStorage) == 0 { + //File not found, send 404 + http.Error(w, "File not found.", 404) + return + } + + //Check if file exists and open + Openfile, err := os.Open(fmt.Sprintf("%s%c%s.torrent", config.TorrentFileStorage, os.PathSeparator, hash)) + defer Openfile.Close() //Close after function return + if err != nil { + //File not found, send 404 + http.Error(w, "File not found.", 404) + return + } + + //Get the file size + FileStat, _ := Openfile.Stat() //Get info from file + FileSize := strconv.FormatInt(FileStat.Size(), 10) //Get file size as a string + + torrent, err := torrentService.GetRawTorrentByHash(hash) + + if err != nil { + //File not found, send 404 + http.Error(w, "File not found.", 404) + return + } + + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s.torrent\"", torrent.Name)) + w.Header().Set("Content-Type", "application/x-bittorrent") + w.Header().Set("Content-Length", FileSize) + //Send the file + // We reset the offset to 0 + Openfile.Seek(0, 0) + io.Copy(w, Openfile) //'Copy' the file to the client + return +} diff --git a/service/torrent/torrent.go b/service/torrent/torrent.go index 88bed8cd..7ec2f438 100644 --- a/service/torrent/torrent.go +++ b/service/torrent/torrent.go @@ -2,11 +2,12 @@ package torrentService import ( "errors" - elastic "gopkg.in/olivere/elastic.v5" "net/http" "strconv" "strings" + elastic "gopkg.in/olivere/elastic.v5" + "github.com/NyaaPantsu/nyaa/config" "github.com/NyaaPantsu/nyaa/db" "github.com/NyaaPantsu/nyaa/model" @@ -99,7 +100,17 @@ func GetTorrentByID(id string) (torrent model.Torrent, err error) { func GetRawTorrentByID(id uint) (torrent model.Torrent, err error) { err = nil if db.ORM.Where("torrent_id = ?", id).Find(&torrent).RecordNotFound() { - err = errors.New("Article is not found") + err = errors.New("Torrent is not found") + } + return +} + +// GetRawTorrentByHash : Get torrent with id without user or comments +// won't fetch user or comments +func GetRawTorrentByHash(hash string) (torrent model.Torrent, err error) { + err = nil + if db.ORM.Where("torrent_hash = ?", hash).Find(&torrent).RecordNotFound() { + err = errors.New("Torrent is not found") } return }