From 7b72fca3c2d023db4c067950f7e336bd863cfc6d Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Tue, 21 Apr 2015 14:29:30 +0200 Subject: [PATCH] +htc introduce big endian read methods to ByteReader --- .../src/main/scala/akka/http/util/ByteReader.scala | 12 ++++++++++-- akka-http/src/main/scala/akka/http/coding/Gzip.scala | 8 ++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/akka-http-core/src/main/scala/akka/http/util/ByteReader.scala b/akka-http-core/src/main/scala/akka/http/util/ByteReader.scala index e68b867719..d9043e4946 100644 --- a/akka-http-core/src/main/scala/akka/http/util/ByteReader.scala +++ b/akka-http-core/src/main/scala/akka/http/util/ByteReader.scala @@ -18,6 +18,8 @@ private[akka] class ByteReader(input: ByteString) { private[this] var off = 0 + def hasRemaining: Boolean = off < input.size + def currentOffset: Int = off def remainingData: ByteString = input.drop(off) def fromStartToHere: ByteString = input.take(currentOffset) @@ -28,8 +30,14 @@ private[akka] class ByteReader(input: ByteString) { off += 1 x.toInt & 0xFF } else throw NeedMoreData - def readShort(): Int = readByte() | (readByte() << 8) - def readInt(): Int = readShort() | (readShort() << 16) + def readShortLE(): Int = readByte() | (readByte() << 8) + def readIntLE(): Int = readShortLE() | (readShortLE() << 16) + def readLongLE(): Long = (readIntBE() & 0xffffffffL) | ((readIntLE() & 0xffffffffL) << 32) + + def readShortBE(): Int = (readByte() << 8) | readByte() + def readIntBE(): Int = (readShortBE() << 16) | readShortBE() + def readLongBE(): Long = ((readIntBE() & 0xffffffffL) << 32) | (readIntBE() & 0xffffffffL) + def skip(numBytes: Int): Unit = if (off + numBytes <= input.length) off += numBytes else throw NeedMoreData diff --git a/akka-http/src/main/scala/akka/http/coding/Gzip.scala b/akka-http/src/main/scala/akka/http/coding/Gzip.scala index bb7cda0dae..f755502f42 100644 --- a/akka-http/src/main/scala/akka/http/coding/Gzip.scala +++ b/akka-http/src/main/scala/akka/http/coding/Gzip.scala @@ -88,10 +88,10 @@ class GzipDecompressor(maxBytesPerChunk: Int = Decoder.MaxBytesPerChunkDefault) if (readByte() != 8) fail("Unsupported GZIP compression method") // check compression method val flags = readByte() skip(6) // skip MTIME, XFL and OS fields - if ((flags & 4) > 0) skip(readShort()) // skip optional extra fields + if ((flags & 4) > 0) skip(readShortLE()) // skip optional extra fields if ((flags & 8) > 0) skipZeroTerminatedString() // skip optional file name if ((flags & 16) > 0) skipZeroTerminatedString() // skip optional file comment - if ((flags & 2) > 0 && crc16(fromStartToHere) != readShort()) fail("Corrupt GZIP header") + if ((flags & 2) > 0 && crc16(fromStartToHere) != readShortLE()) fail("Corrupt GZIP header") inflater.reset() crc32.reset() @@ -107,8 +107,8 @@ class GzipDecompressor(maxBytesPerChunk: Int = Decoder.MaxBytesPerChunkDefault) def read(reader: ByteReader, ctx: Context[ByteString]): SyncDirective = { import reader._ - if (readInt() != crc32.getValue.toInt) fail("Corrupt data (CRC32 checksum error)") - if (readInt() != inflater.getBytesWritten.toInt /* truncated to 32bit */ ) fail("Corrupt GZIP trailer ISIZE") + if (readIntLE() != crc32.getValue.toInt) fail("Corrupt data (CRC32 checksum error)") + if (readIntLE() != inflater.getBytesWritten.toInt /* truncated to 32bit */ ) fail("Corrupt GZIP trailer ISIZE") becomeWithRemaining(Initial, remainingData, ctx) }