/* * Created on Dec 1, 2009 */ package craterstudio.indiespot.http; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import java.util.TreeSet; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import craterstudio.bytes.Hash; import craterstudio.func.OrderComparator; import craterstudio.io.FileUtil; import craterstudio.io.Streams; import craterstudio.misc.Compression; import craterstudio.misc.Compression.ArchiveEntry; import craterstudio.text.Text; import craterstudio.util.HighLevel; import craterstudio.util.concur.SimpleCountDownLatch; import jawnae.net.http.core.HttpRequest; import jawnae.net.http.core.HttpResponse; import jawnae.net.http.core.HttpService; import jawnae.net.http.core.StatusCode; import jawnae.net.http.impl.HttpServerUtil; public class JavaFourKayShrinkService extends HttpService { static final String PATH_TO_JDK = "/root/jdk1.6.0_18/bin/"; static final String ALTERNATIVE_BOOTCLASSPATH = "/home/indiespot/java-15-rt.jar"; static final File GENERATED_FILE_BASE = new File("/home/indiespot/http-files/4k/"); static final long EXEC_DELAY = 250; static Lock queue_lock = new ReentrantLock(); @Override public void servePOST(HttpRequest request, HttpResponse response) throws Exception { try { if (request.isMultiPartPost()) { request.processMultiPartPost(); } String sourcecode = request.getCurrent("sourcecode"); boolean isJarOnly = sourcecode == null; boolean fixed = request.getCurrentBoolean("fixed"); int reruns = request.getCurrentBoolean("randomize") ? 8 : 1; int maxSplit = request.getCurrentBoolean("randomize") ? 256 : 4; response.setStatusCode(StatusCode.OK); response.setKeepAlive(false); response.setTransferEncodingChunked(true); response.setContentType("text/html"); String className; if (isJarOnly) { className = "x"; } else { className = Text.between(sourcecode, "public class", "{"); if (className == null) HttpServerUtil.abort(response, "public class name not found"); className = className.trim(); if (Text.indexOfWhiteSpace(className) != -1) className = className.substring(0, Text.indexOfWhiteSpace(className)); if (className.isEmpty()) HttpServerUtil.abort(response, "class name not found"); if (className.contains("..")) HttpServerUtil.abort(response, "class name invalid"); if (Text.before(sourcecode, "class").contains("package")) HttpServerUtil.abort(response, "class must not be in a package"); } PrintStream html = response.createPrintStream(); html.append("
"); File javaFile = new File(GENERATED_FILE_BASE, className + ".java"); File classFile = new File(GENERATED_FILE_BASE, className + ".class"); if (sourcecode == null) sourcecode = Text.generateRandomCode(256); String downloadprefix = String.valueOf(Hash.toHex(Hash.md5(Text.utf8(sourcecode)))); if (className.equals("download")) throw new IllegalStateException(); int[] javaVersions = new int[] { /*5,*/6 }; String[] jarTypes = new String[] { "normal", "progrd" }; String[] compressors = new String[] { "7z", "kz", "bj" }; if (request.getCurrentBoolean("randomize")) { int delay = 90; for (int i = 0; i < delay; i++) { html.append(""); html.append("");
html.append(className + ".java => " + javaFile.length() + " bytes
");
html.append(className + ".class => " + classFile.length() + " bytes
");
for (int javaVersion : javaVersions)
{
for (String jarType : jarTypes)
{
File xJarFile = getTempResourceFilename(className, jarType, javaVersion, null, "jar");
File xPackFile = getTempResourceFilename(className, jarType, javaVersion, null, "pack");
html.append(xJarFile.getName() + " => " + xJarFile.length() + " bytes
");
html.append(xPackFile.getName() + " => " + xPackFile.length() + " bytes
");
}
}
class ResultEntry
{
File file;
String html;
}
TreeSet entries = new TreeSet(new OrderComparator()
{
public boolean areEqual(ResultEntry a, ResultEntry b)
{
return false;
}
public boolean isOrdered(ResultEntry a, ResultEntry b)
{
return a.file.length() < b.file.length();
}
});
for (int javaVersion : javaVersions)
{
for (String jarType : jarTypes)
{
for (String compressor : compressors)
{
File packGzFile = getDownloadPackGzFilename(downloadprefix, jarType, javaVersion, compressor);
if (!packGzFile.exists())
continue;
String htmlEntry = "";
htmlEntry += "" + Text.after(packGzFile.getName(), "download.") + " => "
+ packGzFile.length() + " bytes ";
htmlEntry += " => test
";
ResultEntry entry = new ResultEntry();
entry.file = packGzFile;
entry.html = htmlEntry;
entries.add(entry);
}
}
}
for (ResultEntry entry : entries)
{
html.append(entry.html);
}
html.flush();
}
}
finally
{
queue_lock.unlock();
javaFile.delete();
classFile.delete();
for (int javaVersion : javaVersions)
{
for (String jarType : jarTypes)
{
File xJarFile = getTempResourceFilename(className, jarType, javaVersion, null, "jar");
File xPackFile = getTempResourceFilename(className, jarType, javaVersion, null, "pack");
xJarFile.delete();
xPackFile.delete();
}
}
html.close();
}
}
catch (Exception exc)
{
exc.printStackTrace();
}
}
private static File getTempResourceFilename(String className, String jarType, int javaVersion, String compressorIfAny, String extension)
{
String filename = className + "." + jarType + ".java" + javaVersion + (compressorIfAny == null ? "" : ("." + compressorIfAny)) + "." +
extension;
return new File(GENERATED_FILE_BASE, filename);
}
private static File getDownloadPackGzFilename(String downloadprefix, String jarType, int javaVersion, String compressor)
{
String filename = "download." + downloadprefix + "." + jarType + ".java" + javaVersion + "." + compressor + ".pack.gz";
return new File(GENERATED_FILE_BASE, filename);
}
private static boolean source(PrintStream html, String sourcecode, File javaFile)
{
System.out.println("create file");
try
{
FileUtil.writeFile(javaFile, Text.utf8(sourcecode));
html.append("sourcecode
");
html.append("OK");
html.flush();
return true;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
}
private static boolean javac(PrintStream html, String caption, File base, File javaFile, String alternativeBootClasspath)
{
System.out.println("javac");
try
{
List cmds = new ArrayList();
cmds.add(PATH_TO_JDK + "javac");
cmds.add("-nowarn");
cmds.add("-target");
cmds.add("1.5");
if (alternativeBootClasspath != null)
{
cmds.add("-bootclasspath");
cmds.add(alternativeBootClasspath);
}
cmds.add("-g:none");
cmds.add("-sourcepath");
cmds.add(base.getAbsolutePath());
cmds.add("-d");
cmds.add(base.getAbsolutePath());
cmds.add(javaFile.getAbsolutePath());
HighLevel.sleep(EXEC_DELAY);
Process proc = Runtime.getRuntime().exec(cmds.toArray(new String[cmds.size()]));
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
Streams.asynchronousTransfer(proc.getInputStream(), stdout);
Streams.asynchronousTransfer(proc.getErrorStream(), stderr);
int exit = proc.waitFor();
html.append("" + caption + "
");
html.append("");
html.append("" + Text.utf8(stdout.toByteArray()) + "");
html.append("");
html.append("");
html.append("" + Text.utf8(stderr.toByteArray()) + "");
html.append("");
if (exit != 0)
html.append("Exit value: " + exit + "");
else
html.append("OK");
html.flush();
if (exit != 0)
return false;
return true;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
}
private static boolean jar(PrintStream html, String caption, File classFile, File jarFile)
{
System.out.println("jar[" + classFile + "=>" + jarFile + "]");
try
{
html.append("" + caption + "
");
html.append("OK");
List entries = new ArrayList();
entries.add(new ArchiveEntry(classFile, classFile.getName()));
Compression.zip(entries, jarFile, true);
html.flush();
return true;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
}
private static boolean proguard(PrintStream html, String caption, File normalJarFile, File progrdJarFile, boolean fixed)
{
System.out.println("proguard");
try
{
String[] cmds = new String[9];
cmds[0] = PATH_TO_JDK + "java";
cmds[1] = "-jar";
cmds[2] = "/home/indiespot/proguard.jar";
cmds[3] = "-include";
cmds[4] = "/home/indiespot/" + (fixed ? "proguard.fixed.conf" : "proguard.conf");
cmds[5] = "-injars";
cmds[6] = normalJarFile.getAbsolutePath();
cmds[7] = "-outjars";
cmds[8] = progrdJarFile.getAbsolutePath();
HighLevel.sleep(EXEC_DELAY);
Process proc = Runtime.getRuntime().exec(cmds);
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
Streams.asynchronousTransfer(proc.getInputStream(), stdout);
Streams.asynchronousTransfer(proc.getErrorStream(), stderr);
int exit = proc.waitFor();
html.append("" + caption + "
");
if (stderr.size() != 0)
{
html.append("");
html.append("" + Text.utf8(stdout.toByteArray()) + "");
html.append("");
html.append("");
html.append("" + Text.utf8(stderr.toByteArray()) + "");
html.append("");
}
if (exit != 0)
html.append("Exit value: " + exit + "");
else
html.append("OK");
html.flush();
if (exit != 0)
return false;
return true;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
}
private static boolean pack200(PrintStream html, String caption, File jarFile, File packFile)
{
System.out.println("pack200");
try
{
String[] cmds = new String[7];
cmds[0] = PATH_TO_JDK + "pack200";
cmds[1] = "--no-gzip";
cmds[2] = "--strip-debug";
cmds[3] = "--no-keep-file-order";
cmds[4] = "--effort=9";
cmds[5] = packFile.getAbsolutePath();
cmds[6] = jarFile.getAbsolutePath();
HighLevel.sleep(EXEC_DELAY);
Process proc = Runtime.getRuntime().exec(cmds);
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
Streams.asynchronousTransfer(proc.getInputStream(), stdout);
Streams.asynchronousTransfer(proc.getErrorStream(), stderr);
int exit = proc.waitFor();
html.append("" + caption + "
");
if (stderr.size() != 0)
{
html.append("");
html.append("" + Text.utf8(stdout.toByteArray()) + "");
html.append("");
html.append("");
html.append("" + Text.utf8(stderr.toByteArray()) + "");
html.append("");
}
if (exit != 0)
html.append("Exit value: " + exit + "");
else
html.append("OK:" + packFile.length() + "");
html.flush();
if (exit != 0)
return false;
return true;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
}
private static int bruteforceKzip(PrintStream html, String caption, File packFile, File packGzFile, int splitOffset, int splitStep, int steps, int
reruns) throws IOException
{
File min = packGzFile;
File[] dst = new File[steps];
int minSplit = -1;
for (int i = 0; i < dst.length; i++)
{
dst[i] = new File(packGzFile.getParentFile(), i + "_" + packGzFile.getName());
int split = splitOffset + i * splitStep;
for (int k = 0; k < reruns; k++)
{
if (kzip_deflopt_gz(html, caption, packFile, dst[i], split, k != 0))
{
if (dst[i].length() != 0 && ((min == null || min.length() == 0) || dst[i].length() < min.length()))
{
min = dst[i];
minSplit = split;
}
}
}
}
if (minSplit != -1)
FileUtil.copyFile(min, packGzFile);
for (int i = 0; i < dst.length; i++)
dst[i].delete();
return minSplit;
}
private static int bruteforceBjwflate(PrintStream html, String caption, File packFile, File packGzFile, int maxSplit) throws IOException
{
File min = packGzFile;
int minSplit = -1;
List dsts = new ArrayList();
for (int splitSize = 4, i = 0; splitSize <= maxSplit; splitSize += (splitSize <= 12 ? 4 : (splitSize <= 32 ? 8 : (splitSize <= 128 ? 16 :
32))), i++)
{
File dst = new File(packGzFile.getParentFile(), splitSize + "_" + packGzFile.getName());
if (bjwflate_deflopt_gz(html, caption, packFile, dst, splitSize, false))
{
if (dst.length() != 0 && ((min == null || min.length() == 0) || dst.length() < min.length()))
{
min = dst;
minSplit = splitSize;
}
}
}
if (minSplit != -1)
FileUtil.copyFile(min, packGzFile);
for (File dst : dsts)
dst.delete();
return minSplit;
}
public static boolean kzip_deflopt_gz(PrintStream html, String caption, File src, File dst, int splitSize, boolean rn)
{
System.out.println("kzip:" + splitSize + " @ " + System.currentTimeMillis());
File zip = new File(src.getParentFile(), src.getName() + ".zip");
File dir = new File(src.getParentFile(), "tmp_" + System.nanoTime());
dir.mkdir();
try
{
// kzip
try
{
FileUtil.copyFile(src, new File(dir, src.getName()));
String[] cmds = new String[rn ? 5 : 4];
cmds[0] = "/root/kzipmix-static/kzip-static";
cmds[1] = "-y";
cmds[2] = "-b" + splitSize;
if (rn)
cmds[3] = "-rn";
cmds[rn ? 4 : 3] = zip.getAbsolutePath();
HighLevel.sleep(EXEC_DELAY);
final Process proc = Runtime.getRuntime().exec(cmds, null, dir);
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
Streams.asynchronousTransfer(proc.getInputStream(), stdout);
Streams.asynchronousTransfer(proc.getErrorStream(), stderr);
final SimpleCountDownLatch latch = new SimpleCountDownLatch();
new Thread()
{
public void run()
{
if (!latch.await(2 * 1000))
{
proc.destroy();
}
}
}.start();
int exit = proc.waitFor();
latch.countDown();
if (splitSize == 0 && !rn)
html.append("" + caption + "
");
if (stderr.size() != 0)
{
html.append("");
html.append("" + Text.utf8(stdout.toByteArray()) + "");
html.append("");
html.append("");
html.append("" + Text.utf8(stderr.toByteArray()) + "");
html.append("");
}
if (exit != 0)
html.append("Exit value: " + exit + "");
html.flush();
if (exit != 0)
return false;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
// gz
try
{
zip2gz(new FileInputStream(zip), new FileOutputStream(dst));
html.append("OK ");
html.flush();
}
catch (IOException exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
return true;
}
finally
{
zip.delete();
FileUtil.deleteDirectory(dir, true);
}
}
public static boolean bjwflate_deflopt_gz(PrintStream html, String caption, File src, File dst, int splitSize, boolean noprep)
{
System.out.println("bjwflate:" + splitSize + " @ " + System.currentTimeMillis());
File zip = new File(src.getParentFile(), src.getName() + ".zip");
try
{
// bjwflate
try
{
String[] cmds = new String[noprep ? 6 : 5];
cmds[0] = "/usr/bin/wine";
cmds[1] = "/root/BJWFlate.exe";
cmds[2] = "-y";
if (noprep)
cmds[3] = "-n";
cmds[noprep ? 4 : 3] = zip.getAbsolutePath();
cmds[noprep ? 5 : 4] = src.getAbsolutePath();
HighLevel.sleep(EXEC_DELAY);
final Process proc = Runtime.getRuntime().exec(cmds, null);
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
Streams.asynchronousTransfer(proc.getInputStream(), stdout);
Streams.asynchronousTransfer(proc.getErrorStream(), stderr);
final SimpleCountDownLatch latch = new SimpleCountDownLatch();
new Thread()
{
public void run()
{
if (!latch.await(2 * 1000))
{
proc.destroy();
}
}
}.start();
int exit = proc.waitFor();
latch.countDown();
if (splitSize == 4)
html.append("" + caption + "
");
if (stderr.size() != 0)
{
html.append("");
html.append("" + Text.utf8(stdout.toByteArray()) + "");
html.append("");
html.append("");
html.append("" + Text.utf8(stderr.toByteArray()) + "");
html.append("");
}
if (exit != 0)
html.append("Exit value: " + exit + "");
html.flush();
if (exit != 0)
return false;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
// deflopt
{
//deflopt(html, zip);
}
// gz
try
{
zip2gz(new FileInputStream(zip), new FileOutputStream(dst));
html.append("OK ");
html.flush();
}
catch (IOException exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
return true;
}
finally
{
zip.delete();
}
}
public static boolean gz_7z(PrintStream html, String caption, File src, File dst)
{
System.out.println("7z");
try
{
String[] cmds = new String[4];
cmds[0] = "/root/p7zip_9.04/bin/7z";
cmds[1] = "a";
cmds[2] = dst.getAbsolutePath();
cmds[3] = src.getAbsolutePath();
HighLevel.sleep(EXEC_DELAY);
Process proc = Runtime.getRuntime().exec(cmds);
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
Streams.asynchronousTransfer(proc.getInputStream(), stdout);
Streams.asynchronousTransfer(proc.getErrorStream(), stderr);
int exit = proc.waitFor();
html.append("" + caption + "
");
if (stderr.size() != 0)
{
html.append("");
html.append("" + Text.utf8(stdout.toByteArray()) + "");
html.append("");
html.append("");
html.append("" + Text.utf8(stderr.toByteArray()) + "");
html.append("");
}
if (exit != 0)
html.append("Exit value: " + exit + "");
else
html.append("OK");
html.flush();
if (exit != 0)
return false;
return true;
}
catch (Exception exc)
{
html.append("");
html.append("EXCEPTION: " + exc.getClass().getName() + "");
html.append("");
html.flush();
exc.printStackTrace();
return false;
}
}
public static void zip2gz(InputStream in, OutputStream out) throws IOException
{
in = new BufferedInputStream(in);
out = new BufferedOutputStream(out);
out.write(0x1f);
out.write(0x8b);
out.write(0x08);
out.write(0x00);
out.write(0x00);
out.write(0x00);
out.write(0x00);
out.write(0x00);
out.write(0x00);
out.write(0xff);
for (int i = 0; i < 14; i++)
in.read();
int crc1 = in.read();
int crc2 = in.read();
int crc3 = in.read();
int crc4 = in.read();
int cmpSz = (in.read() & 0xff) + ((in.read() & 0xff) << 8) + ((in.read() & 0xff) << 16) + ((in.read() & 0xff) << 24);
int ucmpSz1 = in.read();
int ucmpSz2 = in.read();
int ucmpSz3 = in.read();
int ucmpSz4 = in.read();
int nameLen = (in.read() & 0xff) + ((in.read() & 0xff) << 8);
int xfLen = (in.read() & 0xff) + ((in.read() & 0xff) << 8);
for (int i = 0; i < nameLen; i++)
in.read();
for (int i = 0; i < xfLen; i++)
in.read();
byte[] buf = new byte[4096];
while (cmpSz > 0)
{
int desired = cmpSz > buf.length ? buf.length : cmpSz;
int len = in.read(buf, 0, desired);
if (len == 0)
throw new EOFException();
out.write(buf, 0, len);
cmpSz -= len;
}
out.write(crc1);
out.write(crc2);
out.write(crc3);
out.write(crc4);
out.write(ucmpSz1);
out.write(ucmpSz2);
out.write(ucmpSz3);
out.write(ucmpSz4);
out.close();
in.close();
}
}