summaryrefslogtreecommitdiff
path: root/chromium/net/spdy/bidirectional_stream_spdy_impl.h
blob: f99fb1842ac0ae7fe91157251f76a8995d4d5ba6 (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
// 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.

#ifndef NET_SPDY_BIDIRECTIONAL_STREAM_SPDY_IMPL_H_
#define NET_SPDY_BIDIRECTIONAL_STREAM_SPDY_IMPL_H_

#include <stdint.h>

#include <memory>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_export.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/bidirectional_stream_request_info.h"
#include "net/http/http_request_info.h"
#include "net/log/net_log_source.h"
#include "net/spdy/spdy_read_queue.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_stream.h"
#include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"

namespace base {
class OneShotTimer;
}  // namespace base

namespace net {

class IOBuffer;
class NetLogWithSource;

class NET_EXPORT_PRIVATE BidirectionalStreamSpdyImpl
    : public BidirectionalStreamImpl,
      public SpdyStream::Delegate {
 public:
  BidirectionalStreamSpdyImpl(const base::WeakPtr<SpdySession>& spdy_session,
                              NetLogSource source_dependency);

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

  ~BidirectionalStreamSpdyImpl() override;

  // BidirectionalStreamImpl implementation:
  void Start(const BidirectionalStreamRequestInfo* request_info,
             const NetLogWithSource& net_log,
             bool send_request_headers_automatically,
             BidirectionalStreamImpl::Delegate* delegate,
             std::unique_ptr<base::OneShotTimer> timer,
             const NetworkTrafficAnnotationTag& traffic_annotation) override;
  void SendRequestHeaders() override;
  int ReadData(IOBuffer* buf, int buf_len) override;
  void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers,
                 const std::vector<int>& lengths,
                 bool end_stream) override;
  NextProto GetProtocol() const override;
  int64_t GetTotalReceivedBytes() const override;
  int64_t GetTotalSentBytes() const override;
  bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
  void PopulateNetErrorDetails(NetErrorDetails* details) override;

  // SpdyStream::Delegate implementation:
  void OnHeadersSent() override;
  void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& headers) override;
  void OnHeadersReceived(
      const spdy::Http2HeaderBlock& response_headers,
      const spdy::Http2HeaderBlock* pushed_request_headers) override;
  void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override;
  void OnDataSent() override;
  void OnTrailers(const spdy::Http2HeaderBlock& trailers) override;
  void OnClose(int status) override;
  bool CanGreaseFrameType() const override;
  NetLogSource source_dependency() const override;

 private:
  int SendRequestHeadersHelper();
  void OnStreamInitialized(int rv);
  // Notifies delegate of an error.
  void NotifyError(int rv);
  void ResetStream();
  void ScheduleBufferedRead();
  void DoBufferedRead();
  bool ShouldWaitForMoreBufferedData() const;
  // Handles the case where stream is closed when SendData()/SendvData() is
  // called. Return true if stream is closed.
  bool MaybeHandleStreamClosedInSendData();

  const base::WeakPtr<SpdySession> spdy_session_;
  raw_ptr<const BidirectionalStreamRequestInfo> request_info_ = nullptr;
  raw_ptr<BidirectionalStreamImpl::Delegate> delegate_ = nullptr;
  std::unique_ptr<base::OneShotTimer> timer_;
  SpdyStreamRequest stream_request_;
  base::WeakPtr<SpdyStream> stream_;
  const NetLogSource source_dependency_;

  NextProto negotiated_protocol_ = kProtoUnknown;

  // Buffers the data as it arrives asynchronously from the stream.
  SpdyReadQueue read_data_queue_;
  // Whether received more data has arrived since started waiting.
  bool more_read_data_pending_ = false;
  // User provided read buffer for ReadData() response.
  scoped_refptr<IOBuffer> read_buffer_;
  int read_buffer_len_ = 0;

  // Whether client has written the end of stream flag in request headers or
  // in SendData()/SendvData().
  bool written_end_of_stream_ = false;
  // Whether a SendData() or SendvData() is pending.
  bool write_pending_ = false;

  // Whether OnClose has been invoked.
  bool stream_closed_ = false;
  // Status reported in OnClose.
  int closed_stream_status_ = ERR_FAILED;
  // After |stream_| has been closed, this keeps track of the total number of
  // bytes received over the network for |stream_| while it was open.
  int64_t closed_stream_received_bytes_ = 0;
  // After |stream_| has been closed, this keeps track of the total number of
  // bytes sent over the network for |stream_| while it was open.
  int64_t closed_stream_sent_bytes_ = 0;
  // True if |stream_| has LoadTimingInfo when it is closed.
  bool closed_has_load_timing_info_ = false;
  // LoadTimingInfo populated when |stream_| is closed.
  LoadTimingInfo closed_load_timing_info_;

  // This is the combined buffer of buffers passed in through SendvData.
  // Keep a reference here so it is alive until OnDataSent is invoked.
  scoped_refptr<IOBuffer> pending_combined_buffer_;

  base::WeakPtrFactory<BidirectionalStreamSpdyImpl> weak_factory_{this};
};

}  // namespace net

#endif  // NET_SPDY_BIDIRECTIONAL_STREAM_SPDY_IMPL_H_