@@ -26,10 +26,13 @@ type Context struct {
26
26
* Request
27
27
Session * session
28
28
Conn
29
+ responseStarted bool
29
30
}
30
31
31
32
func (ctx * Context ) Abort (status int , body string ) {
32
- //send an error
33
+ ctx .Conn .StartResponse (status )
34
+ ctx .Conn .WriteString (body )
35
+ ctx .responseStarted = true
33
36
}
34
37
35
38
//Sets a cookie -- duration is the amount of time in seconds. 0 = forever
@@ -49,7 +52,7 @@ func (ctx *Context) SetCookie(name string, value string, duration int64) {
49
52
var sessionMap = make (map [string ]* session )
50
53
51
54
func randomString (length int ) string {
52
- pop := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw "
55
+ pop := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "
53
56
var res bytes.Buffer
54
57
55
58
for i := 0 ; i < length ; i ++ {
@@ -65,19 +68,17 @@ type session struct {
65
68
Id string
66
69
}
67
70
68
- func newSession () * session {
69
- s := session {
70
- Data : make (map [string ]interface {}),
71
- Id : randomString (10 ),
72
- }
73
-
74
- return & s
75
- }
71
+ func newSession () * session {
72
+ s := session {
73
+ Data : make (map [string ]interface {}),
74
+ Id : randomString (10 ),
75
+ }
76
76
77
- func (s * session ) save () {
78
- sessionMap [s .Id ] = s ;
77
+ return & s
79
78
}
80
79
80
+ func (s * session ) save () { sessionMap [s .Id ] = s }
81
+
81
82
var contextType reflect.Type
82
83
var staticDir string
83
84
@@ -147,11 +148,6 @@ func httpHandler(c *http.Conn, req *http.Request) {
147
148
routeHandler (wreq , & conn )
148
149
}
149
150
150
- func error (conn Conn , code int , body string ) {
151
- conn .StartResponse (code )
152
- conn .WriteString (body )
153
- }
154
-
155
151
func routeHandler (req * Request , conn Conn ) {
156
152
requestPath := req .URL .Path
157
153
@@ -168,23 +164,23 @@ func routeHandler(req *Request, conn Conn) {
168
164
log .Stderrf ("Failed to parse form data %q" , perr .String ())
169
165
}
170
166
171
- //check the cookies for a session id
167
+ //check the cookies for a session id
172
168
perr = req .ParseCookies ()
173
169
if perr != nil {
174
170
log .Stderrf ("Failed to parse cookies %q" , perr .String ())
175
171
}
176
172
177
- s := newSession ()
178
-
179
- for k ,v := range ( req .Cookies ) {
180
- if k == sessionKey {
181
- if sess ,ok := sessionMap [ v ]; ok {
182
- s = sess
183
- }
184
- }
185
- }
186
-
187
- ctx := Context {req , s , conn }
173
+ s := newSession ()
174
+
175
+ for k , v := range ( req .Cookies ) {
176
+ if k == sessionKey {
177
+ if sess , ok := sessionMap [v ]; ok {
178
+ s = sess
179
+ }
180
+ }
181
+ }
182
+
183
+ ctx := Context {req , s , conn , false }
188
184
189
185
//try to serve a static file
190
186
staticFile := path .Join (staticDir , requestPath )
@@ -212,49 +208,54 @@ func routeHandler(req *Request, conn Conn) {
212
208
continue
213
209
}
214
210
215
- var args vector.Vector ;
211
+ var args vector.Vector
216
212
217
213
handlerType := route .handler .Type ().(* reflect.FuncType )
218
-
219
- //check if the first arg in the handler is a context type
214
+
215
+ //check if the first arg in the handler is a context type
220
216
if handlerType .NumIn () > 0 {
221
- if a0 ,ok := handlerType .In (0 ).(* reflect.PtrType ); ok {
217
+ if a0 , ok := handlerType .In (0 ).(* reflect.PtrType ); ok {
222
218
typ := a0 .Elem ()
223
219
if typ == contextType {
224
- args .Push ( reflect .NewValue (& ctx ) )
220
+ args .Push (reflect .NewValue (& ctx ))
225
221
}
226
222
}
227
223
}
228
224
229
225
for _ , arg := range match [1 :] {
230
- args .Push ( reflect .NewValue (arg ) )
226
+ args .Push (reflect .NewValue (arg ))
231
227
}
232
228
233
229
if len (args ) != handlerType .NumIn () {
234
230
log .Stderrf ("Incorrect number of arguments for %s\n " , requestPath )
235
- error ( conn , 500 , "Server Error" )
231
+ ctx . Abort ( 500 , "Server Error" )
236
232
return
237
233
}
238
234
239
- valArgs := make ( []reflect.Value , len (args ) );
240
- for i ,j := range (args ) { valArgs [i ] = j .(reflect.Value ) };
235
+ valArgs := make ([]reflect.Value , len (args ))
236
+ for i , j := range (args ) {
237
+ valArgs [i ] = j .(reflect.Value )
238
+ }
241
239
ret := route .handler .Call (valArgs )[0 ].(* reflect.StringValue ).Get ()
242
-
243
- //check if session data is stored
244
- if len (s .Data ) > 0 {
245
- s .save ()
246
- //set the session for half an hour
247
- ctx .SetCookie (sessionKey , s .Id , 1800 );
248
- }
249
-
250
- conn .StartResponse (200 )
251
-
252
- conn .WriteString (ret )
240
+
241
+ if ! ctx .responseStarted {
242
+ //check if session data is stored
243
+ if len (s .Data ) > 0 {
244
+ s .save ()
245
+ //set the session for half an hour
246
+ ctx .SetCookie (sessionKey , s .Id , 1800 )
247
+ }
248
+
249
+ conn .StartResponse (200 )
250
+ ctx .responseStarted = true
251
+ conn .WriteString (ret )
252
+ }
253
+
253
254
return
254
255
}
255
256
}
256
257
257
- error ( conn , 404 , "Page not found" )
258
+ ctx . Abort ( 404 , "Page not found" )
258
259
}
259
260
260
261
//runs the web application and serves http requests
0 commit comments