-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
137 lines (112 loc) · 3.48 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
132
133
134
135
136
137
package goose
import (
"encoding/json"
"fmt"
"net/http"
)
// Context represents the context of the current HTTP request
type Context struct {
ResponseWriter http.ResponseWriter
Request *http.Request
// request-related
Path string
Method string
// response-related
// HTTP status code
Code int
// misc
Params map[string]string
handlers []HandlerFunc
// used in the middleware component
index int
goose *Goose
}
func newContext(goose *Goose) *Context {
return &Context{goose: goose}
}
func (ctx *Context) resetContext(w http.ResponseWriter, r *http.Request) {
*ctx = Context{
ResponseWriter: w,
Request: r,
Path: r.URL.Path,
Method: r.Method,
index: -1,
goose: ctx.goose,
}
}
// Response part
// Header sets the header information for the response
func (ctx *Context) Header(key, value string) {
ctx.ResponseWriter.Header().Set(key, value)
}
// StatusCode sets the status code for the response
func (ctx *Context) StatusCode(code int) {
ctx.Code = code
ctx.ResponseWriter.WriteHeader(code)
}
// String writes string to the response
func (ctx *Context) String(format string, a ...interface{}) {
ctx.StringC(http.StatusOK, format, a...)
}
// HTML writes "data" to template "tplName" in the response
func (ctx *Context) HTML(tplName string, data interface{}) {
ctx.HTMLC(http.StatusOK, tplName, data)
}
// JSON writes json to the response
func (ctx *Context) JSON(obj interface{}) {
ctx.JSONC(http.StatusOK, obj)
}
// StringC writes string to the response with status Code
func (ctx *Context) StringC(statusCode int, format string, a ...interface{}) {
ctx.Header("Content-Type", "text/plain; charset=utf-8")
ctx.StatusCode(statusCode)
if _, err := ctx.ResponseWriter.Write([]byte(fmt.Sprintf(format, a...))); err != nil {
ctx.Abort(http.StatusInternalServerError, err.Error())
}
}
// HTMLC writes html to the response with status Code
func (ctx *Context) HTMLC(statusCode int, tplName string, data interface{}) {
ctx.Header("Content-Type", "text/html; charset=utf-8")
ctx.StatusCode(statusCode)
err := ctx.goose.template.templates.ExecuteTemplate(ctx.ResponseWriter, tplName, data)
if err != nil {
ctx.Abort(http.StatusInternalServerError, err.Error())
}
}
// JSONC writes json to the response with status Code
func (ctx *Context) JSONC(statusCode int, obj interface{}) {
ctx.Header("Content-Type", "application/json; charset=utf-8")
ctx.StatusCode(statusCode)
encoder := json.NewEncoder(ctx.ResponseWriter)
if err := encoder.Encode(obj); err != nil {
ctx.Abort(http.StatusInternalServerError, err.Error())
}
}
// Request part
// Query returns the value of the given param in the request URL
func (ctx *Context) Query(param string) string {
return ctx.Request.URL.Query().Get(param)
}
// misc part
// Param returns the value associated with wildcard param in the routing pattern
func (ctx *Context) Param(param string) string {
value, exists := ctx.Params[param]
if !exists {
panic(fmt.Sprintf("Wildcard parameter %s doesn't exist.", param))
}
return value
}
// Next gives control to the next handler in Context.handlers
func (ctx *Context) Next() {
ctx.index++
numOfHandlers := len(ctx.handlers)
for ; ctx.index < numOfHandlers; ctx.index++ {
ctx.handlers[ctx.index](ctx)
}
}
// Abort stops the execution of current context and write to
// response with statusCode and message
func (ctx *Context) Abort(statusCode int, message string) {
ctx.index = len(ctx.handlers)
ctx.JSONC(statusCode, X{"message": message})
}