File: filter_source_stream.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (154 lines) | stat: -rw-r--r-- 5,819 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_FILTER_FILTER_SOURCE_STREAM_H_
#define NET_FILTER_FILTER_SOURCE_STREAM_H_

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "base/containers/flat_set.h"
#include "base/memory/scoped_refptr.h"
#include "base/types/expected.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
#include "net/filter/source_stream.h"
#include "net/filter/source_stream_type.h"

namespace net {

class DrainableIOBuffer;
class HttpResponseHeaders;
class IOBuffer;

// FilterSourceStream represents SourceStreams that always have an upstream
// from which undecoded input can be read. Except the ultimate upstream in
// the filter chain, all other streams should implement FilterSourceStream
// instead of SourceStream.
class NET_EXPORT_PRIVATE FilterSourceStream : public SourceStream {
 public:
  // |upstream| is the SourceStream from which |this| will read data.
  // |upstream| cannot be null.
  FilterSourceStream(SourceStreamType type,
                     std::unique_ptr<SourceStream> upstream);

  FilterSourceStream(const FilterSourceStream&) = delete;
  FilterSourceStream& operator=(const FilterSourceStream&) = delete;

  ~FilterSourceStream() override;

  // SourceStream implementation.
  int Read(IOBuffer* read_buffer,
           int read_buffer_size,
           CompletionOnceCallback callback) override;
  std::string Description() const override;
  bool MayHaveMoreBytes() const override;

  static SourceStreamType ParseEncodingType(std::string_view encoding);

  // Parses the "Content-Encoding" HTTP header from the provided headers.
  // Returns a vector of SourceStreamType representing the encoding types found,
  // in the order they appear in the header.
  // Returns an empty vector if:
  //   - No "Content-Encoding" HTTP header is set.
  //   - The value of "Content-Encoding" HTTP header is empty string.
  //   - An unknown encoding type is encountered.
  //   - An encoding type is found that is not within the accepted_stream_types
  //     set (if provided).
  static std::vector<SourceStreamType> GetContentEncodingTypes(
      const std::optional<base::flat_set<SourceStreamType>>&
          accepted_stream_types,
      const HttpResponseHeaders& headers);

  // Creates a chained decoding SourceStream by wrapping the provided `upstream`
  // SourceStream with a series of decoding FilterSourceStreams.
  // The decoding is performed in the reverse order of the `types` vector.
  // The `types` vector must not contain SourceStreamType::kNone or
  // SourceStreamType::kUnknown.
  static std::unique_ptr<SourceStream> CreateDecodingSourceStream(
      std::unique_ptr<SourceStream> upstream,
      const std::vector<SourceStreamType>& types);

 private:
  enum State {
    STATE_NONE,
    // Reading data from |upstream_| into |input_buffer_|.
    STATE_READ_DATA,
    // Reading data from |upstream_| completed.
    STATE_READ_DATA_COMPLETE,
    // Filtering data contained in |input_buffer_|.
    STATE_FILTER_DATA,
    // Filtering data contained in |input_buffer_| completed.
    STATE_FILTER_DATA_COMPLETE,
    STATE_DONE,
  };

  int DoLoop(int result);
  int DoReadData();
  int DoReadDataComplete(int result);
  int DoFilterData();

  // Helper method used as a callback argument passed to |upstream_->Read()|.
  void OnIOComplete(int result);

  // Subclasses should implement this method to filter data from
  // |input_buffer| and write to |output_buffer|.
  // This method must complete synchronously (i.e. It cannot return
  // ERR_IO_PENDING). If an unrecoverable error occurred, this should return
  // ERR_CONTENT_DECODING_FAILED or a more specific error code.
  //
  // If FilterData() returns 0, *|consumed_bytes| must be equal to
  // |input_buffer_size|. Upstream EOF is reached when FilterData() is called
  // with |upstream_eof_reached| = true.
  // TODO(xunjieli): consider allowing asynchronous response via callback
  // to support off-thread decompression.
  virtual base::expected<size_t, Error> FilterData(
      IOBuffer* output_buffer,
      size_t output_buffer_size,
      IOBuffer* input_buffer,
      size_t input_buffer_size,
      size_t* consumed_bytes,
      bool upstream_eof_reached) = 0;

  // Returns a string representation of the type of this FilterSourceStream.
  // This is for UMA logging.
  virtual std::string GetTypeAsString() const = 0;

  // Returns whether |this| still needs more input data from |upstream_|.
  // By default, |this| will continue reading until |upstream_| returns an error
  // or EOF. Subclass can override this to return false to skip reading all the
  // input from |upstream_|.
  virtual bool NeedMoreData() const;

  // The SourceStream from which |this| will read data from. Data flows from
  // |upstream_| to |this_|.
  std::unique_ptr<SourceStream> upstream_;

  State next_state_ = STATE_NONE;

  // Buffer for reading data out of |upstream_| and then for use by |this|
  // before the filtered data is returned through Read().
  scoped_refptr<IOBuffer> input_buffer_;

  // Wrapper around |input_buffer_| that makes visible only the unread data.
  // Keep this as a member because subclass might not drain everything in a
  // single FilterData().
  scoped_refptr<DrainableIOBuffer> drainable_input_buffer_;

  // Not null if there is a pending Read.
  scoped_refptr<IOBuffer> output_buffer_;
  size_t output_buffer_size_ = 0;
  CompletionOnceCallback callback_;

  // Reading from |upstream_| has returned 0 byte or an error code.
  bool upstream_end_reached_ = false;
};

}  // namespace net

#endif  // NET_FILTER_FILTER_SOURCE_STREAM_H_