all repos — flounder @ 543b6a470d38804179b76ecdc947a3d969c279a1

A small site builder for the Gemini protocol

http.go (view raw)

  1package main
  2
  3import (
  4	"html/template"
  5	"log"
  6	"net/http"
  7	"path"
  8	"strings"
  9)
 10
 11var t *template.Template
 12
 13// TODO somewhat better error handling
 14const InternalServerErrorMsg = "500: Internal Server Error"
 15
 16func renderError(w http.ResponseWriter, errorMsg string, statusCode int) { // TODO think about pointers
 17	data := struct{ ErrorMsg string }{errorMsg}
 18	err := t.ExecuteTemplate(w, "error.html", data)
 19	if err != nil { // shouldn't happen probably
 20		http.Error(w, errorMsg, statusCode)
 21	}
 22}
 23
 24func indexHandler(w http.ResponseWriter, r *http.Request) {
 25	indexFiles, err := getIndexFiles()
 26	if err != nil {
 27		log.Println(err)
 28		renderError(w, InternalServerErrorMsg, 500)
 29		return
 30	}
 31	allUsers, err := getUsers()
 32	if err != nil {
 33		log.Println(err)
 34		renderError(w, InternalServerErrorMsg, 500)
 35		return
 36	}
 37	data := struct {
 38		Domain    string
 39		PageTitle string
 40		Files     []*File
 41		Users     []string
 42	}{c.RootDomain, c.SiteTitle, indexFiles, allUsers}
 43	err = t.ExecuteTemplate(w, "index.html", data)
 44	if err != nil {
 45		log.Println(err)
 46		renderError(w, InternalServerErrorMsg, 500)
 47		return
 48	}
 49
 50}
 51
 52func editFileHandler(w http.ResponseWriter, r *http.Request) {
 53	// read file content. create if dne
 54	// authUser := "alex"
 55	data := struct {
 56		FileName  string
 57		FileText  string
 58		PageTitle string
 59	}{"filename", "filetext", c.SiteTitle}
 60	err := t.ExecuteTemplate(w, "edit_file.html", data)
 61	if err != nil {
 62		log.Println(err)
 63		renderError(w, InternalServerErrorMsg, 500)
 64		return
 65	}
 66}
 67
 68func mySiteHandler(w http.ResponseWriter, r *http.Request) {
 69	authUser := "alex"
 70	// check auth
 71	files, _ := getUserFiles(authUser)
 72	data := struct {
 73		Domain    string
 74		PageTitle string
 75		AuthUser  string
 76		Files     []*File
 77	}{c.RootDomain, c.SiteTitle, authUser, files}
 78	_ = t.ExecuteTemplate(w, "my_site.html", data)
 79}
 80
 81func loginHandler(w http.ResponseWriter, r *http.Request) {
 82	if r.Method == "GET" {
 83		// show page
 84		data := struct {
 85			Error     string
 86			PageTitle string
 87		}{"", "Login"}
 88		err := t.ExecuteTemplate(w, "login.html", data)
 89		if err != nil {
 90			log.Println(err)
 91			renderError(w, InternalServerErrorMsg, 500)
 92			return
 93		}
 94	} else if r.Method == "POST" {
 95		r.ParseForm()
 96		name := r.Form.Get("username")
 97		password := r.Form.Get("password")
 98		err := checkAuth(name, password)
 99		if err == nil {
100			log.Println("logged in")
101			// redirect home
102		} else {
103			data := struct {
104				Error     string
105				PageTitle string
106			}{"Invalid login or password", c.SiteTitle}
107			err := t.ExecuteTemplate(w, "login.html", data)
108			if err != nil {
109				log.Println(err)
110				renderError(w, InternalServerErrorMsg, 500)
111				return
112			}
113		}
114		// create session
115		// redirect home
116		// verify login
117		// check for errors
118	}
119}
120
121func registerHandler(w http.ResponseWriter, r *http.Request) {
122	if r.Method == "GET" {
123		data := struct {
124			Domain    string
125			Errors    []string
126			PageTitle string
127		}{c.RootDomain, nil, "Register"}
128		err := t.ExecuteTemplate(w, "register.html", data)
129		if err != nil {
130			log.Println(err)
131			renderError(w, InternalServerErrorMsg, 500)
132			return
133		}
134	} else if r.Method == "POST" {
135	}
136}
137
138// Server a user's file
139func userFile(w http.ResponseWriter, r *http.Request) {
140	userName := strings.Split(r.Host, ".")[0]
141	fileName := path.Join(c.FilesDirectory, userName, r.URL.Path)
142	// if gemini -- parse, convert, serve
143	// else
144	http.ServeFile(w, r, fileName)
145}
146
147func runHTTPServer() {
148	log.Println("Running http server")
149	var err error
150	t, err = template.ParseGlob("./templates/*.html") // TODO make template dir configruable
151	if err != nil {
152		log.Fatal(err)
153	}
154	http.HandleFunc(c.RootDomain+"/", indexHandler)
155	http.HandleFunc(c.RootDomain+"/my_site", mySiteHandler)
156	http.HandleFunc(c.RootDomain+"/edit/", editFileHandler)
157	http.HandleFunc(c.RootDomain+"/login", loginHandler)
158	http.HandleFunc(c.RootDomain+"/register", registerHandler)
159	// http.HandleFunc("/delete/", deleteFileHandler)
160	// login+register functions
161
162	// handle user files based on subdomain
163	http.HandleFunc("/", userFile)
164	log.Fatal(http.ListenAndServe(":8080", logRequest(http.DefaultServeMux)))
165}
166
167func logRequest(handler http.Handler) http.Handler {
168	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
169		log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
170		handler.ServeHTTP(w, r)
171	})
172}