[go: nahoru, domu]

blob: 649975f6e113c3b7795f26bdb84408ced62bace2 [file] [log] [blame]
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/chrome_plugin_util.h"
#include <algorithm>
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
//
// ScopableCPRequest
//
ScopableCPRequest::ScopableCPRequest(const char* u, const char* m,
CPBrowsingContext c) {
pdata = NULL;
data = NULL;
#if defined(OS_WIN)
url = _strdup(u);
method = _strdup(m);
#else
url = strdup(u);
method = strdup(m);
#endif
context = c;
}
ScopableCPRequest::~ScopableCPRequest() {
pdata = NULL;
data = NULL;
free(const_cast<char*>(url));
free(const_cast<char*>(method));
}
//
// PluginHelper
//
// static
void PluginHelper::DestroyAllHelpersForPlugin(ChromePluginLib* plugin) {
NotificationService::current()->Notify(
NotificationType::CHROME_PLUGIN_UNLOADED,
Source<ChromePluginLib>(plugin),
NotificationService::NoDetails());
}
PluginHelper::PluginHelper(ChromePluginLib* plugin) : plugin_(plugin) {
DCHECK(CalledOnValidThread());
registrar_.Add(this, NotificationType::CHROME_PLUGIN_UNLOADED,
Source<ChromePluginLib>(plugin_));
}
PluginHelper::~PluginHelper() {
DCHECK(CalledOnValidThread());
}
void PluginHelper::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
DCHECK(CalledOnValidThread());
DCHECK(type == NotificationType::CHROME_PLUGIN_UNLOADED);
DCHECK(plugin_ == Source<ChromePluginLib>(source).ptr());
delete this;
}
//
// PluginResponseUtils
//
uint32 PluginResponseUtils::CPLoadFlagsToNetFlags(uint32 flags) {
uint32 net_flags = 0;
#define HANDLE_FLAG(name) \
if (flags & CPREQUEST##name) \
net_flags |= net::name
HANDLE_FLAG(LOAD_VALIDATE_CACHE);
HANDLE_FLAG(LOAD_BYPASS_CACHE);
HANDLE_FLAG(LOAD_PREFERRING_CACHE);
HANDLE_FLAG(LOAD_ONLY_FROM_CACHE);
HANDLE_FLAG(LOAD_DISABLE_CACHE);
HANDLE_FLAG(LOAD_DISABLE_INTERCEPT);
net_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS;
return net_flags;
}
int PluginResponseUtils::GetResponseInfo(
const net::HttpResponseHeaders* response_headers,
CPResponseInfoType type, void* buf, size_t buf_size) {
if (!response_headers)
return CPERR_FAILURE;
switch (type) {
case CPRESPONSEINFO_HTTP_STATUS:
if (buf && buf_size) {
int status = response_headers->response_code();
memcpy(buf, &status, std::min(buf_size, sizeof(status)));
}
break;
case CPRESPONSEINFO_HTTP_RAW_HEADERS: {
const std::string& headers = response_headers->raw_headers();
if (buf_size < headers.size()+1)
return static_cast<int>(headers.size()+1);
if (buf)
memcpy(buf, headers.c_str(), headers.size()+1);
break;
}
default:
return CPERR_INVALID_VERSION;
}
return CPERR_SUCCESS;
}
CPError CPB_GetCommandLineArgumentsCommon(const char* url,
std::string* arguments) {
const CommandLine cmd = *CommandLine::ForCurrentProcess();
std::wstring arguments_w;
// Use the same UserDataDir for new launches that we currently have set.
FilePath user_data_dir = cmd.GetSwitchValuePath(switches::kUserDataDir);
if (!user_data_dir.empty()) {
// Make sure user_data_dir is an absolute path.
if (file_util::AbsolutePath(&user_data_dir) &&
file_util::PathExists(user_data_dir)) {
// TODO(evanm): use CommandLine APIs instead of this.
arguments_w += std::wstring(L"--") + ASCIIToWide(switches::kUserDataDir) +
L"=\"" + user_data_dir.ToWStringHack() + L"\" ";
}
}
#if defined(OS_CHROMEOS)
FilePath profile = cmd.GetSwitchValuePath(switches::kLoginProfile);
if (!profile.empty()) {
arguments_w += std::wstring(L"--") + ASCIIToWide(switches::kLoginProfile) +
L"=\"" + profile.ToWStringHack() + L"\" ";
}
#endif
// Use '--app=url' instead of just 'url' to launch the browser with minimal
// chrome.
// Note: Do not change this flag! Old Gears shortcuts will break if you do!
std::string url_string(url);
ReplaceSubstringsAfterOffset(&url_string, 0, "\\", "%5C");
ReplaceSubstringsAfterOffset(&url_string, 0, "\"", "%22");
ReplaceSubstringsAfterOffset(&url_string, 0, ";", "%3B");
ReplaceSubstringsAfterOffset(&url_string, 0, "$", "%24");
#if defined(OS_WIN) // Windows shortcuts can't escape % so we use \x instead.
ReplaceSubstringsAfterOffset(&url_string, 0, "%", "\\x");
#endif
std::wstring url_w = UTF8ToWide(url_string);
// TODO(evanm): use CommandLine APIs instead of this.
arguments_w += std::wstring(L"--") + ASCIIToWide(switches::kApp) +
L"=\"" + url_w + L"\"";
*arguments = WideToUTF8(arguments_w);
return CPERR_SUCCESS;
}
//
// Host functions shared by browser and plugin processes
//
void* STDCALL CPB_Alloc(uint32 size) {
return malloc(size);
}
void STDCALL CPB_Free(void* memory) {
free(memory);
}