feat: implement /s5/debug/storage_locations/:hash
This commit is contained in:
parent
0c88e80a66
commit
510a57162c
|
@ -49,7 +49,8 @@ func getRoutes(h *s5.HttpHandler, portal interfaces.Portal) map[string]jape.Hand
|
|||
"DELETE /s5/delete/:cid": s5.AuthMiddleware(h.AccountPinDelete, portal),
|
||||
|
||||
// Debug API
|
||||
"GET /s5/debug/download_urls/:cid": s5.AuthMiddleware(h.DebugDownloadUrls, portal),
|
||||
"GET /s5/debug/download_urls/:cid": s5.AuthMiddleware(h.DebugDownloadUrls, portal),
|
||||
"GET /s5/debug/storage_locations/:hash": s5.AuthMiddleware(h.DebugStorageLocations, portal),
|
||||
|
||||
//Registry API
|
||||
"GET /s5/registry": s5.AuthMiddleware(h.RegistryQuery, portal),
|
||||
|
|
101
api/s5/http.go
101
api/s5/http.go
|
@ -28,6 +28,7 @@ import (
|
|||
"mime/multipart"
|
||||
"net/http"
|
||||
"nhooyr.io/websocket"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
@ -1137,6 +1138,106 @@ func (h *HttpHandler) DownloadBlob(jc jape.Context) {
|
|||
http.Redirect(jc.ResponseWriter, jc.Request, next.Location().BytesURL(), http.StatusFound)
|
||||
}
|
||||
|
||||
func (h *HttpHandler) DebugStorageLocations(jc jape.Context) {
|
||||
var hash string
|
||||
|
||||
if jc.DecodeParam("hash", &hash) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var kinds string
|
||||
|
||||
if jc.DecodeForm("kinds", &kinds) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
decodedHash, err := encoding.MultihashFromBase64Url(hash)
|
||||
if jc.Check("error decoding hash", err) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
typeList := strings.Split(kinds, ",")
|
||||
typeIntList := make([]types.StorageLocationType, 0)
|
||||
|
||||
for _, typeStr := range typeList {
|
||||
typeInt, err := strconv.Atoi(typeStr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
typeIntList = append(typeIntList, types.StorageLocationType(typeInt))
|
||||
}
|
||||
|
||||
if len(typeIntList) == 0 {
|
||||
typeIntList = []types.StorageLocationType{
|
||||
types.StorageLocationTypeFull,
|
||||
types.StorageLocationTypeFile,
|
||||
types.StorageLocationTypeBridge,
|
||||
types.StorageLocationTypeArchive,
|
||||
}
|
||||
}
|
||||
|
||||
dlUriProvider := s5storage.NewStorageLocationProvider(h.getNode(), decodedHash, types.StorageLocationTypeFull, types.StorageLocationTypeFile, types.StorageLocationTypeBridge)
|
||||
|
||||
err = dlUriProvider.Start()
|
||||
if jc.Check("error starting search", err) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = dlUriProvider.Next()
|
||||
if jc.Check("error fetching locations", err) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
locations, err := h.getNode().GetCachedStorageLocations(decodedHash, typeIntList)
|
||||
if jc.Check("error getting cached locations", err) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
availableNodes := lo.Keys[string, s5interfaces.StorageLocation](locations)
|
||||
availableNodesIds := make([]*encoding.NodeId, len(availableNodes))
|
||||
|
||||
for i, nodeIdStr := range availableNodes {
|
||||
nodeId, err := encoding.DecodeNodeId(nodeIdStr)
|
||||
if jc.Check("error decoding node id", err) != nil {
|
||||
return
|
||||
}
|
||||
availableNodesIds[i] = nodeId
|
||||
}
|
||||
|
||||
availableNodesIds, err = h.getNode().Services().P2P().SortNodesByScore(availableNodesIds)
|
||||
|
||||
if jc.Check("error sorting nodes", err) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
debugLocations := make([]DebugStorageLocation, len(availableNodes))
|
||||
|
||||
for i, nodeId := range availableNodesIds {
|
||||
nodeIdStr, err := nodeId.ToBase58()
|
||||
if jc.Check("error encoding node id", err) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
score, err := h.getNode().Services().P2P().GetNodeScore(nodeId)
|
||||
|
||||
if jc.Check("error getting node score", err) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
debugLocations[i] = DebugStorageLocation{
|
||||
Type: locations[nodeIdStr].Type(),
|
||||
Parts: locations[nodeIdStr].Parts(),
|
||||
Expiry: locations[nodeIdStr].Expiry(),
|
||||
NodeId: nodeIdStr,
|
||||
Score: score,
|
||||
}
|
||||
}
|
||||
|
||||
jc.Encode(&DebugStorageLocationsResponse{
|
||||
Locations: debugLocations,
|
||||
})
|
||||
}
|
||||
|
||||
func setAuthCookie(jwt string, jc jape.Context) {
|
||||
authCookie := http.Cookie{
|
||||
Name: "s5-auth-token",
|
||||
|
|
|
@ -66,3 +66,15 @@ type RegistrySetRequest struct {
|
|||
Data string `json:"data"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
type DebugStorageLocation struct {
|
||||
Type int `json:"type"`
|
||||
Parts []string `json:"parts"`
|
||||
Expiry int64 `json:"expiry"`
|
||||
NodeId string `json:"nodeId"`
|
||||
Score float64 `json:"score"`
|
||||
}
|
||||
|
||||
type DebugStorageLocationsResponse struct {
|
||||
Locations []DebugStorageLocation `json:"locations"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue