lux-fw 0.1.35 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +5 -5
  2. data/.version +1 -1
  3. data/bin/cli/am +67 -41
  4. data/bin/cli/assets +1 -1
  5. data/bin/cli/console +3 -2
  6. data/bin/cli/eval +11 -2
  7. data/bin/cli/exceptions +1 -1
  8. data/bin/cli/generate +4 -0
  9. data/bin/cli/render +18 -0
  10. data/bin/cli/routes +3 -1
  11. data/bin/cli/server +4 -1
  12. data/bin/lux +10 -1
  13. data/bin/txt/nginx.conf +35 -18
  14. data/lib/common/class_attributes.rb +10 -10
  15. data/lib/common/{before_and_after.rb → class_callbacks.rb} +12 -21
  16. data/lib/common/crypt.rb +10 -6
  17. data/lib/common/dynamic_class.rb +12 -7
  18. data/lib/common/generic_model.rb +6 -6
  19. data/lib/common/hash_with_indifferent_access.rb +6 -284
  20. data/lib/{lux/helper/lib/html_tag.rb → common/html_tag_builder.rb} +1 -1
  21. data/lib/common/policy.rb +2 -2
  22. data/lib/common/url.rb +6 -4
  23. data/lib/lux-fw.rb +2 -13
  24. data/lib/lux/api/api.rb +34 -47
  25. data/lib/lux/api/lib/dsl.rb +2 -2
  26. data/lib/lux/api/lib/model_api.rb +40 -23
  27. data/lib/lux/api/lib/response.rb +30 -5
  28. data/lib/lux/application/application.rb +182 -0
  29. data/lib/lux/{controller → application}/lib/nav.rb +18 -21
  30. data/lib/lux/application/lib/plugs.rb +10 -0
  31. data/lib/lux/application/lib/render.rb +58 -0
  32. data/lib/lux/application/lib/route_test.rb +64 -0
  33. data/lib/lux/cache/cache.rb +27 -16
  34. data/lib/lux/cell/cell.rb +66 -54
  35. data/lib/lux/config/config.rb +51 -27
  36. data/lib/lux/current/current.rb +122 -0
  37. data/lib/lux/{page → current}/lib/encrypt_params.rb +2 -2
  38. data/lib/lux/{page → current}/lib/static_file.rb +29 -25
  39. data/lib/lux/delayed_job/delayed_job.rb +4 -4
  40. data/lib/lux/error/error.rb +31 -16
  41. data/lib/lux/helper/helper.rb +32 -37
  42. data/lib/lux/helper/helpers/application_helper.rb +3 -0
  43. data/lib/lux/helper/helpers/html_helper.rb +3 -0
  44. data/lib/lux/helper/helpers/mailer_helper.rb +11 -0
  45. data/lib/lux/lux.rb +40 -30
  46. data/lib/lux/mailer/mailer.rb +46 -29
  47. data/lib/lux/{page → response}/lib/flash.rb +1 -1
  48. data/lib/lux/response/lib/header.rb +21 -0
  49. data/lib/lux/response/response.rb +237 -0
  50. data/lib/lux/template/template.rb +20 -18
  51. data/lib/overload/array.rb +5 -0
  52. data/lib/overload/auto_loader.rb +27 -0
  53. data/lib/overload/blank.rb +8 -2
  54. data/lib/overload/float.rb +10 -0
  55. data/lib/overload/hash.rb +5 -12
  56. data/lib/overload/integer.rb +1 -5
  57. data/lib/overload/nil.rb +5 -0
  58. data/lib/overload/object.rb +1 -0
  59. data/lib/overload/r.rb +5 -0
  60. data/lib/overload/string.rb +4 -5
  61. data/lib/overload/{date.rb → time.rb} +23 -3
  62. metadata +37 -73
  63. data/bin/forever +0 -65
  64. data/bin/job_que +0 -39
  65. data/lib/lux/api/lib/application_api.rb +0 -38
  66. data/lib/lux/api/lib/doc_builder.rb +0 -19
  67. data/lib/lux/api/lib/rescue.rb +0 -8
  68. data/lib/lux/controller/controller.rb +0 -185
  69. data/lib/lux/controller/lib/plugs.rb +0 -10
  70. data/lib/lux/html/html.rb +0 -3
  71. data/lib/lux/html/lib/form.rb +0 -81
  72. data/lib/lux/html/lib/input.rb +0 -71
  73. data/lib/lux/html/lib/input_types.rb +0 -287
  74. data/lib/lux/lib/lux.rb +0 -51
  75. data/lib/lux/page/lib/response.rb +0 -178
  76. data/lib/lux/page/page.rb +0 -292
  77. data/lib/lux/rescue_from/rescue_from.rb +0 -63
  78. data/lib/plugins/assets/assets_plug.rb +0 -31
  79. data/lib/plugins/assets/helper_module_adapter.rb +0 -51
  80. data/lib/plugins/assets/init.rb +0 -4
  81. data/lib/plugins/db_helpers/array_and_hstore.rb +0 -64
  82. data/lib/plugins/db_helpers/arrays_and_tags.rb +0 -23
  83. data/lib/plugins/db_helpers/before_save.rb +0 -44
  84. data/lib/plugins/db_helpers/cached_find_by.rb +0 -45
  85. data/lib/plugins/db_helpers/class_and_instance.rb +0 -120
  86. data/lib/plugins/db_helpers/dataset_plugin.rb +0 -101
  87. data/lib/plugins/db_helpers/filter_wrappers.rb +0 -21
  88. data/lib/plugins/db_helpers/link_plugin.rb +0 -95
  89. data/lib/plugins/db_helpers/localize_plugin.rb +0 -57
  90. data/lib/plugins/db_helpers/primary_keys.rb +0 -36
  91. data/lib/plugins/db_helpers/typero_attributes.rb +0 -69
  92. data/lib/plugins/db_logger/init.rb +0 -18
  93. data/lib/plugins/db_logger/lux_response_adapter.rb +0 -9
  94. data/lib/plugins/paginate/helper.rb +0 -32
  95. data/lib/plugins/paginate/sequel_adapter.rb +0 -18
  96. data/lib/vendor/mini_assets/lib/asset.rb +0 -71
  97. data/lib/vendor/mini_assets/lib/asset/css.rb +0 -19
  98. data/lib/vendor/mini_assets/lib/asset/js.rb +0 -17
  99. data/lib/vendor/mini_assets/lib/base.rb +0 -69
  100. data/lib/vendor/mini_assets/lib/base/javascript.rb +0 -13
  101. data/lib/vendor/mini_assets/lib/base/stylesheet.rb +0 -5
  102. data/lib/vendor/mini_assets/lib/manifest.rb +0 -18
  103. data/lib/vendor/mini_assets/lib/opts.rb +0 -16
  104. data/lib/vendor/mini_assets/mini_assets.rb +0 -74
  105. data/lib/vendor/oauth/lib/facebook.rb +0 -35
  106. data/lib/vendor/oauth/lib/github.rb +0 -37
  107. data/lib/vendor/oauth/lib/google.rb +0 -41
  108. data/lib/vendor/oauth/lib/linkedin.rb +0 -41
  109. data/lib/vendor/oauth/lib/stackexchange.rb +0 -37
  110. data/lib/vendor/oauth/lib/twitter.rb +0 -41
  111. data/lib/vendor/oauth/oauth.rb +0 -46
