diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 6e263ee60..2c536483e 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -549,7 +549,7 @@ public class Base { } - public String getInstalledContribsInfo() { + public byte[] getInstalledContribsInfo() { List contribs = getInstalledContribs(); StringList entries = new StringList(); for (Contribution c : contribs) { @@ -560,22 +560,23 @@ public class Base { entries.append(entry); } String joined = "id=" + Preferences.get("update.id") + entries.join("&"); - StringBuilder sb = new StringBuilder(); - try { - // Truly ridiculous attempt to shove everything into a GET request. - // More likely to be seen as part of a grand plot. - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - GZIPOutputStream output = new GZIPOutputStream(baos); - PApplet.saveStream(output, new ByteArrayInputStream(joined.getBytes())); - output.close(); - byte[] b = baos.toByteArray(); - for (int i = 0; i < b.length; i++) { - sb.append(PApplet.hex(b[i], 2)); - } - } catch (IOException e) { - e.printStackTrace(); - } - return sb.toString(); +// StringBuilder sb = new StringBuilder(); +// try { +// // Truly ridiculous attempt to shove everything into a GET request. +// // More likely to be seen as part of a grand plot. +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); +// GZIPOutputStream output = new GZIPOutputStream(baos); +// PApplet.saveStream(output, new ByteArrayInputStream(joined.getBytes())); +// output.close(); +// byte[] b = baos.toByteArray(); +// for (int i = 0; i < b.length; i++) { +// sb.append(PApplet.hex(b[i], 2)); +// } +// } catch (IOException e) { +// e.printStackTrace(); +// } +// return sb.toString(); + return joined.getBytes(); } diff --git a/app/src/processing/app/contrib/ContributionListing.java b/app/src/processing/app/contrib/ContributionListing.java index b9ee2c3f4..57ea49826 100644 --- a/app/src/processing/app/contrib/ContributionListing.java +++ b/app/src/processing/app/contrib/ContributionListing.java @@ -23,7 +23,6 @@ package processing.app.contrib; import java.io.*; import java.net.*; -import java.nio.file.Files; import java.util.*; import java.util.concurrent.locks.ReentrantLock; @@ -407,33 +406,32 @@ public class ContributionListing { url = new URL(LISTING_URL); // final String contribInfo = // base.getInstalledContribsInfo(); -//// "?id=" + Preferences.get("update.id") + -//// "&" + base.getInstalledContribsInfo(); +// "?id=" + Preferences.get("update.id") + +// "&" + base.getInstalledContribsInfo(); // url = new URL(LISTING_URL + "?" + contribInfo); // System.out.println(contribInfo.length() + " " + contribInfo); + + File tempContribFile = Base.getSettingsFile("contribs.tmp"); + tempContribFile.setWritable(true); + ContributionManager.download(url, base.getInstalledContribsInfo(), + tempContribFile, progress); + if (!progress.isCanceled() && !progress.isError()) { + if (listingFile.exists()) { + listingFile.delete(); // may silently fail, but below may still work + } + if (tempContribFile.renameTo(listingFile)) { + hasDownloadedLatestList = true; + hasListDownloadFailed = false; + setAdvertisedList(listingFile); + } else { + hasListDownloadFailed = true; + } + } + } catch (MalformedURLException e) { progress.error(e); progress.finished(); } - - if (!progress.isFinished()) { - File tempContribFile = Base.getSettingsFile("contributions_temp.txt"); - tempContribFile.setWritable(true); - ContributionManager.download(url, tempContribFile, progress); - if (!progress.isCanceled() && !progress.isError()) { - try { - Files.deleteIfExists(listingFile.toPath()); - listingFile = new File(Files.move(tempContribFile.toPath(), tempContribFile.toPath().resolveSibling(listingFile.toPath())).toString()); - } catch (IOException e) { - e.printStackTrace(); - } - hasDownloadedLatestList = true; - hasListDownloadFailed = false; - setAdvertisedList(listingFile); - } - else - hasListDownloadFailed = true; - } downloadingListingLock.unlock(); } }, "Contribution List Downloader").start(); diff --git a/app/src/processing/app/contrib/ContributionManager.java b/app/src/processing/app/contrib/ContributionManager.java index 743378ac1..3749ad55a 100644 --- a/app/src/processing/app/contrib/ContributionManager.java +++ b/app/src/processing/app/contrib/ContributionManager.java @@ -24,6 +24,7 @@ package processing.app.contrib; import java.io.*; import java.net.*; import java.util.*; +import java.util.zip.GZIPOutputStream; import javax.swing.SwingWorker; @@ -45,27 +46,39 @@ public class ContributionManager { /** * Blocks until the file is downloaded or an error occurs. * - * @return true if the file was successfully downloaded, false otherwise. - * * @param source the URL of the file to download + * @param post Binary blob of POST data if a payload should be sent. + * Must already be URL-encoded and will be Gzipped for upload. * @param dest The file on the local system where the file will be written. * This must be a file (not a directory), and must already exist. * @param progress null if progress is irrelevant, such as when downloading * for an install during startup, when the ProgressMonitor * is useless since UI isn't setup yet. - * @throws FileNotFoundException if an error occurred downloading the file + * + * @return true if the file was successfully downloaded, false otherwise. */ - static boolean download(URL source, File dest, ContribProgressMonitor progress) { + static boolean download(URL source, byte[] post, + File dest, ContribProgressMonitor progress) { boolean success = false; try { -// System.out.println("downloading file " + source); -// URLConnection conn = source.openConnection(); + HttpURLConnection conn = (HttpURLConnection) source.openConnection(); HttpURLConnection.setFollowRedirects(true); conn.setConnectTimeout(15 * 1000); conn.setReadTimeout(60 * 1000); - conn.setRequestMethod("GET"); - conn.connect(); + + if (post == null) { + conn.setRequestMethod("GET"); + conn.connect(); + } else { + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setRequestProperty("Content-Encoding", "gzip"); + conn.setUseCaches(false); + conn.setDoInput(true); + conn.setDoOutput(true); + conn.getOutputStream().write(gzipEncode(post)); + } if (progress != null) { // TODO this is often -1, may need to set progress to indeterminate @@ -116,6 +129,15 @@ public class ContributionManager { } + static private byte[] gzipEncode(byte[] what) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + GZIPOutputStream output = new GZIPOutputStream(baos); + PApplet.saveStream(output, new ByteArrayInputStream(what)); + output.close(); + return baos.toByteArray(); + } + + /** * Non-blocking call to download and install a contribution in a new thread. * @@ -143,7 +165,7 @@ public class ContributionManager { contribZip.setWritable(true); // necessary? try { - download(url, contribZip, downloadProgress); + download(url, null, contribZip, downloadProgress); if (!downloadProgress.isCanceled() && !downloadProgress.isError()) { installProgress.startTask(Language.text("contrib.progress.installing"), ContribProgressMonitor.UNKNOWN); @@ -230,7 +252,7 @@ public class ContributionManager { contribZip.setWritable(true); // necessary? try { - download(url, contribZip, null); + download(url, null, contribZip, null); LocalContribution contribution = ad.install(base, contribZip, false, null); @@ -361,7 +383,7 @@ public class ContributionManager { isPrevDone = false; - download(url, contribZip, null); + download(url, null, contribZip, null); String arg = "contrib.import.progress.install"; base.getActiveEditor().statusNotice(Language.interpolate(arg,ad.name));