sinatra 1.2.0.a → 1.2.0.c

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.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

@@ -172,7 +172,7 @@ Rack body对象或者HTTP状态码:
172
172
 
173
173
  需要引入haml gem/library以渲染 HAML 模板:
174
174
 
175
- ## 你需要在你的应用中引入 haml
175
+ # 你需要在你的应用中引入 haml
176
176
  require 'haml'
177
177
 
178
178
  get '/' do
@@ -195,7 +195,7 @@ Rack body对象或者HTTP状态码:
195
195
 
196
196
  === Erb模板
197
197
 
198
- ## 你需要在你的应用中引入 erb
198
+ # 你需要在你的应用中引入 erb
199
199
  require 'erb'
200
200
 
201
201
  get '/' do
@@ -208,7 +208,7 @@ Rack body对象或者HTTP状态码:
208
208
 
209
209
  需要引入erubis gem/library以渲染 erubis 模板:
210
210
 
211
- ## 你需要在你的应用中引入 erubis
211
+ # 你需要在你的应用中引入 erubis
212
212
  require 'erubis'
213
213
 
214
214
  get '/' do
@@ -221,7 +221,7 @@ Rack body对象或者HTTP状态码:
221
221
 
222
222
  需要引入 builder gem/library 以渲染 builder templates:
223
223
 
224
- ## 需要在你的应用中引入builder
224
+ # 需要在你的应用中引入builder
225
225
  require 'builder'
226
226
 
227
227
  get '/' do
@@ -234,7 +234,7 @@ Rack body对象或者HTTP状态码:
234
234
 
235
235
  需要引入 nokogiri gem/library 以渲染 nokogiri 模板:
236
236
 
237
- ## 需要在你的应用中引入 nokogiri
237
+ # 需要在你的应用中引入 nokogiri
238
238
  require 'nokogiri'
239
239
 
240
240
  get '/' do
@@ -247,7 +247,7 @@ Rack body对象或者HTTP状态码:
247
247
 
248
248
  需要引入 haml gem/library 以渲染 Sass 模板:
249
249
 
250
- ## 需要在你的应用中引入 haml 或者 sass
250
+ # 需要在你的应用中引入 haml 或者 sass
251
251
  require 'sass'
252
252
 
253
253
  get '/stylesheet.css' do
@@ -271,7 +271,7 @@ Rack body对象或者HTTP状态码:
271
271
 
272
272
  需要引入 haml gem/library 来渲染 Scss templates:
273
273
 
274
- ## 需要在你的应用中引入 haml 或者 sass
274
+ # 需要在你的应用中引入 haml 或者 sass
275
275
  require 'sass'
276
276
 
277
277
  get '/stylesheet.css' do
@@ -295,7 +295,7 @@ Rack body对象或者HTTP状态码:
295
295
 
296
296
  需要引入 less gem/library 以渲染 Less 模板:
297
297
 
298
- ## 需要在你的应用中引入 less
298
+ # 需要在你的应用中引入 less
299
299
  require 'less'
300
300
 
301
301
  get '/stylesheet.css' do
@@ -308,7 +308,7 @@ Rack body对象或者HTTP状态码:
308
308
 
309
309
  需要引入 liquid gem/library 来渲染 Liquid 模板:
310
310
 
311
- ## 需要在你的应用中引入 liquid
311
+ # 需要在你的应用中引入 liquid
312
312
  require 'liquid'
313
313
 
314
314
  get '/' do
@@ -326,7 +326,7 @@ Rack body对象或者HTTP状态码:
326
326
 
327
327
  需要引入 rdiscount gem/library 以渲染 Markdown 模板:
328
328
 
329
- ## 需要在你的应用中引入rdiscount
329
+ # 需要在你的应用中引入rdiscount
330
330
  require "rdiscount"
331
331
 
332
332
  get '/' do
@@ -349,7 +349,7 @@ Rack body对象或者HTTP状态码:
349
349
 
350
350
  需要引入 RedCloth gem/library 以渲染 Textile 模板:
351
351
 
