This source file includes following definitions.
- plugin_stream_
- didReceiveResponse
- didReceiveData
- pending_failure_notification_
- Cancel
- URLRedirectResponse
- OnUploadProgress
- OnReceivedRedirect
- OnReceivedResponse
- OnDownloadedData
- OnReceivedData
- OnCompletedRequest
#include "content/child/npapi/plugin_url_fetcher.h"
#include "base/memory/scoped_ptr.h"
#include "content/child/child_thread.h"
#include "content/child/npapi/plugin_host.h"
#include "content/child/npapi/plugin_instance.h"
#include "content/child/npapi/plugin_stream_url.h"
#include "content/child/npapi/webplugin.h"
#include "content/child/npapi/webplugin_resource_client.h"
#include "content/child/plugin_messages.h"
#include "content/child/request_extra_data.h"
#include "content/child/request_info.h"
#include "content/child/resource_dispatcher.h"
#include "content/child/web_url_loader_impl.h"
#include "content/common/resource_request_body.h"
#include "content/common/service_worker/service_worker_types.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "webkit/child/multipart_response_delegate.h"
#include "webkit/child/resource_loader_bridge.h"
#include "webkit/common/resource_response_info.h"
namespace content {
namespace {
class MultiPartResponseClient : public blink::WebURLLoaderClient {
public:
explicit MultiPartResponseClient(PluginStreamUrl* plugin_stream)
: byte_range_lower_bound_(0), plugin_stream_(plugin_stream) {}
virtual void didReceiveResponse(
blink::WebURLLoader* loader,
const blink::WebURLResponse& response) OVERRIDE {
int64 byte_range_upper_bound, instance_size;
if (!webkit_glue::MultipartResponseDelegate::ReadContentRanges(
response, &byte_range_lower_bound_, &byte_range_upper_bound,
&instance_size)) {
NOTREACHED();
}
}
virtual void didReceiveData(blink::WebURLLoader* loader,
const char* data,
int data_length,
int encoded_data_length) OVERRIDE {
int64 data_offset = byte_range_lower_bound_;
byte_range_lower_bound_ += data_length;
plugin_stream_->DidReceiveData(data, data_length, data_offset);
}
private:
int64 byte_range_lower_bound_;
PluginStreamUrl* plugin_stream_;
};
}
PluginURLFetcher::PluginURLFetcher(PluginStreamUrl* plugin_stream,
const GURL& url,
const GURL& first_party_for_cookies,
const std::string& method,
const char* buf,
unsigned int len,
const GURL& referrer,
const std::string& range,
bool notify_redirects,
bool is_plugin_src_load,
int origin_pid,
int render_frame_id,
int render_view_id,
unsigned long resource_id,
bool copy_stream_data)
: plugin_stream_(plugin_stream),
url_(url),
first_party_for_cookies_(first_party_for_cookies),
method_(method),
referrer_(referrer),
notify_redirects_(notify_redirects),
is_plugin_src_load_(is_plugin_src_load),
origin_pid_(origin_pid),
render_frame_id_(render_frame_id),
render_view_id_(render_view_id),
resource_id_(resource_id),
copy_stream_data_(copy_stream_data),
data_offset_(0),
pending_failure_notification_(false) {
RequestInfo request_info;
request_info.method = method;
request_info.url = url;
request_info.first_party_for_cookies = first_party_for_cookies;
request_info.referrer = referrer;
request_info.load_flags = net::LOAD_NORMAL;
request_info.requestor_pid = origin_pid;
request_info.request_type = ResourceType::OBJECT;
request_info.routing_id = render_view_id;
RequestExtraData extra_data;
extra_data.set_render_frame_id(render_frame_id);
extra_data.set_is_main_frame(false);
request_info.extra_data = &extra_data;
std::vector<char> body;
if (method == "POST") {
bool content_type_found = false;
std::vector<std::string> names;
std::vector<std::string> values;
PluginHost::SetPostData(buf, len, &names, &values, &body);
for (size_t i = 0; i < names.size(); ++i) {
if (!request_info.headers.empty())
request_info.headers += "\r\n";
request_info.headers += names[i] + ": " + values[i];
if (LowerCaseEqualsASCII(names[i], "content-type"))
content_type_found = true;
}
if (!content_type_found) {
if (!request_info.headers.empty())
request_info.headers += "\r\n";
request_info.headers += "Content-Type: application/x-www-form-urlencoded";
}
} else {
if (!range.empty())
request_info.headers = std::string("Range: ") + range;
}
bridge_.reset(ChildThread::current()->resource_dispatcher()->CreateBridge(
request_info));
if (!body.empty()) {
scoped_refptr<ResourceRequestBody> request_body =
new ResourceRequestBody;
request_body->AppendBytes(&body[0], body.size());
bridge_->SetRequestBody(request_body.get());
}
bridge_->Start(this);
}
PluginURLFetcher::~PluginURLFetcher() {
}
void PluginURLFetcher::Cancel() {
bridge_->Cancel();
if (multipart_delegate_)
multipart_delegate_->Cancel();
plugin_stream_ = NULL;
}
void PluginURLFetcher::URLRedirectResponse(bool allow) {
if (!plugin_stream_)
return;
if (allow) {
bridge_->SetDefersLoading(false);
} else {
bridge_->Cancel();
plugin_stream_->DidFail(resource_id_);
}
}
void PluginURLFetcher::OnUploadProgress(uint64 position, uint64 size) {
}
bool PluginURLFetcher::OnReceivedRedirect(
const GURL& new_url,
const webkit_glue::ResourceResponseInfo& info,
bool* has_new_first_party_for_cookies,
GURL* new_first_party_for_cookies) {
if (!plugin_stream_)
return false;
if (is_plugin_src_load_ &&
!plugin_stream_->instance()->webplugin()->CheckIfRunInsecureContent(
new_url)) {
plugin_stream_->DidFail(resource_id_);
return false;
}
int response_code = info.headers->response_code();
if (response_code != 307)
method_ = "GET";
GURL old_url = url_;
url_ = new_url;
*has_new_first_party_for_cookies = true;
*new_first_party_for_cookies = first_party_for_cookies_;
if (!notify_redirects_) {
if (response_code == 307 && method_ == "POST" &&
old_url.GetOrigin() != new_url.GetOrigin()) {
plugin_stream_->DidFail(resource_id_);
return false;
}
} else {
bridge_->SetDefersLoading(true);
plugin_stream_->WillSendRequest(url_, response_code);
}
return true;
}
void PluginURLFetcher::OnReceivedResponse(
const webkit_glue::ResourceResponseInfo& info) {
if (!plugin_stream_)
return;
bool request_is_seekable = true;
DCHECK(!multipart_delegate_.get());
if (plugin_stream_->seekable()) {
int response_code = info.headers->response_code();
if (response_code == 206) {
blink::WebURLResponse response;
response.initialize();
WebURLLoaderImpl::PopulateURLResponse(url_, info, &response);
std::string multipart_boundary;
if (webkit_glue::MultipartResponseDelegate::ReadMultipartBoundary(
response, &multipart_boundary)) {
plugin_stream_->instance()->webplugin()->DidStartLoading();
MultiPartResponseClient* multi_part_response_client =
new MultiPartResponseClient(plugin_stream_);
multipart_delegate_.reset(new webkit_glue::MultipartResponseDelegate(
multi_part_response_client, NULL, response, multipart_boundary));
data_offset_ = 0;
return;
}
int64 upper_bound = 0, instance_size = 0;
webkit_glue::MultipartResponseDelegate::ReadContentRanges(
response, &data_offset_, &upper_bound, &instance_size);
} else if (response_code == 200) {
}
}
int expected_length = std::max(static_cast<int>(info.content_length), 0);
base::Time temp;
uint32 last_modified = 0;
std::string headers;
if (info.headers) {
if (info.headers->GetLastModifiedValue(&temp))
last_modified = static_cast<uint32>(temp.ToDoubleT());
int response_code = info.headers->response_code();
headers = base::StringPrintf("HTTP %d ", response_code);
headers += info.headers->GetStatusText();
headers += "\n";
void* iter = NULL;
std::string name, value;
while (info.headers->EnumerateHeaderLines(&iter, &name, &value)) {
if (!name.empty() && !value.empty())
headers += name + ": " + value + "\n";
}
if ((url_.SchemeIs("http") || url_.SchemeIs("https")) &&
(response_code < 100 || response_code >= 400)) {
pending_failure_notification_ = true;
}
}
plugin_stream_->DidReceiveResponse(info.mime_type,
headers,
expected_length,
last_modified,
request_is_seekable);
}
void PluginURLFetcher::OnDownloadedData(int len,
int encoded_data_length) {
}
void PluginURLFetcher::OnReceivedData(const char* data,
int data_length,
int encoded_data_length) {
if (!plugin_stream_)
return;
if (multipart_delegate_) {
multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length);
} else {
int64 offset = data_offset_;
data_offset_ += data_length;
if (copy_stream_data_) {
scoped_ptr<char[]> data_copy(new char[data_length]);
memcpy(data_copy.get(), data, data_length);
plugin_stream_->DidReceiveData(data_copy.get(), data_length, offset);
} else {
plugin_stream_->DidReceiveData(data, data_length, offset);
}
}
}
void PluginURLFetcher::OnCompletedRequest(
int error_code,
bool was_ignored_by_handler,
bool stale_copy_in_cache,
const std::string& security_info,
const base::TimeTicks& completion_time,
int64 total_transfer_size) {
if (!plugin_stream_)
return;
if (multipart_delegate_) {
multipart_delegate_->OnCompletedRequest();
multipart_delegate_.reset();
}
if (error_code == net::OK) {
plugin_stream_->DidFinishLoading(resource_id_);
} else {
plugin_stream_->DidFail(resource_id_);
}
}
}