Class: Deas::Runner

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

Direct Known Subclasses

DeasRunner, TestRunner

Defined Under Namespace

Classes: NormalizedParams, SendFileBody

Constant Summary collapse

DEFAULT_MIME_TYPE =
'application/octet-stream'.freeze
DEFAULT_CHARSET =
'utf-8'.freeze
DEFAULT_STATUS =
200.freeze
DEFAULT_BODY =
[].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(handler_class, args = nil) ⇒ Runner

Returns a new instance of Runner.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/deas/runner.rb', line 20

def initialize(handler_class, args = nil)
  @status, @headers, @body = nil, Rack::Utils::HeaderHash.new, nil

  @handler_class = handler_class
  @handler = @handler_class.new(self)

  args ||= {}
  @request         = args[:request]
  @route_path      = args[:route_path].to_s
  @params          = args[:params]          || {}
  @logger          = args[:logger]          || Deas::NullLogger.new
  @router          = args[:router]          || Deas::Router.new
  @template_source = args[:template_source] || Deas::NullTemplateSource.new
end

Instance Attribute Details

#handlerObject (readonly)

Returns the value of attribute handler.



16
17
18
# File 'lib/deas/runner.rb', line 16

def handler
  @handler
end

#handler_classObject (readonly)

Returns the value of attribute handler_class.



16
17
18
# File 'lib/deas/runner.rb', line 16

def handler_class
  @handler_class
end

#loggerObject (readonly)

Returns the value of attribute logger.



18
19
20
# File 'lib/deas/runner.rb', line 18

def logger
  @logger
end

#paramsObject (readonly)

Returns the value of attribute params.



17
18
19
# File 'lib/deas/runner.rb', line 17

def params
  @params
end

#requestObject (readonly)

Returns the value of attribute request.



17
18
19
# File 'lib/deas/runner.rb', line 17

def request
  @request
end

#route_pathObject (readonly)

Returns the value of attribute route_path.



17
18
19
# File 'lib/deas/runner.rb', line 17

def route_path
  @route_path
end

#routerObject (readonly)

Returns the value of attribute router.



18
19
20
# File 'lib/deas/runner.rb', line 18

def router
  @router
end

#template_sourceObject (readonly)

Returns the value of attribute template_source.



18
19
20
# File 'lib/deas/runner.rb', line 18

def template_source
  @template_source
end

Instance Method Details

#body(value = nil) ⇒ Object



57
58
59
60
61
62
63
64
65
# File 'lib/deas/runner.rb', line 57

def body(value = nil)
  if !value.nil?
    # http://www.rubydoc.info/github/rack/rack/master/file/SPEC#The_Body
    # "The Body must respond to each and must only yield String values"
    # String#each is a thing in 1.8.7, so account for it here
    @body = !value.respond_to?(:each) || value.kind_of?(String) ? [*value.to_s] : value
  end
  @body
end

#content_type(extname, params = nil) ⇒ Object



67
68
69
# File 'lib/deas/runner.rb', line 67

def content_type(extname, params = nil)
  self.headers['Content-Type'] = get_content_type(extname, params)
end

#halt(*args) ⇒ Object



79
80
81
82
83
84
# File 'lib/deas/runner.rb', line 79

def halt(*args)
  self.status(args.shift)  if args.first.instance_of?(::Fixnum)
  self.headers(args.shift) if args.first.kind_of?(::Hash)
  self.body(args.shift)
  throw :halt
end

#headers(value = nil) ⇒ Object



52
53
54
55
# File 'lib/deas/runner.rb', line 52

def headers(value = nil)
  @headers.merge!(value) if !value.nil?
  @headers
end

#partial(template_name, locals = nil) ⇒ Object



133
134
135
# File 'lib/deas/runner.rb', line 133

def partial(template_name, locals = nil)
  source_partial(self.template_source, template_name, locals)
end

#redirect(location, *halt_args) ⇒ Object



86
87
88
89
90
# File 'lib/deas/runner.rb', line 86

def redirect(location, *halt_args)
  self.status(302)
  self.headers['Location'] = get_absolute_url(location)
  halt(*halt_args)
end

#render(template_name, locals = nil) ⇒ Object



121
122
123
# File 'lib/deas/runner.rb', line 121

def render(template_name, locals = nil)
  source_render(self.template_source, template_name, locals)
end

#runObject

Raises:

  • (NotImplementedError)


39
40
41
# File 'lib/deas/runner.rb', line 39

def run
  raise NotImplementedError
end

#send_file(file_path, opts = nil) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/deas/runner.rb', line 92

def send_file(file_path, opts = nil)
  path_name = Pathname.new(file_path)
  self.halt(404, []) if !path_name.exist?

  env   = self.request.env
  mtime = path_name.mtime.httpdate.to_s
  self.halt(304, []) if env['HTTP_IF_MODIFIED_SINCE'] == mtime
  self.headers['Last-Modified'] ||= mtime

  self.headers['Content-Type'] ||= get_content_type(path_name.extname)

  opts ||= {}
  disposition = opts[:disposition]
  filename    = opts[:filename]
  disposition ||= 'attachment' if !filename.nil?
  filename    ||= path_name.basename
  if !disposition.nil?
    self.headers['Content-Disposition'] ||= "#{disposition};filename=\"#{filename}\""
  end

  sfb = SendFileBody.new(env, path_name)
  self.body(sfb)
  self.headers['Content-Length'] ||= sfb.size.to_s
  self.headers['Content-Range']  ||= sfb.content_range if sfb.partial?
  self.status(sfb.partial? ? 206 : 200)

  self.halt # be consistent with halts above - `send_file` always halts
end


71
72
73
74
75
76
77
# File 'lib/deas/runner.rb', line 71

def set_cookie(name, value, opts = nil)
  Rack::Utils.set_cookie_header!(
    self.headers,
    name,
    (opts || {}).merge(:value => value)
  )
end

#source_partial(source, template_name, locals = nil) ⇒ Object



137
138
139
# File 'lib/deas/runner.rb', line 137

def source_partial(source, template_name, locals = nil)
  source.partial(template_name, locals || {})
end

#source_render(source, template_name, locals = nil) ⇒ Object



125
126
127
128
129
130
131
# File 'lib/deas/runner.rb', line 125

def source_render(source, template_name, locals = nil)
  self.headers['Content-Type'] ||= get_content_type(
    File.extname(template_name),
    'charset' => DEFAULT_CHARSET
  )
  self.body(source.render(template_name, self.handler, locals || {}))
end

#splatObject



35
36
37
# File 'lib/deas/runner.rb', line 35

def splat
  @splat ||= parse_splat_value
end

#status(value = nil) ⇒ Object



47
48
49
50
# File 'lib/deas/runner.rb', line 47

def status(value = nil)
  @status = value if !value.nil?
  @status
end

#to_rackObject



43
44
45
# File 'lib/deas/runner.rb', line 43

def to_rack
  [self.status || DEFAULT_STATUS, self.headers.to_hash, self.body || DEFAULT_BODY]
end