forked from Qortal/qortal
Added GET /data/file/frompeer API endpoint
This requests a file from the supplied peer address, and stores a copy locally if successful. Still a work in progress.
This commit is contained in:
parent
5ac676d201
commit
592490d709
@ -8,23 +8,26 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.qortal.api.ApiError;
|
import org.qortal.api.*;
|
||||||
import org.qortal.api.ApiErrors;
|
import org.qortal.network.Network;
|
||||||
import org.qortal.api.ApiExceptionFactory;
|
import org.qortal.network.Peer;
|
||||||
import org.qortal.api.Security;
|
import org.qortal.network.PeerAddress;
|
||||||
|
import org.qortal.network.message.*;
|
||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.repository.Repository;
|
import org.qortal.repository.Repository;
|
||||||
import org.qortal.repository.RepositoryManager;
|
import org.qortal.repository.RepositoryManager;
|
||||||
import org.qortal.settings.Settings;
|
import org.qortal.settings.Settings;
|
||||||
import org.qortal.storage.DataFile;
|
import org.qortal.storage.DataFile;
|
||||||
import org.qortal.storage.DataFile.ValidationResult;
|
import org.qortal.storage.DataFile.ValidationResult;
|
||||||
|
import org.qortal.utils.Base58;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.*;
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@Path("/data")
|
@Path("/data")
|
||||||
@ -121,7 +124,6 @@ public class DataResource {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ApiErrors({ApiError.REPOSITORY_ISSUE})
|
|
||||||
public String deleteFile(String base58Digest) {
|
public String deleteFile(String base58Digest) {
|
||||||
Security.checkApiCallAllowed(request);
|
Security.checkApiCallAllowed(request);
|
||||||
|
|
||||||
@ -132,4 +134,66 @@ public class DataResource {
|
|||||||
return "false";
|
return "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/file/frompeer")
|
||||||
|
@Operation(
|
||||||
|
summary = "Request file from a given peer, using supplied base58 encoded SHA256 digest string",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
description = "true if retrieved, false if not",
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.TEXT_PLAIN,
|
||||||
|
schema = @Schema(
|
||||||
|
type = "string"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiErrors({ApiError.REPOSITORY_ISSUE})
|
||||||
|
public String getFileFromPeer(@QueryParam("base58Digest") String base58Digest,
|
||||||
|
@QueryParam("peer") String targetPeerAddress) {
|
||||||
|
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
|
||||||
|
if (base58Digest == null) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
|
||||||
|
}
|
||||||
|
if (targetPeerAddress == null) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to resolve passed address to make things easier
|
||||||
|
PeerAddress peerAddress = PeerAddress.fromString(targetPeerAddress);
|
||||||
|
InetSocketAddress resolvedAddress = peerAddress.toSocketAddress();
|
||||||
|
|
||||||
|
List<Peer> peers = Network.getInstance().getHandshakedPeers();
|
||||||
|
Peer targetPeer = peers.stream().filter(peer -> peer.getResolvedAddress().equals(resolvedAddress)).findFirst().orElse(null);
|
||||||
|
|
||||||
|
if (targetPeer == null) {
|
||||||
|
LOGGER.error("Peer not connected");
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataFile dataFile = DataFile.fromBase58Digest(base58Digest);
|
||||||
|
if (dataFile.exists()) {
|
||||||
|
LOGGER.info("Data file {} already exists but we'll request it anyway", dataFile);
|
||||||
|
}
|
||||||
|
Message getDataFileMessage = new GetDataFileMessage(Base58.decode(base58Digest));
|
||||||
|
|
||||||
|
Message message = targetPeer.getResponse(getDataFileMessage);
|
||||||
|
if (message == null || message.getType() != Message.MessageType.DATA_FILE)
|
||||||
|
return "invalid file received";
|
||||||
|
|
||||||
|
DataFileMessage dataFileMessage = (DataFileMessage) message;
|
||||||
|
|
||||||
|
return String.format("Received file %s, size %d bytes", dataFileMessage.getDataFile(), dataFileMessage.getDataFile().size());
|
||||||
|
} catch (ApiException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (DataException | InterruptedException e) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_DATA);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user