picombo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|