-
Notifications
You must be signed in to change notification settings - Fork 36
/
pipeline.go
95 lines (82 loc) · 1.9 KB
/
pipeline.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
package thinkgo
import (
"container/list"
"html/template"
"net/http"
"github.com/forgoer/thinkgo/context"
"github.com/forgoer/thinkgo/router"
"github.com/forgoer/thinkgo/think"
)
type Pipeline struct {
handlers []think.Handler
pipeline *list.List
passable *context.Request
}
// Pipeline returns a new Pipeline
func NewPipeline() *Pipeline {
p := &Pipeline{
pipeline: list.New(),
}
return p
}
// Pipe Push a Middleware Handler to the pipeline
func (p *Pipeline) Pipe(m think.Handler) *Pipeline {
p.pipeline.PushBack(m)
return p
}
// Pipe Batch push Middleware Handlers to the pipeline
func (p *Pipeline) Through(hls []think.Handler) *Pipeline {
for _, hl := range hls {
p.Pipe(hl)
}
return p
}
// Passable set the request being sent through the pipeline.
func (p *Pipeline) Passable(passable *context.Request) *Pipeline {
p.passable = passable
return p
}
// Run run the pipeline
func (p *Pipeline) Run() interface{} {
var result interface{}
e := p.pipeline.Front()
if e != nil {
result = p.handler(p.passable, e)
}
return result
}
// ServeHTTP
func (p *Pipeline) ServeHTTP(w http.ResponseWriter, r *http.Request) {
request := context.NewRequest(r)
request.CookieHandler = context.ParseCookieHandler()
p.Passable(request)
result := p.Run()
switch result.(type) {
case router.Response:
result.(router.Response).Send(w)
break
case template.HTML:
think.Html(string(result.(template.HTML))).Send(w)
break
case http.Handler:
result.(http.Handler).ServeHTTP(w, r)
break
default:
think.Response(result).Send(w)
break
}
}
func (p *Pipeline) handler(passable *context.Request, e *list.Element) interface{} {
if e == nil {
return nil
}
hl := e.Value.(think.Handler)
result := hl.Process(passable, p.closure(e))
return result
}
func (p *Pipeline) closure(e *list.Element) think.Closure {
return func(req *context.Request) interface{} {
e = e.Next()
return p.handler(req, e)
}
}