Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fabfcd14d | ||
|
|
19c13c43f6 | ||
|
|
fc7451ab40 | ||
|
|
c8e09a989d | ||
|
|
7b04c49f4a | ||
|
|
de57779200 | ||
|
|
d706a2c4a3 | ||
|
|
90252d971f | ||
|
|
16c4ade51b | ||
|
|
58e8a594eb | ||
|
|
66a35fcf10 | ||
|
|
05ef683334 |
BIN
exec-simpleserve
Executable file
BIN
exec-simpleserve
Executable file
Binary file not shown.
25
go.mod
Normal file
25
go.mod
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
module local/simpleserve
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
replace local/args => ../args
|
||||||
|
|
||||||
|
replace local/gziphttp => ../gziphttp
|
||||||
|
|
||||||
|
replace local/notes-server/notes/md => ../notes-server/notes/md
|
||||||
|
|
||||||
|
replace local/oauth2 => ../oauth2
|
||||||
|
|
||||||
|
replace local/router => ../router
|
||||||
|
|
||||||
|
replace local/simpleserve => ../simpleserve
|
||||||
|
|
||||||
|
replace local/storage => ../storage
|
||||||
|
|
||||||
|
replace local/logb => ../logb
|
||||||
|
|
||||||
|
require (
|
||||||
|
local/args v0.0.0-00010101000000-000000000000
|
||||||
|
local/gziphttp v0.0.0-00010101000000-000000000000
|
||||||
|
local/notes-server/notes/md v0.0.0-00010101000000-000000000000
|
||||||
|
)
|
||||||
6
go.sum
Normal file
6
go.sum
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
github.com/gomarkdown/markdown v0.0.0-20220607163217-45f7c050e2d1 h1:wAupuFkZ/yq219/mSbqDtMfUZQY0gTYEtoz3/LKtppU=
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20220607163217-45f7c050e2d1/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
85
main.go
85
main.go
@@ -32,7 +32,9 @@ func main() {
|
|||||||
fs = args.NewArgSet()
|
fs = args.NewArgSet()
|
||||||
fs.Append(args.STRING, "p", "port to serve", "8100")
|
fs.Append(args.STRING, "p", "port to serve", "8100")
|
||||||
fs.Append(args.BOOL, "md", "whether to render markdown as html", true)
|
fs.Append(args.BOOL, "md", "whether to render markdown as html", true)
|
||||||
fs.Append(args.STRING, "md-css", "css to load for md", "./public/bundle.css")
|
fs.Append(args.BOOL, "ro", "read only mode", false)
|
||||||
|
fs.Append(args.BOOL, "https", "https only", false)
|
||||||
|
fs.Append(args.STRING, "md-css", "css to load for md", "/dev/null")
|
||||||
fs.Append(args.STRING, "md-class", "class to wrap md", "phb")
|
fs.Append(args.STRING, "md-class", "class to wrap md", "phb")
|
||||||
fs.Append(args.STRING, "d", "static path to serve", "./public")
|
fs.Append(args.STRING, "d", "static path to serve", "./public")
|
||||||
if err := fs.Parse(); err != nil {
|
if err := fs.Parse(); err != nil {
|
||||||
@@ -41,6 +43,8 @@ func main() {
|
|||||||
|
|
||||||
d := fs.Get("d").GetString()
|
d := fs.Get("d").GetString()
|
||||||
md := fs.Get("md").GetBool()
|
md := fs.Get("md").GetBool()
|
||||||
|
ro := fs.Get("ro").GetBool()
|
||||||
|
https := fs.Get("https").GetBool()
|
||||||
mdCss := fs.Get("md-css").GetString()
|
mdCss := fs.Get("md-css").GetString()
|
||||||
mdClass := fs.Get("md-class").GetString()
|
mdClass := fs.Get("md-class").GetString()
|
||||||
if mdCss != "" {
|
if mdCss != "" {
|
||||||
@@ -89,15 +93,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
p := strings.TrimPrefix(fs.Get("p").GetString(), ":")
|
p := strings.TrimPrefix(fs.Get("p").GetString(), ":")
|
||||||
|
|
||||||
http.Handle("/", http.HandlerFunc(handler(d, md, mdCss, mdClass)))
|
http.Handle("/", http.HandlerFunc(handler(https, ro, d, md, mdCss, mdClass)))
|
||||||
|
|
||||||
log.Printf("Serving %s on HTTP port: %s\n", d, p)
|
log.Printf("Serving %s on HTTP port: %s\n", d, p)
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(":"+p, nil))
|
log.Fatal(http.ListenAndServe(":"+p, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handler(d string, md bool, mdCss, mdClass string) http.HandlerFunc {
|
func handler(https, ro bool, d string, md bool, mdCss, mdClass string) http.HandlerFunc {
|
||||||
return gzip(endpoints(withDel(withMD(d, md, mdCss, mdClass, fserve(d)))))
|
return httpsOnly(https, gzip(endpoints(ro, withDel(ro, withMD(d, md, mdCss, mdClass, fserve(d))))))
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeMeta(w http.ResponseWriter) {
|
func writeMeta(w http.ResponseWriter) {
|
||||||
@@ -118,6 +122,18 @@ func writeForm(w http.ResponseWriter) {
|
|||||||
`, ENDPOINT_UPLOAD)
|
`, ENDPOINT_UPLOAD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func httpsOnly(https bool, foo http.HandlerFunc) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if https && r.URL.Scheme != "https" {
|
||||||
|
log.Printf("redirecting: %+v", r.URL)
|
||||||
|
r.URL.Scheme = "https"
|
||||||
|
http.Redirect(w, r, r.URL.String(), http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
foo(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func gzip(foo http.HandlerFunc) http.HandlerFunc {
|
func gzip(foo http.HandlerFunc) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if gziphttp.Can(r) {
|
if gziphttp.Can(r) {
|
||||||
@@ -129,17 +145,19 @@ func gzip(foo http.HandlerFunc) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func endpoints(foo http.HandlerFunc) http.HandlerFunc {
|
func endpoints(ro bool, foo http.HandlerFunc) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if isDir(r) {
|
if isDir(r) {
|
||||||
writeMeta(w)
|
writeMeta(w)
|
||||||
writeForm(w)
|
if !ro {
|
||||||
|
writeForm(w)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if isUploaded(r) {
|
if !ro && isUploaded(r) {
|
||||||
if err := upload(w, r); err != nil {
|
if err := upload(w, r); err != nil {
|
||||||
fmt.Fprintln(w, err.Error())
|
fmt.Fprintln(w, err.Error())
|
||||||
}
|
}
|
||||||
} else if isDeleted(r) {
|
} else if !ro && isDeleted(r) {
|
||||||
if err := del(w, r); err != nil {
|
if err := del(w, r); err != nil {
|
||||||
fmt.Fprintln(w, err.Error())
|
fmt.Fprintln(w, err.Error())
|
||||||
}
|
}
|
||||||
@@ -198,19 +216,19 @@ func withMD(dir string, enabled bool, mdCss, mdClass string, foo http.HandlerFun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withDel(foo http.HandlerFunc) http.HandlerFunc {
|
func withDel(ro bool, foo http.HandlerFunc) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if !isDir(r) {
|
if !isDir(r) {
|
||||||
foo(w, r)
|
foo(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Fprintln(w, `<a href=".."><input type="button" style="padding: .15em 4em .35em 4em" value=".."/></a>`+"\n")
|
fmt.Fprintln(w, `<a href=".."><input type="button" style="padding: .15em 4em .35em 4em" value=".."/></a>`)
|
||||||
w2 := httptest.NewRecorder()
|
w2 := httptest.NewRecorder()
|
||||||
foo(w2, r)
|
foo(w2, r)
|
||||||
b := bytes.Split(w2.Body.Bytes(), []byte("\n"))
|
b := bytes.Split(w2.Body.Bytes(), []byte("\n"))
|
||||||
buff := bytes.NewBuffer(nil)
|
buff := bytes.NewBuffer(nil)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
if bytes.Contains(b[i], []byte("<a href=")) {
|
if !ro && bytes.Contains(b[i], []byte("<a href=")) {
|
||||||
re := regexp.MustCompile(`href="[^"]*"`)
|
re := regexp.MustCompile(`href="[^"]*"`)
|
||||||
match := re.Find(b[i])
|
match := re.Find(b[i])
|
||||||
if len(match) > 0 {
|
if len(match) > 0 {
|
||||||
@@ -272,3 +290,48 @@ func toRealPath(p string) string {
|
|||||||
d := path.Join(fs.Get("d").GetString())
|
d := path.Join(fs.Get("d").GetString())
|
||||||
return path.Join(d, p)
|
return path.Join(d, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setContentTypeIfMedia(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch strings.ToLower(path.Ext(r.URL.Path)) {
|
||||||
|
case ".mp4":
|
||||||
|
w.Header().Set("Content-Type", "video/mp4")
|
||||||
|
case ".mkv":
|
||||||
|
w.Header().Set("Content-Type", "video/x-matroska")
|
||||||
|
case ".mp3":
|
||||||
|
w.Header().Set("Content-Type", "audio/mpeg3")
|
||||||
|
case ".epub", ".mobi":
|
||||||
|
w.Header().Set("Content-Disposition", "attachment")
|
||||||
|
case ".jpg", ".jpeg":
|
||||||
|
w.Header().Set("Content-Type", "image/jpeg")
|
||||||
|
case ".gif":
|
||||||
|
w.Header().Set("Content-Type", "image/gif")
|
||||||
|
case ".png":
|
||||||
|
w.Header().Set("Content-Type", "image/png")
|
||||||
|
case ".ico":
|
||||||
|
w.Header().Set("Content-Type", "image/x-icon")
|
||||||
|
case ".svg":
|
||||||
|
w.Header().Set("Content-Type", "image/svg+xml")
|
||||||
|
case ".css":
|
||||||
|
w.Header().Set("Content-Type", "text/css")
|
||||||
|
case ".js":
|
||||||
|
w.Header().Set("Content-Type", "text/javascript")
|
||||||
|
case ".json":
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
case ".html", ".htm":
|
||||||
|
w.Header().Set("Content-Type", "text/html")
|
||||||
|
case ".pdf":
|
||||||
|
w.Header().Set("Content-Type", "application/pdf")
|
||||||
|
case ".webm":
|
||||||
|
w.Header().Set("Content-Type", "video/webm")
|
||||||
|
case ".weba":
|
||||||
|
w.Header().Set("Content-Type", "audio/webm")
|
||||||
|
case ".webp":
|
||||||
|
w.Header().Set("Content-Type", "image/webp")
|
||||||
|
case ".zip":
|
||||||
|
w.Header().Set("Content-Type", "application/zip")
|
||||||
|
case ".7z":
|
||||||
|
w.Header().Set("Content-Type", "application/x-7z-compressed")
|
||||||
|
case ".tar":
|
||||||
|
w.Header().Set("Content-Type", "application/x-tar")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ func SetContentTypeIfMedia(w http.ResponseWriter, r *http.Request) {
|
|||||||
v = "image/jpeg"
|
v = "image/jpeg"
|
||||||
case ".md":
|
case ".md":
|
||||||
v = "text/markdown"
|
v = "text/markdown"
|
||||||
|
v = "text/html"
|
||||||
case ".gif":
|
case ".gif":
|
||||||
v = "image/gif"
|
v = "image/gif"
|
||||||
case ".png":
|
case ".png":
|
||||||
|
|||||||
Reference in New Issue
Block a user