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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/webplugin_impl.h ('k') | webkit/glue/webplugin_impl_mac.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 9
10 MSVC_PUSH_WARNING_LEVEL(0); 10 MSVC_PUSH_WARNING_LEVEL(0);
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 276 }
277 } 277 }
278 278
279 WebCore::Widget* WebPluginImpl::Create(const GURL& url, 279 WebCore::Widget* WebPluginImpl::Create(const GURL& url,
280 char** argn, 280 char** argn,
281 char** argv, 281 char** argv,
282 int argc, 282 int argc,
283 WebCore::Element *element, 283 WebCore::Element *element,
284 WebFrameImpl *frame, 284 WebFrameImpl *frame,
285 WebPluginDelegate* delegate, 285 WebPluginDelegate* delegate,
286 bool load_manually) { 286 bool load_manually,
287 const std::string& mime_type) {
287 WebPluginImpl* webplugin = new WebPluginImpl(element, frame, delegate, url, 288 WebPluginImpl* webplugin = new WebPluginImpl(element, frame, delegate, url,
288 load_manually); 289 load_manually, mime_type, argc,
290 argn, argv);
289 291
290 if (!delegate->Initialize(url, argn, argv, argc, webplugin, load_manually)) { 292 if (!delegate->Initialize(url, argn, argv, argc, webplugin, load_manually)) {
291 delegate->PluginDestroyed(); 293 delegate->PluginDestroyed();
292 delegate = NULL; 294 delegate = NULL;
293 delete webplugin; 295 delete webplugin;
294 return NULL; 296 return NULL;
295 } 297 }
296 298
297 WebPluginContainer* container = new WebPluginContainer(webplugin); 299 WebPluginContainer* container = new WebPluginContainer(webplugin);
298 webplugin->SetContainer(container); 300 webplugin->SetContainer(container);
299 return container; 301 return container;
300 } 302 }
301 303
302 WebPluginImpl::WebPluginImpl(WebCore::Element* element, 304 WebPluginImpl::WebPluginImpl(WebCore::Element* element,
303 WebFrameImpl* webframe, 305 WebFrameImpl* webframe,
304 WebPluginDelegate* delegate, 306 WebPluginDelegate* delegate,
305 const GURL& plugin_url, 307 const GURL& plugin_url,
306 bool load_manually) 308 bool load_manually,
309 const std::string& mime_type,
310 int arg_count,
311 char** arg_names,
312 char** arg_values)
307 : windowless_(false), 313 : windowless_(false),
308 window_(NULL), 314 window_(NULL),
309 element_(element), 315 element_(element),
310 webframe_(webframe), 316 webframe_(webframe),
311 delegate_(delegate), 317 delegate_(delegate),
312 force_geometry_update_(false), 318 force_geometry_update_(false),
313 visible_(false), 319 visible_(false),
314 received_first_paint_notification_(false), 320 received_first_paint_notification_(false),
315 widget_(NULL), 321 widget_(NULL),
316 plugin_url_(plugin_url), 322 plugin_url_(plugin_url),
317 load_manually_(load_manually), 323 load_manually_(load_manually),
318 first_geometry_update_(true) { 324 first_geometry_update_(true),
325 mime_type_(mime_type) {
326
327 ArrayToVector(arg_count, arg_names, &arg_names_);
328 ArrayToVector(arg_count, arg_values, &arg_values_);
319 } 329 }
320 330
321 WebPluginImpl::~WebPluginImpl() { 331 WebPluginImpl::~WebPluginImpl() {
322 } 332 }
323 333
324 void WebPluginImpl::SetWindow(HWND window, HANDLE pump_messages_event) { 334 void WebPluginImpl::SetWindow(HWND window, HANDLE pump_messages_event) {
325 if (window) { 335 if (window) {
326 DCHECK(!windowless_); // Make sure not called twice. 336 DCHECK(!windowless_); // Make sure not called twice.
327 window_ = window; 337 window_ = window;
328 } else { 338 } else {
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 result.append(L"\n"); 979 result.append(L"\n");
970 } 980 }
971 } 981 }
972 982
973 return result; 983 return result;
974 } 984 }
975 985
976 void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle, 986 void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle,
977 const WebCore::ResourceResponse& response) { 987 const WebCore::ResourceResponse& response) {
978 static const int kHttpPartialResponseStatusCode = 206; 988 static const int kHttpPartialResponseStatusCode = 206;
989 static const int kHttpResponseSuccessStatusCode = 200;
979 990
980 WebPluginResourceClient* client = GetClientFromHandle(handle); 991 WebPluginResourceClient* client = GetClientFromHandle(handle);
981 if (!client) 992 if (!client)
982 return; 993 return;
983 994
984 WebPluginContainer::HttpResponseInfo http_response_info; 995 WebPluginContainer::HttpResponseInfo http_response_info;
985 WebPluginContainer::ReadHttpResponseInfo(response, &http_response_info); 996 WebPluginContainer::ReadHttpResponseInfo(response, &http_response_info);
986 997
987 bool cancel = false; 998 bool cancel = false;
999 bool request_is_seekable = true;
1000 if (client->IsMultiByteResponseExpected()) {
1001 if (response.httpStatusCode() == kHttpPartialResponseStatusCode) {
1002 HandleHttpMultipartResponse(response, client);
1003 return;
1004 } else if (response.httpStatusCode() == kHttpResponseSuccessStatusCode) {
1005 // If the client issued a byte range request and the server responds with
1006 // HTTP 200 OK, it indicates that the server does not support byte range
1007 // requests.
1008 // We need to emulate Firefox behavior by doing the following:-
1009 // 1. Destroy the plugin instance in the plugin process. Ensure that
1010 // existing resource requests initiated for the plugin instance
1011 // continue to remain valid.
1012 // 2. Create a new plugin instance and notify it about the response
1013 // received here.
1014 if (!ReinitializePluginForResponse(handle)) {
1015 NOTREACHED();
1016 return;
1017 }
988 1018
989 if (response.httpStatusCode() == kHttpPartialResponseStatusCode) { 1019 // The server does not support byte range requests. No point in creating
990 HandleHttpMultipartResponse(response, client); 1020 // seekable streams.
991 return; 1021 request_is_seekable = false;
1022
1023 delete client;
1024 client = NULL;
1025
1026 // Create a new resource client for this request.
1027 for (size_t i = 0; i < clients_.size(); ++i) {
1028 if (clients_[i].handle.get() == handle) {
1029 WebPluginResourceClient* resource_client =
1030 delegate_->CreateResourceClient(clients_[i].id,
1031 plugin_url_.spec().c_str(),
1032 NULL, false, NULL);
1033 clients_[i].client = resource_client;
1034 client = resource_client;
1035 break;
1036 }
1037 }
1038
1039 DCHECK(client != NULL);
1040 }
992 } 1041 }
993 1042
994 client->DidReceiveResponse( 1043 client->DidReceiveResponse(
995 base::SysWideToNativeMB(http_response_info.mime_type), 1044 base::SysWideToNativeMB(http_response_info.mime_type),
996 base::SysWideToNativeMB(GetAllHeaders(response)), 1045 base::SysWideToNativeMB(GetAllHeaders(response)),
997 http_response_info.expected_length, 1046 http_response_info.expected_length,
998 http_response_info.last_modified, &cancel); 1047 http_response_info.last_modified, request_is_seekable, &cancel);
999 1048
1000 if (cancel) { 1049 if (cancel) {
1001 handle->cancel(); 1050 handle->cancel();
1002 RemoveClient(handle); 1051 RemoveClient(handle);
1003 return; 1052 return;
1004 } 1053 }
1005 1054
1006 // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP 1055 // Bug http://b/issue?id=925559. The flash plugin would not handle the HTTP
1007 // error codes in the stream header and as a result, was unaware of the 1056 // error codes in the stream header and as a result, was unaware of the
1008 // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF 1057 // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 for (size_t i = 0; i < clients_.size(); ++i) { 1120 for (size_t i = 0; i < clients_.size(); ++i) {
1072 if (clients_[i].handle.get() == handle) { 1121 if (clients_[i].handle.get() == handle) {
1073 RemoveClient(i); 1122 RemoveClient(i);
1074 return; 1123 return;
1075 } 1124 }
1076 } 1125 }
1077 } 1126 }
1078 1127
1079 void WebPluginImpl::SetContainer(WebPluginContainer* container) { 1128 void WebPluginImpl::SetContainer(WebPluginContainer* container) {
1080 if (container == NULL) { 1129 if (container == NULL) {
1081 // The frame maintains a list of JSObjects which are related to this 1130 TearDownPluginInstance(NULL);
1082 // plugin. Tell the frame we're gone so that it can invalidate all
1083 // of those sub JSObjects.
1084 if (frame()) {
1085 ASSERT(widget_ != NULL);
1086 frame()->script()->cleanupScriptObjectsForPlugin(widget_);
1087 }
1088
1089 // Call PluginDestroyed() first to prevent the plugin from calling us back
1090 // in the middle of tearing down the render tree.
1091 delegate_->PluginDestroyed();
1092 delegate_ = NULL;
1093
1094 // Cancel any pending requests because otherwise this deleted object will be
1095 // called by the ResourceDispatcher.
1096 int int_offset = 0;
1097 while (!clients_.empty()) {
1098 if (clients_[int_offset].handle)
1099 clients_[int_offset].handle->cancel();
1100 WebPluginResourceClient* resource_client = clients_[int_offset].client;
1101 RemoveClient(int_offset);
1102 if (resource_client)
1103 resource_client->DidFail();
1104 }
1105
1106 // This needs to be called now and not in the destructor since the
1107 // webframe_ might not be valid anymore.
1108 webframe_->set_plugin_delegate(NULL);
1109 webframe_ = NULL;
1110 } 1131 }
1111 widget_ = container; 1132 widget_ = container;
1112 } 1133 }
1113 1134
1114 WebCore::ScrollView* WebPluginImpl::parent() const { 1135 WebCore::ScrollView* WebPluginImpl::parent() const {
1115 if (widget_) 1136 if (widget_)
1116 return widget_->parent(); 1137 return widget_->parent();
1117 1138
1118 return NULL; 1139 return NULL;
1119 } 1140 }
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 1329
1309 MultiPartResponseClient* multi_part_response_client = 1330 MultiPartResponseClient* multi_part_response_client =
1310 new MultiPartResponseClient(client); 1331 new MultiPartResponseClient(client);
1311 1332
1312 MultipartResponseDelegate* multi_part_response_handler = 1333 MultipartResponseDelegate* multi_part_response_handler =
1313 new MultipartResponseDelegate(multi_part_response_client, NULL, 1334 new MultipartResponseDelegate(multi_part_response_client, NULL,
1314 response, 1335 response,
1315 multipart_boundary); 1336 multipart_boundary);
1316 multi_part_response_map_[client] = multi_part_response_handler; 1337 multi_part_response_map_[client] = multi_part_response_handler;
1317 } 1338 }
1339
1340 bool WebPluginImpl::ReinitializePluginForResponse(
1341 WebCore::ResourceHandle* response_handle) {
1342 WebFrameImpl* web_frame = WebFrameImpl::FromFrame(frame());
1343 if (!web_frame)
1344 return false;
1345
1346 WebViewImpl* web_view = web_frame->webview_impl();
1347 if (!web_view)
1348 return false;
1349
1350 WebPluginContainer* container_widget = widget_;
1351
1352 // Destroy the current plugin instance.
1353 TearDownPluginInstance(response_handle);
1354
1355 widget_ = container_widget;
1356 webframe_ = web_frame;
1357 // Turn off the load_manually flag as we are going to hand data off to the
1358 // plugin.
1359 load_manually_ = false;
1360
1361 WebViewDelegate* webview_delegate = web_view->GetDelegate();
1362 std::string actual_mime_type;
1363 WebPluginDelegate* plugin_delegate =
1364 webview_delegate->CreatePluginDelegate(web_view, plugin_url_,
1365 mime_type_, std::string(),
1366 &actual_mime_type);
1367
1368 char** arg_names = new char*[arg_names_.size()];
1369 char** arg_values = new char*[arg_values_.size()];
1370
1371 for (unsigned int index = 0; index < arg_names_.size(); ++index) {
1372 arg_names[index] = const_cast<char*>(arg_names_[index].c_str());
1373 arg_values[index] = const_cast<char*>(arg_values_[index].c_str());
1374 }
1375
1376 bool init_ok = plugin_delegate->Initialize(plugin_url_, arg_names,
1377 arg_values, arg_names_.size(),
1378 this, load_manually_);
1379 delete[] arg_names;
1380 delete[] arg_values;
1381
1382 if (!init_ok) {
1383 SetContainer(NULL);
1384 // TODO(iyengar) Should we delete the current plugin instance here?
1385 return false;
1386 }
1387
1388 mime_type_ = actual_mime_type;
1389 delegate_ = plugin_delegate;
1390 // Force a geometry update to occur to ensure that the plugin becomes
1391 // visible.
1392 widget_->frameRectsChanged();
1393 delegate_->FlushGeometryUpdates();
1394 return true;
1395 }
1396
1397 void WebPluginImpl::ArrayToVector(int total_values, char** values,
1398 std::vector<std::string>* value_vector) {
1399 DCHECK(value_vector != NULL);
1400 for (int index = 0; index < total_values; ++index) {
1401 value_vector->push_back(values[index]);
1402 }
1403 }
1404
1405 void WebPluginImpl::TearDownPluginInstance(
1406 WebCore::ResourceHandle* response_handle_to_ignore) {
1407 // The frame maintains a list of JSObjects which are related to this
1408 // plugin. Tell the frame we're gone so that it can invalidate all
1409 // of those sub JSObjects.
1410 if (frame()) {
1411 ASSERT(widget_ != NULL);
1412 frame()->script()->cleanupScriptObjectsForPlugin(widget_);
1413 }
1414
1415 // Call PluginDestroyed() first to prevent the plugin from calling us back
1416 // in the middle of tearing down the render tree.
1417 delegate_->PluginDestroyed();
1418 delegate_ = NULL;
1419
1420 // Cancel any pending requests because otherwise this deleted object will
1421 // be called by the ResourceDispatcher.
1422 std::vector<ClientInfo>::iterator client_index = clients_.begin();
1423 while (client_index != clients_.end()) {
1424 ClientInfo& client_info = *client_index;
1425
1426 if (response_handle_to_ignore == client_info.handle) {
1427 client_index++;
1428 continue;
1429 }
1430
1431 if (client_info.handle)
1432 client_info.handle->cancel();
1433
1434 WebPluginResourceClient* resource_client = client_info.client;
1435 client_index = clients_.erase(client_index);
1436 if (resource_client)
1437 resource_client->DidFail();
1438 }
1439
1440 // This needs to be called now and not in the destructor since the
1441 // webframe_ might not be valid anymore.
1442 webframe_->set_plugin_delegate(NULL);
1443 webframe_ = NULL;
1444 }
OLDNEW
« 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