352
- ## 在你的应用中引入redcloth
352
+ # 在你的应用中引入redcloth
353
353
  require "redcloth"
354
354
 
355
355
  get '/' do
@@ -371,7 +371,7 @@ Rack body对象或者HTTP状态码:
371
371
 
372
372
  需要引入 RDoc gem/library 以渲染RDoc模板:
373
373
 
374
- ## 需要在你的应用中引入rdoc
374
+ # 需要在你的应用中引入rdoc
375
375
  require "rdoc"
376
376
 
377
377
  get '/' do
@@ -393,7 +393,7 @@ Rack body对象或者HTTP状态码:
393
393
 
394
394
  需要引入 radius gem/library 以渲染 Radius 模板:
395
395
 
396
- ## You'll need to require radius in your app
396
+ # You'll need to require radius in your app
397
397
  require 'radius'
398
398
 
399
399
  get '/' do
@@ -411,7 +411,7 @@ Rack body对象或者HTTP状态码:
411
411
 
412
412
  需要引入markaby gem/library以渲染Markaby模板:
413
413
 
414
- ##需要在你的应用中引入 markaby
414
+ #需要在你的应用中引入 markaby
415
415
  require 'markaby'
416
416
 
417
417
  get '/' do
@@ -424,7 +424,7 @@ Rack body对象或者HTTP状态码:
424
424
 
425
425
  需要引入 slim gem/library 来渲染 Slim 模板:
426
426
 
427
- ## 需要在你的应用中引入 slim
427
+ # 需要在你的应用中引入 slim
428
428
  require 'slim'
429
429
 
430
430
  get '/' do
@@ -438,7 +438,7 @@ Rack body对象或者HTTP状态码:
438
438
  需要引入 coffee-script gem/library 并在路径中存在 `coffee` 二进制文件以渲染
439
439
  CoffeeScript 模板:
440
440
 
441
- ## 需要在你的应用中引入coffee-script
441
+ # 需要在你的应用中引入coffee-script
442
442
  require 'coffee-script'
443
443
 
444
444
  get '/application.js' do
data/Rakefile CHANGED
@@ -6,6 +6,8 @@ require 'date'
6
6
  task :default => :test
7
7
  task :spec => :test
8
8
 
9
+ CLEAN.include "**/*.rbc"
10
+
9
11
  def source_version
10
12
  line = File.read('lib/sinatra/base.rb')[/^\s*VERSION = .*/]
11
13
  line.match(/.*VERSION = '(.*)'/)[1]
@@ -17,21 +19,11 @@ task :test do
17
19
  ENV.delete 'LC_CTYPE'
18
20
  end
19
21
 
20
- if !ENV['NO_TEST_FIX'] and RUBY_VERSION == '1.9.2' and RUBY_PATCHLEVEL == 0
21
- # Avoids seg fault
22
- task(:test) do
23
- second_run = %w[settings rdoc markaby templates static textile].map { |l| "test/#{l}_test.rb" }
24
- first_run = Dir.glob('test/*_test.rb') - second_run
25
- [first_run, second_run].each { |f| sh "testrb #{f.join ' '}" }
26
- end
27
- else
28
- Rake::TestTask.new(:test) do |t|
29
- t.test_files = FileList['test/*_test.rb']
30
- t.ruby_opts = ['-rubygems'] if defined? Gem
31
- t.ruby_opts << '-I.'
32
- end
22
+ Rake::TestTask.new(:test) do |t|
23
+ t.test_files = FileList['test/*_test.rb']
24
+ t.ruby_opts = ['-rubygems'] if defined? Gem
25
+ t.ruby_opts << '-I.'
33
26
  end
34
-
35
27
  # Rcov ================================================================
36
28
  namespace :test do
37
29
  desc 'Mesures test coverage'
@@ -7,7 +7,7 @@ require 'sinatra/showexceptions'
7
7
  require 'tilt'
8
8
 
9
9
  module Sinatra
10
- VERSION = '1.2.0.a'
10
+ VERSION = '1.2.0.c'
11
11
 
