sinatra 1.4.8 → 2.0.8.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (129) hide show
  1. checksums.yaml +5 -5
  2. data/AUTHORS.md +1 -0
  3. data/CHANGELOG.md +238 -54
  4. data/CONTRIBUTING.md +8 -8
  5. data/Gemfile +47 -47
  6. data/LICENSE +4 -1
  7. data/MAINTENANCE.md +42 -0
  8. data/README.de.md +650 -442
  9. data/README.es.md +738 -357
  10. data/README.fr.md +15 -15
  11. data/README.hu.md +37 -3
  12. data/README.ja.md +124 -66
  13. data/README.ko.md +14 -14
  14. data/README.malayalam.md +3141 -0
  15. data/README.md +530 -403
  16. data/README.pt-br.md +2361 -334
  17. data/README.pt-pt.md +2 -2
  18. data/README.ru.md +856 -607
  19. data/README.zh.md +90 -28
  20. data/Rakefile +77 -51
  21. data/SECURITY.md +35 -0
  22. data/VERSION +1 -0
  23. data/lib/sinatra/base.rb +177 -239
  24. data/lib/sinatra/indifferent_hash.rb +200 -0
  25. data/lib/sinatra/main.rb +30 -10
  26. data/lib/sinatra/show_exceptions.rb +102 -62
  27. data/lib/sinatra/version.rb +1 -1
  28. data/sinatra.gemspec +44 -8
  29. metadata +41 -166
  30. data/lib/sinatra/ext.rb +0 -17
  31. data/test/asciidoctor_test.rb +0 -72
  32. data/test/base_test.rb +0 -167
  33. data/test/builder_test.rb +0 -91
  34. data/test/coffee_test.rb +0 -96
  35. data/test/compile_test.rb +0 -183
  36. data/test/contest.rb +0 -91
  37. data/test/creole_test.rb +0 -65
  38. data/test/delegator_test.rb +0 -160
  39. data/test/encoding_test.rb +0 -20
  40. data/test/erb_test.rb +0 -116
  41. data/test/extensions_test.rb +0 -98
  42. data/test/filter_test.rb +0 -487
  43. data/test/haml_test.rb +0 -109
  44. data/test/helper.rb +0 -132
  45. data/test/helpers_test.rb +0 -1917
  46. data/test/integration/app.rb +0 -79
  47. data/test/integration_helper.rb +0 -236
  48. data/test/integration_test.rb +0 -104
  49. data/test/less_test.rb +0 -69
  50. data/test/liquid_test.rb +0 -77
  51. data/test/mapped_error_test.rb +0 -285
  52. data/test/markaby_test.rb +0 -80
  53. data/test/markdown_test.rb +0 -85
  54. data/test/mediawiki_test.rb +0 -68
  55. data/test/middleware_test.rb +0 -68
  56. data/test/nokogiri_test.rb +0 -67
  57. data/test/public/favicon.ico +0 -0
  58. data/test/public/hello+world.txt +0 -1
  59. data/test/rabl_test.rb +0 -89
  60. data/test/rack_test.rb +0 -45
  61. data/test/radius_test.rb +0 -59
  62. data/test/rdoc_test.rb +0 -66
  63. data/test/readme_test.rb +0 -130
  64. data/test/request_test.rb +0 -100
  65. data/test/response_test.rb +0 -63
  66. data/test/result_test.rb +0 -76
  67. data/test/route_added_hook_test.rb +0 -59
  68. data/test/routing_test.rb +0 -1456
  69. data/test/sass_test.rb +0 -115
  70. data/test/scss_test.rb +0 -88
  71. data/test/server_test.rb +0 -56
  72. data/test/settings_test.rb +0 -582
  73. data/test/sinatra_test.rb +0 -12
  74. data/test/slim_test.rb +0 -102
  75. data/test/static_test.rb +0 -266
  76. data/test/streaming_test.rb +0 -149
  77. data/test/stylus_test.rb +0 -90
  78. data/test/templates_test.rb +0 -382
  79. data/test/textile_test.rb +0 -65
  80. data/test/views/a/in_a.str +0 -1
  81. data/test/views/ascii.erb +0 -2
  82. data/test/views/b/in_b.str +0 -1
  83. data/test/views/calc.html.erb +0 -1
  84. data/test/views/error.builder +0 -3
  85. data/test/views/error.erb +0 -3
  86. data/test/views/error.haml +0 -3
  87. data/test/views/error.sass +0 -2
  88. data/test/views/explicitly_nested.str +0 -1
  89. data/test/views/foo/hello.test +0 -1
  90. data/test/views/hello.asciidoc +0 -1
  91. data/test/views/hello.builder +0 -1
  92. data/test/views/hello.coffee +0 -1
  93. data/test/views/hello.creole +0 -1
  94. data/test/views/hello.erb +0 -1
  95. data/test/views/hello.haml +0 -1
  96. data/test/views/hello.less +0 -5
  97. data/test/views/hello.liquid +0 -1
  98. data/test/views/hello.mab +0 -1
  99. data/test/views/hello.md +0 -1
  100. data/test/views/hello.mediawiki +0 -1
  101. data/test/views/hello.nokogiri +0 -1
  102. data/test/views/hello.rabl +0 -2
  103. data/test/views/hello.radius +0 -1
  104. data/test/views/hello.rdoc +0 -1
  105. data/test/views/hello.sass +0 -2
  106. data/test/views/hello.scss +0 -3
  107. data/test/views/hello.slim +0 -1
  108. data/test/views/hello.str +0 -1
  109. data/test/views/hello.styl +0 -2
  110. data/test/views/hello.test +0 -1
  111. data/test/views/hello.textile +0 -1
  112. data/test/views/hello.wlang +0 -1
  113. data/test/views/hello.yajl +0 -1
  114. data/test/views/layout2.builder +0 -3
  115. data/test/views/layout2.erb +0 -2
  116. data/test/views/layout2.haml +0 -2
  117. data/test/views/layout2.liquid +0 -2
  118. data/test/views/layout2.mab +0 -2
  119. data/test/views/layout2.nokogiri +0 -3
  120. data/test/views/layout2.rabl +0 -3
  121. data/test/views/layout2.radius +0 -2
  122. data/test/views/layout2.slim +0 -3
  123. data/test/views/layout2.str +0 -2
  124. data/test/views/layout2.test +0 -1
  125. data/test/views/layout2.wlang +0 -2
  126. data/test/views/nested.str +0 -1
  127. data/test/views/utf8.erb +0 -2
  128. data/test/wlang_test.rb +0 -87
  129. data/test/yajl_test.rb +0 -86
