diff --git a/dhstore.go b/dhstore.go index 27f9efa..46b8806 100644 --- a/dhstore.go +++ b/dhstore.go @@ -24,8 +24,6 @@ type ( } ) -type ( - EncryptedValueKeyResult struct { - EncryptedValueKey EncryptedValueKey `json:"EncryptedValueKey"` - } -) +type EncryptedValueKeyResult struct { + EncryptedValueKey EncryptedValueKey `json:"EncryptedValueKey"` +} diff --git a/go.mod b/go.mod index 1abea8f..3d4dc8c 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,10 @@ require ( github.com/cockroachdb/pebble v0.0.0-20220726144858-a78491c0086f github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-log/v2 v2.5.1 - github.com/ipni/go-libipni v0.4.0 - github.com/libp2p/go-libp2p v0.29.2 + github.com/ipni/go-libipni v0.5.0 + github.com/libp2p/go-libp2p v0.31.0 github.com/mr-tron/base58 v1.2.0 - github.com/multiformats/go-multiaddr v0.10.1 + github.com/multiformats/go-multiaddr v0.11.0 github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 github.com/multiformats/go-varint v0.0.7 @@ -43,7 +43,7 @@ require ( github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.2.1 // indirect - github.com/kr/text v0.1.0 // indirect + github.com/kr/text v0.2.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -59,12 +59,11 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect go.opentelemetry.io/otel/sdk v1.11.1 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect - go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect - golang.org/x/sys v0.10.0 // indirect + go.uber.org/zap v1.25.0 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/sys v0.11.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 58d358e..3f4d71d 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -123,9 +124,9 @@ github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipni/go-libipni v0.4.0 h1:zZ8OU2N0D4iYt0E9jInbDapeh9bG10b5sBgqvScflNw= -github.com/ipni/go-libipni v0.4.0/go.mod h1:LxH6NUmEVruK3FjV2bFWfXKougX7AIe7wVjvPqITrDI= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= +github.com/ipni/go-libipni v0.5.0 h1:UTVq4U9cReNz/rbeVeUvl+JTLexdfb7yjmBgouSteJ8= +github.com/ipni/go-libipni v0.5.0/go.mod h1:UnrhEqjVI2Z2HXlaieOBONJmtW557nZkYpB4IIsMD+s= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= @@ -155,14 +156,15 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-libp2p v0.29.2 h1:uPw/c8hOxoLP/KhFnzlc5Ejqf+OmAL1dwIsqE31WBtY= -github.com/libp2p/go-libp2p v0.29.2/go.mod h1:OU7nSq0aEZMsV2wY8nXn1+XNNt9q2UiR8LjW3Kmp2UE= +github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= +github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -190,8 +192,8 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.10.1 h1:HghtFrWyZEPrpTvgAMFJi6gFdgHfs2cb0pyfDsk+lqU= -github.com/multiformats/go-multiaddr v0.10.1/go.mod h1:jLEZsA61rwWNZQTHHnqq2HNa+4os/Hz54eqiRnsRqYQ= +github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= +github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= @@ -281,28 +283,26 @@ go.opentelemetry.io/otel/sdk/metric v0.33.0/go.mod h1:xdypMeA21JBOvjjzDUtD0kzIcH go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -363,8 +363,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= diff --git a/pebble/pebble.go b/pebble/pebble.go index 1578792..5023b04 100644 --- a/pebble/pebble.go +++ b/pebble/pebble.go @@ -5,17 +5,12 @@ import ( "io" "github.com/cockroachdb/pebble" - logging "github.com/ipfs/go-log/v2" "github.com/ipni/dhstore" "github.com/multiformats/go-multicodec" "github.com/multiformats/go-multihash" ) -var ( - logger = logging.Logger("store/pebble") - - _ dhstore.DHStore = (*PebbleDHStore)(nil) -) +var _ dhstore.DHStore = (*PebbleDHStore)(nil) const ( encValueKeysCap = 5 @@ -115,7 +110,6 @@ func (s *PebbleDHStore) Lookup(mh multihash.Multihash) ([]dhstore.EncryptedValue if errors.Is(err, pebble.ErrNotFound) { return nil, nil } - logger.Debugw("failed to find multihash", "key", mh.B58String(), "err", err) return nil, err } defer vkbClose.Close() diff --git a/server/server.go b/server/server.go index feb1cb9..bf88484 100644 --- a/server/server.go +++ b/server/server.go @@ -8,7 +8,6 @@ import ( "net" "net/http" "path" - "strings" "time" logging "github.com/ipfs/go-log/v2" @@ -75,9 +74,12 @@ func New(dhs dhstore.DHStore, addr string, options ...Option) (*Server, error) { }, } - mux.HandleFunc("/cid/", s.handleMhOrCidSubtree) + mux.HandleFunc("/cid/", s.handleNoEncMhOrCidSubtree) + mux.HandleFunc("/encrypted/cid/", s.handleEncMhOrCidSubtree) mux.HandleFunc("/multihash", s.handleMh) - mux.HandleFunc("/multihash/", s.handleMhOrCidSubtree) + mux.HandleFunc("/encrypted/multihash", s.handleMh) + mux.HandleFunc("/multihash/", s.handleNoEncMhOrCidSubtree) + mux.HandleFunc("/encrypted/multihash/", s.handleEncMhOrCidSubtree) mux.HandleFunc("/metadata", s.handleMetadata) mux.HandleFunc("/metadata/", s.handleMetadataSubtree) mux.HandleFunc("/ready", s.handleReady) @@ -132,7 +134,15 @@ func (s *Server) handleMh(w http.ResponseWriter, r *http.Request) { } } -func (s *Server) handleMhOrCidSubtree(w http.ResponseWriter, r *http.Request) { +func (s *Server) handleEncMhOrCidSubtree(w http.ResponseWriter, r *http.Request) { + s.handleMhOrCidSubtree(w, r, true) +} + +func (s *Server) handleNoEncMhOrCidSubtree(w http.ResponseWriter, r *http.Request) { + s.handleMhOrCidSubtree(w, r, false) +} + +func (s *Server) handleMhOrCidSubtree(w http.ResponseWriter, r *http.Request, encrypted bool) { if r.Method != http.MethodGet { w.Header().Set("Allow", http.MethodGet) http.Error(w, "", http.StatusMethodNotAllowed) @@ -146,27 +156,60 @@ func (s *Server) handleMhOrCidSubtree(w http.ResponseWriter, r *http.Request) { return } - if rspWriter.MultihashCode() == multihash.DBL_SHA2_256 { - s.lookupMh(newEncResponseWriter(rspWriter), r) + if encrypted { + s.lookupMh(newEncResponseWriter(rspWriter), r, true) + return + } + // If multihash is DBL_SHA2_256, then this is probably an encrypted lookup, + // so try that first. If no results found, then do a non-encrypted lookup. + // It is possible for a non-encrypted multihash to be DBL_SHA2_256. + if rspWriter.MultihashCode() == multihash.DBL_SHA2_256 && s.lookupMh(newEncResponseWriter(rspWriter), r, s.dhfind == nil) { return } + // Do non-encrypted lookup. All encrypted multihashes are DBL_SHA2_256, so + // there is no need to do an encrypted lookup for a non-DBL_SHA2_256 + // multihash. s.dhfindMh(rwriter.NewProviderResponseWriter(rspWriter), r) } -func (s *Server) lookupMh(w *encResponseWriter, r *http.Request) { +func (s *Server) lookupMh(w *encResponseWriter, r *http.Request, writeIfNotFound bool) bool { + var start time.Time if s.metrics != nil { - start := time.Now() + start = time.Now() defer func() { + if start.IsZero() { + return // metrics skipped + } s.metrics.RecordHttpLatency(context.Background(), time.Since(start), r.Method, w.PathType(), w.StatusCode()) }() } - s.handleGetMh(w, r) + evks, err := s.dhs.Lookup(w.Multihash()) + if err != nil { + s.handleError(w, err) + return true + } + if evks == nil && !writeIfNotFound { + start = time.Time{} // skip mettics + return false + } + for _, evk := range evks { + if err = w.writeEncryptedValueKey(evk); err != nil { + log.Errorw("Failed to encode encrypted value key", "err", err) + http.Error(w, "", http.StatusInternalServerError) + return true + } + } + if err = w.close(); err != nil { + log.Errorw("Failed to finalize lookup results", "err", err) + writeError(w, err) + } + return true } func (s *Server) dhfindMh(w *rwriter.ProviderResponseWriter, r *http.Request) { if s.dhfind == nil { - http.Error(w, "multihash must be of code dbl-sha2-256 when dhfind not enabled", http.StatusBadRequest) + http.Error(w, "unencrypted lookup not available when dhfind not enabled", http.StatusBadRequest) return } @@ -218,7 +261,7 @@ func (s *Server) dhfindMh(w *rwriter.ProviderResponseWriter, r *http.Request) { // If there were no results - return 404, otherwise finalize the response // and return 200. if !haveResults { - http.Error(w, "", http.StatusNotFound) + http.Error(w, "not found by unencrypted lookup", http.StatusNotFound) return } @@ -263,25 +306,6 @@ func (s *Server) FindMetadata(ctx context.Context, hvk []byte) ([]byte, error) { return s.dhs.GetMetadata(dhstore.HashedValueKey(hvk)) } -func (s *Server) handleGetMh(w *encResponseWriter, r *http.Request) { - evks, err := s.dhs.Lookup(w.Multihash()) - if err != nil { - s.handleError(w, err) - return - } - for _, evk := range evks { - if err = w.writeEncryptedValueKey(evk); err != nil { - log.Errorw("Failed to encode encrypted value key", "err", err) - http.Error(w, "", http.StatusInternalServerError) - return - } - } - if err = w.close(); err != nil { - log.Errorw("Failed to finalize lookup results", "err", err) - writeError(w, err) - } -} - func (s *Server) handlePutMhs(w http.ResponseWriter, r *http.Request) { var mir MergeIndexRequest err := json.NewDecoder(r.Body).Decode(&mir) @@ -370,7 +394,7 @@ func (s *Server) handleMetadataSubtree(w http.ResponseWriter, r *http.Request) { } func (s *Server) handleGetMetadata(w http.ResponseWriter, r *http.Request) { - sk := strings.TrimPrefix(path.Base(r.URL.Path), "metadata/") + sk := path.Base(r.URL.Path) hvk, err := base58.Decode(sk) if err != nil { http.Error(w, fmt.Sprintf("cannot decode key %s as bas58: %s", sk, err.Error()), http.StatusBadRequest) @@ -394,7 +418,7 @@ func (s *Server) handleGetMetadata(w http.ResponseWriter, r *http.Request) { } func (s *Server) handleDeleteMetadata(w http.ResponseWriter, r *http.Request) { - sk := strings.TrimPrefix(path.Base(r.URL.Path), "metadata/") + sk := path.Base(r.URL.Path) b, err := base58.Decode(sk) if err != nil { http.Error(w, fmt.Sprintf("cannot decode key %s as bas58: %s", sk, err.Error()), http.StatusBadRequest) diff --git a/server/server_test.go b/server/server_test.go index aefae74..da6f6b7 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -43,6 +43,12 @@ func TestNewServeMux(t *testing.T) { onTarget: "/multihash", expectStatus: http.StatusMethodNotAllowed, }, + { + name: "GET /encrypted/multihash is 405", + onMethod: http.MethodGet, + onTarget: "/multihash", + expectStatus: http.StatusMethodNotAllowed, + }, { name: "PUT /multihash with no body is 400", onMethod: http.MethodPut, @@ -64,6 +70,14 @@ func TestNewServeMux(t *testing.T) { expectStatus: http.StatusBadRequest, expectBody: "at least one merge must be specified", }, + { + name: "PUT /multihash with no merges is 400", + onMethod: http.MethodPut, + onTarget: "/multihash", + onBody: "{}", + expectStatus: http.StatusBadRequest, + expectBody: "at least one merge must be specified", + }, { name: "PUT /multihash with invalid multihash is 400", onMethod: http.MethodPut, @@ -121,11 +135,11 @@ func TestNewServeMux(t *testing.T) { expectBody: "input isn't valid multihash", }, { - name: "GET /multihash/subtree with valid non-dbl-sha2-256 multihash is 400", + name: "GET /multihash/subtree with valid non-dbl-sha2-256 multihash an no dhfind is 400", onMethod: http.MethodGet, onTarget: "/multihash/QmcgwdNjFQVhKt6aWWtSPgdLbNvULRoFMU6CCYwHsN3EEH", expectStatus: http.StatusBadRequest, - expectBody: "multihash must be of code dbl-sha2-256 when dhfind not enabled", + expectBody: "unencrypted lookup not available when dhfind not enabled", }, { name: "GET /multihash/subtree with valid non-dbl-sha2-256 multihash and dhfind is 404", @@ -135,13 +149,26 @@ func TestNewServeMux(t *testing.T) { dhfind: true, }, { - name: "GET /multihash/subtree with valid absent dbl-sha2-256 multihash is 404", + name: "GET /encrypted/multihash/subtree with valid absent dbl-sha2-256 multihash is 404", onMethod: http.MethodGet, - onTarget: "/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", + onTarget: "/encrypted/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", expectStatus: http.StatusNotFound, }, { - name: "GET /multihash/subtree with valid present dbl-sha2-256 multihash is 200", + name: "GET /encrypted/multihash/subtree with valid present dbl-sha2-256 multihash is 200", + onStore: func(t *testing.T, store dhstore.DHStore) { + mh, err := multihash.FromB58String("2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82") + require.NoError(t, err) + require.NoError(t, store.MergeIndexes([]dhstore.Index{{Key: mh, Value: []byte("fish")}})) + }, + onMethod: http.MethodGet, + onTarget: "/encrypted/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", + expectStatus: http.StatusOK, + expectBody: `{"EncryptedMultihashResults": [{ "Multihash": "ViAJKqT0hRtxENbtjWwvnRogQknxUnhswNrose3ZjEP8Iw==", "EncryptedValueKeys": ["ZmlzaA=="] }]}`, + expectJSON: true, + }, + { // Probably incrypted - it is encrypted + name: "GET /multihash/subtree with valid present dbl-sha2-256 multihash encrypted lookup is 200", onStore: func(t *testing.T, store dhstore.DHStore) { mh, err := multihash.FromB58String("2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82") require.NoError(t, err) @@ -153,6 +180,14 @@ func TestNewServeMux(t *testing.T) { expectBody: `{"EncryptedMultihashResults": [{ "Multihash": "ViAJKqT0hRtxENbtjWwvnRogQknxUnhswNrose3ZjEP8Iw==", "EncryptedValueKeys": ["ZmlzaA=="] }]}`, expectJSON: true, }, + { // Probably incrypted - it is not encrypted + name: "GET /multihash/subtree with valid absent dbl-sha2-256 multihash unencrypted lookup is 404", + onMethod: http.MethodGet, + onTarget: "/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", + expectStatus: http.StatusNotFound, + expectBody: `not found by unencrypted lookup`, + dhfind: true, + }, { name: "streaming GET /multihash/subtree with bad length is 400", onAcceptHeader: "application/x-ndjson", @@ -169,6 +204,22 @@ func TestNewServeMux(t *testing.T) { expectStatus: http.StatusBadRequest, expectBody: "varint not minimally encoded", }, + { + name: "streaming GET /encrypted/multihash/subtree with bad length is 400", + onAcceptHeader: "application/x-ndjson", + onMethod: http.MethodGet, + onTarget: "/encrypted/multihash/asda", + expectStatus: http.StatusBadRequest, + expectBody: "length greater than remaining number of bytes in buffer", + }, + { + name: "streaming GET /encrypted/multihash/subtree with invalid varint is 400", + onAcceptHeader: "application/x-ndjson", + onMethod: http.MethodGet, + onTarget: "/encrypted/multihash/Quickfish", + expectStatus: http.StatusBadRequest, + expectBody: "varint not minimally encoded", + }, { name: "streaming GET /multihash/subtree with invalid multihash is 400", onAcceptHeader: "application/x-ndjson", @@ -177,13 +228,21 @@ func TestNewServeMux(t *testing.T) { expectStatus: http.StatusBadRequest, expectBody: "input isn't valid multihash", }, + { + name: "streaming GET /encrypted/multihash/subtree with invalid multihash is 400", + onAcceptHeader: "application/x-ndjson", + onMethod: http.MethodGet, + onTarget: "/encrypted/multihash/Qmackerel", + expectStatus: http.StatusBadRequest, + expectBody: "input isn't valid multihash", + }, { name: "streaming GET /multihash/subtree with valid non-dbl-sha2-256 multihash is 400", onAcceptHeader: "application/x-ndjson", onMethod: http.MethodGet, onTarget: "/multihash/QmcgwdNjFQVhKt6aWWtSPgdLbNvULRoFMU6CCYwHsN3EEH", expectStatus: http.StatusBadRequest, - expectBody: "multihash must be of code dbl-sha2-256 when dhfind not enabled", + expectBody: "unencrypted lookup not available when dhfind not enabled", }, { name: "streaming GET /multihash/subtree with valid non-dbl-sha2-256 multihash and dhfind is 404", @@ -194,14 +253,14 @@ func TestNewServeMux(t *testing.T) { dhfind: true, }, { - name: "streaming GET /multihash/subtree with valid absent dbl-sha2-256 multihash is 404", + name: "streaming GET /encrypted/multihash/subtree with valid absent dbl-sha2-256 multihash is 404", onAcceptHeader: "application/x-ndjson", onMethod: http.MethodGet, - onTarget: "/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", + onTarget: "/encrypted/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", expectStatus: http.StatusNotFound, }, { - name: "streaming GET /multihash/subtree with valid present dbl-sha2-256 multihash is 200", + name: "streaming GET /encrypted/multihash/subtree with valid present dbl-sha2-256 multihash is 200", onAcceptHeader: "application/x-ndjson", onStore: func(t *testing.T, store dhstore.DHStore) { mh, err := multihash.FromB58String("2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82") @@ -213,7 +272,7 @@ func TestNewServeMux(t *testing.T) { })) }, onMethod: http.MethodGet, - onTarget: "/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", + onTarget: "/encrypted/multihash/2wvdp9y1J63yDvaPawP4kUjXezRLcu9x9u2DAB154dwai82", expectStatus: http.StatusOK, expectBody: `{"EncryptedValueKey":"ZmlzaA=="} {"EncryptedValueKey":"bG9ic3Rlcg=="}