mirror of
				https://github.com/packwiz/packwiz-installer.git
				synced 2025-10-31 11:04:31 +01:00 
			
		
		
		
	Make github request handling work, fix some things
This commit is contained in:
		| @@ -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(); | ||||||
| @@ -100,4 +146,23 @@ 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); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user