diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 02:25:55 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 02:25:55 +0000 |
commit | 673b4bfcb945174ebbfa5992082eee883dc7262f (patch) | |
tree | ff8f784c1eb1c4641100634e0a4d80b753b1e20a /chrome_frame | |
parent | bd82e7c36b9faf9b1f736b77c18344ed2b4556e3 (diff) | |
download | chromium_src-673b4bfcb945174ebbfa5992082eee883dc7262f.zip chromium_src-673b4bfcb945174ebbfa5992082eee883dc7262f.tar.gz chromium_src-673b4bfcb945174ebbfa5992082eee883dc7262f.tar.bz2 |
Remove ChromeFrame resource-related IPCs and the code which depended on them.
BUG=316496, 316203
R=ananta@chromium.org, ananta
Review URL: https://codereview.chromium.org/109683005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241449 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
20 files changed, 6 insertions, 3356 deletions
diff --git a/chrome_frame/chrome_active_document.cc b/chrome_frame/chrome_active_document.cc index 6557a1f..15e68ee 100644 --- a/chrome_frame/chrome_active_document.cc +++ b/chrome_frame/chrome_active_document.cc @@ -53,15 +53,13 @@ const DWORD kIEEncodingIdArray[] = { }; ChromeActiveDocument::ChromeActiveDocument() - : navigation_info_(new NavigationInfo()), - first_navigation_(true), + : first_navigation_(true), is_automation_client_reused_(false), popup_allowed_(false), accelerator_table_(NULL) { TRACE_EVENT_BEGIN_ETW("chromeframe.createactivedocument", this, ""); url_fetcher_->set_frame_busting(false); - memset(navigation_info_.get(), 0, sizeof(NavigationInfo)); } HRESULT ChromeActiveDocument::FinalConstruct() { @@ -406,22 +404,7 @@ STDMETHODIMP ChromeActiveDocument::LoadHistory(IStream* stream, } STDMETHODIMP ChromeActiveDocument::SaveHistory(IStream* stream) { - // TODO(sanjeevr): We need to fetch the entire list of navigation entries - // from Chrome and persist it in the stream. And in LoadHistory we need to - // pass this list back to Chrome which will recreate the list. This will allow - // Back-Forward navigation to anchors to work correctly when we navigate to a - // page outside of ChromeFrame and then come back. - if (!stream) { - NOTREACHED(); - return E_INVALIDARG; - } - - LARGE_INTEGER offset = {0}; - ULARGE_INTEGER new_pos = {0}; - DWORD written = 0; - std::wstring url = UTF8ToWide(navigation_info_->url.spec()); - return stream->Write(url.c_str(), (url.length() + 1) * sizeof(wchar_t), - &written); + return E_INVALIDARG; } STDMETHODIMP ChromeActiveDocument::SetPositionCookie(DWORD position_cookie) { @@ -429,10 +412,6 @@ STDMETHODIMP ChromeActiveDocument::SetPositionCookie(DWORD position_cookie) { } STDMETHODIMP ChromeActiveDocument::GetPositionCookie(DWORD* position_cookie) { - if (!position_cookie) - return E_INVALIDARG; - - *position_cookie = navigation_info_->navigation_index; return S_OK; } @@ -598,183 +577,6 @@ bool IsFindAccelerator(const MSG& msg) { !(base::win::IsAltPressed() || base::win::IsShiftPressed()); } -void ChromeActiveDocument::UpdateNavigationState( - const NavigationInfo& new_navigation_info, int flags) { - // This could be NULL if the active document instance is being destroyed. - if (!m_spInPlaceSite) { - DVLOG(1) << __FUNCTION__ << "m_spInPlaceSite is NULL. Returning"; - return; - } - - HRESULT hr = S_OK; - bool is_title_changed = - (navigation_info_->title != new_navigation_info.title); - bool is_ssl_state_changed = - (navigation_info_->security_style != - new_navigation_info.security_style) || - (navigation_info_->displayed_insecure_content != - new_navigation_info.displayed_insecure_content) || - (navigation_info_->ran_insecure_content != - new_navigation_info.ran_insecure_content); - - if (is_ssl_state_changed) { - int lock_status = SECURELOCK_SET_UNSECURE; - switch (new_navigation_info.security_style) { - case content::SECURITY_STYLE_AUTHENTICATED: - lock_status = new_navigation_info.displayed_insecure_content ? - SECURELOCK_SET_MIXED : SECURELOCK_SET_SECUREUNKNOWNBIT; - break; - default: - break; - } - - base::win::ScopedVariant secure_lock_status(lock_status); - IEExec(&CGID_ShellDocView, INTERNAL_CMDID_SET_SSL_LOCK, - OLECMDEXECOPT_DODEFAULT, secure_lock_status.AsInput(), NULL); - } - - // A number of poorly written bho's crash in their event sink callbacks if - // chrome frame is the currently loaded document. This is because they expect - // chrome frame to implement interfaces like IHTMLDocument, etc. We patch the - // event sink's of these bho's and don't invoke the event sink if chrome - // frame is the currently loaded document. - if (GetConfigBool(true, kEnableBuggyBhoIntercept)) { - base::win::ScopedComPtr<IWebBrowser2> wb2; - DoQueryService(SID_SWebBrowserApp, m_spClientSite, wb2.Receive()); - if (wb2 && buggy_bho::BuggyBhoTls::GetInstance()) { - buggy_bho::BuggyBhoTls::GetInstance()->PatchBuggyBHOs(wb2); - } - } - - // Ideally all navigations should come to Chrome Frame so that we can call - // BeforeNavigate2 on installed BHOs and give them a chance to cancel the - // navigation. However, in practice what happens is as below: - // The very first navigation that happens in CF happens via a Load or a - // LoadHistory call. In this case, IE already has the correct information for - // its travel log as well address bar. For other internal navigations (navs - // that only happen within Chrome such as anchor navigations) we need to - // update IE's internal state after the fact. In the case of internal - // navigations, we notify the BHOs but ignore the should_cancel flag. - - // Another case where we need to issue BeforeNavigate2 calls is as below:- - // We get notified after the fact, when navigations are initiated within - // Chrome via window.open calls. These navigations are handled by creating - // an external tab container within chrome and then connecting to it from IE. - // We still want to update the address bar/history, etc, to ensure that - // the special URL used by Chrome to indicate this is updated correctly. - ChromeFrameUrl cf_url; - bool is_attach_external_tab_url = cf_url.Parse(std::wstring(url_)) && - cf_url.attach_to_external_tab(); - - bool is_internal_navigation = - IsNewNavigation(new_navigation_info, flags) || is_attach_external_tab_url; - - if (new_navigation_info.url.is_valid()) - url_.Allocate(UTF8ToWide(new_navigation_info.url.spec()).c_str()); - - if (is_internal_navigation) { - // IE6 does not support tabs. If Chrome sent us a window open request - // indicating that the navigation needs to occur in a foreground tab or - // a popup window, then we need to ensure that the new window in IE6 is - // brought to the foreground. - if (GetIEVersion() == IE_6 && - is_attach_external_tab_url && - (cf_url.disposition() == NEW_FOREGROUND_TAB || - cf_url.disposition() == NEW_POPUP)) { - base::win::ScopedComPtr<IWebBrowser2> wb2; - DoQueryService(SID_SWebBrowserApp, m_spClientSite, wb2.Receive()); - if (wb2) - BaseActiveX::BringWebBrowserWindowToTop(wb2); - } - base::win::ScopedComPtr<IDocObjectService> doc_object_svc; - base::win::ScopedComPtr<IWebBrowserEventsService> web_browser_events_svc; - - DoQueryService(__uuidof(web_browser_events_svc), m_spClientSite, - web_browser_events_svc.Receive()); - - if (!web_browser_events_svc.get()) { - DoQueryService(SID_SShellBrowser, m_spClientSite, - doc_object_svc.Receive()); - } - - // web_browser_events_svc can be NULL on IE6. - if (web_browser_events_svc) { - VARIANT_BOOL should_cancel = VARIANT_FALSE; - web_browser_events_svc->FireBeforeNavigate2Event(&should_cancel); - } else if (doc_object_svc) { - BOOL should_cancel = FALSE; - doc_object_svc->FireBeforeNavigate2(NULL, url_, 0, NULL, NULL, 0, - NULL, FALSE, &should_cancel); - } - - // We need to tell IE that we support navigation so that IE will query us - // for IPersistHistory and call GetPositionCookie to save our navigation - // index. - base::win::ScopedVariant html_window(static_cast<IUnknown*>( - static_cast<IHTMLWindow2*>(this))); - IEExec(&CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, - html_window.AsInput(), NULL); - - // We pass the HLNF_INTERNALJUMP flag to INTERNAL_CMDID_FINALIZE_TRAVEL_LOG - // since we want to make IE treat all internal navigations within this page - // (including anchor navigations and subframe navigations) as anchor - // navigations. This will ensure that IE calls GetPositionCookie - // to save the current position cookie in the travel log and then call - // SetPositionCookie when the user hits Back/Forward to come back here. - base::win::ScopedVariant internal_navigation(HLNF_INTERNALJUMP); - IEExec(&CGID_Explorer, INTERNAL_CMDID_FINALIZE_TRAVEL_LOG, 0, - internal_navigation.AsInput(), NULL); - - // We no longer need to lie to IE. If we lie persistently to IE, then - // IE reuses us for new navigations. - IEExec(&CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, NULL, NULL); - - if (doc_object_svc) { - // Now call the FireNavigateCompleteEvent which makes IE update the text - // in the address-bar. - doc_object_svc->FireNavigateComplete2(this, 0); - doc_object_svc->FireDocumentComplete(this, 0); - } else if (web_browser_events_svc) { - web_browser_events_svc->FireNavigateComplete2Event(); - web_browser_events_svc->FireDocumentCompleteEvent(); - } - } - - if (is_title_changed) { - base::win::ScopedVariant title(new_navigation_info.title.c_str()); - IEExec(NULL, OLECMDID_SETTITLE, OLECMDEXECOPT_DONTPROMPTUSER, - title.AsInput(), NULL); - } - - // There are cases in which we receive NavigationStateChanged events for - // provisional loads. These events will contain a new URL but will not be - // considered new navigations since their navigation_index is 0. For these - // events, do not update the navigation_info_ state, as this will muck up the - // travel log when the subsequent committed navigation event takes place. - // - // Given this filtering, also special-case first navigations since those - // are needed to initially populate navigation_info_ to keep it in sync with - // what was placed in the IE travel log when CF was first opened. - // - // Lastly, allow through navigation events that would neither affect the - // travel log nor cause the page location to change, as these will - // contain informational state (referrer, title, etc.) that we should - // preserve. - if (is_internal_navigation || IsFirstNavigation(new_navigation_info) || - new_navigation_info.url == navigation_info_->url) { - // It is important that we only update the navigation_info_ after we have - // finalized the travel log. This is because IE will ask for information - // such as navigation index when the travel log is finalized and we need - // supply the old index and not the new one. - *navigation_info_ = new_navigation_info; - } - - // Update the IE zone here. Ideally we would like to do it when the active - // document is activated. However that does not work at times as the frame we - // get there is not the actual frame which handles the command. - IEExec(&CGID_Explorer, SBCMDID_MIXEDZONE, 0, NULL, NULL); -} - void ChromeActiveDocument::OnFindInPage() { TabProxy* tab = GetTabProxy(); if (tab) { @@ -786,9 +588,6 @@ void ChromeActiveDocument::OnFindInPage() { } void ChromeActiveDocument::OnViewSource() { - DCHECK(navigation_info_->url.is_valid()); - HostNavigate(GURL(content::kViewSourceScheme + std::string(":") + - navigation_info_->url.spec()), GURL(), NEW_WINDOW); } void ChromeActiveDocument::OnDetermineSecurityZone(const GUID* cmd_group_guid, @@ -916,19 +715,6 @@ HRESULT ChromeActiveDocument::OnRefreshPage(const GUID* cmd_group_guid, TabProxy* tab_proxy = GetTabProxy(); if (tab_proxy) { tab_proxy->ReloadAsync(); - } else { - DLOG(ERROR) << "No automation proxy"; - DCHECK(automation_client_.get() != NULL) << "how did it get freed?"; - // The current url request manager (url_fetcher_) has been switched to - // a stopping state so we need to reset it and get a new one for the new - // automation server. - ResetUrlRequestManager(); - url_fetcher_->set_frame_busting(false); - // And now launch the current URL again. This starts a new server process. - DCHECK(navigation_info_->url.is_valid()); - ChromeFrameUrl cf_url; - cf_url.Parse(UTF8ToWide(navigation_info_->url.spec())); - LaunchUrl(cf_url, navigation_info_->referrer.spec()); } return S_OK; @@ -1117,44 +903,3 @@ LRESULT ChromeActiveDocument::OnSetFocus(UINT message, WPARAM wparam, BOOL& handled) { // NO_LINT return 0; } - -bool ChromeActiveDocument::IsNewNavigation( - const NavigationInfo& new_navigation_info, int flags) const { - // A new navigation is typically an internal navigation which is initiated by - // the renderer(WebKit). Condition 1 below has to be true along with the - // any of the other conditions below. - // 1. The navigation notification flags passed in as the flags parameter - // is not INVALIDATE_TYPE_LOAD which indicates that the loading state of - // the tab changed. - // 2. The navigation index is greater than 0 which means that a top level - // navigation was initiated on the current external tab. - // 3. The navigation type has changed. - // 4. The url or the referrer are different. - if (flags == content::INVALIDATE_TYPE_LOAD) - return false; - - if (new_navigation_info.navigation_index <= 0) - return false; - - if (new_navigation_info.navigation_index == - navigation_info_->navigation_index) - return false; - - if (new_navigation_info.navigation_type != navigation_info_->navigation_type) - return true; - - if (new_navigation_info.url != navigation_info_->url) - return true; - - if (new_navigation_info.referrer != navigation_info_->referrer) - return true; - - return false; -} - -bool ChromeActiveDocument::IsFirstNavigation( - const NavigationInfo& new_navigation_info) const { - return (navigation_info_->url.is_empty() && - new_navigation_info.navigation_type == - content::NAVIGATION_TYPE_NEW_PAGE); -} diff --git a/chrome_frame/chrome_active_document.h b/chrome_frame/chrome_active_document.h index b9e7278..51ea649 100644 --- a/chrome_frame/chrome_active_document.h +++ b/chrome_frame/chrome_active_document.h @@ -345,10 +345,6 @@ END_EXEC_COMMAND_MAP() HRESULT GetInPlaceFrame(IOleInPlaceFrame** in_place_frame); protected: - // A helper method that updates our internal navigation state - // as well as IE's navigation state (viz Title and current URL). - // The navigation_flags is a TabContents::InvalidateTypes enum - void UpdateNavigationState(const NavigationInfo& nav_info, int flags); TabProxy* GetTabProxy() const { if (automation_client_.get()) @@ -406,19 +402,9 @@ END_EXEC_COMMAND_MAP() LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); - // Returns true if the NavigationInfo object passed in represents a new - // navigation initiated by the renderer. - bool IsNewNavigation(const NavigationInfo& new_navigation_info, - int flags) const; - - // Returns true if the NavigationInfo object passed in represents a first - // page navigation initiated as this active document was being created. - bool IsFirstNavigation(const NavigationInfo& new_navigation_info) const; - protected: typedef std::map<int, OLECMDF> CommandStatusMap; - scoped_ptr<NavigationInfo> navigation_info_; bool is_doc_object_; // This indicates whether this is the first navigation in this diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp index 369a873..390019e 100644 --- a/chrome_frame/chrome_frame.gyp +++ b/chrome_frame/chrome_frame.gyp @@ -129,7 +129,6 @@ 'test/com_message_event_unittest.cc', 'test/dll_redirector_test.cc', 'test/exception_barrier_unittest.cc', - 'test/html_util_unittests.cc', 'test/http_negotiate_unittest.cc', 'test/infobar_unittests.cc', 'test/policy_settings_unittest.cc', @@ -260,7 +259,6 @@ 'test/ui_test.cc', 'test/urlmon_moniker_tests.h', 'test/urlmon_moniker_integration_test.cc', - 'test/url_request_test.cc', 'test/win_event_receiver.cc', 'test/win_event_receiver.h', '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_launcher_exe_version.rc', @@ -430,11 +428,6 @@ 'test/win_event_receiver.cc', 'test/win_event_receiver.h', 'test/net/fake_external_tab.cc', - 'test/net/fake_external_tab.h', - 'test/net/test_automation_provider.cc', - 'test/net/test_automation_provider.h', - 'test/net/test_automation_resource_message_filter.cc', - 'test/net/test_automation_resource_message_filter.h', '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_tab.h', 'test_utils.cc', 'test_utils.h', diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc index 305fcaf..e894fad 100644 --- a/chrome_frame/chrome_frame_automation.cc +++ b/chrome_frame/chrome_frame_automation.cc @@ -601,8 +601,6 @@ void ChromeFrameAutomationClient::Uninitialize() { // Called from client's FinalRelease() / destructor if (url_fetcher_) { - // Clean up any outstanding requests - url_fetcher_->StopAllRequests(); url_fetcher_ = NULL; } @@ -679,52 +677,6 @@ void ChromeFrameAutomationClient::AutomationServerDied() { base::Unretained(this))); } -bool ChromeFrameAutomationClient::ProcessUrlRequestMessage(TabProxy* tab, - const IPC::Message& msg, bool ui_thread) { - // Either directly call appropriate url_fetcher function - // or postpone call to the UI thread. - uint16 msg_type = msg.type(); - switch (msg_type) { - default: - return false; - - case AutomationMsg_RequestStart::ID: - if (ui_thread || (url_fetcher_flags_ & - PluginUrlRequestManager::START_REQUEST_THREADSAFE)) { - AutomationMsg_RequestStart::Dispatch(&msg, url_fetcher_, this, - &PluginUrlRequestManager::StartUrlRequest); - return true; - } - break; - - case AutomationMsg_RequestRead::ID: - if (ui_thread || (url_fetcher_flags_ & - PluginUrlRequestManager::READ_REQUEST_THREADSAFE)) { - AutomationMsg_RequestRead::Dispatch(&msg, url_fetcher_, this, - &PluginUrlRequestManager::ReadUrlRequest); - return true; - } - break; - - case AutomationMsg_RequestEnd::ID: - if (ui_thread || (url_fetcher_flags_ & - PluginUrlRequestManager::STOP_REQUEST_THREADSAFE)) { - AutomationMsg_RequestEnd::Dispatch(&msg, url_fetcher_, this, - &PluginUrlRequestManager::EndUrlRequest); - return true; - } - break; - } - - PostTask( - FROM_HERE, - base::Bind( - base::IgnoreResult( - &ChromeFrameAutomationClient::ProcessUrlRequestMessage), - base::Unretained(this), tab, msg, true)); - return true; -} - // These are invoked in channel's background thread. // Cannot call any method of the activex here since it is a STA kind of being. // By default we marshal the IPC message to the main/GUI thread and from there @@ -732,9 +684,6 @@ bool ChromeFrameAutomationClient::ProcessUrlRequestMessage(TabProxy* tab, bool ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab, const IPC::Message& msg) { DCHECK(tab == tab_.get()); - // Quickly process network related messages. - if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false)) - return true; // Early check to avoid needless marshaling if (chrome_frame_delegate_ == NULL) @@ -896,40 +845,3 @@ void ChromeFrameAutomationClient::SetUrlFetcher( url_fetcher_flags_ = url_fetcher->GetThreadSafeFlags(); url_fetcher_->set_delegate(this); } - -////////////////////////////////////////////////////////////////////////// -// PluginUrlRequestDelegate implementation. -// Forward network related responses to Chrome. - -void ChromeFrameAutomationClient::OnResponseStarted( - int request_id, const char* mime_type, const char* headers, int size, - base::Time last_modified, const std::string& redirect_url, - int redirect_status, const net::HostPortPair& socket_address, - uint64 upload_size) { - AutomationURLResponse response; - response.mime_type = mime_type; - if (headers) - response.headers = headers; - response.content_length = size; - response.last_modified = last_modified; - response.redirect_url = redirect_url; - response.redirect_status = redirect_status; - response.socket_address = socket_address; - response.upload_size = upload_size; - - automation_server_->Send(new AutomationMsg_RequestStarted( - tab_->handle(), request_id, response)); -} - -void ChromeFrameAutomationClient::OnReadComplete(int request_id, - const std::string& data) { - automation_server_->Send(new AutomationMsg_RequestData( - tab_->handle(), request_id, data)); -} - -void ChromeFrameAutomationClient::OnResponseEnd( - int request_id, - const net::URLRequestStatus& status) { - automation_server_->Send(new AutomationMsg_RequestEnd( - tab_->handle(), request_id, status)); -} diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h index cf7e37c..37008bc 100644 --- a/chrome_frame/chrome_frame_automation.h +++ b/chrome_frame/chrome_frame_automation.h @@ -395,20 +395,6 @@ class ChromeFrameAutomationClient void ReportNavigationError(AutomationMsg_NavigationResponseValues error_code, const std::string& url); - bool ProcessUrlRequestMessage(TabProxy* tab, const IPC::Message& msg, - bool ui_thread); - - // PluginUrlRequestDelegate implementation. Simply adds tab's handle - // as parameter and forwards to Chrome via IPC. - virtual void OnResponseStarted( - int request_id, const char* mime_type, const char* headers, int size, - base::Time last_modified, const std::string& redirect_url, - int redirect_status, const net::HostPortPair& socket_address, - uint64 upload_size); - virtual void OnReadComplete(int request_id, const std::string& data); - virtual void OnResponseEnd(int request_id, - const net::URLRequestStatus& status); - bool is_initialized() const { return init_state_ == INITIALIZED; } diff --git a/chrome_frame/chrome_frame_delegate.cc b/chrome_frame/chrome_frame_delegate.cc index 2914219..c1133d58 100644 --- a/chrome_frame/chrome_frame_delegate.cc +++ b/chrome_frame/chrome_frame_delegate.cc @@ -4,38 +4,14 @@ #include "chrome_frame/chrome_frame_delegate.h" -#include "chrome/common/automation_messages.h" - #define NO_CODE ((void)0) bool ChromeFrameDelegateImpl::IsTabMessage(const IPC::Message& message) { - bool is_tab_message = true; - IPC_BEGIN_MESSAGE_MAP(ChromeFrameDelegateImpl, message) - IPC_MESSAGE_HANDLER_GENERIC(AutomationMsg_RequestStart, NO_CODE) - IPC_MESSAGE_HANDLER_GENERIC(AutomationMsg_RequestRead, NO_CODE) - IPC_MESSAGE_HANDLER_GENERIC(AutomationMsg_RequestEnd, NO_CODE) - IPC_MESSAGE_UNHANDLED(is_tab_message = false); - IPC_END_MESSAGE_MAP() - - return is_tab_message; + return false; } #undef NO_CODE bool ChromeFrameDelegateImpl::OnMessageReceived(const IPC::Message& msg) { - if (!IsValid()) { - DLOG(WARNING) << __FUNCTION__ - << " Msgs received for a NULL automation client instance"; - return false; - } - - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(ChromeFrameDelegateImpl, msg) - IPC_MESSAGE_HANDLER(AutomationMsg_RequestStart, OnRequestStart) - IPC_MESSAGE_HANDLER(AutomationMsg_RequestRead, OnRequestRead) - IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - - return handled; + return false; } diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h index 9df536b..d1edf2f 100644 --- a/chrome_frame/chrome_frame_delegate.h +++ b/chrome_frame/chrome_frame_delegate.h @@ -20,9 +20,7 @@ #include "ipc/ipc_message.h" class GURL; -struct AutomationURLRequest; struct ContextMenuModel; -struct NavigationInfo; namespace net { class URLRequestStatus; @@ -79,14 +77,6 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate { virtual bool IsValid() const { return true; } - - protected: - // Protected methods to be overridden. - virtual void OnRequestStart( - int request_id, const AutomationURLRequest& request) {} - virtual void OnRequestRead(int request_id, int bytes_to_read) {} - virtual void OnRequestEnd(int request_id, - const net::URLRequestStatus& status) {} }; // This interface enables tasks to be marshaled to desired threads. diff --git a/chrome_frame/plugin_url_request.h b/chrome_frame/plugin_url_request.h index ba1e1d1..42e22db 100644 --- a/chrome_frame/plugin_url_request.h +++ b/chrome_frame/plugin_url_request.h @@ -25,14 +25,6 @@ class PluginUrlRequestManager; class DECLSPEC_NOVTABLE PluginUrlRequestDelegate { // NOLINT public: - virtual void OnResponseStarted( - int request_id, const char* mime_type, const char* headers, int size, - base::Time last_modified, const std::string& redirect_url, - int redirect_status, const net::HostPortPair& socket_address, - uint64 upload_size) = 0; - virtual void OnReadComplete(int request_id, const std::string& data) = 0; - virtual void OnResponseEnd(int request_id, - const net::URLRequestStatus& status) = 0; virtual void AddPrivacyDataForUrl(const std::string& url, const std::string& policy_ref, int32 flags) {} @@ -64,37 +56,9 @@ class DECLSPEC_NOVTABLE PluginUrlRequestManager { // NOLINT }; virtual ThreadSafeFlags GetThreadSafeFlags() = 0; - // These are called directly from Automation Client when network related - // automation messages are received from Chrome. - // Strip 'tab' handle and forward to the virtual methods implemented by - // derived classes. - void StartUrlRequest(int request_id, - const AutomationURLRequest& request_info) { - StartRequest(request_id, request_info); - } - - void ReadUrlRequest(int request_id, int bytes_to_read) { - ReadRequest(request_id, bytes_to_read); - } - - void EndUrlRequest(int request_id, const net::URLRequestStatus& s) { - EndRequest(request_id); - } - - void StopAllRequests() { - StopAll(); - } - protected: PluginUrlRequestDelegate* delegate_; bool enable_frame_busting_; - - private: - virtual void StartRequest( - int request_id, const AutomationURLRequest& request_info) = 0; - virtual void ReadRequest(int request_id, int bytes_to_read) = 0; - virtual void EndRequest(int request_id) = 0; - virtual void StopAll() = 0; }; // Used as base class. Holds Url request properties (url, method, referrer..) diff --git a/chrome_frame/test/automation_client_mock.cc b/chrome_frame/test/automation_client_mock.cc index 6bc6e28..0512336 100644 --- a/chrome_frame/test/automation_client_mock.cc +++ b/chrome_frame/test/automation_client_mock.cc @@ -49,27 +49,6 @@ void MockProxyFactory::GetServerImpl(ChromeFrameAutomationProxy* pxy, base::TimeDelta::FromMilliseconds(params->launch_timeout()) / 2); } -void CFACMockTest::SetAutomationServerOk(int times) { - EXPECT_CALL(factory_, GetAutomationServer(testing::NotNull(), - LaunchParamProfileEq(profile_path_.BaseName().value()), - testing::NotNull())) - .Times(times) - .WillRepeatedly(testing::Invoke(CreateFunctor(&factory_, - &MockProxyFactory::GetServerImpl, get_proxy(), id_, - AUTOMATION_SUCCESS))); - - EXPECT_CALL(factory_, - ReleaseAutomationServer(testing::Eq(id_), testing::NotNull())) - .Times(times); -} - -void CFACMockTest::Set_CFD_LaunchFailed(AutomationLaunchResult result) { - EXPECT_CALL(cfd_, OnAutomationServerLaunchFailed(testing::Eq(result), - testing::_)) - .Times(1) - .WillOnce(QUIT_LOOP(loop_)); -} - MATCHER_P(MsgType, msg_type, "IPC::Message::type()") { const IPC::Message& m = arg; return (m.type() == msg_type); @@ -112,7 +91,6 @@ class CFACWithChrome : public testing::Test { virtual void TearDown() OVERRIDE; static base::FilePath profile_path_; - MockCFDelegate cfd_; scoped_refptr<ChromeFrameAutomationClient> client_; scoped_refptr<ChromeFrameLaunchParams> launch_params_; chrome_frame_test::TimedMsgLoop loop_; @@ -145,31 +123,3 @@ void CFACWithChrome::SetUp() { void CFACWithChrome::TearDown() { client_->Uninitialize(); } - -// We mock ChromeFrameDelegate only. The rest is with real AutomationProxy -TEST_F(CFACWithChrome, CreateTooFast) { - int timeout = 0; // Chrome cannot send Hello message so fast. - - EXPECT_CALL(cfd_, OnAutomationServerLaunchFailed(AUTOMATION_TIMEOUT, _)) - .WillOnce(QUIT_LOOP(loop_)); - - launch_params_->set_launch_timeout(timeout); - EXPECT_TRUE(client_->Initialize(&cfd_, launch_params_)); - loop_.RunFor(kChromeLaunchTimeout); -} - -// This test may fail if Chrome take more that 10 seconds (timeout var) to -// launch. In this case GMock shall print something like "unexpected call to -// OnAutomationServerLaunchFailed". I'm yet to find out how to specify -// that this is an unexpected call, and still to execute an action. -TEST_F(CFACWithChrome, CreateNotSoFast) { - EXPECT_CALL(cfd_, OnAutomationServerReady()) - .WillOnce(QUIT_LOOP(loop_)); - - EXPECT_CALL(cfd_, OnAutomationServerLaunchFailed(_, _)) - .Times(0); - - EXPECT_TRUE(client_->Initialize(&cfd_, launch_params_)); - - loop_.RunFor(kChromeLaunchTimeout); -} diff --git a/chrome_frame/test/automation_client_mock.h b/chrome_frame/test/automation_client_mock.h index 131bb8e..f606c8c 100644 --- a/chrome_frame/test/automation_client_mock.h +++ b/chrome_frame/test/automation_client_mock.h @@ -17,58 +17,6 @@ using testing::StrictMock; -// ChromeFrameAutomationClient [CFAC] tests. -struct MockCFDelegate : public ChromeFrameDelegateImpl { - MOCK_CONST_METHOD0(GetWindow, WindowType()); - MOCK_METHOD1(GetBounds, void(RECT* bounds)); - MOCK_METHOD0(GetDocumentUrl, std::string()); - MOCK_METHOD2(ExecuteScript, bool(const std::string& script, - std::string* result)); - MOCK_METHOD0(OnAutomationServerReady, void()); - MOCK_METHOD2(OnAutomationServerLaunchFailed, void( - AutomationLaunchResult reason, const std::string& server_version)); - // This remains in interface since we call it if Navigate() - // returns immediate error. - MOCK_METHOD2(OnLoadFailed, void(int error_code, const std::string& url)); - - // Do not mock this method. :) Use it as message demuxer and dispatcher - // to the following methods (which we mock) - // MOCK_METHOD1(OnMessageReceived, void(const IPC::Message&)); - - MOCK_METHOD0(OnChannelError, void(void)); - MOCK_METHOD1(OnLoad, void(const GURL& url)); - MOCK_METHOD2(OnRequestStart, void(int request_id, - const AutomationURLRequest& request)); - MOCK_METHOD2(OnRequestRead, void(int request_id, int bytes_to_read)); - MOCK_METHOD2(OnRequestEnd, void(int request_id, - const net::URLRequestStatus& status)); - - // Use for sending network responses - void SetRequestDelegate(PluginUrlRequestDelegate* request_delegate) { - request_delegate_ = request_delegate; - } - - void ReplyStarted(int request_id, const char* headers) { - request_delegate_->OnResponseStarted(request_id, "text/html", headers, - 0, base::Time::Now(), std::string(), 0, net::HostPortPair(), 0); - } - - void ReplyData(int request_id, const std::string* data) { - request_delegate_->OnReadComplete(request_id, *data); - } - - void Reply(const net::URLRequestStatus& status, int request_id) { - request_delegate_->OnResponseEnd(request_id, status); - } - - void Reply404(int request_id) { - ReplyStarted(request_id, "HTTP/1.1 404\r\n\r\n"); - Reply(net::URLRequestStatus(), request_id); - } - - PluginUrlRequestDelegate* request_delegate_; -}; - class MockAutomationProxy : public ChromeFrameAutomationProxy { public: MOCK_METHOD1(Send, bool(IPC::Message*)); @@ -100,71 +48,4 @@ struct MockAutomationMessageSender : public AutomationMessageSender { StrictMock<MockAutomationProxy>* proxy_; }; -// [CFAC] -- uses a ProxyFactory for creation of ChromeFrameAutomationProxy -// -- uses ChromeFrameAutomationProxy -// -- uses TabProxy obtained from ChromeFrameAutomationProxy -// -- uses ChromeFrameDelegate as outgoing interface -// -// We mock ProxyFactory to return mock object (MockAutomationProxy) implementing -// ChromeFrameAutomationProxy interface. -// Since CFAC uses TabProxy for few calls and TabProxy is not easy mockable, -// we create 'real' TabProxy but with fake AutomationSender (the one responsible -// for sending messages over channel). -// Additionally we have mock implementation ChromeFrameDelagate interface - -// MockCFDelegate. - -// Test fixture, saves typing all of it's members. -class CFACMockTest : public testing::Test { - public: - MockProxyFactory factory_; - MockCFDelegate cfd_; - chrome_frame_test::TimedMsgLoop loop_; - // Most of the test uses the mocked proxy, but some tests need - // to validate the functionality of the real proxy object. - // So we have a mock that is used as the default for the returned_proxy_ - // pointer, but tests can set their own pointer in there as needed. - StrictMock<MockAutomationProxy> mock_proxy_; - ChromeFrameAutomationProxy* returned_proxy_; - scoped_ptr<AutomationHandleTracker> tracker_; - MockAutomationMessageSender dummy_sender_; - scoped_refptr<TabProxy> tab_; - // the victim of all tests - scoped_refptr<ChromeFrameAutomationClient> client_; - - base::FilePath profile_path_; - int timeout_; - void* id_; // Automation server id we are going to return - int tab_handle_; // Tab handle. Any non-zero value is Ok. - - inline ChromeFrameAutomationProxy* get_proxy() { - return returned_proxy_; - } - - inline void CreateTab() { - ASSERT_EQ(NULL, tab_.get()); - tab_ = new TabProxy(&dummy_sender_, tracker_.get(), tab_handle_); - } - - // Easy methods to set expectations. - void SetAutomationServerOk(int times); - void Set_CFD_LaunchFailed(AutomationLaunchResult result); - - protected: - CFACMockTest() - : timeout_(500), - returned_proxy_(static_cast<ChromeFrameAutomationProxy*>(&mock_proxy_)) { - GetChromeFrameProfilePath(L"Adam.N.Epilinter", &profile_path_); - id_ = reinterpret_cast<void*>(5); - tab_handle_ = 3; - } - - virtual void SetUp() { - dummy_sender_.ForwardTo(&mock_proxy_); - tracker_.reset(new AutomationHandleTracker()); - - client_ = new ChromeFrameAutomationClient; - client_->set_proxy_factory(&factory_); - } -}; - #endif // CHROME_FRAME_TEST_AUTOMATION_CLIENT_MOCK_H_ diff --git a/chrome_frame/test/html_util_unittests.cc b/chrome_frame/test/html_util_unittests.cc deleted file mode 100644 index 4ec4b72..0000000 --- a/chrome_frame/test/html_util_unittests.cc +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright (c) 2012 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 <windows.h> -#include <atlsecurity.h> -#include <shellapi.h> -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/file_util.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_handle.h" -#include "base/message_loop/message_loop.h" -#include "base/path_service.h" -#include "base/strings/utf_string_conversions.h" -#include "net/base/net_util.h" - -#include "chrome/browser/automation/url_request_automation_job.h" -#include "chrome/common/chrome_version_info.h" -#include "chrome_frame/chrome_frame_automation.h" -#include "chrome_frame/chrome_frame_delegate.h" -#include "chrome_frame/html_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "webkit/common/user_agent/user_agent_util.h" - -const char kChromeFrameUserAgent[] = "chromeframe"; - -class HtmlUtilUnittest : public testing::Test { - protected: - // Constructor - HtmlUtilUnittest() {} - - // Returns the test path given a test case. - virtual bool GetTestPath(const std::string& test_case, base::FilePath* path) { - if (!path) { - NOTREACHED(); - return false; - } - - base::FilePath test_path; - if (!PathService::Get(base::DIR_SOURCE_ROOT, &test_path)) { - NOTREACHED(); - return false; - } - - test_path = test_path.AppendASCII("chrome_frame"); - test_path = test_path.AppendASCII("test"); - test_path = test_path.AppendASCII("html_util_test_data"); - test_path = test_path.AppendASCII(test_case); - - *path = test_path; - return true; - } - - virtual bool GetTestData(const std::string& test_case, std::wstring* data) { - if (!data) { - NOTREACHED(); - return false; - } - - base::FilePath path; - if (!GetTestPath(test_case, &path)) { - NOTREACHED(); - return false; - } - - std::string raw_data; - base::ReadFileToString(path, &raw_data); - - // Convert to wide using the "best effort" assurance described in - // string_util.h - data->assign(UTF8ToWide(raw_data)); - return true; - } -}; - -TEST_F(HtmlUtilUnittest, BasicTest) { - std::wstring test_data; - GetTestData("basic_test.html", &test_data); - - HTMLScanner scanner(test_data.c_str()); - - // Grab the meta tag from the document and ensure that we get exactly one. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - ASSERT_EQ(1, tag_list.size()); - - // Pull out the http-equiv attribute and check its value: - HTMLScanner::StringRange attribute_value; - EXPECT_TRUE(tag_list[0].GetTagAttribute(L"http-equiv", &attribute_value)); - EXPECT_TRUE(attribute_value.Equals(L"X-UA-Compatible")); - - // Pull out the content attribute and check its value: - EXPECT_TRUE(tag_list[0].GetTagAttribute(L"content", &attribute_value)); - EXPECT_TRUE(attribute_value.Equals(L"chrome=1")); -} - -TEST_F(HtmlUtilUnittest, QuotesTest) { - std::wstring test_data; - GetTestData("quotes_test.html", &test_data); - - HTMLScanner scanner(test_data.c_str()); - - // Grab the meta tag from the document and ensure that we get exactly one. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - ASSERT_EQ(1, tag_list.size()); - - // Pull out the http-equiv attribute and check its value: - HTMLScanner::StringRange attribute_value; - EXPECT_TRUE(tag_list[0].GetTagAttribute(L"http-equiv", &attribute_value)); - EXPECT_TRUE(attribute_value.Equals(L"X-UA-Compatible")); - - // Pull out the content attribute and check its value: - EXPECT_TRUE(tag_list[0].GetTagAttribute(L"content", &attribute_value)); - EXPECT_TRUE(attribute_value.Equals(L"chrome=1")); -} - -TEST_F(HtmlUtilUnittest, DegenerateCasesTest) { - std::wstring test_data; - GetTestData("degenerate_cases_test.html", &test_data); - - HTMLScanner scanner(test_data.c_str()); - - // Scan for meta tags in the document. We expect not to pick up the one - // that appears to be there since it is technically inside a quote block. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - EXPECT_TRUE(tag_list.empty()); -} - -TEST_F(HtmlUtilUnittest, MultipleTagsTest) { - std::wstring test_data; - GetTestData("multiple_tags.html", &test_data); - - HTMLScanner scanner(test_data.c_str()); - - // Grab the meta tag from the document and ensure that we get exactly three. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - EXPECT_EQ(7, tag_list.size()); - - // Pull out the content attribute for each tag and check its value: - HTMLScanner::StringRange attribute_value; - HTMLScanner::StringRangeList::const_iterator tag_list_iter( - tag_list.begin()); - int valid_tag_count = 0; - for (; tag_list_iter != tag_list.end(); tag_list_iter++) { - HTMLScanner::StringRange attribute_value; - if (tag_list_iter->GetTagAttribute(L"http-equiv", &attribute_value) && - attribute_value.Equals(L"X-UA-Compatible")) { - EXPECT_TRUE(tag_list_iter->GetTagAttribute(L"content", &attribute_value)); - EXPECT_TRUE(attribute_value.Equals(L"chrome=1")); - valid_tag_count++; - } - } - EXPECT_EQ(3, valid_tag_count); -} - -TEST_F(HtmlUtilUnittest, ShortDegenerateTest1) { - std::wstring test_data( - L"<foo><META http-equiv=X-UA-Compatible content='chrome=1'"); - - HTMLScanner scanner(test_data.c_str()); - - // Scan for meta tags in the document. We expect not to pick up the one - // that is there since it is not properly closed. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - EXPECT_TRUE(tag_list.empty()); -} - -TEST_F(HtmlUtilUnittest, ShortDegenerateTest2) { - std::wstring test_data( - L"<foo <META http-equiv=X-UA-Compatible content='chrome=1'/>"); - - HTMLScanner scanner(test_data.c_str()); - - // Scan for meta tags in the document. We expect not to pick up the one - // that appears to be there since it is inside a non-closed tag. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - EXPECT_TRUE(tag_list.empty()); -} - -TEST_F(HtmlUtilUnittest, QuoteInsideHTMLCommentTest) { - std::wstring test_data( - L"<!-- comment' --><META http-equiv=X-UA-Compatible content='chrome=1'/>"); - - HTMLScanner scanner(test_data.c_str()); - - // Grab the meta tag from the document and ensure that we get exactly one. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - ASSERT_EQ(1, tag_list.size()); - - // Pull out the http-equiv attribute and check its value: - HTMLScanner::StringRange attribute_value; - EXPECT_TRUE(tag_list[0].GetTagAttribute(L"http-equiv", &attribute_value)); - EXPECT_TRUE(attribute_value.Equals(L"X-UA-Compatible")); - - // Pull out the content attribute and check its value: - EXPECT_TRUE(tag_list[0].GetTagAttribute(L"content", &attribute_value)); - EXPECT_TRUE(attribute_value.Equals(L"chrome=1")); -} - -TEST_F(HtmlUtilUnittest, CloseTagInsideHTMLCommentTest) { - std::wstring test_data( - L"<!-- comment> <META http-equiv=X-UA-Compatible content='chrome=1'/>-->"); - - HTMLScanner scanner(test_data.c_str()); - - // Ensure that the the meta tag is NOT detected. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - ASSERT_TRUE(tag_list.empty()); -} - -TEST_F(HtmlUtilUnittest, IEConditionalCommentTest) { - std::wstring test_data( - L"<!--[if lte IE 8]><META http-equiv=X-UA-Compatible content='chrome=1'/>" - L"<![endif]-->"); - - HTMLScanner scanner(test_data.c_str()); - - // Ensure that the the meta tag IS detected. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - ASSERT_EQ(1, tag_list.size()); -} - -TEST_F(HtmlUtilUnittest, IEConditionalCommentWithNestedCommentTest) { - std::wstring test_data( - L"<!--[if IE]><!--<META http-equiv=X-UA-Compatible content='chrome=1'/>" - L"--><![endif]-->"); - - HTMLScanner scanner(test_data.c_str()); - - // Ensure that the the meta tag IS NOT detected. - HTMLScanner::StringRangeList tag_list; - scanner.GetTagsByName(L"meta", &tag_list, L"body"); - ASSERT_TRUE(tag_list.empty()); -} - -TEST_F(HtmlUtilUnittest, IEConditionalCommentWithMultipleNestedTagsTest) { - std::wstring test_data( - L"<!--[if lte IE 8]> <META http-equiv=X-UA-Compatible " - L"content='chrome=1'/><foo bar></foo><foo baz/><![endif]-->" - L"<boo hoo><boo hah>"); - - HTMLScanner scanner(test_data.c_str()); - - // Ensure that the the meta tag IS detected. - HTMLScanner::StringRangeList meta_tag_list; - scanner.GetTagsByName(L"meta", &meta_tag_list, L"body"); - ASSERT_EQ(1, meta_tag_list.size()); - - // Ensure that the foo tags are also detected. - HTMLScanner::StringRangeList foo_tag_list; - scanner.GetTagsByName(L"foo", &foo_tag_list, L"body"); - ASSERT_EQ(2, foo_tag_list.size()); - - // Ensure that the boo tags are also detected. - HTMLScanner::StringRangeList boo_tag_list; - scanner.GetTagsByName(L"boo", &boo_tag_list, L"body"); - ASSERT_EQ(2, boo_tag_list.size()); -} - -TEST_F(HtmlUtilUnittest, IEConditionalCommentWithAlternateEndingTest) { - std::wstring test_data( - L"<!--[if lte IE 8]> <META http-equiv=X-UA-Compatible " - L"content='chrome=1'/><foo bar></foo><foo baz/><![endif]>" - L"<boo hoo><!--><boo hah>"); - - HTMLScanner scanner(test_data.c_str()); - - // Ensure that the the meta tag IS detected. - HTMLScanner::StringRangeList meta_tag_list; - scanner.GetTagsByName(L"meta", &meta_tag_list, L"body"); - ASSERT_EQ(1, meta_tag_list.size()); - - // Ensure that the foo tags are also detected. - HTMLScanner::StringRangeList foo_tag_list; - scanner.GetTagsByName(L"foo", &foo_tag_list, L"body"); - ASSERT_EQ(2, foo_tag_list.size()); - - // Ensure that the boo tags are also detected. - HTMLScanner::StringRangeList boo_tag_list; - scanner.GetTagsByName(L"boo", &boo_tag_list, L"body"); - ASSERT_EQ(2, boo_tag_list.size()); -} - -TEST_F(HtmlUtilUnittest, IEConditionalCommentNonTerminatedTest) { - // This test shouldn't detect any tags up until the end of the conditional - // comment tag. - std::wstring test_data( - L"<!--[if lte IE 8> <META http-equiv=X-UA-Compatible " - L"content='chrome=1'/><foo bar></foo><foo baz/><![endif]>" - L"<boo hoo><!--><boo hah>"); - - HTMLScanner scanner(test_data.c_str()); - - // Ensure that the the meta tag IS NOT detected. - HTMLScanner::StringRangeList meta_tag_list; - scanner.GetTagsByName(L"meta", &meta_tag_list, L"body"); - ASSERT_TRUE(meta_tag_list.empty()); - - // Ensure that the foo tags are NOT detected. - HTMLScanner::StringRangeList foo_tag_list; - scanner.GetTagsByName(L"foo", &foo_tag_list, L"body"); - ASSERT_TRUE(foo_tag_list.empty()); - - // Ensure that the boo tags are detected. - HTMLScanner::StringRangeList boo_tag_list; - scanner.GetTagsByName(L"boo", &boo_tag_list, L"body"); - ASSERT_EQ(2, boo_tag_list.size()); -} - -struct UserAgentTestCase { - std::string input_; - std::string expected_; -} user_agent_test_cases[] = { - { - "", "" - }, { - "Mozilla/4.7 [en] (WinNT; U)", - "Mozilla/4.7 [en] (WinNT; U; chromeframe/0.0.0.0)" - }, { - "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)", - "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT; chromeframe/0.0.0.0)" - }, { - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; T312461; " - ".NET CLR 1.1.4322)", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; T312461; " - ".NET CLR 1.1.4322; chromeframe/0.0.0.0)" - }, { - "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 4.0) Opera 5.11 [en]", - "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 4.0; chromeframe/0.0.0.0) " - "Opera 5.11 [en]" - }, { - "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)", - "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; " - "chromeframe/0.0.0.0)" - }, { - "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) " - "Gecko/20030208 Netscape/7.02", - "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2; " - "chromeframe/0.0.0.0) Gecko/20030208 Netscape/7.02" - }, { - "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040612 " - "Firefox/0.8", - "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6; chromeframe/0.0.0.0) " - "Gecko/20040612 Firefox/0.8" - }, { - "Mozilla/5.0 (compatible; Konqueror/3.2; Linux) (KHTML, like Gecko)", - "Mozilla/5.0 (compatible; Konqueror/3.2; Linux; chromeframe/0.0.0.0) " - "(KHTML, like Gecko)" - }, { - "Lynx/2.8.4rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.6h", - "Lynx/2.8.4rel.1 libwww-FM/2.14 SSL-MM/1.4.1 " - "OpenSSL/0.9.6h chromeframe/0.0.0.0", - }, { - "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.7.10) " - "Gecko/20050716 Firefox/1.0.6", - "Mozilla/5.0 (X11; U; Linux i686 (x86_64; chromeframe/0.0.0.0); en-US; " - "rv:1.7.10) Gecko/20050716 Firefox/1.0.6" - }, { - "Invalid/1.1 ((((((", - "Invalid/1.1 (((((( chromeframe/0.0.0.0", - }, { - "Invalid/1.1 ()))))", - "Invalid/1.1 ( chromeframe/0.0.0.0)))))", - }, { - "Strange/1.1 ()", - "Strange/1.1 ( chromeframe/0.0.0.0)", - } -}; - -TEST_F(HtmlUtilUnittest, AddChromeFrameToUserAgentValue) { - for (int i = 0; i < arraysize(user_agent_test_cases); ++i) { - std::string new_ua( - http_utils::AddChromeFrameToUserAgentValue( - user_agent_test_cases[i].input_)); - EXPECT_EQ(user_agent_test_cases[i].expected_, new_ua); - } - - // Now do the same test again, but test that we don't add the chromeframe - // tag if we've already added it. - for (int i = 0; i < arraysize(user_agent_test_cases); ++i) { - std::string ua(user_agent_test_cases[i].expected_); - std::string new_ua(http_utils::AddChromeFrameToUserAgentValue(ua)); - EXPECT_EQ(user_agent_test_cases[i].expected_, new_ua); - } -} - -TEST_F(HtmlUtilUnittest, RemoveChromeFrameFromUserAgentValue) { - for (int i = 0; i < arraysize(user_agent_test_cases); ++i) { - std::string new_ua( - http_utils::RemoveChromeFrameFromUserAgentValue( - user_agent_test_cases[i].expected_)); - EXPECT_EQ(user_agent_test_cases[i].input_, new_ua); - } - - // Also test that we don't modify the UA if chromeframe is not present. - for (int i = 0; i < arraysize(user_agent_test_cases); ++i) { - std::string ua(user_agent_test_cases[i].input_); - std::string new_ua(http_utils::RemoveChromeFrameFromUserAgentValue(ua)); - EXPECT_EQ(user_agent_test_cases[i].input_, new_ua); - } -} - -TEST_F(HtmlUtilUnittest, GetDefaultUserAgentHeaderWithCFTag) { - std::string ua(http_utils::GetDefaultUserAgentHeaderWithCFTag()); - EXPECT_NE(0u, ua.length()); - EXPECT_NE(std::string::npos, ua.find("Mozilla")); - EXPECT_NE(std::string::npos, ua.find(kChromeFrameUserAgent)); -} - -TEST_F(HtmlUtilUnittest, GetChromeUserAgent) { - // This code is duplicated from chrome_content_client.cc to avoid - // introducing a link-time dependency on chrome_common. - chrome::VersionInfo version_info; - std::string product("Chrome/"); - product += version_info.is_valid() ? version_info.Version() : "0.0.0.0"; - std::string chrome_ua(webkit_glue::BuildUserAgentFromProduct(product)); - - const char* ua = http_utils::GetChromeUserAgent(); - EXPECT_EQ(ua, chrome_ua); -} - -TEST_F(HtmlUtilUnittest, GetDefaultUserAgent) { - std::string ua(http_utils::GetDefaultUserAgent()); - EXPECT_NE(0u, ua.length()); - EXPECT_NE(std::string::npos, ua.find("Mozilla")); -} - -TEST_F(HtmlUtilUnittest, GetChromeFrameUserAgent) { - const char* call1 = http_utils::GetChromeFrameUserAgent(); - const char* call2 = http_utils::GetChromeFrameUserAgent(); - // Expect static buffer since caller does no cleanup. - EXPECT_EQ(call1, call2); - std::string ua(call1); - EXPECT_EQ("chromeframe/0.0.0.0", ua); -} - -TEST(HttpUtils, HasFrameBustingHeader) { - // Simple negative cases. - EXPECT_FALSE(http_utils::HasFrameBustingHeader("")); - EXPECT_FALSE(http_utils::HasFrameBustingHeader("Content-Type: text/plain")); - EXPECT_FALSE(http_utils::HasFrameBustingHeader("X-Frame-Optionss: ALLOWALL")); - // Explicit negative cases, test that we ignore case. - EXPECT_FALSE(http_utils::HasFrameBustingHeader("X-Frame-Options: ALLOWALL")); - EXPECT_FALSE(http_utils::HasFrameBustingHeader("X-Frame-Options: allowall")); - EXPECT_FALSE(http_utils::HasFrameBustingHeader("X-Frame-Options: ALLowalL")); - // Added space, ensure stripped out - EXPECT_FALSE(http_utils::HasFrameBustingHeader( - "X-Frame-Options: ALLOWALL ")); - // Added space with linefeed, ensure still stripped out - EXPECT_FALSE(http_utils::HasFrameBustingHeader( - "X-Frame-Options: ALLOWALL \r\n")); - // Multiple identical headers, all of them allowing framing. - EXPECT_FALSE(http_utils::HasFrameBustingHeader( - "X-Frame-Options: ALLOWALL\r\n" - "X-Frame-Options: ALLOWALL\r\n" - "X-Frame-Options: ALLOWALL")); - // Interleave with other headers. - EXPECT_FALSE(http_utils::HasFrameBustingHeader( - "Content-Type: text/plain\r\n" - "X-Frame-Options: ALLOWALL\r\n" - "Content-Length: 42")); - - // Simple positive cases. - EXPECT_TRUE(http_utils::HasFrameBustingHeader("X-Frame-Options: deny")); - EXPECT_TRUE(http_utils::HasFrameBustingHeader( - "X-Frame-Options: SAMEorigin")); - - // Verify that we pick up case changes in the header name too: - EXPECT_TRUE(http_utils::HasFrameBustingHeader("X-FRAME-OPTIONS: deny")); - EXPECT_TRUE(http_utils::HasFrameBustingHeader("x-frame-options: deny")); - EXPECT_TRUE(http_utils::HasFrameBustingHeader("X-frame-optionS: deny")); - EXPECT_TRUE(http_utils::HasFrameBustingHeader("X-Frame-optionS: deny")); - - // Allowall entries do not override the denying entries, are - // order-independent, and the deny entries can interleave with - // other headers. - EXPECT_TRUE(http_utils::HasFrameBustingHeader( - "Content-Length: 42\r\n" - "X-Frame-Options: ALLOWall\r\n" - "X-Frame-Options: deny\r\n")); - EXPECT_TRUE(http_utils::HasFrameBustingHeader( - "X-Frame-Options: ALLOWall\r\n" - "Content-Length: 42\r\n" - "X-Frame-Options: SAMEORIGIN\r\n")); - EXPECT_TRUE(http_utils::HasFrameBustingHeader( - "X-Frame-Options: deny\r\n" - "X-Frame-Options: ALLOWall\r\n" - "Content-Length: 42\r\n")); - EXPECT_TRUE(http_utils::HasFrameBustingHeader( - "X-Frame-Options: SAMEORIGIN\r\n" - "X-Frame-Options: ALLOWall\r\n")); -} diff --git a/chrome_frame/test/net/fake_external_tab.cc b/chrome_frame/test/net/fake_external_tab.cc index 9bac14d..8ae7b87 100644 --- a/chrome_frame/test/net/fake_external_tab.cc +++ b/chrome_frame/test/net/fake_external_tab.cc @@ -2,1016 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome_frame/test/net/fake_external_tab.h" - -#include <atlbase.h> -#include <atlcom.h> -#include <exdisp.h> -#include <Winsock2.h> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/debug/debugger.h" -#include "base/file_util.h" -#include "base/file_version_info.h" -#include "base/files/scoped_temp_dir.h" -#include "base/i18n/icu_util.h" -#include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" -#include "base/prefs/json_pref_store.h" -#include "base/prefs/pref_registry_simple.h" -#include "base/prefs/pref_service.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/system_monitor/system_monitor.h" -#include "base/test/test_timeouts.h" -#include "base/threading/platform_thread.h" -#include "base/threading/thread.h" -#include "base/win/scoped_comptr.h" -#include "base/win/scoped_handle.h" -#include "chrome/app/chrome_main_delegate.h" -#include "chrome/browser/automation/automation_provider_list.h" -#include "chrome/browser/chrome_content_browser_client.h" -#include "chrome/browser/prefs/browser_prefs.h" -#include "chrome/browser/prefs/proxy_config_dictionary.h" -#include "chrome/browser/process_singleton.h" -#include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/renderer_host/web_cache_manager.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_content_client.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_paths_internal.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" -#include "chrome/renderer/chrome_content_renderer_client.h" -#include "chrome/test/base/ui_test_utils.h" -#include "chrome/test/logging/win/file_logger.h" -#include "chrome/test/logging/win/log_file_printer.h" -#include "chrome/test/logging/win/test_log_collector.h" -#include "chrome_frame/crash_server_init.h" -#include "chrome_frame/test/chrome_frame_test_utils.h" -#include "chrome_frame/test/ie_configurator.h" -#include "chrome_frame/test/net/test_automation_resource_message_filter.h" -#include "chrome_frame/test/simulate_input.h" -#include "chrome_frame/test/win_event_receiver.h" -#include "chrome_frame/utils.h" -#include "content/public/app/content_main.h" -#include "content/public/app/startup_helper_win.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/content_client.h" -#include "content/public/common/content_paths.h" -#include "net/base/net_util.h" -#include "net/url_request/url_request_test_util.h" -#include "sandbox/win/src/sandbox_types.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/resource/resource_bundle_win.h" -#include "ui/base/ui_base_paths.h" - -#if defined(USE_AURA) -#include "ui/aura/env.h" -#include "ui/gfx/screen.h" -#include "ui/views/widget/desktop_aura/desktop_screen.h" -#endif - -using content::BrowserThread; - -namespace { - -// We must store this globally so that our main delegate can set it. -static CFUrlRequestUnittestRunner* g_test_suite = NULL; - -// Copied here for access by CreateBrowserMainParts and InitGoogleTest. -static int g_argc = 0; -static char** g_argv = NULL; - -// A special command line switch to allow developers to manually launch the -// browser and debug CF inside the browser. -const char kManualBrowserLaunch[] = "manual-browser"; - -// Pops up a message box after the test environment has been set up -// and before tearing it down. Useful for when debugging tests and not -// the test environment that's been set up. -const char kPromptAfterSetup[] = "prompt-after-setup"; - -const int kTestServerPort = 4666; -// The test HTML we use to initialize Chrome Frame. -// Note that there's a little trick in there to avoid an extra URL request -// that the browser will otherwise make for the site's favicon. -// If we don't do this the browser will create a new URL request after -// the CF page has been initialized and that URL request will confuse the -// global URL instance counter in the unit tests and subsequently trip -// some DCHECKs. -const char kChromeFrameHtml[] = "<html><head>" - "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />" - "<link rel=\"shortcut icon\" href=\"file://c:\\favicon.ico\"/>" - "</head><body>Chrome Frame should now be loaded</body></html>"; - -// Uses the IAccessible interface for the window to set the focus. -// This can be useful when you don't have control over the thread that -// owns the window. -// NOTE: this depends on oleacc.lib which the net tests already depend on -// but other unit tests don't depend on oleacc so we can't just add the method -// directly into chrome_frame_test_utils.cc (without adding a -// #pragma comment(lib, "oleacc.lib")). -bool SetFocusToAccessibleWindow(HWND hwnd) { - bool ret = false; - base::win::ScopedComPtr<IAccessible> acc; - AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, - reinterpret_cast<void**>(acc.Receive())); - if (acc) { - VARIANT self = { VT_I4 }; - self.lVal = CHILDID_SELF; - ret = SUCCEEDED(acc->accSelect(SELFLAG_TAKEFOCUS, self)); - } - return ret; -} - -class FakeContentBrowserClient : public chrome::ChromeContentBrowserClient { - public: - virtual ~FakeContentBrowserClient() {} - - virtual content::BrowserMainParts* CreateBrowserMainParts( - const content::MainFunctionParams& parameters) OVERRIDE; -}; - -base::LazyInstance<ChromeContentClient> - g_chrome_content_client = LAZY_INSTANCE_INITIALIZER; - -// Override the default ContentBrowserClient to let Chrome participate in -// content logic. Must be done before any tabs are created. -base::LazyInstance<FakeContentBrowserClient> - g_browser_client = LAZY_INSTANCE_INITIALIZER; - -base::LazyInstance<ChromeContentRendererClient> - g_renderer_client = LAZY_INSTANCE_INITIALIZER; - -class FakeMainDelegate : public content::ContentMainDelegate { - public: - virtual ~FakeMainDelegate() {} - - virtual bool BasicStartupComplete(int* exit_code) OVERRIDE { - logging_win::InstallTestLogCollector( - testing::UnitTest::GetInstance()); - - content::SetContentClient(&g_chrome_content_client.Get()); - content::SetRendererClientForTesting(&g_renderer_client.Get()); - return false; - } - - // Override the default ContentBrowserClient to let Chrome participate in - // content logic. We use a subclass of Chrome's implementation, - // FakeContentBrowserClient, to override CreateBrowserMainParts. Must - // be done before any tabs are created. - virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE { - return &g_browser_client.Get(); - }; -}; - -void FilterDisabledTests() { - if (::testing::FLAGS_gtest_filter.length() && - ::testing::FLAGS_gtest_filter != "*") { - // Don't override user specified filters. - return; - } - - const char* disabled_tests[] = { - // Tests disabled since they're testing the same functionality used - // by the TestAutomationProvider. - "URLRequestTest.Intercept", - "URLRequestTest.InterceptNetworkError", - "URLRequestTest.InterceptRestartRequired", - "URLRequestTest.InterceptRespectsCancelMain", - "URLRequestTest.InterceptRespectsCancelRedirect", - "URLRequestTest.InterceptRespectsCancelFinal", - "URLRequestTest.InterceptRespectsCancelInRestart", - "URLRequestTest.InterceptRedirect", - "URLRequestTest.InterceptServerError", - "URLRequestTestFTP.*", - - // Tests that are currently not working: - - // Temporarily disabled because they needs user input (login dialog). - "URLRequestTestHTTP.BasicAuth", - "URLRequestTestHTTP.BasicAuthWithCookies", - - // ChromeFrame does not support load timing. - "URLRequestTestHTTP.BasicAuthLoadTiming", - "URLRequestTestHTTP.GetTestLoadTiming", - "URLRequestTestHTTP.RedirectLoadTiming", - - // HTTPS tests temporarily disabled due to the certificate error dialog. - // TODO(tommi): The tests currently fail though, so need to fix. - "HTTPSRequestTest.HTTPSMismatchedTest", - "HTTPSRequestTest.HTTPSExpiredTest", - "HTTPSRequestTest.ClientAuthTest", - - // More HTTPS tests failing due to certificate dialogs. - // http://crbug.com/102991 - "URLRequestTestHTTP.HTTPSToHTTPRedirectNoRefererTest", - "HTTPSRequestTest.HTTPSGetTest", - - // Tests chrome's network stack's cache (might not apply to CF). - "URLRequestTestHTTP.VaryHeader", - "URLRequestTestHTTP.GetZippedTest", - - // Tests that requests can be blocked asynchronously in states - // OnBeforeURLRequest, OnBeforeSendHeaders and OnHeadersReceived. At least - // the second state is not supported by CF. - "URLRequestTestHTTP.NetworkDelegateBlockAsynchronously", - - // Tests for cancelling requests in states OnBeforeSendHeaders and - // OnHeadersReceived, which do not seem supported by CF. - "URLRequestTestHTTP.NetworkDelegateCancelRequestSynchronously2", - "URLRequestTestHTTP.NetworkDelegateCancelRequestSynchronously3", - "URLRequestTestHTTP.NetworkDelegateCancelRequestAsynchronously2", - "URLRequestTestHTTP.NetworkDelegateCancelRequestAsynchronously3", - - // Tests that requests can be cancelled while blocking in - // OnBeforeSendHeaders state. But this state is not supported by CF. - "URLRequestTestHTTP.NetworkDelegateCancelWhileWaiting2", - - // Tests that requests can be cancelled while blocking in - // OnHeadersRecevied state. At first glance, this state does not appear to - // be supported by CF. - "URLRequestTestHTTP.NetworkDelegateCancelWhileWaiting3", - - // Tests that requests can be cancelled while blocking in OnAuthRequired - // state. At first glance, this state does not appear to be supported by CF. - // IE displays a credentials prompt during this test - I (erikwright) - // believe that, from Chrome's point of view this is not a state change. In - // any case, I also believe that we do not have support for handling the - // credentials dialog during tests. - "URLRequestTestHTTP.NetworkDelegateCancelWhileWaiting4", - - // I suspect we can only get this one to work (if at all) on IE8 and - // later by using the new INTERNET_OPTION_SUPPRESS_BEHAVIOR flags - // See http://msdn.microsoft.com/en-us/library/aa385328(VS.85).aspx - "URLRequestTest.DoNotSaveCookies", - "URLRequestTest.DelayedCookieCallback", - - // TODO(ananta): This test has been consistently failing. Disabling it for - // now. - "URLRequestTestHTTP.GetTest_NoCache", - - // These tests use HTTPS, and IE's trust store does not have the test - // certs. So these tests time out waiting for user input. The - // functionality they test (HTTP Strict Transport Security and - // HTTP-based Public Key Pinning) does not work in Chrome Frame anyway. - "URLRequestTestHTTP.ProcessPKP", - "URLRequestTestHTTP.ProcessSTS", - "URLRequestTestHTTP.ProcessSTSOnce", - "URLRequestTestHTTP.ProcessSTSAndPKP", - "URLRequestTestHTTP.ProcessSTSAndPKP2", - - // These tests have been disabled as the Chrome cookie policies don't make - // sense or have not been implemented for the host network stack. - "URLRequestTest.DoNotSaveCookies_ViaPolicy", - "URLRequestTest.DoNotSendCookies_ViaPolicy", - "URLRequestTest.DoNotSaveCookies_ViaPolicy_Async", - "URLRequestTest.CookiePolicy_ForceSession", - "URLRequestTest.DoNotSendCookies", - "URLRequestTest.DoNotSendCookies_ViaPolicy_Async", - "URLRequestTest.CancelTest_During_OnGetCookies", - "URLRequestTest.CancelTest_During_OnSetCookie", - - // These tests are disabled as they rely on functionality provided by - // Chrome's HTTP stack like the ability to set the proxy for a URL, etc. - "URLRequestTestHTTP.ProxyTunnelRedirectTest", - "URLRequestTestHTTP.NetworkDelegateTunnelConnectionFailed", - "URLRequestTestHTTP.UnexpectedServerAuthTest", - - // These tests are disabled as they expect an empty UA to be echoed back - // from the server which is not the case in ChromeFrame. - "URLRequestTestHTTP.DefaultUserAgent", - "URLRequestTestHTTP.EmptyHttpUserAgentSettings", - // This test modifies the UploadData object after it has been marshaled to - // ChromeFrame. We don't support this. - "URLRequestTestHTTP.TestPostChunkedDataAfterStart", - - // Do not work in CF, it may well be that IE is unconditionally - // adding Accept-Encoding header by default to outgoing requests. - "URLRequestTestHTTP.DefaultAcceptEncoding", - "URLRequestTestHTTP.OverrideAcceptEncoding", - - // Not supported in ChromeFrame as we use IE's network stack. - "URLRequestTest.NetworkDelegateProxyError", - "URLRequestTest.AcceptClockSkewCookieWithWrongDateTimezone", - - // URLRequestAutomationJob needs to support NeedsAuth. - // http://crbug.com/98446 - "URLRequestTestHTTP.NetworkDelegateOnAuthRequiredSyncNoAction", - "URLRequestTestHTTP.NetworkDelegateOnAuthRequiredSyncSetAuth", - "URLRequestTestHTTP.NetworkDelegateOnAuthRequiredSyncCancel", - "URLRequestTestHTTP.NetworkDelegateOnAuthRequiredAsyncNoAction", - "URLRequestTestHTTP.NetworkDelegateOnAuthRequiredAsyncSetAuth", - "URLRequestTestHTTP.NetworkDelegateOnAuthRequiredAsyncCancel", - - // Flaky on the tryservers, http://crbug.com/103097 - "URLRequestTestHTTP.MultipleRedirectTest", - "URLRequestTestHTTP.NetworkDelegateRedirectRequest", - - // These tests are unsupported in CF. - "HTTPSRequestTest.HTTPSPreloadedHSTSTest", - "HTTPSRequestTest.HTTPSErrorsNoClobberTSSTest", - "HTTPSRequestTest.HSTSPreservesPosts", - "HTTPSRequestTest.ResumeTest", - "HTTPSRequestTest.SSLSessionCacheShardTest", - "HTTPSRequestTest.SSLSessionCacheShardTest", - "HTTPSRequestTest.SSLv3Fallback", - "HTTPSRequestTest.TLSv1Fallback", - "HTTPSHardFailTest.*", - "HTTPSOCSPTest.*", - "HTTPSEVCRLSetTest.*", - "HTTPSCRLSetTest.*", - - // Chrome Frame doesn't support GetFullRequestHeaders. - "URLRequestTest*.*_GetFullRequestHeaders", - - // IE redirects to data: URLs differently. - "URLRequestTestHTTP.RestrictDataRedirects", - - // Chrome frame doesn't use URLRequestHttpJob, so doesn't call into - // NetworkDelegates in OnStartCompleted, unlike Chrome. - "URLRequestTestHTTP.NetworkDelegateInfo", - "URLRequestTestHTTP.NetworkDelegateInfoAuth", - "URLRequestTestHTTP.NetworkDelegateInfoRedirect", - }; - - const char* ie9_disabled_tests[] = { - // These always hang on Joi's box with IE9, http://crbug.com/105435. - // Several other tests, e.g. URLRequestTestHTTP.CancelTest2, 3 and - // 5, often hang but not always. - "URLRequestTestHTTP.NetworkDelegateRedirectRequestPost", - "URLRequestTestHTTP.GetTest", - "HTTPSRequestTest.HTTPSPreloadedHSTSTest", - // This always hangs on erikwright's box with IE9. - "URLRequestTestHTTP.Redirect302Tests" - }; - - std::string filter("-"); // All following filters will be negative. - for (int i = 0; i < arraysize(disabled_tests); ++i) { - if (i > 0) - filter += ":"; - - // If the rule has the form TestSuite.TestCase, also filter out - // TestSuite.FLAKY_TestCase . This way the exclusion rules above - // don't need to be updated when a test is marked flaky. - base::StringPiece test_name(disabled_tests[i]); - size_t dot_index = test_name.find('.'); - if (dot_index != base::StringPiece::npos && - dot_index + 1 < test_name.size()) { - test_name.substr(0, dot_index).AppendToString(&filter); - filter += ".FLAKY_"; - test_name.substr(dot_index + 1).AppendToString(&filter); - filter += ":"; - } - filter += disabled_tests[i]; - } - - if (chrome_frame_test::GetInstalledIEVersion() >= IE_9) { - for (int i = 0; i < arraysize(ie9_disabled_tests); ++i) { - filter += ":"; - filter += ie9_disabled_tests[i]; - } - } - - ::testing::FLAGS_gtest_filter = filter; -} - -} // namespace - -// Same as BrowserProcessImpl, but uses custom profile manager. -class FakeBrowserProcessImpl : public BrowserProcessImpl { - public: - FakeBrowserProcessImpl(base::SequencedTaskRunner* local_state_task_runner, - const CommandLine& command_line) - : BrowserProcessImpl(local_state_task_runner, command_line) { - profiles_dir_.CreateUniqueTempDir(); - } - - virtual ~FakeBrowserProcessImpl() {} - - virtual ProfileManager* profile_manager() OVERRIDE { - if (!profile_manager_.get()) { - profile_manager_.reset( - new ProfileManagerWithoutInit(profiles_dir_.path())); - } - return profile_manager_.get(); - } - - virtual MetricsService* metrics_service() OVERRIDE { - return NULL; - } - - void DestroyProfileManager() { - profile_manager_.reset(); - } - - private: - base::ScopedTempDir profiles_dir_; - scoped_ptr<ProfileManager> profile_manager_; -}; - -class SupplyProxyCredentials : public WindowObserver { - public: - SupplyProxyCredentials(const char* username, const char* password); - - protected: - struct DialogProps { - HWND username_; - HWND password_; - }; - - virtual void OnWindowOpen(HWND hwnd); - virtual void OnWindowClose(HWND hwnd); - static BOOL CALLBACK EnumChildren(HWND hwnd, LPARAM param); - - protected: - std::string username_; - std::string password_; -}; - - -SupplyProxyCredentials::SupplyProxyCredentials(const char* username, - const char* password) - : username_(username), password_(password) { -} - -void SupplyProxyCredentials::OnWindowClose(HWND hwnd) { } - -void SupplyProxyCredentials::OnWindowOpen(HWND hwnd) { - DialogProps props = {0}; - ::EnumChildWindows(hwnd, EnumChildren, reinterpret_cast<LPARAM>(&props)); - DCHECK(::IsWindow(props.username_)); - DCHECK(::IsWindow(props.password_)); - - // We can't use SetWindowText to set the username/password, so simulate - // keyboard input instead. - simulate_input::ForceSetForegroundWindow(hwnd); - CHECK(SetFocusToAccessibleWindow(props.username_)); - simulate_input::SendStringA(username_.c_str()); - Sleep(100); - - simulate_input::SendCharA(VK_TAB, simulate_input::NONE); - Sleep(100); - simulate_input::SendStringA(password_.c_str()); - - Sleep(100); - simulate_input::SendCharA(VK_RETURN, simulate_input::NONE); -} - -// static -BOOL SupplyProxyCredentials::EnumChildren(HWND hwnd, LPARAM param) { - if (!::IsWindowVisible(hwnd)) - return TRUE; // Ignore but continue to enumerate. - - DialogProps* props = reinterpret_cast<DialogProps*>(param); - - char class_name[MAX_PATH] = {0}; - ::GetClassNameA(hwnd, class_name, arraysize(class_name)); - if (lstrcmpiA(class_name, "Edit") == 0) { - if (props->username_ == NULL || props->username_ == hwnd) { - props->username_ = hwnd; - } else if (props->password_ == NULL) { - props->password_ = hwnd; - } - } else { - EnumChildWindows(hwnd, EnumChildren, param); - } - - return TRUE; -} - -FakeExternalTab::FakeExternalTab() { - user_data_dir_ = chrome_frame_test::GetProfilePathForIE(); - - if (base::PathExists(user_data_dir_)) { - VLOG(1) << __FUNCTION__ << " deleting IE Profile user data directory " - << user_data_dir_.value(); - bool deleted = base::DeleteFile(user_data_dir_, true); - LOG_IF(ERROR, !deleted) << "Failed to delete user data directory directory " - << user_data_dir_.value(); - } - - PathService::Get(chrome::DIR_USER_DATA, &overridden_user_dir_); - PathService::Override(chrome::DIR_USER_DATA, user_data_dir_); -} - -FakeExternalTab::~FakeExternalTab() { - if (!overridden_user_dir_.empty()) { - PathService::Override(chrome::DIR_USER_DATA, overridden_user_dir_); - } -} - -void FakeExternalTab::Initialize() { - DCHECK(g_browser_process == NULL); - - TestTimeouts::Initialize(); - - // Load Chrome.dll as our resource dll. - base::FilePath dll; - PathService::Get(base::DIR_MODULE, &dll); - dll = dll.Append(chrome::kBrowserResourcesDll); - HMODULE res_mod = ::LoadLibraryExW(dll.value().c_str(), - NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); - DCHECK(res_mod); - _AtlBaseModule.SetResourceInstance(res_mod); - - // Point the ResourceBundle at chrome.dll. - ui::SetResourcesDataDLL(_AtlBaseModule.GetResourceInstance()); - - ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); - - base::FilePath resources_pack_path; - PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path); - ResourceBundle::GetSharedInstance().AddDataPackFromPath( - resources_pack_path, ui::SCALE_FACTOR_NONE); - - CommandLine* cmd = CommandLine::ForCurrentProcess(); - // Disable Device Discovery with switch because this test does not respect - // BrowserContextKeyedBaseFactory::ServiceIsNULLWhileTesting. - cmd->AppendSwitch(switches::kDisableDeviceDiscoveryNotifications); - cmd->AppendSwitch(switches::kDisableWebResources); - cmd->AppendSwitch(switches::kSingleProcess); - - base::FilePath local_state_path; - CHECK(PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path)); - scoped_refptr<base::SequencedTaskRunner> local_state_task_runner = - JsonPrefStore::GetTaskRunnerForFile(local_state_path, - BrowserThread::GetBlockingPool()); - browser_process_.reset(new FakeBrowserProcessImpl(local_state_task_runner, - *cmd)); - // BrowserProcessImpl's constructor should set g_browser_process. - DCHECK(g_browser_process); - g_browser_process->SetApplicationLocale("en-US"); - - content::RenderProcessHost::SetRunRendererInProcess(true); - - // TODO(joi): Registration should be done up front via browser_prefs.cc - scoped_refptr<PrefRegistrySimple> registry = static_cast<PrefRegistrySimple*>( - browser_process_->local_state()->DeprecatedGetPrefRegistry()); - if (!browser_process_->local_state()->FindPreference( - prefs::kMetricsReportingEnabled)) { - registry->RegisterBooleanPref(prefs::kMetricsReportingEnabled, false); - } -} - -void FakeExternalTab::InitializePostThreadsCreated() { -#if defined(USE_AURA) - aura::Env::CreateInstance(); - gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, - views::CreateDesktopScreen()); -#endif - base::FilePath profile_path( - profiles::GetDefaultProfileDir(user_data())); - Profile* profile = - g_browser_process->profile_manager()->GetProfile(profile_path); -} - -void FakeExternalTab::Shutdown() { - browser_process_.reset(); - g_browser_process = NULL; - - ResourceBundle::CleanupSharedInstance(); -} - -FakeBrowserProcessImpl* FakeExternalTab::browser_process() const { - return browser_process_.get(); -} - -CFUrlRequestUnittestRunner::CFUrlRequestUnittestRunner(int argc, char** argv) - : NetTestSuite(argc, argv, false), - chrome_frame_html_("/chrome_frame", kChromeFrameHtml), - registrar_(chrome_frame_test::GetTestBedType()), - test_result_(0), - launch_browser_( - !CommandLine::ForCurrentProcess()->HasSwitch(kManualBrowserLaunch)), - prompt_after_setup_( - CommandLine::ForCurrentProcess()->HasSwitch(kPromptAfterSetup)), - tests_ran_(false) { -} - -CFUrlRequestUnittestRunner::~CFUrlRequestUnittestRunner() { -} - -void CFUrlRequestUnittestRunner::StartChromeFrameInHostBrowser() { - if (!launch_browser_) - return; - - chrome_frame_test::CloseAllIEWindows(); - - // Tweak IE settings to make it amenable to testing before launching it. - ie_configurator_.reset(chrome_frame_test::CreateConfigurator()); - if (ie_configurator_.get() != NULL) { - ie_configurator_->Initialize(); - ie_configurator_->ApplySettings(); - } - - test_http_server_.reset(new test_server::SimpleWebServer("127.0.0.1", - kTestServerPort)); - test_http_server_->AddResponse(&chrome_frame_html_); - std::wstring url(base::StringPrintf(L"http://localhost:%i/chrome_frame", - kTestServerPort)); - - // Launch IE. This launches IE correctly on Vista too. - base::win::ScopedHandle ie_process(chrome_frame_test::LaunchIE(url)); - EXPECT_TRUE(ie_process.IsValid()); - - // NOTE: If you're running IE8 and CF is not being loaded, you need to - // disable IE8's prebinding until CF properly handles that situation. - // - // HKCU\Software\Microsoft\Internet Explorer\Main - // Value name: EnablePreBinding (REG_DWORD) - // Value: 0 -} - -void CFUrlRequestUnittestRunner::ShutDownHostBrowser() { - if (launch_browser_) - chrome_frame_test::CloseAllIEWindows(); -} - -void CFUrlRequestUnittestRunner::OnIEShutdownFailure() { - LOG(ERROR) << "Failed to shutdown IE and npchrome_frame cleanly after test " - "execution."; - - if (ie_configurator_.get() != NULL) - ie_configurator_->RevertSettings(); - - StopFileLogger(true); - ::ExitProcess(0); -} - -// Override virtual void Initialize to not call icu initialize. -void CFUrlRequestUnittestRunner::Initialize() { - DCHECK(::GetCurrentThreadId() == test_thread_id_); - - // Start by replicating some of the steps that would otherwise be - // done by TestSuite::Initialize. We can't call the base class - // directly because it will attempt to initialize some things such as - // ICU that have already been initialized for this process. - CFUrlRequestUnittestRunner::InitializeLogging(); - - SuppressErrorDialogs(); - base::debug::SetSuppressDebugUI(true); - logging::SetLogAssertHandler(UnitTestAssertHandler); - - // Next, do some initialization for NetTestSuite. - NetTestSuite::InitializeTestThreadNoNetworkChangeNotifier(); - - // Finally, override the host used by the HTTP tests. See - // http://crbug.com/114369 . - OverrideHttpHost(); -} - -void CFUrlRequestUnittestRunner::Shutdown() { - DCHECK(::GetCurrentThreadId() == test_thread_id_); - NetTestSuite::Shutdown(); - OleUninitialize(); -} - -void CFUrlRequestUnittestRunner::OnInitialTabLoaded() { - test_http_server_.reset(); - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&CFUrlRequestUnittestRunner::CancelInitializationTimeout, - base::Unretained(this))); - StartTests(); -} - -void CFUrlRequestUnittestRunner::OnProviderDestroyed() { - if (tests_ran_) { - StopFileLogger(false); - - if (ie_configurator_.get() != NULL) - ie_configurator_->RevertSettings(); - - if (crash_service_) - base::KillProcess(crash_service_, 0, false); - - ::ExitProcess(test_result()); - } else { - DLOG(ERROR) << "Automation Provider shutting down before test execution " - "has completed."; - } -} - -void CFUrlRequestUnittestRunner::StartTests() { - if (prompt_after_setup_) - MessageBoxA(NULL, "click ok to run", "", MB_OK); - - DCHECK_EQ(test_thread_.IsValid(), false); - StopFileLogger(false); - test_thread_.Set(::CreateThread(NULL, 0, RunAllUnittests, this, 0, - &test_thread_id_)); - DCHECK(test_thread_.IsValid()); -} - -// static -DWORD CFUrlRequestUnittestRunner::RunAllUnittests(void* param) { - base::PlatformThread::SetName("CFUrlRequestUnittestRunner"); - CFUrlRequestUnittestRunner* me = - reinterpret_cast<CFUrlRequestUnittestRunner*>(param); - me->test_result_ = me->Run(); - me->tests_ran_ = true; - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&CFUrlRequestUnittestRunner::TakeDownBrowser, - base::Unretained(me))); - return 0; -} - -void CFUrlRequestUnittestRunner::TakeDownBrowser() { - if (prompt_after_setup_) - MessageBoxA(NULL, "click ok to exit", "", MB_OK); - - // Start capturing logs from npchrome_frame and the in-process Chrome to help - // diagnose failures in IE shutdown. This will be Stopped in either - // OnIEShutdownFailure or OnProviderDestroyed. - StartFileLogger(); - - // AddRef to ensure that IE going away does not trigger the Chrome shutdown - // process. - // IE shutting down will, however, trigger the automation channel to shut - // down, at which time we will exit the process (see OnProviderDestroyed). - g_browser_process->AddRefModule(); - ShutDownHostBrowser(); - - // In case IE is somehow hung, make sure we don't sit around until a try-bot - // kills us. OnIEShutdownFailure will log and exit with an error. - BrowserThread::PostDelayedTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&CFUrlRequestUnittestRunner::OnIEShutdownFailure, - base::Unretained(this)), - TestTimeouts::action_max_timeout()); -} - -void CFUrlRequestUnittestRunner::InitializeLogging() { - base::FilePath exe; - PathService::Get(base::FILE_EXE, &exe); - base::FilePath log_filename = exe.ReplaceExtension(FILE_PATH_LITERAL("log")); - logging::LoggingSettings settings; - settings.logging_dest = logging::LOG_TO_ALL; - settings.log_file = log_filename.value().c_str(); - settings.delete_old = logging::DELETE_OLD_LOG_FILE; - logging::InitLogging(settings); - // We want process and thread IDs because we may have multiple processes. - // Note: temporarily enabled timestamps in an effort to catch bug 6361. - logging::SetLogItems(true, true, true, true); -} - -void CFUrlRequestUnittestRunner::CancelInitializationTimeout() { - timeout_closure_.Cancel(); -} - -void CFUrlRequestUnittestRunner::StartInitializationTimeout() { - timeout_closure_.Reset( - base::Bind(&CFUrlRequestUnittestRunner::OnInitializationTimeout, - base::Unretained(this))); - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - timeout_closure_.callback(), - TestTimeouts::action_max_timeout()); -} - -void CFUrlRequestUnittestRunner::OnInitializationTimeout() { - LOG(ERROR) << "Failed to start Chrome Frame in the host browser."; - - base::FilePath snapshot; - if (ui_test_utils::SaveScreenSnapshotToDesktop(&snapshot)) - LOG(ERROR) << "Screen snapshot saved to " << snapshot.value(); - - StopFileLogger(true); - - if (launch_browser_) - chrome_frame_test::CloseAllIEWindows(); - - if (ie_configurator_.get() != NULL) - ie_configurator_->RevertSettings(); - - if (crash_service_) - base::KillProcess(crash_service_, 0, false); - - ::ExitProcess(1); -} - -void CFUrlRequestUnittestRunner::OverrideHttpHost() { - override_http_host_.reset( - new net::ScopedCustomUrlRequestTestHttpHost( - chrome_frame_test::GetLocalIPv4Address())); -} - -void CFUrlRequestUnittestRunner::PreEarlyInitialization() { - testing::InitGoogleTest(&g_argc, g_argv); - FilterDisabledTests(); - StartFileLogger(); -} - -int CFUrlRequestUnittestRunner::PreCreateThreads() { - fake_chrome_.reset(new FakeExternalTab()); - fake_chrome_->Initialize(); - fake_chrome_->browser_process()->PreCreateThreads(); - ProcessSingleton::NotificationCallback callback( - base::Bind( - &CFUrlRequestUnittestRunner::ProcessSingletonNotificationCallback, - base::Unretained(this))); - process_singleton_.reset(new ProcessSingleton(fake_chrome_->user_data(), - callback)); - return 0; -} - -bool CFUrlRequestUnittestRunner::ProcessSingletonNotificationCallback( - const CommandLine& command_line, const base::FilePath& current_directory) { - std::string channel_id = command_line.GetSwitchValueASCII( - switches::kAutomationClientChannelID); - EXPECT_FALSE(channel_id.empty()); - - Profile* profile = g_browser_process->profile_manager()->GetLastUsedProfile( - fake_chrome_->user_data()); - - AutomationProviderList* list = g_browser_process->GetAutomationProviderList(); - DCHECK(list); - list->AddProvider( - TestAutomationProvider::NewAutomationProvider(profile, channel_id, this)); - return true; -} - -void CFUrlRequestUnittestRunner::PreMainMessageLoopRun() { - fake_chrome_->InitializePostThreadsCreated(); - // Call Create directly instead of NotifyOtherProcessOrCreate as failure is - // prefered to notifying another process here. - if (!process_singleton_->Create()) { - LOG(FATAL) << "Failed to start up ProcessSingleton. Is another test " - << "executable or Chrome Frame running?"; - if (crash_service_) - base::KillProcess(crash_service_, 0, false); - ::ExitProcess(1); - } -} - -bool CFUrlRequestUnittestRunner::MainMessageLoopRun(int* result_code) { - DCHECK(base::MessageLoop::current()); - DCHECK(base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI); - - // We need to allow IO on the main thread for these tests. - base::ThreadRestrictions::SetIOAllowed(true); - StartChromeFrameInHostBrowser(); - StartInitializationTimeout(); - return false; -} - -void CFUrlRequestUnittestRunner::PostMainMessageLoopRun() { - process_singleton_->Cleanup(); - fake_chrome_->browser_process()->StartTearDown(); - - // Must do this separately as the mock profile_manager_ is not the - // same member as BrowserProcessImpl::StartTearDown resets. - fake_chrome_->browser_process()->DestroyProfileManager(); - - if (crash_service_) - base::KillProcess(crash_service_, 0, false); - - base::KillProcesses(chrome_frame_test::kIEImageName, 0, NULL); - base::KillProcesses(chrome_frame_test::kIEBrokerImageName, 0, NULL); -} - -void CFUrlRequestUnittestRunner::PostDestroyThreads() { - process_singleton_.reset(); - fake_chrome_->browser_process()->PostDestroyThreads(); - fake_chrome_->Shutdown(); - fake_chrome_.reset(); - -#ifndef NDEBUG - // Avoid CRT cleanup in debug test runs to ensure that webkit ASSERTs which - // check if globals are created and destroyed on the same thread don't fire. - // Webkit global objects are created on the inproc renderer thread. - ::ExitProcess(test_result()); -#endif -} - -void CFUrlRequestUnittestRunner::StartFileLogger() { - if (base::CreateTemporaryFile(&log_file_)) { - file_logger_.reset(new logging_win::FileLogger()); - file_logger_->Initialize(); - file_logger_->StartLogging(log_file_); - } else { - LOG(ERROR) << "Failed to create an ETW log file"; - } -} - -void CFUrlRequestUnittestRunner::StopFileLogger(bool print) { - if (file_logger_.get() != NULL && file_logger_->is_logging()) { - file_logger_->StopLogging(); - - if (print) { - // Flushing stdout should prevent unrelated output from being interleaved - // with the log file output. - std::cout.flush(); - // Dump the log to stderr. - logging_win::PrintLogFile(log_file_, &std::cerr); - std::cerr.flush(); - } - } - - if (!log_file_.empty() && !base::DeleteFile(log_file_, false)) - LOG(ERROR) << "Failed to delete log file " << log_file_.value(); - - log_file_.clear(); - file_logger_.reset(); -} - -const char* IEVersionToString(IEVersion version) { - switch (version) { - case IE_6: - return "IE6"; - case IE_7: - return "IE7"; - case IE_8: - return "IE8"; - case IE_9: - return "IE9"; - case IE_10: - return "IE10"; - case IE_UNSUPPORTED: - return "Unknown IE Version"; - case NON_IE: - return "Could not find IE"; - default: - return "Error."; - } -} - -content::BrowserMainParts* FakeContentBrowserClient::CreateBrowserMainParts( - const content::MainFunctionParams& parameters) { - // Normally this would happen during browser startup, but for tests - // we need to trigger creation of Profile-related services. - ChromeBrowserMainExtraPartsProfiles:: - EnsureBrowserContextKeyedServiceFactoriesBuilt(); - - // We never delete this, as the content module takes ownership. - // - // We must not construct this earlier, or we will have out-of-order - // AtExitManager creation/destruction. - g_test_suite = new CFUrlRequestUnittestRunner(g_argc, g_argv); - g_test_suite->set_crash_service(chrome_frame_test::StartCrashService()); - return g_test_suite; -} - -// We must provide a few functions content/ expects to link with. They -// are never called for this executable. -int PluginMain(const content::MainFunctionParams& parameters) { - NOTREACHED(); - return 0; -} - -int PpapiBrokerMain(const content::MainFunctionParams& parameters) { - return PluginMain(parameters); -} - -int PpapiPluginMain(const content::MainFunctionParams& parameters) { - return PluginMain(parameters); -} - -int WorkerMain(const content::MainFunctionParams& parameters) { - return PluginMain(parameters); -} - int main(int argc, char** argv) { - ScopedChromeFrameRegistrar::RegisterAndExitProcessIfDirected(); - g_argc = argc; - g_argv = argv; - - google_breakpad::scoped_ptr<google_breakpad::ExceptionHandler> breakpad( - InitializeCrashReporting(HEADLESS)); - - // Display the IE version we run with. This must be done after - // CFUrlRequestUnittestRunner is constructed since that initializes logging. - IEVersion ie_version = chrome_frame_test::GetInstalledIEVersion(); - LOG(INFO) << "Running CF net tests with IE version: " - << IEVersionToString(ie_version); - - // See url_request_unittest.cc for these credentials. - SupplyProxyCredentials credentials("user", "secret"); - WindowWatchdog watchdog; - watchdog.AddObserver(&credentials, "Windows Security", ""); - - sandbox::SandboxInterfaceInfo sandbox_info = {0}; - content::InitializeSandboxInfo(&sandbox_info); - FakeMainDelegate delegate; - content::ContentMain( - reinterpret_cast<HINSTANCE>(GetModuleHandle(NULL)), - &sandbox_info, - &delegate); - - // Note: In debug builds, we ExitProcess during PostDestroyThreads. - return g_test_suite->test_result(); + return 0; } diff --git a/chrome_frame/test/net/fake_external_tab.h b/chrome_frame/test/net/fake_external_tab.h deleted file mode 100644 index f4dac94..0000000 --- a/chrome_frame/test/net/fake_external_tab.h +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_FRAME_TEST_NET_FAKE_EXTERNAL_TAB_H_ -#define CHROME_FRAME_TEST_NET_FAKE_EXTERNAL_TAB_H_ - -#include <string> - -#include "base/cancelable_callback.h" -#include "base/files/file_path.h" -#include "base/message_loop/message_loop.h" -#include "base/process/process.h" -#include "base/win/scoped_handle.h" -#include "chrome/browser/browser_process_impl.h" -#include "chrome_frame/test/net/test_automation_provider.h" -#include "chrome_frame/test/test_server.h" -#include "chrome_frame/test_utils.h" -#include "content/public/browser/browser_main_parts.h" -#include "content/public/browser/browser_thread.h" -#include "net/test/net_test_suite.h" - -class CommandLine; -class FakeBrowserProcessImpl; -class ProcessSingleton; - -namespace net { -class ScopedCustomUrlRequestTestHttpHost; -} // namespace net - -namespace content { -class NotificationService; -} // namespace content - -namespace logging_win { -class FileLogger; -} // namespace logging_win - -namespace chrome_frame_test { -class IEConfigurator; -} // namespace chrome_frame_test - -class FakeExternalTab { - public: - FakeExternalTab(); - virtual ~FakeExternalTab(); - - virtual void Initialize(); - virtual void InitializePostThreadsCreated(); - virtual void Shutdown(); - - const base::FilePath& user_data() const { - return user_data_dir_; - } - - FakeBrowserProcessImpl* browser_process() const; - - private: - scoped_ptr<FakeBrowserProcessImpl> browser_process_; - base::FilePath overridden_user_dir_; - base::FilePath user_data_dir_; - scoped_ptr<content::NotificationService> notificaton_service_; - - DISALLOW_COPY_AND_ASSIGN(FakeExternalTab); -}; - -// The "master class" that spins the UI and test threads. -// -// In this weird test executable that pretends to almost be Chrome, it -// plays a similar role to ChromeBrowserMainParts, and must fulfill -// the existing contract between ChromeBrowserMainParts and -// BrowserProcessImpl, i.e. poking BrowserProcessImpl at certain -// lifetime events. -class CFUrlRequestUnittestRunner - : public NetTestSuite, - public TestAutomationProviderDelegate, - public content::BrowserMainParts { - public: - CFUrlRequestUnittestRunner(int argc, char** argv); - virtual ~CFUrlRequestUnittestRunner(); - - virtual void StartChromeFrameInHostBrowser(); - - virtual void ShutDownHostBrowser(); - - // Overrides to not call icu initialize - virtual void Initialize(); - virtual void Shutdown(); - - // TestAutomationProviderDelegate. - virtual void OnInitialTabLoaded(); - virtual void OnProviderDestroyed(); - - void StartTests(); - - // Borrowed from TestSuite::Initialize(). - void InitializeLogging(); - - int test_result() const { - return test_result_; - } - - void set_crash_service(base::ProcessHandle handle) { - crash_service_ = handle; - } - - // content::BrowserMainParts implementation. - virtual void PreEarlyInitialization() OVERRIDE; - virtual int PreCreateThreads() OVERRIDE; - virtual void PreMainMessageLoopRun() OVERRIDE; - virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; - virtual void PostMainMessageLoopRun() OVERRIDE; - virtual void PostDestroyThreads() OVERRIDE; - - protected: - // This is the thread that runs all the UrlRequest tests. - // Within its context, the Initialize() and Shutdown() routines above - // will be called. - static DWORD WINAPI RunAllUnittests(void* param); - - void TakeDownBrowser(); - - protected: - base::win::ScopedHandle test_thread_; - base::ProcessHandle crash_service_; - DWORD test_thread_id_; - - scoped_ptr<net::ScopedCustomUrlRequestTestHttpHost> override_http_host_; - - scoped_ptr<test_server::SimpleWebServer> test_http_server_; - test_server::SimpleResponse chrome_frame_html_; - - // The fake chrome instance. - scoped_ptr<FakeExternalTab> fake_chrome_; - ScopedChromeFrameRegistrar registrar_; - int test_result_; - - private: - // Causes HTTP tests to run over an external address rather than 127.0.0.1. - // See http://crbug.com/114369 . - void OverrideHttpHost(); - void StartFileLogger(); - void StopFileLogger(bool print); - void OnIEShutdownFailure(); - - void CancelInitializationTimeout(); - void StartInitializationTimeout(); - void OnInitializationTimeout(); - - bool ProcessSingletonNotificationCallback( - const CommandLine& command_line, - const base::FilePath& current_directory); - - bool launch_browser_; - bool prompt_after_setup_; - bool tests_ran_; - scoped_ptr<ProcessSingleton> process_singleton_; - base::CancelableClosure timeout_closure_; - scoped_ptr<logging_win::FileLogger> file_logger_; - base::FilePath log_file_; - scoped_ptr<chrome_frame_test::IEConfigurator> ie_configurator_; - - DISALLOW_COPY_AND_ASSIGN(CFUrlRequestUnittestRunner); -}; - -#endif // CHROME_FRAME_TEST_NET_FAKE_EXTERNAL_TAB_H_ diff --git a/chrome_frame/test/net/test_automation_provider.cc b/chrome_frame/test/net/test_automation_provider.cc deleted file mode 100644 index 57095de..0000000 --- a/chrome_frame/test/net/test_automation_provider.cc +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2012 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_frame/test/net/test_automation_provider.h" - -#include "base/command_line.h" -#include "base/file_version_info.h" -#include "base/path_service.h" -#include "chrome/common/automation_messages.h" -#include "chrome_frame/test/net/test_automation_resource_message_filter.h" -#include "net/url_request/url_request_context.h" - -namespace { - -// A special command line switch to just run the unit tests without CF in -// the picture. Can be useful when the harness itself needs to be debugged. -const char kNoCfTestRun[] = "no-cf-test-run"; - -bool CFTestsDisabled() { - static bool switch_present = CommandLine::ForCurrentProcess()-> - HasSwitch(kNoCfTestRun); - return switch_present; -} - -} // end namespace - -TestAutomationProvider* TestAutomationProvider::g_provider_instance_ = NULL; - -TestAutomationProvider::TestAutomationProvider( - Profile* profile, - TestAutomationProviderDelegate* delegate) - : AutomationProvider(profile), tab_handle_(-1), delegate_(delegate) { - // We need to register the protocol factory before the - // AutomationResourceMessageFilter registers the automation job factory to - // ensure that we don't inadvarently end up handling http requests which - // we don't expect. The initial chrome frame page for the network tests - // issues http requests which our test factory should not handle. - net::URLRequest::Deprecated::RegisterProtocolFactory( - "http", TestAutomationProvider::Factory); - net::URLRequest::Deprecated::RegisterProtocolFactory( - "https", TestAutomationProvider::Factory); - automation_resource_message_filter_ = - new TestAutomationResourceMessageFilter(this); - g_provider_instance_ = this; -} - -TestAutomationProvider::~TestAutomationProvider() { - delegate_->OnProviderDestroyed(); - g_provider_instance_ = NULL; -} - -bool TestAutomationProvider::OnMessageReceived(const IPC::Message& msg) { - if (automation_resource_message_filter_->OnMessageReceived(msg)) - return true; // Message handled by the filter. - - return __super::OnMessageReceived(msg); -} - -net::URLRequestJob* TestAutomationProvider::Factory( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - const std::string& scheme) { - if (CFTestsDisabled()) - return NULL; - - if (request->url().SchemeIsHTTPOrHTTPS()) { - // Only look at requests that don't have any user data. - // ResourceDispatcherHost uses the user data for requests that it manages. - // We don't want to mess with those. - - // We could also check if the current thread is our TestUrlRequest thread - // and only intercept requests that belong to that thread. - if (g_provider_instance_ && request->GetUserData(NULL) == NULL && - g_provider_instance_->tab_handle_ != -1) { - // We generate our own request id which is also what - // ResourceDispatcherHost does (well, the id is actually generated by - // ResourceDispatcher). Since these requests are divided into with - // and without userdata, we're OK. However, just to make debugging - // a little easier, we have a significantly higher start value. - static int new_id = 0x00100000; - URLRequestAutomationJob* job = new URLRequestAutomationJob( - request, network_delegate, - request->context()->http_user_agent_settings(), - g_provider_instance_->tab_handle_, new_id++, - g_provider_instance_->automation_resource_message_filter_, false); - return job; - } - } - - return NULL; -} - -std::string TestAutomationProvider::GetProtocolVersion() { - // Return the version of npchrome_frame.dll. We used to use - // chrome.dll, but the other end of the pipe in this case is - // actually npchrome_frame.dll (which fetches its version info from - // itself), and occasionally we run into RC dependency problems in - // incremental builds so that the version information does not get - // updated in one module but does in another, so better to use the - // exact same version to avoid hard-to-debug problems in development - // builds. - base::FilePath path; - PathService::Get(base::DIR_MODULE, &path); - path = path.AppendASCII("npchrome_frame.dll"); - - std::string version; - scoped_ptr<FileVersionInfo> version_info( - FileVersionInfo::CreateFileVersionInfo(path)); - if (version_info.get()) { - version = WideToASCII(version_info->product_version()); - } - return version; -} - -// static -TestAutomationProvider* TestAutomationProvider::NewAutomationProvider( - Profile* p, const std::string& channel, - TestAutomationProviderDelegate* delegate) { - TestAutomationProvider* automation = new TestAutomationProvider(p, delegate); - automation->InitializeChannel(channel); - automation->SetExpectedTabCount(1); - return automation; -} diff --git a/chrome_frame/test/net/test_automation_provider.h b/chrome_frame/test/net/test_automation_provider.h deleted file mode 100644 index 04c4e52..0000000 --- a/chrome_frame/test/net/test_automation_provider.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2012 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. -#ifndef CHROME_FRAME_TEST_NET_TEST_AUTOMATION_PROVIDER_H_ -#define CHROME_FRAME_TEST_NET_TEST_AUTOMATION_PROVIDER_H_ - -#include <string> -#include "chrome/browser/automation/automation_provider.h" - -namespace net { -class NetworkDelegate; -class URLRequest; -class URLRequestJob; -} // namespace net - -class TestAutomationResourceMessageFilter; - -// Callback interface for TestAutomationProvider. -class TestAutomationProviderDelegate { - public: - virtual void OnInitialTabLoaded() = 0; - virtual void OnProviderDestroyed() = 0; -}; - -// A slightly customized version of AutomationProvider. -// We override AutomationProvider to be able to filter received messages -// (see TestAutomationResourceMessageFilter) and know when the initial -// ExternalTab has been loaded. -// In order to intercept UrlRequests and make the URLRequestAutomationJob class -// handle requests from unit tests, we register a protocol factory for -// http/https. -class TestAutomationProvider - : public AutomationProvider { - public: - TestAutomationProvider(Profile* profile, - TestAutomationProviderDelegate* delegate); - - virtual ~TestAutomationProvider(); - - // AutomationProvider overrides. - virtual bool OnMessageReceived(const IPC::Message& msg); - - // Protocol factory for handling http/https requests over automation. - static net::URLRequestJob* Factory(net::URLRequest* request, - net::NetworkDelegate* network_delegate, - const std::string& scheme); - - // Call to instantiate and initialize a new instance of - // TestAutomationProvider. - static TestAutomationProvider* NewAutomationProvider( - Profile* p, - const std::string& channel, - TestAutomationProviderDelegate* delegate); - - protected: - virtual std::string GetProtocolVersion(); - - int tab_handle_; - TestAutomationProviderDelegate* delegate_; - - static TestAutomationProvider* g_provider_instance_; -}; - -#endif // CHROME_FRAME_TEST_NET_TEST_AUTOMATION_PROVIDER_H_ diff --git a/chrome_frame/test/net/test_automation_resource_message_filter.cc b/chrome_frame/test/net/test_automation_resource_message_filter.cc deleted file mode 100644 index d6b75b9..0000000 --- a/chrome_frame/test/net/test_automation_resource_message_filter.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2012 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_frame/test/net/test_automation_resource_message_filter.h" - -#include "base/bind.h" - -TestAutomationResourceMessageFilter::TestAutomationResourceMessageFilter( - AutomationProvider* automation) : automation_(automation) { -} - -bool TestAutomationResourceMessageFilter::Send(IPC::Message* message) { - return automation_->Send(message); -} - -// static -void TestAutomationResourceMessageFilter::OnRequestMessage( - URLRequestAutomationJob* job, IPC::Message* msg) { - job->OnMessage(*msg); - delete msg; -} - -bool TestAutomationResourceMessageFilter::OnMessageReceived( - const IPC::Message& message) { - // See if we want to process this message... call the base class - // for filter messages, send the message to the correct thread - // for URL requests. - bool handled = false; - int request_id; - if (URLRequestAutomationJob::MayFilterMessage(message, &request_id)) { - base::AutoLock lock(requests_lock_); - RequestMap::iterator it = requests_.find(request_id); - if (it != requests_.end()) { - handled = true; - IPC::Message* msg = new IPC::Message(message); - RequestJob& job = it->second; - - // SUBTLE: Why is this safe? We pass the URLRequestAutomationJob to a - // posted task which then takes a reference. We then release the lock, - // meaning we are no longer protecting access to the request_map_ which - // holds our last owned reference to the URLRequestAutomationJob. Thus - // the posted task could be the one holding the last reference. - // - // If the posted task were to be run on a thread other than the one the - // URLRequestAutomationJob was created on, we could destroy the job on - // the wrong thread (resulting in badness as URLRequestJobs must be - // created and destroyed on the same thread). The destruction will happen - // on the correct thread here since we post to job.loop_ which is set as - // the message loop of the current thread when RegisterRequest is invoked - // by URLRequestJob's constructor. - job.loop_->PostTask(FROM_HERE, - base::Bind(OnRequestMessage, job.job_, msg)); - } - } else { - handled = AutomationResourceMessageFilter::OnMessageReceived(message); - } - return handled; -} - -// Add request to the list of outstanding requests. -bool TestAutomationResourceMessageFilter::RegisterRequest( - URLRequestAutomationJob* job) { - // Store the request in an internal map like the parent class - // does, but also store the current loop pointer so we can send - // request messages to that loop. - base::AutoLock lock(requests_lock_); - DCHECK(requests_.end() == requests_.find(job->id())); - RequestJob request_job = { base::MessageLoop::current(), job }; - requests_[job->id()] = request_job; - return true; -} - -// Remove request from the list of outstanding requests. -void TestAutomationResourceMessageFilter::UnRegisterRequest( - URLRequestAutomationJob* job) { - base::AutoLock lock(requests_lock_); - requests_.erase(job->id()); -} diff --git a/chrome_frame/test/net/test_automation_resource_message_filter.h b/chrome_frame/test/net/test_automation_resource_message_filter.h deleted file mode 100644 index 56fd03a..0000000 --- a/chrome_frame/test/net/test_automation_resource_message_filter.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2012 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. -#ifndef CHROME_FRAME_TEST_NET_TEST_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_ -#define CHROME_FRAME_TEST_NET_TEST_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_ - -#include <map> - -#include "base/synchronization/lock.h" -#include "chrome/browser/automation/automation_provider.h" -#include "chrome/browser/automation/automation_resource_message_filter.h" -#include "chrome/browser/automation/url_request_automation_job.h" - -// Performs the same duties as AutomationResourceMessageFilter but with one -// difference. Instead of being tied to an IPC channel running on Chrome's -// IO thread, this instance runs on the unit test's IO thread (all URL request -// tests have their own IO loop) and is tied to an instance of -// AutomationProvider (TestAutomationProvider to be exact). -// -// Messages from the AutomationProvider that are destined to request objects -// owned by this class are marshaled over to the request's IO thread instead -// of using the thread the messages are received on. This way we allow the -// URL request tests to run sequentially as they were written while still -// allowing the automation layer to work as it normally does (i.e. process -// its messages on the receiving thread). -class TestAutomationResourceMessageFilter - : public AutomationResourceMessageFilter { - public: - explicit TestAutomationResourceMessageFilter(AutomationProvider* automation); - - virtual bool Send(IPC::Message* message); - - static void OnRequestMessage(URLRequestAutomationJob* job, - IPC::Message* msg); - - virtual bool OnMessageReceived(const IPC::Message& message); - - // Add request to the list of outstanding requests. - virtual bool RegisterRequest(URLRequestAutomationJob* job); - // Remove request from the list of outstanding requests. - virtual void UnRegisterRequest(URLRequestAutomationJob* job); - - protected: - AutomationProvider* automation_; - // declare the request map. - struct RequestJob { - base::MessageLoop* loop_; - scoped_refptr<URLRequestAutomationJob> job_; - }; - typedef std::map<int, RequestJob> RequestMap; - RequestMap requests_; - - // Protects access to requests_. - base::Lock requests_lock_; -}; - -#endif // CHROME_FRAME_TEST_NET_TEST_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_ diff --git a/chrome_frame/test/url_request_test.cc b/chrome_frame/test/url_request_test.cc deleted file mode 100644 index 85ee388..0000000 --- a/chrome_frame/test/url_request_test.cc +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright (c) 2012 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 <atlbase.h> -#include <atlcom.h> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "chrome/common/automation_messages.h" -#include "chrome_frame/test/chrome_frame_test_utils.h" -#include "chrome_frame/test/test_server.h" -#include "chrome_frame/test/test_with_web_server.h" -#include "chrome_frame/urlmon_url_request.h" -#include "chrome_frame/urlmon_url_request_private.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gmock_mutant.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::CreateFunctor; - -using chrome_frame_test::kChromeFrameLongNavigationTimeout; - -static void AppendToStream(IStream* s, void* buffer, ULONG cb) { - ULONG bytes_written; - LARGE_INTEGER current_pos; - LARGE_INTEGER zero = {0}; - // Remember current position. - ASSERT_HRESULT_SUCCEEDED(s->Seek(zero, STREAM_SEEK_CUR, - reinterpret_cast<ULARGE_INTEGER*>(¤t_pos))); - // Seek to the end. - ASSERT_HRESULT_SUCCEEDED(s->Seek(zero, STREAM_SEEK_END, NULL)); - ASSERT_HRESULT_SUCCEEDED(s->Write(buffer, cb, &bytes_written)); - ASSERT_EQ(cb, bytes_written); - // Seek to original position. - ASSERT_HRESULT_SUCCEEDED(s->Seek(current_pos, STREAM_SEEK_SET, NULL)); -} - -class MockUrlDelegate : public PluginUrlRequestDelegate { - public: - MOCK_METHOD9(OnResponseStarted, void(int request_id, const char* mime_type, - const char* headers, int size, base::Time last_modified, - const std::string& redirect_url, int redirect_status, - const net::HostPortPair& socket_address, uint64 upload_size)); - MOCK_METHOD2(OnReadComplete, void(int request_id, const std::string& data)); - MOCK_METHOD2(OnResponseEnd, void(int request_id, - const net::URLRequestStatus& status)); - - void PostponeReadRequest(chrome_frame_test::TimedMsgLoop* loop, - UrlmonUrlRequest* request, int bytes_to_read) { - loop->PostTask(FROM_HERE, - base::Bind(&MockUrlDelegate::RequestRead, - base::Unretained(this), request, bytes_to_read)); - } - - private: - void RequestRead(UrlmonUrlRequest* request, int bytes_to_read) { - request->Read(bytes_to_read); - } -}; - -// Simplest UrlmonUrlRequest. Retrieve a file from local web server. -TEST(UrlmonUrlRequestTest, Simple1) { - MockUrlDelegate mock; - chrome_frame_test::TimedMsgLoop loop; - - testing::StrictMock<MockWebServer> mock_server(1337, - ASCIIToWide(chrome_frame_test::GetLocalIPv4Address()), - chrome_frame_test::GetTestDataFolder()); - mock_server.ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE)); - - CComObjectStackEx<UrlmonUrlRequest> request; - - request.AddRef(); - request.Initialize(&mock, 1, // request_id - WideToUTF8(mock_server.Resolve(L"chrome_frame_window_open.html")), - "get", - "", // referrer - "", // extra request - NULL, // upload data - ResourceType::MAIN_FRAME, // resource type - true, - 0); // frame busting - - testing::InSequence s; - EXPECT_CALL(mock, OnResponseStarted(1, testing::_, testing::_, testing::_, - testing::_, testing::_, testing::_, - testing::_, testing::_)) - .Times(1) - .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor( - &request, &UrlmonUrlRequest::Read, 512)))); - - - EXPECT_CALL(mock, OnReadComplete(1, testing::Property(&std::string::size, - testing::Gt(0u)))) - .Times(testing::AtLeast(1)) - .WillRepeatedly(testing::InvokeWithoutArgs(CreateFunctor(&mock, - &MockUrlDelegate::PostponeReadRequest, &loop, &request, 64))); - - EXPECT_CALL(mock, OnResponseEnd(1, testing::_)) - .Times(1) - .WillOnce(QUIT_LOOP_SOON(loop, base::TimeDelta::FromSeconds(2))); - - request.Start(); - loop.RunFor(kChromeFrameLongNavigationTimeout); - request.Release(); -} - -// Same as Simple1 except we use the HEAD verb to fetch only the headers -// from the server. -TEST(UrlmonUrlRequestTest, Head) { - MockUrlDelegate mock; - chrome_frame_test::TimedMsgLoop loop; - // Use SimpleWebServer instead of the python server to support HEAD - // requests. - test_server::SimpleWebServer server(13337); - test_server::SimpleResponse head_response("/head", ""); - server.AddResponse(&head_response); - - CComObjectStackEx<UrlmonUrlRequest> request; - - request.AddRef(); - request.Initialize(&mock, 1, // request_id - base::StringPrintf("http://%s:13337/head", server.host().c_str()), - "head", - "", // referrer - "", // extra request - NULL, // upload data - ResourceType::MAIN_FRAME, // resource type - true, - 0); // frame busting - - testing::InSequence s; - EXPECT_CALL(mock, OnResponseStarted(1, testing::_, testing::_, testing::_, - testing::_, testing::_, testing::_, - testing::_, testing::_)) - .Times(1) - .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor( - &request, &UrlmonUrlRequest::Read, 512)))); - - // For HEAD requests we don't expect content reads. - EXPECT_CALL(mock, OnReadComplete(1, testing::_)).Times(0); - - EXPECT_CALL(mock, OnResponseEnd(1, testing::_)) - .Times(1) - .WillOnce(QUIT_LOOP_SOON(loop, base::TimeDelta::FromSeconds(2))); - - request.Start(); - loop.RunFor(kChromeFrameLongNavigationTimeout); - request.Release(); -} - -TEST(UrlmonUrlRequestTest, UnreachableUrl) { - MockUrlDelegate mock; - chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<UrlmonUrlRequest> request; - - testing::StrictMock<MockWebServer> mock_server(1337, - ASCIIToWide(chrome_frame_test::GetLocalIPv4Address()), - chrome_frame_test::GetTestDataFolder()); - mock_server.ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE)); - - GURL unreachable(WideToUTF8(mock_server.Resolve( - L"non_existing.html"))); - - request.AddRef(); - request.Initialize(&mock, 1, // request_id - unreachable.spec(), "get", - "", // referrer - "", // extra request - NULL, // upload data - ResourceType::MAIN_FRAME, // resource type - true, - 0); // frame busting - - // Expect headers - EXPECT_CALL(mock, OnResponseStarted(1, testing::_, - testing::StartsWith("HTTP/1.1 404"), - testing::_, testing::_, testing::_, - testing::_, testing::_, testing::_)) - .Times(1) - .WillOnce(QUIT_LOOP_SOON(loop, base::TimeDelta::FromSeconds(2))); - - EXPECT_CALL(mock, OnResponseEnd(1, testing::Property( - &net::URLRequestStatus::error, - net::ERR_TUNNEL_CONNECTION_FAILED))) - .Times(testing::AtMost(1)); - - request.Start(); - loop.RunFor(kChromeFrameLongNavigationTimeout); - request.Release(); -} - -TEST(UrlmonUrlRequestTest, ZeroLengthResponse) { - MockUrlDelegate mock; - chrome_frame_test::TimedMsgLoop loop; - - testing::StrictMock<MockWebServer> mock_server(1337, - ASCIIToWide(chrome_frame_test::GetLocalIPv4Address()), - chrome_frame_test::GetTestDataFolder()); - mock_server.ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE)); - - CComObjectStackEx<UrlmonUrlRequest> request; - - request.AddRef(); - request.Initialize(&mock, 1, // request_id - WideToUTF8(mock_server.Resolve(L"empty.html")), "get", - "", // referrer - "", // extra request - NULL, // upload data - ResourceType::MAIN_FRAME, // resource type - true, - 0); // frame busting - - // Expect headers - EXPECT_CALL(mock, OnResponseStarted(1, testing::_, testing::_, testing::_, - testing::_, testing::_, testing::_, - testing::_, testing::_)) - .Times(1) - .WillOnce(QUIT_LOOP(loop)); - - request.Start(); - loop.RunFor(kChromeFrameLongNavigationTimeout); - EXPECT_FALSE(loop.WasTimedOut()); - - // Should stay quiet, since we do not ask for anything for awhile. - EXPECT_CALL(mock, OnResponseEnd(1, testing::_)).Times(0); - loop.RunFor(base::TimeDelta::FromSeconds(3)); - - // Invoke read. Only now the response end ("server closed the connection") - // is supposed to be delivered. - EXPECT_CALL(mock, OnResponseEnd(1, testing::Property( - &net::URLRequestStatus::is_success, true))).Times(1); - request.Read(512); - request.Release(); -} - -ACTION_P4(ManagerRead, loop, mgr, request_id, bytes_to_read) { - loop->PostTask(FROM_HERE, - base::Bind(&UrlmonUrlRequestManager::ReadUrlRequest, - base::Unretained(mgr), request_id, bytes_to_read)); -} -ACTION_P3(ManagerEndRequest, loop, mgr, request_id) { - loop->PostTask(FROM_HERE, base::Bind(&UrlmonUrlRequestManager::EndUrlRequest, - base::Unretained(mgr), request_id, - net::URLRequestStatus())); -} - -// Simplest test - retrieve file from local web server. -TEST(UrlmonUrlRequestManagerTest, Simple1) { - MockUrlDelegate mock; - chrome_frame_test::TimedMsgLoop loop; - - testing::StrictMock<MockWebServer> mock_server(1337, - ASCIIToWide(chrome_frame_test::GetLocalIPv4Address()), - chrome_frame_test::GetTestDataFolder()); - mock_server.ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE)); - - scoped_ptr<UrlmonUrlRequestManager> mgr(new UrlmonUrlRequestManager()); - mgr->set_delegate(&mock); - AutomationURLRequest r1; - r1.url = WideToUTF8(mock_server.Resolve(L"chrome_frame_window_open.html")); - r1.method = "get"; - r1.resource_type = 0; - r1.load_flags = 0; - - EXPECT_CALL(mock, OnResponseStarted(1, testing::_, testing::_, testing::_, - testing::_, testing::_, testing::_, testing::_, - testing::_)) - .Times(1) - .WillOnce(ManagerRead(&loop, mgr.get(), 1, 512)); - - EXPECT_CALL(mock, OnReadComplete(1, testing::Property(&std::string::size, - testing::Gt(0u)))) - .Times(testing::AtLeast(1)) - .WillRepeatedly(ManagerRead(&loop, mgr.get(), 1, 2)); - - EXPECT_CALL(mock, OnResponseEnd(1, testing::_)) - .Times(1) - .WillOnce(QUIT_LOOP_SOON(loop, base::TimeDelta::FromSeconds(2))); - - mgr->StartUrlRequest(1, r1); - loop.RunFor(kChromeFrameLongNavigationTimeout); - mgr.reset(); -} - -TEST(UrlmonUrlRequestManagerTest, Abort1) { - MockUrlDelegate mock; - chrome_frame_test::TimedMsgLoop loop; - - testing::StrictMock<MockWebServer> mock_server(1337, - ASCIIToWide(chrome_frame_test::GetLocalIPv4Address()), - chrome_frame_test::GetTestDataFolder()); - mock_server.ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE)); - - scoped_ptr<UrlmonUrlRequestManager> mgr(new UrlmonUrlRequestManager()); - mgr->set_delegate(&mock); - AutomationURLRequest r1; - r1.url = WideToUTF8(mock_server.Resolve(L"chrome_frame_window_open.html")); - r1.method = "get"; - r1.resource_type = 0; - r1.load_flags = 0; - - EXPECT_CALL(mock, OnResponseStarted(1, testing::_, testing::_, testing::_, - testing::_, testing::_, testing::_, testing::_, - testing::_)) - .Times(1) - .WillOnce(testing::DoAll( - ManagerEndRequest(&loop, mgr.get(), 1), - QUIT_LOOP_SOON(loop, base::TimeDelta::FromSeconds(3)))); - - EXPECT_CALL(mock, OnReadComplete(1, testing::_)) - .Times(0); - - EXPECT_CALL(mock, OnResponseEnd(1, testing::_)) - .Times(0); - - mgr->StartUrlRequest(1, r1); - loop.RunFor(kChromeFrameLongNavigationTimeout); - mgr.reset(); -} diff --git a/chrome_frame/urlmon_url_request.cc b/chrome_frame/urlmon_url_request.cc index 078aa9c..95eed34 100644 --- a/chrome_frame/urlmon_url_request.cc +++ b/chrome_frame/urlmon_url_request.cc @@ -201,54 +201,7 @@ void UrlmonUrlRequest::TerminateBind(const TerminateBindCallback& callback) { } size_t UrlmonUrlRequest::SendDataToDelegate(size_t bytes_to_read) { - DCHECK_EQ(thread_, base::PlatformThread::CurrentId()); - DCHECK_NE(id(), -1); - DCHECK_GT(bytes_to_read, 0U); - size_t bytes_copied = 0; - if (delegate_) { - std::string read_data; - if (cache_) { - HRESULT hr = ReadStream(cache_, bytes_to_read, &read_data); - if (hr == S_FALSE || read_data.length() < bytes_to_read) { - DVLOG(1) << __FUNCTION__ << me() << "all cached data read"; - cache_.Release(); - } - } - - if (read_data.empty() && pending_data_) { - size_t pending_data_read_save = pending_read_size_; - pending_read_size_ = 0; - - // AddRef the stream while we call Read to avoid a potential issue - // where we can get a call to OnDataAvailable while inside Read and - // in our OnDataAvailable call, we can release the stream object - // while still using it. - base::win::ScopedComPtr<IStream> pending(pending_data_); - HRESULT hr = ReadStream(pending, bytes_to_read, &read_data); - if (read_data.empty()) - pending_read_size_ = pending_data_read_save; - // If we received S_FALSE it indicates that there is no more data in the - // stream. Clear it to ensure that OnStopBinding correctly sends over the - // response end notification to chrome. - if (hr == S_FALSE) - pending_data_.Release(); - } - - bytes_copied = read_data.length(); - - if (bytes_copied) { - ++calling_delegate_; - DCHECK_NE(id(), -1); - // The delegate can go away in the middle of ReadStream - if (delegate_) - delegate_->OnReadComplete(id(), read_data); - --calling_delegate_; - } - } else { - DLOG(ERROR) << __FUNCTION__ << me() << "no delegate"; - } - - return bytes_copied; + return 0; } STDMETHODIMP UrlmonUrlRequest::OnStartBinding(DWORD reserved, @@ -647,59 +600,6 @@ STDMETHODIMP UrlmonUrlRequest::BeginningTransaction(const wchar_t* url, STDMETHODIMP UrlmonUrlRequest::OnResponse(DWORD dwResponseCode, const wchar_t* response_headers, const wchar_t* request_headers, wchar_t** additional_headers) { - DCHECK_EQ(thread_, base::PlatformThread::CurrentId()); - DVLOG(1) << __FUNCTION__ << me() << "headers: \n" - << (response_headers == NULL ? L"EMPTY" : response_headers); - - if (!delegate_) { - DLOG(WARNING) << "Invalid delegate"; - return S_OK; - } - - delegate_->AddPrivacyDataForUrl(url(), "", 0); - - std::string raw_headers; - if (response_headers) - raw_headers = WideToUTF8(response_headers); - - // Security check for frame busting headers. We don't honor the headers - // as-such, but instead simply kill requests which we've been asked to - // look for if they specify a value for "X-Frame-Options" other than - // "ALLOWALL" (the others are "deny" and "sameorigin"). This puts the onus - // on the user of the UrlRequest to specify whether or not requests should - // be inspected. For ActiveDocuments, the answer is "no", since WebKit's - // detection/handling is sufficient and since ActiveDocuments cannot be - // hosted as iframes. For NPAPI and ActiveX documents, the Initialize() - // function of the PluginUrlRequest object allows them to specify how they'd - // like requests handled. Both should set enable_frame_busting_ to true to - // avoid CSRF attacks. Should WebKit's handling of this ever change, we will - // need to re-visit how and when frames are killed to better mirror a policy - // which may do something other than kill the sub-document outright. - - // NOTE(slightlyoff): We don't use net::HttpResponseHeaders here because - // of lingering ICU/base_noicu issues. - if (enable_frame_busting_) { - if (http_utils::HasFrameBustingHeader(raw_headers)) { - DLOG(ERROR) << "X-Frame-Options header other than ALLOWALL " << - "detected, navigation canceled"; - return E_FAIL; - } - } - - DVLOG(1) << __FUNCTION__ << me() << "Calling OnResponseStarted"; - - // Inform the delegate. - headers_received_ = true; - DCHECK_NE(id(), -1); - delegate_->OnResponseStarted(id(), - "", // mime_type - raw_headers.c_str(), // headers - 0, // size - base::Time(), // last_modified - status_.get_redirection().utf8_url, - status_.get_redirection().http_code, - socket_address_, - post_data_len()); return S_OK; } @@ -867,19 +767,6 @@ HRESULT UrlmonUrlRequest::StartAsyncDownload() { } void UrlmonUrlRequest::NotifyDelegateAndDie() { - DCHECK_EQ(thread_, base::PlatformThread::CurrentId()); - DVLOG(1) << __FUNCTION__ << me(); - - PluginUrlRequestDelegate* delegate = delegate_; - delegate_ = NULL; - ReleaseBindings(); - TerminateTransaction(); - if (delegate && id() != -1) { - net::URLRequestStatus result = status_.get_result(); - delegate->OnResponseEnd(id(), result); - } else { - DLOG(WARNING) << __FUNCTION__ << me() << "no delegate"; - } } void UrlmonUrlRequest::TerminateTransaction() { @@ -1008,283 +895,12 @@ void UrlmonUrlRequestManager::SetInfoForUrl(const std::wstring& url, } } -void UrlmonUrlRequestManager::StartRequest(int request_id, - const AutomationURLRequest& request_info) { - DVLOG(1) << __FUNCTION__ << " id: " << request_id; - - if (stopping_) { - DLOG(WARNING) << __FUNCTION__ << " request not started (stopping)"; - return; - } - - DCHECK(request_map_.find(request_id) == request_map_.end()); -#ifndef NDEBUG - if (background_worker_thread_enabled_) { - base::AutoLock lock(background_resource_map_lock_); - DCHECK(background_request_map_.find(request_id) == - background_request_map_.end()); - } -#endif // NDEBUG - DCHECK(GURL(request_info.url).is_valid()); - - // Non frame requests like sub resources, images, etc are handled on the - // background thread. - if (background_worker_thread_enabled_ && - !ResourceType::IsFrame( - static_cast<ResourceType::Type>(request_info.resource_type))) { - DLOG(INFO) << "Downloading resource type " - << request_info.resource_type - << " on background thread"; - background_thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&UrlmonUrlRequestManager::StartRequestHelper, - base::Unretained(this), request_id, request_info, - &background_request_map_, &background_resource_map_lock_)); - return; - } - StartRequestHelper(request_id, request_info, &request_map_, NULL); -} - -void UrlmonUrlRequestManager::StartRequestHelper( - int request_id, - const AutomationURLRequest& request_info, - RequestMap* request_map, - base::Lock* request_map_lock) { - DCHECK(request_map); - scoped_refptr<UrlmonUrlRequest> new_request; - bool is_started = false; - if (pending_request_) { - if (pending_request_->url() != request_info.url) { - DLOG(INFO) << __FUNCTION__ - << "Received url request for url:" - << request_info.url - << ". Stopping pending url request for url:" - << pending_request_->url(); - pending_request_->Stop(); - pending_request_ = NULL; - } else { - new_request.swap(pending_request_); - is_started = true; - DVLOG(1) << __FUNCTION__ << new_request->me() - << " assigned id " << request_id; - } - } - - if (!is_started) { - CComObject<UrlmonUrlRequest>* created_request = NULL; - CComObject<UrlmonUrlRequest>::CreateInstance(&created_request); - new_request = created_request; - } - - // Format upload data if it's chunked. - if (request_info.upload_data && request_info.upload_data->is_chunked()) { - ScopedVector<net::UploadElement>* elements = - request_info.upload_data->elements_mutable(); - for (size_t i = 0; i < elements->size(); ++i) { - net::UploadElement* element = (*elements)[i]; - DCHECK(element->type() == net::UploadElement::TYPE_BYTES); - std::string chunk_length = base::StringPrintf( - "%X\r\n", static_cast<unsigned int>(element->bytes_length())); - std::vector<char> bytes; - bytes.insert(bytes.end(), chunk_length.data(), - chunk_length.data() + chunk_length.length()); - const char* data = element->bytes(); - bytes.insert(bytes.end(), data, data + element->bytes_length()); - const char* crlf = "\r\n"; - bytes.insert(bytes.end(), crlf, crlf + strlen(crlf)); - if (i == elements->size() - 1) { - const char* end_of_data = "0\r\n\r\n"; - bytes.insert(bytes.end(), end_of_data, - end_of_data + strlen(end_of_data)); - } - element->SetToBytes(&bytes[0], static_cast<int>(bytes.size())); - } - } - - new_request->Initialize(static_cast<PluginUrlRequestDelegate*>(this), - request_id, - request_info.url, - request_info.method, - request_info.referrer, - request_info.extra_request_headers, - request_info.upload_data, - static_cast<ResourceType::Type>(request_info.resource_type), - enable_frame_busting_, - request_info.load_flags); - new_request->set_parent_window(notification_window_); - new_request->set_privileged_mode(privileged_mode_); - - if (request_map_lock) - request_map_lock->Acquire(); - - (*request_map)[request_id] = new_request; - - if (request_map_lock) - request_map_lock->Release(); - - if (!is_started) { - // Freshly created, start now. - new_request->Start(); - } else { - // Request is already underway, call OnResponse so that the - // other side can start reading. - DCHECK(!new_request->response_headers().empty()); - new_request->OnResponse( - 0, UTF8ToWide(new_request->response_headers()).c_str(), NULL, NULL); - } -} - -void UrlmonUrlRequestManager::ReadRequest(int request_id, int bytes_to_read) { - DVLOG(1) << __FUNCTION__ << " id: " << request_id; - // if we fail to find the request in the normal map and the background - // request map, it may mean that the request could have failed with a - // network error. - scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id, - &request_map_); - if (request) { - request->Read(bytes_to_read); - } else if (background_worker_thread_enabled_) { - base::AutoLock lock(background_resource_map_lock_); - request = LookupRequest(request_id, &background_request_map_); - if (request) { - background_thread_->message_loop()->PostTask( - FROM_HERE, base::Bind(base::IgnoreResult(&UrlmonUrlRequest::Read), - request.get(), bytes_to_read)); - } - } - if (!request) - DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; -} - void UrlmonUrlRequestManager::BindTerminated(IMoniker* moniker, IBindCtx* bind_ctx, IStream* post_data, const char* request_headers) { } -void UrlmonUrlRequestManager::EndRequest(int request_id) { - DVLOG(1) << __FUNCTION__ << " id: " << request_id; - scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id, - &request_map_); - if (request) { - request_map_.erase(request_id); - request->Stop(); - } else if (background_worker_thread_enabled_) { - base::AutoLock lock(background_resource_map_lock_); - request = LookupRequest(request_id, &background_request_map_); - if (request) { - background_request_map_.erase(request_id); - background_thread_->message_loop()->PostTask( - FROM_HERE, base::Bind(&UrlmonUrlRequest::Stop, request.get())); - } - } - if (!request) - DLOG(ERROR) << __FUNCTION__ << " no request found for " << request_id; -} - -void UrlmonUrlRequestManager::StopAll() { - DVLOG(1) << __FUNCTION__; - if (stopping_) - return; - - stopping_ = true; - - DVLOG(1) << __FUNCTION__ << " stopping " << request_map_.size() - << " requests"; - - StopAllRequestsHelper(&request_map_, NULL); - - if (background_worker_thread_enabled_) { - DCHECK(background_thread_.get()); - background_thread_->message_loop()->PostTask( - FROM_HERE, base::Bind(&UrlmonUrlRequestManager::StopAllRequestsHelper, - base::Unretained(this), &background_request_map_, - &background_resource_map_lock_)); - background_thread_->Stop(); - background_thread_.reset(); - } -} - -void UrlmonUrlRequestManager::StopAllRequestsHelper( - RequestMap* request_map, - base::Lock* request_map_lock) { - DCHECK(request_map); - - DVLOG(1) << __FUNCTION__ << " stopping " << request_map->size() - << " requests"; - - if (request_map_lock) - request_map_lock->Acquire(); - - for (RequestMap::iterator it = request_map->begin(); - it != request_map->end(); ++it) { - DCHECK(it->second != NULL); - it->second->Stop(); - } - request_map->clear(); - - if (request_map_lock) - request_map_lock->Release(); -} - -void UrlmonUrlRequestManager::OnResponseStarted( - int request_id, const char* mime_type, const char* headers, int size, - base::Time last_modified, const std::string& redirect_url, - int redirect_status, const net::HostPortPair& socket_address, - uint64 upload_size) { - DCHECK_NE(request_id, -1); - DVLOG(1) << __FUNCTION__; - -#ifndef NDEBUG - scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id, - &request_map_); - if (request == NULL && background_worker_thread_enabled_) { - base::AutoLock lock(background_resource_map_lock_); - request = LookupRequest(request_id, &background_request_map_); - } - DCHECK(request != NULL); -#endif // NDEBUG - delegate_->OnResponseStarted( - request_id, mime_type, headers, size, last_modified, redirect_url, - redirect_status, socket_address, upload_size); -} - -void UrlmonUrlRequestManager::OnReadComplete(int request_id, - const std::string& data) { - DCHECK_NE(request_id, -1); - DVLOG(1) << __FUNCTION__ << " id: " << request_id; -#ifndef NDEBUG - scoped_refptr<UrlmonUrlRequest> request = LookupRequest(request_id, - &request_map_); - if (request == NULL && background_worker_thread_enabled_) { - base::AutoLock lock(background_resource_map_lock_); - request = LookupRequest(request_id, &background_request_map_); - } - DCHECK(request != NULL); -#endif // NDEBUG - delegate_->OnReadComplete(request_id, data); - DVLOG(1) << __FUNCTION__ << " done id: " << request_id; -} - -void UrlmonUrlRequestManager::OnResponseEnd( - int request_id, - const net::URLRequestStatus& status) { - DCHECK_NE(request_id, -1); - DVLOG(1) << __FUNCTION__; - DCHECK(status.status() != net::URLRequestStatus::CANCELED); - RequestMap::size_type erased_count = request_map_.erase(request_id); - if (erased_count != 1u && background_worker_thread_enabled_) { - base::AutoLock lock(background_resource_map_lock_); - erased_count = background_request_map_.erase(request_id); - if (erased_count != 1u) { - DLOG(WARNING) << __FUNCTION__ - << " Failed to find request id:" - << request_id; - } - } - delegate_->OnResponseEnd(request_id, status); -} - scoped_refptr<UrlmonUrlRequest> UrlmonUrlRequestManager::LookupRequest( int request_id, RequestMap* request_map) { RequestMap::iterator it = request_map->find(request_id); @@ -1310,7 +926,6 @@ UrlmonUrlRequestManager::UrlmonUrlRequestManager() } UrlmonUrlRequestManager::~UrlmonUrlRequestManager() { - StopAll(); } void UrlmonUrlRequestManager::AddPrivacyDataForUrl( diff --git a/chrome_frame/urlmon_url_request.h b/chrome_frame/urlmon_url_request.h index 4ae2783..92f050b 100644 --- a/chrome_frame/urlmon_url_request.h +++ b/chrome_frame/urlmon_url_request.h @@ -80,21 +80,6 @@ class UrlmonUrlRequestManager // PluginUrlRequestManager implementation. virtual PluginUrlRequestManager::ThreadSafeFlags GetThreadSafeFlags(); - virtual void StartRequest(int request_id, - const AutomationURLRequest& request_info); - virtual void ReadRequest(int request_id, int bytes_to_read); - virtual void EndRequest(int request_id); - virtual void StopAll(); - - // PluginUrlRequestDelegate implementation - virtual void OnResponseStarted( - int request_id, const char* mime_type, const char* headers, int size, - base::Time last_modified, const std::string& redirect_url, - int redirect_status, const net::HostPortPair& socket_address, - uint64 upload_size); - virtual void OnReadComplete(int request_id, const std::string& data); - virtual void OnResponseEnd(int request_id, - const net::URLRequestStatus& status); // This method is passed as a callback to UrlmonUrlRequest::TerminateBind. // We simply forward moniker and bind_ctx to host ActiveX/ActiveDocument, @@ -115,15 +100,6 @@ class UrlmonUrlRequestManager // synchronize access. base::Lock background_resource_map_lock_; - // Helper function to stop all requests in the request map. - void StopAllRequestsHelper(RequestMap* request_map, - base::Lock* request_map_lock); - // Helper function for initiating a new IE request. - void StartRequestHelper(int request_id, - const AutomationURLRequest& request_info, - RequestMap* request_map, - base::Lock* request_map_lock); - scoped_refptr<UrlmonUrlRequest> pending_request_; scoped_ptr<base::Thread> background_thread_; |