|
@@ -0,0 +1,126 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "flag"
|
|
|
+ "fmt"
|
|
|
+ "html/template"
|
|
|
+ "log"
|
|
|
+ "net/http"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+var host = flag.String("h", "localhost", "Host on which to serve")
|
|
|
+var port = flag.String("p", "9090", "Port on which to serve")
|
|
|
+var mainFolder = flag.String("f", "", "Absolute path to where files are kept")
|
|
|
+var logFilePath = flag.String("l", "", "Path to log file")
|
|
|
+
|
|
|
+type paths struct {
|
|
|
+ textFile string
|
|
|
+ htmlFile string
|
|
|
+}
|
|
|
+
|
|
|
+func getPaths(folder string) (paths, error) {
|
|
|
+ destination := filepath.Join(*mainFolder, folder)
|
|
|
+ if !strings.HasPrefix(destination, *mainFolder) {
|
|
|
+ return paths{}, fmt.Errorf("Wrong destination: %s", destination)
|
|
|
+ }
|
|
|
+
|
|
|
+ if _, err := os.Stat(destination); os.IsNotExist(err) {
|
|
|
+ return paths{}, fmt.Errorf("Destination folder doesn't exist at %s!", destination)
|
|
|
+ }
|
|
|
+
|
|
|
+ textFile := filepath.Join(destination, "index.txt")
|
|
|
+ if _, err := os.Stat(textFile); os.IsNotExist(err) {
|
|
|
+ return paths{}, fmt.Errorf("Text file doesn't exist at %s!", textFile)
|
|
|
+ }
|
|
|
+
|
|
|
+ return paths{textFile, filepath.Join(destination, "index.html")}, nil
|
|
|
+}
|
|
|
+
|
|
|
+type params struct {
|
|
|
+ folder string
|
|
|
+ option string
|
|
|
+}
|
|
|
+
|
|
|
+func getParameters(path string) (params, error) {
|
|
|
+ if path == "" {
|
|
|
+ return params{}, fmt.Errorf("Empty string!")
|
|
|
+ }
|
|
|
+
|
|
|
+ parts := strings.Split(path, "/")
|
|
|
+ partsCount := len(parts)
|
|
|
+ if partsCount > 2 {
|
|
|
+ return params{}, fmt.Errorf("Too many parameters: %s", parts)
|
|
|
+ }
|
|
|
+
|
|
|
+ if partsCount == 2 {
|
|
|
+ return params{parts[0], parts[1]}, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return params{parts[0], ""}, nil
|
|
|
+}
|
|
|
+
|
|
|
+func serve(w http.ResponseWriter, r *http.Request) {
|
|
|
+ pathFromURL := strings.TrimPrefix(r.URL.Path, "/")
|
|
|
+ t := template.Must(template.ParseFiles("./html/result.html"))
|
|
|
+
|
|
|
+ parameters, err := getParameters(pathFromURL)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ t.Execute(w, "Bad parameters!")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ paths, err := getPaths(parameters.folder)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ w.WriteHeader(http.StatusNotFound)
|
|
|
+ t.Execute(w, "Not found!")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if parameters.option == "t" {
|
|
|
+ http.ServeFile(w, r, paths.textFile)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if _, err := os.Stat(paths.htmlFile); os.IsNotExist(err) {
|
|
|
+ err := convert(paths)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ http.ServeFile(w, r, paths.textFile)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ http.ServeFile(w, r, paths.htmlFile)
|
|
|
+}
|
|
|
+
|
|
|
+func setLog() *os.File {
|
|
|
+ if *logFilePath == "" {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ file, err := os.OpenFile(*logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatalf("Can't open logs file: %s", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ log.SetOutput(file)
|
|
|
+ return file
|
|
|
+}
|
|
|
+
|
|
|
+func main() {
|
|
|
+ flag.Parse()
|
|
|
+
|
|
|
+ logFile := setLog()
|
|
|
+ if logFile != nil {
|
|
|
+ defer logFile.Close()
|
|
|
+ }
|
|
|
+
|
|
|
+ hostname := *host + ":" + *port
|
|
|
+ http.HandleFunc("/", serve)
|
|
|
+ log.Fatal(http.ListenAndServe(hostname, nil))
|
|
|
+}
|