@@ -1,48 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # plugins should extend this
4
- module DefaultHelper
5
- end
6
-
7
3
  class Lux::Helper
8
4
 
9
- class << self
10
- def for group, locals={}, &block
11
- base_class_helper = if [Symbol, String].include?(group.class)
12
- "#{group}_helper".classify.constantize
13
- elsif group
14
- group
15
- end
5
+ # create helper object that cah be used in template render
6
+ def initialize instance, *list
7
+ extend ApplicationHelper
16
8
 
17
- helper = Lux::Helper.new
18
- helper.extend DefaultHelper
19
- helper.extend base_class_helper if base_class_helper
20
-
21
- # locals overide globals
22
- for k, v in locals
23
- helper.instance_variable_set("@#{k.to_s.sub('@','')}", v)
24
- end
9
+ list.flatten.compact.each do |el|
10
+ el = el.to_s.classify+'Helper'
11
+ extend el.constantize
12
+ end
25
13
 
26
- return helper.instance_exec &block if block
14
+ local_vars = instance.class == Hash ? instance : instance.instance_variables_hash
27
15
 
28
- helper
16
+ # locals overide globals
17
+ for k, v in local_vars
18
+ instance_variable_set("@#{k.to_s.sub('@','')}", v)
29
19
  end
20
+
21
+ # helper.instance_exec &block if block
30
22
  end
