Module: IntervalResponse

Defined in:
lib/interval_response.rb,
lib/interval_response/version.rb

Defined Under Namespace

Classes: Abstract, Empty, Error, Full, Invalid, LazyFile, Multi, RackBodyWrapper, Sequence, Single

Constant Summary collapse

ENTIRE_RESOURCE_RANGE =
'bytes=0-'
VERSION =
"0.1.7"

Class Method Summary collapse

Class Method Details

.new(interval_sequence, rack_env_headers) ⇒ Empty, ...

Creates a new IntervalResponse object. The object returned does not have a specific class, but is one of the following objects, which all support the same interface:

  • IntervalResponse::Empty for an empty response

  • IntervalResponse::Single for a single HTTP range

  • IntervalResponse::Full for the entire resource

  • IntervalResponse::Multi for multipart ranges response with multiple HTTP ranges

  • IntervalResponse::Invalid for responses that are 416 (Unsatisfiable range)

Parameters:

  • interval_sequence (IntervalResponse::Sequence)

    the sequence of segments

  • rack_env_headers (Hash)

    the Rack env, or a Hash containing ‘HTTP_RANGE’ and ‘HTTP_IF_RANGE’ headers

Returns:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/interval_response.rb', line 33

def self.new(interval_sequence, rack_env_headers)
  http_range_header_value = rack_env_headers['HTTP_RANGE']
  http_if_range_header_value = rack_env_headers['HTTP_IF_RANGE']

  # If the 'If-Range' header is provided but does not match, discard the Range header. It means
  # that the client is requesting a certain representation of the resource and wants a range
  # _within_ that representation, but the representation has since changed and the offsets
  # no longer make sense. In that case we are supposed to answer with a 200 and the full
  # monty.
  if http_if_range_header_value && http_if_range_header_value != interval_sequence.etag
    Measurometer.increment_counter('interval_response.if_range_mismatch', 1)
    return new(interval_sequence, 'HTTP_RANGE' => ENTIRE_RESOURCE_RANGE)
  end

  if http_if_range_header_value
    Measurometer.increment_counter('interval_response.if_range_match', 1)
  elsif http_range_header_value
    Measurometer.increment_counter('interval_response.if_range_not_provided', 1)
  end

  prepare_response(interval_sequence, http_range_header_value).tap do |res|
    response_type_name_for_metric = res.class.to_s.split('::').last.downcase # Some::Module::Empty => empty
    Measurometer.increment_counter('interval_response.resp_%s' % response_type_name_for_metric, 1)
  end
end