darkhelmet-sinatra 0.9.1 → 0.9.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ = 0.9.1.1 / 2009-03-09
2
+
3
+ * Fix directory traversal vulnerability in default static files
4
+ route. See [#177] for more info.
5
+
1
6
  = 0.9.1 / 2009-03-01
2
7
 
3
8
  * Sinatra now runs under Ruby 1.9.1 [#61]
@@ -10,7 +15,7 @@
10
15
 
11
16
  * New request-level #forward method for middleware components: passes
12
17
  the env to the downstream app and merges the response status, headers,
13
- and body into the current context.
18
+ and body into the current context. [#126]
14
19
 
15
20
  * Requests are now automatically forwarded to the downstream app when
16
21
  running as middleware and no matching route is found or all routes
@@ -43,6 +48,11 @@
43
48
  ":session" option to any of the mock request methods. e.g.,
44
49
  get '/', {}, :session => { 'foo' => 'bar' }
45
50
 
51
+ * The testing framework specific files ('sinatra/test/spec',
52
+ 'sinatra/test/bacon', 'sinatra/test/rspec', etc.) have been deprecated.
53
+ See http://sinatrarb.com/testing.html for instructions on setting up
54
+ a testing environment with these frameworks.
55
+
46
56
  * The request-level #send_data method from Sinatra 0.3.3 has been added
47
57
  for compatibility but is deprecated.
48
58
 
@@ -57,6 +67,12 @@
57
67
  * Fixed some issues with running under Rack's CGI handler caused by
58
68
  writing informational stuff to stdout.
59
69
 
70
+ * Fixed that reloading was sometimes enabled when starting from a
71
+ rackup file [#110]
72
+
73
+ * Fixed that "." in route patterns erroneously matched any character
74
+ instead of a literal ".". [#124]
75
+
60
76
  = 0.9.0.4 / 2009-01-25
61
77
 
62
78
  * Using halt with more than 1 args causes ArgumentError [#131]
data/README.rdoc CHANGED
@@ -159,8 +159,8 @@ Renders the inlined template string.
159
159
 
160
160
  === Accessing Variables in Templates
161
161
 
162
- Templates are evaluated within the same context as the route blocks. Instance
163
- variables set in route blocks are available in templates:
162
+ Templates are evaluated within the same context as route handlers. Instance
163
+ variables set in route handlers are direcly accessible by templates:
164
164
 
165
165
  get '/:id' do
166
166
  @foo = Foo.find(params[:id])
@@ -199,12 +199,11 @@ Templates may be defined at the end of the source file:
199
199
 
200
200
  NOTE: In-file templates defined in the source file that requires sinatra
201
201
  are automatically loaded. Call the <tt>use_in_file_templates!</tt>
202
- method explicitly if you have in-file templates in another source file.
202
+ method explicitly if you have in-file templates in other source files.
203
203
 
204
204
  === Named Templates
205
205
 
206
- It's possible to define named templates using the top-level <tt>template</tt>
207
- method:
206
+ Templates may also be defined using the top-level <tt>template</tt> method:
208
207
 
209
208
  template :layout do
210
209
  "%html\n =yield\n"
@@ -228,7 +227,7 @@ is rendered. You can disable layouts by passing <tt>:layout => false</tt>.
228
227
  == Helpers
229
228
 
230
229
  Use the top-level <tt>helpers</tt> method to define helper methods for use in
231
- route blocks and templates:
230
+ route handlers and templates:
232
231
 
233
232
  helpers do
234
233
  def bar(name)
@@ -244,7 +243,7 @@ route blocks and templates:
244
243
 
245
244
  Before filters are evaluated before each request within the context of the
246
245
  request and can modify the request and response. Instance variables set in
247
- filters are accessible by routes and templates.
246
+ filters are accessible by routes and templates:
248
247
 
249
248
  before do
250
249
  @note = 'Hi!'
@@ -272,8 +271,7 @@ Or set the status and body ...
272
271
 
273
272
  == Passing
274
273
 
275
- A route can punt processing to the next matching route using the <tt>pass</tt>
276
- statement:
274
+ A route can punt processing to the next matching route using <tt>pass</tt>:
277
275
 
278
276
  get '/guess/:who' do
279
277
  pass unless params[:who] == 'Frank'
@@ -403,85 +401,34 @@ typically don't have to +use+ them explicitly.
403
401
 
404
402
  == Testing
405
403
 
406
- The Sinatra::Test module includes a variety of helper methods for testing
407
- your Sinatra app. Sinatra includes support for Test::Unit, test-spec, RSpec,
408
- and Bacon through separate source files.
404
+ The Sinatra::Test mixin and Sinatra::TestHarness class include a variety of
405
+ helper methods for testing your Sinatra app:
409
406
 
410
- === Test::Unit
411
-
412
- require 'sinatra'
413
- require 'sinatra/test/unit'
414
407
  require 'my_sinatra_app'
408
+ require 'test/unit'
409
+ require 'sinatra/test'
415
410
 
416
411
  class MyAppTest < Test::Unit::TestCase
417
- def test_my_default
418
- get '/'
419
- assert_equal 'My Default Page!', @response.body
420
- end
412
+ include Sinatra::Test
421
413
 
422
- def test_with_agent
423
- get '/', :env => { :agent => 'Songbird' }
424
- assert_equal "You're in Songbird!", @response.body
425
- end
426
-
427
- ...
428
- end
429
-
430
- === Test::Spec
431
-
432
- Install the test-spec gem and require <tt>'sinatra/test/spec'</tt> before
433
- your app:
434
-
435
- require 'sinatra'
436
- require 'sinatra/test/spec'
437
- require 'my_sinatra_app'
438
-
439
- describe 'My app' do
440
- it "should show a default page" do
414
+ def test_my_default
441
415
  get '/'
442
- should.be.ok
443
- body.should.equal 'My Default Page!'
416
+ assert_equal 'Hello World!', @response.body
444
417
  end
445
418
 
446
- ...
447
- end
448
-
449
- === RSpec
450
-
451
- Install the rspec gem and require <tt>'sinatra/test/rspec'</tt> before
452
- your app:
453
-
454
- require 'sinatra'
455
- require 'sinatra/test/rspec'
456
- require 'my_sinatra_app'
457
-
458
- describe 'My app' do
459
- it 'should show a default page' do
460
- get '/'
461
- @response.should be_ok
462
- @response.body.should == 'My Default Page!'
419
+ def test_with_params
420
+ get '/meet', {:name => 'Frank'}
421
+ assert_equal 'Hello Frank!', @response.body
463
422
  end
464
423
 
465
- ...
466
-
467
- end
468
-
469
- === Bacon
470
-
471
- require 'sinatra'
472
- require 'sinatra/test/bacon'
473
- require 'my_sinatra_app'
474
-
475
- describe 'My app' do
476
- it 'should be ok' do
477
- get '/'
478
- should.be.ok
479
- body.should == 'Im OK'
424
+ def test_with_rack_env
425
+ get '/', {}, :agent => 'Songbird'
426
+ assert_equal "You're using Songbird!", @response.body
480
427
  end
481
428
  end
482
429
 
483
- See Sinatra::Test for more information on +get+, +post+, +put+, and
484
- friends.
430
+ See http://www.sinatrarb.com/testing.html for more on Sinatra::Test and using it
431
+ with other test frameworks such as RSpec, Bacon, and test/spec.
485
432
 
486
433
  == Command line
487
434
 
@@ -531,5 +478,6 @@ To update the Sinatra sources in the future:
531
478
  help? Have a patch?
532
479
  * {Lighthouse}[http://sinatra.lighthouseapp.com] - Issue tracking and release
533
480
  planning.
481
+ * {Twitter}[http://twitter.com/sinatra]
534
482
  * {Mailing List}[http://groups.google.com/group/sinatrarb]
535
483
  * {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net
data/lib/sinatra/base.rb CHANGED
@@ -6,7 +6,7 @@ require 'rack/builder'
6
6
  require 'colored'
7
7
 
8
8
  module Sinatra
9
- VERSION = '0.9.1'
9
+ VERSION = '0.9.1.1'
10
10
 
11
11
  # The request object. See Rack::Request for more info:
12
12
  # http://rack.rubyforge.org/doc/classes/Rack/Request.html
@@ -101,6 +101,12 @@ module Sinatra
101
101
  error 404, body
102
102
  end
103
103
 
104
+ # Set multiple response headers with Hash.
105
+ def headers(hash=nil)
106
+ response.headers.merge! hash if hash
107
+ response.headers
108
+ end
109
+
104
110
  # Access the underlying Rack session.
105
111
  def session
106
112
  env['rack.session'] ||= {}
@@ -380,7 +386,7 @@ module Sinatra
380
386
  status, headers, body = @app.call(@request.env)
381
387
  @response.status = status
382
388
  @response.body = body
383
- headers.each { |k, v| @response[k] = v }
389
+ @response.headers.merge! headers
384
390
  nil
385
391
  end
386
392
 
@@ -551,6 +557,7 @@ module Sinatra
551
557
  @middleware = []
552
558
  @errors = {}
553
559
  @prototype = nil
560
+ @extensions = []
554
561
 
555
562
  class << self
556
563
  attr_accessor :routes, :filters, :conditions, :templates,
@@ -696,10 +703,16 @@ module Sinatra
696
703
  lambda { unbound_method.bind(self).call }
697
704
  end
698
705
 
706
+ invoke_hook(:route_added, verb, path)
707
+
699
708
  (routes[verb] ||= []).
700
709
  push([pattern, path, keys, conditions, block]).last
701
710
  end
702
711
 
712
+ def invoke_hook(name, *args)
713
+ extensions.each { |e| e.send(name, *args) if e.respond_to?(name) }
714
+ end
715
+
703
716
  def compile(path)
704
717
  keys = []
705
718
  if path.respond_to? :to_str
@@ -731,8 +744,13 @@ module Sinatra
731
744
  include *extensions if extensions.any?
732
745
  end
733
746
 
747
+ def extensions
748
+ (@extensions + (superclass.extensions rescue [])).uniq
749
+ end
750
+
734
751
  def register(*extensions, &block)
735
752
  extensions << Module.new(&block) if block_given?
753
+ @extensions += extensions
736
754
  extensions.each do |extension|
737
755
  extend extension
738
756
  extension.registered(self) if extension.respond_to?(:registered)
@@ -815,6 +833,7 @@ module Sinatra
815
833
  @errors = base.errors.dup
816
834
  @middleware = base.middleware.dup
817
835
  @prototype = nil
836
+ @extensions = []
818
837
  end
819
838
 
820
839
  protected
@@ -882,7 +901,9 @@ module Sinatra
882
901
  # static files route
883
902
  get(/.*[^\/]$/) do
884
903
  pass unless options.static? && options.public?
885
- path = options.public + unescape(request.path_info)
904
+ public_dir = File.expand_path(options.public)
905
+ path = File.expand_path(public_dir + unescape(request.path_info))
906
+ pass if path[0, public_dir.length] != public_dir
886
907
  pass unless File.file?(path)
887
908
  send_file path, :disposition => nil
888
909
  end
@@ -87,12 +87,10 @@ module Sinatra
87
87
  end
88
88
 
89
89
  # Deprecated. Use: response['Header-Name']
90
- def headers(header=nil)
91
- sinatra_warn "The 'headers' method is deprecated; use 'response' instead."
92
- response.headers.merge!(header) if header
93
- response.headers
90
+ def header(header=nil)
91
+ sinatra_warn "The 'header' method is deprecated; use 'headers' instead."
92
+ headers(header)
94
93
  end
95
- alias :header :headers
96
94
 
97
95
  # Deprecated. Use: halt
98
96
  def stop(*args, &block)
data/lib/sinatra/test.rb CHANGED
@@ -4,6 +4,10 @@ module Sinatra
4
4
  module Test
5
5
  include Rack::Utils
6
6
 
7
+ def self.included(base)
8
+ Sinatra::Default.set(:environment, :test)
9
+ end
10
+
7
11
  attr_reader :app, :request, :response
8
12
 
9
13
  def self.deprecate(framework)
@@ -116,6 +120,7 @@ for more information.
116
120
 
117
121
  def initialize(app=nil)
118
122
  @app = app || Sinatra::Application
123
+ @app.set(:environment, :test)
119
124
  end
120
125
  end
121
126
  end
data/sinatra.gemspec CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'sinatra'
6
- s.version = '0.9.1'
7
- s.date = '2009-03-01'
6
+ s.version = '0.9.1.1'
7
+ s.date = '2009-03-09'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
data/test/helper.rb CHANGED
@@ -19,10 +19,6 @@ end
19
19
  class Test::Unit::TestCase
20
20
  include Sinatra::Test
21
21
 
22
- def setup
23
- Sinatra::Default.set :environment, :test
24
- end
25
-
26
22
  # Sets up a Sinatra::Base subclass defined with the block
27
23
  # given. Used in setup or individual spec methods to establish
28
24
  # the application.
data/test/helpers_test.rb CHANGED
@@ -140,6 +140,36 @@ describe 'Helpers#not_found' do
140
140
  end
141
141
  end
142
142
 
143
+ describe 'Helpers#headers' do
144
+ it 'sets headers on the response object when given a Hash' do
145
+ mock_app {
146
+ get '/' do
147
+ headers 'X-Foo' => 'bar', 'X-Baz' => 'bling'
148
+ 'kthx'
149
+ end
150
+ }
151
+
152
+ get '/'
153
+ assert ok?
154
+ assert_equal 'bar', response['X-Foo']
155
+ assert_equal 'bling', response['X-Baz']
156
+ assert_equal 'kthx', body
157
+ end
158
+
159
+ it 'returns the response headers hash when no hash provided' do
160
+ mock_app {
161
+ get '/' do
162
+ headers['X-Foo'] = 'bar'
163
+ 'kthx'
164
+ end
165
+ }
166
+
167
+ get '/'
168
+ assert ok?
169
+ assert_equal 'bar', response['X-Foo']
170
+ end
171
+ end
172
+
143
173
  describe 'Helpers#session' do
144
174
  it 'uses the existing rack.session' do
145
175
  mock_app {
data/test/static_test.rb CHANGED
@@ -62,4 +62,19 @@ describe 'Static' do
62
62
  get "/foobarbaz.txt"
63
63
  assert not_found?
64
64
  end
65
+
66
+ it 'serves files when .. path traverses within public directory' do
67
+ get "/data/../#{File.basename(__FILE__)}"
68
+ assert ok?
69
+ assert_equal File.read(__FILE__), body
70
+ end
71
+
72
+ it '404s when .. path traverses outside of public directory' do
73
+ mock_app {
74
+ set :static, true
75
+ set :public, File.dirname(__FILE__) + '/data'
76
+ }
77
+ get "/../#{File.basename(__FILE__)}"
78
+ assert not_found?
79
+ end
65
80
  end
data/test/test_test.rb CHANGED
@@ -130,6 +130,12 @@ describe 'Sinatra::Test' do
130
130
  assert called
131
131
  end
132
132
 
133
+ it 'sets the environment to :test on include' do
134
+ Sinatra::Default.set(:environment, :production)
135
+ Class.new { include Sinatra::Test }
136
+ assert_equal :test, Sinatra::Default.environment
137
+ end
138
+
133
139
  def test_TestHarness
134
140
  session = Sinatra::TestHarness.new(@app)
135
141
  response = session.get('/')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: darkhelmet-sinatra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Mizerany
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-01 00:00:00 -08:00
12
+ date: 2009-03-09 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency