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}