-
Notifications
You must be signed in to change notification settings - Fork 55
/
server.go
112 lines (88 loc) · 2.23 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package booklitcmd
import (
"bytes"
"io"
"net/http"
"strings"
"sync"
"github.com/sirupsen/logrus"
"github.com/vito/booklit"
"github.com/vito/booklit/load"
"github.com/vito/booklit/render"
)
type Server struct {
In string
Processor *load.Processor
Templates string
Engine *render.HTMLEngine
FileServer http.Handler
buildLock sync.Mutex
}
func (server *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log := logrus.WithFields(logrus.Fields{
"request": r.URL.Path,
})
log.Debugln("serving")
section, found, err := server.loadRequestedSection(r.URL.Path)
if err != nil {
log.Errorf("failed to load section: %s", err)
w.WriteHeader(http.StatusInternalServerError)
booklit.ErrorResponse(w, err)
return
}
if !found {
server.FileServer.ServeHTTP(w, r)
return
}
server.buildLock.Lock()
defer server.buildLock.Unlock()
if server.Templates != "" {
err := server.Engine.LoadTemplates(server.Templates)
if err != nil {
log.Errorf("failed to load templates: %s", err)
w.WriteHeader(http.StatusInternalServerError)
booklit.ErrorResponse(w, err)
return
}
}
log = log.WithFields(logrus.Fields{
"section": section.Path,
})
log.Info("rendering")
rendered := new(bytes.Buffer)
err = server.Engine.RenderSection(rendered, section)
if err != nil {
log.Errorf("failed to render: %s", err)
w.WriteHeader(http.StatusInternalServerError)
booklit.ErrorResponse(w, err)
return
}
_, err = io.Copy(w, rendered)
if err != nil {
log.Errorf("failed to write response: %s", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (server *Server) loadRequestedSection(path string) (*booklit.Section, bool, error) {
ext := server.Engine.FileExtension()
if path == "/" {
path = "/index." + ext
}
if !strings.HasSuffix(path, "."+ext) {
return nil, false, nil
}
tagName := strings.TrimSuffix(strings.TrimPrefix(path, "/"), "."+ext)
logrus.WithFields(logrus.Fields{
"section": server.In,
}).Info("loading root section")
rootSection, err := server.Processor.LoadFile(server.In, basePluginFactories)
if err != nil {
return nil, false, err
}
tags := rootSection.FindTag(tagName)
if len(tags) == 0 {
return nil, false, nil
}
return tags[0].Section, true, nil
}