halcyon 0.5.1 → 0.5.2

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/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