From 9895cd8161102a405211fcf2f7c1c450a85bae57 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 13 Oct 2016 02:16:20 +0200 Subject: basic features are done --- src/daq/s5proxy/sample.json | 16 +++-- src/daq/s5proxy/src/s5proxy/config.go | 64 ++++++++++++++++++ src/daq/s5proxy/src/s5proxy/proxy.go | 117 +++++++++++++++++++++++++++++++++ src/daq/s5proxy/src/s5proxy/s5proxy.go | 14 +++- 4 files changed, 203 insertions(+), 8 deletions(-) create mode 100644 src/daq/s5proxy/src/s5proxy/config.go create mode 100644 src/daq/s5proxy/src/s5proxy/proxy.go diff --git a/src/daq/s5proxy/sample.json b/src/daq/s5proxy/sample.json index 8086a82..1339fbf 100644 --- a/src/daq/s5proxy/sample.json +++ b/src/daq/s5proxy/sample.json @@ -1,9 +1,13 @@ { - 'listen': ':8443', - 'connect': ':8000', - 'request_header': { - } - 'response_header': { - 'Cache-Control': 'no-cache' + "listen": ":8443", + "connect": "http://emc01.spreadspace.org:8000", + "cert": "fullchain.pem", + "key": "private.key", + "request_header": { + "X-hello": "world", + "X-verr": "stefan" + }, + "response_header": { + "Cache-Control": "no-cache" } } diff --git a/src/daq/s5proxy/src/s5proxy/config.go b/src/daq/s5proxy/src/s5proxy/config.go new file mode 100644 index 0000000..bffb672 --- /dev/null +++ b/src/daq/s5proxy/src/s5proxy/config.go @@ -0,0 +1,64 @@ +// +// sfive +// +// sfive - spreadspace streaming statistics suite is a generic +// statistic collection tool for streaming server infrastuctures. +// The system collects and stores meta data like number of views +// and throughput from a number of streaming servers and stores +// it in a global data store. +// The data acquisition is designed to be generic and extensible in +// order to support different streaming software. +// sfive also contains tools and applications to filter and visualize +// live and recorded data. +// +// +// Copyright (C) 2014-2016 Christian Pointner +// Markus Grüneis +// +// This file is part of sfive. +// +// sfive is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 3 +// as published by the Free Software Foundation. +// +// sfive is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with sfive. If not, see . +// + +package main + +import ( + "encoding/json" + "os" +) + +type Config struct { + ListenAddr string `json:"listen"` + ConnectAddr string `json:"connect"` + CertFile string `json:"cert"` + KeyFile string `json:"key"` + RequestHeader map[string]string `json:"request_header"` + ResponseHeader map[string]string `json:"response_header"` +} + +func readConfig(configfile string) (conf *Config, err error) { + s5l.Printf("reading config from: %s", configfile) + + var f *os.File + if f, err = os.Open(configfile); err != nil { + return + } + defer f.Close() + + conf = &Config{} + conf.RequestHeader = make(map[string]string) + conf.ResponseHeader = make(map[string]string) + + err = json.NewDecoder(f).Decode(conf) + return +} diff --git a/src/daq/s5proxy/src/s5proxy/proxy.go b/src/daq/s5proxy/src/s5proxy/proxy.go new file mode 100644 index 0000000..d1fb892 --- /dev/null +++ b/src/daq/s5proxy/src/s5proxy/proxy.go @@ -0,0 +1,117 @@ +// +// sfive +// +// sfive - spreadspace streaming statistics suite is a generic +// statistic collection tool for streaming server infrastuctures. +// The system collects and stores meta data like number of views +// and throughput from a number of streaming servers and stores +// it in a global data store. +// The data acquisition is designed to be generic and extensible in +// order to support different streaming software. +// sfive also contains tools and applications to filter and visualize +// live and recorded data. +// +// +// Copyright (C) 2014-2016 Christian Pointner +// Markus Grüneis +// +// This file is part of sfive. +// +// sfive is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 3 +// as published by the Free Software Foundation. +// +// sfive is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with sfive. If not, see . +// + +package main + +import ( + "crypto/tls" + "net/http" + "net/http/httputil" + "net/url" +) + +type s5proxyResponseWriter struct { + wrapped http.ResponseWriter + conf *Config +} + +func (r s5proxyResponseWriter) Header() http.Header { + return r.wrapped.Header() +} + +func (r s5proxyResponseWriter) Write(data []byte) (int, error) { + return r.wrapped.Write(data) +} + +func (r s5proxyResponseWriter) WriteHeader(status int) { + for hdr, value := range r.conf.ResponseHeader { + r.wrapped.Header().Set(hdr, value) + } + r.wrapped.WriteHeader(status) +} + +func proxyHandler(c *Config, p *httputil.ReverseProxy, w http.ResponseWriter, r *http.Request) { + pw := s5proxyResponseWriter{wrapped: w, conf: c} + p.ServeHTTP(pw, r) +} + +func s5proxyInit(conf *Config) (m *http.ServeMux, err error) { + remote, err := url.Parse(conf.ConnectAddr) + if err != nil { + return + } + p := httputil.NewSingleHostReverseProxy(remote) + origDir := p.Director + + p.Director = func(req *http.Request) { + origDir(req) + for hdr, value := range conf.RequestHeader { + req.Header.Set(hdr, value) + } + } + + m = http.NewServeMux() + m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + proxyHandler(conf, p, w, r) + }) + return +} + +func runProxy(conf *Config) error { + + mux, err := s5proxyInit(conf) + if err != nil { + return err + } + + // TODO: make this configurable + cfg := &tls.Config{ + MinVersion: tls.VersionTLS10, + CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, + PreferServerCipherSuites: true, + CipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_RSA_WITH_AES_256_CBC_SHA, + }, + } + + srv := &http.Server{ + Addr: conf.ListenAddr, + Handler: mux, + TLSConfig: cfg, + TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0), + } + + return srv.ListenAndServeTLS(conf.CertFile, conf.KeyFile) +} diff --git a/src/daq/s5proxy/src/s5proxy/s5proxy.go b/src/daq/s5proxy/src/s5proxy/s5proxy.go index 65e653d..f180138 100644 --- a/src/daq/s5proxy/src/s5proxy/s5proxy.go +++ b/src/daq/s5proxy/src/s5proxy/s5proxy.go @@ -41,7 +41,7 @@ import ( var s5l = log.New(os.Stderr, "[s5]\t", log.LstdFlags) func main() { - config := flag.String("config", "/etc/s5proxy/default.json", "path to the config file") + cf := flag.String("config", "/etc/s5proxy/default.json", "path to the config file") help := flag.Bool("help", false, "show usage") @@ -53,5 +53,15 @@ func main() { return } - s5l.Printf("reading config from: %s", *config) + conf, err := readConfig(*cf) + if err != nil { + s5l.Printf("Error reading config file: %v\n", err) + os.Exit(1) + } + + err = runProxy(conf) + if err != nil { + s5l.Printf("Error: %+v\n", err) + } + s5l.Println("shuting down!") } -- cgit v1.2.3