Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Aug 7, 2023
1 parent 28e1fa6 commit 12adc51
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 10 deletions.
2 changes: 1 addition & 1 deletion routing/http/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (c *client) GetProviders(ctx context.Context, key cid.Cid) (provs iter.Resu
it = iter.ToResultIter(sliceIt)
case mediaTypeNDJSON:
skipBodyClose = true
it = ndjson.NewProvidersResponseIter(resp.Body)
it = ndjson.NewRecordsIter(resp.Body)
default:
logger.Errorw("unknown media type", "MediaType", mediaType, "ContentType", respContentType)
return nil, errors.New("unknown content type")
Expand Down
5 changes: 5 additions & 0 deletions routing/http/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func (m *mockContentRouter) GetProviders(ctx context.Context, key cid.Cid, limit
return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1)
}

func (m *mockContentRouter) GetPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) {
args := m.Called(ctx, pid, limit)
return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1)
}

func (m *mockContentRouter) GetIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) {
args := m.Called(ctx, name)
return args.Get(0).(*ipns.Record), args.Error(1)
Expand Down
29 changes: 29 additions & 0 deletions routing/http/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/ipfs/boxo/routing/http/types/iter"
jsontypes "github.com/ipfs/boxo/routing/http/types/json"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p/core/peer"

logging "github.com/ipfs/go-log/v2"
)
Expand All @@ -37,6 +38,7 @@ var logger = logging.Logger("service/server/delegatedrouting")

const (
GetProvidersPath = "/routing/v1/providers/{cid}"
GetPeersPath = "/routing/v1/peers/{peer-id}"
GetIPNSRecordPath = "/routing/v1/ipns/{cid}"
)

Expand All @@ -50,6 +52,10 @@ type ContentRouter interface {
// Limit indicates the maximum amount of results to return; 0 means unbounded.
GetProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error)

// GetPeers searches for peers who have the provided [peer.ID].
// Limit indicates the maximum amount of results to return; 0 means unbounded.
GetPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error)

// GetIPNSRecord searches for an [ipns.Record] for the given [ipns.Name].
GetIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error)

Expand Down Expand Up @@ -96,8 +102,10 @@ func Handler(svc ContentRouter, opts ...Option) http.Handler {

r := mux.NewRouter()
r.HandleFunc(GetProvidersPath, server.getProviders).Methods(http.MethodGet)
r.HandleFunc(GetPeersPath, server.getPeers).Methods(http.MethodGet)
r.HandleFunc(GetIPNSRecordPath, server.getIPNSRecord).Methods(http.MethodGet)
r.HandleFunc(GetIPNSRecordPath, server.putIPNSRecord).Methods(http.MethodPut)

return r
}

Expand Down Expand Up @@ -222,6 +230,27 @@ func (s *server) getProvidersNDJSON(w http.ResponseWriter, provIter iter.ResultI
}
}

func (s *server) getPeers(w http.ResponseWriter, r *http.Request) {
pidStr := mux.Vars(r)["peer-id"]

// pidStr must be in CIDv1 format. Therefore, use [cid.Decode]. We can't use
// [peer.Decode] because that would allow other formats to pass through.
cid, err := cid.Decode(pidStr)
if err != nil {
writeErr(w, "GetPeers", http.StatusBadRequest, fmt.Errorf("unable to parse peer ID: %w", err))
return
}

Check warning on line 242 in routing/http/server/server.go

View check run for this annotation

Codecov / codecov/patch

routing/http/server/server.go#L233-L242

Added lines #L233 - L242 were not covered by tests

pid, err := peer.FromCid(cid)
if err != nil {
writeErr(w, "GetPeers", http.StatusBadRequest, fmt.Errorf("unable to parse peer ID: %w", err))
return
}

Check warning on line 248 in routing/http/server/server.go

View check run for this annotation

Codecov / codecov/patch

routing/http/server/server.go#L244-L248

Added lines #L244 - L248 were not covered by tests

// TODO
_ = pid

Check warning on line 251 in routing/http/server/server.go

View check run for this annotation

Codecov / codecov/patch

routing/http/server/server.go#L251

Added line #L251 was not covered by tests
}

func (s *server) getIPNSRecord(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Header.Get("Accept"), mediaTypeIPNSRecord) {
writeErr(w, "GetIPNSRecord", http.StatusNotAcceptable, errors.New("content type in 'Accept' header is missing or not supported"))
Expand Down
5 changes: 5 additions & 0 deletions routing/http/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ func (m *mockContentRouter) GetProviders(ctx context.Context, key cid.Cid, limit
return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1)
}

func (m *mockContentRouter) GetPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[types.Record], error) {
args := m.Called(ctx, pid, limit)
return args.Get(0).(iter.ResultIter[types.Record]), args.Error(1)
}

func (m *mockContentRouter) GetIPNSRecord(ctx context.Context, name ipns.Name) (*ipns.Record, error) {
args := m.Called(ctx, name)
return args.Get(0).(*ipns.Record), args.Error(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,25 @@ import (

// ProvidersResponse is the result of a GET Providers request.
type ProvidersResponse struct {
Providers []types.Record
Providers RecordsArray
}

func (r *ProvidersResponse) UnmarshalJSON(b []byte) error {
var tempFPR struct{ Providers []json.RawMessage }
err := json.Unmarshal(b, &tempFPR)
// PeersResponse is the result of a GET Peers request.
type PeersResponse struct {
Peers RecordsArray
}

// RecordsArray is an array of [types.Record]
type RecordsArray []types.Record

func (r *RecordsArray) UnmarshalJSON(b []byte) error {
var tempRecords []json.RawMessage
err := json.Unmarshal(b, &tempRecords)
if err != nil {
return err
}

Check warning on line 27 in routing/http/types/json/responses.go

View check run for this annotation

Codecov / codecov/patch

routing/http/types/json/responses.go#L26-L27

Added lines #L26 - L27 were not covered by tests

for _, provBytes := range tempFPR.Providers {
for _, provBytes := range tempRecords {
var readProv types.UnknownRecord
err := json.Unmarshal(provBytes, &readProv)
if err != nil {
Expand All @@ -32,9 +40,9 @@ func (r *ProvidersResponse) UnmarshalJSON(b []byte) error {
if err != nil {
return err
}

Check warning on line 42 in routing/http/types/json/responses.go

View check run for this annotation

Codecov / codecov/patch

routing/http/types/json/responses.go#L41-L42

Added lines #L41 - L42 were not covered by tests
r.Providers = append(r.Providers, &prov)
*r = append(*r, &prov)
default:
r.Providers = append(r.Providers, &readProv)
*r = append(*r, &readProv)

Check warning on line 45 in routing/http/types/json/responses.go

View check run for this annotation

Codecov / codecov/patch

routing/http/types/json/responses.go#L44-L45

Added lines #L44 - L45 were not covered by tests
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/ipfs/boxo/routing/http/types/iter"
)

// NewProvidersResponseIter returns an iterator that reads [types.Record] from the given [io.Reader].
func NewProvidersResponseIter(r io.Reader) iter.Iter[iter.Result[types.Record]] {
// NewRecordsIter returns an iterator that reads [types.Record] from the given [io.Reader].
func NewRecordsIter(r io.Reader) iter.Iter[iter.Result[types.Record]] {
jsonIter := iter.FromReaderJSON[types.UnknownRecord](r)
mapFn := func(upr iter.Result[types.UnknownRecord]) iter.Result[types.Record] {
var result iter.Result[types.Record]
Expand Down

0 comments on commit 12adc51

Please sign in to comment.