halcyon 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -27,7 +27,8 @@ project = {
27
27
  :dependencies => {
28
28
  'json_pure' => '>=1.1.2',
29
29
  'rack' => '>=0.3.0',
30
- 'merb' => '>=0.9.2',
30
+ 'extlib' => '>=0.9.4',
31
+ 'merb' => '>=0.9.4',
31
32
  'rubigen' => '>=1.2.4'
32
33
  },
33
34
  :requirements => 'install the json gem to get faster JSON parsing',
@@ -1,6 +1,6 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
2
 
3
- %w(rubygems rack merb-core/core_ext merb-core/vendor/facets merb-core/dispatch/router json uri).each {|dep|require dep}
3
+ %w(rubygems rack extlib merb-core/vendor/facets merb-core/dispatch/router json uri).each {|dep|require dep}
4
4
 
5
5
  # Provides global values, like the root of the current application directory,
6
6
  # the current logger, the application name, and the framework version.
@@ -11,11 +11,11 @@ $:.unshift File.dirname(__FILE__)
11
11
  # Halcyon.config #=> {:allow_from => :all, :logging => {...}, ...}
12
12
  # Halcyon.paths #=> {:config => Halcyon.root/'config', ...}
13
13
  # Halcyon.logger #=> #<Logger>
14
- # Halcyon.version #=> "0.5.1"
14
+ # Halcyon.version #=> "0.5.2"
15
15
  #
16
16
  module Halcyon
17
17
 
18
- VERSION = [0,5,1] unless defined?(Halcyon::VERSION)
18
+ VERSION = [0,5,2] unless defined?(Halcyon::VERSION)
19
19
 
20
20
  autoload :Application, 'halcyon/application'
21
21
  autoload :Client, 'halcyon/client'
@@ -165,7 +165,7 @@ module Halcyon
165
165
  # default to the Application controller
166
166
  ::Application.new(env)
167
167
  when String
168
- # pulled from URL, so camelize (from merb/core_ext) and symbolize first
168
+ # pulled from URL, so camelize (from extlib) and symbolize first
169
169
  begin
170
170
  Object.const_get(route[:controller].camel_case.to_sym).new(env)
171
171
  rescue NameError => e
@@ -289,8 +289,8 @@ module Halcyon
289
289
  # Run configuration files (when available)
290
290
  # These are unique in that they are Ruby files that we require so we
291
291
  # can get rid of YAML config files and use Ruby configuration files.
292
- Dir.glob(Halcyon.paths[:config]/'*.rb').each do |config_file|
293
- require config_file
292
+ Dir.glob(%w(init config environment).map{|file| Halcyon.paths[:config]/file+'.rb' }).each do |config_file|
293
+ require config_file if File.exist?(config_file)
294
294
  end
295
295
 
296
296
  # Yield to the block to handle boot configuration (and other tasks).
@@ -307,13 +307,13 @@ module Halcyon
307
307
  Halcyon.logger = Halcyon::Logger.setup(Halcyon.config[:logging])
308
308
 
309
309
  # Run initializers
310
- Dir.glob(%w(requires hooks routes *).map{|init|Halcyon.paths[:init]/init+'.rb'}).each do |initializer|
310
+ Dir.glob(%w(requires hooks routes *).map{|init|Halcyon.paths[:init]/init+'.rb'}).uniq.each do |initializer|
311
311
  self.logger.debug "Init: #{File.basename(initializer).chomp('.rb').camel_case}" if
312
312
  require initializer.chomp('.rb')
313
313
  end
314
314
 
315
315
  # Setup autoloads for Controllers found in Halcyon.root/'app' (by default)
316
- Dir.glob([Halcyon.paths[:controller]/'application.rb', Halcyon.paths[:controller]/'*.rb']).each do |controller|
316
+ Dir.glob([Halcyon.paths[:controller]/'application.rb', Halcyon.paths[:controller]/'*.rb']).uniq.each do |controller|
317
317
  self.logger.debug "Load: #{File.basename(controller).chomp('.rb').camel_case} Controller" if
318
318
  require controller.chomp('.rb')
319
319
  end
@@ -22,7 +22,7 @@ module Halcyon
22
22
  def startup &hook
23
23
  Halcyon.hooks[:startup] << hook
24
24
  end
25
-
25
+
26
26
  # Sets the shutdown hook to the proc.
27
27
  #
28
28
  # Close any resources opened in the +startup+ hook.
@@ -1,4 +1,4 @@
1
- %w(rubygems merb-core/core_ext merb-core/dispatch/router uri).each {|dep|require dep}
1
+ %w(rubygems extlib merb-core/dispatch/router uri).each {|dep|require dep}
2
2
 
3
3
  module Halcyon
4
4
  class Application
@@ -174,7 +174,8 @@ module Halcyon
174
174
  res = Net::HTTP.start(self.uri.host, self.uri.port) {|http|http.request(req)}
175
175
 
176
176
  # parse response
177
- body = JSON.parse(res.body).to_mash
177
+ # unescape just in case any problematic characters were POSTed through
178
+ body = JSON.parse(Rack::Utils.unescape(res.body)).to_mash
178
179
 
179
180
  # handle non-successes
180
181
  if self.options[:raise_exceptions] && !res.kind_of?(Net::HTTPSuccess)
@@ -193,8 +194,26 @@ module Halcyon
193
194
  def format_body(data)
194
195
  data = {:body => data} unless data.is_a? Hash
195
196
  data.to_mash
196
- # uses the Merb Hash#to_params method defined in merb/core_ext.
197
- data.to_params
197
+ # Hash.to_params (from extlib) doesn't escape keys/values
198
+ build_query(data)
199
+ end
200
+
201
+ # Ported over from Rack::Utils.build_query which has not been released yet
202
+ # as of Halcyon 0.5.2's release.
203
+ #
204
+ # The key difference from this and extlib's Hash.to_params is
205
+ # that the keys and values are escaped (which cause many problems).
206
+ #
207
+ # TODO: Remove when Rack is released with Rack::Utils.build_query included.
208
+ #
209
+ def build_query(params)
210
+ params.map { |k, v|
211
+ if v.class == Array
212
+ build_query(v.map { |x| [k, x] })
213
+ else
214
+ Rack::Utils.escape(k) + "=" + Rack::Utils.escape(v)
215
+ end
216
+ }.join("&")
198
217
  end
199
218
 
200
219
  end
@@ -206,7 +206,7 @@ module Halcyon
206
206
  :level => 'debug'
207
207
  },
