/* * [Unwrap.java] * * Summary: Unwraps an object shipped via HTTP CGI-POST. * * Copyright: (c) 2006-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.4 2006-03-05 reformat with IntelliJ and add Javadoc. */ package com.mindprod.transporter; import com.mindprod.base64.Base64u; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.zip.GZIPInputStream; /** * Unwraps an object shipped via HTTP CGI-POST. *

* The Object is serialised, compressed, and Base64u armoured. *

* No encryption or digital * signing. See Transporter.java for example of use. * * @author Roedy Green, Canadian Mind Products * @version 1.4 2006-03-05 reformat with IntelliJ and add Javadoc. * @since 2006 */ public class Unwrap { /** * used to help remove ASCII armouring. */ private final Base64u disarmourer; /** * constructor */ public Unwrap() { disarmourer = new Base64u(); disarmourer.setLineLength( Integer.MAX_VALUE ); disarmourer.setLineSeparator( "\n" ); } /** * Decompress message. * * @param message GZIPPed to be decompressed. * * @return message decompressed. * @throws IOException if cannot decompress the message */ protected byte[] decompress( byte[] message ) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream( message ); GZIPInputStream gzis = new GZIPInputStream( bais, 4096/* buffsize */ ); ArrayList v = new ArrayList<>( 11 ); // if all goes well, we will do this all in one read. // length read of -1 marks EOF. int decompressedLength; do { // R E A D byte[] decompressedBlock = new byte[ Tools.TYPICAL_MESSAGE_SIZE ]; decompressedLength = gzis.read( decompressedBlock, 0 /* offset */, Tools.TYPICAL_MESSAGE_SIZE /* bytes to read */ ); if ( decompressedLength <= 0 ) { // nothing or -= eof } else if ( decompressedLength < Tools.TYPICAL_MESSAGE_SIZE ) { v.add( Tools .subarray( decompressedBlock, 0, decompressedLength ) ); } else { v.add( decompressedBlock ); } } while ( decompressedLength >= 0 ); // C L O S E gzis.close(); // glue all the blocks read together. return Tools.join( v ); } /** * remove ASCII base64u armouring from a Base64u encoded message. * * @param armoured armoured Base64u string. * * @return raw bytes of message.. */ protected byte[] disarmour( String armoured ) { return disarmourer.decode( armoured ); } /** * reconstitute a serializsed object * * @param pickled pickled object's bytes * * @return reconstituted object * @throws IOException */ protected Serializable reconstitute( byte[] pickled ) throws IOException { try {// O P E N ByteArrayInputStream bais = new ByteArrayInputStream( pickled ); ObjectInputStream ois = new ObjectInputStream( bais ); // R E A D Serializable o = ( Serializable ) ois.readObject(); // C L O S E ois.close(); return o; } catch ( ClassNotFoundException e ) { throw new IOException( "Corrupt ObjectStream " + e.getMessage() ); } } /** * unwraps an armoured, compressed, serialised object. does not parse parm=value. * * @param s base64u string. * * @return reconstituted object. * @throws IOException if cannot unwrap the message ) */ public Serializable unwrap( String s ) throws IOException { return reconstitute( decompress( disarmour( s ) ) ); } }