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

Unified Diff: webkit/glue/webplugin_impl.cc

Issue 14122: Handle HTTP 200 responses received in response to byte range requests issued... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years 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
« no previous file with comments | « webkit/glue/webplugin_impl.h ('k') | webkit/glue/webplugin_impl_mac.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/glue/webplugin_impl.cc
===================================================================
--- webkit/glue/webplugin_impl.cc (revision 7063)
+++ webkit/glue/webplugin_impl.cc (working copy)
@@ -283,9 +283,11 @@
WebCore::Element *element,
WebFrameImpl *frame,
WebPluginDelegate* delegate,
- bool load_manually) {
+ bool load_manually,
+ const std::string& mime_type) {
WebPluginImpl* webplugin = new WebPluginImpl(element, frame, delegate, url,
- load_manually);
+ load_manually, mime_type, argc,
+ argn, argv);
if (!delegate->Initialize(url, argn, argv, argc, webplugin, load_manually)) {
delegate->PluginDestroyed();
@@ -303,7 +305,11 @@
WebFrameImpl* webframe,
WebPluginDelegate* delegate,
const GURL& plugin_url,
- bool load_manually)
+ bool load_manually,
+ const std::string& mime_type,
+ int arg_count,
+ char** arg_names,
+ char** arg_values)
: windowless_(false),
window_(NULL),
element_(element),
@@ -315,7 +321,11 @@
widget_(NULL),
plugin_url_(plugin_url),
load_manually_(load_manually),
- first_geometry_update_(true) {
+ first_geometry_update_(true),
+ mime_type_(mime_type) {
+
+ ArrayToVector(arg_count, arg_names, &arg_names_);
+ ArrayToVector(arg_count, arg_values, &arg_values_);
}
WebPluginImpl::~WebPluginImpl() {
@@ -976,6 +986,7 @@
void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle,
const WebCore::ResourceResponse& response) {
static const int kHttpPartialResponseStatusCode = 206;
+ static const int kHttpResponseSuccessStatusCode = 200;
WebPluginResourceClient* client = GetClientFromHandle(handle);
if (!client)
@@ -985,17 +996,55 @@
WebPluginContainer::ReadHttpResponseInfo(response, &http_response_info);
bool cancel = false;
+ bool request_is_seekable = true;
+ if (client->IsMultiByteResponseExpected()) {
+ if (response.httpStatusCode() == kHttpPartialResponseStatusCode) {
+ HandleHttpMultipartResponse(response, client);
+ return;
+ } else if (response.httpStatusCode() == kHttpResponseSuccessStatusCode) {
+ // If the client issued a byte range request and the server responds with
+ // HTTP 200 OK, it indicates that the server does not support byte range
+ // requests.
+ // We need to emulate Firefox behavior by doing the following:-
+ // 1. Destroy the plugin instance in the plugin process. Ensure that
+ // existing resource requests initiated for the plugin instance
+ // continue to remain valid.
+ // 2. Create a new plugin instance and notify it about the response
+ // received here.
+ if (!ReinitializePluginForResponse(handle)) {
+ NOTREACHED();
+ return;
+ }
- if (response.httpStatusCode() == kHttpPartialResponseStatusCode) {
- HandleHttpMultipartResponse(response, client);
- return;
+ // The server does not support byte range requests. No point in creating
+ // seekable streams.
+ request_is_seekable = false;
+
+ delete client;
+ client = NULL;
+
+ // Create a new resource client for this request.
+ for (size_t i = 0; i < clients_.size(); ++i) {
+ if (clients_[i].handle.get() == handle) {
+ WebPluginResourceClient* resource_client =
+ delegate_->CreateResourceClient(clients_[i].id,
+ plugin_url_.spec().c_str(),
+ NULL, false, NULL);
+ clients_[i].client = resource_client;
+ client = resource_client;
+ break;
+ }
+ }
+
+ DCHECK(client != NULL);
+ }
}
client->DidReceiveResponse(
base::SysWideToNativeMB(http_response_info.mime_type),
base::SysWideToNativeMB(GetAllHeaders(response)),
http_response_info.expected_length,
- http_response_info.last_modified, &cancel);
+ http_response_info.last_modified, request_is_seekable, &cancel);
if (cancel) {
handle->cancel();
@@ -1078,35 +1127,7 @@
void WebPluginImpl::SetContainer(WebPluginContainer* container) {
if (container == NULL) {
- // The frame maintains a list of JSObjects which are related to this
- // plugin. Tell the frame we're gone so that it can invalidate all
- // of those sub JSObjects.
- if (frame()) {
- ASSERT(widget_ != NULL);
- frame()->script()->cleanupScriptObjectsForPlugin(widget_);
- }
-
- // Call PluginDestroyed() first to prevent the plugin from calling us back
- // in the middle of tearing down the render tree.
- delegate_->PluginDestroyed();
- delegate_ = NULL;
-
- // Cancel any pending requests because otherwise this deleted object will be
- // called by the ResourceDispatcher.
- int int_offset = 0;
- while (!clients_.empty()) {
- if (clients_[int_offset].handle)
- clients_[int_offset].handle->cancel();
- WebPluginResourceClient* resource_client = clients_[int_offset].client;
- RemoveClient(int_offset);
- if (resource_client)
- resource_client->DidFail();
- }
-
- // This needs to be called now and not in the destructor since the
- // webframe_ might not be valid anymore.
- webframe_->set_plugin_delegate(NULL);
- webframe_ = NULL;
+ TearDownPluginInstance(NULL);
}
widget_ = container;
}
@@ -1315,3 +1336,109 @@
multipart_boundary);
multi_part_response_map_[client] = multi_part_response_handler;
}
+
+bool WebPluginImpl::ReinitializePluginForResponse(
+ WebCore::ResourceHandle* response_handle) {
+ WebFrameImpl* web_frame = WebFrameImpl::FromFrame(frame());
+ if (!web_frame)
+ return false;
+
+ WebViewImpl* web_view = web_frame->webview_impl();
+ if (!web_view)
+ return false;
+
+ WebPluginContainer* container_widget = widget_;
+
+ // Destroy the current plugin instance.
+ TearDownPluginInstance(response_handle);
+
+ widget_ = container_widget;
+ webframe_ = web_frame;
+ // Turn off the load_manually flag as we are going to hand data off to the
+ // plugin.
+ load_manually_ = false;
+
+ WebViewDelegate* webview_delegate = web_view->GetDelegate();
+ std::string actual_mime_type;
+ WebPluginDelegate* plugin_delegate =
+ webview_delegate->CreatePluginDelegate(web_view, plugin_url_,
+ mime_type_, std::string(),
+ &actual_mime_type);
+
+ char** arg_names = new char*[arg_names_.size()];
+ char** arg_values = new char*[arg_values_.size()];
+
+ for (unsigned int index = 0; index < arg_names_.size(); ++index) {
+ arg_names[index] = const_cast<char*>(arg_names_[index].c_str());
+ arg_values[index] = const_cast<char*>(arg_values_[index].c_str());
+ }
+
+ bool init_ok = plugin_delegate->Initialize(plugin_url_, arg_names,
+ arg_values, arg_names_.size(),
+ this, load_manually_);
+ delete[] arg_names;
+ delete[] arg_values;
+
+ if (!init_ok) {
+ SetContainer(NULL);
+ // TODO(iyengar) Should we delete the current plugin instance here?
+ return false;
+ }
+
+ mime_type_ = actual_mime_type;
+ delegate_ = plugin_delegate;
+ // Force a geometry update to occur to ensure that the plugin becomes
+ // visible.
+ widget_->frameRectsChanged();
+ delegate_->FlushGeometryUpdates();
+ return true;
+}
+
+void WebPluginImpl::ArrayToVector(int total_values, char** values,
+ std::vector<std::string>* value_vector) {
+ DCHECK(value_vector != NULL);
+ for (int index = 0; index < total_values; ++index) {
+ value_vector->push_back(values[index]);
+ }
+}
+
+void WebPluginImpl::TearDownPluginInstance(
+ WebCore::ResourceHandle* response_handle_to_ignore) {
+ // The frame maintains a list of JSObjects which are related to this
+ // plugin. Tell the frame we're gone so that it can invalidate all
+ // of those sub JSObjects.
+ if (frame()) {
+ ASSERT(widget_ != NULL);
+ frame()->script()->cleanupScriptObjectsForPlugin(widget_);
+ }
+
+ // Call PluginDestroyed() first to prevent the plugin from calling us back
+ // in the middle of tearing down the render tree.
+ delegate_->PluginDestroyed();
+ delegate_ = NULL;
+
+ // Cancel any pending requests because otherwise this deleted object will
+ // be called by the ResourceDispatcher.
+ std::vector<ClientInfo>::iterator client_index = clients_.begin();
+ while (client_index != clients_.end()) {
+ ClientInfo& client_info = *client_index;
+
+ if (response_handle_to_ignore == client_info.handle) {
+ client_index++;
+ continue;
+ }
+
+ if (client_info.handle)
+ client_info.handle->cancel();
+
+ WebPluginResourceClient* resource_client = client_info.client;
+ client_index = clients_.erase(client_index);
+ if (resource_client)
+ resource_client->DidFail();
+ }
+
+ // This needs to be called now and not in the destructor since the
+ // webframe_ might not be valid anymore.
+ webframe_->set_plugin_delegate(NULL);
+ webframe_ = NULL;
+}
« no previous file with comments | « webkit/glue/webplugin_impl.h ('k') | webkit/glue/webplugin_impl_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698