Make certificate viewer a tab-modal dialog.
[chromium-blink-merge.git] / net / spdy / spdy_stream.h
blobd3ef69f76733e949fb94e846bfedd370b09f91ed
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.
5 #ifndef NET_SPDY_SPDY_STREAM_H_
6 #define NET_SPDY_SPDY_STREAM_H_
8 #include <deque>
9 #include <string>
10 #include <vector>
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 "googleurl/src/gurl.h"
18 #include "net/base/bandwidth_metrics.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/net_export.h"
21 #include "net/base/net_log.h"
22 #include "net/base/request_priority.h"
23 #include "net/socket/ssl_client_socket.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/spdy/spdy_session.h"
28 #include "net/ssl/server_bound_cert_service.h"
29 #include "net/ssl/ssl_client_cert_type.h"
31 namespace net {
33 class AddressList;
34 class IPEndPoint;
35 class SSLCertRequestInfo;
36 class SSLInfo;
38 // Returned by some SpdyStream::Delegate functions to indicate whether
39 // there's more data to send.
40 enum SpdySendStatus {
41 MORE_DATA_TO_SEND,
42 NO_MORE_DATA_TO_SEND
45 // The SpdyStream is used by the SpdySession to represent each stream known
46 // on the SpdySession. This class provides interfaces for SpdySession to use.
47 // Streams can be created either by the client or by the server. When they
48 // are initiated by the client, both the SpdySession and client object (such as
49 // a SpdyNetworkTransaction) will maintain a reference to the stream. When
50 // initiated by the server, only the SpdySession will maintain any reference,
51 // until such a time as a client object requests a stream for the path.
52 class NET_EXPORT_PRIVATE SpdyStream
53 : public base::RefCounted<SpdyStream> {
54 public:
55 // Delegate handles protocol specific behavior of spdy stream.
56 class NET_EXPORT_PRIVATE Delegate {
57 public:
58 Delegate() {}
60 // Called when SYN frame has been sent.
61 // Returns true if no more data to be sent after SYN frame.
62 virtual SpdySendStatus OnSendHeadersComplete() = 0;
64 // Called when stream is ready to send data.
65 // Returns network error code. OK when it successfully sent data.
66 // ERR_IO_PENDING when performing operation asynchronously.
67 virtual int OnSendBody() = 0;
69 // Called when body data has been sent. |bytes_sent| is the number
70 // of bytes that has been sent (may be zero). Must return whether
71 // there's more body data to send.
72 virtual SpdySendStatus OnSendBodyComplete(size_t bytes_sent) = 0;
74 // Called when the SYN_STREAM, SYN_REPLY, or HEADERS frames are received.
75 // Normal streams will receive a SYN_REPLY and optional HEADERS frames.
76 // Pushed streams will receive a SYN_STREAM and optional HEADERS frames.
77 // Because a stream may have a SYN_* frame and multiple HEADERS frames,
78 // this callback may be called multiple times.
79 // |status| indicates network error. Returns network error code.
80 virtual int OnResponseReceived(const SpdyHeaderBlock& response,
81 base::Time response_time,
82 int status) = 0;
84 // Called when a HEADERS frame is sent.
85 virtual void OnHeadersSent() = 0;
87 // Called when data is received. |buffer| may be NULL, which
88 // signals EOF. Must return OK if the data was received
89 // successfully, or a network error code otherwise.
90 virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) = 0;
92 // Called when data is sent.
93 virtual void OnDataSent(size_t bytes_sent) = 0;
95 // Called when SpdyStream is closed. No other delegate functions
96 // will be called after this is called, and the delegate must not
97 // access the stream after this is called.
98 virtual void OnClose(int status) = 0;
100 protected:
101 virtual ~Delegate() {}
103 private:
104 DISALLOW_COPY_AND_ASSIGN(Delegate);
107 // SpdyStream constructor
108 SpdyStream(SpdySession* session,
109 const std::string& path,
110 RequestPriority priority,
111 int32 initial_send_window_size,
112 int32 initial_recv_window_size,
113 bool pushed,
114 const BoundNetLog& net_log);
116 // Set new |delegate|. |delegate| must not be NULL.
117 // If it already received SYN_REPLY or data, OnResponseReceived() or
118 // OnDataReceived() will be called.
119 void SetDelegate(Delegate* delegate);
120 Delegate* GetDelegate() { return delegate_; }
122 // Detach delegate from the stream. It will cancel the stream if it was not
123 // cancelled yet. It is safe to call multiple times.
124 void DetachDelegate();
126 // Is this stream a pushed stream from the server.
127 bool pushed() const { return pushed_; }
129 SpdyStreamId stream_id() const { return stream_id_; }
130 void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; }
132 bool response_received() const { return response_received_; }
133 void set_response_received() { response_received_ = true; }
135 // For pushed streams, we track a path to identify them.
136 const std::string& path() const { return path_; }
138 RequestPriority priority() const { return priority_; }
140 int32 send_window_size() const { return send_window_size_; }
142 int32 recv_window_size() const { return recv_window_size_; }
144 bool send_stalled_by_flow_control() { return send_stalled_by_flow_control_; }
146 void set_send_stalled_by_flow_control(bool stalled) {
147 send_stalled_by_flow_control_ = stalled;
150 // Called by the session to adjust this stream's send window size by
151 // |delta_window_size|, which is the difference between the
152 // SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame
153 // and the previous initial send window size, possibly unstalling
154 // this stream. Although |delta_window_size| may cause this stream's
155 // send window size to go negative, it must not cause it to wrap
156 // around in either direction. Does nothing if the stream is already
157 // closed.
159 // If stream flow control is turned off, this must not be called.
160 void AdjustSendWindowSize(int32 delta_window_size);
162 // Called when bytes are consumed from a SpdyBuffer for a DATA frame
163 // that is to be written or is being written. Increases the send
164 // window size accordingly if some or all of the SpdyBuffer is being
165 // discarded.
167 // If stream flow control is turned off, this must not be called.
168 void OnWriteBufferConsumed(size_t frame_payload_size,
169 size_t consume_size,
170 SpdyBuffer::ConsumeSource consume_source);
172 // Called by the session to increase this stream's send window size
173 // by |delta_window_size| (which must be at least 1) from a received
174 // WINDOW_UPDATE frame or from a dropped DATA frame that was
175 // intended to be sent, possibly unstalling this stream. If
176 // |delta_window_size| would cause this stream's send window size to
177 // overflow, calls into the session to reset this stream. Does
178 // nothing if the stream is already closed.
180 // If stream flow control is turned off, this must not be called.
181 void IncreaseSendWindowSize(int32 delta_window_size);
183 // If stream flow control is turned on, called by the session to
184 // decrease this stream's send window size by |delta_window_size|,
185 // which must be at least 0 and at most kMaxSpdyFrameChunkSize.
186 // |delta_window_size| must not cause this stream's send window size
187 // to go negative. Does nothing if the stream is already closed.
189 // If stream flow control is turned off, this must not be called.
190 void DecreaseSendWindowSize(int32 delta_window_size);
192 // Called when bytes are consumed by the delegate from a SpdyBuffer
193 // containing received data. Increases the receive window size
194 // accordingly.
196 // If stream flow control is turned off, this must not be called.
197 void OnReadBufferConsumed(size_t consume_size,
198 SpdyBuffer::ConsumeSource consume_source);
200 // Called by OnReadBufferConsume to increase this stream's receive
201 // window size by |delta_window_size|, which must be at least 1 and
202 // must not cause this stream's receive window size to overflow,
203 // possibly also sending a WINDOW_UPDATE frame. Does nothing if the
204 // stream is not active.
206 // If stream flow control is turned off, this must not be called.
207 void IncreaseRecvWindowSize(int32 delta_window_size);
209 // Called by OnDataReceived (which is in turn called by the session)
210 // to decrease this stream's receive window size by
211 // |delta_window_size|, which must be at least 1 and must not cause
212 // this stream's receive window size to go negative.
214 // If stream flow control is turned off or the stream is not active,
215 // this must not be called.
216 void DecreaseRecvWindowSize(int32 delta_window_size);
218 int GetPeerAddress(IPEndPoint* address) const;
219 int GetLocalAddress(IPEndPoint* address) const;
221 // Returns true if the underlying transport socket ever had any reads or
222 // writes.
223 bool WasEverUsed() const;
225 const BoundNetLog& net_log() const { return net_log_; }
227 const SpdyHeaderBlock& spdy_headers() const;
228 void set_spdy_headers(scoped_ptr<SpdyHeaderBlock> headers);
229 base::Time GetRequestTime() const;
230 void SetRequestTime(base::Time t);
232 // Called by the SpdySession when a response (e.g. a SYN_STREAM or SYN_REPLY)
233 // has been received for this stream. Returns a status code.
234 int OnResponseReceived(const SpdyHeaderBlock& response);
236 // Called by the SpdySession when late-bound headers are received for a
237 // stream. Returns a status code.
238 int OnHeaders(const SpdyHeaderBlock& headers);
240 // Called by the SpdySession when response data has been received for this
241 // stream. This callback may be called multiple times as data arrives
242 // from the network, and will never be called prior to OnResponseReceived.
244 // |buffer| contains the data received, or NULL if the stream is
245 // being closed. The stream must copy any data from this
246 // buffer before returning from this callback.
248 // |length| is the number of bytes received (at most 2^24 - 1) or 0 if
249 // the stream is being closed.
250 void OnDataReceived(scoped_ptr<SpdyBuffer> buffer);
252 // Called by the SpdySession when a frame has been successfully and
253 // completely written. |frame_size| is the total size of the frame
254 // in bytes, including framing overhead.
255 void OnFrameWriteComplete(SpdyFrameType frame_type, size_t frame_size);
257 // Called by the SpdySession when the request is finished. This callback
258 // will always be called at the end of the request and signals to the
259 // stream that the stream has no more network events. No further callbacks
260 // to the stream will be made after this call.
261 // |status| is an error code or OK.
262 void OnClose(int status);
264 // Called by the SpdySession to log stream related errors.
265 void LogStreamError(int status, const std::string& description);
267 void Cancel();
268 void Close();
269 bool cancelled() const { return cancelled_; }
270 bool closed() const { return io_state_ == STATE_DONE; }
271 // TODO(satorux): This is only for testing. We should be able to remove
272 // this once crbug.com/113107 is addressed.
273 bool body_sent() const { return io_state_ > STATE_SEND_BODY_COMPLETE; }
275 // Interface for Spdy[Http|WebSocket]Stream to use.
277 // Sends the request.
278 // For non push stream, it will send SYN_STREAM frame.
279 int SendRequest(bool has_upload_data);
281 // Queues a HEADERS frame to be sent.
282 void QueueHeaders(scoped_ptr<SpdyHeaderBlock> headers);
284 // Queues a DATA frame to be sent. May not queue all the data that
285 // is given (or even any of it) depending on flow control.
286 void QueueStreamData(IOBuffer* data, int length,
287 SpdyDataFlags flags);
289 // Fills SSL info in |ssl_info| and returns true when SSL is in use.
290 bool GetSSLInfo(SSLInfo* ssl_info,
291 bool* was_npn_negotiated,
292 NextProto* protocol_negotiated);
294 // Fills SSL Certificate Request info |cert_request_info| and returns
295 // true when SSL is in use.
296 bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
298 // If the stream is stalled on sending data, but the session is not
299 // stalled on sending data and |send_window_size_| is positive, then
300 // set |send_stalled_by_flow_control_| to false and unstall the data
301 // sending. Called by the session or by the stream itself. Must be
302 // called only when the stream is still open.
303 void PossiblyResumeIfSendStalled();
305 bool is_idle() const {
306 return io_state_ == STATE_OPEN || io_state_ == STATE_DONE;
309 int response_status() const { return response_status_; }
311 // Returns true if the URL for this stream is known.
312 bool HasUrl() const;
314 // Get the URL associated with this stream. Only valid when has_url() is
315 // true.
316 GURL GetUrl() const;
318 int GetProtocolVersion() const;
320 private:
321 class SynStreamBufferProducer;
322 class HeaderBufferProducer;
324 enum State {
325 STATE_NONE,
326 STATE_GET_DOMAIN_BOUND_CERT,
327 STATE_GET_DOMAIN_BOUND_CERT_COMPLETE,
328 STATE_SEND_DOMAIN_BOUND_CERT,
329 STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE,
330 STATE_SEND_HEADERS,
331 STATE_SEND_HEADERS_COMPLETE,
332 STATE_SEND_BODY,
333 STATE_SEND_BODY_COMPLETE,
334 STATE_WAITING_FOR_RESPONSE,
335 STATE_OPEN,
336 STATE_DONE
339 friend class base::RefCounted<SpdyStream>;
341 virtual ~SpdyStream();
343 void OnGetDomainBoundCertComplete(int result);
345 // Try to make progress sending/receiving the request/response.
346 int DoLoop(int result);
348 // The implementations of each state of the state machine.
349 int DoGetDomainBoundCert();
350 int DoGetDomainBoundCertComplete(int result);
351 int DoSendDomainBoundCert();
352 int DoSendDomainBoundCertComplete();
353 int DoSendHeaders();
354 int DoSendHeadersComplete();
355 int DoSendBody();
356 int DoSendBodyComplete();
357 int DoReadHeaders();
358 int DoReadHeadersComplete(int result);
359 int DoOpen();
361 // Update the histograms. Can safely be called repeatedly, but should only
362 // be called after the stream has completed.
363 void UpdateHistograms();
365 // When a server pushed stream is first created, this function is posted on
366 // the MessageLoop to replay all the data that the server has already sent.
367 void PushedStreamReplayData();
369 // Produces the SYN_STREAM frame for the stream. The stream must
370 // already be activated.
371 scoped_ptr<SpdyFrame> ProduceSynStreamFrame();
373 // Produce the initial HEADER frame for the stream with the given
374 // block. The stream must already be activated.
375 scoped_ptr<SpdyFrame> ProduceHeaderFrame(
376 scoped_ptr<SpdyHeaderBlock> header_block);
378 base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;
380 // There is a small period of time between when a server pushed stream is
381 // first created, and the pushed data is replayed. Any data received during
382 // this time should continue to be buffered.
383 bool continue_buffering_data_;
385 SpdyStreamId stream_id_;
386 const std::string path_;
387 const RequestPriority priority_;
388 size_t slot_;
390 // Flow control variables.
391 bool send_stalled_by_flow_control_;
392 int32 send_window_size_;
393 int32 recv_window_size_;
394 int32 unacked_recv_window_bytes_;
396 const bool pushed_;
397 ScopedBandwidthMetrics metrics_;
398 bool response_received_;
400 scoped_refptr<SpdySession> session_;
402 // The transaction should own the delegate.
403 SpdyStream::Delegate* delegate_;
405 // The request to send.
406 scoped_ptr<SpdyHeaderBlock> request_;
408 // The time at which the request was made that resulted in this response.
409 // For cached responses, this time could be "far" in the past.
410 base::Time request_time_;
412 scoped_ptr<SpdyHeaderBlock> response_;
413 base::Time response_time_;
415 State io_state_;
417 // Since we buffer the response, we also buffer the response status.
418 // Not valid until the stream is closed.
419 int response_status_;
421 bool cancelled_;
422 bool has_upload_data_;
424 BoundNetLog net_log_;
426 base::TimeTicks send_time_;
427 base::TimeTicks recv_first_byte_time_;
428 base::TimeTicks recv_last_byte_time_;
430 // Number of data bytes that have been sent/received on this stream, not
431 // including frame overhead. Note that this does not count headers.
432 int send_bytes_;
433 int recv_bytes_;
435 // Data received before delegate is attached.
436 ScopedVector<SpdyBuffer> pending_buffers_;
438 SSLClientCertType domain_bound_cert_type_;
439 std::string domain_bound_private_key_;
440 std::string domain_bound_cert_;
441 ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;
443 // When OnFrameWriteComplete() is called, these variables are set.
444 SpdyFrameType just_completed_frame_type_;
445 size_t just_completed_frame_size_;
447 DISALLOW_COPY_AND_ASSIGN(SpdyStream);
450 } // namespace net
452 #endif // NET_SPDY_SPDY_STREAM_H_