github.com/cs3org/reva/v2@v2.27.7/internal/http/services/dataprovider/dataprovider.go (about) 1 // Copyright 2018-2021 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package dataprovider 20 21 import ( 22 "fmt" 23 "net/http" 24 25 "github.com/mitchellh/mapstructure" 26 "github.com/rs/zerolog" 27 28 "github.com/cs3org/reva/v2/pkg/appctx" 29 "github.com/cs3org/reva/v2/pkg/events" 30 "github.com/cs3org/reva/v2/pkg/events/stream" 31 datatxregistry "github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/registry" 32 "github.com/cs3org/reva/v2/pkg/rhttp/global" 33 "github.com/cs3org/reva/v2/pkg/rhttp/router" 34 "github.com/cs3org/reva/v2/pkg/storage" 35 "github.com/cs3org/reva/v2/pkg/storage/fs/registry" 36 ) 37 38 func init() { 39 global.Register("dataprovider", New) 40 } 41 42 type config struct { 43 Prefix string `mapstructure:"prefix" docs:"data;The prefix to be used for this HTTP service"` 44 Driver string `mapstructure:"driver" docs:"localhome;The storage driver to be used."` 45 Drivers map[string]map[string]interface{} `mapstructure:"drivers" docs:"url:pkg/storage/fs/localhome/localhome.go;The configuration for the storage driver"` 46 DataTXs map[string]map[string]interface{} `mapstructure:"data_txs" docs:"url:pkg/rhttp/datatx/manager/simple/simple.go;The configuration for the data tx protocols"` 47 NatsAddress string `mapstructure:"nats_address"` 48 NatsClusterID string `mapstructure:"nats_clusterID"` 49 NatsTLSInsecure bool `mapstructure:"nats_tls_insecure"` 50 NatsRootCACertPath string `mapstructure:"nats_root_ca_cert_path"` 51 NatsEnableTLS bool `mapstructure:"nats_enable_tls"` 52 NatsUsername string `mapstructure:"nats_username"` 53 NatsPassword string `mapstructure:"nats_password"` 54 } 55 56 func (c *config) init() { 57 if c.Prefix == "" { 58 c.Prefix = "data" 59 } 60 if c.Driver == "" { 61 c.Driver = "localhome" 62 } 63 } 64 65 type svc struct { 66 conf *config 67 handler http.Handler 68 storage storage.FS 69 dataTXs map[string]http.Handler 70 } 71 72 // New returns a new datasvc 73 func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) { 74 conf := &config{} 75 if err := mapstructure.Decode(m, conf); err != nil { 76 return nil, err 77 } 78 79 conf.init() 80 81 var evstream events.Stream 82 83 if conf.NatsAddress == "" || conf.NatsClusterID == "" { 84 log.Warn().Msg("missing or incomplete nats configuration. Events will not be published.") 85 } else { 86 s, err := stream.NatsFromConfig("dataprovider", false, stream.NatsConfig{ 87 Endpoint: conf.NatsAddress, 88 Cluster: conf.NatsClusterID, 89 EnableTLS: conf.NatsEnableTLS, 90 TLSInsecure: conf.NatsTLSInsecure, 91 TLSRootCACertificate: conf.NatsRootCACertPath, 92 AuthUsername: conf.NatsUsername, 93 AuthPassword: conf.NatsPassword, 94 }) 95 if err != nil { 96 return nil, err 97 } 98 99 evstream = s 100 } 101 102 fs, err := getFS(conf, evstream, log) 103 if err != nil { 104 return nil, err 105 } 106 107 dataTXs, err := getDataTXs(conf, fs, evstream, log) 108 if err != nil { 109 return nil, err 110 } 111 112 s := &svc{ 113 storage: fs, 114 conf: conf, 115 dataTXs: dataTXs, 116 } 117 118 err = s.setHandler() 119 return s, err 120 } 121 122 func getFS(c *config, stream events.Stream, log *zerolog.Logger) (storage.FS, error) { 123 if f, ok := registry.NewFuncs[c.Driver]; ok { 124 return f(c.Drivers[c.Driver], stream, log) 125 } 126 return nil, fmt.Errorf("driver not found: %s", c.Driver) 127 } 128 129 func getDataTXs(c *config, fs storage.FS, publisher events.Publisher, log *zerolog.Logger) (map[string]http.Handler, error) { 130 if c.DataTXs == nil { 131 c.DataTXs = make(map[string]map[string]interface{}) 132 } 133 if len(c.DataTXs) == 0 { 134 c.DataTXs["simple"] = make(map[string]interface{}) 135 c.DataTXs["simple"]["cache_store"] = "noop" 136 c.DataTXs["simple"]["cache_database"] = "reva" 137 c.DataTXs["spaces"] = make(map[string]interface{}) 138 c.DataTXs["spaces"]["cache_store"] = "noop" 139 c.DataTXs["spaces"]["cache_database"] = "reva" 140 c.DataTXs["tus"] = make(map[string]interface{}) 141 c.DataTXs["tus"]["cache_store"] = "noop" 142 c.DataTXs["tus"]["cache_database"] = "reva" 143 } 144 145 txs := make(map[string]http.Handler) 146 for t := range c.DataTXs { 147 if f, ok := datatxregistry.NewFuncs[t]; ok { 148 if tx, err := f(c.DataTXs[t], publisher, log); err == nil { 149 if handler, err := tx.Handler(fs); err == nil { 150 txs[t] = handler 151 } 152 } 153 } 154 } 155 return txs, nil 156 } 157 158 func (s *svc) Close() error { 159 return nil 160 } 161 162 func (s *svc) Unprotected() []string { 163 return []string{ 164 "/tus", 165 } 166 } 167 168 func (s *svc) Prefix() string { 169 return s.conf.Prefix 170 } 171 172 func (s *svc) Handler() http.Handler { 173 return s.handler 174 } 175 176 func (s *svc) setHandler() error { 177 178 s.handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 179 log := appctx.GetLogger(r.Context()) 180 log.Debug().Msgf("dataprovider routing: path=%s", r.URL.Path) 181 182 head, tail := router.ShiftPath(r.URL.Path) 183 184 if handler, ok := s.dataTXs[head]; ok { 185 r.URL.Path = tail 186 handler.ServeHTTP(w, r) 187 return 188 } 189 190 // If we don't find a prefix match for any of the protocols, upload the resource 191 // through the direct HTTP protocol 192 if handler, ok := s.dataTXs["simple"]; ok { 193 handler.ServeHTTP(w, r) 194 return 195 } 196 197 w.WriteHeader(http.StatusInternalServerError) 198 }) 199 200 return nil 201 }