-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
131 lines (113 loc) · 3.98 KB
/
context.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package enliven
import (
"html/template"
"net/http"
)
// Context stores context variables and the session that will be passed to requests
type Context struct {
Session ISession
Vars map[string]string // This map specifically to hold route key value pairs.
Strings map[string]string
Integers map[string]int
Booleans map[string]bool
Storage map[string]interface{}
Enliven *Enliven
Response http.ResponseWriter
Request *http.Request
}
// String sets up string headers and outputs a string response
func (ctx *Context) String(output string) {
ctx.Response.Header().Set("Content-Type", "text/plain")
ctx.Response.Write([]byte(output))
}
// HTML sets up HTML headers and outputs a string response
func (ctx *Context) HTML(output string) {
ctx.Response.Header().Set("Content-Type", "text/html")
ctx.Response.Write([]byte(output))
}
// AnonymousTemplate sets up HTML headers and outputs an html/template response
func (ctx *Context) AnonymousTemplate(tmpl *template.Template) {
ctx.Response.Header().Set("Content-Type", "text/html")
err := tmpl.Execute(ctx.Response, ctx)
if err != nil {
ctx.String(err.Error())
}
}
// ExecuteBaseTemplate sets up HTML headers and outputs an html/template response for a specific template definition
func (ctx *Context) ExecuteBaseTemplate(templateName string) {
ctx.Response.Header().Set("Content-Type", "text/html")
err := ctx.Enliven.Core.TemplateManager.BaseTemplate.ExecuteTemplate(ctx.Response, templateName, ctx)
if err != nil {
ctx.String(err.Error())
}
}
// ExecuteTemplate gets a specific template from our list of templates and executes it
func (ctx *Context) ExecuteTemplate(templateName string) {
if _, ok := ctx.Enliven.Core.TemplateManager.Templates[templateName]; ok {
err := ctx.Enliven.Core.TemplateManager.Templates[templateName].Execute(ctx.Response, ctx)
if err != nil {
panic(err)
}
} else {
panic("Attempt to execute template that does not exist: " + templateName)
}
}
// JSON sets up JSON headers and outputs a JSON response
// Expects to recieve the result of json marshalling ([]byte)
func (ctx *Context) JSON(output []byte) {
ctx.Response.Header().Set("Content-Type", "application/json")
ctx.Response.Write(output)
}
// Redirect is a shortcut for redirecting a browser to a new URL
func (ctx *Context) Redirect(location string, status ...int) {
var statusCode int
if len(status) > 0 {
statusCode = status[0]
} else {
statusCode = 302
}
http.Redirect(ctx.Response, ctx.Request, location, statusCode)
}
// Forbidden returns a 403 status and the forbidden page.
func (ctx *Context) Forbidden() {
ctx.Response.WriteHeader(http.StatusForbidden)
ctx.ExecuteBaseTemplate("forbidden")
}
// NotFound returns a 404 status and the not-found page
func (ctx *Context) NotFound() {
ctx.Response.WriteHeader(http.StatusNotFound)
ctx.ExecuteBaseTemplate("notfound")
}
// BadRequest returns a 400 status and the bad-request page
func (ctx *Context) BadRequest() {
ctx.Response.WriteHeader(http.StatusBadRequest)
ctx.ExecuteBaseTemplate("badrequest")
}
// EmptyOK outputs a 200 status with nothing else
func (ctx *Context) EmptyOK() {
ctx.Response.WriteHeader(http.StatusOK)
ctx.String("")
}
// --------------------------------------------------
// CHandler Handles injecting the initial request context before passing handling on to the Middleware struct
type CHandler func(*Context)
// ServeHTTP is the first handler that gets hit when a request comes in.
func (ch CHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
ctx := &Context{
Vars: make(map[string]string),
Strings: make(map[string]string),
Integers: make(map[string]int),
Booleans: make(map[string]bool),
Storage: make(map[string]interface{}),
Enliven: &enliven,
Response: rw,
Request: r,
}
ch(ctx)
}
// ContextHandler sets up serving the first request, and the handing off of subsequent requests to the Middleware struct
func ContextHandler(h Middleware) CHandler {
return CHandler(func(ctx *Context) {
h.handler.ServeHTTP(ctx, h.next.ServeHTTP)
})
}