Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / cronet / android / url_request_adapter.cc
index 9d9e29b..8b2df90 100644 (file)
@@ -9,11 +9,15 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/cronet/android/url_request_context_adapter.h"
 #include "components/cronet/android/wrapped_channel_upload_element_reader.h"
+#include "net/base/elements_upload_data_stream.h"
 #include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
 #include "net/base/upload_bytes_element_reader.h"
+#include "net/http/http_response_headers.h"
 #include "net/http/http_status_code.h"
 
 namespace cronet {
@@ -32,7 +36,8 @@ URLRequestAdapter::URLRequestAdapter(URLRequestContextAdapter* context,
       http_status_code_(0),
       canceled_(false),
       expected_size_(0),
-      chunked_upload_(false) {
+      chunked_upload_(false),
+      disable_redirect_(false) {
   context_ = context;
   delegate_ = delegate;
   url_ = url;
@@ -40,6 +45,7 @@ URLRequestAdapter::URLRequestAdapter(URLRequestContextAdapter* context,
 }
 
 URLRequestAdapter::~URLRequestAdapter() {
+  DCHECK(OnNetworkThread());
   CHECK(url_request_ == NULL);
 }
 
@@ -56,15 +62,19 @@ void URLRequestAdapter::SetUploadContent(const char* bytes, int bytes_len) {
   std::vector<char> data(bytes, bytes + bytes_len);
   scoped_ptr<net::UploadElementReader> reader(
       new net::UploadOwnedBytesElementReader(&data));
-  upload_data_stream_.reset(
-      net::UploadDataStream::CreateWithReader(reader.Pass(), 0));
+  upload_data_stream_ =
+      net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0);
 }
 
 void URLRequestAdapter::SetUploadChannel(JNIEnv* env, int64 content_length) {
   scoped_ptr<net::UploadElementReader> reader(
       new WrappedChannelElementReader(delegate_, content_length));
-  upload_data_stream_.reset(
-      net::UploadDataStream::CreateWithReader(reader.Pass(), 0));
+  upload_data_stream_ =
+      net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0);
+}
+
+void URLRequestAdapter::DisableRedirects() {
+  disable_redirect_ = true;
 }
 
 void URLRequestAdapter::EnableChunkedUpload() {
@@ -76,7 +86,7 @@ void URLRequestAdapter::AppendChunk(const char* bytes, int bytes_len,
   VLOG(1) << "AppendChunk, len: " << bytes_len << ", last: " << is_last_chunk;
   scoped_ptr<char[]> buf(new char[bytes_len]);
   memcpy(buf.get(), bytes, bytes_len);
-  context_->GetNetworkTaskRunner()->PostTask(
+  context_->PostTaskToNetworkThread(
       FROM_HERE,
       base::Bind(&URLRequestAdapter::OnAppendChunk,
                  base::Unretained(this),
@@ -107,7 +117,7 @@ std::string URLRequestAdapter::GetNegotiatedProtocol() const {
 }
 
 void URLRequestAdapter::Start() {
-  context_->GetNetworkTaskRunner()->PostTask(
+  context_->PostTaskToNetworkThread(
       FROM_HERE,
       base::Bind(&URLRequestAdapter::OnInitiateConnection,
                  base::Unretained(this)));
@@ -115,10 +125,12 @@ void URLRequestAdapter::Start() {
 
 void URLRequestAdapter::OnAppendChunk(const scoped_ptr<char[]> bytes,
                                       int bytes_len, bool is_last_chunk) {
+  DCHECK(OnNetworkThread());
   url_request_->AppendChunkToUpload(bytes.get(), bytes_len, is_last_chunk);
 }
 
 void URLRequestAdapter::OnInitiateConnection() {
+  DCHECK(OnNetworkThread());
   if (canceled_) {
     return;
   }
@@ -158,12 +170,13 @@ void URLRequestAdapter::Cancel() {
 
   canceled_ = true;
 
-  context_->GetNetworkTaskRunner()->PostTask(
+  context_->PostTaskToNetworkThread(
       FROM_HERE,
       base::Bind(&URLRequestAdapter::OnCancelRequest, base::Unretained(this)));
 }
 
 void URLRequestAdapter::OnCancelRequest() {
+  DCHECK(OnNetworkThread());
   VLOG(1) << "Canceling chromium request: " << url_.possibly_invalid_spec();
 
   if (url_request_ != NULL) {
@@ -174,18 +187,21 @@ void URLRequestAdapter::OnCancelRequest() {
 }
 
 void URLRequestAdapter::Destroy() {
-  context_->GetNetworkTaskRunner()->PostTask(
+  context_->PostTaskToNetworkThread(
       FROM_HERE, base::Bind(&URLRequestAdapter::OnDestroyRequest, this));
 }
 
 // static
 void URLRequestAdapter::OnDestroyRequest(URLRequestAdapter* self) {
+  DCHECK(self->OnNetworkThread());
   VLOG(1) << "Destroying chromium request: "
           << self->url_.possibly_invalid_spec();
   delete self;
 }
 
+// static
 void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) {
+  DCHECK(OnNetworkThread());
   if (request->status().status() != net::URLRequestStatus::SUCCESS) {
     OnRequestFailed();
     return;
@@ -194,6 +210,10 @@ void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) {
   http_status_code_ = request->GetResponseCode();
   VLOG(1) << "Response started with status: " << http_status_code_;
 
+  net::HttpResponseHeaders* headers = request->response_headers();
+  if (headers)
+    http_status_text_ = headers->GetStatusText();
+
   request->GetResponseHeaderByName("Content-Type", &content_type_);
   expected_size_ = request->GetExpectedContentSize();
   delegate_->OnResponseStarted(this);
@@ -203,6 +223,7 @@ void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) {
 
 // Reads all available data or starts an asynchronous read.
 void URLRequestAdapter::Read() {
+  DCHECK(OnNetworkThread());
   while (true) {
     if (read_buffer_->RemainingCapacity() == 0) {
       int new_capacity = read_buffer_->capacity() + kBufferSizeIncrement;
@@ -210,8 +231,9 @@ void URLRequestAdapter::Read() {
     }
 
     int bytes_read;
-    if (url_request_->Read(
-            read_buffer_, read_buffer_->RemainingCapacity(), &bytes_read)) {
+    if (url_request_->Read(read_buffer_.get(),
+                           read_buffer_->RemainingCapacity(),
+                           &bytes_read)) {
       if (bytes_read == 0) {
         OnRequestSucceeded();
         break;
@@ -239,6 +261,7 @@ void URLRequestAdapter::Read() {
 
 void URLRequestAdapter::OnReadCompleted(net::URLRequest* request,
                                         int bytes_read) {
+  DCHECK(OnNetworkThread());
   VLOG(1) << "Asynchronously read: " << bytes_read << " bytes";
   if (bytes_read < 0) {
     OnRequestFailed();
@@ -252,13 +275,29 @@ void URLRequestAdapter::OnReadCompleted(net::URLRequest* request,
   Read();
 }
 
+void URLRequestAdapter::OnReceivedRedirect(net::URLRequest* request,
+                                           const net::RedirectInfo& info,
+                                           bool* defer_redirect) {
+  DCHECK(OnNetworkThread());
+  if (disable_redirect_) {
+    http_status_code_ = request->GetResponseCode();
+    request->CancelWithError(net::ERR_TOO_MANY_REDIRECTS);
+    error_code_ = net::ERR_TOO_MANY_REDIRECTS;
+    canceled_ = true;
+    *defer_redirect = false;
+    OnRequestCompleted();
+  }
+}
+
 void URLRequestAdapter::OnBytesRead(int bytes_read) {
+  DCHECK(OnNetworkThread());
   read_buffer_->set_offset(read_buffer_->offset() + bytes_read);
   bytes_read_ += bytes_read;
   total_bytes_read_ += bytes_read;
 }
 
 void URLRequestAdapter::OnRequestSucceeded() {
+  DCHECK(OnNetworkThread());
   if (canceled_) {
     return;
   }
@@ -270,6 +309,7 @@ void URLRequestAdapter::OnRequestSucceeded() {
 }
 
 void URLRequestAdapter::OnRequestFailed() {
+  DCHECK(OnNetworkThread());
   if (canceled_) {
     return;
   }
@@ -281,19 +321,26 @@ void URLRequestAdapter::OnRequestFailed() {
 }
 
 void URLRequestAdapter::OnRequestCanceled() {
+  DCHECK(OnNetworkThread());
   OnRequestCompleted();
 }
 
 void URLRequestAdapter::OnRequestCompleted() {
+  DCHECK(OnNetworkThread());
   VLOG(1) << "Completed: " << url_.possibly_invalid_spec();
-  url_request_.reset();
 
   delegate_->OnBytesRead(this);
   delegate_->OnRequestFinished(this);
+  url_request_.reset();
 }
 
 unsigned char* URLRequestAdapter::Data() const {
+  DCHECK(OnNetworkThread());
   return reinterpret_cast<unsigned char*>(read_buffer_->StartOfBuffer());
 }
 
+bool URLRequestAdapter::OnNetworkThread() const {
+  return context_->GetNetworkTaskRunner()->BelongsToCurrentThread();
+}
+
 }  // namespace cronet