Home | History | Annotate | Download | only in spdy
      1 // Copyright (c) 2011 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_TEST_UTIL_H_
      6 #define NET_SPDY_SPDY_TEST_UTIL_H_
      7 #pragma once
      8 
      9 #include "base/basictypes.h"
     10 #include "net/base/cert_verifier.h"
     11 #include "net/base/mock_host_resolver.h"
     12 #include "net/base/request_priority.h"
     13 #include "net/base/ssl_config_service_defaults.h"
     14 #include "net/http/http_auth_handler_factory.h"
     15 #include "net/http/http_cache.h"
     16 #include "net/http/http_network_session.h"
     17 #include "net/http/http_network_layer.h"
     18 #include "net/http/http_transaction_factory.h"
     19 #include "net/proxy/proxy_service.h"
     20 #include "net/socket/socket_test_util.h"
     21 #include "net/spdy/spdy_framer.h"
     22 #include "net/url_request/url_request_context.h"
     23 
     24 namespace net {
     25 
     26 // Default upload data used by both, mock objects and framer when creating
     27 // data frames.
     28 const char kDefaultURL[] = "http://www.google.com";
     29 const char kUploadData[] = "hello!";
     30 const int kUploadDataSize = arraysize(kUploadData)-1;
     31 
     32 // NOTE: In GCC, on a Mac, this can't be in an anonymous namespace!
     33 // This struct holds information used to construct spdy control and data frames.
     34 struct SpdyHeaderInfo {
     35   spdy::SpdyControlType kind;
     36   spdy::SpdyStreamId id;
     37   spdy::SpdyStreamId assoc_id;
     38   spdy::SpdyPriority priority;
     39   spdy::SpdyControlFlags control_flags;
     40   bool compressed;
     41   spdy::SpdyStatusCodes status;
     42   const char* data;
     43   uint32 data_length;
     44   spdy::SpdyDataFlags data_flags;
     45 };
     46 
     47 // Chop a frame into an array of MockWrites.
     48 // |data| is the frame to chop.
     49 // |length| is the length of the frame to chop.
     50 // |num_chunks| is the number of chunks to create.
     51 MockWrite* ChopWriteFrame(const char* data, int length, int num_chunks);
     52 
     53 // Chop a SpdyFrame into an array of MockWrites.
     54 // |frame| is the frame to chop.
     55 // |num_chunks| is the number of chunks to create.
     56 MockWrite* ChopWriteFrame(const spdy::SpdyFrame& frame, int num_chunks);
     57 
     58 // Chop a frame into an array of MockReads.
     59 // |data| is the frame to chop.
     60 // |length| is the length of the frame to chop.
     61 // |num_chunks| is the number of chunks to create.
     62 MockRead* ChopReadFrame(const char* data, int length, int num_chunks);
     63 
     64 // Chop a SpdyFrame into an array of MockReads.
     65 // |frame| is the frame to chop.
     66 // |num_chunks| is the number of chunks to create.
     67 MockRead* ChopReadFrame(const spdy::SpdyFrame& frame, int num_chunks);
     68 
     69 // Adds headers and values to a map.
     70 // |extra_headers| is an array of { name, value } pairs, arranged as strings
     71 // where the even entries are the header names, and the odd entries are the
     72 // header values.
     73 // |headers| gets filled in from |extra_headers|.
     74 void AppendHeadersToSpdyFrame(const char* const extra_headers[],
     75                               int extra_header_count,
     76                               spdy::SpdyHeaderBlock* headers);
     77 
     78 // Writes |str| of the given |len| to the buffer pointed to by |buffer_handle|.
     79 // Uses a template so buffer_handle can be a char* or an unsigned char*.
     80 // Updates the |*buffer_handle| pointer by |len|
     81 // Returns the number of bytes written into *|buffer_handle|
     82 template<class T>
     83 int AppendToBuffer(const char* str,
     84                    int len,
     85                    T** buffer_handle,
     86                    int* buffer_len_remaining) {
     87   DCHECK_GT(len, 0);
     88   DCHECK(NULL != buffer_handle) << "NULL buffer handle";
     89   DCHECK(NULL != *buffer_handle) << "NULL pointer";
     90   DCHECK(NULL != buffer_len_remaining)
     91       << "NULL buffer remainder length pointer";
     92   DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
     93   memcpy(*buffer_handle, str, len);
     94   *buffer_handle += len;
     95   *buffer_len_remaining -= len;
     96   return len;
     97 }
     98 
     99 // Writes |val| to a location of size |len|, in big-endian format.
    100 // in the buffer pointed to by |buffer_handle|.
    101 // Updates the |*buffer_handle| pointer by |len|
    102 // Returns the number of bytes written
    103 int AppendToBuffer(int val,
    104                    int len,
    105                    unsigned char** buffer_handle,
    106                    int* buffer_len_remaining);
    107 
    108 // Construct a SPDY packet.
    109 // |head| is the start of the packet, up to but not including
    110 // the header value pairs.
    111 // |extra_headers| are the extra header-value pairs, which typically
    112 // will vary the most between calls.
    113 // |tail| is any (relatively constant) header-value pairs to add.
    114 // |buffer| is the buffer we're filling in.
    115 // Returns a SpdyFrame.
    116 spdy::SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo& header_info,
    117                                      const char* const extra_headers[],
    118                                      int extra_header_count,
    119                                      const char* const tail[],
    120                                      int tail_header_count);
    121 
    122 // Construct a generic SpdyControlFrame.
    123 spdy::SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
    124                                            int extra_header_count,
    125                                            bool compressed,
    126                                            int stream_id,
    127                                            RequestPriority request_priority,
    128                                            spdy::SpdyControlType type,
    129                                            spdy::SpdyControlFlags flags,
    130                                            const char* const* kHeaders,
    131                                            int kHeadersSize);
    132 spdy::SpdyFrame* ConstructSpdyControlFrame(const char* const extra_headers[],
    133                                            int extra_header_count,
    134                                            bool compressed,
    135                                            int stream_id,
    136                                            RequestPriority request_priority,
    137                                            spdy::SpdyControlType type,
    138                                            spdy::SpdyControlFlags flags,
    139                                            const char* const* kHeaders,
    140                                            int kHeadersSize,
    141                                            int associated_stream_id);
    142 
    143 // Construct an expected SPDY reply string.
    144 // |extra_headers| are the extra header-value pairs, which typically
    145 // will vary the most between calls.
    146 // |buffer| is the buffer we're filling in.
    147 // Returns the number of bytes written into |buffer|.
    148 int ConstructSpdyReplyString(const char* const extra_headers[],
    149                              int extra_header_count,
    150                              char* buffer,
    151                              int buffer_length);
    152 
    153 // Construct an expected SPDY SETTINGS frame.
    154 // |settings| are the settings to set.
    155 // Returns the constructed frame.  The caller takes ownership of the frame.
    156 spdy::SpdyFrame* ConstructSpdySettings(spdy::SpdySettings settings);
    157 
    158 // Construct a SPDY GOAWAY frame.
    159 // Returns the constructed frame.  The caller takes ownership of the frame.
    160 spdy::SpdyFrame* ConstructSpdyGoAway();
    161 
    162 // Construct a SPDY WINDOW_UPDATE frame.
    163 // Returns the constructed frame.  The caller takes ownership of the frame.
    164 spdy::SpdyFrame* ConstructSpdyWindowUpdate(spdy::SpdyStreamId,
    165                                            uint32 delta_window_size);
    166 
    167 // Construct a SPDY RST_STREAM frame.
    168 // Returns the constructed frame.  The caller takes ownership of the frame.
    169 spdy::SpdyFrame* ConstructSpdyRstStream(spdy::SpdyStreamId stream_id,
    170                                         spdy::SpdyStatusCodes status);
    171 
    172 // Construct a single SPDY header entry, for validation.
    173 // |extra_headers| are the extra header-value pairs.
    174 // |buffer| is the buffer we're filling in.
    175 // |index| is the index of the header we want.
    176 // Returns the number of bytes written into |buffer|.
    177 int ConstructSpdyHeader(const char* const extra_headers[],
    178                         int extra_header_count,
    179                         char* buffer,
    180                         int buffer_length,
    181                         int index);
    182 
    183 // Constructs a standard SPDY GET SYN packet, optionally compressed
    184 // for the url |url|.
    185 // |extra_headers| are the extra header-value pairs, which typically
    186 // will vary the most between calls.
    187 // Returns a SpdyFrame.
    188 spdy::SpdyFrame* ConstructSpdyGet(const char* const url,
    189                                   bool compressed,
    190                                   int stream_id,
    191                                   RequestPriority request_priority);
    192 
    193 // Constructs a standard SPDY GET SYN packet, optionally compressed.
    194 // |extra_headers| are the extra header-value pairs, which typically
    195 // will vary the most between calls.
    196 // Returns a SpdyFrame.
    197 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
    198                                   int extra_header_count,
    199                                   bool compressed,
    200                                   int stream_id,
    201                                   RequestPriority request_priority);
    202 
    203 // Constructs a standard SPDY GET SYN packet, optionally compressed.
    204 // |extra_headers| are the extra header-value pairs, which typically
    205 // will vary the most between calls.  If |direct| is false, the
    206 // the full url will be used instead of simply the path.
    207 // Returns a SpdyFrame.
    208 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
    209                                   int extra_header_count,
    210                                   bool compressed,
    211                                   int stream_id,
    212                                   RequestPriority request_priority,
    213                                   bool direct);
    214 
    215 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
    216 spdy::SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
    217                                       int extra_header_count,
    218                                       int stream_id);
    219 
    220 // Constructs a standard SPDY push SYN packet.
    221 // |extra_headers| are the extra header-value pairs, which typically
    222 // will vary the most between calls.
    223 // Returns a SpdyFrame.
    224 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
    225                                   int extra_header_count,
    226                                   int stream_id,
    227                                   int associated_stream_id);
    228 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
    229                                   int extra_header_count,
    230                                   int stream_id,
    231                                   int associated_stream_id,
    232                                   const char* url);
    233 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
    234                                   int extra_header_count,
    235                                   int stream_id,
    236                                   int associated_stream_id,
    237                                   const char* url,
    238                                   const char* status,
    239                                   const char* location);
    240 spdy::SpdyFrame* ConstructSpdyPush(int stream_id,
    241                                   int associated_stream_id,
    242                                   const char* url);
    243 
    244 spdy::SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
    245                                           const char* const extra_headers[],
    246                                           int extra_header_count);
    247 
    248 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
    249 // |extra_headers| are the extra header-value pairs, which typically
    250 // will vary the most between calls.
    251 // Returns a SpdyFrame.
    252 spdy::SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
    253                                           int extra_header_count,
    254                                           int stream_id);
    255 
    256 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
    257 // |extra_headers| are the extra header-value pairs, which typically
    258 // will vary the most between calls.
    259 // Returns a SpdyFrame.
    260 spdy::SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id);
    261 
    262 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
    263 // Error status code.
    264 // Returns a SpdyFrame.
    265 spdy::SpdyFrame* ConstructSpdySynReplyError(int stream_id);
    266 
    267 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
    268 // Returns a SpdyFrame.
    269 spdy::SpdyFrame* ConstructSpdySynReplyError(
    270     const char* const status,
    271     const char* const* const extra_headers,
    272     int extra_header_count,
    273     int stream_id);
    274 
    275 // Constructs a standard SPDY POST SYN packet.
    276 // |extra_headers| are the extra header-value pairs, which typically
    277 // will vary the most between calls.
    278 // Returns a SpdyFrame.
    279 spdy::SpdyFrame* ConstructSpdyPost(int64 content_length,
    280                                    const char* const extra_headers[],
    281                                    int extra_header_count);
    282 
    283 // Constructs a chunked transfer SPDY POST SYN packet.
    284 // |extra_headers| are the extra header-value pairs, which typically
    285 // will vary the most between calls.
    286 // Returns a SpdyFrame.
    287 spdy::SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
    288                                           int extra_header_count);
    289 
    290 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
    291 // |extra_headers| are the extra header-value pairs, which typically
    292 // will vary the most between calls.
    293 // Returns a SpdyFrame.
    294 spdy::SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
    295                                            int extra_header_count);
    296 
    297 // Constructs a single SPDY data frame with the contents "hello!"
    298 spdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
    299                                         bool fin);
    300 
    301 // Constructs a single SPDY data frame with the given content.
    302 spdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
    303                                         uint32 len, bool fin);
    304 
    305 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
    306 spdy::SpdyFrame* ConstructWrappedSpdyFrame(
    307     const scoped_ptr<spdy::SpdyFrame>& frame, int stream_id);
    308 
    309 // Create an async MockWrite from the given SpdyFrame.
    310 MockWrite CreateMockWrite(const spdy::SpdyFrame& req);
    311 
    312 // Create an async MockWrite from the given SpdyFrame and sequence number.
    313 MockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq);
    314 
    315 MockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq, bool async);
    316 
    317 // Create a MockRead from the given SpdyFrame.
    318 MockRead CreateMockRead(const spdy::SpdyFrame& resp);
    319 
    320 // Create a MockRead from the given SpdyFrame and sequence number.
    321 MockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq);
    322 
    323 MockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq, bool async);
    324 
    325 // Combines the given SpdyFrames into the given char array and returns
    326 // the total length.
    327 int CombineFrames(const spdy::SpdyFrame** frames, int num_frames,
    328                   char* buff, int buff_len);
    329 
    330 // Helper to manage the lifetimes of the dependencies for a
    331 // HttpNetworkTransaction.
    332 class SpdySessionDependencies {
    333  public:
    334   // Default set of dependencies -- "null" proxy service.
    335   SpdySessionDependencies();
    336 
    337   // Custom proxy service dependency.
    338   explicit SpdySessionDependencies(ProxyService* proxy_service);
    339 
    340   ~SpdySessionDependencies();
    341 
    342   static HttpNetworkSession* SpdyCreateSession(
    343       SpdySessionDependencies* session_deps);
    344   static HttpNetworkSession* SpdyCreateSessionDeterministic(
    345       SpdySessionDependencies* session_deps);
    346 
    347   // NOTE: host_resolver must be ordered before http_auth_handler_factory.
    348   scoped_ptr<MockHostResolverBase> host_resolver;
    349   scoped_ptr<CertVerifier> cert_verifier;
    350   scoped_refptr<ProxyService> proxy_service;
    351   scoped_refptr<SSLConfigService> ssl_config_service;
    352   scoped_ptr<MockClientSocketFactory> socket_factory;
    353   scoped_ptr<DeterministicMockClientSocketFactory> deterministic_socket_factory;
    354   scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
    355 };
    356 
    357 class SpdyURLRequestContext : public URLRequestContext {
    358  public:
    359   SpdyURLRequestContext();
    360 
    361   MockClientSocketFactory& socket_factory() { return socket_factory_; }
    362 
    363  protected:
    364   virtual ~SpdyURLRequestContext();
    365 
    366  private:
    367   MockClientSocketFactory socket_factory_;
    368 };
    369 
    370 const SpdyHeaderInfo make_spdy_header(spdy::SpdyControlType type);
    371 }  // namespace net
    372 
    373 #endif  // NET_SPDY_SPDY_TEST_UTIL_H_
    374