// Copyright (c) 2012 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 PPAPI_PROXY_WEBSOCKET_RESOURCE_H_
#define PPAPI_PROXY_WEBSOCKET_RESOURCE_H_
#include <queue>
#include "ppapi/c/ppb_websocket.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/ppb_websocket_api.h"
namespace ppapi {
class StringVar;
class Var;
namespace proxy {
// This class contains protocol checks which doesn't affect security when it
// run with untrusted code.
class PPAPI_PROXY_EXPORT WebSocketResource
: public PluginResource,
public NON_EXPORTED_BASE(thunk::PPB_WebSocket_API) {
public:
WebSocketResource(Connection connection, PP_Instance instance);
virtual ~WebSocketResource();
// PluginResource implementation.
virtual thunk::PPB_WebSocket_API* AsPPB_WebSocket_API() OVERRIDE;
// PPB_WebSocket_API implementation.
virtual int32_t Connect(const PP_Var& url,
const PP_Var protocols[],
uint32_t protocol_count,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual int32_t Close(uint16_t code,
const PP_Var& reason,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual int32_t ReceiveMessage(
PP_Var* message,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual int32_t SendMessage(const PP_Var& message) OVERRIDE;
virtual uint64_t GetBufferedAmount() OVERRIDE;
virtual uint16_t GetCloseCode() OVERRIDE;
virtual PP_Var GetCloseReason() OVERRIDE;
virtual PP_Bool GetCloseWasClean() OVERRIDE;
virtual PP_Var GetExtensions() OVERRIDE;
virtual PP_Var GetProtocol() OVERRIDE;
virtual PP_WebSocketReadyState GetReadyState() OVERRIDE;
virtual PP_Var GetURL() OVERRIDE;
private:
// PluginResource override.
virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
const IPC::Message& msg) OVERRIDE;
// IPC message handlers.
void OnPluginMsgConnectReply(const ResourceMessageReplyParams& params,
const std::string& url,
const std::string& protocol);
void OnPluginMsgCloseReply(const ResourceMessageReplyParams& params,
unsigned long buffered_amount,
bool was_clean,
unsigned short code,
const std::string& reason);
void OnPluginMsgReceiveTextReply(const ResourceMessageReplyParams& params,
const std::string& message);
void OnPluginMsgReceiveBinaryReply(const ResourceMessageReplyParams& params,
const std::vector<uint8_t>& message);
void OnPluginMsgErrorReply(const ResourceMessageReplyParams& params);
void OnPluginMsgBufferedAmountReply(const ResourceMessageReplyParams& params,
unsigned long buffered_amount);
void OnPluginMsgStateReply(const ResourceMessageReplyParams& params,
int32_t state);
void OnPluginMsgClosedReply(const ResourceMessageReplyParams& params,
unsigned long buffered_amount,
bool was_clean,
unsigned short code,
const std::string& reason);
// Picks up a received message and moves it to user receiving buffer. This
// function is used in both ReceiveMessage for fast returning path, and
// OnPluginMsgReceiveTextReply and OnPluginMsgReceiveBinaryReply for delayed
// callback invocations.
int32_t DoReceive();
// Holds user callbacks to invoke later.
scoped_refptr<TrackedCallback> connect_callback_;
scoped_refptr<TrackedCallback> close_callback_;
scoped_refptr<TrackedCallback> receive_callback_;
// Represents readyState described in the WebSocket API specification. It can
// be read via GetReadyState().
PP_WebSocketReadyState state_;
// Becomes true if any error is detected. Incoming data will be disposed
// if this variable is true, then ReceiveMessage() returns PP_ERROR_FAILED
// after returning all received data.
bool error_was_received_;
// Keeps a pointer to PP_Var which is provided via ReceiveMessage().
// Received data will be copied to this PP_Var on ready.
PP_Var* receive_callback_var_;
// Keeps received data until ReceiveMessage() requests.
std::queue<scoped_refptr<Var> > received_messages_;
// Keeps empty string for functions to return empty string.
scoped_refptr<StringVar> empty_string_;
// Keeps the status code field of closing handshake. It can be read via
// GetCloseCode().
uint16_t close_code_;
// Keeps the reason field of closing handshake. It can be read via
// GetCloseReason().
scoped_refptr<StringVar> close_reason_;
// Becomes true when closing handshake is performed successfully. It can be
// read via GetCloseWasClean().
PP_Bool close_was_clean_;
// Represents extensions described in the WebSocket API specification. It can
// be read via GetExtensions().
scoped_refptr<StringVar> extensions_;
// Represents protocol described in the WebSocket API specification. It can be
// read via GetProtocol().
scoped_refptr<StringVar> protocol_;
// Represents url described in the WebSocket API specification. It can be
// read via GetURL().
scoped_refptr<StringVar> url_;
// Keeps the number of bytes of application data that have been queued using
// SendMessage(). WebKit side implementation calculates the actual amount.
// This is a cached value which is notified through a WebKit callback.
// This value is used to calculate bufferedAmount in the WebSocket API
// specification. The calculated value can be read via GetBufferedAmount().
uint64_t buffered_amount_;
// Keeps the number of bytes of application data that have been ignored
// because the connection was already closed.
// This value is used to calculate bufferedAmount in the WebSocket API
// specification. The calculated value can be read via GetBufferedAmount().
uint64_t buffered_amount_after_close_;
DISALLOW_COPY_AND_ASSIGN(WebSocketResource);
};
} // namespace proxy
} // namespace ppapi
#endif // PPAPI_PROXY_WEBSOCKET_RESOURCE_H_