sinatra 2.1.0 → 2.2.4

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.

data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.2.4
data/lib/sinatra/base.rb CHANGED
@@ -78,6 +78,8 @@ module Sinatra
78
78
  super
79
79
  rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
80
80
  raise BadRequest, "Invalid query parameters: #{Rack::Utils.escape_html(e.message)}"
81
+ rescue EOFError => e
82
+ raise BadRequest, "Invalid multipart/form-data: #{Rack::Utils.escape_html(e.message)}"
81
83
  end
82
84
 
83
85
  class AcceptEntry
@@ -188,7 +190,7 @@ module Sinatra
188
190
  headers["Content-Length"] = body.map(&:bytesize).reduce(0, :+).to_s
189
191
  end
190
192
 
191
- [status.to_i, headers, result]
193
+ [status, headers, result]
192
194
  end
193
195
 
194
196
  private
@@ -198,11 +200,11 @@ module Sinatra
198
200
  end
199
201
 
200
202
  def drop_content_info?
201
- status.to_i / 100 == 1 or drop_body?
203
+ informational? or drop_body?
202
204
  end
203
205
 
204
206
  def drop_body?
205
- DROP_BODY_RESPONSES.include?(status.to_i)
207
+ DROP_BODY_RESPONSES.include?(status)
206
208
  end
207
209
  end
208
210
 
@@ -379,16 +381,23 @@ module Sinatra
379
381
  response['Content-Type'] = mime_type
380
382
  end
381
383
 
384
+ # https://html.spec.whatwg.org/#multipart-form-data
385
+ MULTIPART_FORM_DATA_REPLACEMENT_TABLE = {
386
+ '"' => '%22',
387
+ "\r" => '%0D',
388
+ "\n" => '%0A'
389
+ }.freeze
390
+
382
391
  # Set the Content-Disposition to "attachment" with the specified filename,
383
392
  # instructing the user agents to prompt to save.
384
393
  def attachment(filename = nil, disposition = :attachment)
385
394
  response['Content-Disposition'] = disposition.to_s.dup
