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

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

Issue 1995513002: Add more BrotliFilter information to UMA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More correct enum->int conversion Created 4 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_filter.h" 5 #include "net/filter/brotli_filter.h"
6 6
7 #include "base/bit_cast.h" 7 #include "base/bit_cast.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/numerics/safe_conversions.h" 10 #include "base/numerics/safe_conversions.h"
11 #include "base/numerics/safe_math.h" 11 #include "base/numerics/safe_math.h"
12 #include "third_party/brotli/dec/decode.h" 12 #include "third_party/brotli/dec/decode.h"
13 13
14 namespace net { 14 namespace net {
15 15
16 namespace {
17 const uint8_t kGzipHeader[] = {0x1f, 0x8b, 0x08};
18 }
19
16 // BrotliFilter applies Brotli content decoding to a data stream. 20 // BrotliFilter applies Brotli content decoding to a data stream.
17 // Brotli format specification: http://www.ietf.org/id/draft-alakuijala-brotli 21 // Brotli format specification: http://www.ietf.org/id/draft-alakuijala-brotli
18 // 22 //
19 // BrotliFilter is a subclass of Filter. See the latter's header file filter.h 23 // BrotliFilter is a subclass of Filter. See the latter's header file filter.h
20 // for sample usage. 24 // for sample usage.
21 class BrotliFilter : public Filter { 25 class BrotliFilter : public Filter {
22 public: 26 public:
23 BrotliFilter(FilterType type) 27 BrotliFilter(FilterType type)
24 : Filter(type), 28 : Filter(type),
25 decoding_status_(DecodingStatus::DECODING_IN_PROGRESS), 29 decoding_status_(DecodingStatus::DECODING_IN_PROGRESS),
26 used_memory_(0), 30 used_memory_(0),
27 used_memory_maximum_(0), 31 used_memory_maximum_(0),
28 consumed_bytes_(0), 32 consumed_bytes_(0),
29 produced_bytes_(0) { 33 produced_bytes_(0),
34 gzip_header_detected_(true) {
30 brotli_state_ = BrotliCreateState(BrotliFilter::AllocateMemory, 35 brotli_state_ = BrotliCreateState(BrotliFilter::AllocateMemory,
31 BrotliFilter::FreeMemory, this); 36 BrotliFilter::FreeMemory, this);
32 CHECK(brotli_state_); 37 CHECK(brotli_state_);
33 } 38 }
34 39
35 ~BrotliFilter() override { 40 ~BrotliFilter() override {
41 BrotliErrorCode error_code = BrotliGetErrorCode(brotli_state_);
36 BrotliDestroyState(brotli_state_); 42 BrotliDestroyState(brotli_state_);
37 brotli_state_ = nullptr; 43 brotli_state_ = nullptr;
38 DCHECK(used_memory_ == 0); 44 DCHECK(used_memory_ == 0);
39 45
46 // Don't report that gzip header was detected in case of lack of input.
47 gzip_header_detected_ &= (consumed_bytes_ >= sizeof(kGzipHeader));
48
40 UMA_HISTOGRAM_ENUMERATION( 49 UMA_HISTOGRAM_ENUMERATION(
41 "BrotliFilter.Status", static_cast<int>(decoding_status_), 50 "BrotliFilter.Status", static_cast<int>(decoding_status_),
42 static_cast<int>(DecodingStatus::DECODING_STATUS_COUNT)); 51 static_cast<int>(DecodingStatus::DECODING_STATUS_COUNT));
52 UMA_HISTOGRAM_BOOLEAN("BrotliFilter.GzipHeaderDetected",
53 static_cast<bool>(gzip_header_detected_));
cbentzel 2016/05/21 19:42:40 Why is this static_cast needed?
eustas 2016/05/23 09:46:23 It is a copy-paste leftover. Removed.
43 if (decoding_status_ == DecodingStatus::DECODING_DONE) { 54 if (decoding_status_ == DecodingStatus::DECODING_DONE) {
44 // CompressionPercent is undefined when there is no output produced. 55 // CompressionPercent is undefined when there is no output produced.
45 if (produced_bytes_ != 0) { 56 if (produced_bytes_ != 0) {
46 UMA_HISTOGRAM_PERCENTAGE( 57 UMA_HISTOGRAM_PERCENTAGE(
47 "BrotliFilter.CompressionPercent", 58 "BrotliFilter.CompressionPercent",
48 static_cast<int>((consumed_bytes_ * 100) / produced_bytes_)); 59 static_cast<int>((consumed_bytes_ * 100) / produced_bytes_));
49 } 60 }
50 } 61 }
62 if (error_code < 0) {
63 UMA_HISTOGRAM_ENUMERATION("BrotliFilter.ErrorCode",
64 -static_cast<int>(error_code),
65 1 - BROTLI_LAST_ERROR_CODE);
66 }
51 67
52 // All code here is for gathering stats, and can be removed when 68 // All code here is for gathering stats, and can be removed when
53 // BrotliFilter is considered stable. 69 // BrotliFilter is considered stable.
54 static const int kBuckets = 48; 70 static const int kBuckets = 48;
55 static const int64_t kMaxKb = 1 << (kBuckets / 3); // 64MiB in KiB 71 static const int64_t kMaxKb = 1 << (kBuckets / 3); // 64MiB in KiB
56 UMA_HISTOGRAM_CUSTOM_COUNTS("BrotliFilter.UsedMemoryKB", 72 UMA_HISTOGRAM_CUSTOM_COUNTS("BrotliFilter.UsedMemoryKB",
57 used_memory_maximum_ / 1024, 1, kMaxKb, 73 used_memory_maximum_ / 1024, 1, kMaxKb,
58 kBuckets); 74 kBuckets);
59 } 75 }
60 76
(...skipping 22 matching lines...) Expand all
83 return Filter::FILTER_ERROR; 99 return Filter::FILTER_ERROR;
84 100
85 size_t output_buffer_size = base::checked_cast<size_t>(*dest_len); 101 size_t output_buffer_size = base::checked_cast<size_t>(*dest_len);
86 size_t input_buffer_size = base::checked_cast<size_t>(stream_data_len_); 102 size_t input_buffer_size = base::checked_cast<size_t>(stream_data_len_);
87 103
88 size_t available_in = input_buffer_size; 104 size_t available_in = input_buffer_size;
89 const uint8_t* next_in = bit_cast<uint8_t*>(next_stream_data_); 105 const uint8_t* next_in = bit_cast<uint8_t*>(next_stream_data_);
90 size_t available_out = output_buffer_size; 106 size_t available_out = output_buffer_size;
91 uint8_t* next_out = bit_cast<uint8_t*>(dest_buffer); 107 uint8_t* next_out = bit_cast<uint8_t*>(dest_buffer);
92 size_t total_out = 0; 108 size_t total_out = 0;
109
110 // Check if start of the input stream looks like gzip stream.
111 for (size_t i = consumed_bytes_; i < sizeof(kGzipHeader); ++i) {
112 if (!gzip_header_detected_)
113 break;
114 size_t j = i - consumed_bytes_;
115 if (j < available_in && kGzipHeader[i] != next_in[j])
116 gzip_header_detected_ = false;
117 }
118
93 BrotliResult result = 119 BrotliResult result =
94 BrotliDecompressStream(&available_in, &next_in, &available_out, 120 BrotliDecompressStream(&available_in, &next_in, &available_out,
95 &next_out, &total_out, brotli_state_); 121 &next_out, &total_out, brotli_state_);
96 122
97 CHECK(available_in <= input_buffer_size); 123 CHECK(available_in <= input_buffer_size);
98 CHECK(available_out <= output_buffer_size); 124 CHECK(available_out <= output_buffer_size);
99 consumed_bytes_ += input_buffer_size - available_in; 125 consumed_bytes_ += input_buffer_size - available_in;
100 produced_bytes_ += output_buffer_size - available_out; 126 produced_bytes_ += output_buffer_size - available_out;
101 127
102 base::CheckedNumeric<size_t> safe_bytes_written(output_buffer_size); 128 base::CheckedNumeric<size_t> safe_bytes_written(output_buffer_size);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 // This variable is updated only by ReadFilteredData. 199 // This variable is updated only by ReadFilteredData.
174 DecodingStatus decoding_status_; 200 DecodingStatus decoding_status_;
175 201
176 BrotliState* brotli_state_; 202 BrotliState* brotli_state_;
177 203
178 size_t used_memory_; 204 size_t used_memory_;
179 size_t used_memory_maximum_; 205 size_t used_memory_maximum_;
180 size_t consumed_bytes_; 206 size_t consumed_bytes_;
181 size_t produced_bytes_; 207 size_t produced_bytes_;
182 208
209 bool gzip_header_detected_;
210
183 DISALLOW_COPY_AND_ASSIGN(BrotliFilter); 211 DISALLOW_COPY_AND_ASSIGN(BrotliFilter);
184 }; 212 };
185 213
186 Filter* CreateBrotliFilter(Filter::FilterType type_id) { 214 Filter* CreateBrotliFilter(Filter::FilterType type_id) {
187 return new BrotliFilter(type_id); 215 return new BrotliFilter(type_id);
188 } 216 }
189 217
190 } // namespace net 218 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698