Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ src

# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/

# keys
*.pem
Copy link
Member

@sokil sokil Jan 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pem ignored in all project or just in demo dir?

Copy link
Author

@mwojtyczka mwojtyczka Jan 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would generally exlude pem files from the whole project. They should never be checked in. For demo it will be generated on the fly.

60 changes: 47 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Basic implementation of proxy client may be found at https://github.com/GoMetric

## Usage

Run server:
* Run server (HTTP):

```bash
statsd-http-proxy \
Expand All @@ -71,6 +71,21 @@ statsd-http-proxy \
--metric-prefix=prefix.subprefix
```

* Run server (HTTPS):

```bash
statsd-http-proxy \
--verbose \
--http-host=127.0.0.1 \
--http-port=433 \
--tls-cert=cert.pem \
--tls-key=key.pem \
--statsd-host=127.0.0.1 \
--statsd-port=8125 \
--jwt-secret=somesecret \
--metric-prefix=prefix.subprefix
```

Print server version and exit:

```bash
Expand All @@ -79,19 +94,23 @@ statsd-http-proxy --version

Command line arguments:

| Parameter | Description | Default value |
|-----------------|--------------------------------------|--------------------------------------------------------------------------------|
| verbose | Print debug info to stderr | Optional. Default false |
| http-host | Host of HTTP server | Optional. Default 127.0.0.1. To accept connections on any interface, set to "" |
| http-port | Port of HTTP server | Optional. Default 80 |
| statsd-host | Host of StatsD instance | Optional. Default 127.0.0.1 |
| statsd-port | Port of StatsD instance | Optional. Default 8125 |
| jwt-secret | JWT token secret | Optional. If not set, server accepts all connections |
| metric-prefix | Prefix, added to any metric name | Optional. If not set, do not add prefix |
| version | Print version of server and exit | Optional |
| Parameter | Description | Default value |
|-----------------|--------------------------------------|-----------------------------------------------------------------------------------|
| verbose | Print debug info to stderr | Optional. Default false |
| http-host | Host of HTTP server | Optional. Default 127.0.0.1. To accept connections on any interface, set to "" |
| http-port | Port of HTTP server | Optional. Default 80 |
| tls-cert | TLS certificate for the HTTPS | Optional. Default "" to use HTTP. If both tls-cert and tls-key set, HTTPS is used |
| tls-key | TLS private key for the HTTPS | Optional. Default "" to use HTTP. If both tls-cert and tls-key set, HTTPS is used |
| statsd-host | Host of StatsD instance | Optional. Default 127.0.0.1 |
| statsd-port | Port of StatsD instance | Optional. Default 8125 |
| jwt-secret | JWT token secret | Optional. If not set, server accepts all connections |
| metric-prefix | Prefix, added to any metric name | Optional. If not set, do not add prefix |
| version | Print version of server and exit | Optional |

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

* HTTP:

```javascript
$.ajax({
url: 'http://127.0.0.1:8080/count/some.key.name',
Expand All @@ -105,6 +124,21 @@ $.ajax({
});
```

* HTTPS (if self-signed certificate is used it has to be accepted!):

```javascript
$.ajax({
url: 'https://127.0.0.1:433/count/some.key.name',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this samples differ only by url. Everyone know what it is https))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed, merged into the existing index.html

method: 'POST',
headers: {
'X-JWT-Token' => 'some-jwt-token'
},
data: {
value: 100500
}
});
```

## Authentication

Authentication is optional. It based on passing JWT token to server, encrypted with secret, specified in `jwt-secret`
Expand Down Expand Up @@ -178,7 +212,7 @@ value=1

| Parameter | Description | Default value |
|------------|--------------------------------------|------------------------------------|
| value | Integer value | Optional. Default 1 |
| value | Integer value | Optional. Default 1 |

## Response

Expand All @@ -188,7 +222,7 @@ Other HTTP status codes:

| CODE | Description |
|------------------|-----------------------------------------|
| 400 Bad Request | Invalid parameters specified |
| 400 Bad Request | Invalid parameters specified |
| 401 Unauthorized | Token not sent |
| 403 Forbidden | Token invalid/expired |
| 404 Not found | Invalid url requested |
Expand Down
28 changes: 24 additions & 4 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,22 @@
</head>
<body>

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

<p>Please start <b>statsdHttpProxy.sh</b> for handling HTTP requests or <b>statsdHttpsProxy.sh</b> for handling HTTPS requests.</p>
<p>Please start <b>statsdStub.sh</b> for monitoring proxied metrics.</p>

<p>Communication protocol:</p>
<div>
<input type="radio" id="protocol" class="protocolRadio"
name="protocol" value="http" checked>
<label for="protocol">HTTP (8080)</label>
<input type="radio" id="protocol" class="protocolRadio"
name="protocol" value="https">
<label for="protocol">HTTPS (433)</label>
</div>

<p>Options:</p>
<ul>
<li><a href="#" data-metric-type="count">Send count</a></li>
<li><a href="#" data-metric-type="timing">Send timing</a></li>
Expand All @@ -26,7 +39,7 @@
(function() {
// Token is valid to 2029-02-23T21:32:22.615Z, and builds with secret: somesecret
var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOjE1MTk0MjE1NDIsImV4cCI6MTg2NjU3Njc0MiwiYXVkIjoiIiwic3ViIjoiIiwiR3JlZXRpbmciOiJIZWxsbywgZGVzY2VuZGFudHMifQ.n2qI2Ar9KzL3IsmlHjZAQmrf_Iz2ugnplwNIl4ELlDk';
var statsdHttpProxyHost = 'http://localhost:8080';
var statsdHttpProxyHost = 'localhost';
var metricName = 'someMetricName';
var metricType = "count";
var tokenMode = "token-in-header";
Expand All @@ -42,7 +55,14 @@
// send some metric
setInterval(function() {
var headers = {};
var url = statsdHttpProxyHost + '/' + metricType + '/' + metricName;
var protocol = $('.protocolRadio:checked').val();
var port = '8080' // http

if (protocol == 'https') {
port = '433'
}

var url = protocol + '://' + statsdHttpProxyHost + ':' + port + '/' + metricType + '/' + metricName;
var data = {};

switch (metricType) {
Expand Down
22 changes: 22 additions & 0 deletions demo/statsdHttpsProxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh

# This server start listening connections by HTTPS and pass it to StatsD by UDP

if [ ! -f "key.pem" -o ! -f "cert.pem" ]; then
echo "Https credentials do not exist. Generating new self-signed certificate and key with a default subject"

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"
fi

CURRENT_DIR=$(dirname $(readlink -f $0))

$CURRENT_DIR/../bin/statsd-http-proxy \
--verbose \
--http-host=127.0.0.1 \
--http-port=433 \
--tls-cert=cert.pem \
--tls-key=key.pem \
--statsd-host=127.0.0.1 \
--statsd-port=8125 \
--jwt-secret=somesecret \
--metric-prefix=prefix.subprefix
17 changes: 13 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package main
import (
"flag"
"fmt"
"github.com/GoMetric/go-statsd-client"
"github.com/dgrijalva/jwt-go"
"github.com/gorilla/mux"
"github.com/GoMetric/go-statsd-client"
"io/ioutil"
"log"
"net/http"
Expand Down Expand Up @@ -41,6 +41,8 @@ const jwtQueryStringKeyName = "token"
// declare command line options
var httpHost = flag.String("http-host", defaultHTTPHost, "HTTP Host")
var httpPort = flag.Int("http-port", defaultHTTPPort, "HTTP Port")
var tlsCert = flag.String("tls-cert", "", "TLS certificate to enable HTTPS")
var tlsKey = flag.String("tls-key", "", "TLS private key to enable HTTPS")
var statsdHost = flag.String("statsd-host", defaultStatsDHost, "StatsD Host")
var statsdPort = flag.Int("statsd-port", defaultStatsDPort, "StatsD Port")
var metricPrefix = flag.String("metric-prefix", "", "Prefix of metric name")
Expand Down Expand Up @@ -102,7 +104,7 @@ func main() {
validateCORS(validateJWT(http.HandlerFunc(handleSetRequest))),
).Methods("POST")

router.PathPrefix("/").Methods("OPTIONS").HandlerFunc(handlePreFlightCORSRequest);
router.PathPrefix("/").Methods("OPTIONS").HandlerFunc(handlePreFlightCORSRequest)

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

// start http server
err := s.ListenAndServe()
var err error
if len(*tlsCert) > 0 && len(*tlsKey) > 0 {
// start https server
err = s.ListenAndServeTLS(*tlsCert, *tlsKey)
} else {
// start http server
err = s.ListenAndServe()
}

if err != nil {
log.Fatal(err)
os.Exit(1)
Expand Down