Skip to content

Commit d73aff2

Browse files
authored
Merge pull request #9 from mwojtyczka/https_support
Added https support
2 parents d462429 + defd2fa commit d73aff2

File tree

5 files changed

+109
-21
lines changed

5 files changed

+109
-21
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ src
1818

1919
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
2020
.glide/
21+
22+
# keys
23+
*.pem

README.md

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Basic implementation of proxy client may be found at https://github.com/GoMetric
5858

5959
## Usage
6060

61-
Run server:
61+
* Run server (HTTP):
6262

6363
```bash
6464
statsd-http-proxy \
@@ -71,6 +71,21 @@ statsd-http-proxy \
7171
--metric-prefix=prefix.subprefix
7272
```
7373

74+
* Run server (HTTPS):
75+
76+
```bash
77+
statsd-http-proxy \
78+
--verbose \
79+
--http-host=127.0.0.1 \
80+
--http-port=433 \
81+
--tls-cert=cert.pem \
82+
--tls-key=key.pem \
83+
--statsd-host=127.0.0.1 \
84+
--statsd-port=8125 \
85+
--jwt-secret=somesecret \
86+
--metric-prefix=prefix.subprefix
87+
```
88+
7489
Print server version and exit:
7590

7691
```bash
@@ -79,19 +94,23 @@ statsd-http-proxy --version
7994

8095
Command line arguments:
8196

82-
| Parameter | Description | Default value |
83-
|-----------------|--------------------------------------|--------------------------------------------------------------------------------|
84-
| verbose | Print debug info to stderr | Optional. Default false |
85-
| http-host | Host of HTTP server | Optional. Default 127.0.0.1. To accept connections on any interface, set to "" |
86-
| http-port | Port of HTTP server | Optional. Default 80 |
87-
| statsd-host | Host of StatsD instance | Optional. Default 127.0.0.1 |
88-
| statsd-port | Port of StatsD instance | Optional. Default 8125 |
89-
| jwt-secret | JWT token secret | Optional. If not set, server accepts all connections |
90-
| metric-prefix | Prefix, added to any metric name | Optional. If not set, do not add prefix |
91-
| version | Print version of server and exit | Optional |
97+
| Parameter | Description | Default value |
98+
|-----------------|--------------------------------------|-----------------------------------------------------------------------------------|
99+
| verbose | Print debug info to stderr | Optional. Default false |
100+
| http-host | Host of HTTP server | Optional. Default 127.0.0.1. To accept connections on any interface, set to "" |
101+
| http-port | Port of HTTP server | Optional. Default 80 |
102+
| tls-cert | TLS certificate for the HTTPS | Optional. Default "" to use HTTP. If both tls-cert and tls-key set, HTTPS is used |
103+
| tls-key | TLS private key for the HTTPS | Optional. Default "" to use HTTP. If both tls-cert and tls-key set, HTTPS is used |
104+
| statsd-host | Host of StatsD instance | Optional. Default 127.0.0.1 |
105+
| statsd-port | Port of StatsD instance | Optional. Default 8125 |
106+
| jwt-secret | JWT token secret | Optional. If not set, server accepts all connections |
107+
| metric-prefix | Prefix, added to any metric name | Optional. If not set, do not add prefix |
108+
| version | Print version of server and exit | Optional |
92109

93110
Sample code to send metric in browser with JWT token in header:
94111

112+
* HTTP:
113+
95114
```javascript
96115
$.ajax({
97116
url: 'http://127.0.0.1:8080/count/some.key.name',
@@ -105,6 +124,21 @@ $.ajax({
105124
});
106125
```
107126

127+
* HTTPS (if self-signed certificate is used it has to be accepted!):
128+
129+
```javascript
130+
$.ajax({
131+
url: 'https://127.0.0.1:433/count/some.key.name',
132+
method: 'POST',
133+
headers: {
134+
'X-JWT-Token' => 'some-jwt-token'
135+
},
136+
data: {
137+
value: 100500
138+
}
139+
});
140+
```
141+
108142
## Authentication
109143

110144
Authentication is optional. It based on passing JWT token to server, encrypted with secret, specified in `jwt-secret`
@@ -180,7 +214,7 @@ value=1
180214

181215
| Parameter | Description | Default value |
182216
|------------|--------------------------------------|------------------------------------|
183-
| value | Integer value | Optional. Default 1 |
217+
| value | Integer value | Optional. Default 1 |
184218

185219
## Response
186220

@@ -190,7 +224,7 @@ Other HTTP status codes:
190224

191225
| CODE | Description |
192226
|------------------|-----------------------------------------|
193-
| 400 Bad Request | Invalid parameters specified |
227+
| 400 Bad Request | Invalid parameters specified |
194228
| 401 Unauthorized | Token not sent |
195229
| 403 Forbidden | Token invalid/expired |
196230
| 404 Not found | Invalid url requested |

demo/index.html

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,22 @@
66
</head>
77
<body>
88

9-
You are running demo of StatsD HTTP Proxy. Please, start <b>statsdHttpProxy.sh</b> for handling HTTP requests and
10-
<b>statsdStub.sh</b> for monitoring proxied metrics.
9+
<p>You are running demo of StatsD HTTP(s) Proxy.</p>
1110

11+
<p>Please start <b>statsdHttpProxy.sh</b> for handling HTTP requests or <b>statsdHttpsProxy.sh</b> for handling HTTPS requests.</p>
12+
<p>Please start <b>statsdStub.sh</b> for monitoring proxied metrics.</p>
13+
14+
<p>Communication protocol:</p>
15+
<div>
16+
<input type="radio" id="protocol" class="protocolRadio"
17+
name="protocol" value="http" checked>
18+
<label for="protocol">HTTP (8080)</label>
19+
<input type="radio" id="protocol" class="protocolRadio"
20+
name="protocol" value="https">
21+
<label for="protocol">HTTPS (433)</label>
22+
</div>
23+
24+
<p>Options:</p>
1225
<ul>
1326
<li><a href="#" data-metric-type="count">Send count</a></li>
1427
<li><a href="#" data-metric-type="timing">Send timing</a></li>
@@ -26,7 +39,7 @@
2639
(function() {
2740
// Token is valid to 2029-02-23T21:32:22.615Z, and builds with secret: somesecret
2841
var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOjE1MTk0MjE1NDIsImV4cCI6MTg2NjU3Njc0MiwiYXVkIjoiIiwic3ViIjoiIiwiR3JlZXRpbmciOiJIZWxsbywgZGVzY2VuZGFudHMifQ.n2qI2Ar9KzL3IsmlHjZAQmrf_Iz2ugnplwNIl4ELlDk';
29-
var statsdHttpProxyHost = 'http://localhost:8080';
42+
var statsdHttpProxyHost = 'localhost';
3043
var metricName = 'someMetricName';
3144
var metricType = "count";
3245
var tokenMode = "token-in-header";
@@ -42,7 +55,14 @@
4255
// send some metric
4356
setInterval(function() {
4457
var headers = {};
45-
var url = statsdHttpProxyHost + '/' + metricType + '/' + metricName;
58+
var protocol = $('.protocolRadio:checked').val();
59+
var port = '8080' // http
60+
61+
if (protocol == 'https') {
62+
port = '433'
63+
}
64+
65+
var url = protocol + '://' + statsdHttpProxyHost + ':' + port + '/' + metricType + '/' + metricName;
4666
var data = {};
4767

4868
switch (metricType) {

demo/statsdHttpsProxy.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
3+
# This server start listening connections by HTTPS and pass it to StatsD by UDP
4+
5+
if [ ! -f "key.pem" -o ! -f "cert.pem" ]; then
6+
echo "Https credentials do not exist. Generating new self-signed certificate and key with a default subject"
7+
8+
openssl req -x509 -nodes -days 358000 -newkey rsa:2048 -keyout key.pem -out cert.pem -subj "/C=PL/ST=test/L=test/O=test/OU=test/CN=test"
9+
fi
10+
11+
CURRENT_DIR=$(dirname $(readlink -f $0))
12+
13+
$CURRENT_DIR/../bin/statsd-http-proxy \
14+
--verbose \
15+
--http-host=127.0.0.1 \
16+
--http-port=433 \
17+
--tls-cert=cert.pem \
18+
--tls-key=key.pem \
19+
--statsd-host=127.0.0.1 \
20+
--statsd-port=8125 \
21+
--jwt-secret=somesecret \
22+
--metric-prefix=prefix.subprefix

main.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package main
33
import (
44
"flag"
55
"fmt"
6+
"github.com/GoMetric/go-statsd-client"
67
"github.com/dgrijalva/jwt-go"
78
"github.com/gorilla/mux"
8-
"github.com/GoMetric/go-statsd-client"
99
"io/ioutil"
1010
"log"
1111
"net/http"
@@ -41,6 +41,8 @@ const jwtQueryStringKeyName = "token"
4141
// declare command line options
4242
var httpHost = flag.String("http-host", defaultHTTPHost, "HTTP Host")
4343
var httpPort = flag.Int("http-port", defaultHTTPPort, "HTTP Port")
44+
var tlsCert = flag.String("tls-cert", "", "TLS certificate to enable HTTPS")
45+
var tlsKey = flag.String("tls-key", "", "TLS private key to enable HTTPS")
4446
var statsdHost = flag.String("statsd-host", defaultStatsDHost, "StatsD Host")
4547
var statsdPort = flag.Int("statsd-port", defaultStatsDPort, "StatsD Port")
4648
var metricPrefix = flag.String("metric-prefix", "", "Prefix of metric name")
@@ -102,7 +104,7 @@ func main() {
102104
validateCORS(validateJWT(http.HandlerFunc(handleSetRequest))),
103105
).Methods("POST")
104106

105-
router.PathPrefix("/").Methods("OPTIONS").HandlerFunc(handlePreFlightCORSRequest);
107+
router.PathPrefix("/").Methods("OPTIONS").HandlerFunc(handlePreFlightCORSRequest)
106108

107109
// Create a new StatsD connection
108110
statsdClient = statsd.NewClient(*statsdHost, *statsdPort)
@@ -122,8 +124,15 @@ func main() {
122124
MaxHeaderBytes: 1 << 20,
123125
}
124126

125-
// start http server
126-
err := s.ListenAndServe()
127+
var err error
128+
if len(*tlsCert) > 0 && len(*tlsKey) > 0 {
129+
// start https server
130+
err = s.ListenAndServeTLS(*tlsCert, *tlsKey)
131+
} else {
132+
// start http server
133+
err = s.ListenAndServe()
134+
}
135+
127136
if err != nil {
128137
log.Fatal(err)
129138
os.Exit(1)

0 commit comments

Comments
 (0)