From 7e6f0b76965847fd0ca88f67edf912bb4c8a119b Mon Sep 17 00:00:00 2001 From: Valentin Kuznetsov Date: Sun, 4 Apr 2021 17:28:07 -0400 Subject: [PATCH] switch server to gorilla mux; fix netron; add middleware support --- src/Go/config.go | 23 +++ src/Go/config.json | 2 +- src/Go/go.mod | 2 + src/Go/go.sum | 68 ++++++ src/Go/handlers.go | 113 ++-------- src/Go/main.go | 187 +---------------- src/Go/middlewares.go | 86 ++++++++ src/Go/server.go | 206 +++++++++++++++++++ src/Go/static/netron/logo.png | Bin 0 -> 96538 bytes src/Go/static/netron/spinner.png | Bin 0 -> 17214 bytes src/Go/static/netron/view-browser.html | 60 +++--- src/Go/static/netron/view-browser.html.orig | 91 ++++++++ src/Go/static/netron/view-electron.html.orig | 83 ++++++++ src/Go/utils.go | 3 - 14 files changed, 609 insertions(+), 315 deletions(-) create mode 100644 src/Go/config.go create mode 100644 src/Go/middlewares.go create mode 100644 src/Go/server.go create mode 100644 src/Go/static/netron/logo.png create mode 100644 src/Go/static/netron/spinner.png create mode 100644 src/Go/static/netron/view-browser.html.orig create mode 100644 src/Go/static/netron/view-electron.html.orig diff --git a/src/Go/config.go b/src/Go/config.go new file mode 100644 index 0000000..eea93d2 --- /dev/null +++ b/src/Go/config.go @@ -0,0 +1,23 @@ +package main + +import "fmt" + +// Configuration stores dbs configuration parameters +type Configuration struct { + Port int `json:"port"` // dbs port number + ModelDir string `json:"modelDir"` // location of model directory + StaticDir string `json:"staticDir"` // speficy static dir location + ConfigProto string `json:"configProto"` // TF config proto file to use + Base string `json:"base"` // dbs base path + LogFile string `json:"logFile"` // log file + Verbose int `json:"verbose"` // verbosity level + ServerKey string `json:"serverKey"` // server key for https + ServerCrt string `json:"serverCrt"` // server certificate for https + UpdateDNs int `json:"updateDNs"` // interval in minutes to update user DNs + CacheLimit int `json:"cacheLimit"` // number of TFModels to keep in cache +} + +// String returns string representation of server configuration +func (c *Configuration) String() string { + return fmt.Sprintf("", c.Port, c.ModelDir, c.StaticDir, c.Base, c.ConfigProto, c.Verbose, c.LogFile, c.ServerCrt, c.ServerKey) +} diff --git a/src/Go/config.json b/src/Go/config.json index 65f438f..38ee098 100644 --- a/src/Go/config.json +++ b/src/Go/config.json @@ -2,7 +2,7 @@ "port": 8083, "auth": "false", "modelDir": "models", - "staticDir": "static", + "staticDir": "", "configProto": "", "base": "", "serverKey": "", diff --git a/src/Go/go.mod b/src/Go/go.mod index 891d6bd..fddccdd 100644 --- a/src/Go/go.mod +++ b/src/Go/go.mod @@ -8,10 +8,12 @@ require ( github.com/galeone/tfgo v0.0.0-20210204182614-84b9a5e77f79 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/gorilla/mux v1.8.0 // indirect github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect github.com/lestrrat-go/strftime v1.0.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/shirou/gopsutil v3.21.3+incompatible // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect + github.com/ulule/limiter/v3 v3.8.0 // indirect github.com/vkuznet/x509proxy v0.0.0-20191014143623-163039704c67 // indirect ) diff --git a/src/Go/go.sum b/src/Go/go.sum index e475f3f..4be0623 100644 --- a/src/Go/go.sum +++ b/src/Go/go.sum @@ -2,28 +2,42 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/galeone/tensorflow v2.4.0-rc0.0.20210202175351-640a390c2283+incompatible h1:32i1dZzY2xO7tSzpea1hrSVOF6QxPPlGjmnVluVF+ps= github.com/galeone/tensorflow v2.4.0-rc0.0.20210202175351-640a390c2283+incompatible/go.mod h1:tPYvIhe58Qvzh/hJfdy0881FcAnouYskaz5tNIDEeMA= github.com/galeone/tfgo v0.0.0-20210204182614-84b9a5e77f79 h1:FqeRBi0Ju7Uv/01BWt5YhHjzQ76MM+kM2T73C8MD2o8= github.com/galeone/tfgo v0.0.0-20210204182614-84b9a5e77f79/go.mod h1:iXe7mY1vKyD1+70cKIwO+7BH18AQ79U0akU5IrgW3GU= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-redis/redis/v8 v8.4.2/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -34,12 +48,30 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4= github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8= github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -50,32 +82,60 @@ github.com/shirou/gopsutil v3.21.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ulule/limiter/v3 v3.8.0 h1:rq76QxDIq5s/rvXc/A6HRHuGmehi/JE18qK3FaRUxKg= +github.com/ulule/limiter/v3 v3.8.0/go.mod h1:TpV4HWgOM7M43mrkE7MU1S62/XtuoZ/C9PL+ExxeTK4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.17.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vkuznet/x509proxy v0.0.0-20191014143623-163039704c67 h1:7s/FGCnCgfaJxmyeE+k18s5Bpx1TIrss4sMesjqRJsI= github.com/vkuznet/x509proxy v0.0.0-20191014143623-163039704c67/go.mod h1:n8gnqWgHpPWW+DyA66Zam8qQshAmDxVVmSmObyR6M8g= +go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa h1:ZYxPR6aca/uhfRJyaOAtflSHjJYiktO7QnJC5ut7iY4= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -102,5 +162,13 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/src/Go/handlers.go b/src/Go/handlers.go index 270d983..14134e4 100644 --- a/src/Go/handlers.go +++ b/src/Go/handlers.go @@ -13,7 +13,6 @@ import ( "os" "runtime" "strings" - "sync/atomic" "time" tf "github.com/galeone/tensorflow/tensorflow/go" @@ -72,10 +71,6 @@ func DataHandler(w http.ResponseWriter, r *http.Request) { // ImageHandler send prediction from TF ML model func ImageHandler(w http.ResponseWriter, r *http.Request) { - if !(r.Method == "POST") { - responseError(w, fmt.Sprintf("wrong HTTP method: %v", r.Method), nil, http.StatusMethodNotAllowed) - return - } model := r.FormValue("model") if model == "" { msg := fmt.Sprintf("unable to read %s model", model) @@ -152,10 +147,6 @@ func ImageHandler(w http.ResponseWriter, r *http.Request) { // PredictProtobufHandler send prediction from TF ML model func PredictProtobufHandler(w http.ResponseWriter, r *http.Request) { - if !(r.Method == "POST") { - responseError(w, fmt.Sprintf("wrong HTTP method: %v", r.Method), nil, http.StatusMethodNotAllowed) - return - } defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { @@ -211,10 +202,6 @@ func PredictProtobufHandler(w http.ResponseWriter, r *http.Request) { // PredictHandler send prediction from TF ML model func PredictHandler(w http.ResponseWriter, r *http.Request) { - if !(r.Method == "POST") { - responseError(w, fmt.Sprintf("wrong HTTP method: %v", r.Method), nil, http.StatusMethodNotAllowed) - return - } defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { @@ -255,10 +242,6 @@ func (gz GzipReader) Close() error { // UploadHandler uploads TF models into the server func UploadHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - w.WriteHeader(http.StatusMethodNotAllowed) - return - } if r.FormValue("model") == "model" { // we received request for upload via form values UploadFormHandler(w, r) @@ -269,11 +252,6 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) { // UploadBundleHandler uploads TF models into the server func UploadBundleHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - msg := "wrong HTTP method" - responseError(w, msg, nil, http.StatusMethodNotAllowed) - return - } var err error var bundle []byte defer r.Body.Close() @@ -314,11 +292,6 @@ func UploadBundleHandler(w http.ResponseWriter, r *http.Request) { // UploadFormHandler uploads TF models into the server via form key-value pairs func UploadFormHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - msg := "wrong HTTP method" - responseError(w, msg, nil, http.StatusMethodNotAllowed) - return - } defer r.Body.Close() if VERBOSE > 0 { @@ -455,6 +428,7 @@ func ModelsHandler(w http.ResponseWriter, r *http.Request) { if err != nil { msg := fmt.Sprintf("Unable to get TF models") responseError(w, msg, err, http.StatusInternalServerError) + return } responseJSON(w, models) } @@ -473,63 +447,8 @@ func DefaultHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte(_header + main + _footer)) } -// AuthHandler authenticate incoming requests and route them to appropriate handler -func AuthHandler(w http.ResponseWriter, r *http.Request) { - // check if server started with hkey file (auth is required) - if Auth == "true" { - status := auth(r) - if !status { - msg := "not allowed access this resource" - responseError(w, msg, nil, http.StatusForbidden) - return - } - } - // increment GET/POST counters - if r.Method == "GET" { - atomic.AddUint64(&TotalGetRequests, 1) - } - if r.Method == "POST" { - atomic.AddUint64(&TotalPostRequests, 1) - } - path := r.URL.Path - if _config.Base != "" { - path = strings.Replace(path, _config.Base, "", 1) - } - arr := strings.Split(path, "/") - path = arr[1] - switch path { - case "upload": - UploadHandler(w, r) - case "delete": - DeleteHandler(w, r) - case "data": - DataHandler(w, r) - case "json": - PredictHandler(w, r) - case "proto": - PredictProtobufHandler(w, r) - case "image": - ImageHandler(w, r) - case "params": - ParamsHandler(w, r) - case "models": - ModelsHandler(w, r) - case "status": - StatusHandler(w, r) - case "netron": - NetronHandler(w, r) - default: - DefaultHandler(w, r) - } -} - // StatusHandler handlers Status requests func StatusHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - msg := "wrong HTTP method" - responseError(w, msg, nil, http.StatusMethodNotAllowed) - return - } // get cpu and mem profiles m, _ := mem.VirtualMemory() s, _ := mem.SwapMemory() @@ -560,11 +479,6 @@ func StatusHandler(w http.ResponseWriter, r *http.Request) { // NetronHandler provides hook to netron visualization library for graphs, // see /~https://github.com/lutzroeder/Netron func NetronHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - msg := "wrong HTTP method" - responseError(w, msg, nil, http.StatusMethodNotAllowed) - return - } var endPoint string base := strings.TrimLeft(_config.Base, "/") for _, v := range strings.Split(r.URL.Path, "/") { @@ -575,18 +489,32 @@ func NetronHandler(w http.ResponseWriter, r *http.Request) { } var ifile string endPoint = strings.TrimLeft(endPoint, "/") + sdir := _config.StaticDir + if sdir == "" { + sdir = "static" + } if endPoint == "" || endPoint == "netron" { - ifile = fmt.Sprintf("%s/netron/%s", _config.StaticDir, "view-browser.html") + ifile = fmt.Sprintf("%s/netron/%s", sdir, "view-browser.html") } else { - ifile = fmt.Sprintf("%s/netron/%s", _config.StaticDir, endPoint) + ifile = fmt.Sprintf("%s/netron/%s", sdir, endPoint) } - // fmt.Println("ifile", ifile) + // log.Println("ifile", ifile, http.Dir(ifile)) page, err := ioutil.ReadFile(ifile) if err != nil { + log.Println("netron", err) msg := fmt.Sprintf("unable to load %s", r.URL.Path) responseError(w, msg, err, http.StatusInternalServerError) return } + if strings.HasSuffix(ifile, "css") { + w.Header().Add("Content-Type", "text/css") + } else if strings.HasSuffix(ifile, "js") { + w.Header().Add("Content-Type", "text/javascript") + } else if strings.HasSuffix(ifile, "png") { + w.Header().Add("Content-Type", "image/png") + } else if strings.HasSuffix(ifile, "psvg") { + w.Header().Add("Content-Type", "image/svg") + } w.Write(page) } @@ -594,11 +522,6 @@ func NetronHandler(w http.ResponseWriter, r *http.Request) { // DeleteHandler authenticate incoming requests and route them to appropriate handler func DeleteHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "DELETE" { - msg := "wrong HTTP method" - responseError(w, msg, nil, http.StatusMethodNotAllowed) - return - } model := r.FormValue("model") files, err := ioutil.ReadDir(_config.ModelDir) if err != nil { diff --git a/src/Go/main.go b/src/Go/main.go index b619955..bdaf24c 100644 --- a/src/Go/main.go +++ b/src/Go/main.go @@ -1,74 +1,13 @@ package main import ( - "crypto/tls" "flag" "fmt" - "log" - "net/http" - "net/url" "os" "runtime" "time" - - rotatelogs "github.com/lestrrat-go/file-rotatelogs" ) -// VERBOSE controls verbosity of the server -var VERBOSE int - -// Auth represents flag to use authentication or not -var Auth string - -// Time0 represents initial time when we start the server -var Time0 time.Time - -// global variables -var ( - _header, _footer, _tmplDir string -) - -// helper function to produce UTC time prefixed output -func utcMsg(data []byte) string { - // return fmt.Sprintf("[" + time.Now().String() + "] " + string(data)) - s := string(data) - v, e := url.QueryUnescape(s) - if e == nil { - return v - } - return s -} - -// custom rotate logger -type rotateLogWriter struct { - RotateLogs *rotatelogs.RotateLogs -} - -func (w rotateLogWriter) Write(data []byte) (int, error) { - return w.RotateLogs.Write([]byte(utcMsg(data))) -} - -// Configuration stores dbs configuration parameters -type Configuration struct { - Port int `json:"port"` // dbs port number - Auth string `json:"auth"` // use authentication or not - ModelDir string `json:"modelDir"` // location of model directory - StaticDir string `json:"staticDir"` // speficy static dir location - ConfigProto string `json:"configProto"` // TF config proto file to use - Base string `json:"base"` // dbs base path - LogFile string `json:"logFile"` // log file - Verbose int `json:"verbose"` // verbosity level - ServerKey string `json:"serverKey"` // server key for https - ServerCrt string `json:"serverCrt"` // server certificate for https - UpdateDNs int `json:"updateDNs"` // interval in minutes to update user DNs - CacheLimit int `json:"cacheLimit"` // number of TFModels to keep in cache -} - -// String returns string representation of server configuration -func (c *Configuration) String() string { - return fmt.Sprintf("", c.Port, c.ModelDir, c.StaticDir, c.Base, c.Auth, c.ConfigProto, c.Verbose, c.LogFile, c.ServerCrt, c.ServerKey) -} - // helper function to return current version func info() string { goVersion := runtime.Version() @@ -76,20 +15,6 @@ func info() string { return fmt.Sprintf("Build: git={{VERSION}} go=%s date=%s", goVersion, tstamp) } -// Memory contains details about memory information -type Memory struct { - Total uint64 `json:"total"` - Free uint64 `json:"free"` - Used uint64 `json:"used"` - UsedPercent float64 `json:"usedPercent"` -} - -// Mem keeps memory information -type Mem struct { - Virtual Memory - Swap Memory -} - func main() { var config string flag.StringVar(&config, "config", "config.json", "configuration file for our server") @@ -101,116 +26,6 @@ func main() { fmt.Println(info()) os.Exit(0) } + server(config) - Time0 = time.Now() - - var err error - _client = httpClient() - err = parseConfig(config) - if err != nil { - log.Println("unable to parse config", err) - } - - // setup config - if _config.LogFile != "" { - logName := _config.LogFile + "-%Y%m%d" - hostname, err := os.Hostname() - if err == nil { - logName = _config.LogFile + "-" + hostname + "-%Y%m%d" - } - rl, err := rotatelogs.New(logName) - if err == nil { - rotlogs := rotateLogWriter{RotateLogs: rl} - log.SetOutput(rotlogs) - log.SetFlags(log.LstdFlags | log.Lshortfile) - } else { - log.SetFlags(log.LstdFlags | log.Lshortfile) - } - } else { - // log time, filename, and line number - log.SetFlags(log.LstdFlags | log.Lshortfile) - } - - // create session options from given config TF proto file - _sessionOptions = readConfigProto(_config.ConfigProto) // default session options - cacheLimit := _config.CacheLimit - if cacheLimit == 0 { - cacheLimit = 10 // default number of models to keep in cache - } - _cache = TFCache{Models: make(map[string]TFCacheEntry), Limit: cacheLimit} - Auth = _config.Auth // set if we gonna use auth or not - VERBOSE = _config.Verbose - - // define our handlers - base := _config.Base - sdir := _config.StaticDir - if sdir == "" { - path, _ := os.Getwd() - sdir = fmt.Sprintf("%s/static", path) - } - tmplDir := fmt.Sprintf("%s/templates", sdir) - cssDir := fmt.Sprintf("%s/css", sdir) - jsDir := fmt.Sprintf("%s/js", sdir) - imgDir := fmt.Sprintf("%s/images", sdir) - _tmplDir = tmplDir - http.Handle(base+"/css/", http.StripPrefix(base+"/css/", http.FileServer(http.Dir(cssDir)))) - http.Handle(base+"/js/", http.StripPrefix(base+"/js/", http.FileServer(http.Dir(jsDir)))) - http.Handle(base+"/images/", http.StripPrefix(base+"/images/", http.FileServer(http.Dir(imgDir)))) - http.Handle(base+"/download/", http.StripPrefix(base+"/download/", http.FileServer(http.Dir(_config.ModelDir)))) - http.HandleFunc(base+"/", AuthHandler) - - // setup templates - var templates Templates - tmplData := make(map[string]interface{}) - tmplData["Base"] = _config.Base - tmplData["Content"] = fmt.Sprintf("Hello from TFaaS") - tmplData["Version"] = info() - tmplData["Models"], _ = TFModels() - _header = templates.Header(tmplDir, tmplData) - _footer = templates.Footer(tmplDir, tmplData) - - // start web server - addr := fmt.Sprintf(":%d", _config.Port) - _, e1 := os.Stat(_config.ServerCrt) - _, e2 := os.Stat(_config.ServerKey) - if e1 == nil && e2 == nil { - - if Auth == "true" { - // init userDNs and update it periodically - _userDNs = UserDNs{DNs: userDNs(), Time: time.Now()} - go func() { - for { - interval := _config.UpdateDNs - if interval == 0 { - interval = 60 - } - d := time.Duration(interval) * time.Minute - log.Println("userDNs are updated", time.Now()) - time.Sleep(d) // sleep for next iteration - _userDNs = UserDNs{DNs: userDNs(), Time: time.Now()} - } - }() - } - - server := &http.Server{ - Addr: addr, - TLSConfig: &tls.Config{ - ClientAuth: tls.RequestClientCert, - }, - } - if _, err := os.Open(_config.ServerKey); err != nil { - log.Println("unable to open server key file", _config.ServerKey, err) - } - if _, err := os.Open(_config.ServerCrt); err != nil { - log.Println("unable to open server cert file", _config.ServerCrt, err) - } - log.Println("starting HTTPs server", addr) - err = server.ListenAndServeTLS(_config.ServerCrt, _config.ServerKey) - } else { - log.Println("starting HTTP server", addr) - err = http.ListenAndServe(addr, nil) - } - if err != nil { - log.Fatal(err) - } } diff --git a/src/Go/middlewares.go b/src/Go/middlewares.go new file mode 100644 index 0000000..8615871 --- /dev/null +++ b/src/Go/middlewares.go @@ -0,0 +1,86 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + "net/url" + + limiter "github.com/ulule/limiter/v3" + stdlib "github.com/ulule/limiter/v3/drivers/middleware/stdlib" + memory "github.com/ulule/limiter/v3/drivers/store/memory" +) + +// limiter middleware pointer +var limiterMiddleware *stdlib.Middleware + +// initialize Limiter middleware pointer +func initLimiter(period string) { + log.Printf("limiter rate='%s'", period) + // create rate limiter with 5 req/second + rate, err := limiter.NewRateFromFormatted(period) + if err != nil { + panic(err) + } + store := memory.NewStore() + instance := limiter.New(store, rate) + limiterMiddleware = stdlib.NewMiddleware(instance) +} + +/* +// helper to auth/authz incoming requests to the server +func authMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // perform authentication + status := CMSAuth.CheckAuthnAuthz(r.Header) + if !status { + log.Printf("ERROR: fail to authenticate, HTTP headers %+v\n", r.Header) + w.WriteHeader(http.StatusForbidden) + return + } + if Config.Verbose > 2 { + log.Printf("Auth layer status: %v headers: %+v\n", status, r.Header) + } + // Call the next handler + next.ServeHTTP(w, r) + }) +} +*/ + +// Validate should implement input validation +func Validate(r *http.Request) error { + return nil +} + +// helper to validate incoming requests' parameters +func validateMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == "POST" { + next.ServeHTTP(w, r) + return + } + // perform validation of input parameters + err := Validate(r) + if err != nil { + uri, _ := url.QueryUnescape(r.RequestURI) + log.Printf("HTTP %s %s validation error %v\n", r.Method, uri, err) + w.WriteHeader(http.StatusBadRequest) + rec := make(map[string]string) + rec["error"] = fmt.Sprintf("Validation error %v", err) + if r, e := json.Marshal(rec); e == nil { + w.Write(r) + } + return + } + // Call the next handler + next.ServeHTTP(w, r) + }) +} + +// limit middleware limits incoming requests +func limitMiddleware(next http.Handler) http.Handler { + return limiterMiddleware.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + next.ServeHTTP(w, r) + })) +} diff --git a/src/Go/server.go b/src/Go/server.go new file mode 100644 index 0000000..7e930c4 --- /dev/null +++ b/src/Go/server.go @@ -0,0 +1,206 @@ +package main + +import ( + "crypto/tls" + "fmt" + "log" + "net/http" + "net/url" + "os" + "strings" + "time" + + "github.com/gorilla/mux" + rotatelogs "github.com/lestrrat-go/file-rotatelogs" +) + +// VERBOSE controls verbosity of the server +var VERBOSE int + +// Time0 represents initial time when we start the server +var Time0 time.Time + +// global variables +var ( + _header, _footer, _tmplDir string +) + +// Memory contains details about memory information +type Memory struct { + Total uint64 `json:"total"` + Free uint64 `json:"free"` + Used uint64 `json:"used"` + UsedPercent float64 `json:"usedPercent"` +} + +// Mem keeps memory information +type Mem struct { + Virtual Memory + Swap Memory +} + +// helper function to produce UTC time prefixed output +func utcMsg(data []byte) string { + // return fmt.Sprintf("[" + time.Now().String() + "] " + string(data)) + s := string(data) + v, e := url.QueryUnescape(s) + if e == nil { + return v + } + return s +} + +// custom rotate logger +type rotateLogWriter struct { + RotateLogs *rotatelogs.RotateLogs +} + +func (w rotateLogWriter) Write(data []byte) (int, error) { + return w.RotateLogs.Write([]byte(utcMsg(data))) +} + +func basePath(s string) string { + if _config.Base != "" { + if strings.HasPrefix(s, "/") { + s = strings.Replace(s, "/", "", 1) + } + if strings.HasPrefix(_config.Base, "/") { + return fmt.Sprintf("%s/%s", _config.Base, s) + } + return fmt.Sprintf("/%s/%s", _config.Base, s) + } + return s +} + +func handlers() *mux.Router { + router := mux.NewRouter() + + // visible routes + router.HandleFunc(basePath("/upload"), UploadHandler).Methods("POST") + router.HandleFunc(basePath("/delete"), DeleteHandler).Methods("DELETE") + router.HandleFunc(basePath("/data"), DataHandler).Methods("GET") + router.HandleFunc(basePath("/json"), PredictHandler).Methods("POST") + router.HandleFunc(basePath("/proto"), PredictProtobufHandler).Methods("POST") + router.HandleFunc(basePath("/image"), ImageHandler).Methods("POST") + router.HandleFunc(basePath("/params"), ParamsHandler).Methods("GET", "POST") + router.HandleFunc(basePath("/models"), ModelsHandler).Methods("GET") + router.HandleFunc(basePath("/status"), StatusHandler).Methods("GET") + router.HandleFunc(basePath("/netron/"), NetronHandler).Methods("GET", "POST") + router.HandleFunc(basePath("/netron/{.*}"), NetronHandler).Methods("GET", "POST") + router.HandleFunc(basePath("/"), DefaultHandler).Methods("GET") + + /* for future use + // for all requests perform first auth/authz action + router.Use(authMiddleware) + // validate all input parameters + router.Use(validateMiddleware) + + // use limiter middleware to slow down clients + router.Use(limitMiddleware) + + */ + + return router +} + +// server represents main web server +func server(config string) { + Time0 = time.Now() + + var err error + _client = httpClient() + err = parseConfig(config) + if err != nil { + log.Println("unable to parse config", err) + } + + // setup config + if _config.LogFile != "" { + logName := _config.LogFile + "-%Y%m%d" + hostname, err := os.Hostname() + if err == nil { + logName = _config.LogFile + "-" + hostname + "-%Y%m%d" + } + rl, err := rotatelogs.New(logName) + if err == nil { + rotlogs := rotateLogWriter{RotateLogs: rl} + log.SetOutput(rotlogs) + log.SetFlags(log.LstdFlags | log.Lshortfile) + } else { + log.SetFlags(log.LstdFlags | log.Lshortfile) + } + } else { + // log time, filename, and line number + log.SetFlags(log.LstdFlags | log.Lshortfile) + } + + // create session options from given config TF proto file + _sessionOptions = readConfigProto(_config.ConfigProto) // default session options + cacheLimit := _config.CacheLimit + if cacheLimit == 0 { + cacheLimit = 10 // default number of models to keep in cache + } + _cache = TFCache{Models: make(map[string]TFCacheEntry), Limit: cacheLimit} + VERBOSE = _config.Verbose + + // define our handlers + sdir := _config.StaticDir + if sdir == "" { + path, _ := os.Getwd() + sdir = fmt.Sprintf("%s/static", path) + } + _tmplDir = fmt.Sprintf("%s/templates", sdir) + + // static handlers + base := _config.Base + for _, name := range []string{"js", "css", "images", "download", "tempaltes"} { + m := fmt.Sprintf("%s/%s/", base, name) + if base == "" || base == "/" { + m = fmt.Sprintf("/%s/", name) + } + d := fmt.Sprintf("%s/%s", sdir, name) + if name == "download" { + d = _config.ModelDir + } + log.Printf("static '%s' => '%s'\n", m, http.Dir(d)) + http.Handle(m, http.StripPrefix(m, http.FileServer(http.Dir(d)))) + } + http.Handle(basePath("/"), handlers()) + + // setup templates + var templates Templates + tmplData := make(map[string]interface{}) + tmplData["Base"] = _config.Base + tmplData["Content"] = fmt.Sprintf("Hello from TFaaS") + tmplData["Version"] = info() + tmplData["Models"], _ = TFModels() + _header = templates.Header(_tmplDir, tmplData) + _footer = templates.Footer(_tmplDir, tmplData) + + // start web server + addr := fmt.Sprintf(":%d", _config.Port) + _, e1 := os.Stat(_config.ServerCrt) + _, e2 := os.Stat(_config.ServerKey) + if e1 == nil && e2 == nil { + server := &http.Server{ + Addr: addr, + TLSConfig: &tls.Config{ + ClientAuth: tls.RequestClientCert, + }, + } + if _, err := os.Open(_config.ServerKey); err != nil { + log.Println("unable to open server key file", _config.ServerKey, err) + } + if _, err := os.Open(_config.ServerCrt); err != nil { + log.Println("unable to open server cert file", _config.ServerCrt, err) + } + log.Println("starting HTTPs server", addr) + err = server.ListenAndServeTLS(_config.ServerCrt, _config.ServerKey) + } else { + log.Println("starting HTTP server", addr) + err = http.ListenAndServe(addr, nil) + } + if err != nil { + log.Fatal(err) + } +} diff --git a/src/Go/static/netron/logo.png b/src/Go/static/netron/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0699bfa49aae54b06b2aed6863333db17278152f GIT binary patch literal 96538 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 cg#VPA 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 CH0;9w literal 0 HcmV?d00001 diff --git a/src/Go/static/netron/spinner.png b/src/Go/static/netron/spinner.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac06a4a35d26afac4f93206f9d33f6e452dc100 GIT binary patch literal 17214 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 TpD9iVLp9ZO|H`_2`|tk);bX=A literal 0 HcmV?d00001 diff --git a/src/Go/static/netron/view-browser.html b/src/Go/static/netron/view-browser.html index fa7859e..f7a07a1 100644 --- a/src/Go/static/netron/view-browser.html +++ b/src/Go/static/netron/view-browser.html @@ -3,21 +3,21 @@ Netron - - - - - - - - - + + + + + + + + +
@@ -69,23 +69,23 @@

- - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/src/Go/static/netron/view-browser.html.orig b/src/Go/static/netron/view-browser.html.orig new file mode 100644 index 0000000..fa7859e --- /dev/null +++ b/src/Go/static/netron/view-browser.html.orig @@ -0,0 +1,91 @@ + + + +Netron + + + + + + + + + + + + +
+ + + + +
.
+
.
+
.
+
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Go/static/netron/view-electron.html.orig b/src/Go/static/netron/view-electron.html.orig new file mode 100644 index 0000000..b5f8cb2 --- /dev/null +++ b/src/Go/static/netron/view-electron.html.orig @@ -0,0 +1,83 @@ + + + + + + + + + +
+ + + +
.
+
.
+
.
+
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Go/utils.go b/src/Go/utils.go index f05fe6f..e8c74da 100644 --- a/src/Go/utils.go +++ b/src/Go/utils.go @@ -50,9 +50,6 @@ func tlsCerts() ([]tls.Certificate, error) { } } if uproxy == "" && uckey == "" { // user doesn't have neither proxy or user certs - if Auth == "true" { - log.Fatal("Neither proxy or user certs are found, use X509_USER_PROXY/X509_USER_KEY/X509_USER_CERT to set them up or run with -auth false") - } return nil, nil } if uproxy != "" {