Commit c35f468e authored by Song Fangzhen's avatar Song Fangzhen Committed by Chromium LUCI CQ

Direct Sockets: Implements close() for TCPSocket.

Below documents are from Eric Willigers <ericwilligers@chromium.org>.
Explainer: https://github.com/WICG/raw-sockets/blob/master/docs/explainer.md

Intent to Prototype:
https://groups.google.com/a/chromium.org/g/blink-dev/c/ARtkaw4e9T4/m/npjeMssPCAAJ

Design doc:
https://docs.google.com/document/d/1Xa5nFkIWxkL3hZHvDYWPhT8sZvNeFpCUKNuqIwZHxnE/edit?usp=sharing

Bug: 905818
Change-Id: I72e869c64a486534ceee150010febb10574cd1d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2595554
Commit-Queue: Ke He <kehe@chromium.org>
Commit-Queue: Eric Willigers <ericwilligers@chromium.org>
Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Reviewed-by: default avatarGlen Robertson <glenrob@chromium.org>
Cr-Commit-Position: refs/heads/master@{#838784}
parent fa7fafbb
...@@ -24,6 +24,7 @@ source_set("unit_tests") { ...@@ -24,6 +24,7 @@ source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
"tcp_readable_stream_wrapper_unittest.cc", "tcp_readable_stream_wrapper_unittest.cc",
"tcp_socket_unittest.cc",
"tcp_writable_stream_wrapper_unittest.cc", "tcp_writable_stream_wrapper_unittest.cc",
] ]
......
...@@ -75,10 +75,38 @@ void TCPSocket::Init(int32_t result, ...@@ -75,10 +75,38 @@ void TCPSocket::Init(int32_t result,
resolver_ = nullptr; resolver_ = nullptr;
} }
ScriptPromise TCPSocket::close(ScriptState*, ExceptionState&) { ScriptPromise TCPSocket::close(ScriptState* script_state, ExceptionState&) {
// TODO(crbug.com/905818): Implement close. local_addr_ = base::nullopt;
NOTIMPLEMENTED(); peer_addr_ = base::nullopt;
return ScriptPromise(); tcp_socket_.reset();
socket_observer_receiver_.reset();
feature_handle_for_scheduler_.reset();
if (resolver_) {
resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kAbortError, "The request was aborted locally"));
resolver_ = nullptr;
DCHECK(!tcp_readable_stream_wrapper_);
DCHECK(!tcp_writable_stream_wrapper_);
return ScriptPromise::CastUndefined(script_state);
}
if (tcp_readable_stream_wrapper_ &&
tcp_readable_stream_wrapper_->GetState() ==
TCPReadableStreamWrapper::State::kOpen) {
tcp_readable_stream_wrapper_->Reset();
}
tcp_readable_stream_wrapper_ = nullptr;
if (tcp_writable_stream_wrapper_ &&
tcp_writable_stream_wrapper_->GetState() ==
TCPWritableStreamWrapper::State::kOpen) {
tcp_writable_stream_wrapper_->Reset();
}
tcp_writable_stream_wrapper_ = nullptr;
return ScriptPromise::CastUndefined(script_state);
} }
ReadableStream* TCPSocket::readable() const { ReadableStream* TCPSocket::readable() const {
......
// Copyright 2020 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.
#include "third_party/blink/renderer/modules/direct_sockets/tcp_socket.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
namespace {
class TCPSocketCreator {
STACK_ALLOCATED();
public:
TCPSocketCreator() = default;
~TCPSocketCreator() = default;
TCPSocket* Create(const V8TestingScope& scope) {
auto* script_state = scope.GetScriptState();
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
auto* tcp_socket = MakeGarbageCollected<TCPSocket>(*resolver);
create_promise_ = resolver->Promise();
return tcp_socket;
}
ScriptPromise GetSciptPromise() { return create_promise_; }
private:
ScriptPromise create_promise_;
};
TEST(TCPSocketTest, Create) {
V8TestingScope scope;
TCPSocketCreator tcp_socket_creator;
auto create_promise = tcp_socket_creator.GetSciptPromise();
EXPECT_TRUE(create_promise.IsEmpty());
tcp_socket_creator.Create(scope);
auto* script_state = scope.GetScriptState();
create_promise = tcp_socket_creator.GetSciptPromise();
ScriptPromiseTester create_tester(script_state, create_promise);
EXPECT_TRUE(create_promise.IsAssociatedWith(script_state));
ASSERT_FALSE(create_tester.IsFulfilled());
}
TEST(TCPSocketTest, CloseBeforeInit) {
V8TestingScope scope;
TCPSocketCreator tcp_socket_creator;
auto* tcp_socket = tcp_socket_creator.Create(scope);
auto* script_state = scope.GetScriptState();
auto create_promise = tcp_socket_creator.GetSciptPromise();
ScriptPromiseTester create_tester(script_state, create_promise);
ASSERT_FALSE(create_tester.IsRejected());
auto close_promise =
tcp_socket->close(script_state, scope.GetExceptionState());
ScriptPromiseTester close_tester(script_state, close_promise);
create_tester.WaitUntilSettled();
ASSERT_TRUE(create_tester.IsRejected());
close_tester.WaitUntilSettled();
ASSERT_TRUE(close_tester.IsFulfilled());
}
TEST(TCPSocketTest, CloseAfterInitWithoutResultOK) {
V8TestingScope scope;
TCPSocketCreator tcp_socket_creator;
auto* tcp_socket = tcp_socket_creator.Create(scope);
auto* script_state = scope.GetScriptState();
auto create_promise = tcp_socket_creator.GetSciptPromise();
ScriptPromiseTester create_tester(script_state, create_promise);
ASSERT_FALSE(create_tester.IsRejected());
int32_t result = net::Error::ERR_FAILED;
tcp_socket->Init(result, net::IPEndPoint(), net::IPEndPoint(),
mojo::ScopedDataPipeConsumerHandle(),
mojo::ScopedDataPipeProducerHandle());
auto close_promise =
tcp_socket->close(script_state, scope.GetExceptionState());
ScriptPromiseTester close_tester(script_state, close_promise);
create_tester.WaitUntilSettled();
ASSERT_TRUE(create_tester.IsRejected());
close_tester.WaitUntilSettled();
ASSERT_TRUE(close_tester.IsFulfilled());
}
TEST(TCPSocketTest, CloseAfterInitWithResultOK) {
V8TestingScope scope;
TCPSocketCreator tcp_socket_creator;
auto* tcp_socket = tcp_socket_creator.Create(scope);
auto* script_state = scope.GetScriptState();
auto create_promise = tcp_socket_creator.GetSciptPromise();
ScriptPromiseTester create_tester(script_state, create_promise);
ASSERT_FALSE(create_tester.IsFulfilled());
int32_t result = net::Error::OK;
tcp_socket->Init(result, net::IPEndPoint(), net::IPEndPoint(),
mojo::ScopedDataPipeConsumerHandle(),
mojo::ScopedDataPipeProducerHandle());
EXPECT_TRUE(tcp_socket->readable());
EXPECT_TRUE(tcp_socket->writable());
auto close_promise =
tcp_socket->close(script_state, scope.GetExceptionState());
ScriptPromiseTester close_tester(script_state, close_promise);
create_tester.WaitUntilSettled();
ASSERT_TRUE(create_tester.IsFulfilled());
close_tester.WaitUntilSettled();
ASSERT_TRUE(close_tester.IsFulfilled());
}
} // namespace
} // namespace blink
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