| Index: webkit/plugins/ppapi/ppb_transport_impl.cc
|
| diff --git a/webkit/plugins/ppapi/ppb_transport_impl.cc b/webkit/plugins/ppapi/ppb_transport_impl.cc
|
| index 55a46e85ac17ea1a4a41d627e72550dc35badadf..9e814cfa2737ed450ba8ad2c581b995f37cf22e6 100644
|
| --- a/webkit/plugins/ppapi/ppb_transport_impl.cc
|
| +++ b/webkit/plugins/ppapi/ppb_transport_impl.cc
|
| @@ -4,8 +4,11 @@
|
|
|
| #include "webkit/plugins/ppapi/ppb_transport_impl.h"
|
|
|
| +#include "base/json/json_reader.h"
|
| +#include "base/json/json_writer.h"
|
| #include "base/message_loop.h"
|
| #include "base/string_util.h"
|
| +#include "base/values.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/socket/socket.h"
|
| @@ -45,6 +48,122 @@ int MapNetError(int result) {
|
| }
|
| }
|
|
|
| +std::string FormatJson(Value* value) {
|
| + std::string result;
|
| + base::JSONWriter::Write(value, false, &result);
|
| + return result;
|
| +}
|
| +
|
| +// ParseConfig() parses JSON blob with P2P Transport
|
| +// configuration. Example of a valid config:
|
| +// {
|
| +// "stunServer": ["stun1.l.google.com:31323", "stun2.l.google.com:54324"],
|
| +// "relayServer": "relay.google.com",
|
| +// "relayToken": "34t34f234f12",
|
| +// "tcpReceiveWindow": 32768,
|
| +// "tcpSendWindow": 32768,
|
| +// };
|
| +int ParseConfig(const std::string& config_str, P2PTransport::Config* config) {
|
| + scoped_ptr<Value> value(base::JSONReader::Read(config_str, true));
|
| + if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) {
|
| + return false;
|
| + }
|
| +
|
| + DictionaryValue* dic_value = static_cast<DictionaryValue*>(value.get());
|
| +
|
| + // Parse STUN servers list.
|
| + config->stun_servers.clear();
|
| + Value* stun_server;
|
| + if (dic_value->Get("stunServer", &stun_server)) {
|
| + if (stun_server->IsType(Value::TYPE_LIST)) {
|
| + ListValue* stun_list = static_cast<ListValue*>(stun_server);
|
| + for (ListValue::iterator it = stun_list->begin();
|
| + it != stun_list->end(); ++it) {
|
| + std::string server_address;
|
| + if ((*it)->GetAsString(&server_address)) {
|
| + config->stun_servers.push_back(server_address);
|
| + } else {
|
| + LOG(ERROR) << "Invalid stun server specification: " <<
|
| + FormatJson(*it);
|
| + return false;
|
| + }
|
| + }
|
| + } else if (stun_server->IsType(Value::TYPE_STRING)) {
|
| + std::string server_address;
|
| + stun_server->GetAsString(&server_address);
|
| + config->stun_servers.push_back(server_address);
|
| + } else {
|
| + LOG(ERROR) << "Invalid stun server specification: "
|
| + << FormatJson(stun_server);
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + // Parse Relay servers list.
|
| + config->relay_servers.clear();
|
| + Value* relay_server;
|
| + if (dic_value->Get("relayServer", &relay_server)) {
|
| + if (relay_server->IsType(Value::TYPE_LIST)) {
|
| + ListValue* relay_list = static_cast<ListValue*>(relay_server);
|
| + for (ListValue::iterator it = relay_list->begin();
|
| + it != relay_list->end(); ++it) {
|
| + std::string server_address;
|
| + if ((*it)->GetAsString(&server_address)) {
|
| + config->relay_servers.push_back(server_address);
|
| + } else {
|
| + LOG(ERROR) << "Invalid relay server specification: "
|
| + << FormatJson(*it);
|
| + return false;
|
| + }
|
| + }
|
| + } else if (relay_server->IsType(Value::TYPE_STRING)) {
|
| + std::string server_address;
|
| + relay_server->GetAsString(&server_address);
|
| + config->relay_servers.push_back(server_address);
|
| + } else {
|
| + LOG(ERROR) << "Invalid relay server specification: "
|
| + << FormatJson(relay_server);
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + // Relay token.
|
| + Value* relay_token;
|
| + if (dic_value->Get("relayToken", &relay_token)) {
|
| + if (!relay_token->GetAsString(&config->relay_token)) {
|
| + LOG(ERROR) << "Invalid relay token: "
|
| + << FormatJson(relay_token);
|
| + return false;
|
| + }
|
| + } else {
|
| + config->relay_token = "";
|
| + }
|
| +
|
| + Value* tcp_receive_window;
|
| + if (dic_value->Get("tcpReceiveWindow", &tcp_receive_window)) {
|
| + if (!tcp_receive_window->GetAsInteger(&config->tcp_receive_window)) {
|
| + LOG(ERROR) << "Invalid TCP receive window value: "
|
| + << FormatJson(tcp_receive_window);
|
| + return false;
|
| + }
|
| + } else {
|
| + config->tcp_receive_window = 0;
|
| + }
|
| +
|
| + Value* tcp_send_window;
|
| + if (dic_value->Get("tcpSendWindow", &tcp_send_window)) {
|
| + if (!tcp_send_window->GetAsInteger(&config->tcp_send_window)) {
|
| + LOG(ERROR) << "Invalid TCP send window value: "
|
| + << FormatJson(tcp_send_window);
|
| + return false;
|
| + }
|
| + } else {
|
| + config->tcp_send_window = 0;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace
|
|
|
| PPB_Transport_Impl::PPB_Transport_Impl(PluginInstance* instance)
|
| @@ -97,6 +216,14 @@ PP_Bool PPB_Transport_Impl::IsWritable() {
|
| return PP_FromBool(writable_);
|
| }
|
|
|
| +int32_t PPB_Transport_Impl::SetConfig(const char* config) {
|
| + // SetConfig() may only be called before Connect().
|
| + if (started_)
|
| + return PP_ERROR_FAILED;
|
| +
|
| + return ParseConfig(config, &config_) ? PP_OK : PP_ERROR_BADARGUMENT;
|
| +}
|
| +
|
| int32_t PPB_Transport_Impl::Connect(PP_CompletionCallback callback) {
|
| if (!p2p_transport_.get())
|
| return PP_ERROR_FAILED;
|
| @@ -108,7 +235,7 @@ int32_t PPB_Transport_Impl::Connect(PP_CompletionCallback callback) {
|
| P2PTransport::Protocol protocol = use_tcp_ ?
|
| P2PTransport::PROTOCOL_TCP : P2PTransport::PROTOCOL_UDP;
|
|
|
| - if (!p2p_transport_->Init(name_, protocol, "", this))
|
| + if (!p2p_transport_->Init(name_, protocol, config_, this))
|
| return PP_ERROR_FAILED;
|
|
|
| started_ = true;
|
|
|