# frozen_string_literal: true# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.require'ipaddr'moduleSeleniummoduleWebDrivermoduleRemotemoduleHttp# @api privateclassDefault<Common# Initializes object.# Warning: Setting {#open_timeout} to non-nil values will cause a separate thread to spawn.# Debuggers that freeze the process will not be able to evaluate any operations if that happens.# @param [ClientConfig] client_config - Configuration used to build the HTTP client.# @param [Numeric] open_timeout - Open timeout to apply to HTTP client.# @param [Numeric] read_timeout - Read timeout (seconds) to apply to HTTP client.definitialize(client_config: nil,open_timeout: nil,read_timeout: nil)ifclient_config&&(open_timeout||read_timeout)raiseArgumentError,'Cannot use both :client_config and :open_timeout/:read_timeout'endclient_config||=ClientConfig.newclient_config.open_timeout=open_timeoutifopen_timeoutclient_config.read_timeout=read_timeoutifread_timeoutsuper(client_config: client_config)enddefopen_timeoutclient_config.open_timeoutenddefread_timeoutclient_config.read_timeoutenddefopen_timeout=(value)client_config.open_timeout=valueenddefread_timeout=(value)client_config.read_timeout=valueenddefproxy=(value)client_config.proxy=valueenddefclose@http&.finishendprivatedefhttp@http||=beginhttp=new_http_clientifserver_url.scheme=='https'http.use_ssl=truehttp.verify_mode=OpenSSL::SSL::VERIFY_NONEendhttp.open_timeout=open_timeoutifopen_timeouthttp.read_timeout=read_timeoutifread_timeoutstart(http)httpendenddefstart(http)http.startendMAX_RETRIES=3defrequest(verb,url,headers,payload,redirects=0)retries=0beginrequest=new_request_for(verb,url,headers,payload)response=response_for(request)rescueErrno::ECONNABORTED,Errno::ECONNRESET,Errno::EADDRINUSE,Errno::EADDRNOTAVAIL# a retry is sometimes needed:# on Windows XP where we may quickly run out of ephemeral ports# when the port becomes temporarily unavailable## A more robust solution is bumping the MaxUserPort setting# as described here:## http://msdn.microsoft.com/en-us/library/aa560610%28v=bts.20%29.aspxraiseifretries>=MAX_RETRIESretries+=1sleep2retryrescueErrno::ECONNREFUSED=>eraisee.class,"using proxy: #{proxy.http}"ifuse_proxy?raiseendifresponse.is_a?Net::HTTPRedirectionfollow_redirect(response,redirects)elseWebDriver.logger.debug(" <<< #{response.instance_variable_get(:@header).inspect}",id: :header)create_responseresponse.code,response.body,response.content_typeendenddeffollow_redirect(response,redirects)WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}")raiseError::WebDriverError,'too many redirects'ifredirects>=client_config.max_redirectsrequest(:get,URI.parse(response['Location']),DEFAULT_HEADERS.dup,nil,redirects+1)enddefnew_request_for(verb,url,headers,payload)req=Net::HTTP.const_get(verb.to_s.capitalize).new(url.path,headers)req.basic_authserver_url.user,server_url.passwordifserver_url.userinforeq.body=payloadifpayloadreqenddefresponse_for(request)http.requestrequestenddefnew_http_clientifuse_proxy?url=proxy.httpunlessproxy.respond_to?(:http)&&urlraiseError::WebDriverError,"expected HTTP proxy, got #{proxy.inspect}"endproxy_uri=URI.parse(url)Net::HTTP.new(server_url.host,server_url.port,proxy_uri.host,proxy_uri.port,proxy_uri.user,proxy_uri.password)elseNet::HTTP.newserver_url.host,server_url.portendenddefproxyclient_config.proxyenddefuse_proxy?returnfalseifproxy.nil?returntrueunlessproxy.no_proxy!proxy_ignored?enddefproxy_ignored?proxy.no_proxy.split(',').map(&:strip).reject(&:empty?).any?do|host|host=='*'||host==server_url.host||ip_match?(host)endenddefip_match?(host)IPAddr.new(host).include?(server_url.host)rescueArgumentErrorfalseendend# Defaultend# Httpend# Remoteend# WebDriverend# Selenium