12
12
  # The request object. See Rack::Request for more info:
13
13
  # http://rack.rubyforge.org/doc/classes/Rack/Request.html
@@ -29,6 +29,10 @@ module Sinatra
29
29
  alias secure? ssl?
30
30
  end
31
31
 
32
+ def forwarded?
33
+ @env.include? "HTTP_X_FORWARDED_HOST"
34
+ end
35
+
32
36
  def route
33
37
  @route ||= begin
34
38
  path = Rack::Utils.unescape(path_info)
@@ -91,24 +95,37 @@ module Sinatra
91
95
 
92
96
  # Halt processing and redirect to the URI provided.
93
97
  def redirect(uri, *args)
94
- if not uri =~ /^https?:\/\//
95
- # According to RFC 2616 section 14.30, "the field value consists of a
96
- # single absolute URI"
97
- abs_uri = "#{request.scheme}://#{request.host}"
98
-
99
- if request.scheme == 'https' && request.port != 443 ||
100
- request.scheme == 'http' && request.port != 80
101
- abs_uri << ":#{request.port}"
102
- end
103
-
104
- uri = (abs_uri << uri)
105
- end
106
-
107
98
  status 302
108
- response['Location'] = uri
99
+
100
+ # According to RFC 2616 section 14.30, "the field value consists of a
101
+ # single absolute URI"
102
+ response['Location'] = url(uri, settings.absolute_redirects?, settings.prefixed_redirects?)
109
103
  halt(*args)
110
104
  end
111
105
 
106
+ # Generates the absolute URI for a given path in the app.
107
+ # Takes Rack routers and reverse proxies into account.
108
+ def uri(addr = nil, absolute = true, add_script_name = true)
109
+ return addr if addr =~ /^https?:\/\//
110
+ uri = [host = ""]
111
+ if absolute
112
+ host << 'http'
113
+ host << 's' if request.secure?
114
+ host << "://"
115
+ if request.forwarded? or request.port != (request.secure? ? 443 : 80)
116
+ host << request.host_with_port
117
+ else
118
+ host << request.host
119
+ end
120
+ end
121
+ uri << request.script_name.to_s if add_script_name
122
+ uri << (addr ? addr : request.path_info).to_s
123
+ File.join uri
124
+ end
125
+
126
+ alias url uri
127
+ alias to uri
128
+
112
129
  # Halt processing and return the error status provided.
113
130
  def error(code, body=nil)
114
131
  code, body = 500, code.to_str if code.respond_to? :to_str
@@ -324,10 +341,17 @@ module Sinatra
324
341
  # with a '304 Not Modified' response.
325
342
  def last_modified(time)
326
343
  return unless time
327
- time = time.to_time if time.respond_to?(:to_time)
328
- time = Time.parse time.strftime('%FT%T%:z') if time.respond_to?(:strftime)
329
- response['Last-Modified'] = time.respond_to?(:httpdate) ? time.httpdate : time.to_s
330
- halt 304 if Time.httpdate(request.env['HTTP_IF_MODIFIED_SINCE']) >= time
344
+ if time.respond_to?(:to_time)
345
+ time = time.to_time
346
+ else
347
+ ## make a best effort to convert something else to a time object
348
+ ## if this fails, this should throw an ArgumentError, then the
349
+ # rescue will result in an http 200, which should be safe
350
+ time = Time.parse(time.to_s)
351
+ end
352
+ response['Last-Modified'] = time.httpdate
353
+ # compare based on seconds since epoch
354
+ halt 304 if Time.httpdate(request.env['HTTP_IF_MODIFIED_SINCE']).to_i >= time.to_i
331
355
  rescue ArgumentError
332
356
  end
333
357
 
@@ -446,6 +470,15 @@ module Sinatra
446
470
  render :slim, template, options, locals
447
471
  end
448
472
 
473
+ # Calls the given block for every possible template file in views,
474
+ # named name.ext, where ext is registered on engine.
475
+ def find_template(views, name, engine)
476
+ Tilt.mappings.each do |ext, klass|
477
+ next unless klass == engine
478
+ yield ::File.join(views, "#{name}.#{ext}")
479
+ end
480
+ end
481
+
449
482
  private