data/README.zh.md CHANGED
@@ -205,7 +205,7 @@ end
205
205
  通过正则表达式匹配路由:
206
206
 
207
207
  ```ruby
208
- get /\A\/hello\/([\w]+)\z/ do
208
+ get /\/hello\/([\w]+)/ do
209
209
  "Hello, #{params['captures'].first}!"
210
210
  end
211
211
  ```
@@ -239,6 +239,17 @@ end
239
239
  ```
240
240
  顺便一提,除非你禁用了路径遍历攻击防护(见下文),请求路径可能在匹配路由前发生改变。
241
241
 
242
+ 你也可以通过`:mustermann_opt`选项定义[Mustermann](https://github.com/sinatra/mustermann)来匹配路由。
243
+
244
+ ```ruby
245
+ get '\A/posts\z', :mustermann_opts => { :type => :regexp, :check_anchors => false } do
246
+ # matches /posts exactly, with explicit anchoring
247
+ "If you match an anchored pattern clap your hands!"
248
+ end
249
+ ```
250
+
251
+ 它看起来像一个[条件](https://github.com/sinatra/sinatra/blob/master/README.zh.md#%E6%9D%A1%E4%BB%B6),但实际不是!这些选项将被合并到全局的`mustermann_opts`。
252
+
242
253
  ### 条件
243
254
 
244
255
  路由可以包含各种匹配条件,比如 user agent:
@@ -313,8 +324,8 @@ Rack 堆栈中的下一个中间件。大多数情况下,返回值是一个字
313
324
 
314
325
  你可以返回任何对象,该对象要么是一个合理的 Rack 响应,要么是一个 Rack body 对象,要么是 HTTP 状态码:
315
326
 
316
- * 一个包含三个元素的数组: `[状态 (Fixnum), 响应首部 (Hash), 响应主体 (可以响应 #each 方法)]`
317
- * 一个包含两个元素的数组: `[状态 (Fixnum), 响应主体 (可以响应 #each 方法)]`
327
+ * 一个包含三个元素的数组: `[状态 (Integer), 响应首部 (Hash), 响应主体 (可以响应 #each 方法)]`
328
+ * 一个包含两个元素的数组: `[状态 (Integer), 响应主体 (可以响应 #each 方法)]`
318
329
  * 一个响应 `#each` 方法,只传回字符串的对象
319
330
  * 一个代表状态码的数字
320
331
 
@@ -372,7 +383,7 @@ end
372
383
  或者,使用消极向前查找:
373
384
 
374
385
  ```ruby
375
- get %r{^(?!/index$)} do
386
+ get %r{(?!/index)} do
376
387
  # ...
377
388
  end
378
389
  ```
@@ -649,7 +660,7 @@ get('/') { markdown :index }
649
660
  <table>
650
661
  <tr>
651
662
  <td>依赖项</td>
652
- <td><a href="http://liquidmarkup.org/" title="liquid">liquid</a></td>
663
+ <td><a href="https://shopify.github.io/liquid/" title="liquid">liquid</a></td>
653
664
  </tr>
654
665
  <tr>
655
666
  <td>文件扩展名</td>
@@ -672,7 +683,7 @@ get('/') { markdown :index }
672
683
  下列任一:
673
684
  <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
674
685
  <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
675
- <a href="http://deveiate.org/projects/BlueCloth" title="BlueCloth">BlueCloth</a>,
686
+ <a href="https://github.com/ged/bluecloth" title="bluecloth">BlueCloth</a>,
676
687
  <a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
677
688
  <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
678
689
  </td>
@@ -1302,33 +1313,59 @@ get '/:value' do
1302
1313
  end
1303
1314
  ```
1304
1315
 
1305
- 请注意 `enable :sessions` 实际将所有的数据保存在一个 cookie 中。
1306
- 这可能并不总是你想要的(cookie 中存储大量的数据会增加你的流量)。
1307
- 你可以使用任何 Rack session 中间件:要达到此目的,**不要**使用 `enable :sessions`,
1308
- 而是按照自己的需要引入想使用的中间件:
1316
+ #### 会话加密
1317
+
1318
+ 为提高安全性,cookie 中的会话数据使用`HMAC-SHA1`进行加密。会话加密的最佳实践应当是像`HMAC-SHA1`这样生成大于或等于64字节 (512 bits, 128 hex characters)的随机值。应当避免使用少于32字节(256 bits, 64 hex characters)的随机值。应当使用生成器来创建安全的密钥,而不是拍脑袋决定。
1319
+
1320
+ 默认情况下,Sinatra会生成一个32字节的密钥,但随着应用程序的每次重新启动,它都会发生改变。如果有多个应用程序的实例,使用Sinatra生成密钥,每个实例将有不同的密钥,这可能不是您想要的。
1321
+
1322
+ 为了更好的安全性和可用性,[建议](https://12factor.net/config)生成安全的随机密钥,并将其存储在运行应用程序的每个主机上的环境变量中,以便所有应用程序实例都将共享相同的密钥。并且应该定期更新会话密钥。下面是一些创建64比特密钥的例子:
1323
+
1324
+ #### 生成密钥
1309
1325
 
1310
1326
  ```ruby
1311
- use Rack::Session::Pool, :expire_after => 2592000
1327
+ $ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
1328
+ 99ae8af...snip...ec0f262ac
1329
+ ```
1312
1330
 
1313
- get '/' do
1314
- "value = " << session['value'].inspect
1315
- end
1331
+ #### 生成密钥(小贴士)
1316
1332
 
1317
- get '/:value' do
1318
- session['value'] = params['value']
1319
- end
1333
+ MRI Ruby目前认为[sysrandom gem](https://github.com/cryptosphere/sysrandom)使用系统的随机数生成器要比用户态的`OpenSSL`好。
1334
+
1335
+ ```ruby
1336
+ $ gem install sysrandom
1337
+ Building native extensions. This could take a while...
1338
+ Successfully installed sysrandom-1.x
1339
+ 1 gem installed
1340
+
1341
+ $ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
1342
+ 99ae8af...snip...ec0f262ac
1320
1343
  ```
1321
1344
 
1322
- 为提高安全性,cookie 中的会话数据会被一个会话密码保护。Sinatra 会为你生成一个随机的密码。
1323
- 然而,每次启动应用时,该密码都会变化,你也可以自己设置该密码,以便所有的应用实例共享:
1345
+ #### 从环境变量使用密钥
1324
1346
 
1347
+ 将Sinatra的SESSION_SECRET环境变量设置为生成的值。在主机的重新启动之间保存这个值。由于这样做的方法会因系统而异,仅供说明之用:
1325
1348
  ```
1326
- set :session_secret, 'super secret'
1349
+ # echo "export SESSION_SECRET=99ae8af...snip...ec0f262ac" >> ~/.bashrc
1327
1350
  ```
1328
1351
 
1329
- 如果你想进一步配置会话,可以在设置 `sessions` 时提供一个选项 hash 作为第二个参数:
1352
+ #### 应用的密钥配置
1330
1353
 
1354
+ 如果SESSION SECRET环境变量不可用,将把应用的随机密钥设置为不安全的。
1355
+
1356
+ 关于[sysrandom gem](https://github.com/cryptosphere/sysrandom)的更多用法:
1357
+
1358
+ ```ruby
1359
+ require 'securerandom'
1360
+ # -or- require 'sysrandom/securerandom'
1361
+ set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
1331
1362
  ```
1363
+
1364
+ #### 会话配置
1365
+
1366
+ 如果你想进一步配置会话,可以在设置 `sessions` 时提供一个选项 hash 作为第二个参数:
1367
+
1368
+ ```ruby
1332
1369
  set :sessions, :domain => 'foo.com'
1333
1370
  ```
1334
1371
 
@@ -1338,6 +1375,31 @@ set :sessions, :domain => 'foo.com'
1338
1375
  set :sessions, :domain => '.foo.com'
1339
1376
  ```
1340
1377
 
1378
+ #### 选择你自己的会话中间件
1379
+
1380
+ 请注意 `enable :sessions` 实际将所有的数据保存在一个 cookie 中。
1381
+ 这可能并不总是你想要的(cookie 中存储大量的数据会增加你的流量)。
1382
+ 你可以使用任何 Rack session 中间件:要达到此目的,**不要**使用 `enable :sessions`,
1383
+ 而是按照自己的需要引入想使用的中间件:
1384
+
1385
+ ```ruby
1386
+ enable :sessions
1387
+ set :session_store, Rack::Session::Pool
1388
+ ```
1389
+
1390
+ 另一种选择是不要调用enable:sessions,而是像你想要的其他中间件一样加入你的中间件。
1391
+
1392
+ 重要的是要注意,使用此方法时,默认情况下不会启用基于会话的保护。
1393
+
1394
+ 还需要添加Rack中间件:
1395
+
1396
+ ```ruby
1397
+ use Rack::Session::Pool, :expire_after => 2592000
1398
+ use Rack::Protection::RemoteToken
1399
+ use Rack::Protection::SessionHijacking
1400
+ ```
1401
+ 更多[安全防护配置](https://github.com/sinatra/sinatra#configuring-attack-protection)的信息。
1402
+
1341
1403
  ### 中断请求
1342
1404
 
1343
1405
  要想在过滤器或路由中立即中断一个请求:
@@ -1933,7 +1995,7 @@ configure do
1933
1995
  end
1934
1996
  ```
1935
1997
 
1936
- 只有当环境 (`RACK_ENV` 环境变量) 被设定为 `:production` 时才运行:
1998
+ 只有当环境 (`APP_ENV` 环境变量) 被设定为 `:production` 时才运行:
1937
1999
 
1938
2000
  ```ruby
1939
2001
  configure :production do
@@ -1965,7 +2027,7 @@ end
1965
2027
 
1966
2028
  ### 配置攻击防护
1967
2029
 
1968
- Sinatra 使用 [Rack::Protection](https://github.com/sinatra/rack-protection#readme)
2030
+ Sinatra 使用 [Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme)
1969
2031
  来抵御常见的攻击。你可以轻易地禁用该行为(但这会大大增加应用被攻击的概率)。
1970
2032
 
1971
2033
  ```ruby
@@ -2033,8 +2095,8 @@ set :protection, :session => true
2033
2095
 
2034
2096
  <dt>environment</dt>
2035
2097
  <dd>
2036
- 当前环境,默认是 <tt>ENV['RACK_ENV']</tt>,
2037
- 或者 <tt>"development"</tt> (如果 ENV['RACK_ENV'] 不可用)。
2098
+ 当前环境,默认是 <tt>ENV['APP_ENV']</tt>,
2099
+ 或者 <tt>"development"</tt> (如果 ENV['APP_ENV'] 不可用)。
2038
2100
  </dd>
2039
2101
 
2040
2102
  <dt>logging</dt>
@@ -2145,15 +2207,15 @@ set :protection, :session => true
2145
2207
  ## 环境
2146
2208
 
2147
2209
  Sinatra 中有三种预先定义的环境:"development"、"production" 和 "test"。
2148
- 环境可以通过 `RACK_ENV` 环境变量设置。默认值为 "development"。
2210
+ 环境可以通过 `APP_ENV` 环境变量设置。默认值为 "development"。
2149
2211
  在开发环境下,每次请求都会重新加载所有模板,
2150
2212
  特殊的 `not_found` 和 `error` 错误处理器会在浏览器中显示 stack trace。
2151
2213
  在测试和生产环境下,模板默认会缓存。
2152
2214
 
2153
- 在不同的环境下运行,设置 `RACK_ENV` 环境变量:
2215
+ 在不同的环境下运行,设置 `APP_ENV` 环境变量:
2154
2216
 
2155
2217
  ```shell
2156
- RACK_ENV=production ruby my_app.rb
2218
+ APP_ENV=production ruby my_app.rb
2157
2219
  ```
2158
2220
 
2159
2221
  可以使用预定义的三种方法: `development?`、`test?` 和 `production?` 来检查当前环境:
data/Rakefile CHANGED
@@ -3,22 +3,13 @@ require 'rake/testtask'
3
3
  require 'fileutils'
4
4
  require 'date'
5
5
 
6
- # CI Reporter is only needed for the CI
7
- begin
8
- require 'ci/reporter/rake/test_unit'
9
- rescue LoadError
10
- end
11
-
12
6
  task :default => :test
13
7
  task :spec => :test
14
8
 
15
9
  CLEAN.include "**/*.rbc"
16
10
 
17
11
  def source_version
18
- @source_version ||= begin
19
- load './lib/sinatra/version.rb'
20
- Sinatra::VERSION
21
- end
12
+ @source_version ||= File.read(File.expand_path("../VERSION", __FILE__)).strip
22
13
  end
23
14
 
24
15
  def prev_feature
@@ -39,7 +30,7 @@ end
39
30
 
40
31
  Rake::TestTask.new(:test) do |t|
41
32
  t.test_files = FileList['test/*_test.rb']
42
- t.ruby_opts = ['-rubygems'] if defined? Gem
33
+ t.ruby_opts = ['-r rubygems'] if defined? Gem
43
34
  t.ruby_opts << '-I.'
44
35
  t.warning = true
45
36
  end
@@ -50,7 +41,7 @@ Rake::TestTask.new(:"test:core") do |t|
50
41
  readme request response result route_added_hook
51
42
  routing server settings sinatra static templates]
52
43
  t.test_files = core_tests.map {|n| "test/#{n}_test.rb"}
53
- t.ruby_opts = ["-rubygems"] if defined? Gem
44
+ t.ruby_opts = ["-r rubygems"] if defined? Gem
54
45
  t.ruby_opts << "-I."
55
46
  t.warning = true
56
47
  end
@@ -61,7 +52,8 @@ namespace :test do
61
52
  desc 'Measures test coverage'
62
53
  task :coverage do
63
54
  rm_f "coverage"
64
- sh "rcov -Ilib test/*_test.rb"
55
+ ENV['COVERAGE'] = '1'
56
+ Rake::Task['test'].invoke
65
57
  end
66
58
  end
67
59
 
@@ -95,9 +87,9 @@ end
95
87
 
96
88
  # Thanks in announcement ===============================================
97
89
 
98
- team = ["Ryan Tomayko", "Blake Mizerany", "Simon Rozet", "Konstantin Haase"]
90
+ team = ["Ryan Tomayko", "Blake Mizerany", "Simon Rozet", "Konstantin Haase", "Zachary Scott"]
99
91
  desc "list of contributors"
100
- task :thanks, [:release,:backports] do |t, a|
92
+ task :thanks, ['release:all', :backports] do |t, a|
101
93
  a.with_defaults :release => "#{prev_version}..HEAD",
102
94
  :backports => "#{prev_feature}.0..#{prev_feature}.x"
103
95
  included = `git log --format=format:"%aN\t%s" #{a.release}`.lines.map { |l| l.force_encoding('binary') }
@@ -146,54 +138,88 @@ end
146
138
  # PACKAGING ============================================================
147
139
 
148
140
  if defined?(Gem)
149
- # Load the gemspec using the same limitations as github
150
- def spec
151
- require 'rubygems' unless defined? Gem::Specification
152
- @spec ||= eval(File.read('sinatra.gemspec'))
141
+ GEMS_AND_ROOT_DIRECTORIES = {
142
+ "sinatra" => ".",
143
+ "sinatra-contrib" => "./sinatra-contrib",
144
+ "rack-protection" => "./rack-protection"
145
+ }
146
+
147
+ def package(gem, ext='')
148
+ "pkg/#{gem}-#{source_version}" + ext
153
149
  end
154
150
 
155
- def package(ext='')
156
- "pkg/sinatra-#{spec.version}" + ext
157
- end
151
+ directory 'pkg/'
152
+ CLOBBER.include('pkg')
158
153
 
159
- desc 'Build packages'
160
- task :package => %w[.gem .tar.gz].map {|e| package(e)}
154
+ GEMS_AND_ROOT_DIRECTORIES.each do |gem, directory|
155
+ file package(gem, '.gem') => ["pkg/", "#{directory + '/' + gem}.gemspec"] do |f|
156
+ sh "cd #{directory} && gem build #{gem}.gemspec"
157
+ mv directory + "/" + File.basename(f.name), f.name
158
+ end
161
159
 
162
- desc 'Build and install as local gem'
163
- task :install => package('.gem') do
164
- sh "gem install #{package('.gem')}"
160
+ file package(gem, '.tar.gz') => ["pkg/"] do |f|
161
+ sh <<-SH
162
+ git archive \
163
+ --prefix=#{gem}-#{source_version}/ \
164
+ --format=tar \
165
+ HEAD -- #{directory} | gzip > #{f.name}
166
+ SH
167
+ end
165
168
  end
166
169
 
167
- directory 'pkg/'
168
- CLOBBER.include('pkg')
170
+ namespace :package do
171
+ GEMS_AND_ROOT_DIRECTORIES.each do |gem, directory|
172
+ desc "Build #{gem} packages"
173
+ task gem => %w[.gem .tar.gz].map { |e| package(gem, e) }
174
+ end
169
175
 
170
- file package('.gem') => %w[pkg/ sinatra.gemspec] + spec.files do |f|
171
- sh "gem build sinatra.gemspec"
172
- mv File.basename(f.name), f.name
176
+ desc "Build all packages"
177
+ task :all => GEMS_AND_ROOT_DIRECTORIES.keys
173
178
  end
174
179
 
175
- file package('.tar.gz') => %w[pkg/] + spec.files do |f|
176
- sh <<-SH
177
- git archive \
178
- --prefix=sinatra-#{source_version}/ \
179
- --format=tar \
180
- HEAD | gzip > #{f.name}
181
- SH
180
+ namespace :install do
181
+ GEMS_AND_ROOT_DIRECTORIES.each do |gem, directory|
182
+ desc "Build and install #{gem} as local gem"
183
+ task gem => package(gem, '.gem') do
184
+ sh "gem install #{package(gem, '.gem')}"
185
+ end
186
+ end
187
+
188
+ desc "Build and install all of the gems as local gems"
189
+ task :all => GEMS_AND_ROOT_DIRECTORIES.keys
182
190
  end
183
191
 
184
- task 'release' => ['test', package('.gem')] do
185
- if File.binread("CHANGELOG.md") =~ /= \d\.\d\.\d . not yet released$/i
186
- fail 'please update the changelog first' unless %x{git symbolic-ref HEAD} == "refs/heads/prerelease\n"
192
+ namespace :release do
193
+ GEMS_AND_ROOT_DIRECTORIES.each do |gem, directory|
194
+ desc "Release #{gem} as a package"
195
+ task gem => "package:#{gem}" do
196
+ sh <<-SH
197
+ gem install #{package(gem, '.gem')} --local &&
198
+ gem push #{package(gem, '.gem')}
199
+ SH
200
+ end
201
+ end
202
+
203
+ desc "Commits the version to github repository"
204
+ task :commit_version do
205
+ %w[
206
+ lib/sinatra
207
+ sinatra-contrib/lib/sinatra/contrib
208
+ rack-protection/lib/rack/protection
209
+ ].each do |path|
210
+ path = File.join(path, 'version.rb')
211
+ File.write(path, File.read(path).sub(/VERSION = '(.+?)'/, "VERSION = '#{source_version}'"))
212
+ end
213
+
214
+ sh <<-SH
215
+ git commit --allow-empty -a -m '#{source_version} release' &&
216
+ git tag -s v#{source_version} -m '#{source_version} release' &&
217
+ git push && (git push origin || true) &&
218
+ git push --tags && (git push origin --tags || true)
219
+ SH
187
220
  end
188
221
 
189
- sh <<-SH
190
- gem install #{package('.gem')} --local &&
191
- gem push #{package('.gem')} &&
192
- git commit --allow-empty -a -m '#{source_version} release' &&
193
- git tag -s v#{source_version} -m '#{source_version} release' &&
194
- git tag -s #{source_version} -m '#{source_version} release' &&
195
- git push && (git push sinatra || true) &&
196
- git push --tags && (git push sinatra --tags || true)
197
- SH
222
+ desc "Release all gems as packages"
223
+ task :all => [:test, :commit_version] + GEMS_AND_ROOT_DIRECTORIES.keys
198
224
  end
199
225
  end
data/SECURITY.md ADDED
@@ -0,0 +1,35 @@
1
+ # Reporting a security bug
2
+
3
+ All security bugs in Sinatra should be reported to the core team through our private mailing list [sinatra-security@googlegroups.com](https://groups.google.com/group/sinatra-security). Your report will be acknowledged within 24 hours, and you’ll receive a more detailed response to your email within 48 hours indicating the next steps in handling your report.
4
+
5
+ After the initial reply to your report the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement. These updates will be sent at least every five days, in reality this is more likely to be every 24-48 hours.
6
+
7
+ If you have not received a reply to your email within 48 hours, or have not heard from the security team for the past five days there are a few steps you can take:
8
+
9
+ * Contact the current security coordinator [Zachary Scott](mailto:zzak@ruby-lang.org) directly
10
+
11
+ ## Disclosure Policy
12
+
13
+ Sinatra has a 5 step disclosure policy, that is upheld to the best of our ability.
14
+
15
+ 1. Security report received and is assigned a primary handler. This person will coordinate the fix and release process.
16
+ 2. Problem is confirmed and, a list of all affected versions is determined. Code is audited to find any potential similar problems.
17
+ 3. Fixes are prepared for all releases which are still supported. These fixes are not committed to the public repository but rather held locally pending the announcement.
18
+ 4. A suggested embargo date for this vulnerability is chosen and distros@openwall is notified. This notification will include patches for all versions still under support and a contact address for packagers who need advice back-porting patches to older versions.
19
+ 5. On the embargo date, the [mailing list][mailing-list] and [security list][security-list] are sent a copy of the announcement. The changes are pushed to the public repository and new gems released to rubygems.
20
+
21
+ Typically the embargo date will be set 72 hours from the time vendor-sec is first notified, however this may vary depending on the severity of the bug or difficulty in applying a fix.
22
+
23
+ This process can take some time, especially when coordination is required with maintainers of other projects. Every effort will be made to handle the bug in as timely a manner as possible, however it’s important that we follow the release process above to ensure that the disclosure is handled in a consistent manner.
24
+
25
+ ## Security Updates
26
+
27
+ Security updates will be posted on the [mailing list][mailing-list] and [security list][security-list].
28
+
29
+ ## Comments on this Policy
30
+
31
+ If you have any suggestions to improve this policy, please send an email the core team at [sinatrarb@googlegroups.com](https://groups.google.com/group/sinatrarb).
32
+
33
+
34
+ [mailing-list]: http://groups.google.com/group/sinatrarb/topics
35
+ [security-list]: http://groups.google.com/group/sinatra-security/topics
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.8.1