blob: 0981b68b8e5b09ceaa0054692e357cce62397d37 [file] [log] [blame]
mef06eab3e82016-04-14 22:45:491// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
gcasto67ace932016-11-10 21:44:495#ifndef COMPONENTS_GRPC_SUPPORT_BIDIRECTIONAL_STREAM_H_
6#define COMPONENTS_GRPC_SUPPORT_BIDIRECTIONAL_STREAM_H_
mef06eab3e82016-04-14 22:45:497
dchengfe3745e6242016-04-21 23:49:588#include <memory>
mef62d0ba2a2016-06-15 21:03:029#include <vector>
dchengfe3745e6242016-04-21 23:49:5810
mef06eab3e82016-04-14 22:45:4911#include "base/macros.h"
12#include "base/memory/ref_counted.h"
mefce9fb502016-09-27 19:45:5613#include "base/memory/weak_ptr.h"
mef06eab3e82016-04-14 22:45:4914#include "base/synchronization/lock.h"
15#include "net/http/bidirectional_stream.h"
gcasto67ace932016-11-10 21:44:4916#include "net/url_request/url_request_context_getter.h"
mef06eab3e82016-04-14 22:45:4917
Brett Wilsonabbb9602017-09-11 23:26:3918namespace base {
tzik0bd4ea132017-02-15 10:52:2819class Location;
Misha Efimov9983c6bb2018-01-30 23:10:3920} // namespace base
tzik0bd4ea132017-02-15 10:52:2821
mef06eab3e82016-04-14 22:45:4922namespace net {
23class HttpRequestHeaders;
24class WrappedIOBuffer;
25} // namespace net
26
gcasto67ace932016-11-10 21:44:4927namespace grpc_support {
mef06eab3e82016-04-14 22:45:4928
29// An adapter to net::BidirectionalStream.
30// Created and configured from any thread. Start, ReadData, WriteData and
31// Destroy can be called on any thread (including network thread), and post
32// calls to corresponding {Start|ReadData|WriteData|Destroy}OnNetworkThread to
33// the network thread. The object is always deleted on network thread. All
34// callbacks into the Delegate are done on the network thread.
35// The app is expected to initiate the next step like ReadData or Destroy.
36// Public methods can be called on any thread.
gcasto67ace932016-11-10 21:44:4937class BidirectionalStream : public net::BidirectionalStream::Delegate {
mef06eab3e82016-04-14 22:45:4938 public:
39 class Delegate {
40 public:
xunjieli07a42ce2016-04-26 20:05:3141 virtual void OnStreamReady() = 0;
mef06eab3e82016-04-14 22:45:4942
Ryan Hamilton0239aac2018-05-19 00:03:1343 virtual void OnHeadersReceived(
44 const spdy::SpdyHeaderBlock& response_headers,
45 const char* negotiated_protocol) = 0;
mef06eab3e82016-04-14 22:45:4946
47 virtual void OnDataRead(char* data, int size) = 0;
48
49 virtual void OnDataSent(const char* data) = 0;
50
Ryan Hamilton0239aac2018-05-19 00:03:1351 virtual void OnTrailersReceived(const spdy::SpdyHeaderBlock& trailers) = 0;
mef06eab3e82016-04-14 22:45:4952
53 virtual void OnSucceeded() = 0;
54
55 virtual void OnFailed(int error) = 0;
56
57 virtual void OnCanceled() = 0;
58 };
59
gcasto67ace932016-11-10 21:44:4960 BidirectionalStream(net::URLRequestContextGetter* request_context_getter,
61 Delegate* delegate);
62 ~BidirectionalStream() override;
mef06eab3e82016-04-14 22:45:4963
mef62d0ba2a2016-06-15 21:03:0264 // Disables automatic flushing of each buffer passed to WriteData().
65 void disable_auto_flush(bool disable_auto_flush) {
66 disable_auto_flush_ = disable_auto_flush;
67 }
68
69 // Delays sending request headers until first call to Flush().
70 void delay_headers_until_flush(bool delay_headers_until_flush) {
71 delay_headers_until_flush_ = delay_headers_until_flush;
72 }
73
mef06eab3e82016-04-14 22:45:4974 // Validates method and headers, initializes and starts the request. If
75 // |end_of_stream| is true, then stream is half-closed after sending header
76 // frame and no data is expected to be written.
77 // Returns 0 if request is valid and started successfully,
78 // Returns -1 if |method| is not valid HTTP method name.
79 // Returns position of invalid header value in |headers| if header name is
80 // not valid.
81 int Start(const char* url,
82 int priority,
83 const char* method,
84 const net::HttpRequestHeaders& headers,
85 bool end_of_stream);
86
87 // Reads more data into |buffer| up to |capacity| bytes.
88 bool ReadData(char* buffer, int capacity);
89
90 // Writes |count| bytes of data from |buffer|. The |end_of_stream| is
91 // passed to remote to indicate end of stream.
92 bool WriteData(const char* buffer, int count, bool end_of_stream);
93
mef62d0ba2a2016-06-15 21:03:0294 // Sends buffers passed to WriteData().
95 void Flush();
96
mef06eab3e82016-04-14 22:45:4997 // Cancels the request. The OnCanceled callback is invoked when request is
98 // caneceled, and not other callbacks are invoked afterwards..
99 void Cancel();
100
101 // Releases all resources for the request and deletes the object itself.
102 void Destroy();
103
104 private:
105 // States of BidirectionalStream are tracked in |read_state_| and
106 // |write_state_|.
107 // The write state is separated as it changes independently of the read state.
108 // There is one initial state: NOT_STARTED. There is one normal final state:
109 // SUCCESS, reached after READING_DONE and WRITING_DONE. There are two
110 // exceptional final states: CANCELED and ERROR, which can be reached from
111 // any other non-final state.
112 enum State {
113 // Initial state, stream not started.
114 NOT_STARTED,
115 // Stream started, request headers are being sent.
116 STARTED,
117 // Waiting for ReadData() to be called.
118 WAITING_FOR_READ,
119 // Reading from the remote, OnDataRead callback will be invoked when done.
120 READING,
121 // There is no more data to read and stream is half-closed by the remote
122 // side.
123 READING_DONE,
124 // Stream is canceled.
125 CANCELED,
126 // Error has occured, stream is closed.
gcasto67ace932016-11-10 21:44:49127 ERR,
mef06eab3e82016-04-14 22:45:49128 // Reading and writing are done, and the stream is closed successfully.
129 SUCCESS,
mef62d0ba2a2016-06-15 21:03:02130 // Waiting for Flush() to be called.
131 WAITING_FOR_FLUSH,
mef06eab3e82016-04-14 22:45:49132 // Writing to the remote, callback will be invoked when done.
133 WRITING,
134 // There is no more data to write and stream is half-closed by the local
135 // side.
136 WRITING_DONE,
137 };
138
mef62d0ba2a2016-06-15 21:03:02139 // Container to hold buffers and sizes of the pending data to be written.
140 class WriteBuffers {
141 public:
142 WriteBuffers();
143 ~WriteBuffers();
144
145 // Clears Write Buffers list.
146 void Clear();
147
148 // Appends |buffer| of |buffer_size| length to the end of buffer list.
149 void AppendBuffer(const scoped_refptr<net::IOBuffer>& buffer,
150 int buffer_size);
151
152 void MoveTo(WriteBuffers* target);
153
154 // Returns true of Write Buffers list is empty.
155 bool Empty() const;
156
157 const std::vector<scoped_refptr<net::IOBuffer>>& buffers() const {
158 return write_buffer_list;
159 }
160
161 const std::vector<int>& lengths() const { return write_buffer_len_list; }
162
163 private:
164 // Every IOBuffer in |write_buffer_list| points to the memory owned by the
165 // application.
166 std::vector<scoped_refptr<net::IOBuffer>> write_buffer_list;
167 // A list of the length of each IOBuffer in |write_buffer_list|.
168 std::vector<int> write_buffer_len_list;
169
170 DISALLOW_COPY_AND_ASSIGN(WriteBuffers);
171 };
172
mef06eab3e82016-04-14 22:45:49173 // net::BidirectionalStream::Delegate implementations:
xunjielibcb0f86e2016-06-03 00:49:29174 void OnStreamReady(bool request_headers_sent) override;
Ryan Hamilton0239aac2018-05-19 00:03:13175 void OnHeadersReceived(
176 const spdy::SpdyHeaderBlock& response_headers) override;
mef06eab3e82016-04-14 22:45:49177 void OnDataRead(int bytes_read) override;
178 void OnDataSent() override;
Ryan Hamilton0239aac2018-05-19 00:03:13179 void OnTrailersReceived(const spdy::SpdyHeaderBlock& trailers) override;
mef06eab3e82016-04-14 22:45:49180 void OnFailed(int error) override;
181 // Helper method to derive OnSucceeded.
182 void MaybeOnSucceded();
183
184 void StartOnNetworkThread(
dchengfe3745e6242016-04-21 23:49:58185 std::unique_ptr<net::BidirectionalStreamRequestInfo> request_info);
mef06eab3e82016-04-14 22:45:49186 void ReadDataOnNetworkThread(scoped_refptr<net::WrappedIOBuffer> read_buffer,
187 int buffer_size);
188 void WriteDataOnNetworkThread(scoped_refptr<net::WrappedIOBuffer> read_buffer,
189 int buffer_size,
190 bool end_of_stream);
mef62d0ba2a2016-06-15 21:03:02191 void FlushOnNetworkThread();
192 void SendFlushingWriteData();
mef06eab3e82016-04-14 22:45:49193 void CancelOnNetworkThread();
194 void DestroyOnNetworkThread();
195
gcasto67ace932016-11-10 21:44:49196 bool IsOnNetworkThread();
Brett Wilsonabbb9602017-09-11 23:26:39197 void PostToNetworkThread(const base::Location& from_here,
Misha Efimov9983c6bb2018-01-30 23:10:39198 base::OnceClosure task);
gcasto67ace932016-11-10 21:44:49199
mef06eab3e82016-04-14 22:45:49200 // Read state is tracking reading flow. Only accessed on network thread.
gcasto67ace932016-11-10 21:44:49201 // | <--- READING <--- |
mef06eab3e82016-04-14 22:45:49202 // | |
gcasto67ace932016-11-10 21:44:49203 // | |
mef06eab3e82016-04-14 22:45:49204 // NOT_STARTED -> STARTED --> WAITING_FOR_READ -> READING_DONE -> SUCCESS
205 State read_state_;
206
207 // Write state is tracking writing flow. Only accessed on network thread.
gcasto67ace932016-11-10 21:44:49208 // | <--- WRITING <--- |
mef06eab3e82016-04-14 22:45:49209 // | |
gcasto67ace932016-11-10 21:44:49210 // | |
mef62d0ba2a2016-06-15 21:03:02211 // NOT_STARTED -> STARTED --> WAITING_FOR_FLUSH -> WRITING_DONE -> SUCCESS
mef06eab3e82016-04-14 22:45:49212 State write_state_;
213
214 bool write_end_of_stream_;
mef62d0ba2a2016-06-15 21:03:02215 bool request_headers_sent_;
216
217 bool disable_auto_flush_;
218 bool delay_headers_until_flush_;
mef06eab3e82016-04-14 22:45:49219
gcasto67ace932016-11-10 21:44:49220 net::URLRequestContextGetter* const request_context_getter_;
mef06eab3e82016-04-14 22:45:49221
222 scoped_refptr<net::WrappedIOBuffer> read_buffer_;
mef62d0ba2a2016-06-15 21:03:02223
224 // Write data that is pending the flush.
225 std::unique_ptr<WriteBuffers> pending_write_data_;
226 // Write data that is flushed, but not sending yet.
227 std::unique_ptr<WriteBuffers> flushing_write_data_;
228 // Write data that is sending.
229 std::unique_ptr<WriteBuffers> sending_write_data_;
230
dchengfe3745e6242016-04-21 23:49:58231 std::unique_ptr<net::BidirectionalStream> bidi_stream_;
mef06eab3e82016-04-14 22:45:49232 Delegate* delegate_;
233
gcasto67ace932016-11-10 21:44:49234 base::WeakPtr<BidirectionalStream> weak_this_;
Jeremy Roman5c341f6d2019-07-15 15:56:10235 base::WeakPtrFactory<BidirectionalStream> weak_factory_{this};
mefce9fb502016-09-27 19:45:56236
gcasto67ace932016-11-10 21:44:49237 DISALLOW_COPY_AND_ASSIGN(BidirectionalStream);
mef06eab3e82016-04-14 22:45:49238};
239
gcasto67ace932016-11-10 21:44:49240} // namespace grpc_support
mef06eab3e82016-04-14 22:45:49241
gcasto67ace932016-11-10 21:44:49242#endif // COMPONENTS_GRPC_SUPPORT_BIDIRECTIONAL_STREAM_H_