Skip to content

Commit

Permalink
fix some possible race conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles-Antoine Mathieu committed Feb 21, 2018
1 parent 12f9059 commit b161950
Show file tree
Hide file tree
Showing 18 changed files with 834 additions and 549 deletions.
21 changes: 9 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ WSP server configuration
---
host : 127.0.0.1 # Address to bind the HTTP server
port : 8080 # Port to bind the HTTP server
timeout : 1000 # Time to wait before acquiring a WS connection to forward the request (milliseconds)
idletimeout : 60000 # Time to wait before closing idle connection when there is enough idle connections (milliseconds)
timeout : 1s # Time to wait before acquiring a WS connection to forward the request (milliseconds)
idletimeout : 60s # Time to wait before closing idle connection when there is enough idle connections (milliseconds)
#blacklist : # Forbidden destination ( deny nothing if empty )
# - method : ".*" # Applied in order before whitelist
# url : "^http(s)?://google.*" # None must match
# headers : # Optinal header check
# X-CUSTOM-HEADER : "^value$" #
# X-CUSTOM-HEADER : "^value$" #
#whitelist : # Allowed destinations ( allow all if empty )
# - method : "^GET$" # Applied in order after blacklist
# url : "^http(s)?://.*$" # One must match
# headers : # Optinal header check
# X-CUSTOM-HEADER : "^value$" #
# secretkey : ThisIsASecret # secret key that must be set in clients configuration
# X-CUSTOM-HEADER : "^value$" #
#secretkey : ThisIsASecret # shared secret key that must match the value set in clients configuration
```

```
Expand Down Expand Up @@ -83,23 +83,20 @@ targets : # Endpoints to connect to
- ws://127.0.0.1:8080/register #
poolidlesize : 10 # Default number of concurrent open (TCP) connections to keep idle per WSP server
poolmaxsize : 100 # Maximum number of concurrent open (TCP) connections per WSP server
#insecureSkipVerify : true # Disable the http client certificate chain and hostname verification
#blacklist : # Forbidden destination ( deny nothing if empty )
# - method : ".*" # Applied in order before whitelist
# url : ".*forbidden.*" # None must match
# headers : # Optinal header check
# X-CUSTOM-HEADER : "^value$" #
# X-CUSTOM-HEADER : "^value$" #
#whitelist : # Allowed destinations ( allow all if empty )
# - method : "^GET$" # Applied in order after blacklist
# url : "http(s)?://.*$" # One must match
# headers : # Optinal header check
# X-CUSTOM-HEADER : "^value$" #
# secretkey : ThisIsASecret # secret key that must match the value set in servers configuration
# X-CUSTOM-HEADER : "^value$" #
# secretkey : ThisIsASecret # shared secret key that must match the value set in servers configuration
```

- poolMinSize is the default number of opened TCP/HTTP/WS connections
to open per WSP server. If there is a burst of simpultaneous requests
the number of open connection will rise and then decrease back to this
number.
- poolMinIdleSize is the number of connection to keep idle, meaning
that if there is more than this number of simultaneous requests the
WSP client will try to open more connections to keep idle connection.
Expand Down
1 change: 1 addition & 0 deletions clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
for i in $(ps faux | grep wsp_ | grep -v grep | awk '{ print $2 }') ; do kill -9 $i ; done
61 changes: 42 additions & 19 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,66 @@
package client

import (
"crypto/tls"
"net/http"

"github.com/gorilla/websocket"
"github.com/root-gg/wsp/common"
"log"
)

// Client connects to one or more Server using HTTP websockets
// Client connects to one or more Server using HTTP WebSocket
// The Server can then send HTTP requests to execute
type Client struct {
Config *Config
Config *Config
validator *common.RequestValidator

client *http.Client
dialer *websocket.Dialer
pools map[string]*Pool
httpClient *http.Client
dialer *websocket.Dialer
pools map[string]*Pool
}

// NewClient creates a new Proxy
func NewClient(config *Config) (c *Client) {
c = new(Client)
c.Config = config
c.client = &http.Client{}
c.dialer = &websocket.Dialer{}
c.pools = make(map[string]*Pool)
func NewClient(config *Config) (client *Client) {
client = new(Client)
client.Config = config

client.validator = &common.RequestValidator{
Whitelist: config.Whitelist,
Blacklist: config.Blacklist,
}
err := client.validator.Initialize()
if err != nil {
log.Fatalf("Unable to initialize the request validator : %s", err)
}

// WebSocket tcp dialer to connect to the remote WSP servers
client.dialer = &websocket.Dialer{}

// HTTP client to execute HTTP requests received by the WebSocket tunnels
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: client.Config.InsecureSkipVerify},
}
client.httpClient = &http.Client{Transport: tr}

client.pools = make(map[string]*Pool)

return
}

// Start the Proxy
func (c *Client) Start() {
for _, target := range c.Config.Targets {
pool := NewPool(c, target, c.Config.SecretKey)
c.pools[target] = pool
go pool.Start()
func (client *Client) Start() {
for _, target := range client.Config.Targets {
pool := NewPool(client, target)
client.pools[target] = pool
pool.start()
}
}

// Shutdown the Proxy
func (c *Client) Shutdown() {
for _, pool := range c.pools {
pool.Shutdown()
func (client *Client) Shutdown() {
for _, pool := range client.pools {
pool.close()
}

}
40 changes: 16 additions & 24 deletions client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"io/ioutil"
"os"

"github.com/nu7hatch/gouuid"
"gopkg.in/yaml.v2"
Expand All @@ -11,13 +12,15 @@ import (

// Config configures an Proxy
type Config struct {
ID string
Targets []string
PoolIdleSize int
PoolMaxSize int
Whitelist []*common.Rule
Blacklist []*common.Rule
SecretKey string
Name string
ID string `json:"-"`
Targets []string
PoolIdleSize int
PoolMaxSize int
Whitelist []*common.Rule
Blacklist []*common.Rule
SecretKey string
InsecureSkipVerify bool
}

// NewConfig creates a new ProxyConfig
Expand All @@ -30,13 +33,16 @@ func NewConfig() (config *Config) {
}
config.ID = id.String()

hostname, err := os.Hostname()
if err != nil {
panic(err)
}
config.Name = hostname

config.Targets = []string{"ws://127.0.0.1:8080/register"}
config.PoolIdleSize = 10
config.PoolMaxSize = 100

config.Whitelist = make([]*common.Rule, 0)
config.Blacklist = make([]*common.Rule, 0)

return
}

Expand All @@ -54,19 +60,5 @@ func LoadConfiguration(path string) (config *Config, err error) {
return
}

// Compile the rules

for _, rule := range config.Whitelist {
if err = rule.Compile(); err != nil {
return
}
}

for _, rule := range config.Blacklist {
if err = rule.Compile(); err != nil {
return
}
}

return
}
Loading

0 comments on commit b161950

Please sign in to comment.