# http/util.js

    1// Copyright 2013 Selenium committers2// Copyright 2013 Software Freedom Conservancy3//4// Licensed under the Apache License, Version 2.0 (the "License");5// you may not use this file except in compliance with the License.6//     You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an "AS IS" BASIS,12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13// See the License for the specific language governing permissions and14// limitations under the License.1516/**17 * @fileoverview Various HTTP utilities.18 */1920var base = require('../_base'),21    HttpClient = require('./index').HttpClient,22    checkResponse = base.require('bot.response').checkResponse,23    Executor = base.require('webdriver.http.Executor'),24    HttpRequest = base.require('webdriver.http.Request'),25    Command = base.require('webdriver.Command'),26    CommandName = base.require('webdriver.CommandName'),27    promise = base.require('webdriver.promise');28293031/**32 * Queries a WebDriver server for its current status.33 * @param {string} url Base URL of the server to query.34 * @param {function(Error, *=)} callback The function to call with the35 *     response.36 */37function getStatus(url, callback) {38  var client = new HttpClient(url);39  var executor = new Executor(client);40  var command = new Command(CommandName.GET_SERVER_STATUS);41  executor.execute(command, function(err, responseObj) {42    if (err) return callback(err);43    try {44      checkResponse(responseObj);45    } catch (ex) {46      return callback(ex);47    }48    callback(null, responseObj['value']);49  });50}515253// PUBLIC API545556/**57 * Queries a WebDriver server for its current status.58 * @param {string} url Base URL of the server to query.59 * @return {!webdriver.promise.Promise.<!Object>} A promise that resolves with60 *     a hash of the server status.61 */62exports.getStatus = function(url) {63  return promise.checkedNodeCall(getStatus.bind(null, url));64};656667/**68 * Waits for a WebDriver server to be healthy and accepting requests.69 * @param {string} url Base URL of the server to query.70 * @param {number} timeout How long to wait for the server.71 * @return {!webdriver.promise.Promise} A promise that will resolve when the72 *     server is ready.73 */74exports.waitForServer = function(url, timeout) {75  var ready = promise.defer(),76      start = Date.now(),77      checkServerStatus = getStatus.bind(null, url, onResponse);78  checkServerStatus();79  return ready.promise;8081  function onResponse(err) {82    if (!ready.isPending()) return;83    if (!err) return ready.fulfill();8485    if (Date.now() - start > timeout) {86      ready.reject(87          Error('Timed out waiting for the WebDriver server at ' + url));88    } else {89      setTimeout(function() {90        if (ready.isPending()) {91          checkServerStatus();92        }93      }, 50);94    }95  }96};979899/**100 * Polls a URL with GET requests until it returns a 2xx response or the101 * timeout expires.102 * @param {string} url The URL to poll.103 * @param {number} timeout How long to wait, in milliseconds.104 * @return {!webdriver.promise.Promise} A promise that will resolve when the105 *     URL responds with 2xx.106 */107exports.waitForUrl = function(url, timeout) {108  var client = new HttpClient(url),109      request = new HttpRequest('GET', ''),110      testUrl = client.send.bind(client, request, onResponse),111      ready = promise.defer(),112      start = Date.now();113  testUrl();114  return ready.promise;115116  function onResponse(err, response) {117    if (!ready.isPending()) return;118    if (!err && response.status > 199 && response.status < 300) {119      return ready.fulfill();120    }121122    if (Date.now() - start > timeout) {123      ready.reject(Error(124          'Timed out waiting for the URL to return 2xx: ' + url));125    } else {126      setTimeout(function() {127        if (ready.isPending()) {128          testUrl();129        }130      }, 50);131    }132  }133};