-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.go
147 lines (129 loc) · 3.04 KB
/
index.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
// Package index is a micro plugin for stripping a path index
package index
import (
"errors"
"net/http"
"strings"
"github.com/micro/cli"
"github.com/micro/micro/plugin"
)
type index struct {
url string
r *response
}
type response struct {
status int
header http.Header
body []byte
}
func (i *index) Flags() []cli.Flag {
return []cli.Flag{
cli.StringFlag{
Name: "index_service",
Usage: "Service/Method to route index to. Specified without namespace e.g greeter/say/hello",
EnvVar: "INDEX_SERVICE",
},
// flags for response instead of service
cli.IntFlag{
Name: "index_status",
Usage: "HTTP status code for response",
EnvVar: "INDEX_STATUS",
},
cli.StringFlag{
Name: "index_header",
Usage: "Comma separated list of key-value pairs for response header",
EnvVar: "INDEX_HEADER",
},
cli.StringFlag{
Name: "index_body",
Usage: "Body of the response",
EnvVar: "INDEX_BODY",
},
}
}
func (i *index) Commands() []cli.Command {
return nil
}
func (i *index) Handler() plugin.Handler {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// set path if index
if r.URL.Path == "/" {
// write response if we have one
if i.r != nil {
// write headers
for k, v := range i.r.header {
w.Header().Add(k, strings.Join(v, ","))
}
// write status
w.WriteHeader(i.r.status)
// write body
w.Write(i.r.body)
// we're done
return
}
// no response, rewrite url to service
r.URL.Path = i.url
}
// serve request
h.ServeHTTP(w, r)
})
}
}
func (i *index) Init(ctx *cli.Context) error {
// check if there's a service
if service := ctx.String("index_service"); len(service) > 0 {
i.url = "/" + service
}
r := new(response)
// check if there's response content
// check status
if status := ctx.Int("index_status"); status > 0 {
r.status = status
}
// check header
if header := ctx.String("index_header"); len(header) > 0 {
head := make(http.Header)
for _, h := range strings.Split(header, ",") {
if parts := strings.Split(h, ":"); len(parts) == 2 {
head[parts[0]] = []string{parts[1]}
}
}
r.header = head
}
// check body
if body := ctx.String("index_body"); len(body) > 0 {
r.body = []byte(body)
}
// if we have status then use the response
if r.status > 0 {
i.r = r
}
if len(i.url) == 0 && i.r == nil {
return errors.New("neither index service or response specified")
}
return nil
}
func (i *index) String() string {
return "index"
}
// NewPlugin creates a new plugin expecting the service specified via flag
func NewPlugin() plugin.Plugin {
return &index{}
}
// WithService creates an index plugin with a service
func WithService(service string) plugin.Plugin {
return &index{
url: "/" + service,
}
}
// WithContent will write the given status, header and body
func WithResponse(status int, header http.Header, body []byte) plugin.Plugin {
return &index{
r: &response{
status: status,
header: header,
body: body,
},
}
}