31
23
 
32
24
  def no_white_space
33
25
  yield.gsub(/>\s+</,'><')
34
26
  end
35
27
 
36
- def page
37
- Lux.page
28
+ def current
29
+ Lux.current
38
30
  end
39
31
 
40
32
  def request
41
- Lux.page.request
33
+ Lux.current.request
42
34
  end
43
35
 
44
36
  def params
45
- Lux.page.params
37
+ Lux.current.params
38
+ end
39
+
40
+ def nav
41
+ Lux.current.nav
46
42
  end
47
43
 
48
44
  # renders just template but it is called
@@ -62,17 +58,16 @@ class Lux::Helper
62
58
  name = "#{Thread.current[:lux][:last_template_path]}/#{name}" unless name.index('/')
63
59
  end
64
60
 
65
- ivh = instance_variables_hash
66
-
67
61
  for k, v in locals
68
- ivh["@_#{k}"] = v
62
+ instance_variable_set("@_#{k}", v)
69
63
  end
70
64
 
71
65
  if block_given?
72
66
  name = "#{name}/layout" unless name.index('/')
73
- Lux::Template.new(name, ivh).render_part { yield }
67
+
68
+ Lux::Template.new(name, self).render_part { yield }
74
69
  else
75
- Lux::Template.new(name, ivh).render_part
70
+ Lux::Template.new(name, self).render_part
76
71
  end
77
72
  end
78
73
 
@@ -93,17 +88,17 @@ class Lux::Helper
93
88
  klass.cell(action, *args) rescue error("#{klass}.#{action}()\n\n#{$!.message}")
94
89
  end
95
90
 
96
- # add locale prefix if using locale
97
- def localize path
98
- return Lux.config(:localize) ? "/#{Locale.current}#{path}" : path
99
- end
100
-
101
91
  # tag :div, { 'class'=>'iform' } do
102
92
  def tag name=nil, opts={}, data=nil
103
- return Lux::Helper::HtmlTag unless name
93
+ return HtmlTagBuilder unless name
104
94
 
105
95
  data = yield(opts) if block_given?
106
- Lux::Helper::HtmlTag.tag name, opts, data
96
+ HtmlTagBuilder.tag name, opts, data
97
+ end
98
+
99
+ # helper(:main).method
100
+ def helper *names
101
+ Lux::Helper.new(self, *names)
107
102
  end
108
103
 
109
104
  end
@@ -0,0 +1,3 @@
1
+ # allways included
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,3 @@
1
+ module HtmlHelper
2
+
3
+ end
@@ -0,0 +1,11 @@
1
+ module MailerHelper
2
+ extend self
3
+
4
+ def mail
5
+ @mail
6
+ end
7
+
8
+ def host
9
+ ENV.fetch('HOST')
10
+ end
11
+ end
data/lib/lux/lux.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../common/class_callbacks.rb'
4
+
3
5
  module Lux
4
6
  extend self
5
7
 
6
8
  ENV_PROD = ENV['RACK_ENV'] == 'production'
7
9
  ENV_DEV = ENV['RACK_ENV'] == 'development'
8
10
  ENV_TEST = ENV['RACK_ENV'] == 'test'
9
- LUX_LIVE = ENV['LUX_LIVE'] == 'true'
10
- LUX_VERBOSE = ENV['LUX_VERBOSE'] == 'true'
11
11
  LUX_CLI = $0 == 'pry' || $0.index('/run.rb') || ENV['RACK_ENV'] == 'test'
12
12
 
13
13
  VERSION = File.read File.expand_path('../../../.version', __FILE__).chomp
@@ -17,39 +17,45 @@ module Lux
17
17
  BACKGROUND_THREADS ||= []
