Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1109)

Unified Diff: content/child/resource_dispatcher.cc

Issue 1103813002: Make WebURLLoader capable of retaining received buffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/child/resource_dispatcher.cc
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc
index baa6f6f65fccb17e223a97bcac4862c61e71c268..6089f778b1161515054a3a350dbc14902f808017 100644
--- a/content/child/resource_dispatcher.cc
+++ b/content/child/resource_dispatcher.cc
@@ -18,6 +18,7 @@
#include "base/strings/string_util.h"
#include "content/child/request_extra_data.h"
#include "content/child/request_info.h"
+#include "content/child/shared_memory_received_data_factory.h"
#include "content/child/site_isolation_policy.h"
#include "content/child/sync_load_response.h"
#include "content/child/threaded_data_provider.h"
@@ -36,6 +37,19 @@ namespace content {
namespace {
+class StringReceivedData final : public RequestPeer::ReceivedData {
+ public:
+ explicit StringReceivedData(scoped_ptr<std::string> string)
+ : string_(string.Pass()) {}
+
+ const char* payload() const override { return string_->data(); }
+ int length() const override { return string_->size(); }
+ int encoded_length() const override { return string_->size(); }
+
+ private:
+ const scoped_ptr<std::string> string_;
+};
+
// Converts |time| from a remote to local TimeTicks, overwriting the original
// value.
void RemoteToLocalTimeTicks(
@@ -191,6 +205,9 @@ void ResourceDispatcher::OnSetDataBuffer(int request_id,
request_info->buffer.reset(
new base::SharedMemory(shm_handle, true)); // read only
+ request_info->received_data_factory =
+ make_scoped_refptr(new SharedMemoryReceivedDataFactory(
+ message_sender_, request_id, request_info->buffer));
bool ok = request_info->buffer->Map(shm_size);
if (!ok) {
@@ -222,7 +239,9 @@ void ResourceDispatcher::OnReceivedData(int request_id,
// Ensure that the SHM buffer remains valid for the duration of this scope.
// It is possible for Cancel() to be called before we exit this scope.
- linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer);
+ // SharedMemoryReceivedDataFactory stores the SHM buffer inside it.
+ scoped_refptr<SharedMemoryReceivedDataFactory> factory(
+ request_info->received_data_factory);
base::TimeTicks time_start = base::TimeTicks::Now();
@@ -233,34 +252,41 @@ void ResourceDispatcher::OnReceivedData(int request_id,
// Check whether this response data is compliant with our cross-site
// document blocking policy. We only do this for the first packet.
- std::string alternative_data;
+ scoped_ptr<std::string> alternative_data;
if (request_info->site_isolation_metadata.get()) {
- request_info->blocked_response =
- SiteIsolationPolicy::ShouldBlockResponse(
- request_info->site_isolation_metadata, data_ptr, data_length,
- &alternative_data);
+ alternative_data = make_scoped_ptr(new std::string);
+ request_info->blocked_response = SiteIsolationPolicy::ShouldBlockResponse(
+ request_info->site_isolation_metadata, data_ptr, data_length,
+ alternative_data.get());
request_info->site_isolation_metadata.reset();
// When the response is blocked we may have any alternative data to
- // send to the renderer. When |alternative_data| is zero-sized, we do not
- // call peer's callback.
- if (request_info->blocked_response && !alternative_data.empty()) {
- data_ptr = alternative_data.data();
- data_length = alternative_data.size();
- encoded_data_length = alternative_data.size();
- }
+ // send to the renderer.
+ // When |alternative_data| is zero-sized, we do not call peer's callback.
+ if (alternative_data->empty())
+ alternative_data.reset();
}
- if (!request_info->blocked_response || !alternative_data.empty()) {
+ if (!request_info->blocked_response || alternative_data) {
if (request_info->threaded_data_provider) {
- request_info->threaded_data_provider->OnReceivedDataOnForegroundThread(
- data_ptr, data_length, encoded_data_length);
+ // TODO(yhirano): Use |alternative_data| when it is not null.
// A threaded data provider will take care of its own ACKing, as the
// data may be processed later on another thread.
tyoshino (SeeGerritForStatus) 2015/05/27 04:32:08 write the reason why we can stop using alternative
yhirano 2015/05/27 04:51:37 Done. Note that I don't break a working code here:
send_ack = false;
- } else {
- request_info->peer->OnReceivedData(
+ request_info->threaded_data_provider->OnReceivedDataOnForegroundThread(
data_ptr, data_length, encoded_data_length);
+ } else {
+ scoped_ptr<RequestPeer::ReceivedData> data;
+ if (alternative_data) {
+ data =
+ make_scoped_ptr(new StringReceivedData(alternative_data.Pass()));
+ } else {
+ data = factory->Create(data_offset, data_length, encoded_data_length);
+ // |data| takes care of ACKing.
+ send_ack = false;
+ }
+ if (data)
tyoshino (SeeGerritForStatus) 2015/05/27 04:32:08 Can data be null?
yhirano 2015/05/27 04:51:37 Done.
+ request_info->peer->OnReceivedData(data.Pass());
}
}
@@ -336,6 +362,9 @@ void ResourceDispatcher::OnRequestComplete(
return;
request_info->completion_time = ConsumeIOTimestamp();
request_info->buffer.reset();
+ if (request_info->received_data_factory)
+ request_info->received_data_factory->Stop();
+ request_info->received_data_factory = nullptr;
request_info->buffer_size = 0;
RequestPeer* peer = request_info->peer;

Powered by Google App Engine
This is Rietveld 408576698