386
- if filename
387
- params = '; filename="%s"' % File.basename(filename)
388
- response['Content-Disposition'] << params
389
- ext = File.extname(filename)
390
- content_type(ext) unless response['Content-Type'] or ext.empty?
391
- end
395
+ return unless filename
396
+
397
+ params = format('; filename="%s"', File.basename(filename).gsub(/["\r\n]/, MULTIPART_FORM_DATA_REPLACEMENT_TABLE))
398
+ response['Content-Disposition'] << params
399
+ ext = File.extname(filename)
400
+ content_type(ext) unless response['Content-Type'] || ext.empty?
392
401
  end
393
402
 
394
403
  # Use the contents of the file at +path+ as the response body.
@@ -869,12 +878,12 @@ module Sinatra
869
878
 
870
879
  def compile_template(engine, data, options, views)
871
880
  eat_errors = options.delete :eat_errors
872
- template_cache.fetch engine, data, options, views do
873
- template = Tilt[engine]
874
- raise "Template engine not found: #{engine}" if template.nil?
881
+ template = Tilt[engine]
882
+ raise "Template engine not found: #{engine}" if template.nil?
875
883
 
876
- case data
877
- when Symbol
884
+ case data
885
+ when Symbol
886
+ template_cache.fetch engine, data, options, views do
878
887
  body, path, line = settings.templates[data]
879
888
  if body
880
889
  body = body.call if body.respond_to?(:call)
@@ -892,17 +901,24 @@ module Sinatra
892
901
  throw :layout_missing if eat_errors and not found
893
902
  template.new(path, 1, options)
894
903
  end
895
- when Proc, String
896
- body = data.is_a?(String) ? Proc.new { data } : data
897
- caller = settings.caller_locations.first
898
- path = options[:path] || caller[0]
899
- line = options[:line] || caller[1]
900
- template.new(path, line.to_i, options, &body)
901
- else
902
- raise ArgumentError, "Sorry, don't know how to render #{data.inspect}."
903
904
  end
905
+ when Proc
906
+ compile_block_template(template, options, &data)
907
+ when String
908
+ template_cache.fetch engine, data, options, views do
909
+ compile_block_template(template, options) { data }
910
+ end
911
+ else
912
+ raise ArgumentError, "Sorry, don't know how to render #{data.inspect}."
904
913
  end
905
914
  end
915
+
916
+ def compile_block_template(template, options, &body)
917
+ caller = settings.caller_locations.first
918
+ path = options[:path] || caller[0]
919
+ line = options[:line] || caller[1]
920
+ template.new(path, line.to_i, options, &body)
921
+ end
906
922
  end
907
923
 
908
924
  # Base class for all Sinatra applications and middleware.
@@ -916,7 +932,7 @@ module Sinatra
916
932
  attr_accessor :app, :env, :request, :response, :params
917
933
  attr_reader :template_cache
918
934
 
919
- def initialize(app = nil)
935
+ def initialize(app = nil, **kwargs)
920
936
  super()
921
937
  @app = app
922
938
  @template_cache = Tilt::Cache.new
@@ -934,6 +950,7 @@ module Sinatra
934
950
  @params = IndifferentHash.new
935
951
  @request = Request.new(env)
936
952
  @response = Response.new
953
+ @pinned_response = nil
937
954
  template_cache.clear if settings.reload_templates
938
955
 
939
956
  invoke { dispatch! }
@@ -994,11 +1011,11 @@ module Sinatra
994
1011
 
995
1012
  # Run filters defined on the class and all superclasses.
996
1013
  # Accepts an optional block to call after each filter is applied.
997
- def filter!(type, base = settings)
998
- filter! type, base.superclass if base.superclass.respond_to?(:filters)
1014
+ def filter!(type, base = settings, &block)
1015
+ filter!(type, base.superclass, &block) if base.superclass.respond_to?(:filters)
999
1016
  base.filters[type].each do |args|
1000
1017
  result = process_route(*args)
1001
- yield result if block_given?
1018
+ block.call(result) if block_given?
1002
1019
  end
1003
1020
  end
1004
1021
 
@@ -1006,7 +1023,7 @@ module Sinatra
1006
1023
  def route!(base = settings, pass_block = nil)
1007
1024
  if routes = base.routes[@request.request_method]
1008
1025
  routes.each do |pattern, conditions, block|
1009
- @response.delete_header('Content-Type') unless @pinned_response
1026
+ response.delete_header('Content-Type') unless @pinned_response
1010
1027
 
1011
1028
  returned_pass_block = process_route(pattern, conditions) do |*args|
1012
1029
  env['sinatra.route'] = "#{@request.request_method} #{pattern}"
@@ -1089,6 +1106,7 @@ module Sinatra
1089
1106
  return unless valid_path?(path)
1090
1107
 
1091
1108
  path = File.expand_path(path)
1109
+ return unless path.start_with?(File.expand_path(public_dir) + '/')
1092
1110
  return unless File.file?(path)
1093
1111
 
1094
1112
  env['sinatra.static_file'] = path
@@ -1124,7 +1142,7 @@ module Sinatra
1124
1142
  invoke do
1125
1143
  static! if settings.static? && (request.get? || request.head?)
1126
1144
  filter! :before do
1127
- @pinned_response = !@response['Content-Type'].nil?
1145
+ @pinned_response = !response['Content-Type'].nil?
1128
1146
  end
1129
1147
  route!
1130
1148
  end
@@ -1145,7 +1163,7 @@ module Sinatra
1145
1163
  end
1146
1164
  @env['sinatra.error'] = boom
1147
1165
 
1148
- if boom.respond_to? :http_status
1166
+ if boom.respond_to? :http_status and boom.http_status.between? 400, 599
1149
1167
  status(boom.http_status)
1150
1168
  elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599
1151
1169
  status(boom.code)
@@ -1153,8 +1171,6 @@ module Sinatra
1153
1171
  status(500)
1154
1172
  end
1155
1173
 
1156
- status(500) unless status.between? 400, 599
1157
-
1158
1174
  if server_error?
1159
1175
  dump_errors! boom if settings.dump_errors?
1160
1176
  raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
@@ -1168,7 +1184,7 @@ module Sinatra
1168
1184
 
1169
1185
  if not_found? || bad_request?
1170
1186
  if boom.message && boom.message != boom.class.name
1171
- body boom.message
1187
+ body Rack::Utils.escape_html(boom.message)
1172
1188
  else
1173
1189
  content_type 'text/html'
1174
1190
  body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>'
@@ -1221,6 +1237,10 @@ module Sinatra
1221
1237
 
1222
1238
  attr_reader :routes, :filters, :templates, :errors
1223
1239
 
1240
+ def callers_to_ignore
1241
+ CALLERS_TO_IGNORE
1242
+ end
1243
+
1224
1244
  # Removes all routes, filters, middleware and extension hooks from the
1225
1245
  # current class (not routes/filters/... defined by its superclass).
1226
1246
  def reset!
@@ -1442,7 +1462,7 @@ module Sinatra
1442
1462
  # in `extensions` available to the handlers and templates
1443
1463
  def helpers(*extensions, &block)
1444
1464
  class_eval(&block) if block_given?
1445
- prepend(*extensions) if extensions.any?
1465
+ include(*extensions) if extensions.any?
1446
1466
  end
1447
1467
 
1448
1468
  # Register an extension. Alternatively take a block from which an
@@ -1471,6 +1491,7 @@ module Sinatra
1471
1491
  @prototype = nil
1472
1492
  @middleware << [middleware, args, block]
1473
1493
  end
1494
+ ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
1474
1495
 
1475
1496
  # Stop the self-hosted server if running.
1476
1497
  def quit!
@@ -1490,7 +1511,7 @@ module Sinatra
1490
1511
  def run!(options = {}, &block)
1491
1512
  return if running?
1492
1513
  set options
1493
- handler = detect_rack_handler
1514
+ handler = Rack::Handler.pick(server)
1494
1515
  handler_name = handler.name.gsub(/.*::/, '')
1495
1516
  server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
1496
1517
  server_settings.merge!(:Port => port, :Host => bind)
@@ -1527,6 +1548,7 @@ module Sinatra
1527
1548
  instance = new!(*args, &bk)
1528
1549
  Wrapper.new(build(instance).to_app, instance)
1529
1550
  end
1551
+ ruby2_keywords :new if respond_to?(:ruby2_keywords, true)
1530
1552
 
1531
1553
  # Creates a Rack::Builder instance with all the middleware set up and
1532
1554
  # the given +app+ as end point.
@@ -1744,17 +1766,6 @@ module Sinatra
1744
1766
  builder.use session_store, options
1745
1767
  end
1746
1768
 
1747
- def detect_rack_handler
1748
- servers = Array(server)
1749
- servers.each do |server_name|
1750
- begin
1751
- return Rack::Handler.get(server_name.to_s)
1752
- rescue LoadError, NameError
1753
- end
1754
- end
1755
- fail "Server handler (#{servers.join(',')}) not found."
1756
- end
1757
-
1758
1769
  def inherited(subclass)
1759
1770
  subclass.reset!
1760
1771
  subclass.set :app_file, caller_files.first unless subclass.app_file?
@@ -1779,7 +1790,7 @@ module Sinatra
1779
1790
  def cleaned_caller(keep = 3)
1780
1791
  caller(1).
1781
1792
  map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
1782
- reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
1793
+ reject { |file, *_| callers_to_ignore.any? { |pattern| file =~ pattern } }
1783
1794
  end
1784
1795
  end
1785
1796
 
@@ -1958,6 +1969,8 @@ module Sinatra
1958
1969
  return super(*args, &block) if respond_to? method_name
1959
1970
  Delegator.target.send(method_name, *args, &block)
1960
1971
  end
1972
+ # ensure keyword argument passing is compatible with ruby >= 2.7
1973
+ ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
1961
1974
  private method_name
1962
1975
  end
1963
1976
  end
@@ -180,6 +180,20 @@ module Sinatra
180
180
  end
181
181
  end
182
182
 
183
+ def select(*args, &block)
184
+ return to_enum(:select) unless block_given?
185
+ dup.tap { |hash| hash.select!(*args, &block) }
186
+ end
187
+
188
+ def reject(*args, &block)
189
+ return to_enum(:reject) unless block_given?
190
+ dup.tap { |hash| hash.reject!(*args, &block) }
191
+ end
192
+
193
+ def compact
194
+ dup.tap(&:compact!)
195
+ end if method_defined?(:compact) # Added in Ruby 2.4
196
+
183
197
  private
184
198
 
185
199
  def convert_key(key)
@@ -1,3 +1,3 @@
1
1
  module Sinatra
2
- VERSION = '2.1.0'
2
+ VERSION = '2.2.3'
3
3
  end
data/sinatra.gemspec CHANGED
@@ -19,9 +19,8 @@ Gem::Specification.new 'sinatra', version do |s|
19
19
  "SECURITY.md",
20
20
  "sinatra.gemspec",
21
21
  "VERSION"]
22
- s.test_files = s.files.select { |p| p =~ /^test\/.*_test.rb/ }
23
- s.extra_rdoc_files = s.files.select { |p| p =~ /^README/ } << 'LICENSE'
24
- s.rdoc_options = %w[--line-numbers --inline-source --title Sinatra --main README.rdoc --encoding=UTF-8]
22
+ s.extra_rdoc_files = %w[README.md LICENSE]
23
+ s.rdoc_options = %w[--line-numbers --title Sinatra --main README.rdoc --encoding=UTF-8]
25
24
 
26
25
  if s.respond_to?(:metadata)
27
26
  s.metadata = {
@@ -33,11 +32,6 @@ Gem::Specification.new 'sinatra', version do |s|
33
32
  'documentation_uri' => 'https://www.rubydoc.info/gems/sinatra'
34
33
  }
35
34
  else
36
- msg = "RubyGems 2.0 or newer is required to protect against public "\
37
- "gem pushes. You can update your rubygems version by running:\n\n"\
38
- "gem install rubygems-update\n"\
39
- "update_rubygems\n"\
40
- "gem update --system"
41
35
  raise <<-EOF
42
36
  RubyGems 2.0 or newer is required to protect against public gem pushes. You can update your rubygems version by running:
43
37
  gem install rubygems-update
@@ -51,5 +45,5 @@ EOF
51
45
  s.add_dependency 'rack', '~> 2.2'
52
46
  s.add_dependency 'tilt', '~> 2.0'
53
47
  s.add_dependency 'rack-protection', version
54
- s.add_dependency 'mustermann', '~> 1.0'
48
+ s.add_dependency 'mustermann', '~> 2.0'
55
49
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Mizerany
8
8
  - Ryan Tomayko
9
9
  - Simon Rozet
10
10
  - Konstantin Haase
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2020-09-04 00:00:00.000000000 Z
14
+ date: 2022-12-16 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rack
@@ -47,46 +47,35 @@ dependencies:
47
47
  requirements:
48
48
  - - '='
49
49
  - !ruby/object:Gem::Version
50
- version: 2.1.0
50
+ version: 2.2.4
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - '='
56
56
  - !ruby/object:Gem::Version
57
- version: 2.1.0
57
+ version: 2.2.4
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: mustermann
60
60
  requirement: !ruby/object:Gem::Requirement
61
61
  requirements:
62
62
  - - "~>"
63
63
  - !ruby/object:Gem::Version
64
- version: '1.0'
64
+ version: '2.0'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
69
  - - "~>"
70
70
  - !ruby/object:Gem::Version
71
- version: '1.0'
71
+ version: '2.0'
72
72
  description: Sinatra is a DSL for quickly creating web applications in Ruby with minimal
73
73
  effort.
74
74
  email: sinatrarb@googlegroups.com
75
75
  executables: []
76
76
  extensions: []
77
77
  extra_rdoc_files:
78
- - README.de.md
79
- - README.es.md
80
- - README.fr.md
81
- - README.hu.md
82
- - README.ja.md
83
- - README.ko.md
84
- - README.malayalam.md
85
78
  - README.md
86
- - README.pt-br.md
87
- - README.pt-pt.md
88
- - README.ru.md
89
- - README.zh.md
90
79
  - LICENSE
91
80
  files:
92
81
  - ".yardopts"
@@ -135,10 +124,9 @@ metadata:
135
124
  bug_tracker_uri: https://github.com/sinatra/sinatra/issues
136
125
  mailing_list_uri: http://groups.google.com/group/sinatrarb
137
126
  documentation_uri: https://www.rubydoc.info/gems/sinatra
138
- post_install_message:
127
+ post_install_message:
139
128
  rdoc_options:
140
129
  - "--line-numbers"
141
- - "--inline-source"
142
130
  - "--title"
143
131
  - Sinatra
144
132
  - "--main"
@@ -157,8 +145,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
145
  - !ruby/object:Gem::Version
158
146
  version: '0'
159
147
  requirements: []
160
- rubygems_version: 3.1.2
161
- signing_key:
148
+ rubyforge_project:
149
+ rubygems_version: 2.7.6.3
150
+ signing_key:
162
151
  specification_version: 4
163
152
  summary: Classy web-development dressed in a DSL
164
153
  test_files: []