Class: FormatParser::RemoteIO

Inherits:
Object
  • Object
show all
Defined in:
lib/remote_io.rb

Overview

Acts as a wrapper for turning a given URL into an IO object you can read from and seek in. Uses Faraday under the hood to perform fetches, so if you apply Faraday configuration tweaks using ‘Faraday.default_connection = …` these will take effect for these RemoteIO objects as well

Defined Under Namespace

Classes: IntermittentFailure, InvalidRequest, UpstreamError

Instance Method Summary collapse

Constructor Details

#initialize(uri, headers: {}) ⇒ RemoteIO

Returns a new instance of RemoteIO.

Parameters:

  • uri (URI, String)

    the remote URL to obtain

  • headers (Hash) (defaults to: {})

    (optional) the HTTP headers to be used in the HTTP request



28
29
30
31
32
33
34
35
# File 'lib/remote_io.rb', line 28

def initialize(uri, headers: {})
  require 'faraday'
  require 'faraday_middleware/response/follow_redirects'
  @headers = headers
  @uri = uri
  @pos = 0
  @remote_size = false
end

Instance Method Details

#posObject

Emulates IO#pos



44
45
46
# File 'lib/remote_io.rb', line 44

def pos
  @pos
end

#read(n_bytes) ⇒ String

Emulates IO#read, but requires the number of bytes to read The read will be limited to the size of the remote resource relative to the current offset in the IO, so if you are at offset 0 in the IO of size 10, doing a ‘read(20)` will only return you 10 bytes of result, and not raise any exceptions.

Parameters:

  • n_bytes (Fixnum, nil)

    how many bytes to read, or nil to read all the way to the end

Returns:

  • (String)

    the read bytes



64
65
66
67
68
69
70
71
72
# File 'lib/remote_io.rb', line 64

def read(n_bytes)
  http_range = (@pos..(@pos + n_bytes - 1))
  maybe_size, maybe_body = Measurometer.instrument('format_parser.RemoteIO.read') { request_range(http_range) }
  if maybe_size && maybe_body
    @remote_size = maybe_size
    @pos += maybe_body.bytesize
    maybe_body.force_encoding(Encoding::ASCII_8BIT)
  end
end

#seek(offset) ⇒ Object

Emulates IO#seek



38
39
40
41
# File 'lib/remote_io.rb', line 38

def seek(offset)
  @pos = offset
  0 # always return 0
end

#sizeInteger

Emulates IO#size.

Returns:

  • (Integer)

    the size of the remote resource



51
52
53
54
# File 'lib/remote_io.rb', line 51

def size
  raise 'Remote size not yet obtained, need to perform at least one read() to retrieve it' unless @remote_size
  @remote_size
end