Class: Lux::Response

Inherits:
Object show all
Defined in:
lib/lux/response/response.rb

Overview

response.header ‘x-blah’, 123 response.max_age = 10 response.public = true response.status = 500

Defined Under Namespace

Classes: File, Flash, Header

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResponse

Returns a new instance of Response.



12
13
14
15
16
# File 'lib/lux/response/response.rb', line 12

def initialize
  @render_start = Time.monotonic
  @headers      = Lux::Response::Header.new
  @max_age      = 0
end

Instance Attribute Details

#content_type(type = nil) ⇒ Object

Returns the value of attribute content_type.



10
11
12
# File 'lib/lux/response/response.rb', line 10

def content_type
  @content_type
end

#cookiesObject

Returns the value of attribute cookies.



10
11
12
# File 'lib/lux/response/response.rb', line 10

def cookies
  @cookies
end

#headersObject

Returns the value of attribute headers.



10
11
12
# File 'lib/lux/response/response.rb', line 10

def headers
  @headers
end

#max_ageObject

define in seconds, how long should page be accessible in client cache if defined, cache becomes public and can be cache by proxies use with care.only for static resources and



9
10
11
# File 'lib/lux/response/response.rb', line 9

def max_age
  @max_age
end

#status(num = nil) ⇒ Object Also known as: status=

Returns the value of attribute status.



10
11
12
# File 'lib/lux/response/response.rb', line 10

def status
  @status
end

Instance Method Details

#auth(relam = nil) ⇒ Object

auth { |user, pass| [user, pass] == [‘foo’, ‘bar’] }



151
152
153
154
155
156
157
158
159
160
161
# File 'lib/lux/response/response.rb', line 151

def auth relam=nil
  if auth = current.request.env['HTTP_AUTHORIZATION']
    credentials = auth.to_s.split('Basic ', 2)[1].unpack("m*").first.split(':', 2)
    return true if yield *credentials
  end

  status 401
  header('WWW-Authenticate', 'Basic realm="%s"' % relam.or('default'))
  body 'HTTP 401 Authorization needed'
  throw :done
end

#body(body_data = nil, status = nil) ⇒ Object



70
71
72
73
74
75
# File 'lib/lux/response/response.rb', line 70

def body body_data=nil, status=nil
  @status = status      if status
  @body   = body_data   if body_data
  @body   = yield @body if block_given?
  @body
end

#body?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/lux/response/response.rb', line 77

def body?
  !!@body
end

#currentObject



18
19
20
# File 'lib/lux/response/response.rb', line 18

def current
  Lux.current
end

#early_hints(link = nil, type = nil) ⇒ Object

http 103



32
33
34
35
36
# File 'lib/lux/response/response.rb', line 32

def early_hints link=nil, type=nil
  @early_hints ||= []
  @early_hints.push [link, type] if type && !@early_hints.include?(link)
  @early_hints
end

#etag(*args) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/lux/response/response.rb', line 38

def etag *args
  unless @headers['etag']
    args.push current.request.url

    key = '"%s"' % Lux.cache.generate_key(args)
    key = 'W/%s' % key unless max_age > 0

    @headers['etag'] = key
  end

  if !@body && current.request.env['HTTP_IF_NONE_MATCH'] == @headers['etag']
    status 304
    body   'not-modified'
  end
end

#flash(message = nil) ⇒ Object



102
103
104
105
106
# File 'lib/lux/response/response.rb', line 102

def flash message=nil
  @flash ||= Flash.new current.session[:lux_flash]

  message ? @flash.error(message) : @flash
end

#halt(status = nil, msg = nil) ⇒ Object



63
64
65
66
67
68
# File 'lib/lux/response/response.rb', line 63

def halt status=nil, msg=nil
  @status = status || 400
  @body   = msg if msg

  throw :done
end

#header(name, value = :_) ⇒ Object



22
23
24
25
# File 'lib/lux/response/response.rb', line 22

def header name, value=:_
  @headers[name] = value if value != :_
  @headers[name]
end

#permanent_redirect(where) ⇒ Object



146
147
148
# File 'lib/lux/response/response.rb', line 146

def permanent_redirect where
  redirect where, status:301
end

#redirect(where, opts = {}) ⇒ Object

redirect ‘/foo’ redirect :back, info: ‘bar …’



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/lux/response/response.rb', line 114

def redirect where, opts={}
  where  = current.request.env['HTTP_REFERER'].or('/') if where == :back
  where  = "#{current.request.path}#{where}" if where[0,1] == '?'
  where  = current.host + where unless where.include?('://')

  # local redirect
  if where.include?(current.host)
    redirect_var = Lux.config.redirect_var || :_r

    url = Url.new where
    url[redirect_var] = current.request.params[redirect_var].to_i + 1

    where =
      if opts.delete(:silent)
        url.delete redirect_var
        url.to_s
      else
        url[redirect_var] > 3 ? '/' : url.to_s
      end
  end

  @status = opts.delete(:status) || 302
  opts.map { |k,v| flash.send(k, v) }

  @body = %[redirecting to #{where}\n\n#{opts.values.join("\n")}]

  @headers['location'] = where
  @headers['access-control-expose-headers'] ||= 'Location'

  throw :done
end

#renderObject



214
215
216
217
218
219
220
221
222
# File 'lib/lux/response/response.rb', line 214

def render
  write_response_body
  write_response_header

  @status ||= 200
  Lux.log " #{@status}, #{@headers['x-lux-speed']}"

  [@status, @headers.to_h, [@body]]
end

#send_file(file, opts = {}) ⇒ Object



108
109
110
# File 'lib/lux/response/response.rb', line 108

def send_file file, opts={}
  ::Lux::Response::File.new(file, opts).send
end

#write_response_bodyObject



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/lux/response/response.rb', line 163

def write_response_body
  unless @body
    @status = 204
    @body = 'Lux HTTP ERROR 204: NO CONTENT'
  end

  # respond as JSON if we recive hash
  if @body.kind_of?(Hash)
    @body = Lux.dev? ? JSON.pretty_generate(@body) : JSON.generate(@body)

    if current.request.params[:callback]
      @body = "#{current.request.params[:callback]}(#{ret})"
      @content_type ||= 'text/javascript'
    else
      @content_type ||= 'application/json'
    end

    @body += "\n"
  else
    # if somebody sets @content_type, respect that
    @body = @body.to_s unless @body.kind_of?(String)
    @content_type ||= 'text/plain' if @body[0,1] != '<'
    @content_type ||= 'text/html'
  end
end

#write_response_headerObject



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/lux/response/response.rb', line 189

def write_response_header
  # cache-control
  @headers['cache-control'] ||= Proc.new do
    cc = ['max-age=%d' % max_age]
    cc.push max_age > 0 ? 'public, no-cache' : 'private, must-revalidate'
    cc.join(', ')
  end.call

  current.session[:lux_flash] = flash.to_h

  # dont annd cookies to public pages (images, etc..)
  unless @headers['cache-control'].index('public')
    cookie = current.session.generate_cookie
    @headers['set-cookie'] = cookie if cookie
  end

  etag(@body) if current.request.request_method == 'GET'

  @headers['x-lux-speed']     = "#{((Time.monotonic - @render_start)*1000).round(1)} ms"
  @headers['content-type']  ||= "#{@content_type}; charset=utf-8"
  @headers['content-length']  = @body.bytesize.to_s

  # if "no-store" is present then HTTP_IF_NONE_MATCH is not sent from browser
end