Commit 8be31472 authored by Misha Efimov's avatar Misha Efimov Committed by Commit Bot

[Cronet] Implement native UploadDataStream API.

Bug: 786559
Cq-Include-Trybots: master.tryserver.chromium.android:android_cronet_tester;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: Ied0c3de493c817e0836fcf42e09736509acbd2d1
Reviewed-on: https://chromium-review.googlesource.com/1086127
Commit-Queue: Misha Efimov <mef@chromium.org>
Reviewed-by: default avatarPaul Jensen <pauljensen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584464}
parent c0893d34
...@@ -55,6 +55,8 @@ source_set("cronet_native_impl") { ...@@ -55,6 +55,8 @@ source_set("cronet_native_impl") {
"io_buffer_with_cronet_buffer.h", "io_buffer_with_cronet_buffer.h",
"runnables.cc", "runnables.cc",
"runnables.h", "runnables.h",
"upload_data_sink.cc",
"upload_data_sink.h",
"url_request.cc", "url_request.cc",
"url_request.h", "url_request.h",
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
#include "components/cronet/native/generated/cronet.idl_impl_interface.h" #include "components/cronet/native/generated/cronet.idl_impl_interface.h"
#include "base/lazy_instance.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
namespace { namespace {
...@@ -23,9 +23,6 @@ class Cronet_BufferCallbackFree : public Cronet_BufferCallback { ...@@ -23,9 +23,6 @@ class Cronet_BufferCallbackFree : public Cronet_BufferCallback {
DISALLOW_COPY_AND_ASSIGN(Cronet_BufferCallbackFree); DISALLOW_COPY_AND_ASSIGN(Cronet_BufferCallbackFree);
}; };
base::LazyInstance<Cronet_BufferCallbackFree>::Leaky
g_cronet_buffer_callback_free = LAZY_INSTANCE_INITIALIZER;
// Concrete implementation of abstract Cronet_Buffer interface. // Concrete implementation of abstract Cronet_Buffer interface.
class Cronet_BufferImpl : public Cronet_Buffer { class Cronet_BufferImpl : public Cronet_Buffer {
public: public:
...@@ -69,7 +66,8 @@ void Cronet_BufferImpl::InitWithAlloc(uint64_t size) { ...@@ -69,7 +66,8 @@ void Cronet_BufferImpl::InitWithAlloc(uint64_t size) {
if (!data_) if (!data_)
return; return;
size_ = size; size_ = size;
callback_ = g_cronet_buffer_callback_free.Pointer(); static base::NoDestructor<Cronet_BufferCallbackFree> static_callback;
callback_ = static_callback.get();
} }
uint64_t Cronet_BufferImpl::GetSize() { uint64_t Cronet_BufferImpl::GetSize() {
......
...@@ -855,28 +855,29 @@ interface UploadDataSink { ...@@ -855,28 +855,29 @@ interface UploadDataSink {
/** /**
* Called by UploadDataProvider when a read succeeds. * Called by UploadDataProvider when a read succeeds.
* *
* @param bytes_read number of bytes read into buffer passed to read().
* @param final_chunk For chunked uploads, |true| if this is the final * @param final_chunk For chunked uploads, |true| if this is the final
* read. It must be |false| for non-chunked uploads. * read. It must be |false| for non-chunked uploads.
*/ */
OnReadSucceeded(bool final_chunk); OnReadSucceeded(uint64 bytes_read, bool final_chunk);
/** /**
* Called by UploadDataProvider when a read fails. * Called by UploadDataProvider when a read fails.
* @param error to pass on to UrlRequestCallback.onFailed(). * @param error_message to pass on to UrlRequestCallback.onFailed().
*/ */
OnReadError(Error error); OnReadError(string error_message);
/** /**
* Called by UploadDataProvider when a rewind succeeds. * Called by UploadDataProvider when a rewind succeeds.
*/ */
OnRewindSucceded(); OnRewindSucceeded();
/** /**
* Called by UploadDataProvider when a rewind fails, or if rewinding * Called by UploadDataProvider when a rewind fails, or if rewinding
* uploads is not supported. * uploads is not supported.
* @param error to pass on to UrlRequestCallback.onFailed(). * @param error_message to pass on to UrlRequestCallback.onFailed().
*/ */
OnRewindError(Error error); OnRewindError(string error_message);
}; };
/** /**
...@@ -898,9 +899,7 @@ interface UploadDataProvider { ...@@ -898,9 +899,7 @@ interface UploadDataProvider {
GetLength() => (int64 length); GetLength() => (int64 length);
/** /**
* Reads upload data into |buffer|. Upon completion, the buffer's * Reads upload data into |buffer|. Each call of this method must be followed be a
* position is updated to the end of the bytes that were read. The buffer's
* limit is not changed. Each call of this method must be followed be a
* single call, either synchronous or asynchronous, to * single call, either synchronous or asynchronous, to
* UploadDataSink.onReadSucceeded() on success * UploadDataSink.onReadSucceeded() on success
* or UploadDataSink.onReadError() on failure. Neither read nor rewind * or UploadDataSink.onReadError() on failure. Neither read nor rewind
...@@ -910,8 +909,7 @@ interface UploadDataProvider { ...@@ -910,8 +909,7 @@ interface UploadDataProvider {
* *
* @param upload_data_sink The object to notify when the read has completed, * @param upload_data_sink The object to notify when the read has completed,
* successfully or otherwise. * successfully or otherwise.
* @param buffer The buffer to copy the read bytes into. Do not change * @param buffer The buffer to copy the read bytes into.
* byteBuffer's limit.
*/ */
Read(UploadDataSink upload_data_sink, Buffer buffer); Read(UploadDataSink upload_data_sink, Buffer buffer);
......
...@@ -468,34 +468,36 @@ Cronet_UploadDataSink_GetClientContext(Cronet_UploadDataSinkPtr self); ...@@ -468,34 +468,36 @@ Cronet_UploadDataSink_GetClientContext(Cronet_UploadDataSinkPtr self);
// The app calls them to manipulate Cronet_UploadDataSink. // The app calls them to manipulate Cronet_UploadDataSink.
CRONET_EXPORT CRONET_EXPORT
void Cronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self, void Cronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self,
uint64_t bytes_read,
bool final_chunk); bool final_chunk);
CRONET_EXPORT CRONET_EXPORT
void Cronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self, void Cronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error); Cronet_String error_message);
CRONET_EXPORT CRONET_EXPORT
void Cronet_UploadDataSink_OnRewindSucceded(Cronet_UploadDataSinkPtr self); void Cronet_UploadDataSink_OnRewindSucceeded(Cronet_UploadDataSinkPtr self);
CRONET_EXPORT CRONET_EXPORT
void Cronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self, void Cronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error); Cronet_String error_message);
// Concrete interface Cronet_UploadDataSink is implemented by Cronet. // Concrete interface Cronet_UploadDataSink is implemented by Cronet.
// The app can implement these for testing / mocking. // The app can implement these for testing / mocking.
typedef void (*Cronet_UploadDataSink_OnReadSucceededFunc)( typedef void (*Cronet_UploadDataSink_OnReadSucceededFunc)(
Cronet_UploadDataSinkPtr self, Cronet_UploadDataSinkPtr self,
uint64_t bytes_read,
bool final_chunk); bool final_chunk);
typedef void (*Cronet_UploadDataSink_OnReadErrorFunc)( typedef void (*Cronet_UploadDataSink_OnReadErrorFunc)(
Cronet_UploadDataSinkPtr self, Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error); Cronet_String error_message);
typedef void (*Cronet_UploadDataSink_OnRewindSuccededFunc)( typedef void (*Cronet_UploadDataSink_OnRewindSucceededFunc)(
Cronet_UploadDataSinkPtr self); Cronet_UploadDataSinkPtr self);
typedef void (*Cronet_UploadDataSink_OnRewindErrorFunc)( typedef void (*Cronet_UploadDataSink_OnRewindErrorFunc)(
Cronet_UploadDataSinkPtr self, Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error); Cronet_String error_message);
// Concrete interface Cronet_UploadDataSink is implemented by Cronet. // Concrete interface Cronet_UploadDataSink is implemented by Cronet.
// The app can use this for testing / mocking. // The app can use this for testing / mocking.
CRONET_EXPORT Cronet_UploadDataSinkPtr Cronet_UploadDataSink_CreateWith( CRONET_EXPORT Cronet_UploadDataSinkPtr Cronet_UploadDataSink_CreateWith(
Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc, Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc,
Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc, Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc,
Cronet_UploadDataSink_OnRewindSuccededFunc OnRewindSuccededFunc, Cronet_UploadDataSink_OnRewindSucceededFunc OnRewindSucceededFunc,
Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc); Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc);
/////////////////////// ///////////////////////
......
...@@ -577,26 +577,27 @@ Cronet_ClientContext Cronet_UploadDataSink_GetClientContext( ...@@ -577,26 +577,27 @@ Cronet_ClientContext Cronet_UploadDataSink_GetClientContext(
} }
void Cronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self, void Cronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self,
uint64_t bytes_read,
bool final_chunk) { bool final_chunk) {
DCHECK(self); DCHECK(self);
self->OnReadSucceeded(final_chunk); self->OnReadSucceeded(bytes_read, final_chunk);
} }
void Cronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self, void Cronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error) { Cronet_String error_message) {
DCHECK(self); DCHECK(self);
self->OnReadError(error); self->OnReadError(error_message);
} }
void Cronet_UploadDataSink_OnRewindSucceded(Cronet_UploadDataSinkPtr self) { void Cronet_UploadDataSink_OnRewindSucceeded(Cronet_UploadDataSinkPtr self) {
DCHECK(self); DCHECK(self);
self->OnRewindSucceded(); self->OnRewindSucceeded();
} }
void Cronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self, void Cronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error) { Cronet_String error_message) {
DCHECK(self); DCHECK(self);
self->OnRewindError(error); self->OnRewindError(error_message);
} }
// Implementation of Cronet_UploadDataSink that forwards calls to C functions // Implementation of Cronet_UploadDataSink that forwards calls to C functions
...@@ -606,34 +607,34 @@ class Cronet_UploadDataSinkStub : public Cronet_UploadDataSink { ...@@ -606,34 +607,34 @@ class Cronet_UploadDataSinkStub : public Cronet_UploadDataSink {
Cronet_UploadDataSinkStub( Cronet_UploadDataSinkStub(
Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc, Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc,
Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc, Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc,
Cronet_UploadDataSink_OnRewindSuccededFunc OnRewindSuccededFunc, Cronet_UploadDataSink_OnRewindSucceededFunc OnRewindSucceededFunc,
Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc) Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc)
: OnReadSucceededFunc_(OnReadSucceededFunc), : OnReadSucceededFunc_(OnReadSucceededFunc),
OnReadErrorFunc_(OnReadErrorFunc), OnReadErrorFunc_(OnReadErrorFunc),
OnRewindSuccededFunc_(OnRewindSuccededFunc), OnRewindSucceededFunc_(OnRewindSucceededFunc),
OnRewindErrorFunc_(OnRewindErrorFunc) {} OnRewindErrorFunc_(OnRewindErrorFunc) {}
~Cronet_UploadDataSinkStub() override {} ~Cronet_UploadDataSinkStub() override {}
protected: protected:
void OnReadSucceeded(bool final_chunk) override { void OnReadSucceeded(uint64_t bytes_read, bool final_chunk) override {
OnReadSucceededFunc_(this, final_chunk); OnReadSucceededFunc_(this, bytes_read, final_chunk);
} }
void OnReadError(Cronet_ErrorPtr error) override { void OnReadError(Cronet_String error_message) override {
OnReadErrorFunc_(this, error); OnReadErrorFunc_(this, error_message);
} }
void OnRewindSucceded() override { OnRewindSuccededFunc_(this); } void OnRewindSucceeded() override { OnRewindSucceededFunc_(this); }
void OnRewindError(Cronet_ErrorPtr error) override { void OnRewindError(Cronet_String error_message) override {
OnRewindErrorFunc_(this, error); OnRewindErrorFunc_(this, error_message);
} }
private: private:
const Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc_; const Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc_;
const Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc_; const Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc_;
const Cronet_UploadDataSink_OnRewindSuccededFunc OnRewindSuccededFunc_; const Cronet_UploadDataSink_OnRewindSucceededFunc OnRewindSucceededFunc_;
const Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc_; const Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc_;
DISALLOW_COPY_AND_ASSIGN(Cronet_UploadDataSinkStub); DISALLOW_COPY_AND_ASSIGN(Cronet_UploadDataSinkStub);
...@@ -642,10 +643,11 @@ class Cronet_UploadDataSinkStub : public Cronet_UploadDataSink { ...@@ -642,10 +643,11 @@ class Cronet_UploadDataSinkStub : public Cronet_UploadDataSink {
Cronet_UploadDataSinkPtr Cronet_UploadDataSink_CreateWith( Cronet_UploadDataSinkPtr Cronet_UploadDataSink_CreateWith(
Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc, Cronet_UploadDataSink_OnReadSucceededFunc OnReadSucceededFunc,
Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc, Cronet_UploadDataSink_OnReadErrorFunc OnReadErrorFunc,
Cronet_UploadDataSink_OnRewindSuccededFunc OnRewindSuccededFunc, Cronet_UploadDataSink_OnRewindSucceededFunc OnRewindSucceededFunc,
Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc) { Cronet_UploadDataSink_OnRewindErrorFunc OnRewindErrorFunc) {
return new Cronet_UploadDataSinkStub(OnReadSucceededFunc, OnReadErrorFunc, return new Cronet_UploadDataSinkStub(OnReadSucceededFunc, OnReadErrorFunc,
OnRewindSuccededFunc, OnRewindErrorFunc); OnRewindSucceededFunc,
OnRewindErrorFunc);
} }
// C functions of Cronet_UploadDataProvider that forward calls to C++ // C functions of Cronet_UploadDataProvider that forward calls to C++
......
...@@ -166,10 +166,10 @@ struct Cronet_UploadDataSink { ...@@ -166,10 +166,10 @@ struct Cronet_UploadDataSink {
} }
Cronet_ClientContext client_context() const { return client_context_; } Cronet_ClientContext client_context() const { return client_context_; }
virtual void OnReadSucceeded(bool final_chunk) = 0; virtual void OnReadSucceeded(uint64_t bytes_read, bool final_chunk) = 0;
virtual void OnReadError(Cronet_ErrorPtr error) = 0; virtual void OnReadError(Cronet_String error_message) = 0;
virtual void OnRewindSucceded() = 0; virtual void OnRewindSucceeded() = 0;
virtual void OnRewindError(Cronet_ErrorPtr error) = 0; virtual void OnRewindError(Cronet_String error_message) = 0;
private: private:
Cronet_ClientContext client_context_ = nullptr; Cronet_ClientContext client_context_ = nullptr;
......
...@@ -66,7 +66,7 @@ Cronet_RawDataPtr TestCronet_Buffer_GetData(Cronet_BufferPtr self) { ...@@ -66,7 +66,7 @@ Cronet_RawDataPtr TestCronet_Buffer_GetData(Cronet_BufferPtr self) {
CHECK(test); CHECK(test);
test->GetData_called_ = true; test->GetData_called_ = true;
return static_cast<Cronet_RawDataPtr>(nullptr); return static_cast<Cronet_RawDataPtr>(0);
} }
} // namespace } // namespace
...@@ -276,7 +276,7 @@ Cronet_String TestCronet_Engine_GetVersionString(Cronet_EnginePtr self) { ...@@ -276,7 +276,7 @@ Cronet_String TestCronet_Engine_GetVersionString(Cronet_EnginePtr self) {
CHECK(test); CHECK(test);
test->GetVersionString_called_ = true; test->GetVersionString_called_ = true;
return static_cast<Cronet_String>(nullptr); return static_cast<Cronet_String>(0);
} }
Cronet_String TestCronet_Engine_GetDefaultUserAgent(Cronet_EnginePtr self) { Cronet_String TestCronet_Engine_GetDefaultUserAgent(Cronet_EnginePtr self) {
CHECK(self); CHECK(self);
...@@ -285,7 +285,7 @@ Cronet_String TestCronet_Engine_GetDefaultUserAgent(Cronet_EnginePtr self) { ...@@ -285,7 +285,7 @@ Cronet_String TestCronet_Engine_GetDefaultUserAgent(Cronet_EnginePtr self) {
CHECK(test); CHECK(test);
test->GetDefaultUserAgent_called_ = true; test->GetDefaultUserAgent_called_ = true;
return static_cast<Cronet_String>(nullptr); return static_cast<Cronet_String>(0);
} }
} // namespace } // namespace
...@@ -485,7 +485,7 @@ class Cronet_UploadDataSinkTest : public ::testing::Test { ...@@ -485,7 +485,7 @@ class Cronet_UploadDataSinkTest : public ::testing::Test {
public: public:
bool OnReadSucceeded_called_ = false; bool OnReadSucceeded_called_ = false;
bool OnReadError_called_ = false; bool OnReadError_called_ = false;
bool OnRewindSucceded_called_ = false; bool OnRewindSucceeded_called_ = false;
bool OnRewindError_called_ = false; bool OnRewindError_called_ = false;
private: private:
...@@ -495,6 +495,7 @@ class Cronet_UploadDataSinkTest : public ::testing::Test { ...@@ -495,6 +495,7 @@ class Cronet_UploadDataSinkTest : public ::testing::Test {
namespace { namespace {
// Implementation of Cronet_UploadDataSink methods for testing. // Implementation of Cronet_UploadDataSink methods for testing.
void TestCronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self, void TestCronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self,
uint64_t bytes_read,
bool final_chunk) { bool final_chunk) {
CHECK(self); CHECK(self);
Cronet_ClientContext client_context = Cronet_ClientContext client_context =
...@@ -504,7 +505,7 @@ void TestCronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self, ...@@ -504,7 +505,7 @@ void TestCronet_UploadDataSink_OnReadSucceeded(Cronet_UploadDataSinkPtr self,
test->OnReadSucceeded_called_ = true; test->OnReadSucceeded_called_ = true;
} }
void TestCronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self, void TestCronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error) { Cronet_String error_message) {
CHECK(self); CHECK(self);
Cronet_ClientContext client_context = Cronet_ClientContext client_context =
Cronet_UploadDataSink_GetClientContext(self); Cronet_UploadDataSink_GetClientContext(self);
...@@ -512,16 +513,17 @@ void TestCronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self, ...@@ -512,16 +513,17 @@ void TestCronet_UploadDataSink_OnReadError(Cronet_UploadDataSinkPtr self,
CHECK(test); CHECK(test);
test->OnReadError_called_ = true; test->OnReadError_called_ = true;
} }
void TestCronet_UploadDataSink_OnRewindSucceded(Cronet_UploadDataSinkPtr self) { void TestCronet_UploadDataSink_OnRewindSucceeded(
Cronet_UploadDataSinkPtr self) {
CHECK(self); CHECK(self);
Cronet_ClientContext client_context = Cronet_ClientContext client_context =
Cronet_UploadDataSink_GetClientContext(self); Cronet_UploadDataSink_GetClientContext(self);
auto* test = static_cast<Cronet_UploadDataSinkTest*>(client_context); auto* test = static_cast<Cronet_UploadDataSinkTest*>(client_context);
CHECK(test); CHECK(test);
test->OnRewindSucceded_called_ = true; test->OnRewindSucceeded_called_ = true;
} }
void TestCronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self, void TestCronet_UploadDataSink_OnRewindError(Cronet_UploadDataSinkPtr self,
Cronet_ErrorPtr error) { Cronet_String error_message) {
CHECK(self); CHECK(self);
Cronet_ClientContext client_context = Cronet_ClientContext client_context =
Cronet_UploadDataSink_GetClientContext(self); Cronet_UploadDataSink_GetClientContext(self);
...@@ -536,14 +538,14 @@ TEST_F(Cronet_UploadDataSinkTest, TestCreate) { ...@@ -536,14 +538,14 @@ TEST_F(Cronet_UploadDataSinkTest, TestCreate) {
Cronet_UploadDataSinkPtr test = Cronet_UploadDataSink_CreateWith( Cronet_UploadDataSinkPtr test = Cronet_UploadDataSink_CreateWith(
TestCronet_UploadDataSink_OnReadSucceeded, TestCronet_UploadDataSink_OnReadSucceeded,
TestCronet_UploadDataSink_OnReadError, TestCronet_UploadDataSink_OnReadError,
TestCronet_UploadDataSink_OnRewindSucceded, TestCronet_UploadDataSink_OnRewindSucceeded,
TestCronet_UploadDataSink_OnRewindError); TestCronet_UploadDataSink_OnRewindError);
CHECK(test); CHECK(test);
Cronet_UploadDataSink_SetClientContext(test, this); Cronet_UploadDataSink_SetClientContext(test, this);
CHECK(!OnReadSucceeded_called_); CHECK(!OnReadSucceeded_called_);
CHECK(!OnReadError_called_); CHECK(!OnReadError_called_);
Cronet_UploadDataSink_OnRewindSucceded(test); Cronet_UploadDataSink_OnRewindSucceeded(test);
CHECK(OnRewindSucceded_called_); CHECK(OnRewindSucceeded_called_);
CHECK(!OnRewindError_called_); CHECK(!OnRewindError_called_);
Cronet_UploadDataSink_Destroy(test); Cronet_UploadDataSink_Destroy(test);
......
...@@ -4,8 +4,25 @@ ...@@ -4,8 +4,25 @@
#include "components/cronet/native/io_buffer_with_cronet_buffer.h" #include "components/cronet/native/io_buffer_with_cronet_buffer.h"
#include "base/no_destructor.h"
#include "components/cronet/native/generated/cronet.idl_impl_interface.h" #include "components/cronet/native/generated/cronet.idl_impl_interface.h"
namespace {
// Implementation of Cronet_BufferCallback that doesn't free the data as it
// is not owned by the buffer.
class Cronet_BufferCallbackUnowned : public Cronet_BufferCallback {
public:
Cronet_BufferCallbackUnowned() = default;
~Cronet_BufferCallbackUnowned() override = default;
void OnDestroy(Cronet_BufferPtr buffer) override {}
private:
DISALLOW_COPY_AND_ASSIGN(Cronet_BufferCallbackUnowned);
};
} // namespace
namespace cronet { namespace cronet {
IOBufferWithCronet_Buffer::IOBufferWithCronet_Buffer( IOBufferWithCronet_Buffer::IOBufferWithCronet_Buffer(
...@@ -25,4 +42,16 @@ Cronet_BufferPtr IOBufferWithCronet_Buffer::Release() { ...@@ -25,4 +42,16 @@ Cronet_BufferPtr IOBufferWithCronet_Buffer::Release() {
return cronet_buffer_.release(); return cronet_buffer_.release();
} }
Cronet_BufferWithIOBuffer::Cronet_BufferWithIOBuffer(net::IOBuffer* io_buffer,
size_t io_buffer_len)
: io_buffer_(io_buffer),
io_buffer_len_(io_buffer_len),
cronet_buffer_(Cronet_Buffer_Create()) {
static base::NoDestructor<Cronet_BufferCallbackUnowned> static_callback;
cronet_buffer_->InitWithDataAndCallback(io_buffer->data(), io_buffer_len,
static_callback.get());
}
Cronet_BufferWithIOBuffer::~Cronet_BufferWithIOBuffer() = default;
} // namespace cronet } // namespace cronet
...@@ -32,6 +32,29 @@ class IOBufferWithCronet_Buffer : public net::WrappedIOBuffer { ...@@ -32,6 +32,29 @@ class IOBufferWithCronet_Buffer : public net::WrappedIOBuffer {
DISALLOW_COPY_AND_ASSIGN(IOBufferWithCronet_Buffer); DISALLOW_COPY_AND_ASSIGN(IOBufferWithCronet_Buffer);
}; };
// Represents a Cronet_Buffer backed by a net::IOBuffer. Keeps both the
// net::IOBuffer and the Cronet_Buffer object alive until destroyed.
class Cronet_BufferWithIOBuffer {
public:
Cronet_BufferWithIOBuffer(net::IOBuffer* io_buffer, size_t io_buffer_len);
~Cronet_BufferWithIOBuffer();
const net::IOBuffer* io_buffer() const { return io_buffer_.get(); }
size_t io_buffer_len() const { return io_buffer_len_; }
// Returns pointer to Cronet buffer owned by |this|.
Cronet_BufferPtr cronet_buffer() { return cronet_buffer_.get(); }
private:
scoped_refptr<net::IOBuffer> io_buffer_;
size_t io_buffer_len_;
// Cronet buffer owned by |this|.
std::unique_ptr<Cronet_Buffer> cronet_buffer_;
DISALLOW_COPY_AND_ASSIGN(Cronet_BufferWithIOBuffer);
};
} // namespace cronet } // namespace cronet
#endif // COMPONENTS_CRONET_NATIVE_IO_BUFFER_WITH_CRONET_BUFFER_H_ #endif // COMPONENTS_CRONET_NATIVE_IO_BUFFER_WITH_CRONET_BUFFER_H_
...@@ -44,6 +44,8 @@ source_set("cronet_native_tests") { ...@@ -44,6 +44,8 @@ source_set("cronet_native_tests") {
"buffer_test.cc", "buffer_test.cc",
"engine_test.cc", "engine_test.cc",
"executors_test.cc", "executors_test.cc",
"test_upload_data_provider.cc",
"test_upload_data_provider.h",
"test_url_request_callback.cc", "test_url_request_callback.cc",
"test_url_request_callback.h", "test_url_request_callback.h",
"url_request_test.cc", "url_request_test.cc",
......
// Copyright 2018 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 "components/cronet/native/test/test_upload_data_provider.h"
#include "base/bind.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// Helper class that runs base::OnceClosure.
class TestRunnable {
public:
// Creates Cronet runnable that runs |task| once and destroys itself.
static Cronet_RunnablePtr CreateRunnable(base::OnceClosure task);
private:
explicit TestRunnable(base::OnceClosure task);
~TestRunnable();
// Runs |self| and destroys it.
static void Run(Cronet_RunnablePtr self);
// Closure to run.
base::OnceClosure task_;
DISALLOW_COPY_AND_ASSIGN(TestRunnable);
};
TestRunnable::TestRunnable(base::OnceClosure task) : task_(std::move(task)) {}
TestRunnable::~TestRunnable() = default;
// static
Cronet_RunnablePtr TestRunnable::CreateRunnable(base::OnceClosure task) {
Cronet_RunnablePtr runnable = Cronet_Runnable_CreateWith(TestRunnable::Run);
Cronet_Runnable_SetClientContext(runnable, new TestRunnable(std::move(task)));
return runnable;
}
// static
void TestRunnable::Run(Cronet_RunnablePtr self) {
CHECK(self);
Cronet_ClientContext context = Cronet_Runnable_GetClientContext(self);
TestRunnable* runnable = static_cast<TestRunnable*>(context);
CHECK(runnable);
std::move(runnable->task_).Run();
delete runnable;
Cronet_Runnable_Destroy(self);
}
} // namespace
namespace cronet {
// Various test utility functions for testing Cronet.
namespace test {
TestUploadDataProvider::TestUploadDataProvider(
SuccessCallbackMode success_callback_mode,
Cronet_ExecutorPtr executor)
: success_callback_mode_(success_callback_mode), executor_(executor) {}
TestUploadDataProvider::~TestUploadDataProvider() = default;
Cronet_UploadDataProviderPtr
TestUploadDataProvider::CreateUploadDataProvider() {
Cronet_UploadDataProviderPtr upload_data_provider =
Cronet_UploadDataProvider_CreateWith(
TestUploadDataProvider::GetLength, TestUploadDataProvider::Read,
TestUploadDataProvider::Rewind, TestUploadDataProvider::Close);
Cronet_UploadDataProvider_SetClientContext(upload_data_provider, this);
return upload_data_provider;
}
void TestUploadDataProvider::AddRead(std::string read) {
EXPECT_TRUE(!started_) << "Adding bytes after read";
reads_.push_back(read);
}
void TestUploadDataProvider::SetReadFailure(int read_fail_index,
FailMode read_fail_mode) {
read_fail_index_ = read_fail_index;
read_fail_mode_ = read_fail_mode;
}
void TestUploadDataProvider::SetRewindFailure(FailMode rewind_fail_mode) {
rewind_fail_mode_ = rewind_fail_mode;
}
int64_t TestUploadDataProvider::GetLength() const {
EXPECT_TRUE(!closed_.IsSet()) << "Data Provider is closed";
if (bad_length_ != -1)
return bad_length_;
return GetUploadedLength();
}
int64_t TestUploadDataProvider::GetUploadedLength() const {
if (chunked_)
return -1ll;
int64_t length = 0ll;
for (const auto& read : reads_)
length += read.size();
return length;
}
void TestUploadDataProvider::Read(Cronet_UploadDataSinkPtr upload_data_sink,
Cronet_BufferPtr buffer) {
int current_read_call = num_read_calls_;
++num_read_calls_;
EXPECT_TRUE(!closed_.IsSet()) << "Data Provider is closed";
AssertIdle();
if (MaybeFailRead(current_read_call, upload_data_sink)) {
failed_ = true;
return;
}
read_pending_ = true;
started_ = true;
bool final_chunk = (chunked_ && next_read_ == reads_.size() - 1);
EXPECT_TRUE(next_read_ < reads_.size()) << "Too many reads: " << next_read_;
const auto& read = reads_[next_read_];
EXPECT_TRUE(read.size() < Cronet_Buffer_GetSize(buffer))
<< "Read buffer smaller than expected.";
memcpy(Cronet_Buffer_GetData(buffer), read.data(), read.size());
++next_read_;
auto complete_closure = base::BindOnce(
[](TestUploadDataProvider* upload_data_provider,
Cronet_UploadDataSink* upload_data_sink, uint64_t bytes_read,
bool final_chunk) {
upload_data_provider->read_pending_ = false;
Cronet_UploadDataSink_OnReadSucceeded(upload_data_sink, bytes_read,
final_chunk);
},
this, upload_data_sink, read.size(), final_chunk);
if (success_callback_mode_ == SYNC) {
std::move(complete_closure).Run();
} else {
PostTaskToExecutor(std::move(complete_closure));
}
}
void TestUploadDataProvider::Rewind(Cronet_UploadDataSinkPtr upload_data_sink) {
++num_rewind_calls_;
EXPECT_TRUE(!closed_.IsSet()) << "Data Provider is closed";
AssertIdle();
if (MaybeFailRewind(upload_data_sink)) {
failed_ = true;
return;
}
// Should never try and rewind when rewinding does nothing.
EXPECT_TRUE(next_read_ != 0) << "Unexpected rewind when already at beginning";
rewind_pending_ = true;
next_read_ = 0;
auto complete_closure = base::BindOnce(
[](TestUploadDataProvider* upload_data_provider,
Cronet_UploadDataSink* upload_data_sink) {
upload_data_provider->rewind_pending_ = false;
Cronet_UploadDataSink_OnRewindSucceeded(upload_data_sink);
},
this, upload_data_sink);
if (success_callback_mode_ == SYNC) {
std::move(complete_closure).Run();
} else {
PostTaskToExecutor(std::move(complete_closure));
}
}
void TestUploadDataProvider::PostTaskToExecutor(base::OnceClosure task) {
EXPECT_TRUE(executor_);
// |runnable| is passed to executor, which destroys it after execution.
Cronet_Executor_Execute(executor_,
TestRunnable::CreateRunnable(std::move(task)));
}
void TestUploadDataProvider::AssertIdle() const {
EXPECT_TRUE(!read_pending_) << "Unexpected operation during read";
EXPECT_TRUE(!rewind_pending_) << "Unexpected operation during rewind";
EXPECT_TRUE(!failed_) << "Unexpected operation after failure";
}
bool TestUploadDataProvider::MaybeFailRead(
int read_index,
Cronet_UploadDataSinkPtr upload_data_sink) {
if (read_index != read_fail_index_)
return false;
if (read_fail_mode_ == NONE)
return false;
if (read_fail_mode_ == CALLBACK_SYNC) {
Cronet_UploadDataSink_OnReadError(upload_data_sink, "Sync read failure");
return true;
}
EXPECT_EQ(read_fail_mode_, CALLBACK_ASYNC);
PostTaskToExecutor(base::BindOnce(
[](Cronet_UploadDataSink* upload_data_sink) {
Cronet_UploadDataSink_OnReadError(upload_data_sink,
"Async read failure");
},
upload_data_sink));
return true;
}
bool TestUploadDataProvider::MaybeFailRewind(
Cronet_UploadDataSinkPtr upload_data_sink) {
if (rewind_fail_mode_ == NONE)
return false;
if (rewind_fail_mode_ == CALLBACK_SYNC) {
Cronet_UploadDataSink_OnRewindError(upload_data_sink,
"Sync rewind failure");
return true;
}
EXPECT_EQ(rewind_fail_mode_, CALLBACK_ASYNC);
PostTaskToExecutor(base::BindOnce(
[](Cronet_UploadDataSink* upload_data_sink) {
Cronet_UploadDataSink_OnRewindError(upload_data_sink,
"Async rewind failure");
},
upload_data_sink));
return true;
}
void TestUploadDataProvider::Close() {
EXPECT_TRUE(!closed_.IsSet()) << "Closed twice";
closed_.Set();
awaiting_close_.Signal();
}
void TestUploadDataProvider::AssertClosed() {
awaiting_close_.TimedWait(base::TimeDelta::FromMilliseconds(5000));
EXPECT_TRUE(closed_.IsSet()) << "Was not closed";
}
/* static */
TestUploadDataProvider* TestUploadDataProvider::GetThis(
Cronet_UploadDataProviderPtr self) {
return static_cast<TestUploadDataProvider*>(
Cronet_UploadDataProvider_GetClientContext(self));
}
/* static */
int64_t TestUploadDataProvider::GetLength(Cronet_UploadDataProviderPtr self) {
return GetThis(self)->GetLength();
}
/* static */
void TestUploadDataProvider::Read(Cronet_UploadDataProviderPtr self,
Cronet_UploadDataSinkPtr upload_data_sink,
Cronet_BufferPtr buffer) {
return GetThis(self)->Read(upload_data_sink, buffer);
}
/* static */
void TestUploadDataProvider::Rewind(Cronet_UploadDataProviderPtr self,
Cronet_UploadDataSinkPtr upload_data_sink) {
return GetThis(self)->Rewind(upload_data_sink);
}
/* static */
void TestUploadDataProvider::Close(Cronet_UploadDataProviderPtr self) {
return GetThis(self)->Close();
}
} // namespace test
} // namespace cronet
// Copyright 2018 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 COMPONENTS_CRONET_NATIVE_TEST_TEST_UPLOAD_DATA_PROVIDER_H_
#define COMPONENTS_CRONET_NATIVE_TEST_TEST_UPLOAD_DATA_PROVIDER_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "cronet_c.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/synchronization/atomic_flag.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cronet {
// Various test utility functions for testing Cronet.
namespace test {
/**
* An UploadDataProvider implementation used in tests.
*/
class TestUploadDataProvider {
public:
// Indicates whether all success callbacks are synchronous or asynchronous.
// Doesn't apply to errors.
enum SuccessCallbackMode { SYNC, ASYNC };
// Indicates whether failures should invoke callbacks synchronously, or
// invoke callback asynchronously.
enum FailMode { NONE, CALLBACK_SYNC, CALLBACK_ASYNC };
TestUploadDataProvider(SuccessCallbackMode success_callback_mode,
Cronet_ExecutorPtr executor);
~TestUploadDataProvider();
Cronet_UploadDataProviderPtr CreateUploadDataProvider();
// Adds the result to be returned by a successful read request. The
// returned bytes must all fit within the read buffer provided by Cronet.
// After a rewind, if there is one, all reads will be repeated.
void AddRead(std::string read);
void SetReadFailure(int read_fail_index, FailMode read_fail_mode);
void SetRewindFailure(FailMode rewind_fail_mode);
void set_bad_length(int64_t bad_length) { bad_length_ = bad_length; }
void set_chunked(bool chunked) { chunked_ = chunked; }
int num_read_calls() const { return num_read_calls_; }
int num_rewind_calls() const { return num_rewind_calls_; }
/**
* Returns the cumulative length of all data added by calls to addRead.
*/
int64_t GetLength() const;
int64_t GetUploadedLength() const;
void Read(Cronet_UploadDataSinkPtr upload_data_sink, Cronet_BufferPtr buffer);
void Rewind(Cronet_UploadDataSinkPtr upload_data_sink);
void AssertClosed();
private:
void PostTaskToExecutor(base::OnceClosure task);
void AssertIdle() const;
bool MaybeFailRead(int read_index, Cronet_UploadDataSinkPtr upload_data_sink);
bool MaybeFailRewind(Cronet_UploadDataSinkPtr upload_data_sink);
void Close();
// Implementation of Cronet_UploadDataProvider methods.
static TestUploadDataProvider* GetThis(Cronet_UploadDataProviderPtr self);
static int64_t GetLength(Cronet_UploadDataProviderPtr self);
static void Read(Cronet_UploadDataProviderPtr self,
Cronet_UploadDataSinkPtr upload_data_sink,
Cronet_BufferPtr buffer);
static void Rewind(Cronet_UploadDataProviderPtr self,
Cronet_UploadDataSinkPtr upload_data_sink);
static void Close(Cronet_UploadDataProviderPtr self);
std::vector<std::string> reads_;
const SuccessCallbackMode success_callback_mode_ = SYNC;
const Cronet_ExecutorPtr executor_;
bool chunked_ = false;
// Index of read to fail on.
int read_fail_index_ = -1;
// Indicates how to fail on a read.
FailMode read_fail_mode_ = NONE;
FailMode rewind_fail_mode_ = NONE;
// Report bad length if not set to -1.
int64_t bad_length_ = -1;
int num_read_calls_ = 0;
int num_rewind_calls_ = 0;
size_t next_read_ = 0;
bool started_ = false;
bool read_pending_ = false;
bool rewind_pending_ = false;
// Used to ensure there are no read/rewind requests after a failure.
bool failed_ = false;
base::AtomicFlag closed_;
base::WaitableEvent awaiting_close_;
};
} // namespace test
} // namespace cronet
#endif // COMPONENTS_CRONET_NATIVE_TEST_TEST_UPLOAD_DATA_PROVIDER_H_
...@@ -68,15 +68,21 @@ TestUrlRequestCallback::~TestUrlRequestCallback() { ...@@ -68,15 +68,21 @@ TestUrlRequestCallback::~TestUrlRequestCallback() {
} }
Cronet_ExecutorPtr TestUrlRequestCallback::GetExecutor(bool direct) { Cronet_ExecutorPtr TestUrlRequestCallback::GetExecutor(bool direct) {
CHECK(!executor_); if (executor_) {
CHECK(direct == allow_direct_executor_);
return executor_;
}
allow_direct_executor_ = direct; allow_direct_executor_ = direct;
if (direct) if (direct) {
return Cronet_Executor_CreateWith(TestUrlRequestCallback::ExecuteDirect); executor_ =
executor_thread_ = Cronet_Executor_CreateWith(TestUrlRequestCallback::ExecuteDirect);
std::make_unique<base::Thread>("TestUrlRequestCallback executor"); } else {
executor_thread_->Start(); executor_thread_ =
executor_ = Cronet_Executor_CreateWith(TestUrlRequestCallback::Execute); std::make_unique<base::Thread>("TestUrlRequestCallback executor");
Cronet_Executor_SetClientContext(executor_, this); executor_thread_->Start();
executor_ = Cronet_Executor_CreateWith(TestUrlRequestCallback::Execute);
Cronet_Executor_SetClientContext(executor_, this);
}
return executor_; return executor_;
} }
...@@ -186,6 +192,8 @@ void TestUrlRequestCallback::OnFailed(Cronet_UrlRequestPtr request, ...@@ -186,6 +192,8 @@ void TestUrlRequestCallback::OnFailed(Cronet_UrlRequestPtr request,
if (info) if (info)
response_info_ = std::make_unique<UrlResponseInfo>(info); response_info_ = std::make_unique<UrlResponseInfo>(info);
last_error_ = error; last_error_ = error;
last_error_code_ = Cronet_Error_error_code_get(error);
last_error_message_ = Cronet_Error_message_get(error);
SignalDone(); SignalDone();
MaybeCancelOrPause(request); MaybeCancelOrPause(request);
} }
......
...@@ -72,6 +72,10 @@ class TestUrlRequestCallback { ...@@ -72,6 +72,10 @@ class TestUrlRequestCallback {
std::unique_ptr<UrlResponseInfo> response_info_; std::unique_ptr<UrlResponseInfo> response_info_;
// Owned by UrlRequest, only valid until UrlRequest is destroyed. // Owned by UrlRequest, only valid until UrlRequest is destroyed.
Cronet_ErrorPtr last_error_ = nullptr; Cronet_ErrorPtr last_error_ = nullptr;
// Values copied from |last_error_| valid after UrlRequest is destroyed.
Cronet_Error_ERROR_CODE last_error_code_ =
Cronet_Error_ERROR_CODE_ERROR_OTHER;
std::string last_error_message_;
ResponseStep response_step_ = NOTHING; ResponseStep response_step_ = NOTHING;
......
This diff is collapsed.
// Copyright 2018 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 COMPONENTS_CRONET_NATIVE_UPLOAD_DATA_SINK_H_
#define COMPONENTS_CRONET_NATIVE_UPLOAD_DATA_SINK_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "components/cronet/cronet_upload_data_stream.h"
#include "components/cronet/cronet_url_request.h"
#include "components/cronet/cronet_url_request_context.h"
#include "components/cronet/native/generated/cronet.idl_impl_interface.h"
namespace cronet {
class Cronet_UrlRequestImpl;
class Cronet_BufferWithIOBuffer;
// Implementation of Cronet_UploadDataSink that uses CronetUploadDataStream.
// Always accessed on client executor.
class Cronet_UploadDataSinkImpl : public Cronet_UploadDataSink {
public:
Cronet_UploadDataSinkImpl(Cronet_UrlRequestImpl* url_request,
Cronet_UploadDataProvider* upload_data_provider,
Cronet_Executor* upload_data_provider_executor);
~Cronet_UploadDataSinkImpl() override;
// Initialize length and attach upload to request. Called on client thread.
bool InitRequest(CronetURLRequest* request);
// Mark stream as closed and post |Close()| callback to consumer.
void PostCloseToExecutor();
private:
class NetworkTasks;
enum UserCallback { READ, REWIND, GET_LENGTH, NOT_IN_CALLBACK };
// Cronet_UploadDataSink
void OnReadSucceeded(uint64_t bytes_read, bool final_chunk) override;
void OnReadError(Cronet_String error_message) override;
void OnRewindSucceeded() override;
void OnRewindError(Cronet_String error_message) override;
// CronetUploadDataStream::Delegate methods posted from the network thread.
void InitializeUploadDataStream(
base::WeakPtr<CronetUploadDataStream> upload_data_stream,
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner);
void Read(net::IOBuffer* buffer, int buf_len);
void Rewind();
void Close();
void CheckState(UserCallback expected_state);
// Cronet objects not owned by |this| and accessed on client thread.
// The request, which owns |this|.
Cronet_UrlRequestImpl* const url_request_ = nullptr;
// Executor for provider callback, used, but not owned, by |this|. Always
// outlives |this| callback.
Cronet_ExecutorPtr const upload_data_provider_executor_ = nullptr;
// These are initialized in InitializeUploadDataStream(), so are safe to
// access during client callbacks, which all happen after initialization.
scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
base::WeakPtr<CronetUploadDataStream> upload_data_stream_;
bool is_chunked_ = false;
uint64_t length_ = 0;
uint64_t remaining_length_ = 0;
// Synchronize access to |buffer_| and other objects below from different
// threads.
base::Lock lock_;
// Data provider callback interface, used, but not owned, by |this|.
// Set to nullptr when data provider is closed.
Cronet_UploadDataProviderPtr upload_data_provider_ = nullptr;
UserCallback in_which_user_callback_ = NOT_IN_CALLBACK;
// Close data provider once it returns from the callback.
bool close_when_not_in_callback_ = false;
// Keeps the net::IOBuffer and Cronet ByteBuffer alive until the next Read().
std::unique_ptr<Cronet_BufferWithIOBuffer> buffer_;
DISALLOW_COPY_AND_ASSIGN(Cronet_UploadDataSinkImpl);
};
} // namespace cronet
#endif // COMPONENTS_CRONET_NATIVE_UPLOAD_DATA_SINK_H_
This diff is collapsed.
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "components/cronet/cronet_url_request.h" #include "components/cronet/cronet_url_request.h"
#include "components/cronet/cronet_url_request_context.h" #include "components/cronet/cronet_url_request_context.h"
#include "components/cronet/native/generated/cronet.idl_impl_interface.h" #include "components/cronet/native/generated/cronet.idl_impl_interface.h"
...@@ -18,6 +17,7 @@ ...@@ -18,6 +17,7 @@
namespace cronet { namespace cronet {
class Cronet_EngineImpl; class Cronet_EngineImpl;
class Cronet_UploadDataSinkImpl;
// Implementation of Cronet_UrlRequest that uses CronetURLRequestContext. // Implementation of Cronet_UrlRequest that uses CronetURLRequestContext.
class Cronet_UrlRequestImpl : public Cronet_UrlRequest { class Cronet_UrlRequestImpl : public Cronet_UrlRequest {
...@@ -38,8 +38,12 @@ class Cronet_UrlRequestImpl : public Cronet_UrlRequest { ...@@ -38,8 +38,12 @@ class Cronet_UrlRequestImpl : public Cronet_UrlRequest {
bool IsDone() override; bool IsDone() override;
void GetStatus(Cronet_UrlRequestStatusListenerPtr listener) override; void GetStatus(Cronet_UrlRequestStatusListenerPtr listener) override;
// Upload data provider has reported error while reading or rewinding
// so request must fail.
void OnUploadDataProviderError(const std::string& error_message);
private: private:
class Callback; class NetworkTasks;
// Return |true| if request has started and is now done. // Return |true| if request has started and is now done.
// Must be called under |lock_| held. // Must be called under |lock_| held.
...@@ -57,6 +61,19 @@ class Cronet_UrlRequestImpl : public Cronet_UrlRequest { ...@@ -57,6 +61,19 @@ class Cronet_UrlRequestImpl : public Cronet_UrlRequest {
bool DestroyRequestUnlessDoneLocked( bool DestroyRequestUnlessDoneLocked(
Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason); Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason);
// Helper method to post |task| to the |executor_|.
void PostTaskToExecutor(base::OnceClosure task);
// Helper methods to invoke application |callback_|.
void InvokeCallbackOnRedirectReceived();
void InvokeCallbackOnResponseStarted();
void InvokeCallbackOnReadCompleted(
std::unique_ptr<Cronet_Buffer> cronet_buffer,
int bytes_read);
void InvokeCallbackOnSucceeded();
void InvokeCallbackOnFailed();
void InvokeCallbackOnCanceled();
// Synchronize access to |request_| and other objects below from different // Synchronize access to |request_| and other objects below from different
// threads. // threads.
base::Lock lock_; base::Lock lock_;
...@@ -72,6 +89,14 @@ class Cronet_UrlRequestImpl : public Cronet_UrlRequest { ...@@ -72,6 +89,14 @@ class Cronet_UrlRequestImpl : public Cronet_UrlRequest {
// The error reported by request. May be nullptr if no error has occurred. // The error reported by request. May be nullptr if no error has occurred.
std::unique_ptr<Cronet_Error> error_; std::unique_ptr<Cronet_Error> error_;
// The upload data stream if specified.
std::unique_ptr<Cronet_UploadDataSinkImpl> upload_data_sink_;
// Application callback interface, used, but not owned, by |this|.
Cronet_UrlRequestCallbackPtr callback_ = nullptr;
// Executor for application callback, used, but not owned, by |this|.
Cronet_ExecutorPtr executor_ = nullptr;
// Cronet Engine used to run network operations. Not owned, accessed from // Cronet Engine used to run network operations. Not owned, accessed from
// client thread. Must outlive this request. // client thread. Must outlive this request.
Cronet_EngineImpl* engine_; Cronet_EngineImpl* engine_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment