Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Unified Diff: blimp/net/compressed_packet_reader.cc

Issue 1825263003: Blimp: add packet-level DEFLATE compression using zlib. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Return net::Error values for Compress()/Decompress() Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: blimp/net/compressed_packet_reader.cc
diff --git a/blimp/net/compressed_packet_reader.cc b/blimp/net/compressed_packet_reader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b5773941e729b97e0f4340f0e643e51313a5f63c
--- /dev/null
+++ b/blimp/net/compressed_packet_reader.cc
@@ -0,0 +1,109 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "blimp/net/compressed_packet_reader.h"
+
+#include <iostream>
+
+#include "base/callback_helpers.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/sys_byteorder.h"
+#include "blimp/net/common.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/socket/stream_socket.h"
+
+namespace blimp {
+
+CompressedPacketReader::CompressedPacketReader(scoped_ptr<PacketReader> source)
+ : source_(std::move(source)),
+ compressed_buf_(new net::GrowableIOBuffer),
+ weak_factory_(this) {
+ DCHECK(source_);
+
+ memset(&zlib_stream_, 0, sizeof(z_stream));
+
+ // MAX_WBITS means we are using the maximal window size for decompression;
+ // a negative value means that we are ignoring headers and CRC checks.
+ int err = inflateInit2(&zlib_stream_, -MAX_WBITS);
Wez 2016/03/29 00:45:39 nit: |init_result|?
Kevin M 2016/03/29 01:25:55 Done.
+ DCHECK_EQ(err, Z_OK);
Wez 2016/03/29 00:45:39 nit: Suggest DCHECK_EQ(Z_OK, err)
Kevin M 2016/03/29 01:25:55 Done.
+}
+
+CompressedPacketReader::~CompressedPacketReader() {
+ inflateEnd(&zlib_stream_);
+}
+
+void CompressedPacketReader::ReadPacket(
+ const scoped_refptr<net::GrowableIOBuffer>& decompressed_buf,
+ const net::CompletionCallback& cb) {
Wez 2016/03/29 00:45:39 nit: |callback|, here and below.
Kevin M 2016/03/29 01:25:55 Done.
+ DCHECK(decompressed_buf);
+ DCHECK(!cb.is_null());
+ source_->ReadPacket(
+ compressed_buf_,
+ base::Bind(&CompressedPacketReader::ReadCompressedPacketDone,
+ weak_factory_.GetWeakPtr(), decompressed_buf, cb));
+}
+
+void CompressedPacketReader::ReadCompressedPacketDone(
+ const scoped_refptr<net::GrowableIOBuffer> decompressed_buf,
+ const net::CompletionCallback& cb,
+ int result) {
+ if (result <= 0) {
+ cb.Run(result);
+ return;
+ }
+
+ cb.Run(DecompressPacket(compressed_buf_->data(), result, decompressed_buf));
+}
+
+int CompressedPacketReader::DecompressPacket(
+ char* compressed,
+ int compressed_size,
+ const scoped_refptr<net::GrowableIOBuffer>& decompressed) {
+ // Read the size of the uncompressed data from the block heading.
+ size_t decompressed_size =
+ base::NetToHost32(*reinterpret_cast<uint32_t*>(compressed));
Wez 2016/03/29 00:45:39 Don't you need to check that |compressed_size| is
Kevin M 2016/03/29 01:25:55 Done.
+ if (decompressed_size == 0) {
+ // Empty payload - nothing to do.
Wez 2016/03/29 00:45:39 Why would we allow an empty but compressed-looking
Kevin M 2016/03/29 01:25:55 Good question. Done.
+ return 0;
+ }
+ if (decompressed_size > kMaxPacketPayloadSizeBytes) {
+ // Payload is too large.
+ return net::ERR_FILE_TOO_BIG;
+ }
+ if (static_cast<uint32_t>(decompressed->capacity()) < decompressed_size) {
Wez 2016/03/29 00:45:39 nit: Don't abutt this buffer-resize logic into the
Kevin M 2016/03/29 01:25:55 Done.
+ decompressed->SetCapacity(decompressed_size);
+ }
+
+ zlib_stream_.next_in =
+ reinterpret_cast<uint8_t*>(compressed + sizeof(uint32_t));
+ zlib_stream_.avail_in =
+ static_cast<unsigned>(compressed_size - sizeof(uint32_t));
Wez 2016/03/29 00:45:39 unsigned what? What about using a safe type-conve
Kevin M 2016/03/29 01:25:55 Done.
+ zlib_stream_.next_out = reinterpret_cast<uint8_t*>(decompressed->data());
+ zlib_stream_.avail_out = decompressed_size;
+ int err = inflate(&zlib_stream_, Z_SYNC_FLUSH);
Wez 2016/03/29 00:45:39 nit: |inflate_result|
Kevin M 2016/03/29 01:25:55 Done.
+ if (err != Z_OK) {
+ DLOG(ERROR) << "inflate() returned unexpected error code: " << err;
+ return net::ERR_UNEXPECTED;
+ }
+
+ // Verify that the decompressed block size is a perfect fit for the output
+ // buffer.
+ if (zlib_stream_.avail_in > 0) {
Wez 2016/03/29 00:45:40 This provides us a mechanism for telling when our
Kevin M 2016/03/29 01:25:55 I was on the fence about this. I favored the simpl
Kevin M 2016/03/29 20:36:23 Done. Removed the payload header size. Instead of
+ DLOG(ERROR) << "Decompressed payload is larger than expected size ("
+ << decompressed_size << " bytes.)";
+ return net::ERR_FILE_TOO_BIG;
+ }
+ if (zlib_stream_.avail_out > 0) {
+ DLOG(ERROR) << "Unexpected end of compressed block, num of extra bytes: "
+ << zlib_stream_.avail_out;
+ return net::ERR_UNEXPECTED;
+ }
+
+ return decompressed_size;
+}
+
+} // namespace blimp

Powered by Google App Engine
This is Rietveld 408576698