// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_H_
#define NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_H_
#pragma once
#include <string>
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "googleurl/src/gurl.h"
namespace net {
class HttpResponseHeaders;
class WebSocketHandshake {
public:
static const int kWebSocketPort;
static const int kSecureWebSocketPort;
enum Mode {
MODE_INCOMPLETE, MODE_NORMAL, MODE_FAILED, MODE_CONNECTED
};
WebSocketHandshake(const GURL& url,
const std::string& origin,
const std::string& location,
const std::string& protocol);
virtual ~WebSocketHandshake();
bool is_secure() const;
// Creates the client handshake message from |this|.
virtual std::string CreateClientHandshakeMessage();
// Reads server handshake message in |len| of |data|, updates |mode_| and
// returns number of bytes of the server handshake message.
// Once connection is established, |mode_| will be MODE_CONNECTED.
// If connection establishment failed, |mode_| will be MODE_FAILED.
// Returns negative if the server handshake message is incomplete.
virtual int ReadServerHandshake(const char* data, size_t len);
Mode mode() const { return mode_; }
protected:
std::string GetResourceName() const;
std::string GetHostFieldValue() const;
std::string GetOriginFieldValue() const;
// Gets the value of the specified header.
// It assures only one header of |name| in |headers|.
// Returns true iff single header of |name| is found in |headers|
// and |value| is filled with the value.
// Returns false otherwise.
static bool GetSingleHeader(const HttpResponseHeaders& headers,
const std::string& name,
std::string* value);
GURL url_;
// Handshake messages that the client is going to send out.
std::string origin_;
std::string location_;
std::string protocol_;
Mode mode_;
// Handshake messages that server sent.
std::string ws_origin_;
std::string ws_location_;
std::string ws_protocol_;
private:
friend class WebSocketHandshakeTest;
class Parameter {
public:
static const int kKey3Size = 8;
static const int kExpectedResponseSize = 16;
Parameter();
~Parameter();
void GenerateKeys();
const std::string& GetSecWebSocketKey1() const { return key_1_; }
const std::string& GetSecWebSocketKey2() const { return key_2_; }
const std::string& GetKey3() const { return key_3_; }
void GetExpectedResponse(uint8* expected) const;
private:
friend class WebSocketHandshakeTest;
// Set random number generator. |rand| should return a random number
// between min and max (inclusive).
static void SetRandomNumberGenerator(
uint32 (*rand)(uint32 min, uint32 max));
void GenerateSecWebSocketKey(uint32* number, std::string* key);
void GenerateKey3();
uint32 number_1_;
uint32 number_2_;
std::string key_1_;
std::string key_2_;
std::string key_3_;
static uint32 (*rand_)(uint32 min, uint32 max);
};
virtual bool ProcessHeaders(const HttpResponseHeaders& headers);
virtual bool CheckResponseHeaders() const;
scoped_ptr<Parameter> parameter_;
DISALLOW_COPY_AND_ASSIGN(WebSocketHandshake);
};
} // namespace net
#endif // NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_H_