450
483
  # logic shared between builder and nokogiri
451
484
  def render_ruby(engine, template, options={}, locals={}, &block)
@@ -469,17 +502,18 @@ module Sinatra
469
502
  layout = @default_layout if layout.nil? or layout == true
470
503
  content_type = options.delete(:content_type) || options.delete(:default_content_type)
471
504
  layout_engine = options.delete(:layout_engine) || engine
505
+ scope = options.delete(:scope) || self
472
506
 
473
507
  # compile and render template
474
508
  layout_was = @default_layout
475
509
  @default_layout = false
476
510
  template = compile_template(engine, data, options, views)
477
- output = template.render(self, locals, &block)
511
+ output = template.render(scope, locals, &block)
478
512
  @default_layout = layout_was
479
513
 
480
514
  # render layout
481
515
  if layout
482
- options = options.merge(:views => views, :layout => false, :eat_errors => eat_errors)
516
+ options = options.merge(:views => views, :layout => false, :eat_errors => eat_errors, :scope => scope)
483
517
  catch(:layout_missing) { output = render(layout_engine, layout, options, locals) { output }}
484
518
  end
485
519
 
@@ -501,13 +535,14 @@ module Sinatra
501
535
  template.new(path, line.to_i, options) { body }
502
536
  else
503
537
  found = false
504
- path = ::File.join(views, "#{data}.#{engine}")
505
- Tilt.mappings.each do |ext, klass|
506
- break if found = File.exists?(path)
507
- next unless klass == template
508
- path = ::File.join(views, "#{data}.#{ext}")
538
+ find_template(views, data, template) do |file|
539
+ path ||= file # keep the initial path rather than the last one
540
+ if found = File.exists?(file)
541
+ path = file
542
+ break
543
+ end
509
544
  end
510
- throw :layout_missing if eat_errors and !found
545
+ throw :layout_missing if eat_errors and not found
511
546
  template.new(path, 1, options)
512
547
  end
513
548
  when data.is_a?(Proc) || data.is_a?(String)
@@ -990,7 +1025,7 @@ module Sinatra
990
1025
  # Will set params[:agent].
991
1026
  def user_agent(pattern)
992
1027
  condition do
993
- if request.user_agent =~ pattern
1028
+ if request.user_agent.to_s =~ pattern
994
1029
  @params[:agent] = $~[1..-1]
995
1030
  true
996
1031
  else
@@ -1007,7 +1042,7 @@ module Sinatra
1007
1042
  condition do
1008
1043
  matching_types = (request.accept & types)
1009
1044
  unless matching_types.empty?
1010
- response.headers['Content-Type'] = matching_types.first
1045
+ content_type matching_types.first
1011
1046
  true
1012
1047
  else
1013
1048
  false
@@ -1067,7 +1102,7 @@ module Sinatra
1067
1102
  def compile(path)
1068
1103
  keys = []
1069
1104
  if path.respond_to? :to_str
1070
- special_chars = %w{. + ( )}
1105
+ special_chars = %w{. + ( ) $}
1071
1106
  pattern =
1072
1107
  path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
1073
1108
  case match