18
18
  Kernel.at_exit { BACKGROUND_THREADS.each { |t| t.join } }
19
19
 
20
- define_method(:prod?) { ENV_PROD }
21
- define_method(:dev?) { ENV_DEV }
22
- define_method(:test?) { ENV_TEST }
23
- define_method(:live?) { LUX_LIVE } # is on a live web server
24
- define_method(:verbose?) { LUX_VERBOSE } # show verbose output
25
- define_method(:cli?) { $0 == 'pry' || $0.index('/run.rb') || ENV['RACK_ENV'] == 'test' }
20
+ define_method(:prod?) { ENV_PROD }
21
+ define_method(:dev?) { ENV_DEV }
22
+ define_method(:test?) { ENV_TEST }
23
+ define_method(:cli?) { !!($0 =~ %r[/bin/lux$]) }
24
+ define_method(:thread) { Thread.current[:lux] }
25
+ define_method(:cache) { Lux::Cache }
26
+
27
+ # main rack response
28
+ def call env=nil
29
+ req = Lux::Current.new env
30
+ req.response.render
31
+ rescue
32
+ raise $! if Lux.config(:show_server_errors)
33
+
34
+ [500, {}, ['Lux server error']]
35
+ end
26
36
 
27
- def env(key=nil)
37
+ def env key=nil
28
38
  return ENV['RACK_ENV'] unless key
29
39
  die "ENV['#{key}'] not found" if ENV[key].nil?
30
40
  ENV[key]
31
41
  end
32
42
 
33
- def config(key=nil)
43
+ def config key=nil
34
44
  return CONFIG unless key
35
45
  die 'Lux.config.%s not found' % key if CONFIG[key].nil?
36
46
  CONFIG[key].kind_of?(Proc) ? CONFIG[key].call() : CONFIG[key]
37
47
  end
38
48
 
39
- def thread
40
- Thread.current[:lux]
49
+ def current
50
+ Thread.current[:lux][:page] ||= Lux::Current.new('/mock')
41
51
  end
42
52
 
43
- def page
44
- Thread.current[:lux][:page] ||= Lux::Page.prepare('/mock')
45
- end
46
-
47
- def page=(what)
53
+ def current=(what)
48
54
  Thread.current[:lux][:page] = what
49
55
  end
50
56
 
51
- def cache
52
- Lux::Cache
57
+ def app &block
58
+ block ? Lux::Application.class_eval(&block) : Lux::Application
53
59
  end
54
60
 
55
61
  def root
@@ -61,7 +67,7 @@ module Lux
61
67
  end
62
68
 
63
69
  def error data
64
- page.status 500
70
+ current.response.status 500
65
71
  Lux::Error.show(data)
66
72
  end
67
73
 
@@ -70,13 +76,9 @@ module Lux
70
76
  puts what
71
77
  end
72
78
 
73
- def uid
74
- Thread.current[:uid_cnt] ||= 0
75
- "uid-#{Thread.current[:uid_cnt]+=1}"
76
- end
77
-
78
79
  def on name, ref=nil, &proc
79
80
  EVENTS[name] ||= []
81
+
80
82
  if block_given?
81
83
  puts "* event: #{name} defined".white
82
84
  EVENTS[name].push(proc)
@@ -102,15 +104,23 @@ module Lux
102
104
  end
103
105
 
104
106
  def speed loops=1
105
- render_start = Time.now.to_f
107
+ render_start = Time.monotonic
106
108
  loops.times { yield }
107
- num = ((Time.now.to_f - render_start)*1_000_000).to_i.to_s
108
- num = "#{num} ms"
109
+ num = (Time.monotonic - render_start) * 1000
110
+ num = "#{num.round(1)} ms"
109
111
  loops == 1 ? num : "Done #{loops.to_s.sub(/(\d)(\d{3})$/,'\1s \2')} loops in #{num}"
110
112
  end
111
113
 
112
- def consumed_memory
113
- `ps -o rss -p #{$$}`.chomp.split("\n").last.to_i / 1000
114
+ # load specific plugin
115
+ def plugin name
116
+ dir = '%s/plugins/%s' % [Lux.fw_root, name]
117
+ base = '%s/base.rb' % dir
118
+
119
+ if File.exist?(base)
120
+ load base
121
+ else
122
+ Lux::Config.require_all('%s/*' % dir)
123
+ end
114
124
  end
