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 0000000..0699bfa Binary files /dev/null and b/src/Go/static/netron/logo.png differ diff --git a/src/Go/static/netron/spinner.png b/src/Go/static/netron/spinner.png new file mode 100644 index 0000000..0ac06a4 Binary files /dev/null and b/src/Go/static/netron/spinner.png differ 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 != "" {