3
0
mirror of https://github.com/Qortal/qortal.git synced 2025-02-14 11:15:49 +00:00

Upgraded gateway to support service and identifier.

The URL used to access the gateway is now interpreted, and the most appropriate resource is served. This means it can be used in different ways to retrieve any type of content from QDN. For example:

/QortalDemo
/QortalDemo/minting-leveling/index.html
/WEBSITE/QortalDemo
/WEBSITE/QortalDemo/minting-leveling/index.html
/APP/QortalDemo
/THUMBNAIL/QortalDemo/qortal_avatar
/QCHAT_IMAGE/birtydasterd/qchat_BfBeCz
/ARBITRARY_DATA/PirateChainWallet/LiteWalletJNI/coinparams.json
This commit is contained in:
CalDescent 2023-01-28 17:56:24 +00:00
parent 37b20aac66
commit 04f248bcdd

View File

@ -16,6 +16,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@Path("/") @Path("/")
@ -76,50 +79,75 @@ public class GatewayResource {
@GET @GET
@Path("{name}/{path:.*}") @Path("{path:.*}")
@SecurityRequirement(name = "apiKey") @SecurityRequirement(name = "apiKey")
public HttpServletResponse getPathByName(@PathParam("name") String name, public HttpServletResponse getPath(@PathParam("path") String inPath) {
@PathParam("path") String inPath) {
// Block requests from localhost, to prevent websites/apps from running javascript that fetches unvetted data // Block requests from localhost, to prevent websites/apps from running javascript that fetches unvetted data
Security.disallowLoopbackRequests(request); Security.disallowLoopbackRequests(request);
return this.get(name, ResourceIdType.NAME, Service.WEBSITE, null, inPath, null, "", true, true); return this.parsePath(inPath, "gateway", null, "", true, true);
}
@GET
@Path("{name}")
@SecurityRequirement(name = "apiKey")
public HttpServletResponse getIndexByName(@PathParam("name") String name) {
// Block requests from localhost, to prevent websites/apps from running javascript that fetches unvetted data
Security.disallowLoopbackRequests(request);
return this.get(name, ResourceIdType.NAME, Service.WEBSITE, null, "/", null, "", true, true);
} }
// Optional /site alternative for backwards support private HttpServletResponse parsePath(String inPath, String qdnContext, String secret58, String prefix, boolean usePrefix, boolean async) {
@GET if (inPath == null || inPath.equals("")) {
@Path("/site/{name}/{path:.*}") // Assume not a real file
public HttpServletResponse getSitePathByName(@PathParam("name") String name, return ArbitraryDataRenderer.getResponse(response, 404, "Error 404: File Not Found");
@PathParam("path") String inPath) {
// Block requests from localhost, to prevent websites/apps from running javascript that fetches unvetted data
Security.disallowLoopbackRequests(request);
return this.get(name, ResourceIdType.NAME, Service.WEBSITE, null, inPath, null, "/site", true, true);
} }
@GET // Default service is WEBSITE
@Path("/site/{name}") Service service = Service.WEBSITE;
public HttpServletResponse getSiteIndexByName(@PathParam("name") String name) { String name = null;
// Block requests from localhost, to prevent websites/apps from running javascript that fetches unvetted data String identifier = null;
Security.disallowLoopbackRequests(request); String outPath = "";
return this.get(name, ResourceIdType.NAME, Service.WEBSITE, null, "/", null, "/site", true, true);
if (!inPath.contains("/")) {
// Assume entire inPath is a registered name
name = inPath;
}
else {
// Parse the path to determine what we need to load
List<String> parts = new LinkedList<>(Arrays.asList(inPath.split("/")));
// Check if the first element is a service
try {
Service parsedService = Service.valueOf(parts.get(0).toUpperCase());
if (parsedService != null) {
// First element matches a service, so we can assume it is one
service = parsedService;
parts.remove(0);
}
} catch (IllegalArgumentException e) {
// Not a service
} }
if (parts.isEmpty()) {
// We need more than just a service
return ArbitraryDataRenderer.getResponse(response, 404, "Error 404: File Not Found");
}
private HttpServletResponse get(String resourceId, ResourceIdType resourceIdType, Service service, String identifier, // Service is removed, so assume first element is now a registered name
String inPath, String secret58, String prefix, boolean usePrefix, boolean async) { name = parts.get(0);
parts.remove(0);
ArbitraryDataRenderer renderer = new ArbitraryDataRenderer(resourceId, resourceIdType, service, identifier, inPath, if (!parts.isEmpty()) {
secret58, prefix, usePrefix, async, "gateway", request, response, context); // Name is removed, so check if the first element is now an identifier
ArbitraryResourceStatus status = this.getStatus(service, name, parts.get(0), false);
if (status.getTotalChunkCount() > 0) {
// Matched service, name and identifier combination - so assume this is an identifier and can be removed
identifier = parts.get(0);
parts.remove(0);
}
}
if (!parts.isEmpty()) {
// outPath can be built by combining any remaining parts
outPath = String.join("/", parts);
}
}
ArbitraryDataRenderer renderer = new ArbitraryDataRenderer(name, ResourceIdType.NAME, service, identifier, outPath,
secret58, prefix, usePrefix, async, qdnContext, request, response, context);
return renderer.render(); return renderer.render();
} }