diff options
Diffstat (limited to 'src/http')
-rw-r--r-- | src/http/http.go | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/http/http.go b/src/http/http.go index d02cfda..76ca62d 100644 --- a/src/http/http.go +++ b/src/http/http.go @@ -1 +1,179 @@ package http + +import ( + "fmt" + "html/template" + "io/ioutil" + "net/http" + "strings" + + "git.darknebu.la/emile/faila/src/structs" + "github.com/gorilla/mux" + "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +// Server defines and runs an HTTP server +func Server() { + r := mux.NewRouter() + + // static js / css hosting + static := r.PathPrefix("/static/").Subrouter() + fs := http.FileServer(http.Dir("./hosted/static")) + static.PathPrefix("/").Handler(http.StripPrefix("/static/", fs)) + + t := r.PathPrefix("/").Subrouter() + t.PathPrefix("/").HandlerFunc(pathHandler) + + // get the ip and port from the config + bindIP := viper.GetString("server.bindip") + listenPort := viper.GetString("server.listenport") + + // define the http server + httpServer := http.Server{ + Addr: fmt.Sprintf("%s:%s", bindIP, listenPort), + Handler: r, + } + + logrus.Warnf("HTTP server defined listening on %s:%s", bindIP, listenPort) + logrus.Fatal(httpServer.ListenAndServe()) +} + +func pathHandler(w http.ResponseWriter, r *http.Request) { + var content map[string]interface{} + content = make(map[string]interface{}) + + breadcrumbsList := breadcrumbs(r) + content["Breadcrumbs"] = breadcrumbsList + + root := viper.GetString("server.root") + requestURI := fmt.Sprintf("%s%s", root, r.RequestURI) + logrus.Infof("requestURI: %s", requestURI) + logrus.Infof("r.RequestURI: %s", r.RequestURI) + + // get all files in the request dir + files, err := ioutil.ReadDir(requestURI) + if err != nil { + logrus.Warn(err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + // define the items (files and dirs) + var items structs.Items + var dirCount int = 0 + var fileCount int = 0 + for _, f := range files { + + // get the file or dirs modtime and format it in a readable way as + // described in the config + modTime := f.ModTime() + if viper.GetString("time.format") == "" { + logrus.Fatalf("Please insert a format for the time in the config (time.format), see the README for more information.") + } + humanModTime := modTime.Format(viper.GetString("time.format")) + + // define the file or dir's url + var url string + if r.RequestURI != "/" { + url = fmt.Sprintf("%s/%s", r.RequestURI, f.Name()) + } else { + url = fmt.Sprintf("/%s", f.Name()) + } + + // define the file or dir + item := structs.Item{ + Name: f.Name(), + HumanSize: f.Size(), + URL: url, + HumanModTime: humanModTime, + IsSymlink: false, + Size: "0", + } + + // if it is a dir, say so + if f.IsDir() == true { + item.IsDir = true + dirCount++ + } + + items = append(items, item) + } + + // add the items to the content map + content["Items"] = items + + // ad the file and dir count to the contents map + content["NumDirs"] = dirCount + content["NumFiles"] = fileCount + + // if there are more than one breadcrumb, define the uppath as the second + // last breadcrumb + // I did this, because somehow things broke when simply using ".." in + // combination with hidden folders + if len(breadcrumbsList) > 1 { + content["UpPath"] = breadcrumbsList[len(breadcrumbsList)-2].Link + } else { + content["UpPath"] = ".." + } + + // In the caddy + content["ItemsLimitedTo"] = 100000000000 + + // define the sort order manually + // TODO: handle this correctly + content["Sort"] = "namedirfirst" + content["Order"] = "desc" + + // if we're not at the root, we can still go futher down! + if r.RequestURI != "/" { + content["CanGoUp"] = "true" + } + + // define a new template to render the challenges in + t := template.New("") + t, err = t.ParseGlob("./hosted/tmpl/*.html") + if err != nil { + logrus.Warn(err) + return + } + + t.ExecuteTemplate(w, "index", content) +} + +// breadcrumbs get's the breadcrumbs from the request +func breadcrumbs(r *http.Request) structs.Breadcrumbs { + logrus.Debugf("----------------------------------------------------------") + logrus.Debugf("%s\n", r.RequestURI) + + request := r.RequestURI + + // mitigate path traversals + strippedRequest := strings.Replace(request, "..", "", -1) + + if request != "/" { + strippedRequest = strings.TrimRight(strippedRequest, "/") + } + + // continue without the first slash, as it produces an unused field that has + // no use + crumbs := strings.Split(strippedRequest[1:], "/") + + // build the breadcrumbs from the split RequestURI + var breadcrumbs structs.Breadcrumbs + for i, crumb := range crumbs { + + text := crumb + + // the link is defined as the text until the given crumb + link := strings.Join(crumbs[:i+1], "/") + + resultCrumb := structs.Crumb{ + Text: text, + Link: fmt.Sprintf("/%s", link), + } + breadcrumbs = append(breadcrumbs, resultCrumb) + } + + return breadcrumbs +} |