summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/fetch
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/fetch')
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/DEPS8
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.h24
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc145
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h36
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc112
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc169
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h67
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc238
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc116
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h12
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h17
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/global_fetch.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/global_fetch.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/headers.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/headers.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/multipart_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.h9
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/trust_token.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc3
49 files changed, 920 insertions, 372 deletions
diff --git a/chromium/third_party/blink/renderer/core/fetch/BUILD.gn b/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
index 596433ac5ea..5b2297669c1 100644
--- a/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
@@ -14,6 +14,8 @@ blink_core_sources("fetch") {
"body_stream_buffer.h",
"bytes_consumer_tee.cc",
"bytes_consumer_tee.h",
+ "bytes_uploader.cc",
+ "bytes_uploader.h",
"fetch_data_loader.cc",
"fetch_data_loader.h",
"fetch_header_list.cc",
diff --git a/chromium/third_party/blink/renderer/core/fetch/DEPS b/chromium/third_party/blink/renderer/core/fetch/DEPS
index 82e8abc9aab..b43df3036d0 100644
--- a/chromium/third_party/blink/renderer/core/fetch/DEPS
+++ b/chromium/third_party/blink/renderer/core/fetch/DEPS
@@ -3,8 +3,16 @@ include_rules = [
"+mojo/public/cpp/system/data_pipe.h",
"+mojo/public/cpp/system/data_pipe_utils.h",
"+mojo/public/cpp/system/simple_watcher.h",
+ "+net/base/net_errors.h",
"+net/base/request_priority.h",
+ "+net/http/http_response_info.h",
"+services/network/public/cpp",
"+services/network/public/mojom",
"+url/gurl.h",
]
+
+specific_include_rules = {
+ "bytes_uploader_test\.cc": [
+ "+base/test/mock_callback.h",
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc
index 148926a43aa..2c7713ace06 100644
--- a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.cc
@@ -99,7 +99,7 @@ BytesConsumer::PublicState BlobBytesConsumer::GetPublicState() const {
return nested_consumer_->GetPublicState();
}
-void BlobBytesConsumer::Trace(Visitor* visitor) {
+void BlobBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(execution_context_);
visitor->Trace(nested_consumer_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h
index 4cc789a8858..6c125ef6d54 100644
--- a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer.h
@@ -37,7 +37,7 @@ class CORE_EXPORT BlobBytesConsumer final : public BytesConsumer {
Error GetError() const override;
String DebugName() const override { return "BlobBytesConsumer"; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.cc b/chromium/third_party/blink/renderer/core/fetch/body.cc
index 437db5482c5..28635ccf614 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/body.cc
@@ -64,7 +64,7 @@ class BodyConsumerBase : public GarbageCollected<BodyConsumerBase>,
WrapPersistent(this), object));
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(resolver_);
FetchDataLoader::Client::Trace(visitor);
}
@@ -162,7 +162,7 @@ class BodyJsonConsumer final : public BodyConsumerBase {
ScriptPromise Body::arrayBuffer(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -195,7 +195,7 @@ ScriptPromise Body::arrayBuffer(ScriptState* script_state,
ScriptPromise Body::blob(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -225,7 +225,7 @@ ScriptPromise Body::blob(ScriptState* script_state,
ScriptPromise Body::formData(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -295,7 +295,7 @@ ScriptPromise Body::formData(ScriptState* script_state,
ScriptPromise Body::json(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -324,7 +324,7 @@ ScriptPromise Body::json(ScriptState* script_state,
ScriptPromise Body::text(ScriptState* script_state,
ExceptionState& exception_state) {
- RejectInvalidConsumption(script_state, exception_state);
+ RejectInvalidConsumption(exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -365,25 +365,14 @@ ReadableStream* Body::body() {
return BodyBuffer()->Stream();
}
-Body::BodyUsed Body::IsBodyUsed(ExceptionState& exception_state) {
+bool Body::IsBodyUsed() const {
auto* body_buffer = BodyBuffer();
- if (!body_buffer)
- return BodyUsed::kUnused;
- base::Optional<bool> stream_disturbed =
- body_buffer->IsStreamDisturbed(exception_state);
- if (exception_state.HadException())
- return BodyUsed::kBroken;
- return stream_disturbed.value() ? BodyUsed::kUsed : BodyUsed::kUnused;
+ return body_buffer && body_buffer->IsStreamDisturbed();
}
-Body::BodyLocked Body::IsBodyLocked(ExceptionState& exception_state) {
+bool Body::IsBodyLocked() const {
auto* body_buffer = BodyBuffer();
- if (!body_buffer)
- return BodyLocked::kUnlocked;
- base::Optional<bool> is_locked = body_buffer->IsStreamLocked(exception_state);
- if (exception_state.HadException())
- return BodyLocked::kBroken;
- return is_locked.value() ? BodyLocked::kLocked : BodyLocked::kUnlocked;
+ return body_buffer && body_buffer->IsStreamLocked();
}
bool Body::HasPendingActivity() const {
@@ -395,31 +384,16 @@ bool Body::HasPendingActivity() const {
return body_buffer->HasPendingActivity();
}
-bool Body::IsBodyUsedForDCheck(ExceptionState& exception_state) {
- return BodyBuffer() &&
- BodyBuffer()->IsStreamDisturbedForDCheck(exception_state);
-}
-
Body::Body(ExecutionContext* context) : ExecutionContextClient(context) {}
-void Body::RejectInvalidConsumption(ScriptState* script_state,
- ExceptionState& exception_state) {
- const auto used = IsBodyUsed(exception_state);
- if (exception_state.HadException()) {
- DCHECK_EQ(used, BodyUsed::kBroken);
- return;
- }
- DCHECK_NE(used, BodyUsed::kBroken);
-
- if (IsBodyLocked(exception_state) == BodyLocked::kLocked) {
- DCHECK(!exception_state.HadException());
+void Body::RejectInvalidConsumption(ExceptionState& exception_state) const {
+ if (IsBodyLocked()) {
exception_state.ThrowTypeError("body stream is locked");
}
- if (exception_state.HadException())
- return;
- if (used == BodyUsed::kUsed)
+ if (IsBodyUsed()) {
exception_state.ThrowTypeError("body stream already read");
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.h b/chromium/third_party/blink/renderer/core/fetch/body.h
index fa3449c1273..3db2c704600 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body.h
+++ b/chromium/third_party/blink/renderer/core/fetch/body.h
@@ -31,9 +31,6 @@ class ScriptState;
// implementation.
class CORE_EXPORT Body : public ExecutionContextClient {
public:
- enum class BodyUsed { kUsed, kUnused, kBroken };
- enum class BodyLocked { kLocked, kUnlocked, kBroken };
-
explicit Body(ExecutionContext*);
ScriptPromise arrayBuffer(ScriptState*, ExceptionState&);
@@ -47,25 +44,16 @@ class CORE_EXPORT Body : public ExecutionContextClient {
// This should only be called from the generated bindings. All other code
// should use IsBodyUsed() instead.
- bool bodyUsed(ExceptionState& exception_state) {
- return IsBodyUsed(exception_state) == BodyUsed::kUsed;
- }
+ bool bodyUsed() const { return IsBodyUsed(); }
- // Returns kUsed, kUnused or kBroken. kBroken implies there is an exception
- // pending and the caller should return to JavaScript immediately.
- virtual BodyUsed IsBodyUsed(ExceptionState&);
+ // True if the body has been read from.
+ virtual bool IsBodyUsed() const;
- // Returns kLocked, kUnlocked or kBroken. kBroken implies there is an
- // exception pending and the caller should return to JavaScript immediately.
- BodyLocked IsBodyLocked(ExceptionState&);
+ // True if the body is locked.
+ bool IsBodyLocked() const;
bool HasPendingActivity() const;
- protected:
- // A version of IsBodyUsed() which catches exceptions and returns
- // false. Should never be used outside DCHECK().
- virtual bool IsBodyUsedForDCheck(ExceptionState& exception_state);
-
private:
// TODO(e_hakkinen): Fix |MimeType()| to always contain parameters and
// remove |ContentType()|.
@@ -76,7 +64,7 @@ class CORE_EXPORT Body : public ExecutionContextClient {
// error conditions. This method wraps those up into one call which throws
// an exception if consumption cannot proceed. The caller must check
// |exception_state| on return.
- void RejectInvalidConsumption(ScriptState*, ExceptionState& exception_state);
+ void RejectInvalidConsumption(ExceptionState& exception_state) const;
DISALLOW_COPY_AND_ASSIGN(Body);
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.idl b/chromium/third_party/blink/renderer/core/fetch/body.idl
index 79a89529153..1f30a408bc8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/body.idl
@@ -7,7 +7,7 @@
[
ActiveScriptWrappable
] interface mixin Body {
- [RaisesException] readonly attribute boolean bodyUsed;
+ readonly attribute boolean bodyUsed;
[CallWith=ScriptState, NewObject, RaisesException] Promise<ArrayBuffer> arrayBuffer();
[CallWith=ScriptState, NewObject, RaisesException] Promise<Blob> blob();
[CallWith=ScriptState, NewObject, RaisesException] Promise<FormData> formData();
diff --git a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
index 815ad1d51fd..b292b445240 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/body.h"
#include "third_party/blink/renderer/core/fetch/bytes_consumer_tee.h"
+#include "third_party/blink/renderer/core/fetch/bytes_uploader.h"
#include "third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h"
@@ -84,7 +85,7 @@ class BodyStreamBuffer::LoaderClient final
void Abort() override { NOTREACHED(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(buffer_);
visitor->Trace(client_);
ExecutionContextLifecycleObserver::Trace(visitor);
@@ -169,13 +170,9 @@ BodyStreamBuffer::BodyStreamBuffer(ScriptState* script_state,
scoped_refptr<BlobDataHandle> BodyStreamBuffer::DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy policy,
ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
- const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
- if (exception_state.HadException() || is_closed.value())
- return nullptr;
- const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
- if (exception_state.HadException() || is_errored.value())
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
+ if (IsStreamClosed() || IsStreamErrored())
return nullptr;
if (made_from_readable_stream_)
@@ -194,13 +191,9 @@ scoped_refptr<BlobDataHandle> BodyStreamBuffer::DrainAsBlobDataHandle(
scoped_refptr<EncodedFormData> BodyStreamBuffer::DrainAsFormData(
ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
- const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
- if (exception_state.HadException() || is_closed.value())
- return nullptr;
- const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
- if (exception_state.HadException() || is_errored.value())
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
+ if (IsStreamClosed() || IsStreamErrored())
return nullptr;
if (made_from_readable_stream_)
@@ -216,6 +209,22 @@ scoped_refptr<EncodedFormData> BodyStreamBuffer::DrainAsFormData(
return nullptr;
}
+void BodyStreamBuffer::DrainAsChunkedDataPipeGetter(
+ ScriptState* script_state,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_receiver,
+ ExceptionState& exception_state) {
+ DCHECK(!IsStreamLocked());
+ auto* consumer = MakeGarbageCollected<ReadableStreamBytesConsumer>(
+ script_state, stream_, exception_state);
+ if (exception_state.HadException())
+ return;
+ stream_uploader_ = MakeGarbageCollected<BytesUploader>(
+ consumer, std::move(pending_receiver),
+ ExecutionContext::From(script_state)
+ ->GetTaskRunner(TaskType::kNetworking));
+}
+
void BodyStreamBuffer::StartLoading(FetchDataLoader* loader,
FetchDataLoader::Client* client,
ExceptionState& exception_state) {
@@ -241,8 +250,8 @@ void BodyStreamBuffer::StartLoading(FetchDataLoader* loader,
void BodyStreamBuffer::Tee(BodyStreamBuffer** branch1,
BodyStreamBuffer** branch2,
ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
*branch1 = nullptr;
*branch2 = nullptr;
scoped_refptr<BlobDataHandle> side_data_blob = TakeSideDataBlob();
@@ -339,41 +348,24 @@ void BodyStreamBuffer::ContextDestroyed() {
UnderlyingSourceBase::ContextDestroyed();
}
-base::Optional<bool> BodyStreamBuffer::IsStreamReadable(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsReadable, exception_state);
-}
-
-base::Optional<bool> BodyStreamBuffer::IsStreamClosed(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsClosed, exception_state);
-}
-
-base::Optional<bool> BodyStreamBuffer::IsStreamErrored(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsErrored, exception_state);
+bool BodyStreamBuffer::IsStreamReadable() const {
+ return stream_->IsReadable();
}
-base::Optional<bool> BodyStreamBuffer::IsStreamLocked(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsLocked, exception_state);
+bool BodyStreamBuffer::IsStreamClosed() const {
+ return stream_->IsClosed();
}
-bool BodyStreamBuffer::IsStreamLockedForDCheck(
- ExceptionState& exception_state) {
- auto result = IsStreamLocked(exception_state);
- return !result || *result;
+bool BodyStreamBuffer::IsStreamErrored() const {
+ return stream_->IsErrored();
}
-base::Optional<bool> BodyStreamBuffer::IsStreamDisturbed(
- ExceptionState& exception_state) {
- return BooleanStreamOperation(&ReadableStream::IsDisturbed, exception_state);
+bool BodyStreamBuffer::IsStreamLocked() const {
+ return stream_->IsLocked();
}
-bool BodyStreamBuffer::IsStreamDisturbedForDCheck(
- ExceptionState& exception_state) {
- auto result = IsStreamDisturbed(exception_state);
- return !result || *result;
+bool BodyStreamBuffer::IsStreamDisturbed() const {
+ return stream_->IsDisturbed();
}
void BodyStreamBuffer::CloseAndLockAndDisturb(ExceptionState& exception_state) {
@@ -384,25 +376,11 @@ void BodyStreamBuffer::CloseAndLockAndDisturb(ExceptionState& exception_state) {
return;
}
- if (stream_->IsBroken()) {
- stream_broken_ = true;
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "Body stream has been lost and cannot be disturbed");
- return;
- }
-
- base::Optional<bool> is_readable = IsStreamReadable(exception_state);
- if (exception_state.HadException())
- return;
-
- DCHECK(is_readable.has_value());
- if (is_readable.value()) {
+ if (IsStreamReadable()) {
// Note that the stream cannot be "draining", because it doesn't have
// the internal buffer.
Close();
}
- DCHECK(!stream_broken_);
stream_->LockAndDisturb(script_state_, exception_state);
}
@@ -417,9 +395,10 @@ scoped_refptr<BlobDataHandle> BodyStreamBuffer::TakeSideDataBlob() {
return std::move(side_data_blob_);
}
-void BodyStreamBuffer::Trace(Visitor* visitor) {
+void BodyStreamBuffer::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(stream_);
+ visitor->Trace(stream_uploader_);
visitor->Trace(consumer_);
visitor->Trace(loader_);
visitor->Trace(signal_);
@@ -520,40 +499,30 @@ void BodyStreamBuffer::StopLoading() {
loader_ = nullptr;
}
-base::Optional<bool> BodyStreamBuffer::BooleanStreamOperation(
- base::Optional<bool> (ReadableStream::*predicate)(ScriptState*,
- ExceptionState&) const,
+BytesConsumer* BodyStreamBuffer::ReleaseHandle(
ExceptionState& exception_state) {
+ DCHECK(!IsStreamLocked());
+ DCHECK(!IsStreamDisturbed());
+
if (stream_broken_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"Body stream has suffered a fatal error and cannot be inspected");
- return base::nullopt;
- }
- ScriptState::Scope scope(script_state_);
- base::Optional<bool> result =
- (stream_->*predicate)(script_state_, exception_state);
- if (exception_state.HadException()) {
- stream_broken_ = true;
- return base::nullopt;
+ return nullptr;
}
- return result;
-}
-
-BytesConsumer* BodyStreamBuffer::ReleaseHandle(
- ExceptionState& exception_state) {
- DCHECK(!IsStreamLockedForDCheck(exception_state));
- DCHECK(!IsStreamDisturbedForDCheck(exception_state));
-
- side_data_blob_.reset();
- if (stream_broken_) {
+ if (!GetExecutionContext()) {
+ // Avoid crashing if ContextDestroyed() has been called.
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
- "Body stream has suffered a fatal error and cannot be inspected");
+ "Cannot release body in a window or worker than has been detached");
return nullptr;
}
+ // Do this after state checks to avoid side-effects when the method does
+ // nothing.
+ side_data_blob_.reset();
+
if (made_from_readable_stream_) {
ScriptState::Scope scope(script_state_);
auto* consumer = MakeGarbageCollected<ReadableStreamBytesConsumer>(
@@ -565,12 +534,8 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle(
return consumer;
}
// We need to call these before calling CloseAndLockAndDisturb.
- const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
- if (exception_state.HadException())
- return nullptr;
- const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
- if (exception_state.HadException())
- return nullptr;
+ const bool is_closed = IsStreamClosed();
+ const bool is_errored = IsStreamErrored();
BytesConsumer* consumer = consumer_.Release();
@@ -578,12 +543,12 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle(
if (exception_state.HadException())
return nullptr;
- if (is_closed.value()) {
+ if (is_closed) {
// Note that the stream cannot be "draining", because it doesn't have
// the internal buffer.
return BytesConsumer::CreateClosed();
}
- if (is_errored.value())
+ if (is_errored)
return BytesConsumer::CreateErrored(BytesConsumer::Error("error"));
DCHECK(consumer);
diff --git a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h
index bac00bcb6b1..38a45519c06 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h
@@ -6,8 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_H_
#include <memory>
-#include "base/optional.h"
#include "base/util/type_safety/pass_key.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -21,6 +22,7 @@
namespace blink {
+class BytesUploader;
class EncodedFormData;
class ExceptionState;
class ReadableStream;
@@ -62,6 +64,10 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
BytesConsumer::BlobSizePolicy,
ExceptionState&);
scoped_refptr<EncodedFormData> DrainAsFormData(ExceptionState&);
+ void DrainAsChunkedDataPipeGetter(
+ ScriptState*,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>,
+ ExceptionState&);
void StartLoading(FetchDataLoader*,
FetchDataLoader::Client* /* client */,
ExceptionState&);
@@ -77,13 +83,11 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
void OnStateChange() override;
String DebugName() const override { return "BodyStreamBuffer"; }
- base::Optional<bool> IsStreamReadable(ExceptionState&);
- base::Optional<bool> IsStreamClosed(ExceptionState&);
- base::Optional<bool> IsStreamErrored(ExceptionState&);
- base::Optional<bool> IsStreamLocked(ExceptionState&);
- bool IsStreamLockedForDCheck(ExceptionState&);
- base::Optional<bool> IsStreamDisturbed(ExceptionState&);
- bool IsStreamDisturbedForDCheck(ExceptionState&);
+ bool IsStreamReadable() const;
+ bool IsStreamClosed() const;
+ bool IsStreamErrored() const;
+ bool IsStreamLocked() const;
+ bool IsStreamDisturbed() const;
void CloseAndLockAndDisturb(ExceptionState&);
ScriptState* GetScriptState() { return script_state_; }
@@ -97,7 +101,9 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
return side_data_blob_;
}
- void Trace(Visitor*) override;
+ bool IsMadeFromReadableStream() const { return made_from_readable_stream_; }
+
+ void Trace(Visitor*) const override;
private:
class LoaderClient;
@@ -116,17 +122,9 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
void EndLoading();
void StopLoading();
- // Implementation of IsStream*() methods. Delegates to |predicate|, one of the
- // methods defined in ReadableStream. Sets |stream_broken_| and throws if
- // |predicate| throws. Throws an exception if called when |stream_broken_|
- // is already true.
- base::Optional<bool> BooleanStreamOperation(
- base::Optional<bool> (ReadableStream::*predicate)(ScriptState*,
- ExceptionState&) const,
- ExceptionState& exception_state);
-
Member<ScriptState> script_state_;
Member<ReadableStream> stream_;
+ Member<BytesUploader> stream_uploader_;
Member<BytesConsumer> consumer_;
// We need this member to keep it alive while loading.
Member<FetchDataLoader> loader_;
@@ -140,6 +138,8 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
bool stream_needs_more_ = false;
bool made_from_readable_stream_;
bool in_process_data_ = false;
+
+ // TODO(ricea): Remove remaining uses of |stream_broken_|.
bool stream_broken_ = false;
DISALLOW_COPY_AND_ASSIGN(BodyStreamBuffer);
diff --git a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
index 821593825d6..d198c1ca8e8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
@@ -133,8 +133,8 @@ TEST_F(BodyStreamBufferTest, Tee) {
BodyStreamBuffer* new2;
buffer->Tee(&new1, &new2, exception_state);
- EXPECT_TRUE(buffer->IsStreamLocked(exception_state).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(exception_state).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
@@ -199,18 +199,18 @@ TEST_F(BodyStreamBufferTest, TeeFromHandleMadeFromStream) {
BodyStreamBuffer* new2;
buffer->Tee(&new1, &new2, exception_state);
- EXPECT_TRUE(buffer->IsStreamLocked(exception_state).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
// Note that this behavior is slightly different from for the behavior of
// a BodyStreamBuffer made from a BytesConsumer. See the above test. In this
// test, the stream will get disturbed when the microtask is performed.
// TODO(yhirano): A uniformed behavior is preferred.
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
v8::MicrotasksScope::PerformCheckpoint(scope.GetScriptState()->GetIsolate());
- EXPECT_TRUE(buffer->IsStreamLocked(exception_state).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(exception_state).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
new1->StartLoading(FetchDataLoader::CreateLoaderAsString(
@@ -238,8 +238,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) {
blob_data_handle),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
scoped_refptr<BlobDataHandle> output_blob_data_handle =
@@ -247,8 +247,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) {
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
ASSERT_NO_EXCEPTION);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
EXPECT_EQ(blob_data_handle, output_blob_data_handle);
@@ -264,8 +264,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) {
BodyStreamBuffer::Create(scope.GetScriptState(), src,
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
@@ -273,8 +273,8 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) {
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
ASSERT_NO_EXCEPTION));
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
}
@@ -290,18 +290,18 @@ TEST_F(BodyStreamBufferTest,
MakeGarbageCollected<BodyStreamBuffer>(scope.GetScriptState(), stream);
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
EXPECT_FALSE(buffer->DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
exception_state));
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
}
TEST_F(BodyStreamBufferTest, DrainAsFormData) {
@@ -319,15 +319,15 @@ TEST_F(BodyStreamBufferTest, DrainAsFormData) {
input_form_data),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
scoped_refptr<EncodedFormData> output_form_data =
buffer->DrainAsFormData(ASSERT_NO_EXCEPTION);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
EXPECT_EQ(output_form_data->FlattenToString(),
@@ -344,15 +344,15 @@ TEST_F(BodyStreamBufferTest, DrainAsFormDataReturnsNull) {
BodyStreamBuffer::Create(scope.GetScriptState(), src,
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
EXPECT_FALSE(buffer->DrainAsFormData(ASSERT_NO_EXCEPTION));
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
}
@@ -367,16 +367,16 @@ TEST_F(BodyStreamBufferTest,
MakeGarbageCollected<BodyStreamBuffer>(scope.GetScriptState(), stream);
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
EXPECT_FALSE(buffer->DrainAsFormData(exception_state));
EXPECT_FALSE(buffer->HasPendingActivity());
- EXPECT_FALSE(buffer->IsStreamLocked(exception_state).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(exception_state).value_or(true));
- EXPECT_TRUE(buffer->IsStreamReadable(exception_state).value_or(false));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
+ EXPECT_TRUE(buffer->IsStreamReadable());
}
TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) {
@@ -405,16 +405,16 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) {
ASSERT_NO_EXCEPTION);
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_TRUE(buffer->HasPendingActivity());
checkpoint.Call(1);
test::RunPendingTasks();
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
ASSERT_TRUE(array_buffer);
EXPECT_EQ("hello", String(static_cast<const char*>(array_buffer->Data()),
@@ -447,16 +447,16 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsBlob) {
client, ASSERT_NO_EXCEPTION);
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_TRUE(buffer->HasPendingActivity());
checkpoint.Call(1);
test::RunPendingTasks();
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(5u, blob_data_handle->size());
}
@@ -486,16 +486,16 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsString) {
client, ASSERT_NO_EXCEPTION);
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_TRUE(buffer->HasPendingActivity());
checkpoint.Call(1);
test::RunPendingTasks();
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
}
@@ -514,10 +514,10 @@ TEST_F(BodyStreamBufferTest, LoadClosedHandle) {
scope.GetScriptState(), BytesConsumer::CreateClosed(),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_TRUE(buffer->IsStreamClosed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamClosed());
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
@@ -527,8 +527,8 @@ TEST_F(BodyStreamBufferTest, LoadClosedHandle) {
client, ASSERT_NO_EXCEPTION);
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
}
@@ -548,10 +548,10 @@ TEST_F(BodyStreamBufferTest, LoadErroredHandle) {
BytesConsumer::CreateErrored(BytesConsumer::Error()),
/* abort_signal = */ nullptr, side_data_blob);
- EXPECT_TRUE(buffer->IsStreamErrored(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamErrored());
- EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
- EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
+ EXPECT_FALSE(buffer->IsStreamLocked());
+ EXPECT_FALSE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
@@ -561,8 +561,8 @@ TEST_F(BodyStreamBufferTest, LoadErroredHandle) {
client, ASSERT_NO_EXCEPTION);
checkpoint.Call(2);
- EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
- EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
+ EXPECT_TRUE(buffer->IsStreamLocked());
+ EXPECT_TRUE(buffer->IsStreamDisturbed());
EXPECT_FALSE(buffer->HasPendingActivity());
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc
index 1492d51b897..37ded968847 100644
--- a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee.cc
@@ -113,7 +113,7 @@ class TeeHelper final : public GarbageCollected<TeeHelper>,
BytesConsumer* Destination1() const { return destination1_; }
BytesConsumer* Destination2() const { return destination2_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(src_);
visitor->Trace(destination1_);
visitor->Trace(destination2_);
@@ -138,7 +138,7 @@ class TeeHelper final : public GarbageCollected<TeeHelper>,
const char* data() const { return buffer_.data(); }
wtf_size_t size() const { return buffer_.size(); }
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
Vector<char> buffer_;
@@ -268,7 +268,7 @@ class TeeHelper final : public GarbageCollected<TeeHelper>,
bool IsCancelled() const { return is_cancelled_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(execution_context_);
visitor->Trace(tee_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h
index 41ade535ece..f3aae804144 100644
--- a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h
@@ -42,7 +42,7 @@ class BytesConsumerTestUtil {
USING_GARBAGE_COLLECTED_MIXIN(MockFetchDataLoaderClient);
public:
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
FetchDataLoader::Client::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc
new file mode 100644
index 00000000000..1cb306e41fc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.cc
@@ -0,0 +1,169 @@
+// 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/core/fetch/bytes_uploader.h"
+
+#include "base/numerics/checked_math.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/single_thread_task_runner.h"
+#include "net/base/net_errors.h"
+#include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"
+
+namespace blink {
+
+BytesUploader::BytesUploader(
+ BytesConsumer* consumer,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_receiver,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : consumer_(consumer),
+ receiver_(this, std::move(pending_receiver)),
+ upload_pipe_watcher_(FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::MANUAL,
+ std::move(task_runner)) {
+ DCHECK(consumer_);
+ DCHECK_EQ(consumer_->GetPublicState(),
+ BytesConsumer::PublicState::kReadableOrWaiting);
+}
+
+BytesUploader::~BytesUploader() = default;
+
+void BytesUploader::Trace(blink::Visitor* visitor) const {
+ visitor->Trace(consumer_);
+ BytesConsumer::Client::Trace(visitor);
+}
+
+void BytesUploader::GetSize(GetSizeCallback get_size_callback) {
+ DCHECK(!get_size_callback_);
+ get_size_callback_ = std::move(get_size_callback);
+}
+
+void BytesUploader::StartReading(
+ mojo::ScopedDataPipeProducerHandle upload_pipe) {
+ DVLOG(3) << this << " StartReading()";
+ DCHECK(get_size_callback_);
+ DCHECK(upload_pipe);
+ if (upload_pipe_) {
+ // Replay was asked by net/ service.
+ CloseOnError();
+ return;
+ }
+ upload_pipe_ = std::move(upload_pipe);
+ upload_pipe_watcher_.Watch(upload_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ WTF::BindRepeating(&BytesUploader::OnPipeWriteable,
+ WrapWeakPersistent(this)));
+ consumer_->SetClient(this);
+ if (consumer_->GetPublicState() ==
+ BytesConsumer::PublicState::kReadableOrWaiting) {
+ WriteDataOnPipe();
+ }
+}
+
+void BytesUploader::OnStateChange() {
+ DVLOG(3) << this << " OnStateChange(). consumer_->GetPublicState()="
+ << consumer_->GetPublicState();
+ DCHECK(get_size_callback_);
+ switch (consumer_->GetPublicState()) {
+ case BytesConsumer::PublicState::kReadableOrWaiting:
+ WriteDataOnPipe();
+ return;
+ case BytesConsumer::PublicState::kClosed:
+ Close();
+ return;
+ case BytesConsumer::PublicState::kErrored:
+ CloseOnError();
+ return;
+ }
+ NOTREACHED();
+}
+
+void BytesUploader::OnPipeWriteable(MojoResult unused) {
+ WriteDataOnPipe();
+}
+
+void BytesUploader::WriteDataOnPipe() {
+ DVLOG(3) << this << " WriteDataOnPipe(). consumer_->GetPublicState()="
+ << consumer_->GetPublicState();
+ DCHECK(upload_pipe_);
+ DCHECK(get_size_callback_);
+ if (!upload_pipe_.is_valid())
+ return;
+
+ while (true) {
+ const char* buffer;
+ size_t available;
+ auto consumer_result = consumer_->BeginRead(&buffer, &available);
+ DVLOG(3) << " consumer_->BeginRead()=" << consumer_result
+ << ", available=" << available;
+ switch (consumer_result) {
+ case BytesConsumer::Result::kError:
+ CloseOnError();
+ return;
+ case BytesConsumer::Result::kShouldWait:
+ return;
+ case BytesConsumer::Result::kDone:
+ Close();
+ return;
+ case BytesConsumer::Result::kOk:
+ break;
+ }
+ DCHECK_EQ(consumer_result, BytesConsumer::Result::kOk);
+ uint32_t written_bytes = base::saturated_cast<uint32_t>(available);
+ const MojoResult mojo_result = upload_pipe_->WriteData(
+ buffer, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
+ DVLOG(3) << " upload_pipe_->WriteData()=" << mojo_result
+ << ", mojo_written=" << written_bytes
+ << ", consumer_->EndRead()=" << consumer_result;
+ if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
+ // Wait for the pipe to have more capacity available
+ consumer_result = consumer_->EndRead(0);
+ upload_pipe_watcher_.ArmOrNotify();
+ return;
+ }
+ if (mojo_result != MOJO_RESULT_OK) {
+ CloseOnError();
+ return;
+ }
+
+ consumer_result = consumer_->EndRead(written_bytes);
+ if (!base::CheckAdd(total_size_, written_bytes)
+ .AssignIfValid(&total_size_)) {
+ CloseOnError();
+ return;
+ }
+
+ switch (consumer_result) {
+ case BytesConsumer::Result::kError:
+ CloseOnError();
+ return;
+ case BytesConsumer::Result::kShouldWait:
+ NOTREACHED();
+ return;
+ case BytesConsumer::Result::kDone:
+ Close();
+ return;
+ case BytesConsumer::Result::kOk:
+ break;
+ }
+ }
+}
+
+void BytesUploader::Close() {
+ DVLOG(3) << this << " Close(). total_size=" << total_size_;
+ DCHECK(get_size_callback_);
+ std::move(get_size_callback_).Run(net::OK, total_size_);
+}
+
+void BytesUploader::CloseOnError() {
+ DVLOG(3) << this << " CloseOnError(). total_size=" << total_size_;
+ DCHECK(consumer_);
+ consumer_->Cancel();
+ DCHECK(get_size_callback_);
+ std::move(get_size_callback_).Run(net::ERR_FAILED, total_size_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h
new file mode 100644
index 00000000000..304814b39b9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BYTES_UPLOADER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BYTES_UPLOADER_H_
+
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace blink {
+
+class CORE_EXPORT BytesUploader
+ : public GarbageCollected<BytesUploader>,
+ public BytesConsumer::Client,
+ public network::mojom::blink::ChunkedDataPipeGetter {
+ USING_GARBAGE_COLLECTED_MIXIN(BytesUploader);
+
+ public:
+ BytesUploader(
+ BytesConsumer* consumer,
+ mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_receiver,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ ~BytesUploader() override;
+ BytesUploader(const BytesUploader&) = delete;
+ BytesUploader& operator=(const BytesUploader&) = delete;
+
+ void Trace(blink::Visitor*) const override;
+
+ private:
+ // BytesConsumer::Client implementation
+ void OnStateChange() override;
+ String DebugName() const override { return "BytesUploader"; }
+
+ // mojom::ChunkedDataPipeGetter implementation:
+ void GetSize(GetSizeCallback get_size_callback) override;
+ void StartReading(mojo::ScopedDataPipeProducerHandle upload_pipe) override;
+
+ void OnPipeWriteable(MojoResult unused);
+ void WriteDataOnPipe();
+
+ void Close();
+ // TODO(yoichio): Add a string parameter and show it on console.
+ void CloseOnError();
+
+ Member<BytesConsumer> consumer_;
+ mojo::Receiver<network::mojom::blink::ChunkedDataPipeGetter> receiver_;
+ mojo::ScopedDataPipeProducerHandle upload_pipe_;
+ mojo::SimpleWatcher upload_pipe_watcher_;
+ GetSizeCallback get_size_callback_;
+ uint64_t total_size_ = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BYTES_UPLOADER_H_
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc
new file mode 100644
index 00000000000..61eed927154
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_uploader_test.cc
@@ -0,0 +1,238 @@
+// 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/core/fetch/bytes_uploader.h"
+
+#include "base/test/mock_callback.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "net/base/net_errors.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+using network::mojom::blink::ChunkedDataPipeGetter;
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+namespace blink {
+
+typedef testing::StrictMock<testing::MockFunction<void(int)>> Checkpoint;
+
+class MockBytesConsumer : public BytesConsumer {
+ public:
+ MockBytesConsumer() = default;
+ ~MockBytesConsumer() override = default;
+
+ MOCK_METHOD2(BeginRead, Result(const char**, size_t*));
+ MOCK_METHOD1(EndRead, Result(size_t));
+ MOCK_METHOD1(SetClient, void(Client*));
+ MOCK_METHOD0(ClearClient, void());
+ MOCK_METHOD0(Cancel, void());
+ MOCK_CONST_METHOD0(GetPublicState, PublicState());
+ MOCK_CONST_METHOD0(GetError, Error());
+ MOCK_CONST_METHOD0(DebugName, String());
+};
+
+class BytesUploaderTest : public ::testing::Test {
+ public:
+ void InitializeBytesUploader(uint32_t capacity = 100u) {
+ mock_bytes_consumer_ = MakeGarbageCollected<MockBytesConsumer>();
+ EXPECT_CALL(*mock_bytes_consumer_, GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+
+ bytes_uploader_ = MakeGarbageCollected<BytesUploader>(
+ mock_bytes_consumer_, remote_.BindNewPipeAndPassReceiver(),
+ Thread::Current()->GetTaskRunner());
+
+ const MojoCreateDataPipeOptions data_pipe_options{
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1,
+ capacity};
+ ASSERT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(&data_pipe_options, &writable_, &readable_));
+ }
+
+ MockBytesConsumer& Mock() const { return *mock_bytes_consumer_; }
+ mojo::ScopedDataPipeProducerHandle& Writable() { return writable_; }
+ mojo::ScopedDataPipeConsumerHandle& Readable() { return readable_; }
+ mojo::Remote<ChunkedDataPipeGetter>& Remote() { return remote_; }
+
+ private:
+ Persistent<BytesUploader> bytes_uploader_;
+ Persistent<MockBytesConsumer> mock_bytes_consumer_;
+
+ mojo::ScopedDataPipeProducerHandle writable_;
+ mojo::ScopedDataPipeConsumerHandle readable_;
+ mojo::Remote<ChunkedDataPipeGetter> remote_;
+};
+
+TEST_F(BytesUploaderTest, Create) {
+ MockBytesConsumer* mock_bytes_consumer =
+ MakeGarbageCollected<MockBytesConsumer>();
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(*mock_bytes_consumer, GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ }
+
+ checkpoint.Call(1);
+ mojo::PendingRemote<ChunkedDataPipeGetter> pending_remote;
+ BytesUploader* bytes_uploader_ = MakeGarbageCollected<BytesUploader>(
+ mock_bytes_consumer, pending_remote.InitWithNewPipeAndPassReceiver(),
+ Thread::Current()->GetTaskRunner());
+ ASSERT_TRUE(bytes_uploader_);
+}
+
+// TODO(yoichio): Needs BytesConsumer state tests.
+
+TEST_F(BytesUploaderTest, ReadEmpty) {
+ InitializeBytesUploader();
+
+ base::MockCallback<ChunkedDataPipeGetter::GetSizeCallback> get_size_callback;
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(Mock(), SetClient(_));
+ EXPECT_CALL(Mock(), GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Return(BytesConsumer::Result::kDone));
+ EXPECT_CALL(get_size_callback, Run(net::OK, 0u));
+
+ EXPECT_CALL(checkpoint, Call(3));
+ }
+
+ checkpoint.Call(1);
+ Remote()->GetSize(get_size_callback.Get());
+ Remote()->StartReading(std::move(Writable()));
+
+ checkpoint.Call(2);
+ test::RunPendingTasks();
+
+ checkpoint.Call(3);
+ char buffer[20] = {};
+ uint32_t num_bytes = sizeof(buffer);
+ MojoResult rv =
+ Readable()->ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+ EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, rv);
+}
+
+TEST_F(BytesUploaderTest, ReadSmall) {
+ InitializeBytesUploader();
+
+ base::MockCallback<ChunkedDataPipeGetter::GetSizeCallback> get_size_callback;
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(Mock(), SetClient(_));
+ EXPECT_CALL(Mock(), GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 6;
+ *buffer = "foobar";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(6u))
+ .WillOnce(Return(BytesConsumer::Result::kDone));
+ EXPECT_CALL(get_size_callback, Run(net::OK, 6u));
+
+ EXPECT_CALL(checkpoint, Call(3));
+ }
+
+ checkpoint.Call(1);
+ Remote()->GetSize(get_size_callback.Get());
+ Remote()->StartReading(std::move(Writable()));
+
+ checkpoint.Call(2);
+ test::RunPendingTasks();
+
+ checkpoint.Call(3);
+ char buffer[20] = {};
+ uint32_t num_bytes = sizeof(buffer);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ Readable()->ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE));
+ EXPECT_EQ(6u, num_bytes);
+ EXPECT_STREQ("foobar", buffer);
+}
+
+TEST_F(BytesUploaderTest, ReadOverPipeCapacity) {
+ InitializeBytesUploader(10u);
+
+ base::MockCallback<ChunkedDataPipeGetter::GetSizeCallback> get_size_callback;
+ Checkpoint checkpoint;
+ {
+ InSequence s;
+
+ EXPECT_CALL(checkpoint, Call(1));
+ EXPECT_CALL(checkpoint, Call(2));
+ EXPECT_CALL(Mock(), SetClient(_));
+ EXPECT_CALL(Mock(), GetPublicState())
+ .WillRepeatedly(Return(BytesConsumer::PublicState::kReadableOrWaiting));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 12;
+ *buffer = "foobarFOOBAR";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(10u))
+ .WillOnce(Return(BytesConsumer::Result::kOk));
+
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 2;
+ *buffer = "AR";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(0u))
+ .WillOnce(Return(BytesConsumer::Result::kOk));
+
+ EXPECT_CALL(checkpoint, Call(3));
+ EXPECT_CALL(checkpoint, Call(4));
+ EXPECT_CALL(Mock(), BeginRead(_, _))
+ .WillOnce(Invoke([](const char** buffer, size_t* size) {
+ *size = 2;
+ *buffer = "AR";
+ return BytesConsumer::Result::kOk;
+ }));
+ EXPECT_CALL(Mock(), EndRead(2u))
+ .WillOnce(Return(BytesConsumer::Result::kDone));
+ EXPECT_CALL(get_size_callback, Run(net::OK, 12u));
+ }
+
+ checkpoint.Call(1);
+ Remote()->GetSize(get_size_callback.Get());
+ Remote()->StartReading(std::move(Writable()));
+
+ checkpoint.Call(2);
+ test::RunPendingTasks();
+
+ checkpoint.Call(3);
+ char buffer[20] = {};
+ uint32_t num_bytes = sizeof(buffer);
+ EXPECT_EQ(MOJO_RESULT_OK,
+ Readable()->ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE));
+ EXPECT_EQ(10u, num_bytes);
+ EXPECT_STREQ("foobarFOOB", buffer);
+
+ checkpoint.Call(4);
+ test::RunPendingTasks();
+ char buffer2[20] = {};
+ num_bytes = sizeof(buffer2);
+ EXPECT_EQ(MOJO_RESULT_OK, Readable()->ReadData(buffer2, &num_bytes,
+ MOJO_READ_DATA_FLAG_NONE));
+ EXPECT_EQ(2u, num_bytes);
+ EXPECT_STREQ("AR", buffer2);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
index 50cfd7c5141..99cbd31de9a 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
@@ -104,7 +104,7 @@ class FetchDataLoaderAsBlobHandle final : public FetchDataLoader,
String DebugName() const override { return "FetchDataLoaderAsBlobHandle"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -182,7 +182,7 @@ class FetchDataLoaderAsArrayBuffer final : public FetchDataLoader,
String DebugName() const override { return "FetchDataLoaderAsArrayBuffer"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -266,7 +266,7 @@ class FetchDataLoaderAsFailure final : public FetchDataLoader,
void Cancel() override { consumer_->Cancel(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -352,7 +352,7 @@ class FetchDataLoaderAsFormData final : public FetchDataLoader,
multipart_parser_->Cancel();
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
visitor->Trace(form_data_);
@@ -507,7 +507,7 @@ class FetchDataLoaderAsString final : public FetchDataLoader,
void Cancel() override { consumer_->Cancel(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -644,7 +644,7 @@ class FetchDataLoaderAsDataPipe final : public FetchDataLoader,
void Cancel() override { StopInternal(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h
index 070f97a1d98..75a9bc80693 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.h
@@ -66,7 +66,7 @@ class CORE_EXPORT FetchDataLoader : public GarbageCollected<FetchDataLoader> {
// This function is called when an abort has been signalled.
virtual void Abort() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
static FetchDataLoader* CreateLoaderAsBlobHandle(const String& mime_type);
@@ -91,7 +91,7 @@ class CORE_EXPORT FetchDataLoader : public GarbageCollected<FetchDataLoader> {
virtual void Cancel() = 0;
- virtual void Trace(Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
index 69aa8773da3..acb6e795a05 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
@@ -94,7 +94,7 @@ class FetchDataLoaderTest : public testing::Test {
BytesConsumer* GetDestination() { return destination_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(destination_);
visitor->Trace(completion_notifier_);
FetchDataLoader::Client::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h b/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h
index d1a561786f6..3a8199c994f 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_header_list.h
@@ -51,7 +51,7 @@ class CORE_EXPORT FetchHeaderList final
static bool IsValidHeaderName(const String&);
static bool IsValidHeaderValue(const String&);
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) const {}
private:
// While using STL data structures in Blink is not very common or
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
index 7bae19a506f..e9b0475fe6a 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -102,7 +102,7 @@ class FetchManager::Loader final
bool is_isolated_world,
AbortSignal*);
~Loader() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
// ThreadableLoaderClient implementation.
bool WillFollowRedirect(const KURL&, const ResourceResponse&) override;
@@ -203,7 +203,7 @@ class FetchManager::Loader final
bool IsFinished() const { return finished_; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(body_);
visitor->Trace(updater_);
visitor->Trace(response_);
@@ -274,7 +274,7 @@ FetchManager::Loader::~Loader() {
DCHECK(!threadable_loader_);
}
-void FetchManager::Loader::Trace(Visitor* visitor) {
+void FetchManager::Loader::Trace(Visitor* visitor) const {
visitor->Trace(fetch_manager_);
visitor->Trace(resolver_);
visitor->Trace(fetch_request_data_);
@@ -407,6 +407,20 @@ void FetchManager::Loader::DidReceiveResponse(
}
}
+ // TODO(crbug.com/1072350): Remove this once enough data is collected.
+ if (fetch_request_data_->Method() != http_names::kGET &&
+ fetch_request_data_->Method() != http_names::kHEAD &&
+ fetch_request_data_->Mode() == network::mojom::RequestMode::kNoCors &&
+ tainting == FetchRequestData::kOpaqueTainting) {
+ UseCounter::Count(execution_context_,
+ WebFeature::kFetchAPINonGetOrHeadOpaqueResponse);
+ if (url_list_.size() > 1) {
+ UseCounter::Count(
+ execution_context_,
+ WebFeature::kFetchAPINonGetOrHeadOpaqueResponseWithRedirect);
+ }
+ }
+
place_holder_body_ = MakeGarbageCollected<PlaceHolderBytesConsumer>();
FetchResponseData* response_data = FetchResponseData::CreateWithBuffer(
BodyStreamBuffer::Create(script_state, place_holder_body_, signal_));
@@ -535,7 +549,9 @@ void FetchManager::Loader::Start(ExceptionState& exception_state) {
// "- should fetching |request| be blocked as content security returns
// blocked"
if (!execution_context_->GetContentSecurityPolicyForWorld()
- ->AllowConnectToSource(fetch_request_data_->Url())) {
+ ->AllowConnectToSource(fetch_request_data_->Url(),
+ fetch_request_data_->Url(),
+ RedirectStatus::kNoRedirect)) {
// "A network error."
PerformNetworkError(
"Refused to connect to '" + fetch_request_data_->Url().ElidedString() +
@@ -713,10 +729,29 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
if (fetch_request_data_->Method() != http_names::kGET &&
fetch_request_data_->Method() != http_names::kHEAD) {
if (fetch_request_data_->Buffer()) {
- request.SetHttpBody(
- fetch_request_data_->Buffer()->DrainAsFormData(exception_state));
+ scoped_refptr<EncodedFormData> form_data =
+ fetch_request_data_->Buffer()->DrainAsFormData(exception_state);
+
if (exception_state.HadException())
return;
+ if (form_data) {
+ request.SetHttpBody(form_data);
+ } else if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() &&
+ RuntimeEnabledFeatures::FetchUploadStreamingEnabled(
+ execution_context_)) {
+ UseCounter::Count(execution_context_,
+ WebFeature::kFetchUploadStreaming);
+ mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
+ pending_remote;
+ fetch_request_data_->Buffer()->DrainAsChunkedDataPipeGetter(
+ resolver_->GetScriptState(),
+ pending_remote.InitWithNewPipeAndPassReceiver(), exception_state);
+ if (exception_state.HadException())
+ return;
+ request.MutableBody().SetStreamBody(std::move(pending_remote));
+ request.SetAllowHTTP1ForStreamingUpload(
+ fetch_request_data_->AllowHTTP1ForStreamingUpload());
+ }
}
}
request.SetCacheMode(fetch_request_data_->CacheMode());
@@ -878,7 +913,7 @@ void FetchManager::OnLoaderFinished(Loader* loader) {
loader->Dispose();
}
-void FetchManager::Trace(Visitor* visitor) {
+void FetchManager::Trace(Visitor* visitor) const {
visitor->Trace(loaders_);
ExecutionContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
index 6b5c87c25ff..e97080faf3e 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
@@ -32,7 +32,7 @@ class CORE_EXPORT FetchManager final
ExceptionState&);
void ContextDestroyed() override;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class Loader;
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc
index 2bc52ecc3a0..ea2c33a39eb 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"
+#include "third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
@@ -66,17 +67,31 @@ bool IsExcludedHeaderForServiceWorkerFetchEvent(const String& header_name) {
return false;
}
+void SignalSize(
+ std::unique_ptr<mojo::Remote<network::mojom::blink::ChunkedDataPipeGetter>>,
+ Persistent<DataPipeBytesConsumer::CompletionNotifier> notifier,
+ int32_t status,
+ uint64_t size) {
+ if (status != 0) {
+ // error case
+ notifier->SignalError(BytesConsumer::Error());
+ return;
+ }
+ notifier->SignalSize(size);
+}
+
} // namespace
FetchRequestData* FetchRequestData::Create(
ScriptState* script_state,
- const mojom::blink::FetchAPIRequest& fetch_api_request,
+ mojom::blink::FetchAPIRequestPtr fetch_api_request,
ForServiceWorkerFetchEvent for_service_worker_fetch_event) {
+ DCHECK(fetch_api_request);
FetchRequestData* request = MakeGarbageCollected<FetchRequestData>(
script_state ? ExecutionContext::From(script_state) : nullptr);
- request->url_ = fetch_api_request.url;
- request->method_ = AtomicString(fetch_api_request.method);
- for (const auto& pair : fetch_api_request.headers) {
+ request->url_ = fetch_api_request->url;
+ request->method_ = AtomicString(fetch_api_request->method);
+ for (const auto& pair : fetch_api_request->headers) {
// TODO(leonhsl): Check sources of |fetch_api_request.headers| to make clear
// whether we really need this filter.
if (EqualIgnoringASCIICase(pair.key, "referer"))
@@ -88,19 +103,56 @@ FetchRequestData* FetchRequestData::Create(
request->header_list_->Append(pair.key, pair.value);
}
- if (fetch_api_request.blob) {
- DCHECK(!fetch_api_request.body);
+ if (fetch_api_request->blob) {
+ DCHECK(fetch_api_request->body.IsEmpty());
request->SetBuffer(BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<BlobBytesConsumer>(
- ExecutionContext::From(script_state), fetch_api_request.blob),
- nullptr /* AbortSignal */));
- } else if (fetch_api_request.body) {
- request->SetBuffer(BodyStreamBuffer::Create(
- script_state,
- MakeGarbageCollected<FormDataBytesConsumer>(
- ExecutionContext::From(script_state), fetch_api_request.body),
+ ExecutionContext::From(script_state), fetch_api_request->blob),
nullptr /* AbortSignal */));
+ } else if (fetch_api_request->body.FormBody()) {
+ request->SetBuffer(
+ BodyStreamBuffer::Create(script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(
+ ExecutionContext::From(script_state),
+ fetch_api_request->body.FormBody()),
+ nullptr /* AbortSignal */));
+ } else if (fetch_api_request->body.StreamBody()) {
+ mojo::ScopedDataPipeConsumerHandle readable;
+ mojo::ScopedDataPipeProducerHandle writable;
+ MojoCreateDataPipeOptions options{sizeof(MojoCreateDataPipeOptions),
+ MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 0};
+ const MojoResult result =
+ mojo::CreateDataPipe(&options, &writable, &readable);
+ if (result == MOJO_RESULT_OK) {
+ DataPipeBytesConsumer::CompletionNotifier* completion_notifier = nullptr;
+ // Explicitly creating a ReadableStream here in order to remember
+ // that the request is created from a ReadableStream.
+ auto* stream = BodyStreamBuffer::Create(
+ script_state,
+ MakeGarbageCollected<DataPipeBytesConsumer>(
+ ExecutionContext::From(script_state)
+ ->GetTaskRunner(TaskType::kNetworking),
+ std::move(readable), &completion_notifier),
+ /*AbortSignal=*/nullptr)
+ ->Stream();
+ request->SetBuffer(
+ MakeGarbageCollected<BodyStreamBuffer>(script_state, stream,
+ /*AbortSignal=*/nullptr));
+
+ auto body_remote = std::make_unique<
+ mojo::Remote<network::mojom::blink::ChunkedDataPipeGetter>>(
+ fetch_api_request->body.TakeStreamBody());
+ auto* body_remote_raw = body_remote.get();
+ (*body_remote_raw)
+ ->GetSize(WTF::Bind(SignalSize, std::move(body_remote),
+ WrapPersistent(completion_notifier)));
+ (*body_remote_raw)->StartReading(std::move(writable));
+ } else {
+ request->SetBuffer(BodyStreamBuffer::Create(
+ script_state, BytesConsumer::CreateErrored(BytesConsumer::Error()),
+ nullptr /* AbortSignal */));
+ }
}
// Context is always set to FETCH later, so we don't copy it
@@ -108,25 +160,27 @@ FetchRequestData* FetchRequestData::Create(
// TODO(crbug.com/1045925): Remove this comment too when
// we deprecate SetContext.
- request->SetDestination(fetch_api_request.destination);
+ request->SetDestination(fetch_api_request->destination);
request->SetReferrerString(AtomicString(Referrer::NoReferrer()));
- if (fetch_api_request.referrer) {
- if (!fetch_api_request.referrer->url.IsEmpty())
- request->SetReferrerString(AtomicString(fetch_api_request.referrer->url));
- request->SetReferrerPolicy(fetch_api_request.referrer->policy);
+ if (fetch_api_request->referrer) {
+ if (!fetch_api_request->referrer->url.IsEmpty()) {
+ request->SetReferrerString(
+ AtomicString(fetch_api_request->referrer->url));
+ }
+ request->SetReferrerPolicy(fetch_api_request->referrer->policy);
}
- request->SetMode(fetch_api_request.mode);
- request->SetCredentials(fetch_api_request.credentials_mode);
- request->SetCacheMode(fetch_api_request.cache_mode);
- request->SetRedirect(fetch_api_request.redirect_mode);
+ request->SetMode(fetch_api_request->mode);
+ request->SetCredentials(fetch_api_request->credentials_mode);
+ request->SetCacheMode(fetch_api_request->cache_mode);
+ request->SetRedirect(fetch_api_request->redirect_mode);
request->SetMimeType(request->header_list_->ExtractMIMEType());
- request->SetIntegrity(fetch_api_request.integrity);
- request->SetKeepalive(fetch_api_request.keepalive);
- request->SetIsHistoryNavigation(fetch_api_request.is_history_navigation);
- request->SetPriority(
- ConvertRequestPriorityToResourceLoadPriority(fetch_api_request.priority));
- if (fetch_api_request.fetch_window_id)
- request->SetWindowId(fetch_api_request.fetch_window_id.value());
+ request->SetIntegrity(fetch_api_request->integrity);
+ request->SetKeepalive(fetch_api_request->keepalive);
+ request->SetIsHistoryNavigation(fetch_api_request->is_history_navigation);
+ request->SetPriority(ConvertRequestPriorityToResourceLoadPriority(
+ fetch_api_request->priority));
+ if (fetch_api_request->fetch_window_id)
+ request->SetWindowId(fetch_api_request->fetch_window_id.value());
return request;
}
@@ -154,6 +208,8 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
request->is_history_navigation_ = is_history_navigation_;
request->window_id_ = window_id_;
request->trust_token_params_ = trust_token_params_;
+ request->allow_http1_for_streaming_upload_ =
+ allow_http1_for_streaming_upload_;
return request;
}
@@ -213,7 +269,7 @@ FetchRequestData::FetchRequestData(ExecutionContext* execution_context)
url_loader_factory_(execution_context),
execution_context_(execution_context) {}
-void FetchRequestData::Trace(Visitor* visitor) {
+void FetchRequestData::Trace(Visitor* visitor) const {
visitor->Trace(buffer_);
visitor->Trace(header_list_);
visitor->Trace(url_loader_factory_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h
index cf2e86c21b8..2bf540d0ccc 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -40,7 +40,7 @@ class CORE_EXPORT FetchRequestData final
enum class ForServiceWorkerFetchEvent { kFalse, kTrue };
static FetchRequestData* Create(ScriptState*,
- const mojom::blink::FetchAPIRequest&,
+ mojom::blink::FetchAPIRequestPtr,
ForServiceWorkerFetchEvent);
FetchRequestData* Clone(ScriptState*, ExceptionState&);
FetchRequestData* Pass(ScriptState*, ExceptionState&);
@@ -138,7 +138,14 @@ class CORE_EXPORT FetchRequestData final
trust_token_params_ = std::move(trust_token_params);
}
- void Trace(Visitor*);
+ void SetAllowHTTP1ForStreamingUpload(bool allow) {
+ allow_http1_for_streaming_upload_ = allow;
+ }
+ bool AllowHTTP1ForStreamingUpload() const {
+ return allow_http1_for_streaming_upload_;
+ }
+
+ void Trace(Visitor*) const;
private:
FetchRequestData* CloneExceptBody();
@@ -183,6 +190,7 @@ class CORE_EXPORT FetchRequestData final
url_loader_factory_;
base::UnguessableToken window_id_;
Member<ExecutionContext> execution_context_;
+ bool allow_http1_for_streaming_upload_ = false;
DISALLOW_COPY_AND_ASSIGN(FetchRequestData);
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc
index 57ab1b71c1b..78efa87e618 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_request_data_test.cc
@@ -40,7 +40,7 @@ class FetchRequestDataTestingPlatformSupport : public TestingPlatformSupport {
TEST(FetchRequestDataTest, For_ServiceWorkerFetchEvent_Headers) {
{
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kTrue);
EXPECT_EQ(2U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
@@ -54,7 +54,7 @@ TEST(FetchRequestDataTest, For_ServiceWorkerFetchEvent_Headers) {
platform;
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kTrue);
EXPECT_EQ(1U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
@@ -67,7 +67,7 @@ TEST(FetchRequestDataTest, For_ServiceWorkerFetchEvent_Headers) {
TEST(FetchRequestDataTest, Not_For_ServiceWorkerFetchEvent_Headers) {
{
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kFalse);
EXPECT_EQ(4U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
@@ -81,7 +81,7 @@ TEST(FetchRequestDataTest, Not_For_ServiceWorkerFetchEvent_Headers) {
platform;
FetchRequestData* request_data = FetchRequestData::Create(
- nullptr /* script_state */, *PrepareFetchAPIRequest(),
+ nullptr /* script_state */, PrepareFetchAPIRequest(),
FetchRequestData::ForServiceWorkerFetchEvent::kFalse);
EXPECT_EQ(4U, request_data->HeaderList()->size());
EXPECT_TRUE(request_data->HeaderList()->Has("x-hi-hi"));
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc
index 7c96506830c..c595b241206 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc
@@ -194,6 +194,10 @@ FetchResponseData* FetchResponseData::Clone(ScriptState* script_state,
new_response->response_time_ = response_time_;
new_response->cache_storage_cache_name_ = cache_storage_cache_name_;
new_response->cors_exposed_header_names_ = cors_exposed_header_names_;
+ new_response->connection_info_ = connection_info_;
+ new_response->alpn_negotiated_protocol_ = alpn_negotiated_protocol_;
+ new_response->loaded_with_credentials_ = loaded_with_credentials_;
+ new_response->was_fetched_via_spdy_ = was_fetched_via_spdy_;
switch (type_) {
case Type::kBasic:
@@ -257,11 +261,15 @@ mojom::blink::FetchAPIResponsePtr FetchResponseData::PopulateFetchAPIResponse(
response->status_text = status_message_;
response->response_type = type_;
response->response_source = response_source_;
+ response->mime_type = mime_type_;
response->response_time = response_time_;
response->cache_storage_cache_name = cache_storage_cache_name_;
response->cors_exposed_header_names =
HeaderSetToVector(cors_exposed_header_names_);
+ response->connection_info = connection_info_;
+ response->alpn_negotiated_protocol = alpn_negotiated_protocol_;
response->loaded_with_credentials = loaded_with_credentials_;
+ response->was_fetched_via_spdy = was_fetched_via_spdy_;
for (const auto& header : HeaderList()->List())
response->headers.insert(header.first, header.second);
response->parsed_headers = ParseHeaders(
@@ -308,6 +316,16 @@ void FetchResponseData::InitFromResourceResponse(
SetResponseSource(network::mojom::FetchResponseSource::kNetwork);
}
+ SetConnectionInfo(response.ConnectionInfo());
+
+ // Some non-http responses, like data: url responses, will have a null
+ // |alpn_negotiated_protocol|. In these cases we leave the default
+ // value of "unknown".
+ if (!response.AlpnNegotiatedProtocol().IsNull())
+ SetAlpnNegotiatedProtocol(response.AlpnNegotiatedProtocol());
+
+ SetWasFetchedViaSpdy(response.WasFetchedViaSPDY());
+
// TODO(wanderview): Remove |tainting| and use |response.GetType()|
// instead once the OOR-CORS disabled path is removed.
SetLoadedWithCredentials(
@@ -326,7 +344,10 @@ FetchResponseData::FetchResponseData(Type type,
status_message_(status_message),
header_list_(MakeGarbageCollected<FetchHeaderList>()),
response_time_(base::Time::Now()),
- loaded_with_credentials_(false) {}
+ connection_info_(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN),
+ alpn_negotiated_protocol_("unknown"),
+ loaded_with_credentials_(false),
+ was_fetched_via_spdy_(false) {}
void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) {
if (type_ == Type::kBasic || type_ == Type::kCors) {
@@ -339,7 +360,7 @@ void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) {
}
}
-void FetchResponseData::Trace(Visitor* visitor) {
+void FetchResponseData::Trace(Visitor* visitor) const {
visitor->Trace(header_list_);
visitor->Trace(internal_response_);
visitor->Trace(buffer_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h
index 1eb7454afb0..0c4bfcb335e 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "net/http/http_response_info.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink-forward.h"
@@ -103,10 +104,19 @@ class CORE_EXPORT FetchResponseData final
void SetCorsExposedHeaderNames(const HTTPHeaderSet& header_names) {
cors_exposed_header_names_ = header_names;
}
- bool LoadedWithCredentials() const { return loaded_with_credentials_; }
+ void SetConnectionInfo(
+ net::HttpResponseInfo::ConnectionInfo connection_info) {
+ connection_info_ = connection_info;
+ }
+ void SetAlpnNegotiatedProtocol(AtomicString alpn_negotiated_protocol) {
+ alpn_negotiated_protocol_ = alpn_negotiated_protocol;
+ }
void SetLoadedWithCredentials(bool loaded_with_credentials) {
loaded_with_credentials_ = loaded_with_credentials;
}
+ void SetWasFetchedViaSpdy(bool was_fetched_via_spdy) {
+ was_fetched_via_spdy_ = was_fetched_via_spdy;
+ }
// If the type is Default, replaces |buffer_|.
// If the type is Basic or CORS, replaces |buffer_| and
@@ -125,7 +135,7 @@ class CORE_EXPORT FetchResponseData final
FetchRequestData::Tainting tainting,
const ResourceResponse& response);
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
network::mojom::FetchResponseType type_;
@@ -141,7 +151,10 @@ class CORE_EXPORT FetchResponseData final
base::Time response_time_;
String cache_storage_cache_name_;
HTTPHeaderSet cors_exposed_header_names_;
+ net::HttpResponseInfo::ConnectionInfo connection_info_;
+ AtomicString alpn_negotiated_protocol_;
bool loaded_with_credentials_;
+ bool was_fetched_via_spdy_;
DISALLOW_COPY_AND_ASSIGN(FetchResponseData);
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc
index d7f8d314135..ac21aeea0c9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc
@@ -267,8 +267,6 @@ TEST_F(FetchResponseDataTest, DefaultResponseTime) {
TEST_F(FetchResponseDataTest, ContentSecurityPolicy) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(
- network::features::kOutOfBlinkFrameAncestors);
FetchResponseData* internal_response = CreateInternalResponse();
internal_response->HeaderList()->Append("content-security-policy",
"frame-ancestors 'none'");
diff --git a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc
index 80ce8b92387..71d540e5326 100644
--- a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc
@@ -313,7 +313,7 @@ class DataPipeAndDataBytesConsumer final : public BytesConsumer {
String DebugName() const override { return "DataPipeAndDataBytesConsumer"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(execution_context_);
visitor->Trace(client_);
visitor->Trace(simple_consumer_);
@@ -479,7 +479,7 @@ class ComplexFormDataBytesConsumer final : public BytesConsumer {
Error GetError() const override { return blob_bytes_consumer_->GetError(); }
String DebugName() const override { return "ComplexFormDataBytesConsumer"; }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(blob_bytes_consumer_);
BytesConsumer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h
index fd06b7d51cd..35f4eba6473 100644
--- a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h
@@ -54,7 +54,7 @@ class FormDataBytesConsumer final : public BytesConsumer {
Error GetError() const override { return impl_->GetError(); }
String DebugName() const override { return impl_->DebugName(); }
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(impl_);
BytesConsumer::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc
index 56cf200312c..31a95c200fb 100644
--- a/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer_test.cc
@@ -103,7 +103,7 @@ scoped_refptr<EncodedFormData> DataPipeFormData() {
new SimpleDataPipeGetter(
String(" hello world"),
data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
- body.AppendDataPipe(data_pipe_getter_remote.PassPipe());
+ body.AppendDataPipe(std::move(data_pipe_getter_remote));
// Add another data pipe.
mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
@@ -112,7 +112,7 @@ scoped_refptr<EncodedFormData> DataPipeFormData() {
new SimpleDataPipeGetter(
String(" here's another data pipe "),
data_pipe_getter_remote2.InitWithNewPipeAndPassReceiver());
- body.AppendDataPipe(data_pipe_getter_remote2.PassPipe());
+ body.AppendDataPipe(std::move(data_pipe_getter_remote2));
// Add some more data.
body.AppendData(WebData("bar baz", 7));
diff --git a/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc b/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
index 80d8de09a20..aed0c0976b8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
@@ -88,7 +88,7 @@ class GlobalFetchImpl final : public GarbageCollected<GlobalFetchImpl<T>>,
return promise;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(fetch_manager_);
ScopedFetcher::Trace(visitor);
Supplement<T>::Trace(visitor);
@@ -118,7 +118,7 @@ GlobalFetch::ScopedFetcher* GlobalFetch::ScopedFetcher::From(
worker.GetExecutionContext());
}
-void GlobalFetch::ScopedFetcher::Trace(Visitor* visitor) {}
+void GlobalFetch::ScopedFetcher::Trace(Visitor* visitor) const {}
ScriptPromise GlobalFetch::fetch(ScriptState* script_state,
LocalDOMWindow& window,
diff --git a/chromium/third_party/blink/renderer/core/fetch/global_fetch.h b/chromium/third_party/blink/renderer/core/fetch/global_fetch.h
index f401074a8ec..8f9afe857de 100644
--- a/chromium/third_party/blink/renderer/core/fetch/global_fetch.h
+++ b/chromium/third_party/blink/renderer/core/fetch/global_fetch.h
@@ -33,7 +33,7 @@ class CORE_EXPORT GlobalFetch {
static ScopedFetcher* From(LocalDOMWindow&);
static ScopedFetcher* From(WorkerGlobalScope&);
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
};
static ScriptPromise fetch(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/core/fetch/headers.cc b/chromium/third_party/blink/renderer/core/fetch/headers.cc
index 893ecc97fe9..ae3e5e8062b 100644
--- a/chromium/third_party/blink/renderer/core/fetch/headers.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/headers.cc
@@ -292,7 +292,7 @@ Headers::Headers()
Headers::Headers(FetchHeaderList* header_list)
: header_list_(header_list), guard_(kNoneGuard) {}
-void Headers::Trace(Visitor* visitor) {
+void Headers::Trace(Visitor* visitor) const {
visitor->Trace(header_list_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/headers.h b/chromium/third_party/blink/renderer/core/fetch/headers.h
index 045bec08cdf..34c4be0f4b5 100644
--- a/chromium/third_party/blink/renderer/core/fetch/headers.h
+++ b/chromium/third_party/blink/renderer/core/fetch/headers.h
@@ -60,7 +60,7 @@ class CORE_EXPORT Headers final : public ScriptWrappable,
void FillWith(const HeadersInit&, ExceptionState&);
FetchHeaderList* HeaderList() const { return header_list_; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
// These methods should only be called when size() would return 0.
diff --git a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
index 2f3383b1201..43024b42f90 100644
--- a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
@@ -333,7 +333,7 @@ void MultipartParser::ParseTransportPadding(const char** bytes_pointer,
++(*bytes_pointer);
}
-void MultipartParser::Trace(Visitor* visitor) {
+void MultipartParser::Trace(Visitor* visitor) const {
visitor->Trace(client_);
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h
index 210efffac61..0cc92c076a9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h
+++ b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.h
@@ -40,7 +40,7 @@ class CORE_EXPORT MultipartParser final
virtual void PartDataInMultipartReceived(const char* bytes, size_t) = 0;
// The method is called whenever all data of a complete part is parsed.
virtual void PartDataInMultipartFullyReceived() = 0;
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
MultipartParser(Vector<char> boundary, Client*);
@@ -50,7 +50,7 @@ class CORE_EXPORT MultipartParser final
bool IsCancelled() const { return state_ == State::kCancelled; }
- void Trace(Visitor*);
+ void Trace(Visitor*) const;
private:
class Matcher {
diff --git a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc
index a5c44e81103..f0cba0e09bf 100644
--- a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.cc
@@ -91,7 +91,7 @@ void PlaceHolderBytesConsumer::Update(BytesConsumer* consumer) {
}
}
-void PlaceHolderBytesConsumer::Trace(Visitor* visitor) {
+void PlaceHolderBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(underlying_);
visitor->Trace(client_);
BytesConsumer::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h
index 09ef3a30d6a..c2c4ec025c9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h
@@ -31,7 +31,7 @@ class CORE_EXPORT PlaceHolderBytesConsumer final : public BytesConsumer {
// This function can be called at most once.
void Update(BytesConsumer* consumer);
- void Trace(Visitor* visitor) override;
+ void Trace(Visitor* visitor) const override;
private:
Member<BytesConsumer> underlying_;
diff --git a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
index 383f9d4bde4..293826bee32 100644
--- a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
@@ -58,7 +58,7 @@ class ReadableStreamBytesConsumer::OnFulfilled final : public ScriptFunction {
return v;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
ScriptFunction::Trace(visitor);
}
@@ -84,7 +84,7 @@ class ReadableStreamBytesConsumer::OnRejected final : public ScriptFunction {
return v;
}
- void Trace(Visitor* visitor) override {
+ void Trace(Visitor* visitor) const override {
visitor->Trace(consumer_);
ScriptFunction::Trace(visitor);
}
@@ -177,7 +177,7 @@ BytesConsumer::Error ReadableStreamBytesConsumer::GetError() const {
return Error("Failed to read from a ReadableStream.");
}
-void ReadableStreamBytesConsumer::Trace(Visitor* visitor) {
+void ReadableStreamBytesConsumer::Trace(Visitor* visitor) const {
visitor->Trace(reader_);
visitor->Trace(client_);
visitor->Trace(pending_buffer_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h
index 8a74a038f90..246b4292395 100644
--- a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h
+++ b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h
@@ -38,7 +38,7 @@ class CORE_EXPORT ReadableStreamBytesConsumer final : public BytesConsumer {
Error GetError() const override;
String DebugName() const override { return "ReadableStreamBytesConsumer"; }
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
class OnFulfilled;
diff --git a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
index fd8affae8f9..eeeeae9434d 100644
--- a/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
@@ -39,7 +39,7 @@ class MockClient : public GarbageCollected<MockClient>,
MOCK_METHOD0(OnStateChange, void());
String DebugName() const override { return "MockClient"; }
- void Trace(Visitor* visitor) override {}
+ void Trace(Visitor* visitor) const override {}
};
TEST(ReadableStreamBytesConsumerTest, Create) {
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.cc b/chromium/third_party/blink/renderer/core/fetch/request.cc
index a6bec95916d..9fdf4da73a9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/request.cc
@@ -175,6 +175,14 @@ static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
execution_context, std::move(form_data)),
nullptr /* AbortSignal */);
content_type = "application/x-www-form-urlencoded;charset=UTF-8";
+ } else if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() &&
+ RuntimeEnabledFeatures::FetchUploadStreamingEnabled(
+ execution_context) &&
+ V8ReadableStream::HasInstance(body, isolate)) {
+ ReadableStream* readable_stream =
+ V8ReadableStream::ToImpl(body.As<v8::Object>());
+ return_buffer =
+ MakeGarbageCollected<BodyStreamBuffer>(script_state, readable_stream);
} else {
String string = NativeValueTraits<IDLUSVString>::NativeValue(
isolate, body, exception_state);
@@ -199,16 +207,13 @@ Request* Request::CreateRequestWithRequestOrString(
// Setup RequestInit's body first
// - "If |input| is a Request object and it is disturbed, throw a
// TypeError."
- if (input_request &&
- input_request->IsBodyUsed(exception_state) == BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (input_request && input_request->IsBodyUsed()) {
exception_state.ThrowTypeError(
"Cannot construct a Request with a Request object that has already "
"been used.");
return nullptr;
}
- if (exception_state.HadException())
- return nullptr;
+
// - "Let |temporaryBody| be |input|'s request's body if |input| is a
// Request object, and null otherwise."
BodyStreamBuffer* temporary_body =
@@ -543,8 +548,6 @@ Request* Request::CreateRequestWithRequestOrString(
return nullptr;
}
- VLOG(1) << "a";
-
if (params.type == TrustTokenOperationType::kIssuance &&
!IsTrustTokenIssuanceAvailableInExecutionContext(*execution_context)) {
exception_state.ThrowTypeError(
@@ -555,6 +558,10 @@ Request* Request::CreateRequestWithRequestOrString(
request->SetTrustTokenParams(std::move(params));
}
+ if (init->hasAllowHTTP1ForStreamingUpload()) {
+ request->SetAllowHTTP1ForStreamingUpload(
+ init->allowHTTP1ForStreamingUpload());
+ }
// "Let |r| be a new Request object associated with |request| and a new
// Headers object whose guard is "request"."
@@ -645,6 +652,21 @@ Request* Request::CreateRequestWithRequestOrString(
return nullptr;
}
+ // If body is non-null and body’s source is null, then:
+ if (temporary_body && temporary_body->IsMadeFromReadableStream()) {
+ // If r’s request’s mode is neither "same-origin" nor "cors", then throw a
+ // TypeError.
+ if (request->Mode() != network::mojom::RequestMode::kSameOrigin &&
+ request->Mode() != network::mojom::RequestMode::kCors) {
+ exception_state.ThrowTypeError(
+ "If request is made from ReadableStream, mode should be"
+ "\"same-origin\" or \"cors\"");
+ return nullptr;
+ }
+ // Set r’s request’s use-CORS-preflight flag.
+ request->SetMode(network::mojom::RequestMode::kCorsWithForcedPreflight);
+ }
+
// "Set |r|'s request's body to |temporaryBody|.
if (temporary_body)
r->request_->SetBuffer(temporary_body);
@@ -717,10 +739,11 @@ Request* Request::Create(ScriptState* script_state, FetchRequestData* request) {
Request* Request::Create(
ScriptState* script_state,
- const mojom::blink::FetchAPIRequest& fetch_api_request,
+ mojom::blink::FetchAPIRequestPtr fetch_api_request,
ForServiceWorkerFetchEvent for_service_worker_fetch_event) {
- FetchRequestData* data = FetchRequestData::Create(
- script_state, fetch_api_request, for_service_worker_fetch_event);
+ FetchRequestData* data =
+ FetchRequestData::Create(script_state, std::move(fetch_api_request),
+ for_service_worker_fetch_event);
return MakeGarbageCollected<Request>(script_state, data);
}
@@ -827,6 +850,7 @@ String Request::credentials() const {
// mode:"
switch (request_->Credentials()) {
case network::mojom::CredentialsMode::kOmit:
+ case network::mojom::CredentialsMode::kOmitBug_775438_Workaround:
return "omit";
case network::mojom::CredentialsMode::kSameOrigin:
return "same-origin";
@@ -889,14 +913,10 @@ bool Request::isHistoryNavigation() const {
Request* Request::clone(ScriptState* script_state,
ExceptionState& exception_state) {
- if (IsBodyLocked(exception_state) == BodyLocked::kLocked ||
- IsBodyUsed(exception_state) == BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (IsBodyLocked() || IsBodyUsed()) {
exception_state.ThrowTypeError("Request body is already used");
return nullptr;
}
- if (exception_state.HadException())
- return nullptr;
FetchRequestData* request = request_->Clone(script_state, exception_state);
if (exception_state.HadException())
@@ -911,7 +931,7 @@ Request* Request::clone(ScriptState* script_state,
FetchRequestData* Request::PassRequestData(ScriptState* script_state,
ExceptionState& exception_state) {
- DCHECK(!IsBodyUsedForDCheck(exception_state));
+ DCHECK(!IsBodyUsed());
FetchRequestData* data = request_->Pass(script_state, exception_state);
if (exception_state.HadException())
return nullptr;
@@ -994,7 +1014,7 @@ network::mojom::RequestDestination Request::GetRequestDestination() const {
return request_->Destination();
}
-void Request::Trace(Visitor* visitor) {
+void Request::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ActiveScriptWrappable<Request>::Trace(visitor);
Body::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.h b/chromium/third_party/blink/renderer/core/fetch/request.h
index 23147aebd4f..6fa038826a5 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.h
+++ b/chromium/third_party/blink/renderer/core/fetch/request.h
@@ -59,7 +59,7 @@ class CORE_EXPORT Request final : public ScriptWrappable,
ExceptionState&);
static Request* Create(ScriptState*, FetchRequestData*);
static Request* Create(ScriptState*,
- const mojom::blink::FetchAPIRequest&,
+ mojom::blink::FetchAPIRequestPtr,
ForServiceWorkerFetchEvent);
Request(ScriptState*, FetchRequestData*, Headers*, AbortSignal*);
@@ -103,7 +103,7 @@ class CORE_EXPORT Request final : public ScriptWrappable,
mojom::RequestContextType GetRequestContextType() const;
network::mojom::RequestDestination GetRequestDestination() const;
- void Trace(Visitor*) override;
+ void Trace(Visitor*) const override;
private:
const FetchRequestData* GetRequest() const { return request_; }
diff --git a/chromium/third_party/blink/renderer/core/fetch/request_init.idl b/chromium/third_party/blink/renderer/core/fetch/request_init.idl
index 3f4f4ba2177..d59ac05c1c4 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request_init.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/request_init.idl
@@ -27,7 +27,7 @@ dictionary RequestInit {
// contexts, this has to be enforced after the fact because the
// SecureContext IDL attribute doesn't affect dictionary members.
[RuntimeEnabled=TrustTokens] TrustToken trustToken;
-
+ [RuntimeEnabled=FetchUploadStreaming] boolean allowHTTP1ForStreamingUpload;
// TODO(domfarolino): add support for RequestInit window member.
//any window; // can only be set to null
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/request_test.cc b/chromium/third_party/blink/renderer/core/fetch/request_test.cc
index 6e05308c72c..0b294198d88 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/request_test.cc
@@ -82,9 +82,10 @@ TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) {
}
fetch_api_request->referrer =
mojom::blink::Referrer::New(KURL(NullURL(), referrer), kReferrerPolicy);
+ const auto fetch_api_request_headers = fetch_api_request->headers;
Request* request =
- Request::Create(scope.GetScriptState(), *fetch_api_request,
+ Request::Create(scope.GetScriptState(), std::move(fetch_api_request),
Request::ForServiceWorkerFetchEvent::kFalse);
DCHECK(request);
EXPECT_EQ(url, request->url());
@@ -118,7 +119,7 @@ TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) {
EXPECT_EQ(referrer, second_fetch_api_request->referrer->url);
EXPECT_EQ(network::mojom::ReferrerPolicy::kAlways,
second_fetch_api_request->referrer->policy);
- EXPECT_EQ(fetch_api_request->headers, second_fetch_api_request->headers);
+ EXPECT_EQ(fetch_api_request_headers, second_fetch_api_request->headers);
}
TEST(ServiceWorkerRequestTest, ToFetchAPIRequestStripsURLFragment) {
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.cc b/chromium/third_party/blink/renderer/core/fetch/response.cc
index f3bd7020c3f..619232c20d5 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/response.cc
@@ -293,12 +293,9 @@ Response* Response::Create(ScriptState* script_state,
// then IsStreamLocked and IsStreamDisturbed will always be false.
// So we don't have to check BodyStreamBuffer is a ReadableStream
// or not.
- if (body->IsStreamLocked(exception_state).value_or(true) ||
- body->IsStreamDisturbed(exception_state).value_or(true)) {
- if (!exception_state.HadException()) {
- exception_state.ThrowTypeError(
- "Response body object should not be disturbed or locked");
- }
+ if (body->IsStreamLocked() || body->IsStreamDisturbed()) {
+ exception_state.ThrowTypeError(
+ "Response body object should not be disturbed or locked");
return nullptr;
}
@@ -384,19 +381,24 @@ FetchResponseData* Response::CreateUnfilteredFetchResponseDataWithoutBody(
response->SetResponseTime(fetch_api_response.response_time);
response->SetCacheStorageCacheName(
fetch_api_response.cache_storage_cache_name);
+ response->SetConnectionInfo(fetch_api_response.connection_info);
+ response->SetAlpnNegotiatedProtocol(
+ WTF::AtomicString(fetch_api_response.alpn_negotiated_protocol));
response->SetLoadedWithCredentials(
fetch_api_response.loaded_with_credentials);
+ response->SetWasFetchedViaSpdy(fetch_api_response.was_fetched_via_spdy);
for (const auto& header : fetch_api_response.headers)
response->HeaderList()->Append(header.key, header.value);
- // TODO(wanderview): This sets the mime type of the Response based on the
- // current headers. This should be correct for most cases, but technically
- // the mime type should really be frozen at the initial Response
- // construction. We should plumb the value through the cache_storage
- // persistence layer and include the explicit mime type in FetchAPIResponse
- // to set here. See: crbug.com/938939
- response->SetMimeType(response->HeaderList()->ExtractMIMEType());
+ // Use the |mime_type| provided by the FetchAPIResponse if its set.
+ // Otherwise fall back to extracting the mime type from the headers. This
+ // can happen when the response is loaded from an older cache_storage
+ // instance that did not yet store the mime_type value.
+ if (!fetch_api_response.mime_type.IsNull())
+ response->SetMimeType(fetch_api_response.mime_type);
+ else
+ response->SetMimeType(response->HeaderList()->ExtractMIMEType());
return response;
}
@@ -469,16 +471,11 @@ Headers* Response::headers() const {
Response* Response::clone(ScriptState* script_state,
ExceptionState& exception_state) {
- if (IsBodyLocked(exception_state) == BodyLocked::kLocked ||
- IsBodyUsed(exception_state) == BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
+ if (IsBodyLocked() || IsBodyUsed()) {
exception_state.ThrowTypeError("Response body is already used");
return nullptr;
}
- if (exception_state.HadException())
- return nullptr;
-
FetchResponseData* response = response_->Clone(script_state, exception_state);
if (exception_state.HadException())
return nullptr;
@@ -520,16 +517,9 @@ bool Response::HasBody() const {
return response_->InternalBuffer();
}
-Body::BodyUsed Response::IsBodyUsed(ExceptionState& exception_state) {
+bool Response::IsBodyUsed() const {
auto* body_buffer = InternalBodyBuffer();
- if (!body_buffer)
- return BodyUsed::kUnused;
- base::Optional<bool> stream_disturbed =
- body_buffer->IsStreamDisturbed(exception_state);
- if (exception_state.HadException())
- return BodyUsed::kBroken;
- DCHECK(stream_disturbed.has_value());
- return stream_disturbed.value() ? BodyUsed::kUsed : BodyUsed::kUnused;
+ return body_buffer && body_buffer->IsStreamDisturbed();
}
String Response::MimeType() const {
@@ -554,7 +544,7 @@ FetchHeaderList* Response::InternalHeaderList() const {
return response_->InternalHeaderList();
}
-void Response::Trace(Visitor* visitor) {
+void Response::Trace(Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ActiveScriptWrappable<Response>::Trace(visitor);
Body::Trace(visitor);
@@ -562,9 +552,4 @@ void Response::Trace(Visitor* visitor) {
visitor->Trace(headers_);
}
-bool Response::IsBodyUsedForDCheck(ExceptionState& exception_state) {
- return InternalBodyBuffer() &&
- InternalBodyBuffer()->IsStreamDisturbedForDCheck(exception_state);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.h b/chromium/third_party/blink/renderer/core/fetch/response.h
index 9d0987f51a7..2899fe168e8 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.h
+++ b/chromium/third_party/blink/renderer/core/fetch/response.h
@@ -114,7 +114,7 @@ class CORE_EXPORT Response final : public ScriptWrappable,
return response_->InternalBuffer();
}
- BodyUsed IsBodyUsed(ExceptionState&) override;
+ bool IsBodyUsed() const override;
String ContentType() const override;
String MimeType() const override;
@@ -124,12 +124,7 @@ class CORE_EXPORT Response final : public ScriptWrappable,
FetchHeaderList* InternalHeaderList() const;
- void Trace(Visitor*) override;
-
- protected:
- // A version of IsBodyUsed() which catches exceptions and returns
- // false. Should never be used outside DCHECK().
- bool IsBodyUsedForDCheck(ExceptionState&) override;
+ void Trace(Visitor*) const override;
private:
const Member<FetchResponseData> response_;
diff --git a/chromium/third_party/blink/renderer/core/fetch/trust_token.idl b/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
index a2b595ec9ac..e4014edc3c7 100644
--- a/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
@@ -25,10 +25,12 @@ dictionary TrustToken {
// 2. |additionalSignedHeaders|
// 3. |includeTimestampHeader|
// 4. |signRequestData|
+ // 5. |additionalSigningData|
//
// Additionally, |issuer| is required when |type| is "send-srr".
USVString issuer;
sequence<USVString> additionalSignedHeaders;
boolean includeTimestampHeader = false;
SignRequestData signRequestData = "omit";
+ DOMString additionalSigningData;
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc b/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc
index c0064cafe44..d7af058e35d 100644
--- a/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc
@@ -85,6 +85,9 @@ bool ConvertTrustTokenToMojom(const TrustToken& in,
return false;
}
+ if (in.hasAdditionalSigningData())
+ out->possibly_unsafe_additional_signing_data = in.additionalSigningData();
+
return true;
}