Home | History | Annotate | Download | only in flip
      1 // Copyright (c) 2009 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_FLIP_FLIP_STREAM_H_
      6 #define NET_FLIP_FLIP_STREAM_H_
      7 
      8 #include <string>
      9 #include <list>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/ref_counted.h"
     13 #include "base/scoped_ptr.h"
     14 #include "base/singleton.h"
     15 #include "net/base/bandwidth_metrics.h"
     16 #include "net/base/completion_callback.h"
     17 #include "net/base/io_buffer.h"
     18 #include "net/base/load_log.h"
     19 #include "net/flip/flip_framer.h"
     20 #include "net/flip/flip_protocol.h"
     21 
     22 namespace net {
     23 
     24 class FlipSession;
     25 class HttpRequestInfo;
     26 class HttpResponseInfo;
     27 class UploadData;
     28 class UploadDataStream;
     29 
     30 // The FlipStream is used by the FlipSession to represent each stream known
     31 // on the FlipSession.
     32 // Streams can be created either by the client or by the server.  When they
     33 // are initiated by the client, both the FlipSession and client object (such as
     34 // a FlipNetworkTransaction) will maintain a reference to the stream.  When
     35 // initiated by the server, only the FlipSession will maintain any reference,
     36 // until such a time as a client object requests a stream for the path.
     37 class FlipStream : public base::RefCounted<FlipStream> {
     38  public:
     39   // FlipStream constructor
     40   FlipStream(FlipSession* session, flip::FlipStreamId stream_id, bool pushed,
     41              LoadLog* log);
     42 
     43   // Ideally I'd use two abstract classes as interfaces for these two sections,
     44   // but since we're ref counted, I can't make both abstract classes inherit
     45   // from RefCounted or we'll have two separate ref counts for the same object.
     46   // TODO(willchan): Consider using linked_ptr here orcreating proxy wrappers
     47   // for FlipStream to provide the appropriate interface.
     48 
     49   // ===================================================
     50   // Interface for [Http|Flip]NetworkTransaction to use.
     51 
     52   // Sends the request.  If |upload_data| is non-NULL, sends that in the request
     53   // body.  |callback| is used when this completes asynchronously.  Note that
     54   // the actual SYN_STREAM packet will have already been sent by this point.
     55   // Also note that FlipStream takes ownership of |upload_data|.
     56   int SendRequest(UploadDataStream* upload_data,
     57                   HttpResponseInfo* response,
     58                   CompletionCallback* callback);
     59 
     60   // Reads the response headers.  Returns a net error code.
     61   int ReadResponseHeaders(CompletionCallback* callback);
     62 
     63   // Reads the response body.  Returns a net error code or the number of bytes
     64   // read.
     65   int ReadResponseBody(
     66       IOBuffer* buf, int buf_len, CompletionCallback* callback);
     67 
     68   // Cancels the stream.  Note that this does not immediately cause deletion of
     69   // the stream.  This function is used to cancel any callbacks from being
     70   // invoked.  TODO(willchan): It should also free up any memory associated with
     71   // the stream, such as IOBuffers.
     72   void Cancel();
     73 
     74   // Returns the number of bytes uploaded.
     75   uint64 GetUploadProgress() const;
     76 
     77   const HttpResponseInfo* GetResponseInfo() const;
     78 
     79   // Is this stream a pushed stream from the server.
     80   bool pushed() const { return pushed_; }
     81 
     82   // =================================
     83   // Interface for FlipSession to use.
     84 
     85   flip::FlipStreamId stream_id() const { return stream_id_; }
     86   void set_stream_id(flip::FlipStreamId stream_id) { stream_id_ = stream_id; }
     87 
     88   // For pushed streams, we track a path to identify them.
     89   const std::string& path() const { return path_; }
     90   void set_path(const std::string& path) { path_ = path; }
     91 
     92   int priority() const { return priority_; }
     93   void set_priority(int priority) { priority_ = priority; }
     94 
     95   // Called by the FlipSession when a response (e.g. a SYN_REPLY) has been
     96   // received for this stream.  |path| is the path of the URL for a server
     97   // initiated stream, otherwise is empty.
     98   void OnResponseReceived(const HttpResponseInfo& response);
     99 
    100   // Called by the FlipSession when response data has been received for this
    101   // stream.  This callback may be called multiple times as data arrives
    102   // from the network, and will never be called prior to OnResponseReceived.
    103   // |buffer| contains the data received.  The stream must copy any data
    104   //          from this buffer before returning from this callback.
    105   // |length| is the number of bytes received or an error.
    106   //         A zero-length count does not indicate end-of-stream.
    107   // Returns true on success and false on error.
    108   bool OnDataReceived(const char* buffer, int bytes);
    109 
    110   // Called by the FlipSession when a write has completed.  This callback
    111   // will be called multiple times for each write which completes.  Writes
    112   // include the SYN_STREAM write and also DATA frame writes.
    113   // |result| is the number of bytes written or a net error code.
    114   void OnWriteComplete(int status);
    115 
    116   // Called by the FlipSession when the request is finished.  This callback
    117   // will always be called at the end of the request and signals to the
    118   // stream that the stream has no more network events.  No further callbacks
    119   // to the stream will be made after this call.
    120   // |status| is an error code or OK.
    121   void OnClose(int status);
    122 
    123   bool cancelled() const { return cancelled_; }
    124 
    125  private:
    126   friend class base::RefCounted<FlipStream>;
    127 
    128   enum State {
    129     STATE_NONE,
    130     STATE_SEND_HEADERS,
    131     STATE_SEND_HEADERS_COMPLETE,
    132     STATE_SEND_BODY,
    133     STATE_SEND_BODY_COMPLETE,
    134     STATE_READ_HEADERS,
    135     STATE_READ_HEADERS_COMPLETE,
    136     STATE_READ_BODY,
    137     STATE_READ_BODY_COMPLETE,
    138     STATE_DONE
    139   };
    140 
    141   ~FlipStream();
    142 
    143   // Try to make progress sending/receiving the request/response.
    144   int DoLoop(int result);
    145 
    146   // Call the user callback.
    147   void DoCallback(int rv);
    148 
    149   // The implementations of each state of the state machine.
    150   int DoSendHeaders();
    151   int DoSendHeadersComplete(int result);
    152   int DoSendBody();
    153   int DoSendBodyComplete(int result);
    154   int DoReadHeaders();
    155   int DoReadHeadersComplete(int result);
    156   int DoReadBody();
    157   int DoReadBodyComplete(int result);
    158 
    159   // Update the histograms.  Can safely be called repeatedly, but should only
    160   // be called after the stream has completed.
    161   void UpdateHistograms();
    162 
    163   flip::FlipStreamId stream_id_;
    164   std::string path_;
    165   int priority_;
    166   const bool pushed_;
    167   // We buffer the response body as it arrives asynchronously from the stream.
    168   // TODO(mbelshe):  is this infinite buffering?
    169   std::list<scoped_refptr<IOBufferWithSize> > response_body_;
    170   bool download_finished_;
    171   ScopedBandwidthMetrics metrics_;
    172 
    173   scoped_refptr<FlipSession> session_;
    174 
    175   HttpResponseInfo* response_;
    176   scoped_ptr<UploadDataStream> request_body_stream_;
    177 
    178   bool response_complete_;  // TODO(mbelshe): fold this into the io_state.
    179   State io_state_;
    180 
    181   // Since we buffer the response, we also buffer the response status.
    182   // Not valid until response_complete_ is true.
    183   int response_status_;
    184 
    185   CompletionCallback* user_callback_;
    186 
    187   // User provided buffer for the ReadResponseBody() response.
    188   scoped_refptr<IOBuffer> user_buffer_;
    189   int user_buffer_len_;
    190 
    191   bool cancelled_;
    192 
    193   scoped_refptr<LoadLog> load_log_;
    194 
    195   base::TimeTicks send_time_;
    196   base::TimeTicks recv_first_byte_time_;
    197   base::TimeTicks recv_last_byte_time_;
    198   int send_bytes_;
    199   int recv_bytes_;
    200   bool histograms_recorded_;
    201 
    202   DISALLOW_COPY_AND_ASSIGN(FlipStream);
    203 };
    204 
    205 }  // namespace net
    206 
    207 #endif  // NET_FLIP_FLIP_STREAM_H_
    208