15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/devtools_ui.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/chrome_url_request_context.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_http_handler.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/url_data_source.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_fetcher.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PathWithoutParams(const std::string& path) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GURL(std::string("chrome-devtools://devtools/") + path) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .path().substr(1); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kRemoteFrontendDomain[] = "chrome-devtools-frontend.appspot.com"; 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kRemoteFrontendBase[] = 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "https://chrome-devtools-frontend.appspot.com/"; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n"; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(DEBUG_DEVTOOLS) 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Local frontend url provided by InspectUI. 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kLocalFrontendURLPrefix[] = "https://localhost:9222/"; 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif // defined(DEBUG_DEVTOOLS) 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FetchRequest : public net::URLFetcherDelegate { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FetchRequest(net::URLRequestContextGetter* request_context, 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& url, 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const content::URLDataSource::GotDataCallback& callback) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : callback_(callback) { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!url.is_valid()) { 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnURLFetchComplete(NULL); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher_.reset(net::URLFetcher::Create(url, net::URLFetcher::GET, this)); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher_->SetRequestContext(request_context); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher_->Start(); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~FetchRequest() {} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE { 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string response; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (source) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) source->GetResponseAsString(&response); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response = kHttpNotFound; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_.Run(base::RefCountedString::TakeString(&response)); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete this; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<net::URLFetcher> fetcher_; 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::URLDataSource::GotDataCallback callback_; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string GetMimeTypeForPath(const std::string& path) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string filename = PathWithoutParams(path); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (EndsWith(filename, ".html", false)) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "text/html"; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (EndsWith(filename, ".css", false)) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "text/css"; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (EndsWith(filename, ".js", false)) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "application/javascript"; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (EndsWith(filename, ".png", false)) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "image/png"; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (EndsWith(filename, ".gif", false)) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "image/gif"; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (EndsWith(filename, ".manifest", false)) { 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return "text/cache-manifest"; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "text/plain"; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// An URLDataSource implementation that handles chrome-devtools://devtools/ 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// requests. Three types of requests could be handled based on the URL path: 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 1. /bundled/: bundled DevTools frontend is served. 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 2. /remote/: Remote DevTools frontend is served from App Engine. 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 3. /localhost/: Remote frontend is served from localhost:9222. This is a 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// debug only feature hidden beihnd a compile time flag DEBUG_DEVTOOLS. 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class DevToolsDataSource : public content::URLDataSource { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) explicit DevToolsDataSource(net::URLRequestContextGetter* 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_context) : request_context_(request_context) { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // content::URLDataSource implementation. 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual std::string GetSource() const OVERRIDE { 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return chrome::kChromeUIDevToolsHost; 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void StartDataRequest( 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& path, 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_process_id, 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_view_id, 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const content::URLDataSource::GotDataCallback& callback) OVERRIDE { 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bundled_path_prefix += "/"; 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (StartsWithASCII(path, bundled_path_prefix, false)) { 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StartBundledDataRequest(path.substr(bundled_path_prefix.length()), 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_process_id, 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_view_id, 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback); 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string remote_path_prefix(chrome::kChromeUIDevToolsRemotePath); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) remote_path_prefix += "/"; 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (StartsWithASCII(path, remote_path_prefix, false)) { 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StartRemoteDataRequest(path.substr(remote_path_prefix.length()), 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_process_id, 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_view_id, 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Serves bundled DevTools frontend from ResourceBundle. 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void StartBundledDataRequest( 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& path, 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int render_process_id, 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int render_view_id, 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const content::URLDataSource::GotDataCallback& callback) { 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string filename = PathWithoutParams(path); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int resource_id = 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::DevToolsHttpHandler::GetFrontendResourceId(filename); 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG_IF(WARNING, -1 == resource_id) << "Unable to find dev tool resource: " 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << filename << ". If you compiled with debug_devtools=1, try running" 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " with --debug-devtools."; 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<base::RefCountedStaticMemory> bytes(rb.LoadDataResourceBytes( 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_id)); 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback.Run(bytes.get()); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Serves remote DevTools frontend from hard-coded App Engine domain. 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void StartRemoteDataRequest( 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& path, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_process_id, 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_view_id, 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const content::URLDataSource::GotDataCallback& callback) { 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url = GURL(kRemoteFrontendBase + path); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(url.host(), kRemoteFrontendDomain); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new FetchRequest(request_context_.get(), url, callback); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual std::string GetMimeType(const std::string& path) const OVERRIDE { 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetMimeTypeForPath(path); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE { 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual ~DevToolsDataSource() {} 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_; 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DevToolsDataSource); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GURL DevToolsUI::GetProxyURL(const std::string& frontend_url) { 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url(frontend_url); 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(DEBUG_DEVTOOLS) 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (frontend_url.find(kLocalFrontendURLPrefix) == 0) { 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string path = url.path(); 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string local_path_prefix = "/"; 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch local_path_prefix += chrome::kChromeUIDevToolsHost; 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch local_path_prefix += "/"; 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (StartsWithASCII(path, local_path_prefix, false)) { 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string local_path = path.substr(local_path_prefix.length()); 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return GURL(base::StringPrintf("%s://%s/%s/%s", 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch chrome::kChromeDevToolsScheme, 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch chrome::kChromeUIDevToolsHost, 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch chrome::kChromeUIDevToolsBundledPath, 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch local_path.c_str())); 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // defined(DEBUG_DEVTOOLS) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(url.is_valid()); 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(url.host(), kRemoteFrontendDomain); 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GURL(base::StringPrintf("%s://%s/%s/%s", 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) chrome::kChromeDevToolsScheme, 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) chrome::kChromeUIDevToolsHost, 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) chrome::kChromeUIDevToolsRemotePath, 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url.path().substr(1).c_str())); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsUI::DevToolsUI(content::WebUI* web_ui) : WebUIController(web_ui) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_ui->SetBindings(0); 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::URLDataSource::Add( 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile, 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new DevToolsDataSource(profile->GetRequestContext())); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 224