115
125
  end
116
126
 
@@ -11,63 +11,80 @@
11
11
  # Mailer.confirm_email('rejotl@gmailcom').body
12
12
 
13
13
  class Lux::Mailer
14
+ ClassCallbacks.define self, :before, :after
15
+ class_attribute :helper
14
16
 
15
- BeforeAndAfter.define self, :before, :after
17
+ attr_reader :mail
16
18
 
17
- attr_reader :subject, :to, :from
19
+ class << self
20
+ # Mailer.prepare(:confirm_email, 'rejotl@gmailcom')
21
+ def prepare template, *args
22
+ obj = new
23
+ obj.instance_variable_set :@_template, template
18
24
 
19
- # Mailer.prepare(:confirm_email, 'rejotl@gmailcom')
20
- def self.prepare(template, *args)
21
- obj = new
22
- obj.instance_variable_set :@_template, template
25
+ ClassCallbacks.execute obj, :before
26
+ obj.send template, *args
27
+ ClassCallbacks.execute obj, :after
23
28
 
24
- BeforeAndAfter.execute(obj, :before)
25
- obj.send(template, *args)
26
- BeforeAndAfter.execute(obj, :after)
29
+ obj
30
+ end
27
31
 
28
- obj
32
+ def render method_name, *args
33
+ send(method_name, *args).body
34
+ end
35
+
36
+ def method_missing method_sym, *args
37
+ prepare(method_sym, *args)
38
+ end
39
+
40
+ def deliver
41
+ send(method_name, *args).deliver
42
+ end
29
43
  end
30
44
 
31
- def self.render(method_name, *args)
32
- send(method_name, *args).body
45
+ ###
46
+
47
+ def initialize
48
+ @mail = DynamicClass.new subject: nil, body: nil, to: nil, cc: nil, from: nil
33
49
  end
34
50
 
35
51
  def deliver
36
- raise "From in mailer not defined" unless @from
37
- raise "To in mailer not defined" unless @to
38
- raise "Subject in mailer not defined" unless @subject
52
+ raise "From in mailer not defined" unless @mail.from
53
+ raise "To in mailer not defined" unless @mail.to
54
+ raise "Subject in mailer not defined" unless @mail.subject
39
55
 
40
56
  require 'mail'
41
57
 
42
58
  Mail.defaults { delivery_method Lux.config(:mail).delivery, Lux.config(:mail).opts }
43
59
 
44
60
  m = Mail.new
45
- m[:from] = @from
46
- m[:to] = @to
47
- m[:subject] = @subject
48
- m[:body] = body
61
+ m[:from] = @mail.from
62
+ m[:to] = @mail.to
63
+ m[:subject] = @mail.subject
64
+ m[:body] = @mail.body || body
49
65
  m[:content_type] = 'text/html; charset=UTF-8'
50
- m.deliver!
51
- end
52
66
 
53
- def deliver_later
54
- Lux.delay(self, :deliver)
67
+ Thread.new { m.deliver! }
55
68
  end
56
69
 
57
- def self.deliver
58
- send(method_name, *args).deliver
70
+ def deliver_later
71
+ Lux.delay self, :deliver
59
72
  end
60
73
 
61
74
  def body
62
- Lux::Template.render_with_layout("mailer/#{@_template}", instance_variables_hash)
75
+ return @mail.body if @mail.body
76
+
77
+ helper = Lux::Helper.new self, self.class.helper
78
+
79
+ Lux::Template.render_with_layout "mailer/#{@_template}", helper
63
80
  end
64
81
 
65
82
  def subject
66
- @subject
83
+ @mail.subject
67
84
  end
68
85
 
69
- def self.method_missing(method_sym, *args)
70
- prepare(method_sym, *args)
86
+ def to
87
+ @mail.to
71
88
  end
72
89
 
73
90
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Lux::Page::Flash
3
+ class Lux::Response::Flash
4
4
 
5
5
  # flash.info 'messsage ...'
6
6
  # flash.info = 'messsage ...'