208
208
  :paths => Paths.new,
209
- :hooks => Hash.new([])
209
+ :hooks => {:startup => [], :shutdown => []}
210
210
  }
211
211
  case (env || :development)
212
212
  when :development
@@ -43,20 +43,27 @@ module Halcyon
43
43
  # # parsing errors will happen if you try to use the wrong marshal
44
44
  # # load method
45
45
  #
46
+ # Returns a Mash if the contents parse to a Hash.
47
+ #
46
48
  def to_hash(from = :from_yaml)
47
- case from
49
+ contents = case from
48
50
  when :from_yaml
49
51
  require 'yaml'
50
52
  YAML.load(self.content)
51
53
  when :from_json
52
54
  JSON.parse(self.content)
53
55
  end
56
+ # return mash instead of hash if result is a hash
57
+ if contents.is_a?(Hash)
58
+ contents = Mash.new contents
59
+ end
60
+ contents
54
61
  end
55
62
 
56
63
  # Filters the contents through ERB.
57
64
  #
58
65
  def filter(content, filter_through_erb)
59
- content = ERB.new(content).result if filter_through_erb
66
+ content = ERB.new(content).result if filter_through_erb
60
67
  content
61
68
  end
62
69
 
@@ -1,3 +1,5 @@
1
+ require 'logger'
2
+
1
3
  module Halcyon
