2020-06-29 21:13:52 +02:00
|
|
|
package http3
|
2020-03-19 05:30:21 +01:00
|
|
|
|
|
|
|
import (
|
2020-06-29 21:13:52 +02:00
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
|
|
|
"net/http"
|
2020-03-19 05:30:21 +01:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/lbryio/lbry.go/v2/extras/errors"
|
|
|
|
"github.com/lbryio/lbry.go/v2/stream"
|
2020-06-29 21:13:52 +02:00
|
|
|
"github.com/lucas-clemente/quic-go"
|
|
|
|
"github.com/lucas-clemente/quic-go/http3"
|
2020-03-19 05:30:21 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Store is a blob store that gets blobs from a peer.
|
|
|
|
// It satisfies the store.BlobStore interface but cannot put or delete blobs.
|
|
|
|
type Store struct {
|
2020-05-13 21:53:57 +02:00
|
|
|
opts StoreOpts
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// StoreOpts allows to set options for a new Store.
|
|
|
|
type StoreOpts struct {
|
|
|
|
Address string
|
|
|
|
Timeout time.Duration
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewStore makes a new peer store.
|
|
|
|
func NewStore(opts StoreOpts) *Store {
|
2020-05-13 21:53:57 +02:00
|
|
|
return &Store{opts: opts}
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
|
|
|
|
2020-05-13 21:53:57 +02:00
|
|
|
func (p *Store) getClient() (*Client, error) {
|
2020-06-29 21:13:52 +02:00
|
|
|
var qconf quic.Config
|
2020-10-15 02:59:12 +02:00
|
|
|
qconf.HandshakeTimeout = 4 * time.Second
|
2020-07-10 15:19:57 +02:00
|
|
|
qconf.MaxIdleTimeout = 5 * time.Second
|
2020-06-29 21:13:52 +02:00
|
|
|
pool, err := x509.SystemCertPool()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
roundTripper := &http3.RoundTripper{
|
|
|
|
TLSClientConfig: &tls.Config{
|
|
|
|
RootCAs: pool,
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
},
|
|
|
|
QuicConfig: &qconf,
|
|
|
|
}
|
2020-06-30 01:14:52 +02:00
|
|
|
connection := &http.Client{
|
2020-06-29 21:13:52 +02:00
|
|
|
Transport: roundTripper,
|
|
|
|
}
|
|
|
|
c := &Client{
|
2020-06-30 01:14:52 +02:00
|
|
|
conn: connection,
|
2020-06-29 21:13:52 +02:00
|
|
|
roundTripper: roundTripper,
|
|
|
|
ServerAddr: p.opts.Address,
|
|
|
|
}
|
2020-05-13 21:53:57 +02:00
|
|
|
return c, errors.Prefix("connection error", err)
|
2020-03-22 04:37:01 +01:00
|
|
|
}
|
|
|
|
|
2020-03-19 05:30:21 +01:00
|
|
|
// Has asks the peer if they have a hash
|
|
|
|
func (p *Store) Has(hash string) (bool, error) {
|
2020-05-13 21:53:57 +02:00
|
|
|
c, err := p.getClient()
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
2020-05-13 21:53:57 +02:00
|
|
|
defer c.Close()
|
|
|
|
return c.HasBlob(hash)
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get downloads the blob from the peer
|
|
|
|
func (p *Store) Get(hash string) (stream.Blob, error) {
|
2020-05-13 21:53:57 +02:00
|
|
|
c, err := p.getClient()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
2020-05-13 21:53:57 +02:00
|
|
|
defer c.Close()
|
|
|
|
return c.GetBlob(hash)
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Put is not supported
|
|
|
|
func (p *Store) Put(hash string, blob stream.Blob) error {
|
2020-06-30 01:14:52 +02:00
|
|
|
panic("http3Store cannot put or delete blobs")
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// PutSD is not supported
|
|
|
|
func (p *Store) PutSD(hash string, blob stream.Blob) error {
|
2020-06-30 01:14:52 +02:00
|
|
|
panic("http3Store cannot put or delete blobs")
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete is not supported
|
|
|
|
func (p *Store) Delete(hash string) error {
|
2020-06-30 01:14:52 +02:00
|
|
|
panic("http3Store cannot put or delete blobs")
|
2020-03-19 05:30:21 +01:00
|
|
|
}
|