Home | History | Annotate | Download | only in websockets
      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_WEBSOCKETS_WEBSOCKET_HANDSHAKE_H_
      6 #define NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_H_
      7 #pragma once
      8 
      9 #include <string>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "googleurl/src/gurl.h"
     14 
     15 namespace net {
     16 
     17 class HttpResponseHeaders;
     18 
     19 class WebSocketHandshake {
     20  public:
     21   static const int kWebSocketPort;
     22   static const int kSecureWebSocketPort;
     23 
     24   enum Mode {
     25     MODE_INCOMPLETE, MODE_NORMAL, MODE_FAILED, MODE_CONNECTED
     26   };
     27   WebSocketHandshake(const GURL& url,
     28                      const std::string& origin,
     29                      const std::string& location,
     30                      const std::string& protocol);
     31   virtual ~WebSocketHandshake();
     32 
     33   bool is_secure() const;
     34   // Creates the client handshake message from |this|.
     35   virtual std::string CreateClientHandshakeMessage();
     36 
     37   // Reads server handshake message in |len| of |data|, updates |mode_| and
     38   // returns number of bytes of the server handshake message.
     39   // Once connection is established, |mode_| will be MODE_CONNECTED.
     40   // If connection establishment failed, |mode_| will be MODE_FAILED.
     41   // Returns negative if the server handshake message is incomplete.
     42   virtual int ReadServerHandshake(const char* data, size_t len);
     43   Mode mode() const { return mode_; }
     44 
     45  protected:
     46   std::string GetResourceName() const;
     47   std::string GetHostFieldValue() const;
     48   std::string GetOriginFieldValue() const;
     49 
     50   // Gets the value of the specified header.
     51   // It assures only one header of |name| in |headers|.
     52   // Returns true iff single header of |name| is found in |headers|
     53   // and |value| is filled with the value.
     54   // Returns false otherwise.
     55   static bool GetSingleHeader(const HttpResponseHeaders& headers,
     56                               const std::string& name,
     57                               std::string* value);
     58 
     59   GURL url_;
     60   // Handshake messages that the client is going to send out.
     61   std::string origin_;
     62   std::string location_;
     63   std::string protocol_;
     64 
     65   Mode mode_;
     66 
     67   // Handshake messages that server sent.
     68   std::string ws_origin_;
     69   std::string ws_location_;
     70   std::string ws_protocol_;
     71 
     72  private:
     73   friend class WebSocketHandshakeTest;
     74 
     75   class Parameter {
     76    public:
     77     static const int kKey3Size = 8;
     78     static const int kExpectedResponseSize = 16;
     79     Parameter();
     80     ~Parameter();
     81 
     82     void GenerateKeys();
     83     const std::string& GetSecWebSocketKey1() const { return key_1_; }
     84     const std::string& GetSecWebSocketKey2() const { return key_2_; }
     85     const std::string& GetKey3() const { return key_3_; }
     86 
     87     void GetExpectedResponse(uint8* expected) const;
     88 
     89    private:
     90     friend class WebSocketHandshakeTest;
     91 
     92     // Set random number generator. |rand| should return a random number
     93     // between min and max (inclusive).
     94     static void SetRandomNumberGenerator(
     95         uint32 (*rand)(uint32 min, uint32 max));
     96     void GenerateSecWebSocketKey(uint32* number, std::string* key);
     97     void GenerateKey3();
     98 
     99     uint32 number_1_;
    100     uint32 number_2_;
    101     std::string key_1_;
    102     std::string key_2_;
    103     std::string key_3_;
    104 
    105     static uint32 (*rand_)(uint32 min, uint32 max);
    106   };
    107 
    108   virtual bool ProcessHeaders(const HttpResponseHeaders& headers);
    109   virtual bool CheckResponseHeaders() const;
    110 
    111   scoped_ptr<Parameter> parameter_;
    112 
    113   DISALLOW_COPY_AND_ASSIGN(WebSocketHandshake);
    114 };
    115 
    116 }  // namespace net
    117 
    118 #endif  // NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_H_
    119