all repos — flounder @ 664d07956cd4b2c58ef4bb4414ce7a324555d3f3

A small site builder for the Gemini protocol

http.go (view raw)

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