class JSON::Schema::Reader

When an unregistered schema is encountered, the {JSON::Schema::Reader} is used to fetch its contents and register it with the {JSON::Validator}.

This default reader will read schemas from the filesystem or from a URI.

Public Class Methods

new(options = {}) click to toggle source

The behavior of the schema reader can be controlled by providing callbacks to determine whether to permit reading referenced schemas. The options accept_uri and accept_file should be procs which accept a URI or Pathname object, and return a boolean value indicating whether to read the referenced schema.

URIs using the file scheme will be normalized into Pathname objects and passed to the accept_file callback.

@param options [Hash] @option options [Boolean, call] accept_uri (true) @option options [Boolean, call] accept_file (true)

@example Reject all unregistered schemas

JSON::Validator.schema_reader = JSON::Schema::Reader.new(
  :accept_uri => false,
  :accept_file => false
)

@example Only permit URIs from certain hosts

JSON::Validator.schema_reader = JSON::Schema::Reader.new(
  :accept_file => false,
  :accept_uri => proc { |uri| ['mycompany.com', 'json-schema.org'].include?(uri.host) }
)
# File lib/json-schema/schema/reader.rb, line 73
def initialize(options = {})
  @accept_uri = options.fetch(:accept_uri, true)
  @accept_file = options.fetch(:accept_file, true)
end

Public Instance Methods

accept_file?(pathname) click to toggle source

@param pathname [Pathname] @return [Boolean]

# File lib/json-schema/schema/reader.rb, line 109
def accept_file?(pathname)
  if @accept_file.respond_to?(:call)
    @accept_file.call(pathname)
  else
    @accept_file
  end
end
accept_uri?(uri) click to toggle source

@param uri [Addressable::URI] @return [Boolean]

# File lib/json-schema/schema/reader.rb, line 99
def accept_uri?(uri)
  if @accept_uri.respond_to?(:call)
    @accept_uri.call(uri)
  else
    @accept_uri
  end
end
read(location) click to toggle source

@param location [#to_s] The location from which to read the schema @return [JSON::Schema] @raise [JSON::Schema::ReadRefused] if accept_uri or accept_file

indicated the schema could not be read

@raise [JSON::Schema::ParseError] if the schema was not a valid JSON object @raise [JSON::Schema::ReadFailed] if reading the location was acceptable but the

attempt to retrieve it failed
# File lib/json-schema/schema/reader.rb, line 85
def read(location)
  uri  = JSON::Util::URI.parse(location.to_s)
  body = if uri.scheme.nil? || uri.scheme == 'file'
           uri = JSON::Util::URI.file_uri(uri)
           read_file(Pathname.new(uri.path).expand_path)
         else
           read_uri(uri)
         end

  JSON::Schema.new(JSON::Validator.parse(body), uri)
end

Private Instance Methods

read_file(pathname) click to toggle source
# File lib/json-schema/schema/reader.rb, line 129
def read_file(pathname)
  if accept_file?(pathname)
    File.read(JSON::Util::URI.unescaped_path(pathname.to_s))
  else
    raise JSON::Schema::ReadRefused.new(pathname.to_s, :file)
  end
rescue Errno::ENOENT
  raise JSON::Schema::ReadFailed.new(pathname.to_s, :file)
end
read_uri(uri) click to toggle source
# File lib/json-schema/schema/reader.rb, line 119
def read_uri(uri)
  if accept_uri?(uri)
    open(uri.to_s).read
  else
    raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
  end
rescue OpenURI::HTTPError, SocketError
  raise JSON::Schema::ReadFailed.new(uri.to_s, :uri)
end