15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SPDY_SPDY_HTTP_STREAM_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SPDY_SPDY_HTTP_STREAM_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/spdy/spdy_read_queue.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/spdy/spdy_session.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_stream.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DrainableIOBuffer;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct HttpRequestInfo;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpResponseInfo;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IOBuffer;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdySession;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UploadDataStream;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The SpdyHttpStream is a HTTP-specific type of stream known to a SpdySession.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          public HttpStream {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // |spdy_session| must not be NULL.
34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, bool direct);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SpdyHttpStream();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyStream* stream() { return stream_.get(); }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancels any callbacks from being invoked and deletes the stream.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Cancel();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStream implementation.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int InitializeStream(const HttpRequestInfo* request_info,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               RequestPriority priority,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const BoundNetLog& net_log,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int SendRequest(const HttpRequestHeaders& headers,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          HttpResponseInfo* response,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const CompletionCallback& callback) OVERRIDE;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual UploadProgress GetUploadProgress() const OVERRIDE;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int ReadResponseBody(IOBuffer* buf,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               int buf_len,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Close(bool not_reusable) OVERRIDE;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HttpStream* RenewStreamForAuth() OVERRIDE;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsResponseBodyComplete() const OVERRIDE;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanFindEndOfResponse() const OVERRIDE;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Must not be called if a NULL SpdySession was pssed into the
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // constructor.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsConnectionReused() const OVERRIDE;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetConnectionReused() OVERRIDE;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsConnectionReusable() const OVERRIDE;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool GetLoadTimingInfo(
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoadTimingInfo* load_timing_info) const OVERRIDE;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetSSLCertRequestInfo(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLCertRequestInfo* cert_request_info) OVERRIDE;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsSpdyHttpStream() const OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Drain(HttpNetworkSession* session) OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SpdyStream::Delegate implementation.
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnRequestHeadersSent() OVERRIDE;
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated(
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SpdyHeaderBlock& response_headers) OVERRIDE;
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE;
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnDataSent() OVERRIDE;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnClose(int status) OVERRIDE;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Must be called only when |request_info_| is non-NULL.
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool HasUploadData() const;
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnStreamCreated(const CompletionCallback& callback, int rv);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Reads the remaining data (whether chunked or not) from the
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // request body stream and sends it if there's any. The read and
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // subsequent sending may happen asynchronously. Must be called only
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // when HasUploadData() is true.
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void ReadAndSendRequestBodyData();
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Called when data has just been read from the request body stream;
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // does the actual sending of data.
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void OnRequestBodyReadCompleted(int status);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call the user callback.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoCallback(int rv);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleBufferedReadCallback();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the callback is invoked.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DoBufferedReadCallback();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ShouldWaitForMoreBufferedData() const;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<SpdyHttpStream> weak_factory_;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const base::WeakPtr<SpdySession> spdy_session_;
113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool is_reused_;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyStreamRequest stream_request_;
115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::WeakPtr<SpdyStream> stream_;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool stream_closed_;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set only when |stream_closed_| is true.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int closed_stream_status_;
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyStreamId closed_stream_id_;
122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool closed_stream_has_load_timing_info_;
123ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  LoadTimingInfo closed_stream_load_timing_info_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The request to send.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo* request_info_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |response_info_| is the HTTP response data object which is filled in
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when a SYN_REPLY comes in for the stream.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is not owned by this stream object, or point to |push_response_info_|.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpResponseInfo* response_info_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpResponseInfo> push_response_info_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't use SpdyStream's |response_header_status_| as we
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // sometimes call back into our delegate before it is updated.
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SpdyResponseHeadersStatus response_headers_status_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We buffer the response body as it arrives asynchronously from the stream.
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdyReadQueue response_body_queue_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompletionCallback callback_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // User provided buffer for the ReadResponseBody() response.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBuffer> user_buffer_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int user_buffer_len_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Temporary buffer used to read the request body from UploadDataStream.
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<IOBufferWithSize> request_body_buf_;
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int request_body_buf_size_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is there a scheduled read callback pending.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool buffered_read_callback_pending_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Has more data been received from the network during the wait for the
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scheduled read callback.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool more_read_data_pending_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is this spdy stream direct to the origin server (or to a proxy).
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool direct_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SpdyHttpStream);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_SPDY_SPDY_HTTP_STREAM_H_
167