From 2f3cdca12d262d6208cc6e8f76e93a7464ee616a Mon Sep 17 00:00:00 2001 From: Graham Date: Sat, 2 May 2020 22:43:30 +0100 Subject: [PATCH] Reduce use of temporary files The Resource::compress method already holds entire files in memory at once, as does the client-side loader. We might as well do the same on the server-side. Signed-off-by: Graham --- .../openrs2/asm/io/Pack200LibraryReader.kt | 19 ++++--------- .../openrs2/asm/io/Pack200LibraryWriter.kt | 23 +++++---------- .../openrs2/asm/io/SignedJarLibraryWriter.kt | 28 ++++++++++--------- .../java/dev/openrs2/crypto/Pkcs12KeyStore.kt | 7 ++--- 4 files changed, 31 insertions(+), 46 deletions(-) diff --git a/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryReader.kt b/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryReader.kt index b0504beb..0dbd0cf0 100644 --- a/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryReader.kt +++ b/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryReader.kt @@ -2,31 +2,24 @@ package dev.openrs2.asm.io import dev.openrs2.asm.classpath.Library import dev.openrs2.compress.gzip.Gzip +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream import java.io.InputStream -import java.nio.file.Files import java.util.jar.JarOutputStream import java.util.jar.Pack200 class Pack200LibraryReader : LibraryReader { override fun read(input: InputStream): Library { - val temp = Files.createTempFile(TEMP_PREFIX, JAR_SUFFIX) - try { + ByteArrayOutputStream().use { tempOutput -> Gzip.createHeaderlessInputStream(input).use { gzipInput -> - JarOutputStream(Files.newOutputStream(temp)).use { output -> - Pack200.newUnpacker().unpack(gzipInput, output) + JarOutputStream(tempOutput).use { jarOutput -> + Pack200.newUnpacker().unpack(gzipInput, jarOutput) } } - return Files.newInputStream(temp).use { tempInput -> + return ByteArrayInputStream(tempOutput.toByteArray()).use { tempInput -> JarLibraryReader().read(tempInput) } - } finally { - Files.deleteIfExists(temp) } } - - private companion object { - private const val TEMP_PREFIX = "tmp" - private const val JAR_SUFFIX = ".jar" - } } diff --git a/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryWriter.kt b/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryWriter.kt index cbf89d92..5c3f2077 100644 --- a/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryWriter.kt +++ b/asm/src/main/java/dev/openrs2/asm/io/Pack200LibraryWriter.kt @@ -3,31 +3,22 @@ package dev.openrs2.asm.io import dev.openrs2.asm.classpath.ClassPath import dev.openrs2.asm.classpath.Library import dev.openrs2.compress.gzip.Gzip +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream import java.io.OutputStream -import java.nio.file.Files import java.util.jar.JarInputStream import java.util.jar.Pack200 class Pack200LibraryWriter : LibraryWriter { override fun write(output: OutputStream, classPath: ClassPath, library: Library) { - val tempJar = Files.createTempFile(TEMP_PREFIX, JAR_SUFFIX) - try { - Files.newOutputStream(tempJar).use { tempOutput -> - JarLibraryWriter().write(tempOutput, classPath, library) - } + ByteArrayOutputStream().use { tempOutput -> + JarLibraryWriter().write(tempOutput, classPath, library) - JarInputStream(Files.newInputStream(tempJar)).use { input -> - Gzip.createHeaderlessOutputStream(output).use { gzip -> - Pack200.newPacker().pack(input, gzip) + return JarInputStream(ByteArrayInputStream(tempOutput.toByteArray())).use { jarInput -> + Gzip.createHeaderlessOutputStream(output).use { gzipOutput -> + Pack200.newPacker().pack(jarInput, gzipOutput) } } - } finally { - Files.deleteIfExists(tempJar) } } - - private companion object { - private const val TEMP_PREFIX = "tmp" - private const val JAR_SUFFIX = ".jar" - } } diff --git a/asm/src/main/java/dev/openrs2/asm/io/SignedJarLibraryWriter.kt b/asm/src/main/java/dev/openrs2/asm/io/SignedJarLibraryWriter.kt index 37da5d3e..525bf4f6 100644 --- a/asm/src/main/java/dev/openrs2/asm/io/SignedJarLibraryWriter.kt +++ b/asm/src/main/java/dev/openrs2/asm/io/SignedJarLibraryWriter.kt @@ -5,9 +5,11 @@ import dev.openrs2.asm.classpath.Library import dev.openrs2.crypto.Pkcs12KeyStore import dev.openrs2.util.io.DeterministicJarOutputStream import dev.openrs2.util.io.entries +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.InputStream import java.io.OutputStream import java.nio.file.Files -import java.nio.file.Path import java.util.jar.JarInputStream import java.util.jar.Manifest @@ -22,24 +24,24 @@ class SignedJarLibraryWriter( ManifestJarLibraryWriter(manifest).write(unsignedOutput, classPath, library) } - val signedJar = Files.createTempFile(TEMP_PREFIX, JAR_SUFFIX) - try { - keyStore.signJar(unsignedJar, signedJar) - repack(signedJar, output) - } finally { - Files.deleteIfExists(signedJar) + ByteArrayOutputStream().use { signedOutput -> + keyStore.signJar(unsignedJar, signedOutput) + + return ByteArrayInputStream(signedOutput.toByteArray()).use { signedInput -> + repack(signedInput, output) + } } } finally { Files.deleteIfExists(unsignedJar) } } - private fun repack(signedJar: Path, output: OutputStream) { - JarInputStream(Files.newInputStream(signedJar)).use { input -> - DeterministicJarOutputStream(output, input.manifest).use { output -> - for (entry in input.entries) { - output.putNextEntry(entry) - input.copyTo(output) + private fun repack(input: InputStream, output: OutputStream) { + JarInputStream(input).use { jarInput -> + DeterministicJarOutputStream(output, jarInput.manifest).use { jarOutput -> + for (entry in jarInput.entries) { + jarOutput.putNextEntry(entry) + jarInput.copyTo(jarOutput) } } } diff --git a/crypto/src/main/java/dev/openrs2/crypto/Pkcs12KeyStore.kt b/crypto/src/main/java/dev/openrs2/crypto/Pkcs12KeyStore.kt index e6fe3ae3..99cf3ddb 100644 --- a/crypto/src/main/java/dev/openrs2/crypto/Pkcs12KeyStore.kt +++ b/crypto/src/main/java/dev/openrs2/crypto/Pkcs12KeyStore.kt @@ -11,6 +11,7 @@ import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder import org.bouncycastle.util.BigIntegers +import java.io.OutputStream import java.nio.file.Files import java.nio.file.Path import java.security.KeyFactory @@ -28,11 +29,9 @@ class Pkcs12KeyStore private constructor(privateKeyEntry: KeyStore.PrivateKeyEnt .signerName(signerName) .build() - fun signJar(input: Path, output: Path) { + fun signJar(input: Path, output: OutputStream) { JarFile(input.toFile()).use { file -> - Files.newOutputStream(output).use { os -> - signer.sign(file, os) - } + signer.sign(file, output) } }