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