@@ -1084,6 +1119,8 @@ module Sinatra
1084
1119
  [/^#{pattern}$/, keys]
1085
1120
  elsif path.respond_to?(:keys) && path.respond_to?(:match)
1086
1121
  [path, path.keys]
1122
+ elsif path.respond_to?(:names) && path.respond_to?(:match)
1123
+ [path, path.names]
1087
1124
  elsif path.respond_to? :match
1088
1125
  [path, keys]
1089
1126
  else
@@ -1280,6 +1317,9 @@ module Sinatra
1280
1317
  set :bind, '0.0.0.0'
1281
1318
  set :port, 4567
1282
1319
 
1320
+ set :absolute_redirects, true
1321
+ set :prefixed_redirects, false
1322
+
1283
1323
  set :app_file, nil
1284
1324
  set :root, Proc.new { app_file && File.expand_path(File.dirname(app_file)) }
1285
1325
  set :views, Proc.new { root && File.join(root, 'views') }
@@ -8,11 +8,36 @@ module Sinatra
8
8
  # Be careful when you use this on public-facing sites as it could reveal
9
9
  # information helpful to attackers.
10
10
  class ShowExceptions < Rack::ShowExceptions
11
+ @@eats_errors = Object.new
12
+ def @@eats_errors.flush(*) end
13
+ def @@eats_errors.puts(*) end
14
+
11
15
  def initialize(app)
12
16
  @app = app
13
17
  @template = ERB.new(TEMPLATE)
14
18
  end
15
19
 
20
+ def call(env)
21
+ @app.call(env)
22
+ rescue Exception => e
23
+ errors, env["rack.errors"] = env["rack.errors"], @@eats_errors
24
+
25
+ if respond_to?(:prefers_plain_text?) and prefers_plain_text?(env)
26
+ content_type = "text/plain"
27
+ body = [dump_exception(e)]
28
+ else
29
+ content_type = "text/html"
30
+ body = pretty(env, e)
31
+ end
32
+
33
+ env["rack.errors"] = errors
34
+
35
+ [500,
36
+ {"Content-Type" => content_type,
37
+ "Content-Length" => Rack::Utils.bytesize(body.join).to_s},
38
+ body]
39
+ end
40
+
16
41
  private
17
42
 
18
43
  def frame_class(frame)
@@ -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 = '1.2.0.a'
7
- s.date = '2010-12-25'
6
+ s.version = '1.2.0.c'
7
+ s.date = '2011-02-19'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
@@ -16,6 +16,8 @@ Gem::Specification.new do |s|
16
16
  s.files = %w[
17
17
  AUTHORS
18
18
  CHANGES
19
+ Gemfile
20
+ Gemfile.lock
19
21
  LICENSE
20
22
  README.de.rdoc
21
23
  README.es.rdoc
@@ -71,7 +73,10 @@ Gem::Specification.new do |s|
71
73
  test/static_test.rb
72
74
  test/templates_test.rb
73
75
  test/textile_test.rb
76
+ test/views/a/in_a.str
74
77
  test/views/ascii.haml
78
+ test/views/b/in_b.str
79
+ test/views/calc.html.erb
75
80
  test/views/error.builder
76
81
  test/views/error.erb
77
82
  test/views/error.erubis
@@ -117,23 +122,8 @@ Gem::Specification.new do |s|
117
122
 
118
123
  s.extra_rdoc_files = %w[README.rdoc README.de.rdoc README.jp.rdoc README.fr.rdoc README.es.rdoc README.hu.rdoc README.zh.rdoc LICENSE]
119
124
  s.add_dependency 'rack', '~> 1.1'
120
- s.add_dependency 'tilt', '~> 1.2'
121
- s.add_development_dependency 'rake'
125
+ s.add_dependency 'tilt', '>= 1.2.2', '< 2.0'
122
126
  s.add_development_dependency 'shotgun', '~> 0.6'
123
- s.add_development_dependency 'rack-test', '>= 0.5.6'
124
- s.add_development_dependency 'haml', '>= 3.0'
125
- s.add_development_dependency 'builder'
126
- s.add_development_dependency 'erubis'
127
- s.add_development_dependency 'less'
128
- s.add_development_dependency 'liquid'
129
- s.add_development_dependency 'rdiscount'
130
- s.add_development_dependency 'RedCloth'
131
- s.add_development_dependency 'radius'
132
- s.add_development_dependency 'markaby'
133
- s.add_development_dependency 'coffee-script', '>= 2.0'
134
- s.add_development_dependency 'rdoc'
135
- s.add_development_dependency 'nokogiri'
136
- s.add_development_dependency 'slim'
137
127
 
138
128
  s.has_rdoc = true
139
129
  s.homepage = "http://sinatra.rubyforge.org"