summaryrefslogtreecommitdiff
path: root/chromium/net/quic/quic_spdy_stream.h
blob: 71c50b4cbd0f9ff235f3e504f31361b6a9453285 (plain)
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// Copyright 2013 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.
//
// The base class for streams which deliver data to/from an application.
// In each direction, the data on such a stream first contains compressed
// headers then body data.

#ifndef NET_QUIC_QUIC_SPDY_STREAM_H_
#define NET_QUIC_QUIC_SPDY_STREAM_H_

#include <stddef.h>
#include <sys/types.h>

#include <list>
#include <string>

#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "net/base/iovec.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_stream_sequencer.h"
#include "net/quic/reliable_quic_stream.h"
#include "net/spdy/spdy_framer.h"

namespace net {

namespace test {
class QuicSpdyStreamPeer;
class ReliableQuicStreamPeer;
}  // namespace test

class QuicSpdySession;

// This is somewhat arbitrary.  It's possible, but unlikely, we will either fail
// to set a priority client-side, or cancel a stream before stripping the
// priority from the wire server-side.  In either case, start out with a
// priority in the middle.
const SpdyPriority kDefaultPriority = 3;

// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
class NET_EXPORT_PRIVATE QuicSpdyStream : public ReliableQuicStream {
 public:
  // Visitor receives callbacks from the stream.
  class NET_EXPORT_PRIVATE Visitor {
   public:
    Visitor() {}

    // Called when the stream is closed.
    virtual void OnClose(QuicSpdyStream* stream) = 0;

   protected:
    virtual ~Visitor() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(Visitor);
  };

  QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session);
  ~QuicSpdyStream() override;

  // Override the base class to send QUIC_STREAM_NO_ERROR to the peer
  // when the stream has not received all the data.
  void CloseWriteSide() override;
  void StopReading() override;

  // ReliableQuicStream implementation
  void OnClose() override;

  // Called by the session when decompressed headers data is received
  // for this stream.
  // May be called multiple times, with each call providing additional headers
  // data until OnStreamHeadersComplete is called.
  virtual void OnStreamHeaders(base::StringPiece headers_data);

  // Called by the session when headers with a priority have been received
  // for this stream.  This method will only be called for server streams.
  virtual void OnStreamHeadersPriority(SpdyPriority priority);

  // Called by the session when decompressed headers have been completely
  // delivered to this stream.  If |fin| is true, then this stream
  // should be closed; no more data will be sent by the peer.
  virtual void OnStreamHeadersComplete(bool fin, size_t frame_len);

  // Called by the session when decompressed PUSH_PROMISE headers data
  // is received for this stream.
  // May be called multiple times, with each call providing additional headers
  // data until OnPromiseHeadersComplete is called.
  virtual void OnPromiseHeaders(StringPiece headers_data);

  // Called by the session when decompressed push promise headers have
  // been completely delivered to this stream.
  virtual void OnPromiseHeadersComplete(QuicStreamId promised_id,
                                        size_t frame_len);

  // Override the base class to not discard response when receiving
  // QUIC_STREAM_NO_ERROR on QUIC_VERSION_29 and later versions.
  void OnStreamReset(const QuicRstStreamFrame& frame) override;

  // Writes the headers contained in |header_block| to the dedicated
  // headers stream.
  virtual size_t WriteHeaders(const SpdyHeaderBlock& header_block,
                              bool fin,
                              QuicAckListenerInterface* ack_notifier_delegate);

  // Sends |data| to the peer, or buffers if it can't be sent immediately.
  void WriteOrBufferBody(const std::string& data,
                         bool fin,
                         QuicAckListenerInterface* ack_notifier_delegate);

  // Writes the trailers contained in |trailer_block| to the dedicated
  // headers stream. Trailers will always have the FIN set.
  size_t WriteTrailers(SpdyHeaderBlock trailer_block,
                       QuicAckListenerInterface* ack_notifier_delegate);

  // Marks |bytes_consumed| of the headers data as consumed.
  void MarkHeadersConsumed(size_t bytes_consumed);

  // Marks |bytes_consumed| of the trailers data as consumed.
  void MarkTrailersConsumed(size_t bytes_consumed);

  // This block of functions wraps the sequencer's functions of the same
  // name.  These methods return uncompressed data until that has
  // been fully processed.  Then they simply delegate to the sequencer.
  virtual size_t Readv(const struct iovec* iov, size_t iov_len);
  virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
  void MarkConsumed(size_t num_bytes);

  // Returns true if header contains a valid 3-digit status and parse the status
  // code to |status_code|.
  bool ParseHeaderStatusCode(SpdyHeaderBlock* header, int* status_code) const;

  // Returns true when all data has been read from the peer, including the fin.
  bool IsDoneReading() const;
  bool HasBytesToRead() const;

  void set_visitor(Visitor* visitor) { visitor_ = visitor; }

  bool headers_decompressed() const { return headers_decompressed_; }

  const std::string& decompressed_headers() const {
    return decompressed_headers_;
  }

  bool trailers_decompressed() const { return trailers_decompressed_; }

  const std::string& decompressed_trailers() const {
    return decompressed_trailers_;
  }

  // Returns whatever trailers have been received for this stream.
  const SpdyHeaderBlock& received_trailers() const {
    return received_trailers_;
  }

  virtual SpdyPriority priority() const;

  // Sets priority_ to priority.  This should only be called before bytes are
  // written to the server.
  void SetPriority(SpdyPriority priority);

  // Called when owning session is getting deleted to avoid subsequent
  // use of the spdy_session_ member.
  void ClearSession();

 protected:
  // Called by OnStreamHeadersComplete depending on which type (initial or
  // trailing) headers are expected next.
  virtual void OnInitialHeadersComplete(bool fin, size_t frame_len);
  virtual void OnTrailingHeadersComplete(bool fin, size_t frame_len);
  QuicSpdySession* spdy_session() const { return spdy_session_; }
  Visitor* visitor() { return visitor_; }

  // Returns true if headers have been fully read and consumed.
  bool FinishedReadingHeaders() const;

 private:
  friend class test::QuicSpdyStreamPeer;
  friend class test::ReliableQuicStreamPeer;
  friend class QuicStreamUtils;

  // Returns true if trailers have been fully read and consumed.
  bool FinishedReadingTrailers() const;

  QuicSpdySession* spdy_session_;

  Visitor* visitor_;
  // True if the headers have been completely decompressed.
  bool headers_decompressed_;
  // The priority of the stream, once parsed.
  SpdyPriority priority_;
  // Contains a copy of the decompressed headers until they are consumed
  // via ProcessData or Readv.
  std::string decompressed_headers_;

  // True if the trailers have been completely decompressed.
  bool trailers_decompressed_;
  // Contains a copy of the decompressed trailers until they are consumed
  // via ProcessData or Readv.
  std::string decompressed_trailers_;
  // The parsed trailers received from the peer.
  SpdyHeaderBlock received_trailers_;

  DISALLOW_COPY_AND_ASSIGN(QuicSpdyStream);
};

}  // namespace net

#endif  // NET_QUIC_QUIC_SPDY_STREAM_H_