Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome_frame/test/net/test_automation_provider.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/file_version_info.h"
      9 #include "base/path_service.h"
     10 #include "chrome/common/automation_messages.h"
     11 #include "chrome_frame/test/net/test_automation_resource_message_filter.h"
     12 #include "net/url_request/url_request_context.h"
     13 
     14 namespace {
     15 
     16 // A special command line switch to just run the unit tests without CF in
     17 // the picture.  Can be useful when the harness itself needs to be debugged.
     18 const char kNoCfTestRun[] = "no-cf-test-run";
     19 
     20 bool CFTestsDisabled() {
     21   static bool switch_present = CommandLine::ForCurrentProcess()->
     22       HasSwitch(kNoCfTestRun);
     23   return switch_present;
     24 }
     25 
     26 }  // end namespace
     27 
     28 TestAutomationProvider* TestAutomationProvider::g_provider_instance_ = NULL;
     29 
     30 TestAutomationProvider::TestAutomationProvider(
     31     Profile* profile,
     32     TestAutomationProviderDelegate* delegate)
     33     : AutomationProvider(profile), tab_handle_(-1), delegate_(delegate) {
     34   // We need to register the protocol factory before the
     35   // AutomationResourceMessageFilter registers the automation job factory to
     36   // ensure that we don't inadvarently end up handling http requests which
     37   // we don't expect. The initial chrome frame page for the network tests
     38   // issues http requests which our test factory should not handle.
     39   net::URLRequest::Deprecated::RegisterProtocolFactory(
     40       "http", TestAutomationProvider::Factory);
     41   net::URLRequest::Deprecated::RegisterProtocolFactory(
     42       "https", TestAutomationProvider::Factory);
     43   automation_resource_message_filter_ =
     44       new TestAutomationResourceMessageFilter(this);
     45   g_provider_instance_ = this;
     46 }
     47 
     48 TestAutomationProvider::~TestAutomationProvider() {
     49   delegate_->OnProviderDestroyed();
     50   g_provider_instance_ = NULL;
     51 }
     52 
     53 bool TestAutomationProvider::OnMessageReceived(const IPC::Message& msg) {
     54   if (automation_resource_message_filter_->OnMessageReceived(msg))
     55     return true;  // Message handled by the filter.
     56 
     57   return __super::OnMessageReceived(msg);
     58 }
     59 
     60 // IPC override to grab the tab handle.
     61 bool TestAutomationProvider::Send(IPC::Message* msg) {
     62   if (msg->type() == AutomationMsg_TabLoaded::ID) {
     63     DCHECK(tab_handle_ == -1) << "Currently only support one tab";
     64     tab_handle_ = msg->routing_id();
     65     DVLOG(1) << "Got tab handle: " << tab_handle_;
     66     DCHECK(tab_handle_ != -1 && tab_handle_ != 0);
     67     delegate_->OnInitialTabLoaded();
     68   }
     69 
     70   return AutomationProvider::Send(msg);
     71 }
     72 
     73 net::URLRequestJob* TestAutomationProvider::Factory(
     74     net::URLRequest* request,
     75     net::NetworkDelegate* network_delegate,
     76     const std::string& scheme) {
     77   if (CFTestsDisabled())
     78     return NULL;
     79 
     80   if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
     81     // Only look at requests that don't have any user data.
     82     // ResourceDispatcherHost uses the user data for requests that it manages.
     83     // We don't want to mess with those.
     84 
     85     // We could also check if the current thread is our TestUrlRequest thread
     86     // and only intercept requests that belong to that thread.
     87     if (g_provider_instance_ && request->GetUserData(NULL) == NULL &&
     88         g_provider_instance_->tab_handle_ != -1) {
     89       // We generate our own request id which is also what
     90       // ResourceDispatcherHost does (well, the id is actually generated by
     91       // ResourceDispatcher).  Since these requests are divided into with
     92       // and without userdata, we're OK.  However, just to make debugging
     93       // a little easier, we have a significantly higher start value.
     94       static int new_id = 0x00100000;
     95       URLRequestAutomationJob* job = new URLRequestAutomationJob(
     96           request, network_delegate,
     97           request->context()->http_user_agent_settings(),
     98           g_provider_instance_->tab_handle_, new_id++,
     99           g_provider_instance_->automation_resource_message_filter_, false);
    100       return job;
    101     }
    102   }
    103 
    104   return NULL;
    105 }
    106 
    107 std::string TestAutomationProvider::GetProtocolVersion() {
    108   // Return the version of npchrome_frame.dll.  We used to use
    109   // chrome.dll, but the other end of the pipe in this case is
    110   // actually npchrome_frame.dll (which fetches its version info from
    111   // itself), and occasionally we run into RC dependency problems in
    112   // incremental builds so that the version information does not get
    113   // updated in one module but does in another, so better to use the
    114   // exact same version to avoid hard-to-debug problems in development
    115   // builds.
    116   base::FilePath path;
    117   PathService::Get(base::DIR_MODULE, &path);
    118   path = path.AppendASCII("npchrome_frame.dll");
    119 
    120   std::string version;
    121   scoped_ptr<FileVersionInfo> version_info(
    122       FileVersionInfo::CreateFileVersionInfo(path));
    123   if (version_info.get()) {
    124     version = WideToASCII(version_info->product_version());
    125   }
    126   return version;
    127 }
    128 
    129 // static
    130 TestAutomationProvider* TestAutomationProvider::NewAutomationProvider(
    131     Profile* p, const std::string& channel,
    132     TestAutomationProviderDelegate* delegate) {
    133   TestAutomationProvider* automation = new TestAutomationProvider(p, delegate);
    134   automation->InitializeChannel(channel);
    135   automation->SetExpectedTabCount(1);
    136   return automation;
    137 }
    138