waw 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE.rdoc +25 -0
- data/README.rdoc +32 -0
- data/bin/waw +32 -0
- data/bin/waw-profile +26 -0
- data/bin/waw-start +26 -0
- data/bin/wspec +33 -0
- data/layouts/empty/Rakefile +14 -0
- data/layouts/empty/config.ru +5 -0
- data/layouts/empty/config/commons.cfg +31 -0
- data/layouts/empty/config/devel.cfg +21 -0
- data/layouts/empty/ignore +7 -0
- data/layouts/empty/logs/dontforgetme +0 -0
- data/layouts/empty/resources/messages.rs +1 -0
- data/layouts/empty/test/wspec/site_respond.wspec +3 -0
- data/layouts/empty/test/wspec/test_all.rb +13 -0
- data/layouts/empty/waw.deploy +1 -0
- data/layouts/empty/waw.routing +6 -0
- data/layouts/static/dependencies +1 -0
- data/layouts/static/public/.wawaccess +18 -0
- data/layouts/static/public/css/style.css +0 -0
- data/layouts/static/public/images/dontforgetme +0 -0
- data/layouts/static/public/js/project.js +0 -0
- data/layouts/static/public/pages/.wawaccess +30 -0
- data/layouts/static/public/pages/404.wtpl +1 -0
- data/layouts/static/public/pages/index.wtpl +5 -0
- data/layouts/static/public/templates/.wawaccess +9 -0
- data/layouts/static/public/templates/layout.wtpl +17 -0
- data/layouts/static/test/wspec/static_pages_are_served.wspec +21 -0
- data/layouts/static/waw.routing +8 -0
- data/lib/waw.rb +99 -0
- data/lib/waw/commands/command.rb +115 -0
- data/lib/waw/commands/profile_command.rb +66 -0
- data/lib/waw/commands/start_command.rb +59 -0
- data/lib/waw/config.rb +110 -0
- data/lib/waw/controller.rb +25 -0
- data/lib/waw/controllers/action/action.rb +91 -0
- data/lib/waw/controllers/action/action_utils.rb +30 -0
- data/lib/waw/controllers/action/js_generation.rb +116 -0
- data/lib/waw/controllers/action_controller.rb +133 -0
- data/lib/waw/controllers/error/backtrace.rb +54 -0
- data/lib/waw/controllers/error_handler.rb +62 -0
- data/lib/waw/controllers/json_controller.rb +31 -0
- data/lib/waw/controllers/no_cache.rb +22 -0
- data/lib/waw/controllers/static/match.rb +80 -0
- data/lib/waw/controllers/static/waw_access.rb +235 -0
- data/lib/waw/controllers/static/waw_access_dsl.rb +48 -0
- data/lib/waw/controllers/static_controller.rb +37 -0
- data/lib/waw/default_config.cfg +14 -0
- data/lib/waw/environment_utils.rb +57 -0
- data/lib/waw/errors.rb +4 -0
- data/lib/waw/ext.rb +3 -0
- data/lib/waw/ext/core.rb +4 -0
- data/lib/waw/ext/core/hash.rb +47 -0
- data/lib/waw/ext/core/logger.rb +10 -0
- data/lib/waw/ext/core/module.rb +20 -0
- data/lib/waw/ext/core/object.rb +29 -0
- data/lib/waw/ext/rack.rb +19 -0
- data/lib/waw/ext/rack/builder.rb +43 -0
- data/lib/waw/ext/rack/delegator.rb +51 -0
- data/lib/waw/ext/rack/urlmap.rb +55 -0
- data/lib/waw/ext/wlang.rb +1 -0
- data/lib/waw/ext/wlang/hosted_language.rb +21 -0
- data/lib/waw/fullstate.rb +8 -0
- data/lib/waw/fullstate/on_class.rb +37 -0
- data/lib/waw/fullstate/on_instance.rb +27 -0
- data/lib/waw/fullstate/variable.rb +36 -0
- data/lib/waw/kern.rb +6 -0
- data/lib/waw/kern/app.rb +48 -0
- data/lib/waw/kern/empty/waw.deploy +0 -0
- data/lib/waw/kern/empty/waw.routing +1 -0
- data/lib/waw/kern/freezed_state.rb +32 -0
- data/lib/waw/kern/hooks.rb +53 -0
- data/lib/waw/kern/lifecycle.rb +248 -0
- data/lib/waw/kern/living_state.rb +87 -0
- data/lib/waw/kern/utils.rb +27 -0
- data/lib/waw/resource_collection.rb +100 -0
- data/lib/waw/restart.rb +32 -0
- data/lib/waw/routing.rb +43 -0
- data/lib/waw/routing/action_routing.rb +78 -0
- data/lib/waw/routing/dsl.rb +45 -0
- data/lib/waw/routing/feedback.rb +23 -0
- data/lib/waw/routing/form_validation_feedback.rb +36 -0
- data/lib/waw/routing/javascript.rb +17 -0
- data/lib/waw/routing/redirect.rb +26 -0
- data/lib/waw/routing/refresh.rb +17 -0
- data/lib/waw/routing/routing_rule.rb +16 -0
- data/lib/waw/scope_utils.rb +69 -0
- data/lib/waw/session.rb +51 -0
- data/lib/waw/testing.rb +1 -0
- data/lib/waw/tools/mail.rb +4 -0
- data/lib/waw/tools/mail/mail.rb +119 -0
- data/lib/waw/tools/mail/mail_agent.rb +123 -0
- data/lib/waw/tools/mail/mailbox.rb +62 -0
- data/lib/waw/tools/mail/template.rb +38 -0
- data/lib/waw/utils/dsl_helper.rb +116 -0
- data/lib/waw/validation.rb +175 -0
- data/lib/waw/validation/and_validator.rb +27 -0
- data/lib/waw/validation/array_validations.rb +38 -0
- data/lib/waw/validation/boolean_validator.rb +32 -0
- data/lib/waw/validation/comparison_validations.rb +45 -0
- data/lib/waw/validation/date_validator.rb +31 -0
- data/lib/waw/validation/default_validator.rb +30 -0
- data/lib/waw/validation/dsl_ruby_extensions.rb +11 -0
- data/lib/waw/validation/errors.rb +17 -0
- data/lib/waw/validation/ext.rb +3 -0
- data/lib/waw/validation/file_validator.rb +30 -0
- data/lib/waw/validation/float_validator.rb +19 -0
- data/lib/waw/validation/helpers.rb +67 -0
- data/lib/waw/validation/integer_validator.rb +16 -0
- data/lib/waw/validation/isin_validator.rb +24 -0
- data/lib/waw/validation/mandatory_validator.rb +17 -0
- data/lib/waw/validation/missing_validator.rb +17 -0
- data/lib/waw/validation/not_validator.rb +20 -0
- data/lib/waw/validation/or_validator.rb +34 -0
- data/lib/waw/validation/regexp_validator.rb +29 -0
- data/lib/waw/validation/same_validator.rb +16 -0
- data/lib/waw/validation/signature.rb +157 -0
- data/lib/waw/validation/size_validations.rb +44 -0
- data/lib/waw/validation/string_validator.rb +15 -0
- data/lib/waw/validation/validator.rb +48 -0
- data/lib/waw/wawgen.rb +2 -0
- data/lib/waw/wawgen/create.rb +166 -0
- data/lib/waw/wawgen/project.rb +25 -0
- data/lib/waw/wspec.rb +5 -0
- data/lib/waw/wspec/browser.rb +240 -0
- data/lib/waw/wspec/dsl.rb +201 -0
- data/lib/waw/wspec/html_analysis.rb +136 -0
- data/lib/waw/wspec/html_analysis/tag.rb +56 -0
- data/lib/waw/wspec/runner.rb +70 -0
- data/lib/waw/wspec/scenario.rb +35 -0
- data/lib/waw/wspec/suite.rb +54 -0
- data/test/bricks/error_handler/config/test.cfg +2 -0
- data/test/bricks/error_handler/logs/webapp.log +1411 -0
- data/test/bricks/error_handler/test/error_handler.wspec +16 -0
- data/test/bricks/error_handler/waw.deploy +1 -0
- data/test/bricks/error_handler/waw.routing +27 -0
- data/test/integration/waw_create_integration_test.rb +24 -0
- data/test/spec/assumptions_spec.rb +30 -0
- data/test/spec/controllers/action_controller_spec.rb +14 -0
- data/test/spec/controllers/static/waw_access_spec.rb +112 -0
- data/test/spec/environment_utils_spec.rb +15 -0
- data/test/spec/ext/core/hash_spec.rb +58 -0
- data/test/spec/fixtures.rb +41 -0
- data/test/spec/fixtures/action/config/default.cfg +2 -0
- data/test/spec/fixtures/action/lib/action_controller_test.rb +12 -0
- data/test/spec/fixtures/action/waw.deploy +1 -0
- data/test/spec/fixtures/action/waw.routing +6 -0
- data/test/spec/fixtures/empty/waw.deploy +0 -0
- data/test/spec/fixtures/empty/waw.routing +0 -0
- data/test/spec/fullstate/on_class_spec.rb +59 -0
- data/test/spec/fullstate/on_instance_spec.rb +59 -0
- data/test/spec/fullstate/session_spec.rb +43 -0
- data/test/spec/fullstate/variable_spec.rb +55 -0
- data/test/spec/resource_collection_spec.rb +50 -0
- data/test/spec/test_all.rb +9 -0
- data/test/spec/tools/mail/mail_agent_spec.rb +116 -0
- data/test/spec/tools/mail/mail_spec.rb +56 -0
- data/test/spec/tools/mail/mailbox_spec.rb +57 -0
- data/test/spec/tools/mail/template_spec.rb +47 -0
- data/test/spec/validation/array_validation_spec.rb +63 -0
- data/test/spec/validation/array_validator_spec.rb +17 -0
- data/test/spec/validation/date_validation_spec.rb +35 -0
- data/test/spec/validation/default_validation_spec.rb +37 -0
- data/test/spec/validation/disjuctive_validation_spec.rb +33 -0
- data/test/spec/validation/errors_spec.rb +37 -0
- data/test/spec/validation/file_validator_spec.rb +34 -0
- data/test/spec/validation/mail_validation_spec.rb +51 -0
- data/test/spec/validation/missing_validation_spec.rb +43 -0
- data/test/spec/validation/same_validation_spec.rb +24 -0
- data/test/spec/validation/signature_intuition_spec.rb +37 -0
- data/test/spec/validation/signature_spec.rb +164 -0
- data/test/spec/validation/validation_spec.rb +28 -0
- data/test/spec/wspec/html_analysis/tag_spec.rb +38 -0
- data/test/spec/wspec/html_analysis_spec.rb +170 -0
- data/test/unit/test_all.rb +8 -0
- data/test/unit/waw/app_test.rb +126 -0
- data/test/unit/waw/app_test/config/commons.cfg +2 -0
- data/test/unit/waw/app_test/config/devel.cfg +1 -0
- data/test/unit/waw/config_test.rb +54 -0
- data/test/unit/waw/controllers/action_controller_test.rb +76 -0
- data/test/unit/waw/controllers/action_test.rb +35 -0
- data/test/unit/waw/controllers/example_action_controller_test.rb +24 -0
- data/test/unit/waw/controllers/multiple_action_controller_test.rb +78 -0
- data/test/unit/waw/controllers/static/example/css/example.css +1 -0
- data/test/unit/waw/controllers/static/example/index.html +1 -0
- data/test/unit/waw/controllers/static/example/js/example.js +1 -0
- data/test/unit/waw/controllers/static/example/pages/hello.wtpl +1 -0
- data/test/unit/waw/controllers/static/waw_access_test.rb +76 -0
- data/test/unit/waw/ext/rack_test.rb +74 -0
- data/test/unit/waw/resource_collection_test.rb +49 -0
- data/test/unit/waw/resources.txt +4 -0
- data/test/unit/waw/routing/routing_test.rb +26 -0
- data/test/unit/waw/utils/dsl_helper_test.rb +79 -0
- data/test/unit/waw/utils/dsl_helper_test_extensions1.rb +4 -0
- data/test/unit/waw/validation/signature_test.rb +193 -0
- data/test/unit/waw/validation_test.rb +319 -0
- data/test/unit/waw/wspec/html_analysis_test.html +81 -0
- data/test/unit/waw/wspec/html_analysis_test.rb +26 -0
- metadata +272 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
module Waw
|
2
|
+
class StaticController < ::Waw::Controller
|
3
|
+
class WawAccess
|
4
|
+
class Match
|
5
|
+
include Waw::ScopeUtils
|
6
|
+
|
7
|
+
# Served file
|
8
|
+
attr_reader :served_file
|
9
|
+
|
10
|
+
# Creates a match instance with a block a arguments
|
11
|
+
# to pass
|
12
|
+
def initialize(wawaccess, served_file, block, *args)
|
13
|
+
@wawaccess, @served_file = wawaccess, served_file
|
14
|
+
@block, @args = block, args
|
15
|
+
end
|
16
|
+
|
17
|
+
# Executes on a wawaccess instance
|
18
|
+
def __execute
|
19
|
+
instance_exec *@args, &@block
|
20
|
+
end
|
21
|
+
|
22
|
+
# Delegated to the wawaccess that created me
|
23
|
+
def root; @wawaccess.root; end
|
24
|
+
def folder; @wawaccess.folder; end
|
25
|
+
|
26
|
+
################################################### Callbacks proposed to .wawaccess rules
|
27
|
+
|
28
|
+
# Deny access to the file
|
29
|
+
def deny
|
30
|
+
body = "Forbidden\n"
|
31
|
+
[403, {"Content-Type" => "text/plain",
|
32
|
+
"Content-Length" => body.size.to_s,
|
33
|
+
"X-Cascade" => "pass"},
|
34
|
+
[body]]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Serves a static file from a real path
|
38
|
+
def static
|
39
|
+
if rack_env
|
40
|
+
rack_env["PATH_INFO"] = served_file
|
41
|
+
@wawaccess.file_server.call(rack_env)
|
42
|
+
else
|
43
|
+
path = File.join(root.folder, served_file)
|
44
|
+
[200, {'Content-Type' => 'text/plain'}, [File.read(path)]]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Run a rewriting
|
49
|
+
def apply(path, result_override = nil, headers_override = {})
|
50
|
+
result = root.do_path_serve(path)
|
51
|
+
[result_override || result[0],
|
52
|
+
result[1].merge(headers_override),
|
53
|
+
result[2]]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Builds a default wlang contect
|
57
|
+
def default_wlang_context
|
58
|
+
context = {"css_files" => root.find_files('css'),
|
59
|
+
"js_files" => root.find_files('js'),
|
60
|
+
"served_file" => served_file}
|
61
|
+
context
|
62
|
+
end
|
63
|
+
|
64
|
+
# Instantiates wlang on the current file, with a given context
|
65
|
+
def wlang(template = nil, context = {}, result_override = nil, headers_override = {})
|
66
|
+
if template.nil?
|
67
|
+
template = File.join(root.folder, served_file)
|
68
|
+
else
|
69
|
+
template = File.join(folder, template)
|
70
|
+
end
|
71
|
+
context = default_wlang_context.merge(context || {})
|
72
|
+
[result_override || 200,
|
73
|
+
{'Content-Type' => 'text/html'}.merge(headers_override || {}),
|
74
|
+
[::WLang.file_instantiate(template, context.unsymbolize_keys).to_s]]
|
75
|
+
end
|
76
|
+
|
77
|
+
end # class Match
|
78
|
+
end # class WawAccess
|
79
|
+
end # class StaticController
|
80
|
+
end # module Waw
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'waw/controllers/static/match'
|
3
|
+
module Waw
|
4
|
+
class StaticController < ::Waw::Controller
|
5
|
+
# Waw version of .htaccess files
|
6
|
+
class WawAccess
|
7
|
+
|
8
|
+
# The folder which is served
|
9
|
+
attr_accessor :folder
|
10
|
+
|
11
|
+
# Strategy :allow_all or :deny_all
|
12
|
+
attr_accessor :strategy
|
13
|
+
|
14
|
+
# Does it inherits its parent configuration?
|
15
|
+
attr_accessor :inherits
|
16
|
+
|
17
|
+
# The parent wawaccess file
|
18
|
+
attr_accessor :parent
|
19
|
+
|
20
|
+
# Fake accessor that go to the top of the hierarchy
|
21
|
+
def file_server
|
22
|
+
@file_server || (parent && parent.file_server)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Creates a default WawAccess file
|
26
|
+
def initialize(parent = nil, folder = nil, read_file = nil)
|
27
|
+
@parent = parent
|
28
|
+
@folder = folder
|
29
|
+
@strategy = :deny_all
|
30
|
+
@inherits = true
|
31
|
+
@serve = []
|
32
|
+
@children = {}
|
33
|
+
@file_server = ::Rack::File.new(folder) if parent.nil?
|
34
|
+
dsl_merge_file(read_file) if read_file
|
35
|
+
end
|
36
|
+
|
37
|
+
################################################### About installation through DSL
|
38
|
+
|
39
|
+
# Returns a wawaccess tree for a given folder
|
40
|
+
def self.load_hierarchy(root_folder, parent = nil)
|
41
|
+
raise ArgumentError, "Invalid folder #{root_folder}" unless (root_folder and File.directory?(root_folder))
|
42
|
+
|
43
|
+
# Locate and load the .wawaccess file or provide a default one
|
44
|
+
wawaccess_file = File.join(root_folder, '.wawaccess')
|
45
|
+
if File.exists?(wawaccess_file)
|
46
|
+
wawaccess = WawAccess.new(parent, root_folder, wawaccess_file)
|
47
|
+
else
|
48
|
+
wawaccess = WawAccess.new(parent, root_folder)
|
49
|
+
wawaccess.strategy = :deny_all
|
50
|
+
wawaccess.inherits = true
|
51
|
+
end
|
52
|
+
|
53
|
+
# Install its children
|
54
|
+
Dir.new(root_folder).each do |file|
|
55
|
+
next if ['.', '..'].include?(file)
|
56
|
+
child_folder = File.join(root_folder, file)
|
57
|
+
next unless File.directory?(child_folder)
|
58
|
+
|
59
|
+
# Load the child and save it
|
60
|
+
wawaccess.add_child(file, WawAccess.load_hierarchy(child_folder, wawaccess))
|
61
|
+
end
|
62
|
+
wawaccess
|
63
|
+
end
|
64
|
+
|
65
|
+
################################################### About installation through DSL
|
66
|
+
|
67
|
+
def recognized_pattern?(pattern)
|
68
|
+
[FalseClass, TrueClass, String,
|
69
|
+
Regexp, Waw::Validation::Validator].any?{|c| c===pattern}
|
70
|
+
end
|
71
|
+
|
72
|
+
# Adds a child in the hierarchy
|
73
|
+
def add_child(folder, wawaccess)
|
74
|
+
@children[folder] = wawaccess
|
75
|
+
end
|
76
|
+
|
77
|
+
# Installs some pattern services
|
78
|
+
def add_serve(patterns, &block)
|
79
|
+
raise ArgumentError, "WawAccess.add_serve expects a block" unless block
|
80
|
+
patterns.each do |pattern|
|
81
|
+
raise WawError, "Invalid serving pattern #{pattern} (#{pattern.class})"\
|
82
|
+
unless recognized_pattern?(pattern)
|
83
|
+
@serve << [pattern, block]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Merges a DSL string inside this waw access
|
88
|
+
def dsl_merge(dsl_str, read_file=nil)
|
89
|
+
begin
|
90
|
+
dsl = WawAccess::DSL.new(self)
|
91
|
+
dsl.instance_eval(dsl_str)
|
92
|
+
rescue WawError => ex
|
93
|
+
raise WawError, "Corrupted .wawaccess file #{read_file}: #{ex.message}", ex.backtrace
|
94
|
+
rescue Exception => ex
|
95
|
+
raise WawError, "Corrupted .wawaccess file #{read_file}: #{ex.message}", ex.backtrace
|
96
|
+
end
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
# Merge with a .wawaccess file
|
101
|
+
def dsl_merge_file(read_file)
|
102
|
+
raise WawError, "Missing .wawaccess file #{readfile}" unless File.file?(read_file)
|
103
|
+
dsl_merge(File.read(read_file), read_file)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
################################################### Utilites about paths
|
108
|
+
|
109
|
+
# Returns the real path of a file
|
110
|
+
def realpath(file)
|
111
|
+
File.expand_path(File.join(folder, file))
|
112
|
+
end
|
113
|
+
|
114
|
+
# Locates the file that would be matched by a given normalized
|
115
|
+
# url.
|
116
|
+
def matching_file(path)
|
117
|
+
File.join(root.folder, path)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Relativize a path against a given folder
|
121
|
+
def relativize(file, folder = folder)
|
122
|
+
file, folder = File.expand_path(file), File.expand_path(folder)
|
123
|
+
file[(folder.length+1)..-1]
|
124
|
+
end
|
125
|
+
|
126
|
+
# Helper to locate css and js files
|
127
|
+
def find_files(pattern)
|
128
|
+
Dir[File.join(folder, pattern, "*.#{pattern}")].sort{|f1, f2|
|
129
|
+
File.basename(f1) <=> File.basename(f2)
|
130
|
+
}.collect{|f|
|
131
|
+
File.join(pattern, File.basename(f))
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
################################################### Utilities about the hierarchy
|
136
|
+
|
137
|
+
# Returns an identifier for this wawaccess
|
138
|
+
def identifier(append = true)
|
139
|
+
if parent
|
140
|
+
parent.identifier(false) + (append ? "#{File.basename(@folder)}/.wawaccess" : File.basename(@folder))
|
141
|
+
else
|
142
|
+
(append ? ".wawaccess" : "")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the root waw access in the hierarchy
|
147
|
+
def root
|
148
|
+
@root ||= (parent ? parent.root : self)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Finds the wawaccess instance for a given url
|
152
|
+
def find_wawaccess_for(url, url_array = url.split('/').reject{|k| k.empty?})
|
153
|
+
if url_array.empty?
|
154
|
+
self
|
155
|
+
else
|
156
|
+
if @children.has_key?(nextfolder = url_array.shift)
|
157
|
+
@children[nextfolder].find_wawaccess_for(url, url_array)
|
158
|
+
else
|
159
|
+
self
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
################################################### .waw access rules application!
|
165
|
+
|
166
|
+
# Finds the matching block inside this .wawaccess handler
|
167
|
+
def find_match(path)
|
168
|
+
@serve.each do |pattern, block|
|
169
|
+
case pattern
|
170
|
+
when FalseClass
|
171
|
+
when TrueClass
|
172
|
+
return Match.new(self, path, block)
|
173
|
+
when String
|
174
|
+
if pattern=='*'
|
175
|
+
return Match.new(self, path, block)
|
176
|
+
elsif /^\*?\.[a-z]+$/ =~ pattern
|
177
|
+
return Match.new(self, path, block) if File.extname(realpath(path))==pattern
|
178
|
+
else
|
179
|
+
return Match.new(self, path, block) if File.basename(realpath(path))==pattern
|
180
|
+
end
|
181
|
+
when Regexp
|
182
|
+
if matchdata = pattern.match(path)
|
183
|
+
return Match.new(self, path, block, *matchdata.to_a)
|
184
|
+
end
|
185
|
+
when Waw::Validation::Validator
|
186
|
+
if pattern.validate(matching_file(path))
|
187
|
+
return Match.new(self, path, block)
|
188
|
+
end
|
189
|
+
else
|
190
|
+
raise WawError, "Unrecognized wawaccess pattern #{pattern}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
nil
|
194
|
+
end
|
195
|
+
|
196
|
+
# Applies the rules defined here or delegate to the parent if allowed
|
197
|
+
def apply_rules(path)
|
198
|
+
if match = find_match(path)
|
199
|
+
match.__execute
|
200
|
+
elsif (parent and inherits)
|
201
|
+
parent.apply_rules(path)
|
202
|
+
else
|
203
|
+
body = "File not found: #{path}\n"
|
204
|
+
[404, {"Content-Type" => "text/plain",
|
205
|
+
"Content-Length" => body.size.to_s,
|
206
|
+
"X-Cascade" => "pass"},
|
207
|
+
[body]]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
################################################### To be called on the tree root only!
|
212
|
+
|
213
|
+
# Normalizes a requested path, removing any .html, .htm suffix
|
214
|
+
def normalize_req_path(req_path)
|
215
|
+
# 1) Decode the req_path with URI::decode
|
216
|
+
req_path = URI::decode(req_path)
|
217
|
+
# 2) Strip first
|
218
|
+
req_path = req_path.strip
|
219
|
+
# 3) Remove first slash
|
220
|
+
req_path = req_path[1..-1] if req_path[0,1]=='/'
|
221
|
+
# 4) Remove last slash
|
222
|
+
req_path = req_path[0..-2] if req_path[req_path.length-1,1]=='/'
|
223
|
+
req_path
|
224
|
+
end
|
225
|
+
|
226
|
+
# Serves a path from a root waw access in the hierarchy
|
227
|
+
def do_path_serve(path)
|
228
|
+
path = normalize_req_path(path)
|
229
|
+
waw_access = (find_wawaccess_for(path) || self)
|
230
|
+
waw_access.apply_rules(path)
|
231
|
+
end
|
232
|
+
|
233
|
+
end # class WawAccess
|
234
|
+
end # class StaticController
|
235
|
+
end # module Waw
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Waw
|
2
|
+
class StaticController < ::Waw::Controller
|
3
|
+
class WawAccess
|
4
|
+
# Domain specific language for .wawaccess language
|
5
|
+
class DSL
|
6
|
+
include ::Waw::Validation
|
7
|
+
|
8
|
+
# Creates a new DSL instance
|
9
|
+
def initialize(wawaccess)
|
10
|
+
raise ArgumentError, "wawaccess cannot be nil" unless WawAccess===wawaccess
|
11
|
+
@wawaccess = wawaccess
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a validator that matches the root of the wawaccess tree
|
15
|
+
def root
|
16
|
+
Waw::Validation.validator{|served_file| File.expand_path(served_file) == File.expand_path(@wawaccess.root.folder)}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Starts a wawaccess file
|
20
|
+
def wawaccess(&block)
|
21
|
+
raise WawError, "#{@wawaccess.identifier}: missing block in wawaccess call" unless block
|
22
|
+
self.instance_eval(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Installs the default strategy
|
26
|
+
def strategy(which = :unknown)
|
27
|
+
raise WawError, "#{@wawaccess.identifier}: unrecognized wawaccess strategy #{which}" unless [:deny_all, :allow_all].include?(which)
|
28
|
+
@wawaccess.strategy = which
|
29
|
+
end
|
30
|
+
|
31
|
+
# Installs the inherits strategy
|
32
|
+
def inherits(which = "unknown")
|
33
|
+
raise WawError, "#{@wawaccess.identifier}: unrecognized wawaccess inherits #{which}" unless [true, false].include?(which)
|
34
|
+
@wawaccess.inherits = which
|
35
|
+
end
|
36
|
+
|
37
|
+
# Serve some patterns
|
38
|
+
def match(*patterns, &block)
|
39
|
+
patterns = patterns.compact
|
40
|
+
raise WawError, "#{@wawaccess.identifier}: missing patterns in wawaccess.match call" if patterns.empty?
|
41
|
+
raise WawError, "#{@wawaccess.identifier}: missing block in wawaccess.match call" if block.nil?
|
42
|
+
@wawaccess.add_serve(patterns, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end # class WawAccess
|
47
|
+
end # class StaticController
|
48
|
+
end # module Waw
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'waw/controllers/static/waw_access'
|
2
|
+
require 'waw/controllers/static/waw_access_dsl'
|
3
|
+
module Waw
|
4
|
+
#
|
5
|
+
# A waw service that serves public pages expressed in wlang wtpl format
|
6
|
+
#
|
7
|
+
class StaticController < ::Waw::Controller
|
8
|
+
|
9
|
+
##############################################################################################
|
10
|
+
### About service creation and configuration
|
11
|
+
##############################################################################################
|
12
|
+
|
13
|
+
# Default options of this service
|
14
|
+
DEFAULT_OPTIONS = {:public => 'public'}
|
15
|
+
|
16
|
+
# Creates a service instance
|
17
|
+
def initialize(opts = {})
|
18
|
+
@options = DEFAULT_OPTIONS.merge(opts)
|
19
|
+
@wawaccess = ::Waw::StaticController::WawAccess.load_hierarchy(File.join(root_folder, public_folder))
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the template folder
|
23
|
+
def public_folder
|
24
|
+
@options[:public] || @options[:root]
|
25
|
+
end
|
26
|
+
|
27
|
+
##############################################################################################
|
28
|
+
### Main service execution
|
29
|
+
##############################################################################################
|
30
|
+
|
31
|
+
# Executes the service
|
32
|
+
def execute(env, req, res)
|
33
|
+
@wawaccess.do_path_serve(env['PATH_INFO'])
|
34
|
+
end
|
35
|
+
|
36
|
+
end # class Controller
|
37
|
+
end # module Waw
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Logger configuration
|
2
|
+
log_dir 'logs'
|
3
|
+
log_file 'webapp.log'
|
4
|
+
log_frequency 'weekly'
|
5
|
+
log_level Logger::DEBUG
|
6
|
+
|
7
|
+
# Web configuration
|
8
|
+
web_domain '127.0.0.1'
|
9
|
+
web_port 9292
|
10
|
+
web_base 'http://127.0.0.1:9292/'
|
11
|
+
|
12
|
+
# About Rack
|
13
|
+
rack_session true
|
14
|
+
rack_session_expire 60 * 60 * 24
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Waw
|
2
|
+
# Provides environment utilities to get the current Rack environment,
|
3
|
+
# session and so on. Some of these utilities make the assumption that
|
4
|
+
# a session is installed in some Rack standard way (through Rack::Session::Pool)
|
5
|
+
# for example.
|
6
|
+
module EnvironmentUtils
|
7
|
+
include Waw::ScopeUtils
|
8
|
+
|
9
|
+
DEPRECATED_MSG = <<-EOF
|
10
|
+
Method ${method_name} is deprecated and will be removed in version 0.3.
|
11
|
+
Please include Waw::ScopeUtils module instead.
|
12
|
+
EOF
|
13
|
+
|
14
|
+
# Returns the current Rack env instance
|
15
|
+
deprecated DEPRECATED_MSG
|
16
|
+
def env
|
17
|
+
rack_env
|
18
|
+
end
|
19
|
+
|
20
|
+
# Checks if a session has a given key
|
21
|
+
deprecated <<-EOF
|
22
|
+
Method ${method_name} is deprecated and will be removed in version 0.3.
|
23
|
+
Please include Waw::ScopeUtils module and use session.has_key? instead.
|
24
|
+
EOF
|
25
|
+
def session_has_key?(key)
|
26
|
+
session.has_key?(key)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Sets a pair inside the session. Returns the value.
|
30
|
+
deprecated <<-EOF
|
31
|
+
Method ${method_name} is deprecated and will be removed in version 0.3.
|
32
|
+
Please include Waw::ScopeUtils module and use session.set instead.
|
33
|
+
EOF
|
34
|
+
def session_set(key, value)
|
35
|
+
session[key] = value
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sets a pair inside the session
|
39
|
+
deprecated <<-EOF
|
40
|
+
Method ${method_name} is deprecated and will be removed in version 0.3.
|
41
|
+
Please include Waw::ScopeUtils module and use session.unset instead.
|
42
|
+
EOF
|
43
|
+
def session_unset(key)
|
44
|
+
session.delete(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get a value from the current session
|
48
|
+
deprecated <<-EOF
|
49
|
+
Method ${method_name} is deprecated and will be removed in version 0.3.
|
50
|
+
Please include Waw::ScopeUtils module and use session.get instead.
|
51
|
+
EOF
|
52
|
+
def session_get(key)
|
53
|
+
session[key]
|
54
|
+
end
|
55
|
+
|
56
|
+
end # module EnvironmentUtils
|
57
|
+
end # module Waw
|