Skip to content

Commit 42e89b1

Browse files
author
刘建平
committed
add virtualhost commands
1 parent 4ad20b9 commit 42e89b1

File tree

6 files changed

+327
-2
lines changed

6 files changed

+327
-2
lines changed

api/auth.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package api
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"github.com/h2object/h2object/util"
7+
)
8+
9+
type HeaderAuth struct{
10+
headers http.Header
11+
}
12+
13+
func NewHeaderAuth() *HeaderAuth {
14+
return &HeaderAuth{
15+
headers: http.Header{},
16+
}
17+
}
18+
19+
func (hds *HeaderAuth) Add(key, value string) {
20+
hds.headers.Add(key, value)
21+
}
22+
23+
func (hds *HeaderAuth) Set(key, value string) {
24+
hds.headers.Set(key, value)
25+
}
26+
27+
func (hds *HeaderAuth) Del(key string) {
28+
hds.headers.Del(key)
29+
}
30+
31+
func (hds *HeaderAuth) Do(req *http.Request) *http.Request {
32+
for k, vs := range hds.headers {
33+
req.Header.Del(k)
34+
for _, v := range vs {
35+
req.Header.Add(k, v)
36+
}
37+
}
38+
return req
39+
}
40+
41+
func NewAdminAuth(appid, secret string) Auth {
42+
auth := NewHeaderAuth()
43+
auth.Del("Authorization")
44+
auth.Add("Authorization", fmt.Sprintf("H2FORWARD %s", util.SignString(secret, appid)))
45+
return auth
46+
}

api/client.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package api
2+
3+
import (
4+
"sync"
5+
"github.com/h2object/rpc"
6+
)
7+
8+
type Auth interface{
9+
rpc.PreRequest
10+
}
11+
12+
type Logger interface{
13+
rpc.Logger
14+
Trace(format string, args ...interface{})
15+
Debug(format string, args ...interface{})
16+
Info(format string, args ...interface{})
17+
Warn(format string, args ...interface{})
18+
Error(format string, args ...interface{})
19+
Critical(format string, args ...interface{})
20+
}
21+
22+
var UserAgent = "Golang h2forward/api package"
23+
24+
type Client struct{
25+
sync.RWMutex
26+
addr string
27+
conn *rpc.Client
28+
}
29+
30+
func NewClient(addr string) *Client {
31+
connection := rpc.NewClient(rpc.H2OAnalyser{})
32+
clt := &Client{
33+
addr: addr,
34+
conn: connection,
35+
}
36+
return clt
37+
}

api/vhost.go

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package api
2+
3+
import (
4+
"github.com/h2object/rpc"
5+
. "github.com/h2object/h2forward/app"
6+
"net/url"
7+
"errors"
8+
)
9+
10+
func (h2o *Client) SetHost(l Logger, auth Auth, hostname string, url string) error {
11+
URL := rpc.BuildHttpURL(h2o.addr, "/virtualhost.json", nil)
12+
13+
h2o.Lock()
14+
defer h2o.Unlock()
15+
16+
h2o.conn.Prepare(auth)
17+
defer h2o.conn.Prepare(nil)
18+
19+
var hurl HostURL
20+
hurl.Host = hostname
21+
hurl.URL = url
22+
23+
if err := h2o.conn.PutJson(l, URL, hurl, nil); err != nil {
24+
return err
25+
}
26+
return nil
27+
}
28+
29+
func (h2o *Client) GetHost(l Logger, auth Auth, hosts []string, ret interface{}) error {
30+
var params url.Values = nil
31+
if len(hosts) > 0 {
32+
params = url.Values{
33+
"host": hosts,
34+
}
35+
}
36+
37+
URL := rpc.BuildHttpURL(h2o.addr, "/virtualhost.json", params)
38+
39+
h2o.Lock()
40+
defer h2o.Unlock()
41+
42+
h2o.conn.Prepare(auth)
43+
defer h2o.conn.Prepare(nil)
44+
45+
if err := h2o.conn.Get(l, URL, ret); err != nil {
46+
return err
47+
}
48+
return nil
49+
}
50+
51+
func (h2o *Client) DelHost(l Logger, auth Auth, hostname string) error {
52+
if hostname == "" {
53+
return errors.New("hostname absent")
54+
}
55+
params := url.Values{
56+
"host": {hostname},
57+
}
58+
URL := rpc.BuildHttpURL(h2o.addr, "/virtualhost.json", params)
59+
60+
h2o.Lock()
61+
defer h2o.Unlock()
62+
63+
h2o.conn.Prepare(auth)
64+
defer h2o.conn.Prepare(nil)
65+
66+
if err := h2o.conn.Delete(l, URL, nil); err != nil {
67+
return err
68+
}
69+
return nil
70+
}
71+
72+
73+

app/application.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,13 @@ func (app *Application) Init() error {
8585
}
8686
app.vhosts = vhosts
8787

88-
forwarder, err := forward.New()
88+
forwarder, err := forward.New(forward.Logger(app.Logger))
8989
if err != nil {
9090
return err
9191
}
9292
app.forwarder = forwarder
9393

94-
reverser, err := reverse.New(app.forwarder, reverse.Route(app.vhosts))
94+
reverser, err := reverse.New(app.forwarder, reverse.Route(app.vhosts), reverse.Logger(app.Logger))
9595
if err != nil {
9696
return err
9797
}

commands/commands.go

