package org.openslx.thrifthelper; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolException; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TTransport; /** * Binary protocol implementation for thrift. * Will not read messages bigger than 12MiB. * */ public class TBinaryProtocolSafe extends TBinaryProtocol { /** * Factory */ @SuppressWarnings( "serial" ) public static class Factory implements TProtocolFactory { protected boolean strictRead_ = false; protected boolean strictWrite_ = true; public Factory() { this( false, true ); } public Factory(boolean strictRead, boolean strictWrite) { strictRead_ = strictRead; strictWrite_ = strictWrite; } public TProtocol getProtocol( TTransport trans ) { return new TBinaryProtocolSafe( trans, strictRead_, strictWrite_ ); } } private static final int maxLen = 12 * 1024 * 1024; // 12 MiB /** * Constructor */ public TBinaryProtocolSafe(TTransport trans) { this( trans, false, true ); } public TBinaryProtocolSafe(TTransport trans, boolean strictRead, boolean strictWrite) { super( trans ); strictRead_ = strictRead; strictWrite_ = strictWrite; } /** * Reading methods. */ public TMessage readMessageBegin() throws TException { int size = readI32(); if ( size > maxLen ) throw new TProtocolException( TProtocolException.SIZE_LIMIT, "Payload too big." ); if ( size < 0 ) { int version = size & VERSION_MASK; if ( version != VERSION_1 ) { throw new TProtocolException( TProtocolException.BAD_VERSION, "Bad version in readMessageBegin" ); } return new TMessage( readString(), (byte) ( size & 0x000000ff ), readI32() ); } else { if ( strictRead_ ) { throw new TProtocolException( TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?" ); } return new TMessage( readStringBody( size ), readByte(), readI32() ); } } public String readString() throws TException { int size = readI32(); if ( size > maxLen ) throw new TProtocolException( TProtocolException.SIZE_LIMIT, "Payload too big." ); if ( trans_.getBytesRemainingInBuffer() >= size ) { try { String s = new String( trans_.getBuffer(), trans_.getBufferPosition(), size, "UTF-8" ); trans_.consumeBuffer( size ); return s; } catch ( UnsupportedEncodingException e ) { throw new TException( "JVM DOES NOT SUPPORT UTF-8" ); } } return readStringBody( size ); } public ByteBuffer readBinary() throws TException { int size = readI32(); if ( size > maxLen ) throw new TProtocolException( TProtocolException.SIZE_LIMIT, "Payload too big." ); if ( trans_.getBytesRemainingInBuffer() >= size ) { ByteBuffer bb = ByteBuffer.wrap( trans_.getBuffer(), trans_.getBufferPosition(), size ); trans_.consumeBuffer( size ); return bb; } byte[] buf = new byte[ size ]; trans_.readAll( buf, 0, size ); return ByteBuffer.wrap( buf ); } }