picombo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/bootstrap.rb +17 -0
- data/lib/classes/bench.rb +57 -0
- data/lib/classes/cache.rb +89 -0
- data/lib/classes/cache_file.rb +80 -0
- data/lib/classes/config.rb +81 -0
- data/lib/classes/cookie.rb +27 -0
- data/lib/classes/e404.rb +5 -0
- data/lib/classes/event.rb +136 -0
- data/lib/classes/html.rb +45 -0
- data/lib/classes/input.rb +59 -0
- data/lib/classes/log.rb +31 -0
- data/lib/classes/router.rb +155 -0
- data/lib/classes/security.rb +46 -0
- data/lib/classes/session.rb +21 -0
- data/lib/classes/url.rb +15 -0
- data/lib/classes/view/xml.rb +17 -0
- data/lib/classes/view.rb +80 -0
- data/lib/config/cache.yaml +3 -0
- data/lib/config/log.yaml +10 -0
- data/lib/config/mimes.yaml +210 -0
- data/lib/config/routes.yaml +1 -0
- data/lib/controllers/error_404.rb +11 -0
- data/lib/controllers/template.rb +34 -0
- data/lib/core/core.rb +234 -0
- data/lib/hooks/datamapper.rb +13 -0
- data/lib/hooks/profiler.rb +3 -0
- data/lib/views/404.rhtml +2 -0
- data/lib/views/bench/footer.rhtml +22 -0
- metadata +82 -0
data/lib/bootstrap.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'thin'
|
2
|
+
require 'erb'
|
3
|
+
require 'yaml'
|
4
|
+
require 'dm-core'
|
5
|
+
require 'singleton'
|
6
|
+
require 'core/core'
|
7
|
+
require 'classes/config'
|
8
|
+
|
9
|
+
def run_system()
|
10
|
+
app = Rack::Builder.new do
|
11
|
+
use Rack::ShowExceptions
|
12
|
+
#use Rack::Reloader
|
13
|
+
use Rack::Static, :urls => ['/css', '/images']
|
14
|
+
use Rack::Session::Cookie
|
15
|
+
run Picombo::Core.new
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Picombo
|
2
|
+
# == Benchmarking Class
|
3
|
+
#
|
4
|
+
# The benchmark class allows you to run simple named benchmarks.
|
5
|
+
#
|
6
|
+
# === Usage
|
7
|
+
#
|
8
|
+
# To start a benchmark, use the Picombo::Bench.instance.start(name) method. Name should be unique to the benchmark being ran.
|
9
|
+
# # Start a simple benchmark
|
10
|
+
# Picombo::Bench.instance.start(:myapp_simple_mark)
|
11
|
+
#
|
12
|
+
# To stop a benchmark, use the Picombo::Bench.instance.stop(name) method.
|
13
|
+
# # Stop the previous benchmark
|
14
|
+
# Picombo::Bench.instance.stop(:myapp_simple_mark)
|
15
|
+
#
|
16
|
+
# You can retrieve the benchmark results anytime after you stop the benchmark with Picombo::Bench.instance.get(name)
|
17
|
+
# # Retrieve the previously ran benchmark
|
18
|
+
# time = Picombo::Bench.instance.get(:myapp_simple_mark)
|
19
|
+
#
|
20
|
+
# You can alter the precision of the returned benchmark time with the second parameter, it defaults to four decimal places
|
21
|
+
# # Only go to two decimal places
|
22
|
+
# time = Picombo::Bench.instance.get(:myapp_simple_mark, 2)
|
23
|
+
#
|
24
|
+
# get() will return nil if the named benchmark doesn't exist
|
25
|
+
class Bench
|
26
|
+
include Singleton
|
27
|
+
|
28
|
+
# Internal hash of benchmarks
|
29
|
+
@@marks = {}
|
30
|
+
|
31
|
+
# Starts a benchmark defined by name
|
32
|
+
def start(name)
|
33
|
+
@@marks[name] = {'start' => Time.new,
|
34
|
+
'stop' => nil}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Stops a benchmark defined by name
|
38
|
+
def stop(name)
|
39
|
+
# only stop if the benchmark exists
|
40
|
+
if (@@marks.has_key?(name))
|
41
|
+
@@marks[name]['stop'] = Time.new
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Gets a benchmark result defined by name
|
46
|
+
def get(name, precision = 4)
|
47
|
+
if ( ! @@marks.has_key?(name))
|
48
|
+
return nil
|
49
|
+
else
|
50
|
+
start = @@marks[name]['start'].to_f
|
51
|
+
stop = @@marks[name]['stop'].to_f
|
52
|
+
rounded_number = (Float((stop-start)) * (10 ** precision)).round.to_f / 10 ** precision
|
53
|
+
return rounded_number.to_s
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Picombo
|
2
|
+
# == Cache Class
|
3
|
+
#
|
4
|
+
# The cache class allows you to serialize ruby objects,
|
5
|
+
# store them in a backend system, and retreive them later.
|
6
|
+
#
|
7
|
+
# Caching can be useful for methods that take a long time to run,
|
8
|
+
# or complex database queries that cannot be made quicker.
|
9
|
+
#
|
10
|
+
# === Usage
|
11
|
+
#
|
12
|
+
# To set a cache item, use the set method:
|
13
|
+
# Picombo::Cache.new.set(:test, '<h1>It Works!</h1><p>This is a test.</p>')
|
14
|
+
# You can also pass a hash into the first parameter to set multiple items
|
15
|
+
#
|
16
|
+
# To retreive a cache item, use the get method:
|
17
|
+
# html = Picombo::Cache.new.get(:test)
|
18
|
+
# # html will contain '<h1>It Works!</h1><p>This is a test.</p>'
|
19
|
+
#
|
20
|
+
# To delete an existing cache item, use the delete method
|
21
|
+
# Picombo::Cache.new.delete(:test)
|
22
|
+
#
|
23
|
+
# === Drivers
|
24
|
+
#
|
25
|
+
# The cache class supports drivers, which will allow you to use different backend
|
26
|
+
# systems to store your cache items. Right now only a file driver is available.
|
27
|
+
# You can write your own cache drivers to behave how you want as well.
|
28
|
+
#
|
29
|
+
# By default the cache driver will use the "default" group in your config file: cache.yaml
|
30
|
+
# You can specify multiple groups as well.
|
31
|
+
#
|
32
|
+
# ==== Usage
|
33
|
+
#
|
34
|
+
# To call the cache driver with an alternate group, just pass that group name into the new method
|
35
|
+
# Picombo::Cache.new('my_other_group')
|
36
|
+
#
|
37
|
+
# To do this, you need to define the 'my_other_group' in your config file
|
38
|
+
#
|
39
|
+
# === Lifetimes
|
40
|
+
#
|
41
|
+
# The cache class supports lifetimes, which will automatically expire cache items after the
|
42
|
+
# specified time period. These are specifies in seconds from the current time. When you use the
|
43
|
+
# set method, you can set a specific lifetime with the third parameter.
|
44
|
+
# The default is located in the config file group
|
45
|
+
class Cache
|
46
|
+
|
47
|
+
@@driver = nil
|
48
|
+
@@config = nil
|
49
|
+
@@group = nil
|
50
|
+
|
51
|
+
# Set up the driver
|
52
|
+
def initialize(group = nil)
|
53
|
+
group = 'default' if group == nil
|
54
|
+
@@group = group
|
55
|
+
@@config = Picombo::Config.get('cache.'+group)
|
56
|
+
driver_name = 'Cache_'+@@config['driver'].capitalize!
|
57
|
+
@@driver = Picombo::const_get(driver_name).new(@@config)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Sets a cache item
|
61
|
+
def set(key, value = nil, lifetime = nil)
|
62
|
+
lifetime = Picombo::Config.get('cache.'+@@group+'.lifetime').to_i if lifetime == nil
|
63
|
+
unless key.is_a? Hash
|
64
|
+
key = {key => value}
|
65
|
+
end
|
66
|
+
|
67
|
+
@@driver.set(key, lifetime)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Retreives a cache item
|
71
|
+
def get(key)
|
72
|
+
@@driver.get(key.to_s, (key.is_a? Array) ? true : false)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Deletes a cache item
|
76
|
+
def delete(keys)
|
77
|
+
unless key.is_a? Array
|
78
|
+
key = [key]
|
79
|
+
end
|
80
|
+
|
81
|
+
@@driver.delete(keys)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Deletes all the cache items
|
85
|
+
def delete_all
|
86
|
+
@@driver.delete_all
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Picombo
|
2
|
+
class Cache_File
|
3
|
+
@@config = nil
|
4
|
+
|
5
|
+
def initialize(config)
|
6
|
+
@@config = config
|
7
|
+
raise "Cache directory does not exist: "+APPPATH+'cache' unless File.directory?(APPPATH+'cache/')
|
8
|
+
raise "Cache directory not writable: "+APPPATH+'cache' unless File.writable?(APPPATH+'cache/')
|
9
|
+
end
|
10
|
+
|
11
|
+
def exists(keys)
|
12
|
+
return Dir.glob(APPPATH+'cache/*~*') if keys == true
|
13
|
+
|
14
|
+
paths = []
|
15
|
+
[*keys].each do |key|
|
16
|
+
Dir.glob(APPPATH+'cache/'+key.to_s+'~*').each do |path|
|
17
|
+
paths.push(path)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
paths.uniq
|
22
|
+
end
|
23
|
+
|
24
|
+
def set(items, lifetime)
|
25
|
+
lifetime+=Time.now.to_i
|
26
|
+
|
27
|
+
success = true
|
28
|
+
|
29
|
+
items.each do |key, value|
|
30
|
+
delete(key)
|
31
|
+
|
32
|
+
File.open(APPPATH+'cache/'+key.to_s+'~'+lifetime.to_s, 'w') {|f| f.write(Marshal.dump(value)) }
|
33
|
+
end
|
34
|
+
|
35
|
+
return true
|
36
|
+
end
|
37
|
+
|
38
|
+
def get(keys, single = false)
|
39
|
+
items = []
|
40
|
+
|
41
|
+
exists(keys).each do |file|
|
42
|
+
if expired(file)
|
43
|
+
next
|
44
|
+
end
|
45
|
+
|
46
|
+
contents = ''
|
47
|
+
File.open(file, "r") do |infile|
|
48
|
+
while (line = infile.gets)
|
49
|
+
contents+=line+"\n"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
items.push(Marshal.load(contents))
|
53
|
+
end
|
54
|
+
items.uniq!
|
55
|
+
|
56
|
+
if single
|
57
|
+
return items.length > 0 ? items.shift : nil
|
58
|
+
else
|
59
|
+
return items
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete(keys)
|
64
|
+
exists(keys).each do |file|
|
65
|
+
File.unlink(file)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete_all
|
70
|
+
exists(true).each do |file|
|
71
|
+
File.unlink(file)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def expired(file)
|
76
|
+
expires = file[file.index('~') + 1, file.length]
|
77
|
+
return (expires != 0 and expires.to_i <= Time.now.to_i);
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Picombo
|
2
|
+
class Config
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
# Internal cache.
|
6
|
+
@@cache = {}
|
7
|
+
|
8
|
+
# Loads configuration files by name
|
9
|
+
def self.load(name)
|
10
|
+
# Look for this config item in the cache
|
11
|
+
if @@cache.has_key?(name)
|
12
|
+
return @@cache[name]
|
13
|
+
end
|
14
|
+
|
15
|
+
configuration, files = {}, Picombo::Core.find_file('config', name, false, 'yaml')
|
16
|
+
|
17
|
+
files.each do |file|
|
18
|
+
configuration.merge! YAML::load_file(file)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Set the internal cache
|
22
|
+
@@cache[name] = configuration
|
23
|
+
|
24
|
+
configuration
|
25
|
+
rescue Errno::ENOENT => e
|
26
|
+
# A config file couldn't be loaded...
|
27
|
+
end
|
28
|
+
|
29
|
+
# Used for dynamic config setting. Not implimented yet
|
30
|
+
def self.set(key, value)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Retrieves a config item in dot notation
|
34
|
+
def self.get(key, required = true)
|
35
|
+
# get the group name from the key
|
36
|
+
key = key.split('.')
|
37
|
+
group = key.shift
|
38
|
+
|
39
|
+
value = key_string(load(group), key.join('.'))
|
40
|
+
|
41
|
+
raise "Config key '"+key.join('.')+"' not found!!" if required && value.nil?
|
42
|
+
|
43
|
+
value
|
44
|
+
end
|
45
|
+
|
46
|
+
# Clears the internal cache for a config file(s)
|
47
|
+
def self.clear(group)
|
48
|
+
@@cache.delete(group)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Allows searching an hash by dot seperated strings
|
52
|
+
def self.key_string(hash, keys)
|
53
|
+
return false if ! hash.is_a? Hash
|
54
|
+
|
55
|
+
keys = keys.split('.')
|
56
|
+
|
57
|
+
until keys.length == 0
|
58
|
+
key = keys.shift
|
59
|
+
|
60
|
+
if hash.has_key? key
|
61
|
+
if hash[key].is_a? Hash and ! keys.empty?
|
62
|
+
hash = hash[key]
|
63
|
+
else
|
64
|
+
return hash[key]
|
65
|
+
end
|
66
|
+
else
|
67
|
+
break
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Define an each method, required for Enumerable.
|
76
|
+
#
|
77
|
+
def self.each(file)
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Picombo
|
2
|
+
class Cookie
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
# Initializes the request for cookies
|
6
|
+
def init(req)
|
7
|
+
@@req = req
|
8
|
+
end
|
9
|
+
|
10
|
+
# Retrieves a cookie item defined by key
|
11
|
+
def self.get(key, default = nil)
|
12
|
+
return @@req.cookies[key] if @@req.cookies.has_key?(key)
|
13
|
+
|
14
|
+
default
|
15
|
+
end
|
16
|
+
|
17
|
+
# Sets a cookie item defined by key to val
|
18
|
+
def self.set(key, val)
|
19
|
+
Picombo::Core.raw_response.set_cookie(key, val)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Deletes a cookie item defined by key
|
23
|
+
def self.delete(key)
|
24
|
+
Picombo::Core.raw_response.delete_cookie(key)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/classes/e404.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
module Picombo
|
2
|
+
# == Event Class
|
3
|
+
#
|
4
|
+
# Process queuing/execution class. Allows an unlimited number of callbacks
|
5
|
+
# to be added to 'events'. Events can be run multiple times, and can also
|
6
|
+
# process event-specific data. By default, Picombo has several system events.
|
7
|
+
#
|
8
|
+
# The event class is a powerful system where you can add, modify or remove Picombo functionality, and you can also create your own events to leverage easy plugablity features in your applicetion.
|
9
|
+
#
|
10
|
+
# === Examples
|
11
|
+
# It's very easy to use events to alter system behavior. This event addition will merge some parameters to every controller call:
|
12
|
+
# Picombo::Event.add('system.post_router') do |data|
|
13
|
+
# data.merge!({:params => ['test', 'test', 'test']})
|
14
|
+
# end
|
15
|
+
# This event will be called on the system.post_router event, after the router has parsed the URI
|
16
|
+
#
|
17
|
+
# Because the system.post_router is called as Picombo::Event.run('system.post_router', uri) it passes the routed uri variable as data in the method above.
|
18
|
+
#
|
19
|
+
# You can also add class methods to events:
|
20
|
+
# Picombo::Event.add('system.shutdown', 'Picombo::Foobar.new.write_access_log')
|
21
|
+
# This might process some data and then write it to an event log on the system.shutdown event right before the output is sent to the browser
|
22
|
+
|
23
|
+
class Event
|
24
|
+
private
|
25
|
+
# Events that have ran.
|
26
|
+
@@ran = []
|
27
|
+
|
28
|
+
# Event-specific data.
|
29
|
+
@@data = nil
|
30
|
+
|
31
|
+
# Callbacks.
|
32
|
+
@@events = {}
|
33
|
+
|
34
|
+
public
|
35
|
+
# Data reader.
|
36
|
+
def self.data()
|
37
|
+
@@data
|
38
|
+
end
|
39
|
+
|
40
|
+
# Data writer.
|
41
|
+
def self.data=(data)
|
42
|
+
@@data = data
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Add a callback to an event queue.
|
47
|
+
#
|
48
|
+
def self.add(name, callback = nil, &block)
|
49
|
+
# Create the event queue if it doesn't exist yet.
|
50
|
+
unless @@events.include?(name) and ! @@events.empty?
|
51
|
+
@@events[name] = []
|
52
|
+
end
|
53
|
+
|
54
|
+
# Make sure there isn't a callback and a block, two callbacks at the same time doesn't make sense.
|
55
|
+
raise ArgumentError.new('You cannot add a callback to an event queue and specify a block, at the same time.') if ! callback.nil? and block_given?
|
56
|
+
|
57
|
+
if block_given?
|
58
|
+
@@events[name].push(block)
|
59
|
+
else
|
60
|
+
# If the callback is a string/array, make sure it doesn't already exist.
|
61
|
+
if ! callback.respond_to?(:call)
|
62
|
+
return false if @@events[name].include?(callback)
|
63
|
+
end
|
64
|
+
|
65
|
+
@@events[name].push(callback)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Return all of the callbacks attached to an event, or an empty array if there are none.
|
71
|
+
#
|
72
|
+
def self.get(name)
|
73
|
+
( ! @@events.include?(name) or @@events[name].empty?) ? [] : @@events[name]
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Remove one or all of the callbacks from a given event.
|
78
|
+
#
|
79
|
+
def self.clear!(name, callback = nil)
|
80
|
+
return false unless @@events.include?(name)
|
81
|
+
|
82
|
+
if callback.nil?
|
83
|
+
@@events[name] = []
|
84
|
+
else
|
85
|
+
@@events[name].delete(callback)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Execute all of the callbacks attached to a given event.
|
91
|
+
#
|
92
|
+
def self.run(name, data = nil)
|
93
|
+
# Make sure the event queue exists and has at least one attached callback.
|
94
|
+
return false unless @@events.include?(name) and ! @@events[name].empty?
|
95
|
+
|
96
|
+
@@data = data
|
97
|
+
|
98
|
+
@@events[name].each do |callback|
|
99
|
+
if callback.is_a?(Array)
|
100
|
+
if callback[0].is_a?(String)
|
101
|
+
const_get(callback[0]).send(callback[1])
|
102
|
+
else
|
103
|
+
callback[0].send(callback[1])
|
104
|
+
end
|
105
|
+
elsif callback.is_a?(String)
|
106
|
+
eval(callback)
|
107
|
+
#callback = callback.split('.')
|
108
|
+
|
109
|
+
#if callback.length > 1
|
110
|
+
# namespace = Object
|
111
|
+
# callback[0].split("::").each do |const|
|
112
|
+
# namespace = namespace.const_get(const)
|
113
|
+
# end
|
114
|
+
|
115
|
+
# Picombo::Log.write('info', 'trying to run '+namespace.inspect+'.'+callback[1])
|
116
|
+
# namespace.send(callback[1])
|
117
|
+
#else
|
118
|
+
# Kernel.send(callback[0])
|
119
|
+
#end
|
120
|
+
elsif callback.is_a?(Proc)
|
121
|
+
callback.call(data)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
@@ran.push(name)
|
126
|
+
@@data = nil
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# Determine whether or not an event has ran yet.
|
131
|
+
#
|
132
|
+
def self.ran?(name)
|
133
|
+
@@ran.include?(name)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/lib/classes/html.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Picombo
|
2
|
+
|
3
|
+
# Helper class to generate HTML
|
4
|
+
|
5
|
+
class Html
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
# Returns a safe email address, by encoding each character in the email
|
9
|
+
def self.email(email)
|
10
|
+
safe = []
|
11
|
+
|
12
|
+
email.each_byte do |char|
|
13
|
+
safe << '&#'+char.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
safe.join
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.style(css)
|
20
|
+
unless css.is_a? Array
|
21
|
+
return '<link type="text/css" href="'+Picombo::Url.base()+css+'" rel="stylesheet" />'
|
22
|
+
end
|
23
|
+
|
24
|
+
to_return = ''
|
25
|
+
css.each do |file|
|
26
|
+
to_return+='<link type="text/css" href="'+Picombo::Url.base()+file+'" rel="stylesheet" />'+"\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
to_return
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.script(js)
|
33
|
+
unless js.is_a? Array
|
34
|
+
return '<script type="text/javascript" src="'+Url.base()+js+'"></script>'
|
35
|
+
end
|
36
|
+
|
37
|
+
to_return = ''
|
38
|
+
js.each do |file|
|
39
|
+
to_return+='<script type="text/javascript" src="'+Url.base()+file+'"></script>'+"\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
to_return
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Picombo
|
2
|
+
# Provides access and XSS filtering to GET and POST input variables
|
3
|
+
#
|
4
|
+
# == Using Input
|
5
|
+
# * To fetch get variables, simple use Picombo::Input.instance().get(get_key)
|
6
|
+
# * To fetch post variables, simple use Picombo::Input.instance().post(post)
|
7
|
+
#
|
8
|
+
# * To return the entire input hash, omit the key
|
9
|
+
# * If the key is not found, the default parameter is returned, by default nil
|
10
|
+
#
|
11
|
+
# === XSS Filtering
|
12
|
+
#
|
13
|
+
# in the main config file, there is an xss_clean option. If you set this to true,
|
14
|
+
# all GET and POST variables will be scanned and cleaned of script data. You can manually
|
15
|
+
# filter strings by using:
|
16
|
+
# Picombo::Input.instance.xss_clean(str)
|
17
|
+
class Input
|
18
|
+
include Singleton
|
19
|
+
|
20
|
+
# Sets the input request
|
21
|
+
def set_request(req)
|
22
|
+
@req = req
|
23
|
+
|
24
|
+
if Picombo::Config.get('config.xss_clean')
|
25
|
+
@req.GET().each do |key, value|
|
26
|
+
Picombo::Log.write(:debug, 'Cleaning GET key: '+key)
|
27
|
+
@req.GET()[key] = Picombo::Security.xss_clean(value, Picombo::Config.get('config.xss_clean'))
|
28
|
+
end
|
29
|
+
@req.POST().each do |key, value|
|
30
|
+
Picombo::Log.write(:debug, 'Cleaning POST key: '+key)
|
31
|
+
@req.POST()[key] = Picombo::Security.xss_clean(value, Picombo::Config.get('config.xss_clean'))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
Picombo::Log.write(:debug, 'Input Library initialized')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Retrieves a GET item by key. If the key doesn't exist, return default
|
38
|
+
# Optionaly returns the entire GET hash if key is nil
|
39
|
+
def get(key = nil, default = nil)
|
40
|
+
return @req.GET() if key.nil?
|
41
|
+
|
42
|
+
get = @req.GET()
|
43
|
+
return get[key] if get.has_key?(key)
|
44
|
+
|
45
|
+
default
|
46
|
+
end
|
47
|
+
|
48
|
+
# Retrieves a POST item by key. If the key doesn't exist, return default
|
49
|
+
# Optionaly returns the entire POST hash if key is nil
|
50
|
+
def post(key = nil, default = nil)
|
51
|
+
return @req.POST() if key.nil?
|
52
|
+
|
53
|
+
post = @req.POST()
|
54
|
+
return post[key] if post.has_key?(key)
|
55
|
+
|
56
|
+
default
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/classes/log.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Picombo
|
2
|
+
# Provides file logging capability
|
3
|
+
#
|
4
|
+
# == Log Levels
|
5
|
+
# Picombo has the following log levels
|
6
|
+
# * 0 - Disable logging (none)
|
7
|
+
# * 1 - Errors and exceptions (info)
|
8
|
+
# * 2 - Warnings (warning)
|
9
|
+
# * 3 - Notices (notice)
|
10
|
+
# * 4 - Debugging (debug)
|
11
|
+
#
|
12
|
+
# The log level is set in config/log.yaml
|
13
|
+
#
|
14
|
+
# To write a log entry, do Picombo::Log.instance().write(:info, 'This is the message!')
|
15
|
+
#
|
16
|
+
class Log
|
17
|
+
include Singleton
|
18
|
+
|
19
|
+
# Writes log entry with level +type+:: with +message+::
|
20
|
+
def self.write(type, message)
|
21
|
+
types = {:none => 0, :info => 1, :warning => 2, :notice => 3, :debug => 4}
|
22
|
+
|
23
|
+
if types[type] <= Picombo::Config.get('log.log_threshold')
|
24
|
+
t = Time.now
|
25
|
+
f = File.new(APPPATH+Picombo::Config.get('log.directory')+t.year.to_s+'-'+t.month.to_s+'-'+t.day.to_s+'.log', 'a')
|
26
|
+
f.write(t.to_s+' --- '+type.to_s+': '+message.to_s+"\n");
|
27
|
+
f.close
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|