mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-04-19 13:06:30 +02:00
Make github request handling work, fix some things
This commit is contained in:
parent
2118a8fda1
commit
fd87edd6ca
@ -1,25 +1,83 @@
|
|||||||
package link.infra.packwiz.installer.request.handlers;
|
package link.infra.packwiz.installer.request.handlers;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class RequestHandlerGithub extends RequestHandlerZip {
|
public class RequestHandlerGithub extends RequestHandlerZip {
|
||||||
|
|
||||||
|
public RequestHandlerGithub() {
|
||||||
|
super(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URI getNewLoc(URI loc) {
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: is caching really needed, if HTTPURLConnection follows redirects correctly?
|
||||||
|
private Map<String, URI> zipUriMap = new HashMap<String, URI>();
|
||||||
|
final ReentrantReadWriteLock zipUriLock = new ReentrantReadWriteLock();
|
||||||
|
private static Pattern repoMatcherPattern = Pattern.compile("/([\\w.-]+/[\\w.-]+).*");
|
||||||
|
|
||||||
|
private String getRepoName(URI loc) {
|
||||||
|
Matcher matcher = repoMatcherPattern.matcher(loc.getPath());
|
||||||
|
matcher.matches();
|
||||||
|
return matcher.group(1);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected URI getZipUri(URI loc) throws Exception {
|
protected URI getZipUri(URI loc) throws Exception {
|
||||||
// TODO Auto-generated method stub
|
String repoName = getRepoName(loc);
|
||||||
return null;
|
String branchName = getBranch(loc);
|
||||||
|
zipUriLock.readLock().lock();
|
||||||
|
URI zipUri = zipUriMap.get(repoName + "/" + branchName);
|
||||||
|
zipUriLock.readLock().unlock();
|
||||||
|
if (zipUri != null) {
|
||||||
|
return zipUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
zipUri = new URI("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);
|
||||||
|
if (zipUriInserted != null) {
|
||||||
|
zipUri = zipUriInserted;
|
||||||
|
}
|
||||||
|
zipUriLock.writeLock().unlock();
|
||||||
|
return zipUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pattern branchMatcherPattern = Pattern.compile("/[\\w.-]+/[\\w.-]+/blob/([\\w.-]+).*");
|
||||||
|
|
||||||
|
private String getBranch(URI loc) {
|
||||||
|
Matcher matcher = branchMatcherPattern.matcher(loc.getPath());
|
||||||
|
matcher.matches();
|
||||||
|
return matcher.group(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected URI getLocationInZip(URI loc) throws Exception {
|
protected URI getLocationInZip(URI loc) throws Exception {
|
||||||
// TODO Auto-generated method stub
|
String path = "/" + getRepoName(loc) + "/blob/" + getBranch(loc);
|
||||||
return null;
|
return new URI(loc.getScheme(), loc.getAuthority(), path, null, null).relativize(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matchesHandler(URI loc) {
|
public boolean matchesHandler(URI loc) {
|
||||||
// TODO Auto-generated method stub
|
String scheme = loc.getScheme();
|
||||||
return false;
|
if (!(scheme.equals("http") || scheme.equals("https"))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!loc.getHost().equals("github.com")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO: sanity checks, support for more github urls
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@ public class RequestHandlerHTTP implements IRequestHandler {
|
|||||||
@Override
|
@Override
|
||||||
public InputStream getFileInputStream(URI loc) throws Exception {
|
public InputStream getFileInputStream(URI loc) throws Exception {
|
||||||
URLConnection conn = loc.toURL().openConnection();
|
URLConnection conn = loc.toURL().openConnection();
|
||||||
conn.addRequestProperty("Accept", "application/octet-stream");
|
// TODO: when do we send specific headers??? should there be a way to signal this?
|
||||||
|
// github *sometimes* requires it, sometimes not!
|
||||||
|
//conn.addRequestProperty("Accept", "application/octet-stream");
|
||||||
// 30 second read timeout
|
// 30 second read timeout
|
||||||
conn.setReadTimeout(30 * 1000);
|
conn.setReadTimeout(30 * 1000);
|
||||||
return conn.getInputStream();
|
return conn.getInputStream();
|
||||||
|
@ -10,11 +10,26 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||||
|
|
||||||
|
protected final boolean modeHasFolder;
|
||||||
|
|
||||||
|
public RequestHandlerZip(boolean modeHasFolder) {
|
||||||
|
this.modeHasFolder = modeHasFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeFolder(String name) {
|
||||||
|
if (modeHasFolder) {
|
||||||
|
return name.substring(name.indexOf("/")+1);
|
||||||
|
} else {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class ZipReader {
|
private class ZipReader {
|
||||||
|
|
||||||
private final ZipInputStream zis;
|
private final ZipInputStream zis;
|
||||||
@ -43,10 +58,11 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
byte[] data = readCurrFile();
|
byte[] data = readCurrFile();
|
||||||
if (loc.equals(new URI(entry.getName()))) {
|
URI fileLoc = new URI(removeFolder(entry.getName()));
|
||||||
|
if (loc.equals(fileLoc)) {
|
||||||
return data;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
readFiles.put(loc, data);
|
readFiles.put(fileLoc, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,6 +84,31 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public URI findInZip(Predicate<URI> matches) throws Exception {
|
||||||
|
filesLock.lock();
|
||||||
|
for (URI file : readFiles.keySet()) {
|
||||||
|
if (matches.test(file)) {
|
||||||
|
filesLock.unlock();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
entry = zis.getNextEntry();
|
||||||
|
if (entry == null) {
|
||||||
|
filesLock.unlock();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] data = readCurrFile();
|
||||||
|
URI fileLoc = new URI(removeFolder(entry.getName()));
|
||||||
|
readFiles.put(fileLoc, data);
|
||||||
|
if (matches.test(fileLoc)) {
|
||||||
|
filesLock.unlock();
|
||||||
|
return fileLoc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<URI, ZipReader> cache = new HashMap<URI, ZipReader>();
|
private final Map<URI, ZipReader> cache = new HashMap<URI, ZipReader>();
|
||||||
@ -91,7 +132,12 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
|||||||
// Recheck, because unlocking read lock allows another thread to modify it
|
// Recheck, because unlocking read lock allows another thread to modify it
|
||||||
zr = cache.get(zipUri);
|
zr = cache.get(zipUri);
|
||||||
if (zr == null) {
|
if (zr == null) {
|
||||||
zr = new ZipReader(super.getFileInputStream(zipUri));
|
InputStream str = super.getFileInputStream(zipUri);
|
||||||
|
if (str == null) {
|
||||||
|
cacheLock.writeLock().unlock();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
zr = new ZipReader(str);
|
||||||
cache.put(zipUri, zr);
|
cache.put(zipUri, zr);
|
||||||
}
|
}
|
||||||
cacheLock.writeLock().unlock();
|
cacheLock.writeLock().unlock();
|
||||||
@ -99,5 +145,24 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
|||||||
|
|
||||||
return zr.getFileInputStream(getLocationInZip(loc));
|
return zr.getFileInputStream(getLocationInZip(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected URI findInZip(URI loc, Predicate<URI> matches) throws Exception {
|
||||||
|
URI zipUri = getZipUri(loc);
|
||||||
|
cacheLock.readLock().lock();
|
||||||
|
ZipReader zr = cache.get(zipUri);
|
||||||
|
cacheLock.readLock().unlock();
|
||||||
|
if (zr == null) {
|
||||||
|
cacheLock.writeLock().lock();
|
||||||
|
// Recheck, because unlocking read lock allows another thread to modify it
|
||||||
|
zr = cache.get(zipUri);
|
||||||
|
if (zr == null) {
|
||||||
|
zr = new ZipReader(super.getFileInputStream(zipUri));
|
||||||
|
cache.put(zipUri, zr);
|
||||||
|
}
|
||||||
|
cacheLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return zr.findInZip(matches);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user