@@ -0,0 +1,21 @@
1
+
2
+ class Lux::Response::Header
3
+ attr_reader :data
4
+
5
+ def initialize
6
+ @data = {}
7
+ end
8
+
9
+ def [] key
10
+ @data[key.downcase]
11
+ end
12
+
13
+ def []= key, value
14
+ @data[key.downcase] = value
15
+ end
16
+
17
+ def to_h
18
+ @data.to_h.sort.to_h
19
+ end
20
+
21
+ end
@@ -0,0 +1,237 @@
1
+ # response.header 'x-blah', 123
2
+ # response.max_age = 10
3
+ # response.public = true
4
+ # response.status = 500
5
+ class Lux::Response
6
+ # define in seconds, how long should page be accessible in client cache
7
+ # if defined, cache becomes public and can be cache by proxies
8
+ # use with care.only for static resources and
9
+ attr_reader :max_age
10
+
11
+ attr_accessor :body, :headers, :cookies, :content_type, :status, :cookie_multidomain, :cookie_domain
12
+
13
+ def initialize
14
+ @render_start = Time.monotonic
15
+ @headers = Lux::Response::Header.new
16
+ @max_age = 0
17
+ end
18
+
19
+ def current
20
+ Lux.current
21
+ end
22
+
23
+ def header name, value=:_
24
+ @headers[name] = value if value != :_
25
+ @headers[name]
26
+ end
27
+
28
+ def max_age= age
29
+ @max_age = age.to_i
30
+ end
31
+
32
+ def etag *args
33
+ unless @headers['etag']
34
+ args.push current.request.url
35
+
36
+ key = '"%s"' % Lux.cache.generate_key(args)
37
+ key = 'W/%s' % key unless max_age > 0
38
+
39
+ @headers['etag'] = key
40
+ end
41
+
42
+ if current.request.env['HTTP_IF_NONE_MATCH'] == @headers['etag']
43
+ @status = 304
44
+ @body = 'not-modified'
45
+ true
46
+ else
47
+ false
48
+ end
49
+ end
50
+
51
+ def status num=nil
52
+ return @status unless num
53
+ raise 'Bad status value [%s]' % num unless num.is_numeric?
54
+
55
+ @status ||= num
56
+ @status
57
+ end
58
+ alias :status= :status
59
+
60
+ def halt status=nil, msg=nil
61
+ @status = status || 400
62
+ @body = msg if msg
63
+
64
+ throw :done
65
+ end
66
+
67
+ def body what=nil
68
+ @body ||= what
69
+
70
+ if @body && block_given?
71
+ @body = yield @body
72
+ Lux.error 'Lux.current.response.body is not a string (bad current.response.body filter)' unless @body.is_a?(String)
73
+ end
74
+
75
+ @body
76
+ end
77
+ alias :body= :body
78
+
79
+ def body! what
80
+ @body = what
81
+ end
82
+
83
+ def content_type type=nil
84
+ return @content_type unless type
85
+
86
+ # can be set only once
87
+ return @content_type if @content_type
88
+
89
+ type = 'application/json' if type == :json
90
+ type = 'text/plain' if type == :text
91
+ type = 'text/html' if type == :html
92
+
93
+ raise 'Invalid page content-type %s' % type if type === Symbol
94
+
95
+ @content_type = type
96
+ end
97
+
98
+ def content_type= type
99
+ content_type type
100
+ end
101
+
102
+ def flash message=nil
103
+ @flash ||= Flash.new current.session[:lux_flash]
104
+
105
+ message ? @flash.error(message) : @flash
106
+ end
107
+
108
+ def redirect where=nil, opts={}
109
+ return @headers['location'] unless where
110
+
111
+ @status = opts.delete(:status) || 302
112
+ opts.map { |k,v| flash.send(k, v) }
113
+
114
+ @headers['location'] = where.index('//') ? where : "#{current.host}#{where}"
115
+ @headers['access-control-expose-headers'] ||= 'Location'
116
+
117
+ @body = %[redirecting to #{@headers['location']}\n\n#{opts.values.join("\n")}]
118
+
119
+ throw :done
120
+ end
121
+
122
+ def permanent_redirect where
123
+ redirect where, status:301
124
+ end
125
+
126
+ # auth { |user, pass| [user, pass] == ['foo', 'bar'] }
127
+ def auth relam=nil
128
+ if auth = current.request.env['HTTP_AUTHORIZATION']
129
+ credentials = auth.to_s.split('Basic ', 2)[1].unpack("m*").first.split(':', 2)
130
+ return true if yield *credentials
131
+ end
132
+
133
+ status 401
134
+ header('WWW-Authenticate', 'Basic realm="%s"' % relam.or('default'))
135
+ body = ErrorCell.unauthorized('HTTP 401 Authorization needed')
136
+
137
+ false
138
+ end
139
+
140
+ def write_response_body
141
+ unless @body
142
+ @status = 404
143
+ @body = Lux.error 'Document not found'
144
+ end
145
+
146
+ # respond as JSON if we recive hash
147
+ if @body.kind_of?(Hash)
148
+ @body = Lux.dev? ? JSON.pretty_generate(@body) : JSON.generate(@body)
149
+
150
+ if current.request.params[:callback]
151
+ @body = "#{current.request.params[:callback]}(#{ret})"
152
+ @content_type ||= 'text/javascript'
153
+ else
154
+ @content_type ||= 'application/json'
155
+ end
156
+
157
+ @body += "\n"
158
+ else
159
+ # if somebody sets @content_type, respect that
160
+ @body = @body.to_s unless @body.kind_of?(String)
161
+ @content_type ||= 'text/plain' if @body[0,1] != '<'
162
+ @content_type ||= 'text/html'
163
+ end
164
+ end
165
+
166
+ def write_response_header
167
+ domain =
168
+ if cookie_domain
169
+ cookie_domain
170
+ elsif cookie_multidomain && current.domain.index('.')
171
+ ".#{current.domain}"
172
+ else
173
+ current.request.host
174
+ end
175
+
176
+ # cache-control
177
+ @headers['cache-control'] ||= Proc.new do
178
+ cc = ['max-age=%d' % max_age]
179
+
180
+ if max_age > 0
181
+ cc.push 'public, no-cache'
182
+ else
183
+ cc.push 'private, must-revalidate'
184
+ end
185
+
186
+ cc.join(', ')
187
+ end.call
188
+
189
+ current.session[:lux_flash] = flash.to_h
190
+
191
+ # dont annd cookies to public pages (images, etc..)
192
+ add_cookies = true
193
+ add_cookies = false if @headers['cache-control'].index('public')
194
+
195
+ if add_cookies
196
+ encrypted = Crypt.encrypt(current.session.to_json)
197
+
198
+ if current.cookies[Lux.config.session_cookie_name] != encrypted
199
+ @headers['set-cookie'] = "#{Lux.config.session_cookie_name}=#{encrypted}; Expires=#{(Time.now+1.month).utc}; Path=/; Domain=#{domain};"
200
+ end
201
+ end
202
+
203
+ etag(@body) if current.request.request_method == 'GET'
204
+
205
+ @headers['x-lux-speed'] = "#{((Time.monotonic - @render_start)*1000).round(1)} ms"
206
+ @headers['content-type'] ||= "#{@content_type}; charset=utf-8"
207
+ @headers['content-length'] = @body.bytesize
208
+ # if "no-store" is present then HTTP_IF_NONE_MATCH is not sent from browser
209
+ end
210
+
211
+ def write_response
212
+ write_response_body
213
+ write_response_header
214
+
215
+ @status ||= 200
216
+ Lux.log " #{@status}, #{@headers['x-lux-speed']}"
217
+
218
+ if ENV['LUX_PRINT_ROUTES']
219
+ print '* Finished route print '
220
+ puts @status == 404 ? 'without a match'.red : 'with a match'.green
221
+ exit
222
+ end
223
+
224
+ [@status, @headers.to_h, [@body]]
225
+ end
226
+
227
+ def render
228
+ Lux.log "\n#{current.request.request_method.white} #{Lux.current.request.path.white}"
229
+
230
+ Lux::Config.live_require_check! if Lux.config(:auto_code_reload)
231
+
232
+ Lux::Application.new.main
233
+
234
+ write_response
235
+ end
236
+
237
+ end