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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(handler_class, args = nil) ⇒ Runner

Returns a new instance of Runner.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/deas/runner.rb', line 26

def initialize(handler_class, args = nil)
  @handler_class = handler_class
  @status, @body = nil, nil
  @headers = Rack::Utils::HeaderHash.new.merge(@handler_class.default_headers)
  @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.



22
23
24
# File 'lib/deas/runner.rb', line 22

def handler
  @handler
end

#handler_classObject (readonly)

Returns the value of attribute handler_class.



22
23
24
# File 'lib/deas/runner.rb', line 22

def handler_class
  @handler_class
end

#loggerObject (readonly)

Returns the value of attribute logger.



24
25
26
# File 'lib/deas/runner.rb', line 24

def logger
  @logger
end

#paramsObject (readonly)

Returns the value of attribute params.



23
24
25
# File 'lib/deas/runner.rb', line 23

def params
  @params
end

#requestObject (readonly)

Returns the value of attribute request.



23
24
25
# File 'lib/deas/runner.rb', line 23

def request
  @request
end

#route_pathObject (readonly)

Returns the value of attribute route_path.



23
24
25
# File 'lib/deas/runner.rb', line 23

def route_path
  @route_path
end

#routerObject (readonly)

Returns the value of attribute router.



24
25
26
# File 'lib/deas/runner.rb', line 24

def router
  @router
end

#template_sourceObject (readonly)

Returns the value of attribute template_source.



24
25
26
# File 'lib/deas/runner.rb', line 24

def template_source
  @template_source
end

Class Method Details

.body_value(value) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/deas/runner.rb', line 14

def self.body_value(value)
  # 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
  return nil if value.to_s.empty?
  !value.respond_to?(:each) || value.kind_of?(String) ? [*value.to_s] : value
end

Instance Method Details

#body(value = nil) ⇒ Object



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

def body(value = nil)
  if !value.nil?
    @body = self.class.body_value(value)
  end
  @body
end

#content_type(extname, params = nil) ⇒ Object



73
74
75
# File 'lib/deas/runner.rb', line 73

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

#halt(*args) ⇒ Object



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

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)    if !args.first.to_s.empty?
  throw :halt
end

#headers(value = nil) ⇒ Object



61
62
63
64
# File 'lib/deas/runner.rb', line 61

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

#partial(template_name, locals = nil) ⇒ Object



139
140
141
# File 'lib/deas/runner.rb', line 139

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

#redirect(location, *halt_args) ⇒ Object



92
93
94
95
96
# File 'lib/deas/runner.rb', line 92

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



127
128
129
# File 'lib/deas/runner.rb', line 127

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

#runObject

Raises:

  • (NotImplementedError)


45
46
47
# File 'lib/deas/runner.rb', line 45

def run
  raise NotImplementedError
end

#send_file(file_path, opts = nil) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/deas/runner.rb', line 98

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


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

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



143
144
145
# File 'lib/deas/runner.rb', line 143

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

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



131
132
133
134
135
136
137
# File 'lib/deas/runner.rb', line 131

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



41
42
43
# File 'lib/deas/runner.rb', line 41

def splat
  @splat ||= parse_splat_value
end

#status(value = nil) ⇒ Object



56
57
58
59
# File 'lib/deas/runner.rb', line 56

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

#to_rackObject



49
50
51
52
53
54
# File 'lib/deas/runner.rb', line 49

def to_rack
  [ self.status || @handler_class.default_status,
    self.headers.to_hash,
    self.body   || @handler_class.default_body
  ]
end