blob: 1898e1d7a12e9aa1187ab86c1f672dcc8cd995c2 [file] [log] [blame]
// Copyright 2015 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_DEFLATE_PARAMETERS_H_
#define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_
#include <stdint.h>
#include <string>
#include "base/logging.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_deflater.h"
#include "net/websockets/websocket_extension.h"
namespace net {
// A WebSocketDeflateParameters represents permessage-deflate extension
// parameters. This class is used either for request and response.
class NET_EXPORT_PRIVATE WebSocketDeflateParameters {
public:
using ContextTakeOverMode = WebSocketDeflater::ContextTakeOverMode;
// Returns a WebSocketExtension instance containing the parameters stored in
// this object.
WebSocketExtension AsExtension() const;
// Returns true when succeeded.
// Returns false and stores the failure message to |failure_message|
// otherwise.
// Note that even if this function succeeds it is not guaranteed that the
// object is valid. To check it, call IsValidAsRequest or IsValidAsResponse.
bool Initialize(const WebSocketExtension& input,
std::string* failure_message);
// Returns true when |*this| and |response| are compatible.
// |*this| must be valid as a request and |response| must be valid as a
// response.
bool IsCompatibleWith(const WebSocketDeflateParameters& response) const;
bool IsValidAsRequest(std::string* failure_message) const;
bool IsValidAsResponse(std::string* failure_message) const;
bool IsValidAsRequest() const {
std::string message;
return IsValidAsRequest(&message);
}
bool IsValidAsResponse() const {
std::string message;
return IsValidAsResponse(&message);
}
ContextTakeOverMode server_context_take_over_mode() const {
return server_context_take_over_mode_;
}
ContextTakeOverMode client_context_take_over_mode() const {
return client_context_take_over_mode_;
}
bool is_server_max_window_bits_specified() const {
return server_max_window_bits_.is_specified;
}
int server_max_window_bits() const {
DCHECK(is_server_max_window_bits_specified());
return server_max_window_bits_.bits;
}
bool is_client_max_window_bits_specified() const {
return client_max_window_bits_.is_specified;
}
bool has_client_max_window_bits_value() const {
DCHECK(is_client_max_window_bits_specified());
return client_max_window_bits_.has_value;
}
int client_max_window_bits() const {
DCHECK(has_client_max_window_bits_value());
return client_max_window_bits_.bits;
}
void SetServerNoContextTakeOver() {
server_context_take_over_mode_ =
WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT;
}
void SetClientNoContextTakeOver() {
client_context_take_over_mode_ =
WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT;
}
// |bits| must be valid as a max_window_bits value.
void SetServerMaxWindowBits(int bits) {
DCHECK(IsValidWindowBits(bits));
server_max_window_bits_ = WindowBits(bits, true, true);
}
void SetClientMaxWindowBits() {
client_max_window_bits_ = WindowBits(0, true, false);
}
// |bits| must be valid as a max_window_bits value.
void SetClientMaxWindowBits(int bits) {
DCHECK(IsValidWindowBits(bits));
client_max_window_bits_ = WindowBits(bits, true, true);
}
int PermissiveServerMaxWindowBits() const {
return server_max_window_bits_.PermissiveBits();
}
int PermissiveClientMaxWindowBits() const {
return client_max_window_bits_.PermissiveBits();
}
// Return true if |bits| is valid as a max_window_bits value.
static bool IsValidWindowBits(int bits) { return 8 <= bits && bits <= 15; }
private:
struct WindowBits {
WindowBits() : WindowBits(0, false, false) {}
WindowBits(int16_t bits, bool is_specified, bool has_value)
: bits(bits), is_specified(is_specified), has_value(has_value) {}
int PermissiveBits() const {
return (is_specified && has_value) ? bits : 15;
}
int16_t bits;
// True when "window bits" parameter appears in the parameters.
bool is_specified;
// True when "window bits" parameter has the value.
bool has_value;
};
// |server_context_take_over_mode| is set to DO_NOT_TAKE_OVER_CONTEXT if and
// only if |server_no_context_takeover| is set in the parameters.
ContextTakeOverMode server_context_take_over_mode_ =
WebSocketDeflater::TAKE_OVER_CONTEXT;
// |client_context_take_over_mode| is set to DO_NOT_TAKE_OVER_CONTEXT if and
// only if |client_no_context_takeover| is set in the parameters.
ContextTakeOverMode client_context_take_over_mode_ =
WebSocketDeflater::TAKE_OVER_CONTEXT;
WindowBits server_max_window_bits_;
WindowBits client_max_window_bits_;
};
} // namespace net
#endif // NET_WEBSOCKETS_WEBSOCKET_DEFLATE_PARAMETERS_H_