summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/resource_handle_impl.cc9
-rw-r--r--webkit/glue/resource_loader_bridge.h2
-rw-r--r--webkit/tools/test_shell/simple_resource_loader_bridge.cc59
3 files changed, 68 insertions, 2 deletions
diff --git a/webkit/glue/resource_handle_impl.cc b/webkit/glue/resource_handle_impl.cc
index dbc8606..961e788 100644
--- a/webkit/glue/resource_handle_impl.cc
+++ b/webkit/glue/resource_handle_impl.cc
@@ -222,6 +222,7 @@ class ResourceHandleInternal : public ResourceLoaderBridge::Peer {
void SetDefersLoading(bool value);
// ResourceLoaderBridge::Peer implementation
+ virtual void OnUploadProgress(uint64 position, uint64 size);
virtual void OnReceivedRedirect(const GURL& new_url);
virtual void OnReceivedResponse(
const ResourceLoaderBridge::ResponseInfo& info,
@@ -358,6 +359,9 @@ bool ResourceHandleInternal::Start(
break;
}
+ if (request_.reportUploadProgress())
+ load_flags_ |= net::LOAD_ENABLE_UPLOAD_PROGRESS;
+
// Translate the table of request headers to a formatted string blob
String headerBuf;
const HTTPHeaderMap& headerMap = request_.httpHeaderFields();
@@ -511,6 +515,11 @@ void ResourceHandleInternal::SetDefersLoading(bool value) {
// ResourceLoaderBridge::Peer impl --------------------------------------------
+void ResourceHandleInternal::OnUploadProgress(uint64 position, uint64 size) {
+ if (client_)
+ client_->didSendData(job_, position, size);
+}
+
void ResourceHandleInternal::OnReceivedRedirect(const GURL& new_url) {
DCHECK(pending_);
diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h
index d5ca181..8d32f0c 100644
--- a/webkit/glue/resource_loader_bridge.h
+++ b/webkit/glue/resource_loader_bridge.h
@@ -93,7 +93,7 @@ class ResourceLoaderBridge {
// Called as upload progress is made.
// note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set
- virtual void OnUploadProgress(uint64 position, uint64 size) {};
+ virtual void OnUploadProgress(uint64 position, uint64 size) = 0;
// Called when a redirect occurs.
virtual void OnReceivedRedirect(const GURL& new_url) = 0;
diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
index 2e94f3f..0c10c966 100644
--- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc
+++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
@@ -34,10 +34,12 @@
#include "base/message_loop.h"
#include "base/ref_counted.h"
+#include "base/time.h"
#include "base/thread.h"
#include "base/waitable_event.h"
#include "net/base/cookie_monster.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
#include "net/base/net_util.h"
#include "net/base/upload_data.h"
#include "net/http/http_response_headers.h"
@@ -100,6 +102,9 @@ struct RequestParams {
scoped_refptr<net::UploadData> upload;
};
+// The interval for calls to RequestProxy::MaybeUpdateUploadProgress
+static const int kUpdateUploadProgressIntervalMsec = 100;
+
// The RequestProxy does most of its work on the IO thread. The Start and
// Cancel methods are proxied over to the IO thread, where an URLRequest object
// is instantiated.
@@ -107,7 +112,9 @@ class RequestProxy : public URLRequest::Delegate,
public base::RefCountedThreadSafe<RequestProxy> {
public:
// Takes ownership of the params.
- RequestProxy() : buf_(new net::IOBuffer(kDataSize)) {
+ RequestProxy()
+ : buf_(new net::IOBuffer(kDataSize)),
+ last_upload_position_(0) {
}
virtual ~RequestProxy() {
@@ -181,6 +188,11 @@ class RequestProxy : public URLRequest::Delegate,
}
}
+ void NotifyUploadProgress(uint64 position, uint64 size) {
+ if (peer_)
+ peer_->OnUploadProgress(position, size);
+ }
+
// --------------------------------------------------------------------------
// The following methods are called on the io thread. They correspond to
// actions performed on the owner's thread.
@@ -196,6 +208,13 @@ class RequestProxy : public URLRequest::Delegate,
request_->set_context(request_context);
request_->Start();
+ if (request_->has_upload() &&
+ params->load_flags & net::LOAD_ENABLE_UPLOAD_PROGRESS) {
+ upload_progress_timer_.Start(
+ base::TimeDelta::FromMilliseconds(kUpdateUploadProgressIntervalMsec),
+ this, &RequestProxy::MaybeUpdateUploadProgress);
+ }
+
delete params;
}
@@ -290,11 +309,42 @@ class RequestProxy : public URLRequest::Delegate,
// Helpers and data:
void Done() {
+ if (upload_progress_timer_.IsRunning()) {
+ MaybeUpdateUploadProgress();
+ upload_progress_timer_.Stop();
+ }
DCHECK(request_.get());
OnCompletedRequest(request_->status(), std::string());
request_.reset(); // destroy on the io thread
}
+ // Called on the IO thread.
+ void MaybeUpdateUploadProgress() {
+ uint64 size = request_->get_upload()->GetContentLength();
+ uint64 position = request_->GetUploadProgress();
+ if (position == last_upload_position_)
+ return; // no progress made since last time
+
+ const uint64 kHalfPercentIncrements = 200;
+ const base::TimeDelta kOneSecond = base::TimeDelta::FromMilliseconds(1000);
+
+ uint64 amt_since_last = position - last_upload_position_;
+ base::TimeDelta time_since_last = base::TimeTicks::Now() -
+ last_upload_ticks_;
+
+ bool is_finished = (size == position);
+ bool enough_new_progress = (amt_since_last > (size /
+ kHalfPercentIncrements));
+ bool too_much_time_passed = time_since_last > kOneSecond;
+
+ if (is_finished || enough_new_progress || too_much_time_passed) {
+ owner_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &RequestProxy::NotifyUploadProgress, position, size));
+ last_upload_ticks_ = base::TimeTicks::Now();
+ last_upload_position_ = position;
+ }
+ }
+
scoped_ptr<URLRequest> request_;
// Size of our async IO data buffers
@@ -309,6 +359,13 @@ class RequestProxy : public URLRequest::Delegate,
// not manage its lifetime, and we may only access it from the owner's
// message loop (owner_loop_).
ResourceLoaderBridge::Peer* peer_;
+
+ // Timer used to pull upload progress info.
+ base::RepeatingTimer<RequestProxy> upload_progress_timer_;
+
+ // Info used to determine whether or not to send an upload progress update.
+ uint64 last_upload_position_;
+ base::TimeTicks last_upload_ticks_;
};
//-----------------------------------------------------------------------------