Skip to content
Newer
Older
100644 149 lines (121 sloc) 3.42 KB
d10507a @paulbellamy Adding a package comment for godoc and godashboard
authored Oct 5, 2011
1 // Mango is a modular web-application framework for Go, inspired by Rack and PEP333.
0956c74 @paulbellamy Re-organising project with examples folder
authored May 21, 2011
2 package mango
e8ede45 @paulbellamy Added main.go which refactors a few things
authored May 20, 2011
3
4 import (
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
5 "fmt"
1aaceb3 @paulbellamy adding a Logger method on the environment to fetch the logger object …
authored May 21, 2011
6 "log"
d968516 @paulbellamy Running go fmt
authored Mar 26, 2012
7 "net/http"
87f980f @paulbellamy Adding support for multiple headers
authored May 25, 2011
8 "net/textproto"
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
9 "os"
e8ede45 @paulbellamy Added main.go which refactors a few things
authored May 20, 2011
10 )
11
cef8d0e @paulbellamy Adding custom mango.Request object and a helper for getting it out of…
authored May 21, 2011
12 type Request struct {
13 *http.Request
14 }
15
16 type Status int
17 type Body string
18
87f980f @paulbellamy Adding support for multiple headers
authored May 25, 2011
19 type Headers http.Header
20
21 func (h Headers) Add(key, value string) {
22 textproto.MIMEHeader(h).Add(key, value)
23 }
24
25 func (h Headers) Set(key, value string) {
26 textproto.MIMEHeader(h).Set(key, value)
27 }
28
29 func (h Headers) Get(key string) string {
30 return textproto.MIMEHeader(h).Get(key)
31 }
32
33 func (h Headers) Del(key string) {
34 textproto.MIMEHeader(h).Del(key)
35 }
36
fd87b26 @paulbellamy Revert "renaming Env to Request which mirrors *http.Request"
authored May 20, 2011
37 type Env map[string]interface{}
1aaceb3 @paulbellamy adding a Logger method on the environment to fetch the logger object …
authored May 21, 2011
38
39 func (this Env) Logger() *log.Logger {
40 if this["mango.logger"] == nil {
41 this["mango.logger"] = log.New(os.Stdout, "", log.Ldate|log.Ltime)
42 }
43
44 return this["mango.logger"].(*log.Logger)
45 }
46
cef8d0e @paulbellamy Adding custom mango.Request object and a helper for getting it out of…
authored May 21, 2011
47 func (this Env) Request() *Request {
48 return this["mango.request"].(*Request)
49 }
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
50
e8619ee @paulbellamy Added skeleton of session handling
authored May 21, 2011
51 func (this Env) Session() map[string]interface{} {
52 return this["mango.session"].(map[string]interface{})
53 }
54
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
55 // This is the core app the user has written
fd87b26 @paulbellamy Revert "renaming Env to Request which mirrors *http.Request"
authored May 20, 2011
56 type App func(Env) (Status, Headers, Body)
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
57
58 // These are pieces of middleware,
ba0a38f @paulbellamy Renaming MangoApp and MangoMiddleware to App and Middleware
authored May 20, 2011
59 // which 'wrap' around the core App
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
60 // (and each other)
fd87b26 @paulbellamy Revert "renaming Env to Request which mirrors *http.Request"
authored May 20, 2011
61 type Middleware func(Env, App) (Status, Headers, Body)
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
62
ba0a38f @paulbellamy Renaming MangoApp and MangoMiddleware to App and Middleware
authored May 20, 2011
63 // Bundle a given list of Middleware pieces into a App
64 func bundle(r ...Middleware) App {
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
65 if len(r) <= 1 {
66 // Terminate the innermost piece of Middleware
67 // Basically stops it from recursing any further.
68 return func(input Env) (Status, Headers, Body) {
69 return r[0](input, func(Env) (Status, Headers, Body) {
70 panic("Core Mango App should never call it's upstream function.")
71 })
72 }
73 }
74 return wrap(r[0], bundle(r[1:]...))
e8ede45 @paulbellamy Added main.go which refactors a few things
authored May 20, 2011
75 }
76
ba0a38f @paulbellamy Renaming MangoApp and MangoMiddleware to App and Middleware
authored May 20, 2011
77 // Attach a piece of Middleware to the outside
78 // of a App. This wraps the inner App
79 // inside the outer Middleware.
80 func wrap(middleware Middleware, app App) App {
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
81 return func(input Env) (Status, Headers, Body) {
82 return middleware(input, app)
83 }
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
84 }
85
ba0a38f @paulbellamy Renaming MangoApp and MangoMiddleware to App and Middleware
authored May 20, 2011
86 // Convert a App into Middleware
87 // We convert the core app into a Middleware
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
88 // so we can pass it to Bundle as part of the
ba0a38f @paulbellamy Renaming MangoApp and MangoMiddleware to App and Middleware
authored May 20, 2011
89 // stack. Because the App does not call its
90 // upstream method, the resulting Middleware
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
91 // will just ignore any upstream passed to it.
ba0a38f @paulbellamy Renaming MangoApp and MangoMiddleware to App and Middleware
authored May 20, 2011
92 func middlewareify(app App) Middleware {
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
93 return func(input Env, upstream App) (Status, Headers, Body) {
94 return app(input)
95 }
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
96 }
e8ede45 @paulbellamy Added main.go which refactors a few things
authored May 20, 2011
97
fec0216 @paulbellamy Renaming mango.Mango to the less redundant mango.Stack
authored May 21, 2011
98 type Stack struct {
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
99 Address string
100 middleware []Middleware
101 app App
9c6d344 @paulbellamy Refactoring source
authored May 21, 2011
102 }
103
0ab6fb4 @paulbellamy Bumping version to 0.02.01 and adding VersionString
authored May 28, 2011
104 func Version() []int {
790ec6e @paulbellamy Bumping version to 0.04.00
authored Mar 26, 2012
105 return []int{0, 4, 0}
0ab6fb4 @paulbellamy Bumping version to 0.02.01 and adding VersionString
authored May 28, 2011
106 }
107
108 func VersionString() string {
109 v := Version()
110 return fmt.Sprintf("%d.%02d.%02d", v[0], v[1], v[2])
e8ede45 @paulbellamy Added main.go which refactors a few things
authored May 20, 2011
111 }
112
fec0216 @paulbellamy Renaming mango.Mango to the less redundant mango.Stack
authored May 21, 2011
113 func (this *Stack) Middleware(middleware ...Middleware) {
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
114 this.middleware = middleware
0ed5c2a @paulbellamy Integrating the functional composition stack building method into the…
authored May 20, 2011
115 }
116
7871cb2 @paulbellamy Adding mango_test file with tests for hello world and custom logger
authored May 24, 2011
117 func (this *Stack) Compile(app App) App {
08085de @paulbellamy running make format
authored May 25, 2011
118 this.app = app
7871cb2 @paulbellamy Adding mango_test file with tests for hello world and custom logger
authored May 24, 2011
119 return bundle(append(this.middleware, middlewareify(this.app))...)
120 }
121
122 func (this *Stack) HandlerFunc(app App) http.HandlerFunc {
08085de @paulbellamy running make format
authored May 25, 2011
123 compiled_app := this.Compile(app)
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
124 return func(w http.ResponseWriter, r *http.Request) {
125 env := make(map[string]interface{})
cef8d0e @paulbellamy Adding custom mango.Request object and a helper for getting it out of…
authored May 21, 2011
126 env["mango.request"] = &Request{r}
0ab6fb4 @paulbellamy Bumping version to 0.02.01 and adding VersionString
authored May 28, 2011
127 env["mango.version"] = Version()
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
128
129 status, headers, body := compiled_app(env)
130
87f980f @paulbellamy Adding support for multiple headers
authored May 25, 2011
131 for key, values := range headers {
132 for _, value := range values {
133 w.Header().Add(key, value)
134 }
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
135 }
136 w.WriteHeader(int(status))
ea791a1 @paulbellamy Fixing binary file transmission. Resolves #15
authored Aug 27, 2011
137 w.Write([]byte(body))
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
138 }
e8ede45 @paulbellamy Added main.go which refactors a few things
authored May 20, 2011
139 }
140
6d064af @paulbellamy Updating to compile on weekly.2012-03-04
authored Mar 10, 2012
141 func (this *Stack) Run(app App) error {
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
142 if this.Address == "" {
143 this.Address = "0.0.0.0:8000"
144 }
5b838c2 @paulbellamy Got session middleware and example working
authored May 22, 2011
145 fmt.Println("Starting Mango Stack On:", this.Address)
7871cb2 @paulbellamy Adding mango_test file with tests for hello world and custom logger
authored May 24, 2011
146 http.HandleFunc("/", this.HandlerFunc(app))
215ed5a @paulbellamy Resetting gofmt formatting to standard
authored May 21, 2011
147 return http.ListenAndServe(this.Address, nil)
e8ede45 @paulbellamy Added main.go which refactors a few things
authored May 20, 2011
148 }
Something went wrong with that request. Please try again.