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
15namespace net {
16
17class HttpResponseHeaders;
18
19class 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