mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-04-19 13:06:30 +02:00
Create a wrapper around URIs to fix issues with spaces
This commit is contained in:
parent
465e4973ba
commit
5a54a90f59
@ -2,6 +2,7 @@ package link.infra.packwiz.installer;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.IndexFile;
|
||||
import link.infra.packwiz.installer.metadata.ManifestFile;
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
||||
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
||||
@ -12,7 +13,6 @@ import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@ -74,7 +74,7 @@ class DownloadTask implements IOptionDetails, IExceptionDetails {
|
||||
}
|
||||
}
|
||||
|
||||
void downloadMetadata(IndexFile parentIndexFile, URI indexUri) {
|
||||
void downloadMetadata(IndexFile parentIndexFile, SpaceSafeURI indexUri) {
|
||||
if (failure != null) return;
|
||||
if (metadataRequired) {
|
||||
try {
|
||||
@ -101,7 +101,7 @@ class DownloadTask implements IOptionDetails, IExceptionDetails {
|
||||
}
|
||||
}
|
||||
|
||||
void download(String packFolder, URI indexUri) {
|
||||
void download(String packFolder, SpaceSafeURI indexUri) {
|
||||
if (failure != null) return;
|
||||
|
||||
// Ensure it is removed
|
||||
|
@ -1,5 +1,6 @@
|
||||
package link.infra.packwiz.installer;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
import link.infra.packwiz.installer.ui.CLIHandler;
|
||||
import link.infra.packwiz.installer.ui.IUserInterface;
|
||||
import link.infra.packwiz.installer.ui.InstallWindow;
|
||||
@ -7,7 +8,6 @@ import org.apache.commons.cli.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class Main {
|
||||
@ -37,7 +37,7 @@ public class Main {
|
||||
}
|
||||
}
|
||||
|
||||
protected void startup(String[] args) {
|
||||
private void startup(String[] args) {
|
||||
Options options = new Options();
|
||||
addNonBootstrapOptions(options);
|
||||
addBootstrapOptions(options);
|
||||
@ -99,7 +99,7 @@ public class Main {
|
||||
}
|
||||
|
||||
try {
|
||||
uOptions.downloadURI = new URI(unparsedArgs[0]);
|
||||
uOptions.downloadURI = new SpaceSafeURI(unparsedArgs[0]);
|
||||
} catch (URISyntaxException e) {
|
||||
// TODO: better error message?
|
||||
ui.handleExceptionAndExit(e);
|
||||
@ -124,6 +124,7 @@ public class Main {
|
||||
}
|
||||
|
||||
// Called by packwiz-installer-bootstrap to set up the help command
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static void addNonBootstrapOptions(Options options) {
|
||||
options.addOption("s", "side", true, "Side to install mods from (client/server, defaults to client)");
|
||||
options.addOption(null, "title", true, "Title of the installer window");
|
||||
|
@ -9,6 +9,7 @@ import com.moandjiezana.toml.Toml;
|
||||
import link.infra.packwiz.installer.metadata.IndexFile;
|
||||
import link.infra.packwiz.installer.metadata.ManifestFile;
|
||||
import link.infra.packwiz.installer.metadata.PackFile;
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
||||
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
||||
@ -20,7 +21,6 @@ import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
@ -35,7 +35,7 @@ public class UpdateManager {
|
||||
private boolean cancelledStartGame = false;
|
||||
|
||||
public static class Options {
|
||||
URI downloadURI = null;
|
||||
SpaceSafeURI downloadURI = null;
|
||||
String manifestFile = "packwiz.json"; // TODO: make configurable
|
||||
String packFolder = ".";
|
||||
Side side = Side.CLIENT;
|
||||
@ -136,9 +136,9 @@ public class UpdateManager {
|
||||
ui.submitProgress(new InstallProgress("Checking local files..."));
|
||||
|
||||
// Invalidation checking must be done here, as it must happen before pack/index hashes are checked
|
||||
List<URI> invalidatedUris = new ArrayList<>();
|
||||
List<SpaceSafeURI> invalidatedUris = new ArrayList<>();
|
||||
if (manifest.cachedFiles != null) {
|
||||
for (Map.Entry<URI, ManifestFile.File> entry : manifest.cachedFiles.entrySet()) {
|
||||
for (Map.Entry<SpaceSafeURI, ManifestFile.File> entry : manifest.cachedFiles.entrySet()) {
|
||||
boolean invalid = false;
|
||||
// if isn't optional, or is optional but optionValue == true
|
||||
if (!entry.getValue().isOptional || entry.getValue().optionValue) {
|
||||
@ -152,7 +152,7 @@ public class UpdateManager {
|
||||
}
|
||||
}
|
||||
if (invalid) {
|
||||
URI fileUri = entry.getKey();
|
||||
SpaceSafeURI fileUri = entry.getKey();
|
||||
System.out.println("File " + fileUri.toString() + " invalidated, marked for redownloading");
|
||||
invalidatedUris.add(fileUri);
|
||||
}
|
||||
@ -202,7 +202,7 @@ public class UpdateManager {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
private void processIndex(URI indexUri, Hash indexHash, String hashFormat, ManifestFile manifest, List<URI> invalidatedUris) {
|
||||
private void processIndex(SpaceSafeURI indexUri, Hash indexHash, String hashFormat, ManifestFile manifest, List<SpaceSafeURI> invalidatedUris) {
|
||||
if (manifest.indexFileHash != null && manifest.indexFileHash.equals(indexHash) && invalidatedUris.isEmpty()) {
|
||||
System.out.println("Modpack files are already up to date!");
|
||||
return;
|
||||
@ -238,9 +238,9 @@ public class UpdateManager {
|
||||
}
|
||||
|
||||
ui.submitProgress(new InstallProgress("Checking local files..."));
|
||||
Iterator<Map.Entry<URI, ManifestFile.File>> it = manifest.cachedFiles.entrySet().iterator();
|
||||
Iterator<Map.Entry<SpaceSafeURI, ManifestFile.File>> it = manifest.cachedFiles.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<URI, ManifestFile.File> entry = it.next();
|
||||
Map.Entry<SpaceSafeURI, ManifestFile.File> entry = it.next();
|
||||
if (entry.getValue().cachedLocation != null) {
|
||||
boolean alreadyDeleted = false;
|
||||
// Delete if option value has been set to false
|
||||
|
@ -1,6 +1,5 @@
|
||||
package link.infra.packwiz.installer.metadata;
|
||||
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.moandjiezana.toml.Toml;
|
||||
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
||||
@ -10,7 +9,6 @@ import link.infra.packwiz.installer.request.HandlerManager;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
@ -20,20 +18,19 @@ public class IndexFile {
|
||||
public List<File> files;
|
||||
|
||||
public static class File {
|
||||
@JsonAdapter(SpaceSafeURIParser.class)
|
||||
public URI file;
|
||||
public SpaceSafeURI file;
|
||||
@SerializedName("hash-format")
|
||||
public String hashFormat;
|
||||
public String hash;
|
||||
public URI alias;
|
||||
public SpaceSafeURI alias;
|
||||
public boolean metafile;
|
||||
public boolean preserve;
|
||||
|
||||
public transient ModFile linkedFile;
|
||||
public transient URI linkedFileURI;
|
||||
public transient SpaceSafeURI linkedFileURI;
|
||||
public transient boolean optionValue = true;
|
||||
|
||||
public void downloadMeta(IndexFile parentIndexFile, URI indexUri) throws Exception {
|
||||
public void downloadMeta(IndexFile parentIndexFile, SpaceSafeURI indexUri) throws Exception {
|
||||
if (!metafile) {
|
||||
return;
|
||||
}
|
||||
@ -51,14 +48,14 @@ public class IndexFile {
|
||||
}
|
||||
}
|
||||
|
||||
public Source getSource(URI indexUri) throws Exception {
|
||||
public Source getSource(SpaceSafeURI indexUri) throws Exception {
|
||||
if (metafile) {
|
||||
if (linkedFile == null) {
|
||||
throw new Exception("Linked file doesn't exist!");
|
||||
}
|
||||
return linkedFile.getSource(linkedFileURI);
|
||||
} else {
|
||||
URI newLoc = HandlerManager.getNewLoc(indexUri, file);
|
||||
SpaceSafeURI newLoc = HandlerManager.getNewLoc(indexUri, file);
|
||||
if (newLoc == null) {
|
||||
throw new Exception("Index file URI is invalid");
|
||||
}
|
||||
@ -94,13 +91,13 @@ public class IndexFile {
|
||||
return "Invalid file";
|
||||
}
|
||||
|
||||
public URI getDestURI() {
|
||||
public SpaceSafeURI getDestURI() {
|
||||
if (alias != null) {
|
||||
return alias;
|
||||
}
|
||||
if (metafile && linkedFile != null) {
|
||||
// TODO: URIs are bad
|
||||
return file.resolve(linkedFile.filename.replace(" ", "%20"));
|
||||
return file.resolve(linkedFile.filename);
|
||||
} else {
|
||||
return file;
|
||||
}
|
||||
|
@ -3,13 +3,12 @@ package link.infra.packwiz.installer.metadata;
|
||||
import link.infra.packwiz.installer.UpdateManager;
|
||||
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
public class ManifestFile {
|
||||
public Hash packFileHash = null;
|
||||
public Hash indexFileHash = null;
|
||||
public Map<URI, File> cachedFiles;
|
||||
public Map<SpaceSafeURI, File> cachedFiles;
|
||||
// If the side changes, EVERYTHING invalidates. FUN!!!
|
||||
public UpdateManager.Options.Side cachedSide = UpdateManager.Options.Side.CLIENT;
|
||||
|
||||
|
@ -1,17 +1,14 @@
|
||||
package link.infra.packwiz.installer.metadata;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import link.infra.packwiz.installer.UpdateManager.Options.Side;
|
||||
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
||||
import link.infra.packwiz.installer.request.HandlerManager;
|
||||
import okio.Source;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ModFile {
|
||||
public String name;
|
||||
public String filename;
|
||||
@ -19,8 +16,7 @@ public class ModFile {
|
||||
|
||||
public Download download;
|
||||
public static class Download {
|
||||
@JsonAdapter(SpaceSafeURIParser.class)
|
||||
public URI url;
|
||||
public SpaceSafeURI url;
|
||||
@SerializedName("hash-format")
|
||||
public String hashFormat;
|
||||
public String hash;
|
||||
@ -36,14 +32,14 @@ public class ModFile {
|
||||
public boolean defaultValue;
|
||||
}
|
||||
|
||||
public Source getSource(URI baseLoc) throws Exception {
|
||||
public Source getSource(SpaceSafeURI baseLoc) throws Exception {
|
||||
if (download == null) {
|
||||
throw new Exception("Metadata file doesn't have download");
|
||||
}
|
||||
if (download.url == null) {
|
||||
throw new Exception("Metadata file doesn't have a download URI");
|
||||
}
|
||||
URI newLoc = HandlerManager.getNewLoc(baseLoc, download.url);
|
||||
SpaceSafeURI newLoc = HandlerManager.getNewLoc(baseLoc, download.url);
|
||||
if (newLoc == null) {
|
||||
throw new Exception("Metadata file URI is invalid");
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
package link.infra.packwiz.installer.metadata;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PackFile {
|
||||
public String name;
|
||||
|
||||
public IndexFileLoc index;
|
||||
public static class IndexFileLoc {
|
||||
@JsonAdapter(SpaceSafeURIParser.class)
|
||||
public URI file;
|
||||
public SpaceSafeURI file;
|
||||
@SerializedName("hash-format")
|
||||
public String hashFormat;
|
||||
public String hash;
|
||||
|
@ -0,0 +1,83 @@
|
||||
package link.infra.packwiz.installer.metadata;
|
||||
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
// The world's worst URI wrapper
|
||||
@JsonAdapter(SpaceSafeURIParser.class)
|
||||
public class SpaceSafeURI implements Comparable<SpaceSafeURI>, Serializable {
|
||||
private final URI u;
|
||||
|
||||
public SpaceSafeURI(String str) throws URISyntaxException {
|
||||
u = new URI(str.replace(" ", "%20"));
|
||||
}
|
||||
|
||||
public SpaceSafeURI(URI uri) {
|
||||
this.u = uri;
|
||||
}
|
||||
|
||||
public SpaceSafeURI(String scheme, String authority, String path, String query, String fragment) throws URISyntaxException {
|
||||
// TODO: do all components need to be replaced?
|
||||
scheme = scheme.replace(" ", "%20");
|
||||
authority = authority.replace(" ", "%20");
|
||||
path = path.replace(" ", "%20");
|
||||
query = query.replace(" ", "%20");
|
||||
fragment = fragment.replace(" ", "%20");
|
||||
u = new URI(scheme, authority, path, query, fragment);
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return u.getPath().replace("%20", " ");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return u.toString().replace("%20", " ");
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public SpaceSafeURI resolve(String path) {
|
||||
return new SpaceSafeURI(u.resolve(path.replace(" ", "%20")));
|
||||
}
|
||||
|
||||
public SpaceSafeURI resolve(SpaceSafeURI loc) {
|
||||
return new SpaceSafeURI(u.resolve(loc.u));
|
||||
}
|
||||
|
||||
public SpaceSafeURI relativize(SpaceSafeURI loc) {
|
||||
return new SpaceSafeURI(u.relativize(loc.u));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof SpaceSafeURI) {
|
||||
return u.equals(((SpaceSafeURI) obj).u);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(SpaceSafeURI uri) {
|
||||
return u.compareTo(uri.u);
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return u.getScheme();
|
||||
}
|
||||
|
||||
public String getAuthority() {
|
||||
return u.getAuthority();
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return u.getHost();
|
||||
}
|
||||
|
||||
public URL toURL() throws MalformedURLException {
|
||||
return u.toURL();
|
||||
}
|
||||
}
|
@ -1,26 +1,24 @@
|
||||
package link.infra.packwiz.installer.metadata;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* This class encodes spaces before parsing the URI, so the URI can actually be
|
||||
* parsed.
|
||||
*/
|
||||
class SpaceSafeURIParser implements JsonDeserializer<URI> {
|
||||
class SpaceSafeURIParser implements JsonDeserializer<SpaceSafeURI> {
|
||||
|
||||
@Override
|
||||
public URI deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
public SpaceSafeURI deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
String uriString = json.getAsString().replace(" ", "%20");
|
||||
try {
|
||||
return new URI(uriString);
|
||||
return new SpaceSafeURI(json.getAsString());
|
||||
} catch (URISyntaxException e) {
|
||||
throw new JsonParseException("Failed to parse URI", e);
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
package link.infra.packwiz.installer.request;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
import link.infra.packwiz.installer.request.handlers.RequestHandlerGithub;
|
||||
import link.infra.packwiz.installer.request.handlers.RequestHandlerHTTP;
|
||||
import okio.Source;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class HandlerManager {
|
||||
|
||||
public static List<IRequestHandler> handlers = new ArrayList<IRequestHandler>();
|
||||
private static List<IRequestHandler> handlers = new ArrayList<>();
|
||||
|
||||
static {
|
||||
handlers.add(new RequestHandlerGithub());
|
||||
handlers.add(new RequestHandlerHTTP());
|
||||
}
|
||||
|
||||
public static URI getNewLoc(URI base, URI loc) {
|
||||
public static SpaceSafeURI getNewLoc(SpaceSafeURI base, SpaceSafeURI loc) {
|
||||
if (loc == null) return null;
|
||||
if (base != null) {
|
||||
loc = base.resolve(loc);
|
||||
@ -35,7 +35,7 @@ public abstract class HandlerManager {
|
||||
// Zip handler discards once read, requesting multiple times on other handlers would cause multiple downloads
|
||||
// Caching system? Copy from already downloaded files?
|
||||
|
||||
public static Source getFileSource(URI loc) throws Exception {
|
||||
public static Source getFileSource(SpaceSafeURI loc) throws Exception {
|
||||
for (IRequestHandler handler : handlers) {
|
||||
if (handler.matchesHandler(loc)) {
|
||||
Source src = handler.getFileSource(loc);
|
||||
|
@ -1,17 +1,16 @@
|
||||
package link.infra.packwiz.installer.request;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
import okio.Source;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* IRequestHandler handles requests for locations specified in modpack metadata.
|
||||
*/
|
||||
public interface IRequestHandler {
|
||||
|
||||
boolean matchesHandler(URI loc);
|
||||
boolean matchesHandler(SpaceSafeURI loc);
|
||||
|
||||
default URI getNewLoc(URI loc) {
|
||||
default SpaceSafeURI getNewLoc(SpaceSafeURI loc) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
@ -20,8 +19,8 @@ public interface IRequestHandler {
|
||||
* It is assumed that each location is read only once for the duration of an IRequestHandler.
|
||||
* @param loc The location to be read
|
||||
* @return The Source containing the data of the file
|
||||
* @throws Exception
|
||||
* @throws Exception Exception if it failed to download a file!!!
|
||||
*/
|
||||
Source getFileSource(URI loc) throws Exception;
|
||||
Source getFileSource(SpaceSafeURI loc) throws Exception;
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package link.infra.packwiz.installer.request.handlers;
|
||||
|
||||
import java.net.URI;
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@ -14,16 +15,16 @@ public class RequestHandlerGithub extends RequestHandlerZip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getNewLoc(URI loc) {
|
||||
public SpaceSafeURI getNewLoc(SpaceSafeURI loc) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
// TODO: is caching really needed, if HTTPURLConnection follows redirects correctly?
|
||||
private Map<String, URI> zipUriMap = new HashMap<>();
|
||||
private Map<String, SpaceSafeURI> zipUriMap = new HashMap<>();
|
||||
private final ReentrantReadWriteLock zipUriLock = new ReentrantReadWriteLock();
|
||||
private static Pattern repoMatcherPattern = Pattern.compile("/([\\w.-]+/[\\w.-]+).*");
|
||||
|
||||
private String getRepoName(URI loc) {
|
||||
private String getRepoName(SpaceSafeURI loc) {
|
||||
Matcher matcher = repoMatcherPattern.matcher(loc.getPath());
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(1);
|
||||
@ -33,22 +34,22 @@ public class RequestHandlerGithub extends RequestHandlerZip {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URI getZipUri(URI loc) throws Exception {
|
||||
protected SpaceSafeURI getZipUri(SpaceSafeURI loc) throws Exception {
|
||||
String repoName = getRepoName(loc);
|
||||
String branchName = getBranch(loc);
|
||||
zipUriLock.readLock().lock();
|
||||
URI zipUri = zipUriMap.get(repoName + "/" + branchName);
|
||||
SpaceSafeURI zipUri = zipUriMap.get(repoName + "/" + branchName);
|
||||
zipUriLock.readLock().unlock();
|
||||
if (zipUri != null) {
|
||||
return zipUri;
|
||||
}
|
||||
|
||||
zipUri = new URI("https://api.github.com/repos/" + repoName + "/zipball/" + branchName);
|
||||
zipUri = new SpaceSafeURI("https://api.github.com/repos/" + repoName + "/zipball/" + branchName);
|
||||
|
||||
zipUriLock.writeLock().lock();
|
||||
// If another thread sets the value concurrently, use the value of the
|
||||
// thread that first acquired the lock.
|
||||
URI zipUriInserted = zipUriMap.putIfAbsent(repoName + "/" + branchName, zipUri);
|
||||
SpaceSafeURI zipUriInserted = zipUriMap.putIfAbsent(repoName + "/" + branchName, zipUri);
|
||||
if (zipUriInserted != null) {
|
||||
zipUri = zipUriInserted;
|
||||
}
|
||||
@ -58,7 +59,7 @@ public class RequestHandlerGithub extends RequestHandlerZip {
|
||||
|
||||
private static Pattern branchMatcherPattern = Pattern.compile("/[\\w.-]+/[\\w.-]+/blob/([\\w.-]+).*");
|
||||
|
||||
private String getBranch(URI loc) {
|
||||
private String getBranch(SpaceSafeURI loc) {
|
||||
Matcher matcher = branchMatcherPattern.matcher(loc.getPath());
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(1);
|
||||
@ -68,13 +69,13 @@ public class RequestHandlerGithub extends RequestHandlerZip {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URI getLocationInZip(URI loc) throws Exception {
|
||||
protected SpaceSafeURI getLocationInZip(SpaceSafeURI loc) throws Exception {
|
||||
String path = "/" + getRepoName(loc) + "/blob/" + getBranch(loc);
|
||||
return new URI(loc.getScheme(), loc.getAuthority(), path, null, null).relativize(loc);
|
||||
return new SpaceSafeURI(loc.getScheme(), loc.getAuthority(), path, null, null).relativize(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesHandler(URI loc) {
|
||||
public boolean matchesHandler(SpaceSafeURI loc) {
|
||||
String scheme = loc.getScheme();
|
||||
if (!("http".equals(scheme) || "https".equals(scheme))) {
|
||||
return false;
|
||||
|
@ -1,22 +1,22 @@
|
||||
package link.infra.packwiz.installer.request.handlers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
import link.infra.packwiz.installer.request.IRequestHandler;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class RequestHandlerHTTP implements IRequestHandler {
|
||||
|
||||
@Override
|
||||
public boolean matchesHandler(URI loc) {
|
||||
public boolean matchesHandler(SpaceSafeURI loc) {
|
||||
String scheme = loc.getScheme();
|
||||
return "http".equals(scheme) || "https".equals(scheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Source getFileSource(URI loc) throws Exception {
|
||||
public Source getFileSource(SpaceSafeURI loc) throws Exception {
|
||||
URLConnection conn = loc.toURL().openConnection();
|
||||
// TODO: when do we send specific headers??? should there be a way to signal this?
|
||||
// github *sometimes* requires it, sometimes not!
|
||||
|
@ -1,12 +1,12 @@
|
||||
package link.infra.packwiz.installer.request.handlers;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -35,7 +35,7 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
private class ZipReader {
|
||||
|
||||
private final ZipInputStream zis;
|
||||
private final Map<URI, Buffer> readFiles = new HashMap<>();
|
||||
private final Map<SpaceSafeURI, Buffer> readFiles = new HashMap<>();
|
||||
// Write lock implies access to ZipInputStream - only 1 thread must read at a time!
|
||||
final ReentrantLock filesLock = new ReentrantLock();
|
||||
private ZipEntry entry;
|
||||
@ -55,14 +55,14 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
}
|
||||
|
||||
// File lock must be obtained before calling this function
|
||||
private Buffer findFile(URI loc) throws IOException, URISyntaxException {
|
||||
private Buffer findFile(SpaceSafeURI loc) throws IOException, URISyntaxException {
|
||||
while (true) {
|
||||
entry = zis.getNextEntry();
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
Buffer data = readCurrFile();
|
||||
URI fileLoc = new URI(removeFolder(entry.getName()));
|
||||
SpaceSafeURI fileLoc = new SpaceSafeURI(removeFolder(entry.getName()));
|
||||
if (loc.equals(fileLoc)) {
|
||||
return data;
|
||||
} else {
|
||||
@ -71,7 +71,7 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
}
|
||||
}
|
||||
|
||||
Source getFileSource(URI loc) throws Exception {
|
||||
Source getFileSource(SpaceSafeURI loc) throws Exception {
|
||||
filesLock.lock();
|
||||
// Assume files are only read once, allow GC by removing
|
||||
Buffer file = readFiles.remove(loc);
|
||||
@ -84,10 +84,10 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
filesLock.unlock();
|
||||
return file;
|
||||
}
|
||||
|
||||
URI findInZip(Predicate<URI> matches) throws Exception {
|
||||
|
||||
SpaceSafeURI findInZip(Predicate<SpaceSafeURI> matches) throws Exception {
|
||||
filesLock.lock();
|
||||
for (URI file : readFiles.keySet()) {
|
||||
for (SpaceSafeURI file : readFiles.keySet()) {
|
||||
if (matches.test(file)) {
|
||||
filesLock.unlock();
|
||||
return file;
|
||||
@ -101,7 +101,7 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
return null;
|
||||
}
|
||||
Buffer data = readCurrFile();
|
||||
URI fileLoc = new URI(removeFolder(entry.getName()));
|
||||
SpaceSafeURI fileLoc = new SpaceSafeURI(removeFolder(entry.getName()));
|
||||
readFiles.put(fileLoc, data);
|
||||
if (matches.test(fileLoc)) {
|
||||
filesLock.unlock();
|
||||
@ -112,19 +112,19 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
|
||||
}
|
||||
|
||||
private final Map<URI, ZipReader> cache = new HashMap<>();
|
||||
private final Map<SpaceSafeURI, ZipReader> cache = new HashMap<>();
|
||||
private final ReentrantReadWriteLock cacheLock = new ReentrantReadWriteLock();
|
||||
|
||||
protected abstract URI getZipUri(URI loc) throws Exception;
|
||||
protected abstract SpaceSafeURI getZipUri(SpaceSafeURI loc) throws Exception;
|
||||
|
||||
protected abstract URI getLocationInZip(URI loc) throws Exception;
|
||||
protected abstract SpaceSafeURI getLocationInZip(SpaceSafeURI loc) throws Exception;
|
||||
|
||||
@Override
|
||||
public abstract boolean matchesHandler(URI loc);
|
||||
public abstract boolean matchesHandler(SpaceSafeURI loc);
|
||||
|
||||
@Override
|
||||
public Source getFileSource(URI loc) throws Exception {
|
||||
URI zipUri = getZipUri(loc);
|
||||
public Source getFileSource(SpaceSafeURI loc) throws Exception {
|
||||
SpaceSafeURI zipUri = getZipUri(loc);
|
||||
cacheLock.readLock().lock();
|
||||
ZipReader zr = cache.get(zipUri);
|
||||
cacheLock.readLock().unlock();
|
||||
@ -147,8 +147,8 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
return zr.getFileSource(getLocationInZip(loc));
|
||||
}
|
||||
|
||||
protected URI findInZip(URI loc, Predicate<URI> matches) throws Exception {
|
||||
URI zipUri = getZipUri(loc);
|
||||
protected SpaceSafeURI findInZip(SpaceSafeURI loc, Predicate<SpaceSafeURI> matches) throws Exception {
|
||||
SpaceSafeURI zipUri = getZipUri(loc);
|
||||
cacheLock.readLock().lock();
|
||||
ZipReader zr = cache.get(zipUri);
|
||||
cacheLock.readLock().unlock();
|
||||
|
Loading…
x
Reference in New Issue
Block a user