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

Side by Side Diff: net/spdy/spdy_stream.h

Issue 2832973003: Split net/spdy into core and chromium subdirectories. (Closed)
Patch Set: Fix some more build rules. Created 3 years, 8 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 | « net/spdy/spdy_session_unittest.cc ('k') | net/spdy/spdy_stream.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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
5 #ifndef NET_SPDY_SPDY_STREAM_H_
6 #define NET_SPDY_SPDY_STREAM_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <deque>
12 #include <memory>
13 #include <vector>
14
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/weak_ptr.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/net_export.h"
20 #include "net/base/request_priority.h"
21 #include "net/log/net_log_source.h"
22 #include "net/log/net_log_with_source.h"
23 #include "net/socket/next_proto.h"
24 #include "net/socket/ssl_client_socket.h"
25 #include "net/spdy/platform/api/spdy_string.h"
26 #include "net/spdy/spdy_buffer.h"
27 #include "net/spdy/spdy_framer.h"
28 #include "net/spdy/spdy_header_block.h"
29 #include "net/spdy/spdy_protocol.h"
30 #include "net/ssl/ssl_client_cert_type.h"
31 #include "url/gurl.h"
32
33 namespace net {
34
35 class IPEndPoint;
36 struct LoadTimingInfo;
37 class SSLInfo;
38 class SpdySession;
39
40 enum SpdyStreamType {
41 // The most general type of stream; there are no restrictions on
42 // when data can be sent and received.
43 SPDY_BIDIRECTIONAL_STREAM,
44 // A stream where the client sends a request with possibly a body,
45 // and the server then sends a response with a body.
46 SPDY_REQUEST_RESPONSE_STREAM,
47 // A server-initiated stream where the server just sends a response
48 // with a body and the client does not send anything.
49 SPDY_PUSH_STREAM
50 };
51
52 // Passed to some SpdyStream functions to indicate whether there's
53 // more data to send.
54 enum SpdySendStatus {
55 MORE_DATA_TO_SEND,
56 NO_MORE_DATA_TO_SEND
57 };
58
59 // SpdyStream is owned by SpdySession and is used to represent each stream known
60 // on the SpdySession. This class provides interfaces for SpdySession to use.
61 // Streams can be created either by the client or by the server. When they
62 // are initiated by the client, both the SpdySession and client object (such as
63 // a SpdyNetworkTransaction) will maintain a reference to the stream. When
64 // initiated by the server, only the SpdySession will maintain any reference,
65 // until such a time as a client object requests a stream for the path.
66 class NET_EXPORT_PRIVATE SpdyStream {
67 public:
68 // Delegate handles protocol specific behavior of spdy stream.
69 class NET_EXPORT_PRIVATE Delegate {
70 public:
71 Delegate() {}
72
73 // Called when the request headers have been sent. Never called
74 // for push streams. Must not cause the stream to be closed.
75 virtual void OnHeadersSent() = 0;
76
77 // OnHeadersReceived(), OnDataReceived(), OnTrailers(), and OnClose()
78 // are guaranteed to be called in the following order:
79 // - OnHeadersReceived() exactly once;
80 // - OnDataReceived() zero or more times;
81 // - OnTrailers() zero or one times;
82 // - OnClose() exactly once.
83
84 // Called when headers have been received.
85 virtual void OnHeadersReceived(const SpdyHeaderBlock& response_headers) = 0;
86
87 // Called when data is received. |buffer| may be NULL, which signals EOF.
88 // May cause the stream to be closed.
89 virtual void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) = 0;
90
91 // Called when data is sent. Must not cause the stream to be closed.
92 virtual void OnDataSent() = 0;
93
94 // Called when trailers are received.
95 virtual void OnTrailers(const SpdyHeaderBlock& trailers) = 0;
96
97 // Called when SpdyStream is closed. No other delegate functions
98 // will be called after this is called, and the delegate must not
99 // access the stream after this is called. Must not cause the
100 // stream to be (re-)closed.
101 //
102 // TODO(akalin): Allow this function to re-close the stream and
103 // handle it gracefully.
104 virtual void OnClose(int status) = 0;
105
106 virtual NetLogSource source_dependency() const = 0;
107
108 protected:
109 virtual ~Delegate() {}
110
111 private:
112 DISALLOW_COPY_AND_ASSIGN(Delegate);
113 };
114
115 // SpdyStream constructor
116 SpdyStream(SpdyStreamType type,
117 const base::WeakPtr<SpdySession>& session,
118 const GURL& url,
119 RequestPriority priority,
120 int32_t initial_send_window_size,
121 int32_t max_recv_window_size,
122 const NetLogWithSource& net_log);
123
124 ~SpdyStream();
125
126 // Set the delegate, which must not be NULL. Must not be called more
127 // than once. For push streams, calling this may cause buffered data
128 // to be sent to the delegate (from a posted task).
129 void SetDelegate(Delegate* delegate);
130
131 // Detach the delegate from the stream, which must not yet be
132 // closed, and cancel it.
133 void DetachDelegate();
134
135 // The time at which the first bytes of the response were received
136 // from the server, or null if the response hasn't been received
137 // yet.
138 base::Time response_time() const { return response_time_; }
139
140 SpdyStreamType type() const { return type_; }
141
142 SpdyStreamId stream_id() const { return stream_id_; }
143 void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; }
144
145 const GURL& url() const { return url_; }
146
147 RequestPriority priority() const { return priority_; }
148 void set_priority(RequestPriority p) { priority_ = p; }
149
150 int32_t send_window_size() const { return send_window_size_; }
151
152 int32_t recv_window_size() const { return recv_window_size_; }
153
154 bool send_stalled_by_flow_control() const {
155 return send_stalled_by_flow_control_;
156 }
157
158 void set_send_stalled_by_flow_control(bool stalled) {
159 send_stalled_by_flow_control_ = stalled;
160 }
161
162 // Called by the session to adjust this stream's send window size by
163 // |delta_window_size|, which is the difference between the
164 // SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame
165 // and the previous initial send window size, possibly unstalling
166 // this stream. Although |delta_window_size| may cause this stream's
167 // send window size to go negative, it must not cause it to wrap
168 // around in either direction. Does nothing if the stream is already
169 // closed.
170 //
171 // If stream flow control is turned off, this must not be called.
172 void AdjustSendWindowSize(int32_t delta_window_size);
173
174 // Called when bytes are consumed from a SpdyBuffer for a DATA frame
175 // that is to be written or is being written. Increases the send
176 // window size accordingly if some or all of the SpdyBuffer is being
177 // discarded.
178 //
179 // If stream flow control is turned off, this must not be called.
180 void OnWriteBufferConsumed(size_t frame_payload_size,
181 size_t consume_size,
182 SpdyBuffer::ConsumeSource consume_source);
183
184 // Called by the session to increase this stream's send window size
185 // by |delta_window_size| (which must be at least 1) from a received
186 // WINDOW_UPDATE frame or from a dropped DATA frame that was
187 // intended to be sent, possibly unstalling this stream. If
188 // |delta_window_size| would cause this stream's send window size to
189 // overflow, calls into the session to reset this stream. Does
190 // nothing if the stream is already closed.
191 //
192 // If stream flow control is turned off, this must not be called.
193 void IncreaseSendWindowSize(int32_t delta_window_size);
194
195 // If stream flow control is turned on, called by the session to
196 // decrease this stream's send window size by |delta_window_size|,
197 // which must be at least 0 and at most kMaxSpdyFrameChunkSize.
198 // |delta_window_size| must not cause this stream's send window size
199 // to go negative. Does nothing if the stream is already closed.
200 //
201 // If stream flow control is turned off, this must not be called.
202 void DecreaseSendWindowSize(int32_t delta_window_size);
203
204 // Called when bytes are consumed by the delegate from a SpdyBuffer
205 // containing received data. Increases the receive window size
206 // accordingly.
207 //
208 // If stream flow control is turned off, this must not be called.
209 void OnReadBufferConsumed(size_t consume_size,
210 SpdyBuffer::ConsumeSource consume_source);
211
212 // Called by OnReadBufferConsume to increase this stream's receive
213 // window size by |delta_window_size|, which must be at least 1 and
214 // must not cause this stream's receive window size to overflow,
215 // possibly also sending a WINDOW_UPDATE frame. Does nothing if the
216 // stream is not active.
217 //
218 // If stream flow control is turned off, this must not be called.
219 void IncreaseRecvWindowSize(int32_t delta_window_size);
220
221 // Called by OnDataReceived or OnPaddingConsumed (which are in turn called by
222 // the session) to decrease this stream's receive window size by
223 // |delta_window_size|, which must be at least 1. May close the stream on
224 // flow control error.
225 //
226 // If stream flow control is turned off or the stream is not active,
227 // this must not be called.
228 void DecreaseRecvWindowSize(int32_t delta_window_size);
229
230 int GetPeerAddress(IPEndPoint* address) const;
231 int GetLocalAddress(IPEndPoint* address) const;
232
233 // Returns true if the underlying transport socket ever had any reads or
234 // writes.
235 bool WasEverUsed() const;
236
237 const NetLogWithSource& net_log() const { return net_log_; }
238
239 base::Time GetRequestTime() const;
240 void SetRequestTime(base::Time t);
241
242 // Called by SpdySession when headers are received for this stream. May close
243 // the stream.
244 void OnHeadersReceived(const SpdyHeaderBlock& response_headers,
245 base::Time response_time,
246 base::TimeTicks recv_first_byte_time);
247
248 // Called by the SpdySession when a frame carrying request headers opening a
249 // push stream is received. Stream transits to STATE_RESERVED_REMOTE state.
250 void OnPushPromiseHeadersReceived(SpdyHeaderBlock headers);
251
252 // Called by the SpdySession when response data has been received
253 // for this stream. This callback may be called multiple times as
254 // data arrives from the network, and will never be called prior to
255 // OnResponseHeadersReceived.
256 //
257 // |buffer| contains the data received, or NULL if the stream is
258 // being closed. The stream must copy any data from this
259 // buffer before returning from this callback.
260 //
261 // |length| is the number of bytes received (at most 2^24 - 1) or 0 if
262 // the stream is being closed.
263 void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer);
264
265 // Called by the SpdySession when padding is consumed to allow for the stream
266 // receiving window to be updated.
267 void OnPaddingConsumed(size_t len);
268
269 // Called by the SpdySession when a frame has been successfully and completely
270 // written. |frame_size| is the total size of the logical frame in bytes,
271 // including framing overhead. For fragmented headers, this is the total size
272 // of the HEADERS or PUSH_PROMISE frame and subsequent CONTINUATION frames.
273 void OnFrameWriteComplete(SpdyFrameType frame_type, size_t frame_size);
274
275 // HEADERS-specific write handler invoked by OnFrameWriteComplete().
276 int OnHeadersSent();
277
278 // DATA-specific write handler invoked by OnFrameWriteComplete().
279 // If more data is already available to be written, the next write is
280 // queued and ERR_IO_PENDING is returned. Returns OK otherwise.
281 int OnDataSent(size_t frame_size);
282
283 // Called by the SpdySession when the request is finished. This callback
284 // will always be called at the end of the request and signals to the
285 // stream that the stream has no more network events. No further callbacks
286 // to the stream will be made after this call. Must be called before
287 // SpdyStream is destroyed.
288 // |status| is an error code or OK.
289 void OnClose(int status);
290
291 // Called by the SpdySession to log stream related errors.
292 void LogStreamError(int status, const SpdyString& description);
293
294 // If this stream is active, reset it, and close it otherwise. In
295 // either case the stream is deleted.
296 void Cancel();
297
298 // Close this stream without sending a RST_STREAM and delete
299 // it.
300 void Close();
301
302 // Must be used only by |session_|.
303 base::WeakPtr<SpdyStream> GetWeakPtr();
304
305 // Interface for the delegate to use.
306
307 // Only one send can be in flight at a time, except for push
308 // streams, which must not send anything.
309
310 // Sends the request headers. The delegate is called back via OnHeadersSent()
311 // when the request headers have completed sending. |send_status| must be
312 // MORE_DATA_TO_SEND for bidirectional streams; for request/response streams,
313 // it must be MORE_DATA_TO_SEND if the request has data to upload, or
314 // NO_MORE_DATA_TO_SEND if not.
315 int SendRequestHeaders(SpdyHeaderBlock request_headers,
316 SpdySendStatus send_status);
317
318 // Sends a DATA frame. The delegate will be notified via
319 // OnDataSent() when the send is complete. |send_status| must be
320 // MORE_DATA_TO_SEND for bidirectional streams; for request/response
321 // streams, it must be MORE_DATA_TO_SEND if there is more data to
322 // upload, or NO_MORE_DATA_TO_SEND if not.
323 void SendData(IOBuffer* data, int length, SpdySendStatus send_status);
324
325 // Fills SSL info in |ssl_info| and returns true when SSL is in use.
326 bool GetSSLInfo(SSLInfo* ssl_info) const;
327
328 // Returns true if ALPN was negotiated for the underlying socket.
329 bool WasAlpnNegotiated() const;
330
331 // Returns the protocol negotiated via ALPN for the underlying socket.
332 NextProto GetNegotiatedProtocol() const;
333
334 // If the stream is stalled on sending data, but the session is not
335 // stalled on sending data and |send_window_size_| is positive, then
336 // set |send_stalled_by_flow_control_| to false and unstall the data
337 // sending. Called by the session or by the stream itself. Must be
338 // called only when the stream is still open.
339 void PossiblyResumeIfSendStalled();
340
341 // Returns whether or not this stream is closed. Note that the only
342 // time a stream is closed and not deleted is in its delegate's
343 // OnClose() method.
344 bool IsClosed() const;
345
346 // Returns whether the streams local endpoint is closed.
347 // The remote endpoint may still be active.
348 bool IsLocallyClosed() const;
349
350 // Returns whether this stream is IDLE: request and response headers
351 // have neither been sent nor receieved.
352 bool IsIdle() const;
353
354 // Returns whether or not this stream is fully open: that request and
355 // response headers are complete, and it is not in a half-closed state.
356 bool IsOpen() const;
357
358 // Returns whether the stream is reserved by remote endpoint: server has sent
359 // intended request headers for a pushed stream, but haven't started response
360 // yet.
361 bool IsReservedRemote() const;
362
363 int response_status() const { return response_status_; }
364
365 void AddRawReceivedBytes(size_t received_bytes);
366 void AddRawSentBytes(size_t sent_bytes);
367
368 int64_t raw_received_bytes() const { return raw_received_bytes_; }
369 int64_t raw_sent_bytes() const { return raw_sent_bytes_; }
370 int recv_bytes() const { return recv_bytes_; }
371
372 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
373
374 // Get the URL from the appropriate stream headers, or the empty
375 // GURL() if it is unknown.
376 const GURL& GetUrlFromHeaders() const { return url_from_header_block_; }
377
378 // Returns the estimate of dynamically allocated memory in bytes.
379 size_t EstimateMemoryUsage() const;
380
381 private:
382 class HeadersBufferProducer;
383
384 // SpdyStream states and transitions are modeled
385 // on the HTTP/2 stream state machine. All states and transitions
386 // are modeled, with the exceptions of RESERVED_LOCAL (the client
387 // cannot initate push streams), and the transition to OPEN due to
388 // a remote HEADERS (the client can only initate streams).
389 enum State {
390 STATE_IDLE,
391 STATE_OPEN,
392 STATE_HALF_CLOSED_LOCAL_UNCLAIMED,
393 STATE_HALF_CLOSED_LOCAL,
394 STATE_HALF_CLOSED_REMOTE,
395 STATE_RESERVED_REMOTE,
396 STATE_CLOSED,
397 };
398
399 // Per RFC 7540 Section 8.1, an HTTP response consists of:
400 // * zero or more header blocks with informational (1xx) HTTP status,
401 // * one header block,
402 // * zero or more DATA frames,
403 // * zero or one header block ("trailers").
404 // Each header block must have a ":status" header field. SpdyStream enforces
405 // these requirements, and resets the stream if they are not met.
406 enum ResponseState {
407 READY_FOR_HEADERS,
408 READY_FOR_DATA_OR_TRAILERS,
409 TRAILERS_RECEIVED
410 };
411
412 // Update the histograms. Can safely be called repeatedly, but should only
413 // be called after the stream has completed.
414 void UpdateHistograms();
415
416 // When a server-push stream is claimed by SetDelegate(), this function is
417 // posted on the current MessageLoop to replay everything the server has sent.
418 // From the perspective of SpdyStream's state machine, headers, data, and
419 // FIN states received prior to the delegate being attached have not yet been
420 // read. While buffered by |pending_recv_data_| it's not until
421 // PushedStreamReplay() is invoked that reads are considered
422 // to have occurred, driving the state machine forward.
423 void PushedStreamReplay();
424
425 // Produces the HEADERS frame for the stream. The stream must
426 // already be activated.
427 std::unique_ptr<SpdySerializedFrame> ProduceHeadersFrame();
428
429 // Queues the send for next frame of the remaining data in
430 // |pending_send_data_|. Must be called only when
431 // |pending_send_data_| is set.
432 void QueueNextDataFrame();
433
434 // Saves the given headers into |response_headers_| and calls
435 // OnHeadersReceived() on the delegate if attached.
436 void SaveResponseHeaders(const SpdyHeaderBlock& response_headers);
437
438 static SpdyString DescribeState(State state);
439
440 const SpdyStreamType type_;
441
442 SpdyStreamId stream_id_;
443 const GURL url_;
444 RequestPriority priority_;
445
446 bool send_stalled_by_flow_control_;
447
448 // Current send window size.
449 int32_t send_window_size_;
450
451 // Maximum receive window size. Each time a WINDOW_UPDATE is sent, it
452 // restores the receive window size to this value.
453 int32_t max_recv_window_size_;
454
455 // Sum of |session_unacked_recv_window_bytes_| and current receive window
456 // size.
457 // TODO(bnc): Rename or change semantics so that |window_size_| is actual
458 // window size.
459 int32_t recv_window_size_;
460
461 // When bytes are consumed, SpdyIOBuffer destructor calls back to SpdySession,
462 // and this member keeps count of them until the corresponding WINDOW_UPDATEs
463 // are sent.
464 int32_t unacked_recv_window_bytes_;
465
466 const base::WeakPtr<SpdySession> session_;
467
468 // The transaction should own the delegate.
469 SpdyStream::Delegate* delegate_;
470
471 // The headers for the request to send.
472 bool request_headers_valid_;
473 SpdyHeaderBlock request_headers_;
474
475 // The URL from the request headers.
476 GURL url_from_header_block_;
477
478 // Data waiting to be sent, and the close state of the local endpoint
479 // after the data is fully written.
480 scoped_refptr<DrainableIOBuffer> pending_send_data_;
481 SpdySendStatus pending_send_status_;
482
483 // Data waiting to be received, and the close state of the remote endpoint
484 // after the data is fully read. Specifically, data received before the
485 // delegate is attached must be buffered and later replayed. A remote FIN
486 // is represented by a final, zero-length buffer.
487 std::vector<std::unique_ptr<SpdyBuffer>> pending_recv_data_;
488
489 // The time at which the request was made that resulted in this response.
490 // For cached responses, this time could be "far" in the past.
491 base::Time request_time_;
492
493 SpdyHeaderBlock response_headers_;
494 ResponseState response_state_;
495 base::Time response_time_;
496
497 State io_state_;
498
499 // Since we buffer the response, we also buffer the response status.
500 // Not valid until the stream is closed.
501 int response_status_;
502
503 NetLogWithSource net_log_;
504
505 base::TimeTicks send_time_;
506 base::TimeTicks recv_first_byte_time_;
507 base::TimeTicks recv_last_byte_time_;
508
509 // Number of bytes that have been received on this stream, including frame
510 // overhead and headers.
511 int64_t raw_received_bytes_;
512 // Number of bytes that have been sent on this stream, including frame
513 // overhead and headers.
514 int64_t raw_sent_bytes_;
515
516 // Number of data bytes that have been sent/received on this stream, not
517 // including frame overhead. Note that this does not count headers.
518 int send_bytes_;
519 int recv_bytes_;
520
521 // Guards calls of delegate write handlers ensuring |this| is not destroyed.
522 // TODO(jgraettinger): Consider removing after crbug.com/35511 is tracked
523 // down.
524 bool write_handler_guard_;
525
526 base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;
527
528 DISALLOW_COPY_AND_ASSIGN(SpdyStream);
529 };
530
531 } // namespace net
532
533 #endif // NET_SPDY_SPDY_STREAM_H_
OLDNEW
« no previous file with comments | « net/spdy/spdy_session_unittest.cc ('k') | net/spdy/spdy_stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698