2017-06-10 21:38:09 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2017-06-17 02:49:44 +02:00
|
|
|
"log"
|
2017-06-17 06:03:36 +02:00
|
|
|
"mime"
|
2017-06-10 21:38:09 +02:00
|
|
|
"net/http"
|
2017-06-17 06:03:36 +02:00
|
|
|
"path"
|
2017-06-17 02:49:44 +02:00
|
|
|
|
|
|
|
"github.com/fsnotify/fsnotify"
|
2017-06-10 21:38:09 +02:00
|
|
|
)
|
|
|
|
|
2017-06-17 05:50:30 +02:00
|
|
|
// Server serves the site on HTTP.
|
2017-06-17 02:49:44 +02:00
|
|
|
type Server struct{ Site *Site }
|
|
|
|
|
2017-06-17 05:50:30 +02:00
|
|
|
// Run runs the server.
|
|
|
|
func (s *Server) Run() error {
|
2017-06-10 21:38:09 +02:00
|
|
|
address := "localhost:4000"
|
2017-06-17 05:50:30 +02:00
|
|
|
if err := s.watchFiles(); err != nil {
|
2017-06-17 02:49:44 +02:00
|
|
|
return err
|
|
|
|
}
|
2017-06-10 21:38:09 +02:00
|
|
|
printSetting("Server address:", "http://"+address+"/")
|
|
|
|
printSetting("Server running...", "press ctrl-c to stop.")
|
2017-06-17 05:50:30 +02:00
|
|
|
http.HandleFunc("/", s.handler)
|
2017-06-12 02:05:17 +02:00
|
|
|
return http.ListenAndServe(address, nil)
|
2017-06-10 21:38:09 +02:00
|
|
|
}
|
|
|
|
|
2017-06-17 06:03:36 +02:00
|
|
|
func (s *Server) handler(rw http.ResponseWriter, r *http.Request) {
|
2017-06-17 04:09:25 +02:00
|
|
|
site := s.Site
|
2017-06-17 02:06:55 +02:00
|
|
|
urlpath := r.URL.Path
|
2017-06-17 06:03:36 +02:00
|
|
|
mimeType := mime.TypeByExtension(path.Ext(urlpath))
|
|
|
|
if mimeType != "" {
|
|
|
|
rw.Header().Set("Content-Type", mimeType)
|
|
|
|
}
|
2017-06-10 21:38:09 +02:00
|
|
|
|
2017-06-17 05:50:30 +02:00
|
|
|
p, found := site.PageForURL(urlpath)
|
2017-06-10 21:38:09 +02:00
|
|
|
if !found {
|
2017-06-17 06:03:36 +02:00
|
|
|
rw.WriteHeader(http.StatusNotFound)
|
2017-06-13 17:00:24 +02:00
|
|
|
p, found = site.Paths["404.html"]
|
2017-06-10 21:38:09 +02:00
|
|
|
}
|
|
|
|
if !found {
|
2017-06-17 06:03:36 +02:00
|
|
|
fmt.Fprintf(rw, "404 page not found: %s", urlpath)
|
2017-06-10 21:38:09 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-06-17 06:03:36 +02:00
|
|
|
err := p.Write(rw)
|
2017-06-10 21:38:09 +02:00
|
|
|
if err != nil {
|
2017-06-17 02:06:55 +02:00
|
|
|
fmt.Printf("Error rendering %s: %s", urlpath, err)
|
2017-06-12 02:05:17 +02:00
|
|
|
}
|
2017-06-10 21:38:09 +02:00
|
|
|
}
|
2017-06-17 02:49:44 +02:00
|
|
|
|
|
|
|
func (s *Server) watchFiles() error {
|
|
|
|
watcher, err := fsnotify.NewWatcher()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case event := <-watcher.Events:
|
|
|
|
log.Println("event:", event)
|
|
|
|
if event.Op&fsnotify.Write == fsnotify.Write {
|
|
|
|
log.Println("modified file:", event.Name)
|
|
|
|
// TODO rebuild the site
|
|
|
|
}
|
|
|
|
case err := <-watcher.Errors:
|
|
|
|
log.Println("error:", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return watcher.Add(s.Site.Source)
|
|
|
|
}
|