Class: Regurgitator::FileRequest

Inherits:
HTTP_Spew::Request
  • Object
show all
Extended by:
Local
Defined in:
lib/regurgitator/file_request.rb

Overview

Opens a IO.select-able object to read a (potentially large) file from a backend. We don’t bother with keepalive since we want send buffers to be empty, so make sure you have enough local ports. You may want to enable TIME-WAIT reuse/recycling in your TCP stack if your network supports it. This object is used as a Rack response body.

Constant Summary collapse

USER_AGENT =
name.dup
PASS_HEADERS =
%w(Range If-Modified-Since Accept-Encoding)

Constants included from Local

Local::STORE_PATHS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Local

addr, addrs, device_path_stat, include?, refresh_addrs!, register, trylocal

Constructor Details

#initialize(env, uris) ⇒ FileRequest

uris may be an array, read-only URIs are at the end



21
22
23
24
25
26
27
28
29
30
# File 'lib/regurgitator/file_request.rb', line 21

def initialize(env, uris)
  uri = uris[-1] # a subclass of this may call multiple URIs
  addr = Socket.pack_sockaddr_in(uri.port, uri.host)
  req = {
    "REQUEST_URI" => uri.request_uri,
    "HTTP_HOST" => "#{uri.host}:#{uri.port}",
  }.merge!(env)
  @uri = uri
  super req, nil, addr
end

Instance Attribute Details

#uriObject (readonly)

used for doing redirects or reproxying with nginx



12
13
14
# File 'lib/regurgitator/file_request.rb', line 12

def uri
  @uri
end

Class Method Details

.run(env, uri_group, timeout = env["regurgitator.timeout"] || 5) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/regurgitator/file_request.rb', line 32

def self.run(env, uri_group, timeout = env["regurgitator.timeout"] || 5)
  local_file = trylocal(env, uri_group) and return local_file.response

  req = {
    "REQUEST_METHOD" => env["REQUEST_METHOD"],
    "HTTP_USER_AGENT" => USER_AGENT,
  }
  PASS_HEADERS.each { |k| pass = env[k] and req[k] = pass }
  tmp = HTTP_Spew.wait(1, uri_group.map { |uris| new(req, uris) }, timeout)
  tmp.delete_if(&:error)
  ready = tmp.shift or raise Regurgitator::NoDevices, "no readable devices"
  tmp.each(&:close)
  ready.response
end