12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/net/url_request_context_getter.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/ip_endpoint.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_log.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_util.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/socket/tcp_server_socket.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SyncUrlFetcher : public net::URLFetcherDelegate { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncUrlFetcher(const GURL& url, 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequestContextGetter* getter, 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* response) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : url_(url), getter_(getter), response_(response), event_(false, false) {} 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SyncUrlFetcher() {} 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Fetch() { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getter_->GetNetworkTaskRunner()->PostTask( 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncUrlFetcher::FetchOnIOThread, base::Unretained(this))); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_.Wait(); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return success_; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void FetchOnIOThread() { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_.reset(net::URLFetcher::Create(url_, net::URLFetcher::GET, this)); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_->SetRequestContext(getter_); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_->Start(); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) success_ = (source->GetResponseCode() == 200); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (success_) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) success_ = source->GetResponseAsString(response_); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_.reset(); // Destroy the fetcher on IO thread. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_.Signal(); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url_; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequestContextGetter* getter_; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* response_; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WaitableEvent event_; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::URLFetcher> fetcher_; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success_; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool FetchUrl(const std::string& url, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequestContextGetter* getter, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* response) { 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SyncUrlFetcher(GURL(url), getter, response).Fetch(); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FindOpenPort(int* port) { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char parts[] = {127, 0, 0, 1}; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::IPAddressNumber address(parts, parts + arraysize(parts)); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog::Source source; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < 10; ++i) { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::TCPServerSocket sock(NULL, source); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use port 0, so that the OS will assign an available ephemeral port. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sock.Listen(net::IPEndPoint(address, 0), 1) != net::OK) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::IPEndPoint end_point; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sock.GetLocalAddress(&end_point) != net::OK) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *port = end_point.port(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 89