-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Draft: Serve custom page when directory listing is disabled
- Loading branch information
Showing
4 changed files
with
149 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
module github.com/loophole/cli | ||
|
||
go 1.14 | ||
go 1.16 | ||
|
||
require ( | ||
github.com/abbot/go-http-auth v0.4.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
//necessary bits and pieces for being able to serve e.g. the custom notification html | ||
// without needing to create files in the users folders | ||
package customfilesystem | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"io/fs" | ||
"net/http" | ||
"path/filepath" | ||
) | ||
|
||
var DirectoryListingDisabledPage = []byte("<!DOCTYPE html><html><body><img src=\"https://raw.githubusercontent.com/loophole/website/master/static/img/logo.png\" alt=\"https://raw.githubusercontent.com/loophole/website/master/static/img/logo.png\" class=\"transparent shrinkToFit\" width=\"400\" height=\"88\"><p>Directory index listing has been disabled. Please enter the path of a file.</p></body></html>") | ||
|
||
type CustomFileSystem struct { | ||
FS http.FileSystem | ||
} | ||
|
||
//the file cannot be reused since it's io.Reader can only be read from once, | ||
// so we need a reusable way to create it | ||
func writeDirectoryListingDisabledPageFile(pageFile *MyFile) { | ||
*pageFile = MyFile{ | ||
Reader: bytes.NewReader(DirectoryListingDisabledPage), | ||
mif: myFileInfo{ | ||
name: "customIndex.html", | ||
data: DirectoryListingDisabledPage, | ||
}, | ||
} | ||
} | ||
|
||
func (cfs CustomFileSystem) Open(path string) (http.File, error) { | ||
f, err := _Open(path, cfs) | ||
|
||
if err != nil { | ||
var pathErrorInstance error = &fs.PathError{ | ||
Err: errors.New(""), | ||
} | ||
if errors.As(err, &pathErrorInstance) { | ||
return nil, err | ||
} | ||
var pageFile *MyFile = &MyFile{} | ||
writeDirectoryListingDisabledPageFile(pageFile) | ||
return pageFile, nil | ||
} | ||
return f, nil | ||
} | ||
|
||
//if there is an elegant way to integrate the following into the function above without | ||
// using labeled breaks or adding even more control structures let me know | ||
func _Open(path string, cfs CustomFileSystem) (http.File, error) { | ||
f, err := cfs.FS.Open(path) | ||
if err != nil { | ||
if path == "/" { | ||
var pageFile *MyFile = &MyFile{} | ||
writeDirectoryListingDisabledPageFile(pageFile) | ||
return pageFile, nil | ||
} | ||
return nil, err | ||
} | ||
|
||
s, err := f.Stat() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if s.IsDir() { | ||
index := filepath.Join(path, "index.html") | ||
if _, err := cfs.FS.Open(index); err != nil { | ||
var pageFile *MyFile = &MyFile{} | ||
writeDirectoryListingDisabledPageFile(pageFile) | ||
return pageFile, nil | ||
} | ||
} | ||
return f, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
//taken from https://stackoverflow.com/questions/52697277/simples-way-to-make-a-byte-into-a-virtual-file-object-in-golang | ||
package customfilesystem | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"os" | ||
"time" | ||
) | ||
|
||
type File interface { | ||
io.Closer | ||
io.Reader | ||
io.Seeker | ||
Readdir(count int) ([]os.FileInfo, error) | ||
Stat() (os.FileInfo, error) | ||
} | ||
|
||
type myFileInfo struct { | ||
name string | ||
data []byte | ||
} | ||
|
||
func (mif myFileInfo) Name() string { return mif.name } | ||
func (mif myFileInfo) Size() int64 { return int64(len(mif.data)) } | ||
func (mif myFileInfo) Mode() os.FileMode { return 0444 } // Read for all | ||
func (mif myFileInfo) ModTime() time.Time { return time.Time{} } // Return anything | ||
func (mif myFileInfo) IsDir() bool { return false } | ||
func (mif myFileInfo) Sys() interface{} { return nil } | ||
|
||
type MyFile struct { | ||
*bytes.Reader | ||
mif myFileInfo | ||
} | ||
|
||
func (mf *MyFile) Close() error { return nil } // Noop, nothing to do | ||
|
||
func (mf *MyFile) Readdir(count int) ([]os.FileInfo, error) { | ||
return nil, nil // We are not a directory but a single file | ||
} | ||
|
||
func (mf *MyFile) Stat() (os.FileInfo, error) { | ||
return mf.mif, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters