Commit 85893f16 authored by maruel@chromium.org's avatar maruel@chromium.org

Revert r111596 "WebSocket Pepper API: in process API implementation"

Broke compile on Linux Builder (dbg)(shared)

TBR=toyoshim@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/8698007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111598 0039d316-1c4b-4281-b951-d872f2087c98
parent 2b68f817
...@@ -231,17 +231,6 @@ class PPAPINaClTest : public PPAPITestBase { ...@@ -231,17 +231,6 @@ class PPAPINaClTest : public PPAPITestBase {
RunTestViaHTTP(#test_name); \ RunTestViaHTTP(#test_name); \
} }
// Similar macros that test with WebSocket server
#define TEST_PPAPI_IN_PROCESS_WITH_WS(test_name) \
TEST_F(PPAPITest, test_name) { \
RunTestWithWebSocketServer(#test_name); \
}
#define TEST_PPAPI_OUT_OF_PROCESS_WITH_WS(test_name) \
TEST_F(OutOfProcessPPAPITest, test_name) { \
RunTestWithWebSocketServer(#test_name); \
}
// NaCl based PPAPI tests // NaCl based PPAPI tests
#define TEST_PPAPI_NACL_VIA_HTTP(test_name) \ #define TEST_PPAPI_NACL_VIA_HTTP(test_name) \
...@@ -471,9 +460,7 @@ TEST_PPAPI_OUT_OF_PROCESS(Flash_MessageLoop) ...@@ -471,9 +460,7 @@ TEST_PPAPI_OUT_OF_PROCESS(Flash_MessageLoop)
TEST_PPAPI_OUT_OF_PROCESS(Flash_GetLocalTimeZoneOffset) TEST_PPAPI_OUT_OF_PROCESS(Flash_GetLocalTimeZoneOffset)
TEST_PPAPI_OUT_OF_PROCESS(Flash_GetCommandLineArgs) TEST_PPAPI_OUT_OF_PROCESS(Flash_GetCommandLineArgs)
TEST_PPAPI_IN_PROCESS(WebSocket_InvalidConnect) TEST_PPAPI_IN_PROCESS(WebSocket_Create)
TEST_PPAPI_IN_PROCESS(WebSocket_IsWebSocket) TEST_PPAPI_IN_PROCESS(WebSocket_IsWebSocket)
TEST_PPAPI_IN_PROCESS_WITH_WS(WebSocket_ValidConnect)
TEST_PPAPI_IN_PROCESS_WITH_WS(WebSocket_TextSendReceive)
#endif // ADDRESS_SANITIZER #endif // ADDRESS_SANITIZER
...@@ -4,196 +4,41 @@ ...@@ -4,196 +4,41 @@
#include "ppapi/tests/test_websocket.h" #include "ppapi/tests/test_websocket.h"
#include <string.h>
#include "base/logging.h"
#include "ppapi/c/dev/ppb_websocket_dev.h" #include "ppapi/c/dev/ppb_websocket_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/cpp/instance.h" #include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h" #include "ppapi/cpp/module.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h" #include "ppapi/tests/testing_instance.h"
static const char kEchoServerURL[] =
"ws://localhost:8880/websocket/tests/hybi/echo";
REGISTER_TEST_CASE(WebSocket); REGISTER_TEST_CASE(WebSocket);
bool TestWebSocket::Init() { bool TestWebSocket::Init() {
websocket_interface_ = static_cast<const PPB_WebSocket_Dev*>( websocket_interface_ = reinterpret_cast<PPB_WebSocket_Dev const*>(
pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_DEV_INTERFACE)); pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_DEV_INTERFACE));
var_interface_ = static_cast<const PPB_Var*>( return !!websocket_interface_;
pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
core_interface_ = static_cast<const PPB_Core*>(
pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
if (!websocket_interface_ || !var_interface_ || !core_interface_)
return false;
return true;
} }
void TestWebSocket::RunTests(const std::string& filter) { void TestWebSocket::RunTests(const std::string& filter) {
RUN_TEST(IsWebSocket, filter); instance_->LogTest("Create", TestCreate());
RUN_TEST(InvalidConnect, filter); instance_->LogTest("IsWebSocket", TestIsWebSocket());
RUN_TEST(ValidConnect, filter);
RUN_TEST(TextSendReceive, filter);
}
PP_Var TestWebSocket::CreateVar(const char* string) {
return var_interface_->VarFromUtf8(
pp::Module::Get()->pp_module(), string, strlen(string));
} }
void TestWebSocket::ReleaseVar(const PP_Var& var) { std::string TestWebSocket::TestCreate() {
var_interface_->Release(var); PP_Resource rsrc = websocket_interface_->Create(instance_->pp_instance());
} if (!rsrc)
return "Could not create websocket via C interface";
bool TestWebSocket::AreEqual(const PP_Var& var, const char* string) {
if (var.type != PP_VARTYPE_STRING)
return false;
uint32_t utf8_length;
const char* utf8 = var_interface_->VarToUtf8(var, &utf8_length);
uint32_t string_length = strlen(string);
if (utf8_length != string_length)
return false;
if (strncmp(utf8, string, utf8_length))
return false;
return true;
}
PP_Resource TestWebSocket::Connect() { PASS();
PP_Var protocols[] = { PP_MakeUndefined() };
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
if (!ws)
return 0;
PP_Var url = CreateVar(kEchoServerURL);
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
int32_t result = websocket_interface_->Connect(
ws, url, protocols, 0,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ReleaseVar(url);
if (force_async_ && result != PP_OK_COMPLETIONPENDING) {
core_interface_->ReleaseResource(ws);
return 0;
}
if (callback.WaitForResult() != PP_OK) {
core_interface_->ReleaseResource(ws);
return 0;
}
return ws;
} }
std::string TestWebSocket::TestIsWebSocket() { std::string TestWebSocket::TestIsWebSocket() {
// Test that a NULL resource isn't a websocket. // Test that a NULL resource isn't a websocket.
pp::Resource null_resource; pp::Resource null_resource;
PP_Bool result = if (websocket_interface_->IsWebSocket(null_resource.pp_resource()))
websocket_interface_->IsWebSocket(null_resource.pp_resource()); return "Null resource was reported as a valid websocket";
ASSERT_FALSE(result);
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws); if (!websocket_interface_->IsWebSocket(ws))
return "websocket was reported as an invalid websocket";
result = websocket_interface_->IsWebSocket(ws);
ASSERT_TRUE(result);
core_interface_->ReleaseResource(ws);
PASS(); PASS();
} }
std::string TestWebSocket::TestInvalidConnect() {
PP_Var protocols[] = { PP_MakeUndefined() };
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws);
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
int32_t result = websocket_interface_->Connect(
ws, PP_MakeUndefined(), protocols, 1,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
result = websocket_interface_->Connect(
ws, PP_MakeUndefined(), protocols, 1,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_ERROR_INPROGRESS, result);
core_interface_->ReleaseResource(ws);
const char* invalid_urls[] = {
"http://www.google.com/invalid_scheme",
"ws://www.google.com/invalid#fragment",
"ws://www.google.com:65535/invalid_port",
NULL
};
for (int i = 0; invalid_urls[i]; ++i) {
ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws);
PP_Var invalid_url = CreateVar(invalid_urls[i]);
result = websocket_interface_->Connect(
ws, invalid_url, protocols, 0,
static_cast<pp::CompletionCallback>(
callback).pp_completion_callback());
ReleaseVar(invalid_url);
core_interface_->ReleaseResource(ws);
ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
}
// TODO(toyoshim): Add invalid protocols tests
PASS();
}
std::string TestWebSocket::TestValidConnect() {
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
PP_Var url = CreateVar(kEchoServerURL);
PP_Var protocols[] = { PP_MakeUndefined() };
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
int32_t result = websocket_interface_->Connect(
ws, url, protocols, 0,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ReleaseVar(url);
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
core_interface_->ReleaseResource(ws);
PASS();
}
// TODO(toyoshim): Add tests to call various interfaces before calling connect.
std::string TestWebSocket::TestTextSendReceive() {
// Connect to test echo server.
PP_Resource ws = Connect();
ASSERT_TRUE(ws);
// Send 'hello pepper' text message.
const char* message = "hello pepper";
PP_Var message_var = CreateVar(message);
int32_t result = websocket_interface_->SendMessage(ws, message_var);
ReleaseVar(message_var);
ASSERT_EQ(PP_OK, result);
// Receive echoed 'hello pepper'.
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
PP_Var received_message;
result = websocket_interface_->ReceiveMessage(ws, &received_message,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_FALSE(result != PP_OK && result != PP_OK_COMPLETIONPENDING);
if (result == PP_OK_COMPLETIONPENDING)
result = callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
ASSERT_TRUE(AreEqual(received_message, message));
ReleaseVar(received_message);
core_interface_->ReleaseResource(ws);
PASS();
}
// TODO(toyoshim): Add other function tests.
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include "ppapi/tests/test_case.h" #include "ppapi/tests/test_case.h"
struct PPB_Core;
struct PPB_Var;
struct PPB_WebSocket_Dev; struct PPB_WebSocket_Dev;
class TestWebSocket : public TestCase { class TestWebSocket : public TestCase {
...@@ -22,21 +20,11 @@ class TestWebSocket : public TestCase { ...@@ -22,21 +20,11 @@ class TestWebSocket : public TestCase {
virtual void RunTests(const std::string& filter); virtual void RunTests(const std::string& filter);
private: private:
PP_Var CreateVar(const char* string); std::string TestCreate();
void ReleaseVar(const PP_Var& var);
bool AreEqual(const PP_Var& var, const char* string);
PP_Resource Connect();
std::string TestIsWebSocket(); std::string TestIsWebSocket();
std::string TestInvalidConnect();
std::string TestValidConnect();
std::string TestTextSendReceive();
// Used by the tests that access the C API directly. // Used by the tests that access the C API directly.
const PPB_WebSocket_Dev* websocket_interface_; const PPB_WebSocket_Dev* websocket_interface_;
const PPB_Var* var_interface_;
const PPB_Core* core_interface_;
}; };
#endif // PAPPI_TESTS_TEST_WEBSOCKET_H_ #endif // PAPPI_TESTS_TEST_WEBSOCKET_H_
...@@ -4,67 +4,19 @@ ...@@ -4,67 +4,19 @@
#include "webkit/plugins/ppapi/ppb_websocket_impl.h" #include "webkit/plugins/ppapi/ppb_websocket_impl.h"
#include <string>
#include "base/logging.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_var.h" #include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/cpp/module.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/shared_impl/var_tracker.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSocket.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
#include "webkit/plugins/ppapi/host_globals.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/resource_helper.h"
using ppapi::PpapiGlobals;
using ppapi::StringVar;
using ppapi::thunk::PPB_WebSocket_API; using ppapi::thunk::PPB_WebSocket_API;
using ppapi::VarTracker;
using WebKit::WebData;
using WebKit::WebDocument;
using WebKit::WebString;
using WebKit::WebSocket;
using WebKit::WebSocketClient;
using WebKit::WebURL;
static const uint32_t kMaxReasonSizeInBytes = 123;
namespace webkit { namespace webkit {
namespace ppapi { namespace ppapi {
PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance)
: Resource(instance), : Resource(instance) {
state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV),
receive_callback_var_(NULL),
wait_for_receive_(false),
close_code_(0),
close_was_clean_(PP_FALSE) {
empty_string_ = new StringVar(
PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0);
} }
PPB_WebSocket_Impl::~PPB_WebSocket_Impl() { PPB_WebSocket_Impl::~PPB_WebSocket_Impl() {
if (websocket_.get())
websocket_->disconnect();
// Clean up received and unread messages
VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker();
while (!received_messages_.empty()) {
PP_Var var = received_messages_.front();
received_messages_.pop();
var_tracker->ReleaseVar(var);
}
} }
// static // static
...@@ -81,302 +33,66 @@ int32_t PPB_WebSocket_Impl::Connect(PP_Var url, ...@@ -81,302 +33,66 @@ int32_t PPB_WebSocket_Impl::Connect(PP_Var url,
const PP_Var protocols[], const PP_Var protocols[],
uint32_t protocol_count, uint32_t protocol_count,
PP_CompletionCallback callback) { PP_CompletionCallback callback) {
// Check mandatory interfaces. // TODO(toyoshim): Implement it.
PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this);
DCHECK(plugin_instance);
if (!plugin_instance)
return PP_ERROR_FAILED;
// Connect() can be called at most once.
if (websocket_.get())
return PP_ERROR_INPROGRESS;
if (state_ != PP_WEBSOCKETREADYSTATE_INVALID_DEV)
return PP_ERROR_INPROGRESS;
state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV;
// Validate |callback| (Doesn't support blocking callback)
if (!callback.func)
return PP_ERROR_BLOCKS_MAIN_THREAD;
// Validate url and convert it to WebURL.
scoped_refptr<StringVar> url_string = StringVar::FromPPVar(url);
if (!url_string)
return PP_ERROR_BADARGUMENT;
GURL gurl(url_string->value());
if (!gurl.is_valid())
return PP_ERROR_BADARGUMENT;
if (!gurl.SchemeIs("ws") && !gurl.SchemeIs("wss"))
return PP_ERROR_BADARGUMENT;
if (gurl.has_ref())
return PP_ERROR_BADARGUMENT;
if (!net::IsPortAllowedByDefault(gurl.IntPort()))
return PP_ERROR_BADARGUMENT;
WebURL web_url(gurl);
// Validate protocols and convert it to WebString.
// TODO(toyoshim): Detect duplicated protocols as error.
std::string protocol_string;
for (uint32_t i = 0; i < protocol_count; i++) {
// TODO(toyoshim): Similar function exist in WebKit::WebSocket.
// We must rearrange them into WebKit::WebChannel and share its protocol
// related implementation via WebKit API.
scoped_refptr<StringVar> string_var;
string_var = StringVar::FromPPVar(protocols[i]);
if (!string_var || !string_var->value().length())
return PP_ERROR_BADARGUMENT;
for (std::string::const_iterator it = string_var->value().begin();
it != string_var->value().end();
++it) {
uint8_t character = static_cast<uint8_t>(*it);
// WebSocket specification says "(Subprotocol string must consist of)
// characters in the range U+0021 to U+007E not including separator
// characters as defined in [RFC2616]."
const uint8_t minimumProtocolCharacter = '!'; // U+0021.
const uint8_t maximumProtocolCharacter = '~'; // U+007E.
if (character < minimumProtocolCharacter ||
character > maximumProtocolCharacter ||
character == '"' || character == '(' || character == ')' ||
character == ',' || character == '/' ||
(character >= ':' && character <= '@') || // U+003A - U+0040
(character >= '[' && character <= ']') || // U+005B - u+005D
character == '{' || character == '}')
return PP_ERROR_BADARGUMENT;
}
if (i != 0)
protocol_string.append(",");
protocol_string.append(string_var->value());
}
WebString web_protocols = WebString::fromUTF8(protocol_string);
// Create WebKit::WebSocket object.
WebDocument document = plugin_instance->container()->element().document();
websocket_.reset(WebSocket::create(document, this));
DCHECK(websocket_.get());
if (!websocket_.get())
return PP_ERROR_NOTSUPPORTED; return PP_ERROR_NOTSUPPORTED;
websocket_->connect(web_url, web_protocols);
state_ = PP_WEBSOCKETREADYSTATE_CONNECTING_DEV;
// Install callback.
connect_callback_ = callback;
return PP_OK_COMPLETIONPENDING;
} }
int32_t PPB_WebSocket_Impl::Close(uint16_t code, int32_t PPB_WebSocket_Impl::Close(uint16_t code,
PP_Var reason, PP_Var reason,
PP_CompletionCallback callback) { PP_CompletionCallback callback) {
// Check mandarory interfaces. // TODO(toyoshim): Implement it.
if (!websocket_.get()) return PP_ERROR_NOTSUPPORTED;
return PP_ERROR_FAILED;
// Validate |callback| (Doesn't support blocking callback)
if (!callback.func)
return PP_ERROR_BLOCKS_MAIN_THREAD;
// Validate |code|.
if (code != WebSocket::CloseEventCodeNotSpecified) {
if (!(code == WebSocket::CloseEventCodeNormalClosure ||
(WebSocket::CloseEventCodeMinimumUserDefined <= code &&
code <= WebSocket::CloseEventCodeMaximumUserDefined)))
return PP_ERROR_NOACCESS;
}
// Validate |reason|.
// TODO(toyoshim): Returns PP_ERROR_BADARGUMENT if |reason| contains any
// surrogates.
scoped_refptr<StringVar> reason_string = StringVar::FromPPVar(reason);
if (!reason_string || reason_string->value().size() > kMaxReasonSizeInBytes)
return PP_ERROR_BADARGUMENT;
// Check state.
if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV ||
state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV)
return PP_ERROR_INPROGRESS;
// Install |callback|.
close_callback_ = callback;
if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) {
state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV;
PP_RunAndClearCompletionCallback(&connect_callback_, PP_ERROR_ABORTED);
websocket_->fail(
"WebSocket was closed before the connection was established.");
return PP_OK_COMPLETIONPENDING;
}
// TODO(toyoshim): Handle bufferedAmount here.
state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV;
WebString web_reason = WebString::fromUTF8(reason_string->value());
websocket_->close(code, web_reason);
return PP_OK_COMPLETIONPENDING;
} }
int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message,
PP_CompletionCallback callback) { PP_CompletionCallback callback) {
// Check state. // TODO(toyoshim): Implement it.
if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || return PP_ERROR_NOTSUPPORTED;
state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV)
return PP_ERROR_BADARGUMENT;
// Just return received message if any received message is queued.
if (!received_messages_.empty())
return DoReceive();
// Or retain |message| as buffer to store and install |callback|.
wait_for_receive_ = true;
receive_callback_var_ = message;
receive_callback_ = callback;
return PP_OK_COMPLETIONPENDING;
} }
int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) {
// Check mandatory interfaces. // TODO(toyoshim): Implement it.
if (!websocket_.get())
return PP_ERROR_FAILED;
// Check state.
if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV ||
state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV)
return PP_ERROR_BADARGUMENT;
if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV ||
state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) {
// TODO(toyoshim): Handle bufferedAmount here.
}
if (message.type != PP_VARTYPE_STRING) {
// TODO(toyoshim): Support binary data.
return PP_ERROR_NOTSUPPORTED; return PP_ERROR_NOTSUPPORTED;
}
// Convert message to WebString.
scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message);
if (!message_string)
return PP_ERROR_BADARGUMENT;
WebString web_message = WebString::fromUTF8(message_string->value());
if (!websocket_->sendText(web_message))
return PP_ERROR_BADARGUMENT;
return PP_OK;
} }
uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { uint64_t PPB_WebSocket_Impl::GetBufferedAmount() {
// TODO(toyoshim): Implement. // TODO(toyoshim): Implement it.
return 0; return 0;
} }
uint16_t PPB_WebSocket_Impl::GetCloseCode() { uint16_t PPB_WebSocket_Impl::GetCloseCode() {
return close_code_; // TODO(toyoshim): Implement it.
return 0;
} }
PP_Var PPB_WebSocket_Impl::GetCloseReason() { PP_Var PPB_WebSocket_Impl::GetCloseReason() {
if (!close_reason_) // TODO(toyoshim): Implement it.
return empty_string_->GetPPVar(); return PP_MakeUndefined();
return close_reason_->GetPPVar();
} }
PP_Bool PPB_WebSocket_Impl::GetCloseWasClean() { PP_Bool PPB_WebSocket_Impl::GetCloseWasClean() {
return close_was_clean_; // TODO(toyoshim): Implement it.
return PP_FALSE;
} }
PP_Var PPB_WebSocket_Impl::GetExtensions() { PP_Var PPB_WebSocket_Impl::GetExtensions() {
// TODO(toyoshim): For now, always returns empty string. // TODO(toyoshim): Implement it.
if (!extensions_) return PP_MakeUndefined();
return empty_string_->GetPPVar();
return extensions_->GetPPVar();
} }
PP_Var PPB_WebSocket_Impl::GetProtocol() { PP_Var PPB_WebSocket_Impl::GetProtocol() {
// TODO(toyoshim): Implement. // TODO(toyoshim): Implement it.
if (!protocol_) return PP_MakeUndefined();
return empty_string_->GetPPVar();
return protocol_->GetPPVar();
} }
PP_WebSocketReadyState_Dev PPB_WebSocket_Impl::GetReadyState() { PP_WebSocketReadyState_Dev PPB_WebSocket_Impl::GetReadyState() {
return state_; // TODO(toyoshim): Implement it.
return PP_WEBSOCKETREADYSTATE_INVALID_DEV;
} }
PP_Var PPB_WebSocket_Impl::GetURL() { PP_Var PPB_WebSocket_Impl::GetURL() {
// TODO(toyoshim): For now, always returns empty string. // TODO(toyoshim): Implement it.
if (!url_) return PP_MakeUndefined();
return empty_string_->GetPPVar();
return url_->GetPPVar();
}
void PPB_WebSocket_Impl::didConnect() {
DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_);
state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV;
PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK);
}
void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) {
// Append received data to queue.
std::string string = message.utf8();
PP_Var var = StringVar::StringToPPVar(
PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), string);
received_messages_.push(var);
if (!wait_for_receive_)
return;
PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive());
}
void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) {
DLOG(INFO) << "didReceiveBinaryData is not implemented yet.";
// TODO(toyoshim): Support to receive binary data.
}
void PPB_WebSocket_Impl::didReceiveMessageError() {
// TODO(toyoshim): Must implement.
DLOG(INFO) << "didReceiveMessageError is not implemented yet.";
}
void PPB_WebSocket_Impl::didStartClosingHandshake() {
// TODO(toyoshim): Must implement.
DLOG(INFO) << "didStartClosingHandshake is not implemented yet.";
}
void PPB_WebSocket_Impl::didClose(unsigned long bufferedAmount,
ClosingHandshakeCompletionStatus status,
unsigned short code,
const WebString& reason) {
// Store code and reason.
close_code_ = code;
std::string reason_string = reason.utf8();
close_reason_ = new StringVar(
PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string);
// TODO(toyoshim): Set close_was_clean_.
// Handle state transition and invoking callback.
DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_);
PP_WebSocketReadyState_Dev state = state_;
state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV;
if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV)
PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK);
if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV)
PP_RunAndClearCompletionCallback(&close_callback_, PP_OK);
}
int32_t PPB_WebSocket_Impl::DoReceive() {
// TODO(toyoshim): Check state.
if (!receive_callback_var_)
return PP_OK;
*receive_callback_var_ = received_messages_.front();
received_messages_.pop();
receive_callback_var_ = NULL;
wait_for_receive_ = false;
return PP_OK;
} }
} // namespace ppapi } // namespace ppapi
......
...@@ -5,22 +5,8 @@ ...@@ -5,22 +5,8 @@
#ifndef WEBKIT_PLUGINS_PPAPI_PPB_WEBSOCKET_IMPL_H_ #ifndef WEBKIT_PLUGINS_PPAPI_PPB_WEBSOCKET_IMPL_H_
#define WEBKIT_PLUGINS_PPAPI_PPB_WEBSOCKET_IMPL_H_ #define WEBKIT_PLUGINS_PPAPI_PPB_WEBSOCKET_IMPL_H_
#include <queue>
#include "base/memory/scoped_ptr.h"
#include "ppapi/shared_impl/resource.h" #include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/ppb_websocket_api.h" #include "ppapi/thunk/ppb_websocket_api.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSocketClient.h"
struct PPB_Var;
namespace ppapi {
class StringVar;
}
namespace WebKit {
class WebSocket;
}
namespace webkit { namespace webkit {
namespace ppapi { namespace ppapi {
...@@ -28,8 +14,7 @@ namespace ppapi { ...@@ -28,8 +14,7 @@ namespace ppapi {
// All implementation is in this class for now. We should move some common // All implementation is in this class for now. We should move some common
// implementation to shared_impl when we implement proxy interfaces. // implementation to shared_impl when we implement proxy interfaces.
class PPB_WebSocket_Impl : public ::ppapi::Resource, class PPB_WebSocket_Impl : public ::ppapi::Resource,
public ::ppapi::thunk::PPB_WebSocket_API, public ::ppapi::thunk::PPB_WebSocket_API {
public ::WebKit::WebSocketClient {
public: public:
explicit PPB_WebSocket_Impl(PP_Instance instance); explicit PPB_WebSocket_Impl(PP_Instance instance);
virtual ~PPB_WebSocket_Impl(); virtual ~PPB_WebSocket_Impl();
...@@ -59,41 +44,6 @@ class PPB_WebSocket_Impl : public ::ppapi::Resource, ...@@ -59,41 +44,6 @@ class PPB_WebSocket_Impl : public ::ppapi::Resource,
virtual PP_WebSocketReadyState_Dev GetReadyState() OVERRIDE; virtual PP_WebSocketReadyState_Dev GetReadyState() OVERRIDE;
virtual PP_Var GetURL() OVERRIDE; virtual PP_Var GetURL() OVERRIDE;
// WebSocketClient implementation.
virtual void didConnect() OVERRIDE;
virtual void didReceiveMessage(const WebKit::WebString& message) OVERRIDE;
virtual void didReceiveBinaryData(
const WebKit::WebData& binaryData) OVERRIDE;
virtual void didReceiveMessageError() OVERRIDE;
virtual void didStartClosingHandshake() OVERRIDE;
virtual void didClose(unsigned long bufferedAmount,
ClosingHandshakeCompletionStatus status,
unsigned short code,
const WebKit::WebString& reason) OVERRIDE;
private:
int32_t DoReceive();
scoped_ptr<WebKit::WebSocket> websocket_;
PP_WebSocketReadyState_Dev state_;
PP_CompletionCallback connect_callback_;
PP_CompletionCallback receive_callback_;
PP_Var* receive_callback_var_;
bool wait_for_receive_;
// TODO(toyoshim): Use std::queue<Var> when it supports binary.
std::queue<PP_Var> received_messages_;
PP_CompletionCallback close_callback_;
uint16_t close_code_;
scoped_refptr< ::ppapi::StringVar> close_reason_;
PP_Bool close_was_clean_;
scoped_refptr< ::ppapi::StringVar> empty_string_;
scoped_refptr< ::ppapi::StringVar> extensions_;
scoped_refptr< ::ppapi::StringVar> protocol_;
scoped_refptr< ::ppapi::StringVar> url_;
DISALLOW_COPY_AND_ASSIGN(PPB_WebSocket_Impl); DISALLOW_COPY_AND_ASSIGN(PPB_WebSocket_Impl);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment