diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:20:51 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:20:51 +0000 |
commit | f5b16fed647e941aa66933178da85db2860d639b (patch) | |
tree | f00e9856c04aad3b558a140955e7674add33f051 /webkit/default_plugin/plugin_database_handler.cc | |
parent | 920c091ac3ee15079194c82ae8a7a18215f3f23c (diff) | |
download | chromium_src-f5b16fed647e941aa66933178da85db2860d639b.zip chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.gz chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.bz2 |
Add webkit to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/default_plugin/plugin_database_handler.cc')
-rw-r--r-- | webkit/default_plugin/plugin_database_handler.cc | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/webkit/default_plugin/plugin_database_handler.cc b/webkit/default_plugin/plugin_database_handler.cc new file mode 100644 index 0000000..3d534ee --- /dev/null +++ b/webkit/default_plugin/plugin_database_handler.cc @@ -0,0 +1,343 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "webkit/default_plugin/plugin_database_handler.h" + +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/string_util.h" +#include "base/time.h" +#include "third_party/libxml/include/libxml/parser.h" +#include "third_party/libxml/include/libxml/xpath.h" +#include "webkit/default_plugin/plugin_impl.h" +#include "webkit/default_plugin/plugin_main.h" + +PluginDatabaseHandler::PluginDatabaseHandler( + PluginInstallerImpl& plugin_installer_instance) + : plugin_downloads_file_(INVALID_HANDLE_VALUE), + plugin_installer_instance_(plugin_installer_instance), + ignore_plugin_db_data_(false) { +} + +PluginDatabaseHandler::~PluginDatabaseHandler() { + if (plugin_downloads_file_ != INVALID_HANDLE_VALUE) { + ::CloseHandle(plugin_downloads_file_); + plugin_downloads_file_ = INVALID_HANDLE_VALUE; + } +} + +bool PluginDatabaseHandler::DownloadPluginsFileIfNeeded( + const std::string& plugin_finder_url) { + DCHECK(!plugin_finder_url.empty()); + // The time in days for which the plugins list is cached. + // TODO(iyengar) Make this configurable. + const int kPluginsListCacheTimeInDays = 3; + + plugin_finder_url_ = plugin_finder_url; + + PathService::Get(base::DIR_MODULE, &plugins_file_); + plugins_file_ += L"\\chrome_plugins_file.xml"; + + bool initiate_download = false; + if (!file_util::PathExists(plugins_file_)) { + initiate_download = true; + } else { + SYSTEMTIME creation_system_time = {0}; + if (!file_util::GetFileCreationLocalTime(plugins_file_, + &creation_system_time)) { + NOTREACHED(); + return false; + } + + FILETIME creation_file_time = {0}; + ::SystemTimeToFileTime(&creation_system_time, &creation_file_time); + + FILETIME current_time = {0}; + ::GetSystemTimeAsFileTime(¤t_time); + + Time file_time = Time::FromFileTime(creation_file_time); + Time current_system_time = Time::FromFileTime(current_time); + + TimeDelta time_diff = file_time - current_system_time; + if (time_diff.InDays() > kPluginsListCacheTimeInDays) { + initiate_download = true; + } + } + + if (initiate_download) { + DLOG(INFO) << "Initiating GetURLNotify on the plugin finder URL " + << plugin_finder_url.c_str(); + + plugin_installer_instance_.set_plugin_installer_state( + PluginListDownloadInitiated); + + DCHECK(default_plugin::g_browser->geturlnotify); + default_plugin::g_browser->geturlnotify( + plugin_installer_instance_.instance(), plugin_finder_url.c_str(), + NULL, NULL); + } else { + DLOG(INFO) << "Plugins file " << plugins_file_.c_str() + << " already exists"; + plugin_downloads_file_ = ::CreateFile(plugins_file_.c_str(), GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { + DLOG(INFO) << "Failed to open plugins file " + << plugins_file_.c_str() << " Error " + << ::GetLastError(); + NOTREACHED(); + return false; + } + // The URLNotify function contains all handling needed to parse the plugins + // file and display the UI accordingly. + plugin_installer_instance_.set_plugin_installer_state( + PluginListDownloadInitiated); + plugin_installer_instance_.URLNotify(plugin_finder_url.c_str(), + NPRES_DONE); + } + return true; +} + +int32 PluginDatabaseHandler::Write(NPStream* stream, int32 offset, + int32 buffer_length, void* buffer) { + if (ignore_plugin_db_data_) { + return buffer_length; + } + + if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { + DLOG(INFO) << "About to create plugins file " << plugins_file_.c_str(); + plugin_downloads_file_ = CreateFile(plugins_file_.c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { + unsigned long error = ::GetLastError(); + if (error == ERROR_SHARING_VIOLATION) { + // File may have been downloaded by another plugin instance on this + // page. + plugin_downloads_file_ = ::CreateFile( + plugins_file_.c_str(), GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (plugin_downloads_file_ != INVALID_HANDLE_VALUE) { + ignore_plugin_db_data_ = true; + return buffer_length; + } + } + + DLOG(INFO) << "Failed to create plugins file " + << plugins_file_.c_str() << " Error " + << ::GetLastError(); + NOTREACHED(); + return 0; + } + } + + unsigned long bytes_written = 0; + if (0 == lstrcmpiA(stream->url, plugin_finder_url_.c_str())) { + DCHECK(plugin_downloads_file_ != INVALID_HANDLE_VALUE); + + WriteFile(plugin_downloads_file_, buffer, buffer_length, &bytes_written, + NULL); + DCHECK(buffer_length == bytes_written); + } + return bytes_written; +} + + +bool PluginDatabaseHandler::ParsePluginList() { + if (plugin_downloads_file_ == INVALID_HANDLE_VALUE) { + DLOG(WARNING) << "Invalid plugins file"; + NOTREACHED(); + return false; + } + + bool parse_result = false; + + std::string plugins_file = WideToUTF8(plugins_file_.c_str()); + xmlDocPtr plugin_downloads_doc = xmlParseFile(plugins_file.c_str()); + if (plugin_downloads_doc == NULL) { + DLOG(WARNING) << "Failed to parse plugins file " << plugins_file.c_str(); + return parse_result; + } + + xmlXPathContextPtr context = NULL; + xmlXPathObjectPtr plugins_result = NULL; + + do { + context = xmlXPathNewContext(plugin_downloads_doc); + if (context == NULL) { + DLOG(WARNING) << "Failed to retrieve XPath context"; + NOTREACHED(); + parse_result = false; + break; + } + + plugins_result = + xmlXPathEvalExpression(reinterpret_cast<const xmlChar*>("//plugin"), + context); + if ((plugins_result == NULL) || + xmlXPathNodeSetIsEmpty(plugins_result->nodesetval)) { + DLOG(WARNING) << "Failed to find XPath //plugin"; + NOTREACHED(); + parse_result = false; + break; + } + + xmlNodeSetPtr plugin_list = plugins_result->nodesetval; + for (int plugin_index = 0; plugin_index < plugin_list->nodeNr; + ++plugin_index) { + PluginDetail plugin_detail; + if (!ReadPluginInfo(plugin_list->nodeTab[plugin_index]->children, + &plugin_detail)) { + DLOG(ERROR) << "Failed to read plugin details at index " + << plugin_index; + break; + } + downloaded_plugins_list_.push_back(plugin_detail); + } + if (downloaded_plugins_list_.size()) + parse_result = true; + } while (0); + + xmlXPathFreeContext(context); + xmlXPathFreeObject(plugins_result); + xmlFreeDoc(plugin_downloads_doc); + xmlCleanupParser(); + DLOG(INFO) << "Parse plugins file result " << parse_result; + return parse_result; +} + +bool PluginDatabaseHandler::GetPluginDetailsForMimeType( + const char* mime_type, const char* language, + std::string* download_url, std::wstring* plugin_name) { + if (!mime_type || !language || !download_url || !plugin_name) { + NOTREACHED(); + return false; + } + + PluginList::iterator plugin_index; + for (plugin_index = downloaded_plugins_list_.begin(); + plugin_index != downloaded_plugins_list_.end(); + ++plugin_index) { + const PluginDetail& current_plugin = *plugin_index; + if ((0 == lstrcmpiA(mime_type, current_plugin.mime_type.c_str())) && + (0 == lstrcmpiA(language, current_plugin.language.c_str()))) { + *download_url = current_plugin.download_url; + *plugin_name = current_plugin.display_name; + return true; + } + } + return false; +} + +void PluginDatabaseHandler::Close(bool delete_file) { + if (plugin_downloads_file_ != INVALID_HANDLE_VALUE) { + ::CloseHandle(plugin_downloads_file_); + plugin_downloads_file_ = INVALID_HANDLE_VALUE; + if (delete_file) { + ::DeleteFile(plugins_file_.c_str()); + plugins_file_.clear(); + } + } +} + +bool PluginDatabaseHandler::ReadPluginInfo(_xmlNode* plugin_node, + PluginDetail* plugin_detail) { + if (!plugin_node) { + NOTREACHED(); + return false; + } + + _xmlNode* plugin_mime_type = plugin_node->next; + if ((plugin_mime_type == NULL) || + (plugin_mime_type->next == NULL)) { + DLOG(WARNING) << "Failed to find mime type node in file"; + NOTREACHED(); + return false; + } + + _xmlNode* plugin_mime_type_val = plugin_mime_type->children; + if (plugin_mime_type_val == NULL) { + DLOG(WARNING) << "Invalid mime type"; + NOTREACHED(); + return false; + } + // Skip the first child of each node as it is the text element + // for that node. + _xmlNode* plugin_lang_node = plugin_mime_type->next->next; + if ((plugin_lang_node == NULL) || + (plugin_lang_node->next == NULL)) { + DLOG(WARNING) << "Failed to find plugin language node"; + NOTREACHED(); + return false; + } + _xmlNode* plugin_lang_val = plugin_lang_node->children; + if (plugin_lang_val == NULL) { + DLOG(WARNING) << "Invalid plugin language"; + NOTREACHED(); + return false; + } + _xmlNode* plugin_name_node = plugin_lang_node->next->next; + if ((plugin_name_node == NULL) || + (plugin_name_node->next == NULL)) { + DLOG(WARNING) << "Failed to find plugin name node"; + NOTREACHED(); + return false; + } + _xmlNode* plugin_name_val = plugin_name_node->children; + if (plugin_name_val == NULL) { + DLOG(WARNING) << "Invalid plugin name"; + NOTREACHED(); + return false; + } + _xmlNode* plugin_download_url_node = plugin_name_node->next->next; + if (plugin_download_url_node == NULL) { + DLOG(WARNING) << "Failed to find plugin URL node"; + NOTREACHED(); + return false; + } + _xmlNode* plugin_download_url_val = plugin_download_url_node->children; + if (plugin_download_url_val == NULL) { + DLOG(WARNING) << "Invalid plugin URL"; + NOTREACHED(); + return false; + } + + plugin_detail->display_name = + UTF8ToWide(reinterpret_cast<const char*>(plugin_name_val->content)); + plugin_detail->download_url = + reinterpret_cast<const char*>(plugin_download_url_val->content); + plugin_detail->mime_type = + reinterpret_cast<const char*>(plugin_mime_type_val->content); + plugin_detail->language = + reinterpret_cast<const char*>(plugin_lang_val->content); + + return true; +} |