more updates

pull/144/head
Henrique Dias 2017-06-19 18:07:03 +01:00
parent 8c19482190
commit af4aaf07df
No known key found for this signature in database
GPG Key ID: 936F5EB68D786730
17 changed files with 167 additions and 189 deletions

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"bytes" "bytes"
@ -7,13 +7,12 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
fm "github.com/hacdias/filemanager"
"github.com/hacdias/filemanager/frontmatter" "github.com/hacdias/filemanager/frontmatter"
"github.com/spf13/hugo/parser" "github.com/spf13/hugo/parser"
) )
// Editor contains the information for the editor page // editor contains the information for the editor page
type Editor struct { type editor struct {
Class string Class string
Mode string Mode string
Visual bool Visual bool
@ -24,12 +23,12 @@ type Editor struct {
} }
} }
// getEditor gets the editor based on a FileInfo struct // newEditor gets the editor based on a FileInfo struct
func getEditor(r *http.Request, i *fm.FileInfo) (*Editor, error) { func newEditor(r *http.Request, i *file) (*editor, error) {
var err error var err error
// Create a new editor variable and set the mode // Create a new editor variable and set the mode
e := new(Editor) e := new(editor)
e.Mode = editorMode(i.Name) e.Mode = editorMode(i.Name)
e.Class = editorClass(e.Mode) e.Class = editorClass(e.Mode)

22
file.go
View File

@ -13,8 +13,8 @@ import (
humanize "github.com/dustin/go-humanize" humanize "github.com/dustin/go-humanize"
) )
// FileInfo contains the information about a particular file or directory. // file contains the information about a particular file or directory.
type FileInfo struct { type file struct {
Name string Name string
Size int64 Size int64
URL string URL string
@ -30,11 +30,11 @@ type FileInfo struct {
UserAllowed bool // Indicates if the user has enough permissions UserAllowed bool // Indicates if the user has enough permissions
} }
// GetInfo retrieves the file information and the error, if there is any. // getFile retrieves the file information and the error, if there is any.
func GetInfo(url *url.URL, c *Config, u *User) (*FileInfo, error) { func getFile(url *url.URL, c *Config, u *User) (*file, error) {
var err error var err error
i := &FileInfo{URL: c.PrefixURL + url.Path} i := &file{URL: c.PrefixURL + url.Path}
i.VirtualPath = strings.Replace(url.Path, c.BaseURL, "", 1) i.VirtualPath = strings.Replace(url.Path, c.BaseURL, "", 1)
i.VirtualPath = strings.TrimPrefix(i.VirtualPath, "/") i.VirtualPath = strings.TrimPrefix(i.VirtualPath, "/")
i.VirtualPath = "/" + i.VirtualPath i.VirtualPath = "/" + i.VirtualPath
@ -75,7 +75,7 @@ var textExtensions = [...]string{
// RetrieveFileType obtains the mimetype and a simplified internal Type // RetrieveFileType obtains the mimetype and a simplified internal Type
// using the first 512 bytes from the file. // using the first 512 bytes from the file.
func (i *FileInfo) RetrieveFileType() error { func (i *file) RetrieveFileType() error {
i.Mimetype = mime.TypeByExtension(i.Extension) i.Mimetype = mime.TypeByExtension(i.Extension)
if i.Mimetype == "" { if i.Mimetype == "" {
@ -126,7 +126,7 @@ func (i *FileInfo) RetrieveFileType() error {
} }
// Reads the file. // Reads the file.
func (i *FileInfo) Read() error { func (i *file) Read() error {
if len(i.Content) != 0 { if len(i.Content) != 0 {
return nil return nil
} }
@ -140,22 +140,22 @@ func (i *FileInfo) Read() error {
} }
// StringifyContent returns the string version of Raw // StringifyContent returns the string version of Raw
func (i FileInfo) StringifyContent() string { func (i file) StringifyContent() string {
return string(i.Content) return string(i.Content)
} }
// HumanSize returns the size of the file as a human-readable string // HumanSize returns the size of the file as a human-readable string
// in IEC format (i.e. power of 2 or base 1024). // in IEC format (i.e. power of 2 or base 1024).
func (i FileInfo) HumanSize() string { func (i file) HumanSize() string {
return humanize.IBytes(uint64(i.Size)) return humanize.IBytes(uint64(i.Size))
} }
// HumanModTime returns the modified time of the file as a human-readable string. // HumanModTime returns the modified time of the file as a human-readable string.
func (i FileInfo) HumanModTime(format string) string { func (i file) HumanModTime(format string) string {
return i.ModTime.Format(format) return i.ModTime.Format(format)
} }
// CanBeEdited checks if the extension of a file is supported by the editor // CanBeEdited checks if the extension of a file is supported by the editor
func (i FileInfo) CanBeEdited() bool { func (i file) CanBeEdited() bool {
return i.Type == "text" return i.Type == "text"
} }

View File

@ -1,4 +1,4 @@
package page package filemanager
import ( import (
"encoding/base64" "encoding/base64"

View File

@ -1,4 +1,4 @@
package page package filemanager
import "testing" import "testing"

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"errors" "errors"
@ -7,21 +7,18 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
fm "github.com/hacdias/filemanager"
"github.com/hacdias/filemanager/assets"
"github.com/hacdias/filemanager/page"
"github.com/mholt/caddy/caddyhttp/httpserver" "github.com/mholt/caddy/caddyhttp/httpserver"
) )
// ServeHTTP starts FileManager. // ServeHTTP starts FileManager.
func ServeHTTP(w http.ResponseWriter, r *http.Request, c *fm.Config) (int, error) { func (c *Config) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
var ( var (
fi *fm.FileInfo fi *file
user *fm.User user *User
code int code int
err error err error
) )
/* TODO: readd this
// Checks if the URL matches the Assets URL. Returns the asset if the // Checks if the URL matches the Assets URL. Returns the asset if the
// method is GET and Status Forbidden otherwise. // method is GET and Status Forbidden otherwise.
if strings.HasPrefix(r.URL.Path, c.BaseURL+assets.BaseURL) { if strings.HasPrefix(r.URL.Path, c.BaseURL+assets.BaseURL) {
@ -30,7 +27,7 @@ func ServeHTTP(w http.ResponseWriter, r *http.Request, c *fm.Config) (int, error
} }
return http.StatusForbidden, nil return http.StatusForbidden, nil
} } */
// Obtains the user. // Obtains the user.
username, _, _ := r.BasicAuth() username, _, _ := r.BasicAuth()
@ -91,7 +88,7 @@ func ServeHTTP(w http.ResponseWriter, r *http.Request, c *fm.Config) (int, error
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }
if preProccessPUT(w, r, c, user) != nil { if c.preProccessPUT(w, r, user) != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }
} }
@ -111,7 +108,7 @@ func ServeHTTP(w http.ResponseWriter, r *http.Request, c *fm.Config) (int, error
// Checks if the User is allowed to access this file // Checks if the User is allowed to access this file
if !user.Allowed(strings.TrimPrefix(r.URL.Path, c.BaseURL)) { if !user.Allowed(strings.TrimPrefix(r.URL.Path, c.BaseURL)) {
if r.Method == http.MethodGet { if r.Method == http.MethodGet {
return page.PrintErrorHTML( return printError(
w, http.StatusForbidden, w, http.StatusForbidden,
errors.New("You don't have permission to access this page"), errors.New("You don't have permission to access this page"),
) )
@ -121,20 +118,20 @@ func ServeHTTP(w http.ResponseWriter, r *http.Request, c *fm.Config) (int, error
} }
if r.URL.Query().Get("search") != "" { if r.URL.Query().Get("search") != "" {
return search(w, r, c, user) return c.search(w, r, user)
} }
if r.URL.Query().Get("command") != "" { if r.URL.Query().Get("command") != "" {
return command(w, r, c, user) return c.command(w, r, user)
} }
if r.Method == http.MethodGet { if r.Method == http.MethodGet {
// Gets the information of the directory/file // Gets the information of the directory/file
fi, err = fm.GetInfo(r.URL, c, user) fi, err = getFile(r.URL, c, user)
code = errorToHTTPCode(err, false) code = errorToHTTPCode(err, false)
if err != nil { if err != nil {
if r.Method == http.MethodGet { if r.Method == http.MethodGet {
return page.PrintErrorHTML(w, code, err) return printError(w, code, err)
} }
return code, err return code, err
} }
@ -148,20 +145,20 @@ func ServeHTTP(w http.ResponseWriter, r *http.Request, c *fm.Config) (int, error
switch { switch {
case r.URL.Query().Get("download") != "": case r.URL.Query().Get("download") != "":
code, err = download(w, r, c, fi) code, err = c.download(w, r, fi)
case r.URL.Query().Get("raw") == "true" && !fi.IsDir: case r.URL.Query().Get("raw") == "true" && !fi.IsDir:
http.ServeFile(w, r, fi.Path) http.ServeFile(w, r, fi.Path)
code, err = 0, nil code, err = 0, nil
case !fi.IsDir && r.URL.Query().Get("checksum") != "": case !fi.IsDir && r.URL.Query().Get("checksum") != "":
code, err = checksum(w, r, c, fi) code, err = c.checksum(w, r, fi)
case fi.IsDir: case fi.IsDir:
code, err = serveListing(w, r, c, user, fi) code, err = c.serveListing(w, r, user, fi)
default: default:
code, err = serveSingle(w, r, c, user, fi) code, err = c.serveSingle(w, r, user, fi)
} }
if err != nil { if err != nil {
code, err = page.PrintErrorHTML(w, code, err) code, err = printError(w, code, err)
} }
return code, err return code, err
@ -169,21 +166,3 @@ func ServeHTTP(w http.ResponseWriter, r *http.Request, c *fm.Config) (int, error
return http.StatusNotImplemented, nil return http.StatusNotImplemented, nil
} }
// errorToHTTPCode converts errors to HTTP Status Code.
func errorToHTTPCode(err error, gone bool) int {
switch {
case os.IsPermission(err):
return http.StatusForbidden
case os.IsNotExist(err):
if !gone {
return http.StatusNotFound
}
return http.StatusGone
case os.IsExist(err):
return http.StatusGone
default:
return http.StatusInternalServerError
}
}

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"crypto/md5" "crypto/md5"
@ -6,17 +6,15 @@ import (
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"encoding/hex" "encoding/hex"
e "errors" "errors"
"hash" "hash"
"io" "io"
"net/http" "net/http"
"os" "os"
fm "github.com/hacdias/filemanager"
) )
// checksum calculates the hash of a filemanager. Supports MD5, SHA1, SHA256 and SHA512. // checksum calculates the hash of a filemanager. Supports MD5, SHA1, SHA256 and SHA512.
func checksum(w http.ResponseWriter, r *http.Request, c *fm.Config, i *fm.FileInfo) (int, error) { func (c *Config) checksum(w http.ResponseWriter, r *http.Request, i *file) (int, error) {
query := r.URL.Query().Get("checksum") query := r.URL.Query().Get("checksum")
file, err := os.Open(i.Path) file, err := os.Open(i.Path)
@ -38,7 +36,7 @@ func checksum(w http.ResponseWriter, r *http.Request, c *fm.Config, i *fm.FileIn
case "sha512": case "sha512":
h = sha512.New() h = sha512.New()
default: default:
return http.StatusBadRequest, e.New("Unknown HASH type") return http.StatusBadRequest, errors.New("Unknown HASH type")
} }
_, err = io.Copy(h, file) _, err = io.Copy(h, file)

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"bytes" "bytes"
@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
fm "github.com/hacdias/filemanager"
) )
var upgrader = websocket.Upgrader{ var upgrader = websocket.Upgrader{
@ -23,7 +22,7 @@ var (
) )
// command handles the requests for VCS related commands: git, svn and mercurial // command handles the requests for VCS related commands: git, svn and mercurial
func command(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.User) (int, error) { func (c *Config) command(w http.ResponseWriter, r *http.Request, u *User) (int, error) {
// Upgrades the connection to a websocket and checks for errors. // Upgrades the connection to a websocket and checks for errors.
conn, err := upgrader.Upgrade(w, r, nil) conn, err := upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"io" "io"
@ -9,13 +9,12 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
fm "github.com/hacdias/filemanager"
"github.com/mholt/archiver" "github.com/mholt/archiver"
) )
// download creates an archive in one of the supported formats (zip, tar, // download creates an archive in one of the supported formats (zip, tar,
// tar.gz or tar.bz2) and sends it to be downloaded. // tar.gz or tar.bz2) and sends it to be downloaded.
func download(w http.ResponseWriter, r *http.Request, c *fm.Config, i *fm.FileInfo) (int, error) { func (c *Config) download(w http.ResponseWriter, r *http.Request, i *file) (int, error) {
query := r.URL.Query().Get("download") query := r.URL.Query().Get("download")
if !i.IsDir { if !i.IsDir {

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"encoding/json" "encoding/json"
@ -6,17 +6,15 @@ import (
"strconv" "strconv"
"strings" "strings"
fm "github.com/hacdias/filemanager"
"github.com/hacdias/filemanager/page"
"github.com/mholt/caddy/caddyhttp/httpserver" "github.com/mholt/caddy/caddyhttp/httpserver"
) )
// serveListing presents the user with a listage of a directory folder. // serveListing presents the user with a listage of a directory folder.
func serveListing(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.User, i *fm.FileInfo) (int, error) { func (c *Config) serveListing(w http.ResponseWriter, r *http.Request, u *User, i *file) (int, error) {
var err error var err error
// Loads the content of the directory // Loads the content of the directory
listing, err := fm.GetListing(u, i.VirtualPath, c.PrefixURL+r.URL.Path) listing, err := GetListing(u, i.VirtualPath, c.PrefixURL+r.URL.Path)
if err != nil { if err != nil {
return errorToHTTPCode(err, true), err return errorToHTTPCode(err, true), err
} }
@ -79,9 +77,9 @@ func serveListing(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.Us
Secure: r.TLS != nil, Secure: r.TLS != nil,
}) })
page := &page.Page{ page := &page{
Minimal: r.Header.Get("Minimal") == "true", Minimal: r.Header.Get("Minimal") == "true",
Info: &page.Info{ Info: &pageInfo{
Name: listing.Name, Name: listing.Name,
Path: i.VirtualPath, Path: i.VirtualPath,
IsDir: true, IsDir: true,
@ -92,7 +90,7 @@ func serveListing(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.Us
}, },
} }
return page.PrintAsHTML(w, "listing") return page.PrintHTML(w, "listing")
} }
// handleSortOrder gets and stores for a Listing the 'sort' and 'order', // handleSortOrder gets and stores for a Listing the 'sort' and 'order',

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"bytes" "bytes"
@ -10,17 +10,11 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/hacdias/filemanager"
"github.com/hacdias/filemanager/frontmatter" "github.com/hacdias/filemanager/frontmatter"
) )
// preProccessPUT is used to update a file that was edited // preProccessPUT is used to update a file that was edited
func preProccessPUT( func (c *Config) preProccessPUT(w http.ResponseWriter, r *http.Request, u *User) (err error) {
w http.ResponseWriter,
r *http.Request,
c *filemanager.Config,
u *filemanager.User,
) (err error) {
var ( var (
data = map[string]interface{}{} data = map[string]interface{}{}
file []byte file []byte

View File

@ -1,4 +1,4 @@
package http package filemanager
import ( import (
"net/http" "net/http"
@ -7,7 +7,6 @@ import (
"strings" "strings"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
fm "github.com/hacdias/filemanager"
) )
type searchOptions struct { type searchOptions struct {
@ -44,7 +43,7 @@ func parseSearch(value string) *searchOptions {
} }
// search ... // search ...
func search(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.User) (int, error) { func (c *Config) search(w http.ResponseWriter, r *http.Request, u *User) (int, error) {
// Upgrades the connection to a websocket and checks for errors. // Upgrades the connection to a websocket and checks for errors.
conn, err := upgrader.Upgrade(w, r, nil) conn, err := upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {

View File

@ -1,24 +1,21 @@
package http package filemanager
import ( import (
"net/http" "net/http"
"strings" "strings"
fm "github.com/hacdias/filemanager"
"github.com/hacdias/filemanager/page"
) )
// serveSingle serves a single file in an editor (if it is editable), shows the // serveSingle serves a single file in an editor (if it is editable), shows the
// plain file, or downloads it if it can't be shown. // plain file, or downloads it if it can't be shown.
func serveSingle(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.User, i *fm.FileInfo) (int, error) { func (c *Config) serveSingle(w http.ResponseWriter, r *http.Request, u *User, i *file) (int, error) {
var err error var err error
if err = i.RetrieveFileType(); err != nil { if err = i.RetrieveFileType(); err != nil {
return errorToHTTPCode(err, true), err return errorToHTTPCode(err, true), err
} }
p := &page.Page{ p := &page{
Info: &page.Info{ Info: &pageInfo{
Name: i.Name, Name: i.Name,
Path: i.VirtualPath, Path: i.VirtualPath,
IsDir: false, IsDir: false,
@ -30,7 +27,7 @@ func serveSingle(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.Use
// If the request accepts JSON, we send the file information. // If the request accepts JSON, we send the file information.
if strings.Contains(r.Header.Get("Accept"), "application/json") { if strings.Contains(r.Header.Get("Accept"), "application/json") {
return p.PrintAsJSON(w) return p.PrintJSON(w)
} }
if i.Type == "text" { if i.Type == "text" {
@ -40,14 +37,14 @@ func serveSingle(w http.ResponseWriter, r *http.Request, c *fm.Config, u *fm.Use
} }
if i.CanBeEdited() && u.AllowEdit { if i.CanBeEdited() && u.AllowEdit {
p.Data, err = getEditor(r, i) p.Info.Data, err = newEditor(r, i)
p.Editor = true p.Info.Editor = true
if err != nil { if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }
return p.PrintAsHTML(w, "frontmatter", "editor") return p.PrintHTML(w, "frontmatter", "editor")
} }
return p.PrintAsHTML(w, "single") return p.PrintHTML(w, "single")
} }

24
http_utils.go Normal file
View File

@ -0,0 +1,24 @@
package filemanager
import (
"net/http"
"os"
)
// errorToHTTPCode converts errors to HTTP Status Code.
func errorToHTTPCode(err error, gone bool) int {
switch {
case os.IsPermission(err):
return http.StatusForbidden
case os.IsNotExist(err):
if !gone {
return http.StatusNotFound
}
return http.StatusGone
case os.IsExist(err):
return http.StatusGone
default:
return http.StatusInternalServerError
}
}

View File

@ -18,7 +18,7 @@ type Listing struct {
// The full path of the request relatively to a File System // The full path of the request relatively to a File System
Path string Path string
// The items (files and folders) in the path // The items (files and folders) in the path
Items []FileInfo Items []file
// The number of directories in the listing // The number of directories in the listing
NumDirs int NumDirs int
// The number of files (items that aren't directories) in the listing // The number of files (items that aren't directories) in the listing
@ -49,7 +49,7 @@ func GetListing(u *User, filePath string, baseURL string) (*Listing, error) {
} }
var ( var (
fileinfos []FileInfo fileinfos []*file
dirCount, fileCount int dirCount, fileCount int
) )
@ -71,7 +71,7 @@ func GetListing(u *User, filePath string, baseURL string) (*Listing, error) {
// Absolute URL // Absolute URL
url := url.URL{Path: baseURL + name} url := url.URL{Path: baseURL + name}
i := FileInfo{ i := &file{
Name: f.Name(), Name: f.Name(),
Size: f.Size(), Size: f.Size(),
ModTime: f.ModTime(), ModTime: f.ModTime(),

View File

@ -1,31 +1,29 @@
// Package page is used to render the HTML to the end user package filemanager
package page
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"html/template" "html/template"
"log" "log"
"net/http" "net/http"
"strconv"
"strings" "strings"
"github.com/hacdias/filemanager"
"github.com/hacdias/filemanager/assets"
) )
// Page contains the informations and functions needed to show the Page // page contains the informations and functions needed to show the Page
type Page struct { type page struct {
*Info Info *pageInfo
Minimal bool Minimal bool
} }
// Info contains the information of a Page // pageInfo contains the information of a Page
type Info struct { type pageInfo struct {
Name string Name string
Path string Path string
IsDir bool IsDir bool
User *filemanager.User User *User
Config *filemanager.Config Config *Config
Data interface{} Data interface{}
Editor bool Editor bool
Display string Display string
@ -39,7 +37,7 @@ type BreadcrumbMapItem struct {
// BreadcrumbMap returns p.Path where every element is a map // BreadcrumbMap returns p.Path where every element is a map
// of URLs and path segment names. // of URLs and path segment names.
func (i Info) BreadcrumbMap() []BreadcrumbMapItem { func (i pageInfo) BreadcrumbMap() []BreadcrumbMapItem {
result := []BreadcrumbMapItem{} result := []BreadcrumbMapItem{}
if len(i.Path) == 0 { if len(i.Path) == 0 {
@ -76,7 +74,7 @@ func (i Info) BreadcrumbMap() []BreadcrumbMapItem {
} }
// PreviousLink returns the path of the previous folder // PreviousLink returns the path of the previous folder
func (i Info) PreviousLink() string { func (i pageInfo) PreviousLink() string {
path := strings.TrimSuffix(i.Path, "/") path := strings.TrimSuffix(i.Path, "/")
path = strings.TrimPrefix(path, "/") path = strings.TrimPrefix(path, "/")
path = i.Config.AbsoluteURL() + "/" + path path = i.Config.AbsoluteURL() + "/" + path
@ -89,8 +87,8 @@ func (i Info) PreviousLink() string {
return path return path
} }
// PrintAsHTML formats the page in HTML and executes the template // PrintHTML formats the page in HTML and executes the template
func (p Page) PrintAsHTML(w http.ResponseWriter, templates ...string) (int, error) { func (p page) PrintHTML(w http.ResponseWriter, templates ...string) (int, error) {
if p.Minimal { if p.Minimal {
templates = append(templates, "minimal") templates = append(templates, "minimal")
@ -103,7 +101,8 @@ func (p Page) PrintAsHTML(w http.ResponseWriter, templates ...string) (int, erro
// For each template, add it to the the tpl variable // For each template, add it to the the tpl variable
for i, t := range templates { for i, t := range templates {
// Get the template from the assets // Get the template from the assets
Page, err := assets.Asset("templates/" + t + ".tmpl") //Page, err := assets.Asset("templates/" + t + ".tmpl")
Page, err := []byte("Shit"), errors.New("Hello")
// Check if there is some error. If so, the template doesn't exist // Check if there is some error. If so, the template doesn't exist
if err != nil { if err != nil {
@ -137,8 +136,8 @@ func (p Page) PrintAsHTML(w http.ResponseWriter, templates ...string) (int, erro
return http.StatusOK, err return http.StatusOK, err
} }
// PrintAsJSON prints the current Page information in JSON // PrintJSON prints the current Page information in JSON
func (p Page) PrintAsJSON(w http.ResponseWriter) (int, error) { func (p page) PrintJSON(w http.ResponseWriter) (int, error) {
marsh, err := json.MarshalIndent(p.Info.Data, "", " ") marsh, err := json.MarshalIndent(p.Info.Data, "", " ")
if err != nil { if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
@ -151,3 +150,61 @@ func (p Page) PrintAsJSON(w http.ResponseWriter) (int, error) {
return http.StatusOK, nil return http.StatusOK, nil
} }
// printError prints the error page
func printError(w http.ResponseWriter, code int, err error) (int, error) {
tpl := errorTemplate
tpl = strings.Replace(tpl, "TITLE", strconv.Itoa(code)+" "+http.StatusText(code), -1)
tpl = strings.Replace(tpl, "CODE", err.Error(), -1)
_, err = w.Write([]byte(tpl))
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
}
const errorTemplate = `<!DOCTYPE html>
<html>
<head>
<title>TITLE</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<style>
html {
background-color: #2196f3;
color: #fff;
font-family: sans-serif;
}
code {
background-color: rgba(0,0,0,0.1);
border-radius: 5px;
padding: 1em;
display: block;
box-sizing: border-box;
}
.center {
max-width: 40em;
margin: 2em auto 0;
}
a {
text-decoration: none;
color: #eee;
font-weight: bold;
}
p {
line-height: 1.3;
}
</style>
</head>
<body>
<div class="center">
<h1>TITLE</h1>
<p>Try reloading the page or hitting the back button. If this error persists, it seems that you may have found a bug! Please create an issue at <a href="https://github.com/hacdias/caddy-filemanager/issues">hacdias/caddy-filemanager</a> repository on GitHub with the code below.</p>
<code>CODE</code>
</div>
</html>`

View File

@ -1,65 +0,0 @@
package page
import (
"net/http"
"strconv"
"strings"
)
const errTemplate = `<!DOCTYPE html>
<html>
<head>
<title>TITLE</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<style>
html {
background-color: #2196f3;
color: #fff;
font-family: sans-serif;
}
code {
background-color: rgba(0,0,0,0.1);
border-radius: 5px;
padding: 1em;
display: block;
box-sizing: border-box;
}
.center {
max-width: 40em;
margin: 2em auto 0;
}
a {
text-decoration: none;
color: #eee;
font-weight: bold;
}
p {
line-height: 1.3;
}
</style>
</head>
<body>
<div class="center">
<h1>TITLE</h1>
<p>Try reloading the page or hitting the back button. If this error persists, it seems that you may have found a bug! Please create an issue at <a href="https://github.com/hacdias/caddy-filemanager/issues">hacdias/caddy-filemanager</a> repository on GitHub with the code below.</p>
<code>CODE</code>
</div>
</html>`
// PrintErrorHTML prints the error page
func PrintErrorHTML(w http.ResponseWriter, code int, err error) (int, error) {
tpl := errTemplate
tpl = strings.Replace(tpl, "TITLE", strconv.Itoa(code)+" "+http.StatusText(code), -1)
tpl = strings.Replace(tpl, "CODE", err.Error(), -1)
_, err = w.Write([]byte(tpl))
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
}

View File

@ -1,4 +1,4 @@
package http package filemanager
import "net/http" import "net/http"