+SocketSecureFunction::SocketSecureFunction() {
+}
+
+SocketSecureFunction::~SocketSecureFunction() {
+}
+
+bool SocketSecureFunction::Prepare() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ params_ = core_api::socket::Secure::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(params_.get());
+ url_request_getter_ = browser_context()->GetRequestContext();
+ return true;
+}
+
+// Override the regular implementation, which would call AsyncWorkCompleted
+// immediately after Work().
+void SocketSecureFunction::AsyncWorkStart() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+
+ Socket* socket = GetSocket(params_->socket_id);
+ if (!socket) {
+ SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
+ error_ = kSocketNotFoundError;
+ AsyncWorkCompleted();
+ return;
+ }
+
+ // Make sure that the socket is a TCP client socket.
+ if (socket->GetSocketType() != Socket::TYPE_TCP ||
+ static_cast<TCPSocket*>(socket)->ClientStream() == NULL) {
+ SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
+ error_ = kSecureSocketTypeError;
+ AsyncWorkCompleted();
+ return;
+ }
+
+ if (!socket->IsConnected()) {
+ SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
+ error_ = kSocketNotConnectedError;
+ AsyncWorkCompleted();
+ return;
+ }
+
+ net::URLRequestContext* url_request_context =
+ url_request_getter_->GetURLRequestContext();
+
+ TLSSocket::UpgradeSocketToTLS(
+ socket,
+ url_request_context->ssl_config_service(),
+ url_request_context->cert_verifier(),
+ url_request_context->transport_security_state(),
+ extension_id(),
+ params_->options.get(),
+ base::Bind(&SocketSecureFunction::TlsConnectDone, this));
+}
+
+void SocketSecureFunction::TlsConnectDone(scoped_ptr<TLSSocket> socket,
+ int result) {
+ // if an error occurred, socket MUST be NULL.
+ DCHECK(result == net::OK || socket == NULL);
+
+ if (socket && result == net::OK) {
+ ReplaceSocket(params_->socket_id, socket.release());
+ } else {
+ RemoveSocket(params_->socket_id);
+ error_ = net::ErrorToString(result);
+ }
+
+ results_ = core_api::socket::Secure::Results::Create(result);
+ AsyncWorkCompleted();
+}
+