2
4
  module Logging
3
5
 
@@ -22,7 +24,7 @@ module Halcyon
22
24
  # Log4r => specifies Log4r
23
25
  def set(logger = 'Logger')
24
26
  Halcyon.send(:remove_const, :Logger) if Halcyon.const_defined? :Logger
25
- Halcyon.const_set :Logger, Halcyon::Logging.const_get(logger)
27
+ Halcyon.const_set :Logger, Halcyon::Logging.const_get(logger.to_sym)
26
28
  end
27
29
 
28
30
  end
@@ -16,11 +16,13 @@ module Halcyon
16
16
  #
17
17
  # # load the config file and initialize the app
18
18
  # Halcyon::Runner.new
19
+ #
19
20
  class Runner
20
21
 
21
22
  autoload :Commands, 'halcyon/runner/commands'
22
23
 
23
24
  # Initializes the application and application resources.
25
+ #
24
26
  def initialize(&block)
25
27
  Halcyon::Application.boot(&block) unless Halcyon::Application.booted
26
28
  @app = Halcyon::Application.new
@@ -30,6 +32,7 @@ module Halcyon
30
32
  # +env+ the request environment details
31
33
  #
32
34
  # Returns [Fixnum:status, {String:header => String:value}, [String:body]]
35
+ #
33
36
  def call(env)
34
37
  @app.call(env)
35
38
  end
@@ -40,6 +43,7 @@ module Halcyon
40
43
  # +argv+ the arguments to pass to the commands
41
44
  #
42
45
  # Returns nothing
46
+ #
43
47
  def run!(argv=ARGV)
44
48
  Commands.send(argv.shift, argv)
45
49
  end
@@ -60,4 +60,11 @@ describe "Halcyon::Client" do
60
60
  @client.get('/time')[:status].should == 200
61
61
  end
62
62
 
63
+ it "should handle ampersands (and others) in POST data correctly" do
64
+ response = @client.post('/returner', :key => "value1&value2=0")
65
+
66
+ response[:status].should == 200
67
+ response[:body].should == {'controller' => 'application', 'action' => 'returner', 'key' => "value1&value2=0"}
68
+ end
69
+
63
70
  end
@@ -40,4 +40,9 @@ class Application < Halcyon::Controller
40
40
  end
41
41
  end
42
42
 
43
+ # Returns exactly what it gets in terms of params
44
+ def returner
45
+ ok params
46
+ end
47
+
43
48
  end
@@ -30,6 +30,10 @@ Halcyon::Application.route do |r|
30
30
  # Safe to remove!
31
31
  r.match('/time').to(:controller => 'application', :action => 'time')
32
32
 
33
+ # Used for testing how requests are routed. Used internally but can be used
34
+ # for personal tests.
35
+ r.match('/returner').to(:controller => 'application', :action => 'returner')
36
+
33
37
  # RESTful routes
34
38
  # r.resources :posts
35
39
 
@@ -15,6 +15,7 @@ end
15
15
 
16
16
  # = Routes
17
17
  Halcyon::Application.route do |r|
18
+ r.match('/returner').to(:controller => 'application', :action => 'returner')
18
19
  r.match('/time').to(:controller => 'application', :action => 'time')
19
20
 
20
21
  r.match('/').to(:controller => 'application', :action => 'index')
@@ -39,4 +40,9 @@ class Application < Halcyon::Controller
39
40
  ok(Time.now.to_s)
40
41
  end
41
42
 
43
+ # Returns exactly what it gets in terms of params
44
+ def returner
45
+ ok params
46
+ end
47
+
42
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: halcyon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Todd
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-26 00:00:00 -04:00
12
+ date: 2008-08-20 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,17 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.2
33
+ version: 0.9.4
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: extlib
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.4
34
44
  version:
35
45
  - !ruby/object:Gem::Dependency
36
46
  name: json_pure