OLD | NEW |
| (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 <deque> | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/memory/ref_counted.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/memory/scoped_vector.h" | |
16 #include "base/memory/weak_ptr.h" | |
17 #include "net/base/bandwidth_metrics.h" | |
18 #include "net/base/io_buffer.h" | |
19 #include "net/base/net_export.h" | |
20 #include "net/base/net_log.h" | |
21 #include "net/base/request_priority.h" | |
22 #include "net/socket/ssl_client_socket.h" | |
23 #include "net/spdy/spdy_buffer.h" | |
24 #include "net/spdy/spdy_framer.h" | |
25 #include "net/spdy/spdy_header_block.h" | |
26 #include "net/spdy/spdy_protocol.h" | |
27 #include "net/ssl/ssl_client_cert_type.h" | |
28 #include "url/gurl.h" | |
29 | |
30 namespace net { | |
31 | |
32 class AddressList; | |
33 class IPEndPoint; | |
34 struct LoadTimingInfo; | |
35 class SSLCertRequestInfo; | |
36 class SSLInfo; | |
37 class SpdySession; | |
38 | |
39 enum SpdyStreamType { | |
40 // The most general type of stream; there are no restrictions on | |
41 // when data can be sent and received. | |
42 SPDY_BIDIRECTIONAL_STREAM, | |
43 // A stream where the client sends a request with possibly a body, | |
44 // and the server then sends a response with a body. | |
45 SPDY_REQUEST_RESPONSE_STREAM, | |
46 // A server-initiated stream where the server just sends a response | |
47 // with a body and the client does not send anything. | |
48 SPDY_PUSH_STREAM | |
49 }; | |
50 | |
51 // Passed to some SpdyStream functions to indicate whether there's | |
52 // more data to send. | |
53 enum SpdySendStatus { | |
54 MORE_DATA_TO_SEND, | |
55 NO_MORE_DATA_TO_SEND | |
56 }; | |
57 | |
58 // Returned by SpdyStream::OnResponseHeadersUpdated() to indicate | |
59 // whether the current response headers are complete or not. | |
60 enum SpdyResponseHeadersStatus { | |
61 RESPONSE_HEADERS_ARE_INCOMPLETE, | |
62 RESPONSE_HEADERS_ARE_COMPLETE | |
63 }; | |
64 | |
65 // The SpdyStream is used by the SpdySession to represent each stream known | |
66 // on the SpdySession. This class provides interfaces for SpdySession to use. | |
67 // Streams can be created either by the client or by the server. When they | |
68 // are initiated by the client, both the SpdySession and client object (such as | |
69 // a SpdyNetworkTransaction) will maintain a reference to the stream. When | |
70 // initiated by the server, only the SpdySession will maintain any reference, | |
71 // until such a time as a client object requests a stream for the path. | |
72 class NET_EXPORT_PRIVATE SpdyStream { | |
73 public: | |
74 // Delegate handles protocol specific behavior of spdy stream. | |
75 class NET_EXPORT_PRIVATE Delegate { | |
76 public: | |
77 Delegate() {} | |
78 | |
79 // Called when the request headers have been sent. Never called | |
80 // for push streams. Must not cause the stream to be closed. | |
81 virtual void OnRequestHeadersSent() = 0; | |
82 | |
83 // WARNING: This function is complicated! Be sure to read the | |
84 // whole comment below if you're working with code that implements | |
85 // or calls this function. | |
86 // | |
87 // Called when the response headers are updated from the | |
88 // server. |response_headers| contains the set of all headers | |
89 // received up to this point; delegates can assume that any | |
90 // headers previously received remain unchanged. | |
91 // | |
92 // This is called at least once before any data is received. If | |
93 // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this will be | |
94 // called again when more headers are received until | |
95 // RESPONSE_HEADERS_ARE_COMPLETE is returned, and any data | |
96 // received before then will be treated as a protocol error. | |
97 // | |
98 // If RESPONSE_HEADERS_ARE_INCOMPLETE is returned, the delegate | |
99 // must not have closed the stream. Otherwise, if | |
100 // RESPONSE_HEADERS_ARE_COMPLETE is returned, the delegate has | |
101 // processed the headers successfully. However, it still may have | |
102 // closed the stream, e.g. if the headers indicated an error | |
103 // condition. | |
104 // | |
105 // Some type-specific behavior: | |
106 // | |
107 // - For bidirectional streams, this may be called even after | |
108 // data is received, but it is expected that | |
109 // RESPONSE_HEADERS_ARE_COMPLETE is always returned. If | |
110 // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is | |
111 // treated as a protocol error. | |
112 // | |
113 // - For request/response streams, this function is called | |
114 // exactly once before data is received, and it is expected | |
115 // that RESPONSE_HEADERS_ARE_COMPLETE is returned. If | |
116 // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is | |
117 // treated as a protocol error. | |
118 // | |
119 // - For push streams, it is expected that this function will be | |
120 // called until RESPONSE_HEADERS_ARE_COMPLETE is returned | |
121 // before any data is received; any deviation from this is | |
122 // treated as a protocol error. | |
123 // | |
124 // TODO(akalin): Treat headers received after data has been | |
125 // received as a protocol error for non-bidirectional streams. | |
126 // TODO(jgraettinger): This should be at the semantic (HTTP) rather | |
127 // than stream layer. Streams shouldn't have a notion of header | |
128 // completeness. Move to SpdyHttpStream/SpdyWebsocketStream. | |
129 virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated( | |
130 const SpdyHeaderBlock& response_headers) = 0; | |
131 | |
132 // Called when data is received after all required response | |
133 // headers have been received. |buffer| may be NULL, which signals | |
134 // EOF. Must return OK if the data was received successfully, or | |
135 // a network error code otherwise. | |
136 // | |
137 // May cause the stream to be closed. | |
138 virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) = 0; | |
139 | |
140 // Called when data is sent. Must not cause the stream to be | |
141 // closed. | |
142 virtual void OnDataSent() = 0; | |
143 | |
144 // Called when SpdyStream is closed. No other delegate functions | |
145 // will be called after this is called, and the delegate must not | |
146 // access the stream after this is called. Must not cause the | |
147 // stream to be be (re-)closed. | |
148 // | |
149 // TODO(akalin): Allow this function to re-close the stream and | |
150 // handle it gracefully. | |
151 virtual void OnClose(int status) = 0; | |
152 | |
153 protected: | |
154 virtual ~Delegate() {} | |
155 | |
156 private: | |
157 DISALLOW_COPY_AND_ASSIGN(Delegate); | |
158 }; | |
159 | |
160 // SpdyStream constructor | |
161 SpdyStream(SpdyStreamType type, | |
162 const base::WeakPtr<SpdySession>& session, | |
163 const GURL& url, | |
164 RequestPriority priority, | |
165 int32 initial_send_window_size, | |
166 int32 initial_recv_window_size, | |
167 const BoundNetLog& net_log); | |
168 | |
169 ~SpdyStream(); | |
170 | |
171 // Set the delegate, which must not be NULL. Must not be called more | |
172 // than once. For push streams, calling this may cause buffered data | |
173 // to be sent to the delegate (from a posted task). | |
174 void SetDelegate(Delegate* delegate); | |
175 | |
176 // Detach the delegate from the stream, which must not yet be | |
177 // closed, and cancel it. | |
178 void DetachDelegate(); | |
179 | |
180 // The time at which the first bytes of the response were received | |
181 // from the server, or null if the response hasn't been received | |
182 // yet. | |
183 base::Time response_time() const { return response_time_; } | |
184 | |
185 SpdyStreamType type() const { return type_; } | |
186 | |
187 SpdyStreamId stream_id() const { return stream_id_; } | |
188 void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; } | |
189 | |
190 const GURL& url() const { return url_; } | |
191 | |
192 RequestPriority priority() const { return priority_; } | |
193 | |
194 int32 send_window_size() const { return send_window_size_; } | |
195 | |
196 int32 recv_window_size() const { return recv_window_size_; } | |
197 | |
198 bool send_stalled_by_flow_control() const { | |
199 return send_stalled_by_flow_control_; | |
200 } | |
201 | |
202 void set_send_stalled_by_flow_control(bool stalled) { | |
203 send_stalled_by_flow_control_ = stalled; | |
204 } | |
205 | |
206 // Called by the session to adjust this stream's send window size by | |
207 // |delta_window_size|, which is the difference between the | |
208 // SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame | |
209 // and the previous initial send window size, possibly unstalling | |
210 // this stream. Although |delta_window_size| may cause this stream's | |
211 // send window size to go negative, it must not cause it to wrap | |
212 // around in either direction. Does nothing if the stream is already | |
213 // closed. | |
214 // | |
215 // If stream flow control is turned off, this must not be called. | |
216 void AdjustSendWindowSize(int32 delta_window_size); | |
217 | |
218 // Called when bytes are consumed from a SpdyBuffer for a DATA frame | |
219 // that is to be written or is being written. Increases the send | |
220 // window size accordingly if some or all of the SpdyBuffer is being | |
221 // discarded. | |
222 // | |
223 // If stream flow control is turned off, this must not be called. | |
224 void OnWriteBufferConsumed(size_t frame_payload_size, | |
225 size_t consume_size, | |
226 SpdyBuffer::ConsumeSource consume_source); | |
227 | |
228 // Called by the session to increase this stream's send window size | |
229 // by |delta_window_size| (which must be at least 1) from a received | |
230 // WINDOW_UPDATE frame or from a dropped DATA frame that was | |
231 // intended to be sent, possibly unstalling this stream. If | |
232 // |delta_window_size| would cause this stream's send window size to | |
233 // overflow, calls into the session to reset this stream. Does | |
234 // nothing if the stream is already closed. | |
235 // | |
236 // If stream flow control is turned off, this must not be called. | |
237 void IncreaseSendWindowSize(int32 delta_window_size); | |
238 | |
239 // If stream flow control is turned on, called by the session to | |
240 // decrease this stream's send window size by |delta_window_size|, | |
241 // which must be at least 0 and at most kMaxSpdyFrameChunkSize. | |
242 // |delta_window_size| must not cause this stream's send window size | |
243 // to go negative. Does nothing if the stream is already closed. | |
244 // | |
245 // If stream flow control is turned off, this must not be called. | |
246 void DecreaseSendWindowSize(int32 delta_window_size); | |
247 | |
248 // Called when bytes are consumed by the delegate from a SpdyBuffer | |
249 // containing received data. Increases the receive window size | |
250 // accordingly. | |
251 // | |
252 // If stream flow control is turned off, this must not be called. | |
253 void OnReadBufferConsumed(size_t consume_size, | |
254 SpdyBuffer::ConsumeSource consume_source); | |
255 | |
256 // Called by OnReadBufferConsume to increase this stream's receive | |
257 // window size by |delta_window_size|, which must be at least 1 and | |
258 // must not cause this stream's receive window size to overflow, | |
259 // possibly also sending a WINDOW_UPDATE frame. Does nothing if the | |
260 // stream is not active. | |
261 // | |
262 // If stream flow control is turned off, this must not be called. | |
263 void IncreaseRecvWindowSize(int32 delta_window_size); | |
264 | |
265 // Called by OnDataReceived (which is in turn called by the session) | |
266 // to decrease this stream's receive window size by | |
267 // |delta_window_size|, which must be at least 1 and must not cause | |
268 // this stream's receive window size to go negative. | |
269 // | |
270 // If stream flow control is turned off or the stream is not active, | |
271 // this must not be called. | |
272 void DecreaseRecvWindowSize(int32 delta_window_size); | |
273 | |
274 int GetPeerAddress(IPEndPoint* address) const; | |
275 int GetLocalAddress(IPEndPoint* address) const; | |
276 | |
277 // Returns true if the underlying transport socket ever had any reads or | |
278 // writes. | |
279 bool WasEverUsed() const; | |
280 | |
281 const BoundNetLog& net_log() const { return net_log_; } | |
282 | |
283 base::Time GetRequestTime() const; | |
284 void SetRequestTime(base::Time t); | |
285 | |
286 // Called at most once by the SpdySession when the initial response | |
287 // headers have been received for this stream, i.e., a SYN_REPLY (or | |
288 // SYN_STREAM for push streams) frame has been received. Returns a status | |
289 // code; if it is an error, the stream was closed by this function. | |
290 int OnInitialResponseHeadersReceived(const SpdyHeaderBlock& response_headers, | |
291 base::Time response_time, | |
292 base::TimeTicks recv_first_byte_time); | |
293 | |
294 // Called by the SpdySession (only after | |
295 // OnInitialResponseHeadersReceived() has been called) when | |
296 // late-bound headers are received for a stream. Returns a status | |
297 // code; if it is an error, the stream was closed by this function. | |
298 int OnAdditionalResponseHeadersReceived( | |
299 const SpdyHeaderBlock& additional_response_headers); | |
300 | |
301 // Called by the SpdySession when a frame carrying request headers opening a | |
302 // push stream is received. Stream transits to STATE_RESERVED_REMOTE state. | |
303 void OnPushPromiseHeadersReceived(const SpdyHeaderBlock& headers); | |
304 | |
305 // Called by the SpdySession when response data has been received | |
306 // for this stream. This callback may be called multiple times as | |
307 // data arrives from the network, and will never be called prior to | |
308 // OnResponseHeadersReceived. | |
309 // | |
310 // |buffer| contains the data received, or NULL if the stream is | |
311 // being closed. The stream must copy any data from this | |
312 // buffer before returning from this callback. | |
313 // | |
314 // |length| is the number of bytes received (at most 2^24 - 1) or 0 if | |
315 // the stream is being closed. | |
316 void OnDataReceived(scoped_ptr<SpdyBuffer> buffer); | |
317 | |
318 // Called by the SpdySession when a frame has been successfully and | |
319 // completely written. |frame_size| is the total size of the frame | |
320 // in bytes, including framing overhead. | |
321 void OnFrameWriteComplete(SpdyFrameType frame_type, size_t frame_size); | |
322 | |
323 // SYN_STREAM-specific write handler invoked by OnFrameWriteComplete(). | |
324 int OnRequestHeadersSent(); | |
325 | |
326 // DATA-specific write handler invoked by OnFrameWriteComplete(). | |
327 // If more data is already available to be written, the next write is | |
328 // queued and ERR_IO_PENDING is returned. Returns OK otherwise. | |
329 int OnDataSent(size_t frame_size); | |
330 | |
331 // Called by the SpdySession when the request is finished. This callback | |
332 // will always be called at the end of the request and signals to the | |
333 // stream that the stream has no more network events. No further callbacks | |
334 // to the stream will be made after this call. | |
335 // |status| is an error code or OK. | |
336 void OnClose(int status); | |
337 | |
338 // Called by the SpdySession to log stream related errors. | |
339 void LogStreamError(int status, const std::string& description); | |
340 | |
341 // If this stream is active, reset it, and close it otherwise. In | |
342 // either case the stream is deleted. | |
343 void Cancel(); | |
344 | |
345 // Close this stream without sending a RST_STREAM and delete | |
346 // it. | |
347 void Close(); | |
348 | |
349 // Must be used only by |session_|. | |
350 base::WeakPtr<SpdyStream> GetWeakPtr(); | |
351 | |
352 // Interface for the delegate to use. | |
353 | |
354 // Only one send can be in flight at a time, except for push | |
355 // streams, which must not send anything. | |
356 | |
357 // Sends the request headers. The delegate is called back via | |
358 // OnRequestHeadersSent() when the request headers have completed | |
359 // sending. |send_status| must be MORE_DATA_TO_SEND for | |
360 // bidirectional streams; for request/response streams, it must be | |
361 // MORE_DATA_TO_SEND if the request has data to upload, or | |
362 // NO_MORE_DATA_TO_SEND if not. | |
363 int SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, | |
364 SpdySendStatus send_status); | |
365 | |
366 // Sends a DATA frame. The delegate will be notified via | |
367 // OnDataSent() when the send is complete. |send_status| must be | |
368 // MORE_DATA_TO_SEND for bidirectional streams; for request/response | |
369 // streams, it must be MORE_DATA_TO_SEND if there is more data to | |
370 // upload, or NO_MORE_DATA_TO_SEND if not. | |
371 void SendData(IOBuffer* data, int length, SpdySendStatus send_status); | |
372 | |
373 // Fills SSL info in |ssl_info| and returns true when SSL is in use. | |
374 bool GetSSLInfo(SSLInfo* ssl_info, | |
375 bool* was_npn_negotiated, | |
376 NextProto* protocol_negotiated); | |
377 | |
378 // Fills SSL Certificate Request info |cert_request_info| and returns | |
379 // true when SSL is in use. | |
380 bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); | |
381 | |
382 // If the stream is stalled on sending data, but the session is not | |
383 // stalled on sending data and |send_window_size_| is positive, then | |
384 // set |send_stalled_by_flow_control_| to false and unstall the data | |
385 // sending. Called by the session or by the stream itself. Must be | |
386 // called only when the stream is still open. | |
387 void PossiblyResumeIfSendStalled(); | |
388 | |
389 // Returns whether or not this stream is closed. Note that the only | |
390 // time a stream is closed and not deleted is in its delegate's | |
391 // OnClose() method. | |
392 bool IsClosed() const; | |
393 | |
394 // Returns whether the streams local endpoint is closed. | |
395 // The remote endpoint may still be active. | |
396 bool IsLocallyClosed() const; | |
397 | |
398 // Returns whether this stream is IDLE: request and response headers | |
399 // have neither been sent nor receieved. | |
400 bool IsIdle() const; | |
401 | |
402 // Returns whether or not this stream is fully open: that request and | |
403 // response headers are complete, and it is not in a half-closed state. | |
404 bool IsOpen() const; | |
405 | |
406 // Returns whether the stream is reserved by remote endpoint: server has sent | |
407 // intended request headers for a pushed stream, but haven't started response | |
408 // yet. | |
409 bool IsReservedRemote() const; | |
410 | |
411 // Returns the protocol used by this stream. Always between | |
412 // kProtoSPDYMinimumVersion and kProtoSPDYMaximumVersion. | |
413 NextProto GetProtocol() const; | |
414 | |
415 int response_status() const { return response_status_; } | |
416 | |
417 void IncrementRawReceivedBytes(size_t received_bytes) { | |
418 raw_received_bytes_ += received_bytes; | |
419 } | |
420 | |
421 int64 raw_received_bytes() const { return raw_received_bytes_; } | |
422 | |
423 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; | |
424 | |
425 // Get the URL from the appropriate stream headers, or the empty | |
426 // GURL() if it is unknown. | |
427 // | |
428 // TODO(akalin): Figure out if we really need this function, | |
429 // i.e. can we just use the URL this stream was created with and/or | |
430 // one we receive headers validate that the URL from them is the | |
431 // same. | |
432 GURL GetUrlFromHeaders() const; | |
433 | |
434 // Returns whether the URL for this stream is known. | |
435 // | |
436 // TODO(akalin): Remove this, as it's only used in tests. | |
437 bool HasUrlFromHeaders() const; | |
438 | |
439 SpdyMajorVersion GetProtocolVersion() const; | |
440 | |
441 private: | |
442 class SynStreamBufferProducer; | |
443 class HeaderBufferProducer; | |
444 | |
445 // SpdyStream states and transitions are modeled | |
446 // on the HTTP/2 stream state machine. All states and transitions | |
447 // are modeled, with the exceptions of RESERVED_LOCAL (the client | |
448 // cannot initate push streams), and the transition to OPEN due to | |
449 // a remote SYN_STREAM (the client can only initate streams). | |
450 enum State { | |
451 STATE_IDLE, | |
452 STATE_OPEN, | |
453 STATE_HALF_CLOSED_LOCAL_UNCLAIMED, | |
454 STATE_HALF_CLOSED_LOCAL, | |
455 STATE_HALF_CLOSED_REMOTE, | |
456 STATE_RESERVED_REMOTE, | |
457 STATE_CLOSED, | |
458 }; | |
459 | |
460 // Update the histograms. Can safely be called repeatedly, but should only | |
461 // be called after the stream has completed. | |
462 void UpdateHistograms(); | |
463 | |
464 // When a server-push stream is claimed by SetDelegate(), this function is | |
465 // posted on the current MessageLoop to replay everything the server has sent. | |
466 // From the perspective of SpdyStream's state machine, headers, data, and | |
467 // FIN states received prior to the delegate being attached have not yet been | |
468 // read. While buffered by |pending_recv_data_| it's not until | |
469 // PushedStreamReplay() is invoked that reads are considered | |
470 // to have occurred, driving the state machine forward. | |
471 void PushedStreamReplay(); | |
472 | |
473 // Produces the SYN_STREAM frame for the stream. The stream must | |
474 // already be activated. | |
475 scoped_ptr<SpdyFrame> ProduceSynStreamFrame(); | |
476 | |
477 // Produce the initial HEADER frame for the stream with the given | |
478 // block. The stream must already be activated. | |
479 scoped_ptr<SpdyFrame> ProduceHeaderFrame( | |
480 scoped_ptr<SpdyHeaderBlock> header_block); | |
481 | |
482 // Queues the send for next frame of the remaining data in | |
483 // |pending_send_data_|. Must be called only when | |
484 // |pending_send_data_| is set. | |
485 void QueueNextDataFrame(); | |
486 | |
487 // Merge the given headers into |response_headers_| and calls | |
488 // OnResponseHeadersUpdated() on the delegate (if attached). | |
489 // Returns a status code; if it is an error, the stream was closed | |
490 // by this function. | |
491 int MergeWithResponseHeaders(const SpdyHeaderBlock& new_response_headers); | |
492 | |
493 static std::string DescribeState(State state); | |
494 | |
495 const SpdyStreamType type_; | |
496 | |
497 SpdyStreamId stream_id_; | |
498 const GURL url_; | |
499 const RequestPriority priority_; | |
500 | |
501 // Flow control variables. | |
502 bool send_stalled_by_flow_control_; | |
503 int32 send_window_size_; | |
504 int32 recv_window_size_; | |
505 int32 unacked_recv_window_bytes_; | |
506 | |
507 ScopedBandwidthMetrics metrics_; | |
508 | |
509 const base::WeakPtr<SpdySession> session_; | |
510 | |
511 // The transaction should own the delegate. | |
512 SpdyStream::Delegate* delegate_; | |
513 | |
514 // The headers for the request to send. | |
515 // | |
516 // TODO(akalin): Hang onto this only until we send it. This | |
517 // necessitates stashing the URL separately. | |
518 scoped_ptr<SpdyHeaderBlock> request_headers_; | |
519 | |
520 // Data waiting to be sent, and the close state of the local endpoint | |
521 // after the data is fully written. | |
522 scoped_refptr<DrainableIOBuffer> pending_send_data_; | |
523 SpdySendStatus pending_send_status_; | |
524 | |
525 // Data waiting to be received, and the close state of the remote endpoint | |
526 // after the data is fully read. Specifically, data received before the | |
527 // delegate is attached must be buffered and later replayed. A remote FIN | |
528 // is represented by a final, zero-length buffer. | |
529 ScopedVector<SpdyBuffer> pending_recv_data_; | |
530 | |
531 // The time at which the request was made that resulted in this response. | |
532 // For cached responses, this time could be "far" in the past. | |
533 base::Time request_time_; | |
534 | |
535 SpdyHeaderBlock response_headers_; | |
536 SpdyResponseHeadersStatus response_headers_status_; | |
537 base::Time response_time_; | |
538 | |
539 State io_state_; | |
540 | |
541 // Since we buffer the response, we also buffer the response status. | |
542 // Not valid until the stream is closed. | |
543 int response_status_; | |
544 | |
545 BoundNetLog net_log_; | |
546 | |
547 base::TimeTicks send_time_; | |
548 base::TimeTicks recv_first_byte_time_; | |
549 base::TimeTicks recv_last_byte_time_; | |
550 | |
551 // Number of bytes that have been received on this stream, including frame | |
552 // overhead and headers. | |
553 int64 raw_received_bytes_; | |
554 | |
555 // Number of data bytes that have been sent/received on this stream, not | |
556 // including frame overhead. Note that this does not count headers. | |
557 int send_bytes_; | |
558 int recv_bytes_; | |
559 | |
560 // Guards calls of delegate write handlers ensuring |this| is not destroyed. | |
561 // TODO(jgraettinger): Consider removing after crbug.com/35511 is tracked | |
562 // down. | |
563 bool write_handler_guard_; | |
564 | |
565 base::WeakPtrFactory<SpdyStream> weak_ptr_factory_; | |
566 | |
567 DISALLOW_COPY_AND_ASSIGN(SpdyStream); | |
568 }; | |
569 | |
570 } // namespace net | |
571 | |
572 #endif // NET_SPDY_SPDY_STREAM_H_ | |
OLD | NEW |