From 8db4a359949666b1c9dc8ee5cc00b086ddd3344b Mon Sep 17 00:00:00 2001 From: Gabriel Simmer Date: Wed, 15 Apr 2020 12:16:27 +0100 Subject: [PATCH] Better handling of serving files, frontend tweaks. Implemented a few new functions to handle the differences between local and remote files - local files will be served (best it can be) with ServeContent(), while remote files will be passed through from the response body directly to the response writer. This isn't a very elegant solution right now, but hoping to refactor this approach and simplify the decision logic. However, serving files from local disks is much better, including improvements to video files and generally better handling of metadata. Also some small tweaks to the frontned to align things a little nicer. --- assets/web/css/styles.css | 19 ++++++++----------- assets/web/javascript/app.js | 3 +-- files/backblaze.go | 11 +++++++---- files/disk.go | 32 +++++++++++++++----------------- files/fileprovider.go | 18 +++++++++++------- files/files_test.go | 17 +++++++---------- router/filerouter.go | 16 ++++++++++++++-- 7 files changed, 63 insertions(+), 53 deletions(-) diff --git a/assets/web/css/styles.css b/assets/web/css/styles.css index 0931783..611b274 100644 --- a/assets/web/css/styles.css +++ b/assets/web/css/styles.css @@ -102,16 +102,6 @@ body, h1 a { } } -.forms { - margin: 0 auto; - width: 40%; -} - -form { - display: inline-block; - width: 30%; -} - @media only screen and (max-width: 1170px) { .grid-lg { display: block; @@ -200,7 +190,14 @@ button { background-color: var(--blue); } -.item { +.item, .forms { display: flex; +} +.item { justify-content: center; +} +.forms { + width: 40%; + margin: 0 auto; + justify-content: space-around; } \ No newline at end of file diff --git a/assets/web/javascript/app.js b/assets/web/javascript/app.js index cc81d04..8f4d0ff 100644 --- a/assets/web/javascript/app.js +++ b/assets/web/javascript/app.js @@ -27,7 +27,7 @@ function getFileListing(provider, path = "") {
- +
@@ -81,7 +81,6 @@ function getProviders() { // Dumb router function for passing around values from the hash. function router(event = null) { let hash = location.hash.replace("#", "") - console.log(hash) // If hash is empty, "redirect" to index. if (hash === "") { getProviders() diff --git a/files/backblaze.go b/files/backblaze.go index b414c9e..ce09b97 100644 --- a/files/backblaze.go +++ b/files/backblaze.go @@ -138,7 +138,11 @@ func (bp *BackblazeProvider) GetDirectory(path string) Directory { return finalDir } -func (bp *BackblazeProvider) ViewFile(path string, w io.Writer) { +func (bp *BackblazeProvider) ViewFile(path string) string { + return "" +} + +func (bp *BackblazeProvider) RemoteFile(path string, w io.Writer) { client := &http.Client{} // Get bucket name >:( bucketIdPayload := fmt.Sprintf(`{"accountId": "%s", "bucketId": "%s"}`, bp.Name, bp.Bucket) @@ -244,7 +248,6 @@ func (bp *BackblazeProvider) SaveFile(file io.Reader, filename string, path stri req.Header.Add("X-Bz-Content-Sha1", fmt.Sprintf("%x", fileSha.Sum(nil))) req.ContentLength = int64(len(bodyBytes)) - // Upload in background. res, err = client.Do(req) if err != nil { fmt.Println(err.Error()) @@ -254,10 +257,10 @@ func (bp *BackblazeProvider) SaveFile(file io.Reader, filename string, path stri return true } -func (bp *BackblazeProvider) DetermineType(path string) string { +func (bp *BackblazeProvider) ObjectInfo(path string) (string, string) { // B2 is really a "flat" filesystem, with directories being virtual. // Therefore, we can assume everything is a file ;) - return "file" + return "file", "remote" } func (bp *BackblazeProvider) CreateDirectory(path string) bool { diff --git a/files/disk.go b/files/disk.go index 004bb51..aea3f45 100644 --- a/files/disk.go +++ b/files/disk.go @@ -42,16 +42,13 @@ func (dp *DiskProvider) GetDirectory(path string) Directory { } } -func (dp *DiskProvider) ViewFile(path string, w io.Writer) { - file := strings.Join([]string{dp.Location,path}, "/") - fileReader, err := os.Open(file) - if err != nil { - return - } - _, err = io.Copy(w, fileReader) - if err != nil { - return - } +func (dp *DiskProvider) ViewFile(path string) string { + rp := strings.Join([]string{dp.Location,path}, "/") + return rp +} + +func (dp *DiskProvider) RemoteFile(path string, writer io.Writer) { + return } func (dp *DiskProvider) SaveFile(file io.Reader, filename string, path string) bool { @@ -71,17 +68,18 @@ func (dp *DiskProvider) SaveFile(file io.Reader, filename string, path string) b return true } -func (dp *DiskProvider) DetermineType(path string) string { +func (dp *DiskProvider) ObjectInfo(path string) (string, string) { rp := strings.Join([]string{dp.Location,path}, "/") - file, err := os.Stat(rp) + fileStat, err := os.Stat(rp) if err != nil { - return "" - } - if file.IsDir() { - return "directory" + fmt.Printf("error stat'ing file %v: %v", rp, err.Error()) + return "", "" } - return "file" + if fileStat.IsDir() { + return "directory", "" + } + return "file", "local" } func (dp *DiskProvider) CreateDirectory(path string) bool { diff --git a/files/fileprovider.go b/files/fileprovider.go index ab1163e..15b9dbe 100644 --- a/files/fileprovider.go +++ b/files/fileprovider.go @@ -31,9 +31,10 @@ type FileContents struct { type FileProviderInterface interface { Setup(args map[string]string) bool GetDirectory(path string) Directory - ViewFile(path string, w io.Writer) + ViewFile(path string) string + RemoteFile(path string, writer io.Writer) SaveFile(file io.Reader, filename string, path string) bool - DetermineType(path string) string + ObjectInfo(path string) (string, string) CreateDirectory(path string) bool Delete(path string) bool } @@ -47,7 +48,11 @@ func (f FileProvider) GetDirectory(path string) Directory { return Directory{} } -func (f FileProvider) ViewFile(path string, w io.Writer) { +func (f FileProvider) ViewFile(path string) string { + return "" +} + +func (f FileProvider) RemoteFile(path string, writer io.Writer) { return } @@ -55,8 +60,8 @@ func (f FileProvider) SaveFile(file io.Reader, filename string, path string) boo return false } -func (f FileProvider) DetermineType(path string) string { - return "" +func (f FileProvider) ObjectInfo(path string) (string, string) { + return "", "" } func (f FileProvider) CreateDirectory(path string) bool { @@ -65,5 +70,4 @@ func (f FileProvider) CreateDirectory(path string) bool { func (f FileProvider) Delete(path string) bool { return false -} - +} \ No newline at end of file diff --git a/files/files_test.go b/files/files_test.go index b32607b..7d09b34 100644 --- a/files/files_test.go +++ b/files/files_test.go @@ -24,8 +24,7 @@ func TestFileProvider(t *testing.T) { t.Errorf("Default FileProvider GetDirectory() files returned %v, expected none.", getdirectory.Files) } - var w bytes.Buffer - fp.ViewFile("", &w); if len(w.Bytes()) > 0 { + viewfile := fp.ViewFile(""); if viewfile != "" { t.Errorf("Default FileProvider ViewFile() %v, expected nothing.", w) } @@ -33,8 +32,8 @@ func TestFileProvider(t *testing.T) { t.Errorf("Default FileProvider SaveFile() attempted to save a file.") } - determinetype := fp.DetermineType(""); if determinetype != "" { - t.Errorf("Default FileProvider DetermineType() did not return an empty string.") + determinetype := fp.ObjectInfo(""); if determinetype != "" { + t.Errorf("Default FileProvider ObjectInfo() did not return an empty string.") } createdirectory := fp.CreateDirectory(""); if createdirectory { @@ -88,10 +87,8 @@ func TestDiskProvider(t *testing.T) { t.Errorf("DiskProvider GetDirectory() files returned %v, expected 1.", getdirectory.Files) } - var w bytes.Buffer - dp.ViewFile("testing.txt", &w); if w.String() != "testing file!" { - fmt.Println(w) - t.Errorf("DiskProvider ViewFile() returned %v, expected \"testing file!\".", w.String()) + viewfile := dp.ViewFile("testing.txt"); if viewfile != DISK_TESTING_GROUNDS + "testing.txt"{ + t.Errorf("DiskProvider ViewFile() returned %v, expected path.", viewfile) } testfile := bytes.NewReader([]byte("second test file!")) @@ -99,8 +96,8 @@ func TestDiskProvider(t *testing.T) { t.Errorf("DiskProvider SaveFile() could not save a file.") } - determinetype := dp.DetermineType("second_test.txt"); if determinetype != "file" { - t.Errorf("DiskProvider DetermineType() returned %v, expected \"file\".", determinetype) + determinetype := dp.ObjectInfo("second_test.txt"); if determinetype != "file" { + t.Errorf("DiskProvider ObjectInfo() returned %v, expected \"file\".", determinetype) } createdirectory := dp.CreateDirectory("test_dir"); if !createdirectory { diff --git a/router/filerouter.go b/router/filerouter.go index 61dfe4f..e5f4561 100644 --- a/router/filerouter.go +++ b/router/filerouter.go @@ -7,8 +7,10 @@ import ( "github.com/gorilla/mux" "net/http" "net/url" + "os" "sort" "strings" + "time" ) func HandleProvider() Handler { @@ -29,7 +31,8 @@ func HandleProvider() Handler { StatusCode: http.StatusInternalServerError, } } - fileType := provider.DetermineType(filename) + fileType, location := provider.ObjectInfo(filename) + if fileType == "" { return &HTTPError{ Message: fmt.Sprintf("error determining filetype for %s\n", filename), @@ -37,7 +40,16 @@ func HandleProvider() Handler { } } if fileType == "file" { - provider.ViewFile(filename, w) + if location == "local" { + rp := provider.ViewFile(filename) + if rp != "" { + f, _ := os.Open(rp) + http.ServeContent(w, r, filename, time.Time{}, f) + } + } + if location == "remote" { + provider.RemoteFile(filename, w) + } return nil } fileList = provider.GetDirectory(filename)