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

Side by Side Diff: net/filter/brotli_source_stream.cc

Issue 2537133002: Update brotli to v1.0.0-snapshot. (Closed)
Patch Set: Created 4 years 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/filter/brotli_source_stream.h" 5 #include "net/filter/brotli_source_stream.h"
6 6
7 #include <brotli/decode.h>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/bit_cast.h" 10 #include "base/bit_cast.h"
9 #include "base/logging.h" 11 #include "base/logging.h"
10 #include "base/macros.h" 12 #include "base/macros.h"
11 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
12 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
13 #include "net/base/io_buffer.h" 15 #include "net/base/io_buffer.h"
14 #include "third_party/brotli/dec/decode.h"
15 16
16 namespace net { 17 namespace net {
17 18
18 namespace { 19 namespace {
19 20
20 const char kBrotli[] = "BROTLI"; 21 const char kBrotli[] = "BROTLI";
21 const uint8_t kGzipHeader[] = {0x1f, 0x8b, 0x08}; 22 const uint8_t kGzipHeader[] = {0x1f, 0x8b, 0x08};
22 23
23 // BrotliSourceStream applies Brotli content decoding to a data stream. 24 // BrotliSourceStream applies Brotli content decoding to a data stream.
24 // Brotli format specification: http://www.ietf.org/id/draft-alakuijala-brotli. 25 // Brotli format specification: http://www.ietf.org/id/draft-alakuijala-brotli.
25 class BrotliSourceStream : public FilterSourceStream { 26 class BrotliSourceStream : public FilterSourceStream {
26 public: 27 public:
27 explicit BrotliSourceStream(std::unique_ptr<SourceStream> upstream) 28 explicit BrotliSourceStream(std::unique_ptr<SourceStream> upstream)
28 : FilterSourceStream(SourceStream::TYPE_BROTLI, std::move(upstream)), 29 : FilterSourceStream(SourceStream::TYPE_BROTLI, std::move(upstream)),
29 decoding_status_(DecodingStatus::DECODING_IN_PROGRESS), 30 decoding_status_(DecodingStatus::DECODING_IN_PROGRESS),
30 used_memory_(0), 31 used_memory_(0),
31 used_memory_maximum_(0), 32 used_memory_maximum_(0),
32 consumed_bytes_(0), 33 consumed_bytes_(0),
33 produced_bytes_(0), 34 produced_bytes_(0),
34 gzip_header_detected_(true) { 35 gzip_header_detected_(true) {
35 brotli_state_ = BrotliCreateState(AllocateMemory, FreeMemory, this); 36 brotli_state_ =
37 BrotliDecoderCreateInstance(AllocateMemory, FreeMemory, this);
36 CHECK(brotli_state_); 38 CHECK(brotli_state_);
37 } 39 }
38 40
39 ~BrotliSourceStream() override { 41 ~BrotliSourceStream() override {
40 BrotliErrorCode error_code = BrotliGetErrorCode(brotli_state_); 42 BrotliDecoderErrorCode error_code =
41 BrotliDestroyState(brotli_state_); 43 BrotliDecoderGetErrorCode(brotli_state_);
44 BrotliDecoderDestroyInstance(brotli_state_);
42 brotli_state_ = nullptr; 45 brotli_state_ = nullptr;
43 DCHECK_EQ(0u, used_memory_); 46 DCHECK_EQ(0u, used_memory_);
44 47
45 // Don't report that gzip header was detected in case of lack of input. 48 // Don't report that gzip header was detected in case of lack of input.
46 gzip_header_detected_ &= (consumed_bytes_ >= sizeof(kGzipHeader)); 49 gzip_header_detected_ &= (consumed_bytes_ >= sizeof(kGzipHeader));
47 50
48 UMA_HISTOGRAM_ENUMERATION( 51 UMA_HISTOGRAM_ENUMERATION(
49 "BrotliFilter.Status", static_cast<int>(decoding_status_), 52 "BrotliFilter.Status", static_cast<int>(decoding_status_),
50 static_cast<int>(DecodingStatus::DECODING_STATUS_COUNT)); 53 static_cast<int>(DecodingStatus::DECODING_STATUS_COUNT));
51 UMA_HISTOGRAM_BOOLEAN("BrotliFilter.GzipHeaderDetected", 54 UMA_HISTOGRAM_BOOLEAN("BrotliFilter.GzipHeaderDetected",
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 return OK; 101 return OK;
99 } 102 }
100 103
101 if (decoding_status_ != DecodingStatus::DECODING_IN_PROGRESS) 104 if (decoding_status_ != DecodingStatus::DECODING_IN_PROGRESS)
102 return ERR_CONTENT_DECODING_FAILED; 105 return ERR_CONTENT_DECODING_FAILED;
103 106
104 const uint8_t* next_in = bit_cast<uint8_t*>(input_buffer->data()); 107 const uint8_t* next_in = bit_cast<uint8_t*>(input_buffer->data());
105 size_t available_in = input_buffer_size; 108 size_t available_in = input_buffer_size;
106 uint8_t* next_out = bit_cast<uint8_t*>(output_buffer->data()); 109 uint8_t* next_out = bit_cast<uint8_t*>(output_buffer->data());
107 size_t available_out = output_buffer_size; 110 size_t available_out = output_buffer_size;
108 size_t total_out = 0;
109 // Check if start of the input stream looks like gzip stream. 111 // Check if start of the input stream looks like gzip stream.
110 for (size_t i = consumed_bytes_; i < sizeof(kGzipHeader); ++i) { 112 for (size_t i = consumed_bytes_; i < sizeof(kGzipHeader); ++i) {
111 if (!gzip_header_detected_) 113 if (!gzip_header_detected_)
112 break; 114 break;
113 size_t j = i - consumed_bytes_; 115 size_t j = i - consumed_bytes_;
114 if (j < available_in && kGzipHeader[i] != next_in[j]) 116 if (j < available_in && kGzipHeader[i] != next_in[j])
115 gzip_header_detected_ = false; 117 gzip_header_detected_ = false;
116 } 118 }
117 119
118 BrotliResult result = 120 BrotliDecoderResult result =
119 BrotliDecompressStream(&available_in, &next_in, &available_out, 121 BrotliDecoderDecompressStream(brotli_state_, &available_in, &next_in,
120 &next_out, &total_out, brotli_state_); 122 &available_out, &next_out, nullptr);
121 123
122 size_t bytes_used = input_buffer_size - available_in; 124 size_t bytes_used = input_buffer_size - available_in;
123 size_t bytes_written = output_buffer_size - available_out; 125 size_t bytes_written = output_buffer_size - available_out;
124 CHECK_GE(bytes_used, 0u); 126 CHECK_GE(bytes_used, 0u);
125 CHECK_GE(bytes_written, 0u); 127 CHECK_GE(bytes_written, 0u);
126 produced_bytes_ += bytes_written; 128 produced_bytes_ += bytes_written;
127 consumed_bytes_ += bytes_used; 129 consumed_bytes_ += bytes_used;
128 130
129 *consumed_bytes = bytes_used; 131 *consumed_bytes = bytes_used;
130 132
131 switch (result) { 133 switch (result) {
132 case BROTLI_RESULT_NEEDS_MORE_OUTPUT: 134 case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:
133 return bytes_written; 135 return bytes_written;
134 case BROTLI_RESULT_SUCCESS: 136 case BROTLI_DECODER_RESULT_SUCCESS:
135 decoding_status_ = DecodingStatus::DECODING_DONE; 137 decoding_status_ = DecodingStatus::DECODING_DONE;
136 // Consume remaining bytes to avoid DCHECK in FilterSourceStream. 138 // Consume remaining bytes to avoid DCHECK in FilterSourceStream.
137 // See crbug.com/659311. 139 // See crbug.com/659311.
138 *consumed_bytes = input_buffer_size; 140 *consumed_bytes = input_buffer_size;
139 return bytes_written; 141 return bytes_written;
140 case BROTLI_RESULT_NEEDS_MORE_INPUT: 142 case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
141 // Decompress needs more input has consumed all existing input. 143 // Decompress needs more input has consumed all existing input.
142 DCHECK_EQ(*consumed_bytes, input_buffer_size); 144 DCHECK_EQ(*consumed_bytes, input_buffer_size);
143 decoding_status_ = DecodingStatus::DECODING_IN_PROGRESS; 145 decoding_status_ = DecodingStatus::DECODING_IN_PROGRESS;
144 return bytes_written; 146 return bytes_written;
145 // If the decompressor threw an error, fail synchronously. 147 // If the decompressor threw an error, fail synchronously.
146 default: 148 default:
147 decoding_status_ = DecodingStatus::DECODING_ERROR; 149 decoding_status_ = DecodingStatus::DECODING_ERROR;
148 return ERR_CONTENT_DECODING_FAILED; 150 return ERR_CONTENT_DECODING_FAILED;
149 } 151 }
150 } 152 }
(...skipping 20 matching lines...) Expand all
171 } 173 }
172 174
173 void FreeMemoryInternal(void* address) { 175 void FreeMemoryInternal(void* address) {
174 if (!address) 176 if (!address)
175 return; 177 return;
176 size_t* array = reinterpret_cast<size_t*>(address); 178 size_t* array = reinterpret_cast<size_t*>(address);
177 used_memory_ -= array[-1]; 179 used_memory_ -= array[-1];
178 free(&array[-1]); 180 free(&array[-1]);
179 } 181 }
180 182
181 BrotliState* brotli_state_; 183 BrotliDecoderState* brotli_state_;
182 184
183 DecodingStatus decoding_status_; 185 DecodingStatus decoding_status_;
184 186
185 size_t used_memory_; 187 size_t used_memory_;
186 size_t used_memory_maximum_; 188 size_t used_memory_maximum_;
187 size_t consumed_bytes_; 189 size_t consumed_bytes_;
188 size_t produced_bytes_; 190 size_t produced_bytes_;
189 191
190 bool gzip_header_detected_; 192 bool gzip_header_detected_;
191 193
192 DISALLOW_COPY_AND_ASSIGN(BrotliSourceStream); 194 DISALLOW_COPY_AND_ASSIGN(BrotliSourceStream);
193 }; 195 };
194 196
195 } // namespace 197 } // namespace
196 198
197 std::unique_ptr<FilterSourceStream> CreateBrotliSourceStream( 199 std::unique_ptr<FilterSourceStream> CreateBrotliSourceStream(
198 std::unique_ptr<SourceStream> previous) { 200 std::unique_ptr<SourceStream> previous) {
199 return base::WrapUnique(new BrotliSourceStream(std::move(previous))); 201 return base::WrapUnique(new BrotliSourceStream(std::move(previous)));
200 } 202 }
201 203
202 } // namespace net 204 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698