+27
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,33 @@ func App() *cli.App {
6262
stopCommand(ctx)
6363
},
6464
},
65+
{
66+
Name: "virtualhost",
67+
Usage: "virtualhost operate command",
68+
Subcommands: []cli.Command{
69+
{
70+
Name: "get",
71+
Usage: "get virtualhost setting by hostname",
72+
Action: func(ctx *cli.Context) {
73+
vhostGetCommand(ctx)
74+
},
75+
},
76+
{
77+
Name: "set",
78+
Usage: "set virtualhost setting by hostname",
79+
Action: func(ctx *cli.Context) {
80+
vhostSetCommand(ctx)
81+
},
82+
},
83+
{
84+
Name: "del",
85+
Usage: "del virtualhost setting by hostname",
86+
Action: func(ctx *cli.Context) {
87+
vhostDelCommand(ctx)
88+
},
89+
},
90+
},
91+
},
6592
}
6693

6794
return app

commands/vhost.go

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package commands
2+
3+
import (
4+
"os"
5+
"fmt"
6+
"path"
7+
"encoding/json"
8+
"path/filepath"
9+
"github.com/codegangsta/cli"
10+
"github.com/h2object/h2forward/app"
11+
"github.com/h2object/h2forward/api"
12+
)
13+
14+
func vhostGetCommand(ctx *cli.Context) {
15+
workdir := ctx.GlobalString("workdir")
16+
if workdir == "" {
17+
fmt.Println("unknown working directory, please use -w to provide.")
18+
os.Exit(1)
19+
}
20+
21+
// directory
22+
directory, err := filepath.Abs(workdir)
23+
if err != nil {
24+
fmt.Println("workdir:", err)
25+
return
26+
}
27+
28+
configs, err := app.LoadCONFIG(path.Join(directory, "h2forward.conf"))
29+
if err != nil {
30+
fmt.Println("load configure failed:", err)
31+
return
32+
}
33+
34+
addr := ctx.GlobalString("api")
35+
36+
configs.SetSection("forward")
37+
AppID := configs.StringDefault("appid", "")
38+
Secret := configs.StringDefault("secret", "")
39+
40+
client := api.NewClient(addr)
41+
auth := api.NewAdminAuth(AppID, Secret)
42+
43+
hosts := ctx.Args()
44+
ret := map[string]interface{}{}
45+
if err := client.GetHost(nil, auth, hosts, &ret); err != nil {
46+
fmt.Println("get host failed:", err)
47+
return
48+
}
49+
50+
b, _ := json.MarshalIndent(ret, "", " ")
51+
fmt.Println(string(b))
52+
return
53+
}
54+
55+
func vhostSetCommand(ctx *cli.Context) {
56+
workdir := ctx.GlobalString("workdir")
57+
if workdir == "" {
58+
fmt.Println("unknown working directory, please use -w to provide.")
59+
os.Exit(1)
60+
}
61+
62+
// directory
63+
directory, err := filepath.Abs(workdir)
64+
if err != nil {
65+
fmt.Println("workdir:", err)
66+
return
67+
}
68+
69+
configs, err := app.LoadCONFIG(path.Join(directory, "h2forward.conf"))
70+
if err != nil {
71+
fmt.Println("load configure failed:", err)
72+
return
73+
}
74+
75+
addr := ctx.GlobalString("api")
76+
77+
configs.SetSection("forward")
78+
AppID := configs.StringDefault("appid", "")
79+
Secret := configs.StringDefault("secret", "")
80+
81+
client := api.NewClient(addr)
82+
auth := api.NewAdminAuth(AppID, Secret)
83+
84+
args := ctx.Args()
85+
if len(args) != 2 {
86+
fmt.Println("command args: <hostname> <url>")
87+
return
88+
}
89+
90+
if err := client.SetHost(nil, auth, args[0], args[1]); err != nil {
91+
fmt.Println("set host failed:", err)
92+
return
93+
}
94+
95+
fmt.Printf("set host (%s) to url (%s) ok.\n", args[0], args[1])
96+
return
97+
}
98+
99+
func vhostDelCommand(ctx *cli.Context) {
100+
workdir := ctx.GlobalString("workdir")
101+
if workdir == "" {
102+
fmt.Println("unknown working directory, please use -w to provide.")
103+
os.Exit(1)
104+
}
105+
106+
// directory
107+
directory, err := filepath.Abs(workdir)
108+
if err != nil {
109+
fmt.Println("workdir:", err)
110+
return
111+
}
112+
113+
configs, err := app.LoadCONFIG(path.Join(directory, "h2forward.conf"))
114+
if err != nil {
115+
fmt.Println("load configure failed:", err)
116+
return
117+
}
118+
119+
addr := ctx.GlobalString("api")
120+
121+
configs.SetSection("forward")
122+
AppID := configs.StringDefault("appid", "")
123+
Secret := configs.StringDefault("secret", "")
124+
125+
client := api.NewClient(addr)
126+
auth := api.NewAdminAuth(AppID, Secret)
127+
128+
args := ctx.Args()
129+
if len(args) == 0 {
130+
fmt.Println("command args: <hostname1> <hostname2> ...")
131+
return
132+
}
133+
134+
for _, host := range args {
135+
if err := client.DelHost(nil, auth, host); err != nil {
136+
fmt.Println("det host failed:", err)
137+
return
138+
}
139+
fmt.Printf("det host (%s) ok.\n", host)
140+
}
141+
return
142+
}

0 commit comments

Comments
 (0)