diff options
author | joshia@google.com <joshia@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-10 18:32:44 +0000 |
---|---|---|
committer | joshia@google.com <joshia@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-10 18:32:44 +0000 |
commit | 6552d203e8c2507b46f6216db84e92b6391e9506 (patch) | |
tree | 2e9fcd266a10df1c071a8ebb787eaae665d9a93b /webkit/glue | |
parent | cdce139e4aac3d2f1e4b2f41f6fc4d77779b2b7f (diff) | |
download | chromium_src-6552d203e8c2507b46f6216db84e92b6391e9506.zip chromium_src-6552d203e8c2507b46f6216db84e92b6391e9506.tar.gz chromium_src-6552d203e8c2507b46f6216db84e92b6391e9506.tar.bz2 |
Add a support to NPN_PostUrl[Notify] using files
Post data to be uploaded from a file. This can be handled in two ways.
1. Read entire file and send the contents as if it was a post data
specified in the argument
2. Send just the file details and read them in the browser at the
time of sending the request.
Approach 2 is more efficient but complicated. Approach 1 has a major
drawback of sending potentially large data over two IPC hops.
In a way 'large data over IPC' problem exists as it is in case of
plugin giving the data directly instead of in a file. Currently we
are going with the approach 1 to get the feature working. We can
optimize this later with approach 2.
BUG=629
Review URL: http://codereview.chromium.org/6548
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3226 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 116 |
1 files changed, 82 insertions, 34 deletions
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index b793032..9b3a7b9 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -4,8 +4,13 @@ #include "webkit/glue/plugins/plugin_host.h" +#include "base/file_util.h" #include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/string_piece.h" #include "base/string_util.h" +#include "base/sys_string_conversions.h" +#include "net/base/net_util.h" #include "webkit/default_plugin/default_plugin_shared.h" #include "webkit/glue/glue_util.h" #include "webkit/glue/webplugin.h" @@ -394,46 +399,89 @@ static NPError PostURLNotify(NPP id, if (!url) return NPERR_INVALID_URL; - if (file) { - // Unfortunately, our WebKit requests can support files which - // contain *only* data. But the files from NPAPI contain - // headers + data! So, we need to read the file, extract - // the headers, write the data back to a new file, and then - // finally we can post the file. TODO: Implement me! - // TODO: implement me + scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + if (!plugin.get()) { NOTREACHED(); return NPERR_GENERIC_ERROR; } - bool is_javascript_url = IsJavaScriptUrl(url); + std::string post_file_contents; - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); - if (plugin.get()) { - // The post data sent by a plugin contains both headers - // and post data. Example: - // Content-type: text/html - // Content-length: 200 - // - // <200 bytes of content here> - // - // Unfortunately, our stream needs these broken apart, - // so we need to parse the data and set headers and data - // separately. - plugin->webplugin()->HandleURLRequest("POST", - is_javascript_url, - target, - len, - buf, - file ? true : false, - notify, - url, - notify_data, - plugin->popups_allowed()); - return NPERR_NO_ERROR; - } else { - NOTREACHED(); + if (file) { + // Post data to be uploaded from a file. This can be handled in two + // ways. + // 1. Read entire file and send the contents as if it was a post data + // specified in the argument + // 2. Send just the file details and read them in the browser at the + // time of sending the request. + // Approach 2 is more efficient but complicated. Approach 1 has a major + // drawback of sending potentially large data over two IPC hops. In a way + // 'large data over IPC' problem exists as it is in case of plugin giving + // the data directly instead of in a file. + // Currently we are going with the approach 1 to get the feature working. + // We can optimize this later with approach 2. + + // TODO(joshia): Design a scheme to send a file descriptor instead of + // entire file contents across. + + // Security alert: + // --------------- + // Here we are blindly uploading whatever file requested by a plugin. + // This is risky as someone could exploit a plugin to send private + // data in arbitrary locations. + // A malicious (non-sandboxed) plugin has unfeterred access to OS + // resources and can do this anyway without using browser's HTTP stack. + // FWIW, Firefox and Safari don't perform any security checks. + + if (!buf) + return NPERR_FILE_NOT_FOUND; + + std::string file_path_ascii(buf); + std::wstring file_path; + static const char kFileUrlPrefix[] = "file:"; + if (StartsWithASCII(file_path_ascii, kFileUrlPrefix, false)) { + GURL file_url(file_path_ascii); + DCHECK(file_url.SchemeIsFile()); + net::FileURLToFilePath(file_url, &file_path); + } else { + std::wstring file_path = base::SysNativeMBToWide(file_path_ascii); + } + + file_util::FileInfo post_file_info = {0}; + if (!file_util::GetFileInfo(file_path.c_str(), &post_file_info) || + post_file_info.is_directory) + return NPERR_FILE_NOT_FOUND; + + if (!file_util::ReadFileToString(file_path, &post_file_contents)) + return NPERR_FILE_NOT_FOUND; + + buf = post_file_contents.c_str(); + len = post_file_contents.size(); } - return NPERR_GENERIC_ERROR; + + bool is_javascript_url = IsJavaScriptUrl(url); + + // The post data sent by a plugin contains both headers + // and post data. Example: + // Content-type: text/html + // Content-length: 200 + // + // <200 bytes of content here> + // + // Unfortunately, our stream needs these broken apart, + // so we need to parse the data and set headers and data + // separately. + plugin->webplugin()->HandleURLRequest("POST", + is_javascript_url, + target, + len, + buf, + false, + notify, + url, + notify_data, + plugin->popups_allowed()); + return NPERR_NO_ERROR; } NPError NPN_PostURLNotify(NPP id, |