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 PING frame.
    159 // Returns the constructed frame.  The caller takes ownership of the frame.
    160 spdy::SpdyFrame* ConstructSpdyPing();
    161 
    162 // Construct a SPDY GOAWAY frame.
    163 // Returns the constructed frame.  The caller takes ownership of the frame.
    164 spdy::SpdyFrame* ConstructSpdyGoAway();
    165 
    166 // Construct a SPDY WINDOW_UPDATE frame.
    167 // Returns the constructed frame.  The caller takes ownership of the frame.
    168 spdy::SpdyFrame* ConstructSpdyWindowUpdate(spdy::SpdyStreamId,
    169                                            uint32 delta_window_size);
    170 
    171 // Construct a SPDY RST_STREAM frame.
    172 // Returns the constructed frame.  The caller takes ownership of the frame.
    173 spdy::SpdyFrame* ConstructSpdyRstStream(spdy::SpdyStreamId stream_id,
    174                                         spdy::SpdyStatusCodes status);
    175 
    176 // Construct a single SPDY header entry, for validation.
    177 // |extra_headers| are the extra header-value pairs.
    178 // |buffer| is the buffer we're filling in.
    179 // |index| is the index of the header we want.
    180 // Returns the number of bytes written into |buffer|.
    181 int ConstructSpdyHeader(const char* const extra_headers[],
    182                         int extra_header_count,
    183                         char* buffer,
    184                         int buffer_length,
    185                         int index);
    186 
    187 // Constructs a standard SPDY GET SYN packet, optionally compressed
    188 // for the url |url|.
    189 // |extra_headers| are the extra header-value pairs, which typically
    190 // will vary the most between calls.
    191 // Returns a SpdyFrame.
    192 spdy::SpdyFrame* ConstructSpdyGet(const char* const url,
    193                                   bool compressed,
    194                                   int stream_id,
    195                                   RequestPriority request_priority);
    196 
    197 // Constructs a standard SPDY GET SYN packet, optionally compressed.
    198 // |extra_headers| are the extra header-value pairs, which typically
    199 // will vary the most between calls.
    200 // Returns a SpdyFrame.
    201 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
    202                                   int extra_header_count,
    203                                   bool compressed,
    204                                   int stream_id,
    205                                   RequestPriority request_priority);
    206 
    207 // Constructs a standard SPDY GET SYN packet, optionally compressed.
    208 // |extra_headers| are the extra header-value pairs, which typically
    209 // will vary the most between calls.  If |direct| is false, the
    210 // the full url will be used instead of simply the path.
    211 // Returns a SpdyFrame.
    212 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
    213                                   int extra_header_count,
    214                                   bool compressed,
    215                                   int stream_id,
    216                                   RequestPriority request_priority,
    217                                   bool direct);
    218 
    219 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
    220 spdy::SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
    221                                       int extra_header_count,
    222                                       int stream_id);
    223 
    224 // Constructs a standard SPDY push SYN packet.
    225 // |extra_headers| are the extra header-value pairs, which typically
    226 // will vary the most between calls.
    227 // Returns a SpdyFrame.
    228 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
    229                                   int extra_header_count,
    230                                   int stream_id,
    231                                   int associated_stream_id);
    232 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
    233                                   int extra_header_count,
    234                                   int stream_id,
    235                                   int associated_stream_id,
    236                                   const char* url);
    237 spdy::SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
    238                                   int extra_header_count,
    239                                   int stream_id,
    240                                   int associated_stream_id,
    241                                   const char* url,
    242                                   const char* status,
    243                                   const char* location);
    244 spdy::SpdyFrame* ConstructSpdyPush(int stream_id,
    245                                   int associated_stream_id,
    246                                   const char* url);
    247 
    248 spdy::SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
    249                                           const char* const extra_headers[],
    250                                           int extra_header_count);
    251 
    252 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
    253 // |extra_headers| are the extra header-value pairs, which typically
    254 // will vary the most between calls.
    255 // Returns a SpdyFrame.
    256 spdy::SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
    257                                           int extra_header_count,
    258                                           int stream_id);
    259 
    260 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
    261 // |extra_headers| are the extra header-value pairs, which typically
    262 // will vary the most between calls.
    263 // Returns a SpdyFrame.
    264 spdy::SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id);
    265 
    266 // Constructs a standard SPDY SYN_REPLY packet with an Internal Server
    267 // Error status code.
    268 // Returns a SpdyFrame.
    269 spdy::SpdyFrame* ConstructSpdySynReplyError(int stream_id);
    270 
    271 // Constructs a standard SPDY SYN_REPLY packet with the specified status code.
    272 // Returns a SpdyFrame.
    273 spdy::SpdyFrame* ConstructSpdySynReplyError(
    274     const char* const status,
    275     const char* const* const extra_headers,
    276     int extra_header_count,
    277     int stream_id);
    278 
    279 // Constructs a standard SPDY POST SYN packet.
    280 // |extra_headers| are the extra header-value pairs, which typically
    281 // will vary the most between calls.
    282 // Returns a SpdyFrame.
    283 spdy::SpdyFrame* ConstructSpdyPost(int64 content_length,
    284                                    const char* const extra_headers[],
    285                                    int extra_header_count);
    286 
    287 // Constructs a chunked transfer SPDY POST SYN packet.
    288 // |extra_headers| are the extra header-value pairs, which typically
    289 // will vary the most between calls.
    290 // Returns a SpdyFrame.
    291 spdy::SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
    292                                           int extra_header_count);
    293 
    294 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY POST.
    295 // |extra_headers| are the extra header-value pairs, which typically
    296 // will vary the most between calls.
    297 // Returns a SpdyFrame.
    298 spdy::SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
    299                                            int extra_header_count);
    300 
    301 // Constructs a single SPDY data frame with the contents "hello!"
    302 spdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
    303                                         bool fin);
    304 
    305 // Constructs a single SPDY data frame with the given content.
    306 spdy::SpdyFrame* ConstructSpdyBodyFrame(int stream_id, const char* data,
    307                                         uint32 len, bool fin);
    308 
    309 // Wraps |frame| in the payload of a data frame in stream |stream_id|.
    310 spdy::SpdyFrame* ConstructWrappedSpdyFrame(
    311     const scoped_ptr<spdy::SpdyFrame>& frame, int stream_id);
    312 
    313 // Create an async MockWrite from the given SpdyFrame.
    314 MockWrite CreateMockWrite(const spdy::SpdyFrame& req);
    315 
    316 // Create an async MockWrite from the given SpdyFrame and sequence number.
    317 MockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq);
    318 
    319 MockWrite CreateMockWrite(const spdy::SpdyFrame& req, int seq, bool async);
    320 
    321 // Create a MockRead from the given SpdyFrame.
    322 MockRead CreateMockRead(const spdy::SpdyFrame& resp);
    323 
    324 // Create a MockRead from the given SpdyFrame and sequence number.
    325 MockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq);
    326 
    327 MockRead CreateMockRead(const spdy::SpdyFrame& resp, int seq, bool async);
    328 
    329 // Combines the given SpdyFrames into the given char array and returns
    330 // the total length.
    331 int CombineFrames(const spdy::SpdyFrame** frames, int num_frames,
    332                   char* buff, int buff_len);
    333 
    334 // Helper to manage the lifetimes of the dependencies for a
    335 // HttpNetworkTransaction.
    336 class SpdySessionDependencies {
    337  public:
    338   // Default set of dependencies -- "null" proxy service.
    339   SpdySessionDependencies();
    340 
    341   // Custom proxy service dependency.
    342   explicit SpdySessionDependencies(ProxyService* proxy_service);
    343 
    344   ~SpdySessionDependencies();
    345 
    346   static HttpNetworkSession* SpdyCreateSession(
    347       SpdySessionDependencies* session_deps);
    348   static HttpNetworkSession* SpdyCreateSessionDeterministic(
    349       SpdySessionDependencies* session_deps);
    350 
    351   // NOTE: host_resolver must be ordered before http_auth_handler_factory.
    352   scoped_ptr<MockHostResolverBase> host_resolver;
    353   scoped_ptr<CertVerifier> cert_verifier;
    354   scoped_refptr<ProxyService> proxy_service;
    355   scoped_refptr<SSLConfigService> ssl_config_service;
    356   scoped_ptr<MockClientSocketFactory> socket_factory;
    357   scoped_ptr<DeterministicMockClientSocketFactory> deterministic_socket_factory;
    358   scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
    359 };
    360 
    361 class SpdyURLRequestContext : public URLRequestContext {
    362  public:
    363   SpdyURLRequestContext();
    364 
    365   MockClientSocketFactory& socket_factory() { return socket_factory_; }
    366 
    367  protected:
    368   virtual ~SpdyURLRequestContext();
    369 
    370  private:
    371   MockClientSocketFactory socket_factory_;
    372 };
    373 
    374 const SpdyHeaderInfo make_spdy_header(spdy::SpdyControlType type);
    375 }  // namespace net
    376 
    377 #endif  // NET_SPDY_SPDY_TEST_UTIL_H_
    378