This repository has been archived by the owner on Jan 31, 2020. It is now read-only.
/
context_util.go
178 lines (145 loc) · 4.61 KB
/
context_util.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package webfw
import (
"io"
"net/http"
"os"
"path"
"path/filepath"
"regexp"
"github.com/urandom/webfw/context"
"github.com/urandom/webfw/renderer"
"github.com/urandom/webfw/util"
lng "github.com/nicksnyder/go-i18n/i18n/language"
)
// GetDispatcher returns the request dispatcher.
func GetDispatcher(c context.Context) *Dispatcher {
if val, ok := c.GetGlobal(context.BaseCtxKey("dispatcher")); ok {
return val.(*Dispatcher)
}
return &Dispatcher{}
}
// GetConfig is a helper function for getting the current config
// from the request context.
func GetConfig(c context.Context) Config {
if val, ok := c.GetGlobal(context.BaseCtxKey("config")); ok {
return val.(Config)
}
return Config{}
}
// GetRenderer returns the current raw renderer from the context.
func GetRenderer(c context.Context) renderer.Renderer {
if val, ok := c.GetGlobal(context.BaseCtxKey("renderer")); ok {
return val.(renderer.Renderer)
}
return renderer.NewRenderer("template", "base.tmpl")
}
// GetLogger returns the error logger, to be used if an error occurs during
// a request.
func GetLogger(c context.Context) Logger {
if val, ok := c.GetGlobal(context.BaseCtxKey("logger")); ok {
return val.(Logger)
}
return NewStandardLogger(os.Stderr, "", 0)
}
// GetParams returns the current request path parameters from the context.
func GetParams(c context.Context, r *http.Request) RouteParams {
if val, ok := c.Get(r, context.BaseCtxKey("params")); ok {
return val.(RouteParams)
}
return RouteParams{}
}
// GetSession returns the current session from the context,
// if the Session middleware is in use.
func GetSession(c context.Context, r *http.Request) context.Session {
if val, ok := c.Get(r, context.BaseCtxKey("session")); ok {
return val.(context.Session)
}
conf := GetConfig(c)
var abspath string
if filepath.IsAbs(conf.Session.Dir) {
abspath = conf.Session.Dir
} else {
var err error
abspath, err = filepath.Abs(path.Join(filepath.Dir(os.Args[0]), conf.Session.Dir))
if err != nil {
abspath = os.TempDir()
}
}
sess := context.NewSession([]byte(conf.Session.Secret), []byte(conf.Session.Cipher), abspath)
sess.SetName(util.UUID())
return sess
}
// GetLanguage returns the current request language, such as "en", or "bg-BG"
// from the context, if the I18N middleware is in use.
func GetLanguage(c context.Context, r *http.Request) string {
if val, ok := c.Get(r, context.BaseCtxKey("lang")); ok {
return val.(string)
}
return GetFallbackLanguage(c, r)
}
var localeRegexp = regexp.MustCompile(`\.[\w\-]+$`)
// GetFallbackLanguage tries to obtain a requested language via the session,
// or the Accept-Language request header, or the LANG or LC_MESSAGES
// environment variables
func GetFallbackLanguage(c context.Context, r *http.Request, fallback ...string) string {
if val, ok := c.Get(r, context.BaseCtxKey("session")); ok {
sess := val.(context.Session)
if language, ok := sess.Get("language"); ok {
return language.(string)
}
}
langs := lng.Parse(r.Header.Get("Accept-Language"))
if len(langs) > 0 {
return langs[0].String()
}
language := os.Getenv("LANG")
if language == "" {
language = os.Getenv("LC_MESSAGES")
language = localeRegexp.ReplaceAllLiteralString(language, "")
}
if language == "" {
if len(fallback) > 0 {
language = fallback[0]
} else {
language = "en"
}
} else {
langs := lng.Parse(language)
if len(langs) > 0 {
return langs[0].String()
}
}
return language
}
// GetRenderCtx returns a RenderCtx wrapper around the current raw renderer
// The wrapper automatically adds the current request ContextData to the
// renderer's Render method call.
func GetRenderCtx(c context.Context, r *http.Request) renderer.RenderCtx {
rnd := GetRenderer(c)
return renderer.RenderCtx(func(w io.Writer, data renderer.RenderData, names ...string) error {
return rnd.Render(w, data, c.GetAll(r), names...)
})
}
// GetForwards returns a set forward path as a string, or the empty string.
func GetForward(c context.Context, r *http.Request) string {
if val, ok := c.Get(r, context.BaseCtxKey("forward")); ok {
return val.(string)
}
return ""
}
// GetNamedForward returns a name, used by the dispatcher to lookup a route to
// forward to.
func GetNamedForward(c context.Context, r *http.Request) string {
if val, ok := c.Get(r, context.BaseCtxKey("named-forward")); ok {
return val.(string)
}
return ""
}
// GetMultiPatternIdentifier returns the identifier for the current
// multi-pattern route.
func GetMultiPatternIdentifier(c context.Context, r *http.Request) string {
if val, ok := c.Get(r, context.BaseCtxKey("multi-pattern-identifier")); ok {
return val.(string)
}
return ""
}