blob: c7cb65bf7e879ecbf3982fb5727e49db02d640ef [file] [log] [blame]
// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef COBALT_WEBSOCKET_WEB_SOCKET_MESSAGE_CONTAINER_H_
#define COBALT_WEBSOCKET_WEB_SOCKET_MESSAGE_CONTAINER_H_
#include <deque>
#include "base/memory/ref_counted.h"
#include "cobalt/websocket/web_socket_frame_container.h"
#include "net/base/io_buffer.h"
#include "net/websockets/websocket_frame.h"
namespace cobalt {
namespace websocket {
const size_t kMaxMessagePayloadInBytes = 4 * 1024 * 1024;
COMPILE_ASSERT(kMaxMessagePayloadInBytes >= kMaxFramePayloadInBytes,
max_message_size_must_be_greater_than_max_payload_size);
class WebSocketMessageContainer {
public:
typedef std::deque<WebSocketFrameContainer> WebSocketFrames;
WebSocketMessageContainer()
: message_completed_(false), payload_size_bytes_(0) {}
~WebSocketMessageContainer() { clear(); }
void clear() {
message_completed_ = false;
payload_size_bytes_ = 0;
frames_.clear();
}
bool GetMessageOpCode(net::WebSocketFrameHeader::OpCode *op_code) const {
DCHECK(op_code);
if (empty()) {
return false;
}
return frames_.begin()->GetFrameOpCode(op_code);
}
bool IsMessageComplete() const { return message_completed_; }
// Returns true if and only if it a text message.
// Note: It is valid to call this function on uncompleted messages.
bool IsTextMessage() const {
net::WebSocketFrameHeader::OpCode message_op_code =
net::WebSocketFrameHeader::kOpCodeContinuation;
bool success = GetMessageOpCode(&message_op_code);
if (!success) {
DLOG(INFO) << "Unable to retrieve the message op code. Empty message?";
return false;
}
DCHECK_NE(message_op_code, net::WebSocketFrameHeader::kOpCodePing);
DCHECK_NE(message_op_code, net::WebSocketFrameHeader::kOpCodePong);
DCHECK_NE(message_op_code, net::WebSocketFrameHeader::kOpCodeClose);
return (message_op_code == net::WebSocketFrameHeader::kOpCodeText);
}
// Should only be called if IsMessageComplete() is false, and
// |frame_container| is a full frame.
bool Take(WebSocketFrameContainer *frame_container);
std::size_t GetCurrentPayloadSizeBytes() const { return payload_size_bytes_; }
scoped_refptr<net::IOBufferWithSize> GetMessageAsIOBuffer() const;
const WebSocketFrames &GetFrames() const { return frames_; }
bool empty() const { return frames_.empty(); }
private:
bool message_completed_;
std::size_t payload_size_bytes_;
WebSocketFrames frames_;
};
} // namespace websocket
} // namespace cobalt
#endif // COBALT_WEBSOCKET_WEB_SOCKET_MESSAGE_CONTAINER_H_