Path: blob/trunk/rb/lib/selenium/webdriver/remote/http/common.rb
4014 views
# frozen_string_literal: true12# Licensed to the Software Freedom Conservancy (SFC) under one3# or more contributor license agreements. See the NOTICE file4# distributed with this work for additional information5# regarding copyright ownership. The SFC licenses this file6# to you under the Apache License, Version 2.0 (the7# "License"); you may not use this file except in compliance8# with the License. You may obtain a copy of the License at9#10# http://www.apache.org/licenses/LICENSE-2.011#12# Unless required by applicable law or agreed to in writing,13# software distributed under the License is distributed on an14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY15# KIND, either express or implied. See the License for the16# specific language governing permissions and limitations17# under the License.1819module Selenium20module WebDriver21module Remote22module Http23class Common24MAX_REDIRECTS = 20 # same as chromium/gecko25CONTENT_TYPE = 'application/json'26DEFAULT_HEADERS = {27'Accept' => CONTENT_TYPE,28'Content-Type' => "#{CONTENT_TYPE}; charset=UTF-8"29}.freeze30BINARY_ENCODINGS = [Encoding::BINARY, Encoding::ASCII_8BIT].freeze3132class << self33attr_accessor :extra_headers34attr_writer :user_agent3536def user_agent37@user_agent ||= "selenium/#{WebDriver::VERSION} (ruby #{Platform.os})"38end39end4041attr_writer :server_url4243def quit_errors44[IOError]45end4647def close48# hook for subclasses - will be called on Driver#quit49end5051# steep:ignore:start52def call(verb, url, command_hash)53url = server_url.merge(url) unless url.is_a?(URI)54headers = common_headers.dup55headers['Cache-Control'] = 'no-cache' if verb == :get5657if command_hash58command_hash = ensure_utf8_encoding(command_hash)59payload = JSON.generate(command_hash)60headers['Content-Length'] = payload.bytesize.to_s if %i[post put].include?(verb)6162WebDriver.logger.debug(" >>> #{url} | #{payload}", id: :command)63WebDriver.logger.debug(" > #{headers.inspect}", id: :header)64elsif verb == :post65payload = '{}'66headers['Content-Length'] = '2'67end6869request verb, url, headers, payload70end71# steep:ignore:end7273private7475def common_headers76@common_headers ||= begin77headers = DEFAULT_HEADERS.dup78headers['User-Agent'] = Common.user_agent79headers = headers.merge(Common.extra_headers || {})8081headers82end83end8485def server_url86return @server_url if @server_url8788raise Error::WebDriverError, 'server_url not set'89end9091def request(*)92raise NotImplementedError, 'subclass responsibility'93end9495def ensure_utf8_encoding(obj)96case obj97when String98encode_string_to_utf8(obj)99when Array100obj.map { |item| ensure_utf8_encoding(item) }101when Hash102obj.each_with_object({}) do |(key, value), result|103result[ensure_utf8_encoding(key)] = ensure_utf8_encoding(value)104end105else106obj107end108end109110def encode_string_to_utf8(str)111return str if str.encoding == Encoding::UTF_8 && str.valid_encoding?112113if BINARY_ENCODINGS.include?(str.encoding)114result = str.dup.force_encoding(Encoding::UTF_8)115return result if result.valid_encoding?116end117118str.encode(Encoding::UTF_8)119rescue EncodingError => e120raise Error::WebDriverError,121"Unable to encode string to UTF-8: #{e.message}. " \122"String encoding: #{str.encoding}, content: #{str.inspect}"123end124125def create_response(code, body, content_type)126code = code.to_i127body = body.to_s.strip128content_type = content_type.to_s129WebDriver.logger.debug("<- #{body}", id: :command)130131if content_type.include? CONTENT_TYPE132raise Error::WebDriverError, "empty body: #{content_type.inspect} (#{code})\n#{body}" if body.empty?133134Response.new(code, JSON.parse(body))135elsif code == 204136Response.new(code)137else138msg = if body.empty?139"unexpected response, code=#{code}, content-type=#{content_type.inspect}"140else141"unexpected response, code=#{code}, content-type=#{content_type.inspect}\n#{body}"142end143144raise Error::WebDriverError, msg145end146end147end # Common148end # Http149end # Remote150end # WebDriver151end # Selenium152153154