1
+
2
+ // Package web is a lightweight web framework for Go. It's ideal for
3
+ // writing simple, performant backend web services.
1
4
package web
2
5
3
6
import (
@@ -31,39 +34,51 @@ type ResponseWriter interface {
31
34
Close ()
32
35
}
33
36
37
+ // A Context object is created for every incoming HTTP request, and is
38
+ // passed to handlers as an optional first argument. It provides information
39
+ // about the request, including the http.Request object, the GET and POST params,
40
+ // and acts as a Writer for the response.
34
41
type Context struct {
35
42
Request * http.Request
36
43
Params map [string ]string
37
44
Server * Server
38
45
ResponseWriter
39
46
}
40
47
48
+ // WriteString writes string data into the response object.
41
49
func (ctx * Context ) WriteString (content string ) {
42
50
ctx .ResponseWriter .Write ([]byte (content ))
43
51
}
44
52
53
+ // Abort is a helper method that sends an HTTP header and an optional
54
+ // body. It is useful for returning 4xx or 5xx errors.
55
+ // Once it has been called, any return value from the handler will
56
+ // not be written to the response.
45
57
func (ctx * Context ) Abort (status int , body string ) {
46
58
ctx .ResponseWriter .WriteHeader (status )
47
59
ctx .ResponseWriter .Write ([]byte (body ))
48
60
}
49
61
62
+ // Redirect is a helper method for 3xx redirects.
50
63
func (ctx * Context ) Redirect (status int , url_ string ) {
51
64
ctx .ResponseWriter .Header ().Set ("Location" , url_ )
52
65
ctx .ResponseWriter .WriteHeader (status )
53
66
ctx .ResponseWriter .Write ([]byte ("Redirecting to: " + url_ ))
54
67
}
55
68
69
+ // Notmodified writes a 304 HTTP response
56
70
func (ctx * Context ) NotModified () {
57
71
ctx .ResponseWriter .WriteHeader (304 )
58
72
}
59
73
74
+ // NotFound writes a 404 HTTP response
60
75
func (ctx * Context ) NotFound (message string ) {
61
76
ctx .ResponseWriter .WriteHeader (404 )
62
77
ctx .ResponseWriter .Write ([]byte (message ))
63
78
}
64
79
65
- //Sets the content type by extension, as defined in the mime package.
66
- //For example, ctx.ContentType("json") sets the content-type to "application/json"
80
+ // Sets the content type by extension, as defined in the mime package.
81
+ // For example, ctx.ContentType("json") sets the content-type to "application/json"
67
82
func (ctx * Context ) ContentType (ext string ) {
68
83
if ! strings .HasPrefix (ext , "." ) {
69
84
ext = "." + ext
@@ -74,6 +89,8 @@ func (ctx *Context) ContentType(ext string) {
74
89
}
75
90
}
76
91
92
+ // SetHeader sets a response header. If `unique` is true, the current value
93
+ // of that header will be overwritten . If false, it will be appended.
77
94
func (ctx * Context ) SetHeader (hdr string , val string , unique bool ) {
78
95
if unique {
79
96
ctx .Header ().Set (hdr , val )
@@ -82,7 +99,8 @@ func (ctx *Context) SetHeader(hdr string, val string, unique bool) {
82
99
}
83
100
}
84
101
85
- //Sets a cookie -- duration is the amount of time in seconds. 0 = forever
102
+ // SetCookie sets a cookie header. Duration is specified in seconds. If the duration
103
+ // is zero, the cookie is permanent.
86
104
func (ctx * Context ) SetCookie (name string , value string , age int64 ) {
87
105
var utctime time.Time
88
106
if age == 0 {
@@ -204,6 +222,8 @@ type responseWriter struct {
204
222
http.ResponseWriter
205
223
}
206
224
225
+ // Close terminates the HTTP connection, and flushes all pending
226
+ // response data.
207
227
func (c * responseWriter ) Close () {
208
228
rwc , buf , _ := c .ResponseWriter .(http.Hijacker ).Hijack ()
209
229
if buf != nil {
@@ -220,7 +240,7 @@ func (s *Server) ServeHTTP(c http.ResponseWriter, req *http.Request) {
220
240
s .routeHandler (req , & w )
221
241
}
222
242
223
- //Calls a function with recover block
243
+ // safelyCall invokes ` function` in recover block
224
244
func (s * Server ) safelyCall (function reflect.Value , args []reflect.Value ) (resp []reflect.Value , e interface {}) {
225
245
defer func () {
226
246
if err := recover (); err != nil {
@@ -244,7 +264,8 @@ func (s *Server) safelyCall(function reflect.Value, args []reflect.Value) (resp
244
264
return function .Call (args ), nil
245
265
}
246
266
247
- //should the context be passed to the handler?
267
+ // requiresContext determines whether 'handlerType' contains
268
+ // an argument to 'web.Ctx' as its first argument
248
269
func requiresContext (handlerType reflect.Type ) bool {
249
270
//if the method doesn't take arguments, no
250
271
if handlerType .NumIn () == 0 {
@@ -264,6 +285,7 @@ func requiresContext(handlerType reflect.Type) bool {
264
285
return false
265
286
}
266
287
288
+ // the main route handler in web.go
267
289
func (s * Server ) routeHandler (req * http.Request , w ResponseWriter ) {
268
290
requestPath := req .URL .Path
269
291
ctx := Context {req , map [string ]string {}, s , w }
@@ -365,12 +387,16 @@ func (s *Server) routeHandler(req *http.Request, w ResponseWriter) {
365
387
ctx .Abort (404 , "Page not found" )
366
388
}
367
389
368
- var Config = & ServerConfig {
369
- RecoverPanic : true ,
390
+ // ServerConfig is configuration for server objects.
391
+ type ServerConfig struct {
392
+ StaticDir string
393
+ Addr string
394
+ Port int
395
+ CookieSecret string
396
+ RecoverPanic bool
370
397
}
371
398
372
- var mainServer = NewServer ()
373
-
399
+ // Server represents a web.go server.
374
400
type Server struct {
375
401
Config * ServerConfig
376
402
routes []route
@@ -398,7 +424,7 @@ func (s *Server) initServer() {
398
424
}
399
425
}
400
426
401
- //Runs the web application and serves http requests
427
+ // Run starts the web application and serves HTTP requests for s
402
428
func (s * Server ) Run (addr string ) {
403
429
s .initServer ()
404
430
@@ -420,7 +446,12 @@ func (s *Server) Run(addr string) {
420
446
s .l .Close ()
421
447
}
422
448
423
- //Runs the web application and serves https requests
449
+ // Run starts the web application and serves HTTP requests for the main server.
450
+ func Run (addr string ) {
451
+ mainServer .Run (addr )
452
+ }
453
+
454
+ // RunTLS starts the web application and serves HTTPS requests for s.
424
455
func (s * Server ) RunTLS (addr string , config * tls.Config ) error {
425
456
s .initServer ()
426
457
mux := http .NewServeMux ()
@@ -435,107 +466,105 @@ func (s *Server) RunTLS(addr string, config *tls.Config) error {
435
466
return http .Serve (s .l , mux )
436
467
}
437
468
438
- //Runs the web application and serves http requests
439
- func Run (addr string ) {
440
- mainServer .Run (addr )
441
- }
442
-
443
- //Runs the secure web application and serves https requests
469
+ // RunTLS starts the web application and serves HTTPS requests for the main server.
444
470
func RunTLS (addr string , config * tls.Config ) {
445
471
mainServer .RunTLS (addr , config )
446
472
}
447
473
448
- //Stops the web server
449
- func (s * Server ) Close () {
450
- if s .l != nil {
451
- s .l .Close ()
452
- }
453
- }
454
-
455
- //Stops the web server
456
- func Close () {
457
- mainServer .Close ()
458
- }
459
-
474
+ // RunScgi starts the web application and serves SCGI requests for s.
460
475
func (s * Server ) RunScgi (addr string ) {
461
476
s .initServer ()
462
477
s .Logger .Printf ("web.go serving scgi %s\n " , addr )
463
478
s .listenAndServeScgi (addr )
464
479
}
465
480
466
- //Runs the web application and serves scgi requests
481
+ // RunScgi starts the web application and serves SCGI requests for the main server.
467
482
func RunScgi (addr string ) {
468
483
mainServer .RunScgi (addr )
469
484
}
470
485
471
- //Runs the web application and serves scgi requests for this Server object .
486
+ // RunFcgi starts the web application and serves FastCGI requests for s .
472
487
func (s * Server ) RunFcgi (addr string ) {
473
488
s .initServer ()
474
489
s .Logger .Printf ("web.go serving fcgi %s\n " , addr )
475
490
s .listenAndServeFcgi (addr )
476
491
}
477
492
478
- //Runs the web application by serving fastcgi requests
493
+ // RunFcgi starts the web application and serves FastCGI requests for the main server.
479
494
func RunFcgi (addr string ) {
480
495
mainServer .RunFcgi (addr )
481
496
}
482
497
483
- //Adds a handler for the 'GET' http method.
498
+ // Close stops server s.
499
+ func (s * Server ) Close () {
500
+ if s .l != nil {
501
+ s .l .Close ()
502
+ }
503
+ }
504
+
505
+ // Close stops the main server.
506
+ func Close () {
507
+ mainServer .Close ()
508
+ }
509
+
510
+ // Get adds a handler for the 'GET' http method for server s.
484
511
func (s * Server ) Get (route string , handler interface {}) {
485
512
s .addRoute (route , "GET" , handler )
486
513
}
487
514
488
- //Adds a handler for the 'POST' http method.
515
+ // Post adds a handler for the 'POST' http method for server s .
489
516
func (s * Server ) Post (route string , handler interface {}) {
490
517
s .addRoute (route , "POST" , handler )
491
518
}
492
519
493
- //Adds a handler for the 'PUT' http method.
520
+ // Put adds a handler for the 'PUT' http method for server s .
494
521
func (s * Server ) Put (route string , handler interface {}) {
495
522
s .addRoute (route , "PUT" , handler )
496
523
}
497
524
498
- //Adds a handler for the 'DELETE' http method.
525
+ // Delete adds a handler for the 'DELETE' http method for server s .
499
526
func (s * Server ) Delete (route string , handler interface {}) {
500
527
s .addRoute (route , "DELETE" , handler )
501
528
}
502
529
503
- //Adds a handler for the 'GET' http method.
530
+ // Get adds a handler for the 'GET' http method in the main server .
504
531
func Get (route string , handler interface {}) {
505
532
mainServer .Get (route , handler )
506
533
}
507
534
508
- //Adds a handler for the 'POST' http method.
535
+ // Post adds a handler for the 'POST' http method in the main server .
509
536
func Post (route string , handler interface {}) {
510
537
mainServer .addRoute (route , "POST" , handler )
511
538
}
512
539
513
- //Adds a handler for the 'PUT' http method.
540
+ // Put adds a handler for the 'PUT' http method in the main server .
514
541
func Put (route string , handler interface {}) {
515
542
mainServer .addRoute (route , "PUT" , handler )
516
543
}
517
544
518
- //Adds a handler for the 'DELETE' http method.
545
+ // Delete adds a handler for the 'DELETE' http method in the main server .
519
546
func Delete (route string , handler interface {}) {
520
547
mainServer .addRoute (route , "DELETE" , handler )
521
548
}
522
549
550
+ // SetLogger sets the logger for server s
523
551
func (s * Server ) SetLogger (logger * log.Logger ) {
524
552
s .Logger = logger
525
553
}
526
554
555
+ // SetLogger sets the logger for the main server.
527
556
func SetLogger (logger * log.Logger ) {
528
557
mainServer .Logger = logger
529
558
}
530
559
531
- type ServerConfig struct {
532
- StaticDir string
533
- Addr string
534
- Port int
535
- CookieSecret string
536
- RecoverPanic bool
560
+ // Config is the configuration of the main server.
561
+ var Config = & ServerConfig {
562
+ RecoverPanic : true ,
537
563
}
538
564
565
+ var mainServer = NewServer ()
566
+
567
+ // internal utility methods
539
568
func webTime (t time.Time ) string {
540
569
ftime := t .Format (time .RFC1123 )
541
570
if strings .HasSuffix (ftime , "UTC" ) {
@@ -565,6 +594,8 @@ func fileExists(dir string) bool {
565
594
return ! info .IsDir ()
566
595
}
567
596
597
+ // Urlencode is a helper method that converts a map into URL-encoded form data.
598
+ // It is a useful when constructing HTTP POST requests.
568
599
func Urlencode (data map [string ]string ) string {
569
600
var buf bytes.Buffer
570
601
for k , v := range data {
0 commit comments