sinatra 2.0.8.1 → 2.1.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/Gemfile +2 -1
- data/README.de.md +3 -3
- data/README.es.md +3 -3
- data/README.fr.md +182 -85
- data/README.hu.md +3 -3
- data/README.ja.md +1 -1
- data/README.ko.md +1 -1
- data/README.md +67 -34
- data/README.pt-br.md +1 -1
- data/README.pt-pt.md +3 -3
- data/README.ru.md +3 -3
- data/README.zh.md +1 -1
- data/VERSION +1 -1
- data/examples/chat.rb +2 -1
- data/examples/rainbows.conf +3 -0
- data/examples/rainbows.rb +20 -0
- data/examples/stream.ru +4 -4
- data/lib/sinatra/base.rb +73 -33
- data/lib/sinatra/main.rb +5 -5
- data/lib/sinatra/show_exceptions.rb +2 -37
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +2 -2
- metadata +10 -9
data/README.hu.md
CHANGED
@@ -120,7 +120,7 @@ A statikus fájlok kiszolgálása a `./public` könyvtárból
|
|
120
120
|
történik, de természetesen más könyvtárat is megadhatsz erre a célra,
|
121
121
|
mégpedig a :public_folder kapcsoló beállításával:
|
122
122
|
|
123
|
-
set :public_folder,
|
123
|
+
set :public_folder, __dir__ + '/static'
|
124
124
|
|
125
125
|
Fontos megjegyezni, hogy a nyilvános könyvtár neve nem szerepel az URL-ben.
|
126
126
|
A ./public/css/style.css fájl az
|
@@ -131,7 +131,7 @@ A ./public/css/style.css fájl az
|
|
131
131
|
A sablonfájlokat rendszerint a `./views` könyvtárba helyezzük, de
|
132
132
|
itt is lehetőség nyílik egyéb könyvtár használatára:
|
133
133
|
|
134
|
-
set :views,
|
134
|
+
set :views, __dir__ + '/templates'
|
135
135
|
|
136
136
|
Nagyon fontos észben tartani, hogy a sablononkra mindig szimbólumokkal
|
137
137
|
hivatkozunk, még akkor is, ha egyéb (ebben az esetben a
|
@@ -700,7 +700,7 @@ De hozzá is adhatod a <tt>sinatra/lib</tt> könyvtárat a <tt>LOAD_PATH</tt>-ho
|
|
700
700
|
az alkalmazásodban:
|
701
701
|
|
702
702
|
```ruby
|
703
|
-
$LOAD_PATH.unshift
|
703
|
+
$LOAD_PATH.unshift __dir__ + '/sinatra/lib'
|
704
704
|
require 'rubygems'
|
705
705
|
require 'sinatra'
|
706
706
|
|
data/README.ja.md
CHANGED
data/README.ko.md
CHANGED
data/README.md
CHANGED
@@ -34,7 +34,7 @@ The code you changed will not take effect until you restart the server.
|
|
34
34
|
Please restart the server every time you change or use
|
35
35
|
[sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
|
36
36
|
|
37
|
-
It is recommended to also run `gem install
|
37
|
+
It is recommended to also run `gem install puma`, which Sinatra will
|
38
38
|
pick up if available.
|
39
39
|
|
40
40
|
## Table of Contents
|
@@ -427,7 +427,7 @@ Static files are served from the `./public` directory. You can specify
|
|
427
427
|
a different location by setting the `:public_folder` option:
|
428
428
|
|
429
429
|
```ruby
|
430
|
-
set :public_folder,
|
430
|
+
set :public_folder, __dir__ + '/static'
|
431
431
|
```
|
432
432
|
|
433
433
|
Note that the public directory name is not included in the URL. A file
|
@@ -1293,7 +1293,7 @@ own `#find_template` method:
|
|
1293
1293
|
|
1294
1294
|
```ruby
|
1295
1295
|
configure do
|
1296
|
-
set :views [ './views/a', './views/b' ]
|
1296
|
+
set :views, [ './views/a', './views/b' ]
|
1297
1297
|
end
|
1298
1298
|
|
1299
1299
|
def find_template(views, name, engine, &block)
|
@@ -1685,36 +1685,52 @@ to `stream` finishes executing. Streaming does not work at all with Shotgun.
|
|
1685
1685
|
|
1686
1686
|
If the optional parameter is set to `keep_open`, it will not call `close` on
|
1687
1687
|
the stream object, allowing you to close it at any later point in the
|
1688
|
-
execution flow. This only works on evented servers, like
|
1688
|
+
execution flow. This only works on evented servers, like Rainbows.
|
1689
1689
|
Other servers will still close the stream:
|
1690
1690
|
|
1691
1691
|
```ruby
|
1692
|
-
#
|
1693
|
-
|
1694
|
-
set :server, :thin
|
1695
|
-
connections = []
|
1692
|
+
# config.ru
|
1693
|
+
require 'sinatra/base'
|
1696
1694
|
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
#
|
1702
|
-
|
1695
|
+
class App < Sinatra::Base
|
1696
|
+
connections = []
|
1697
|
+
|
1698
|
+
get '/subscribe', provides: 'text/event-stream' do
|
1699
|
+
# register a client's interest in server events
|
1700
|
+
stream(:keep_open) do |out|
|
1701
|
+
connections << out
|
1702
|
+
# purge dead connections
|
1703
|
+
connections.reject!(&:closed?)
|
1704
|
+
end
|
1703
1705
|
end
|
1704
|
-
end
|
1705
1706
|
|
1706
|
-
post '
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1707
|
+
post '/' do
|
1708
|
+
connections.each do |out|
|
1709
|
+
# notify client that a new message has arrived
|
1710
|
+
out << "data: #{params[:msg]}\n\n"
|
1711
|
+
|
1712
|
+
# indicate client to connect again
|
1713
|
+
out.close
|
1714
|
+
end
|
1710
1715
|
|
1711
|
-
#
|
1712
|
-
out.close
|
1716
|
+
204 # response without entity body
|
1713
1717
|
end
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
run App
|
1721
|
+
```
|
1714
1722
|
|
1715
|
-
|
1716
|
-
|
1723
|
+
```ruby
|
1724
|
+
# rainbows.conf
|
1725
|
+
Rainbows! do
|
1726
|
+
use :EventMachine
|
1717
1727
|
end
|
1728
|
+
````
|
1729
|
+
|
1730
|
+
Run:
|
1731
|
+
|
1732
|
+
```shell
|
1733
|
+
rainbows -c rainbows.conf
|
1718
1734
|
```
|
1719
1735
|
|
1720
1736
|
It's also possible for the client to close the connection when trying to
|
@@ -2264,6 +2280,15 @@ set :protection, :session => true
|
|
2264
2280
|
used for built-in server.
|
2265
2281
|
</dd>
|
2266
2282
|
|
2283
|
+
<dt>default_content_type</dt>
|
2284
|
+
<dd>
|
2285
|
+
Content-Type to assume if unknown (defaults to <tt>"text/html"</tt>). Set
|
2286
|
+
to <tt>nil</tt> to not set a default Content-Type on every response; when
|
2287
|
+
configured so, you must set the Content-Type manually when emitting content
|
2288
|
+
or the user-agent will have to sniff it (or, if <tt>nosniff</tt> is enabled
|
2289
|
+
in Rack::Protection::XSSHeader, assume <tt>application/octet-stream</tt>).
|
2290
|
+
</dd>
|
2291
|
+
|
2267
2292
|
<dt>default_encoding</dt>
|
2268
2293
|
<dd>Encoding to assume if unknown (defaults to <tt>"utf-8"</tt>).</dd>
|
2269
2294
|
|
@@ -2368,7 +2393,7 @@ set :protection, :session => true
|
|
2368
2393
|
If you are using a WEBrick web server, presumably for your development
|
2369
2394
|
environment, you can pass a hash of options to <tt>server_settings</tt>,
|
2370
2395
|
such as <tt>SSLEnable</tt> or <tt>SSLVerifyClient</tt>. However, web
|
2371
|
-
servers such as Puma
|
2396
|
+
servers such as Puma do not support this, so you can set
|
2372
2397
|
<tt>server_settings</tt> by defining it as a method when you call
|
2373
2398
|
<tt>configure</tt>.
|
2374
2399
|
</dd>
|
@@ -2419,7 +2444,7 @@ set :protection, :session => true
|
|
2419
2444
|
|
2420
2445
|
<dt>threaded</dt>
|
2421
2446
|
<dd>
|
2422
|
-
If set to <tt>true</tt>, will tell
|
2447
|
+
If set to <tt>true</tt>, will tell server to use
|
2423
2448
|
<tt>EventMachine.defer</tt> for processing the request.
|
2424
2449
|
</dd>
|
2425
2450
|
|
@@ -3008,7 +3033,7 @@ Options are:
|
|
3008
3033
|
-p # set the port (default is 4567)
|
3009
3034
|
-o # set the host (default is 0.0.0.0)
|
3010
3035
|
-e # set the environment (default is development)
|
3011
|
-
-s # specify rack server/handler (default is
|
3036
|
+
-s # specify rack server/handler (default is puma)
|
3012
3037
|
-q # turn on quiet mode for server (default is off)
|
3013
3038
|
-x # turn on the mutex lock (default is off)
|
3014
3039
|
```
|
@@ -3020,15 +3045,15 @@ _Paraphrasing from
|
|
3020
3045
|
by Konstantin_
|
3021
3046
|
|
3022
3047
|
Sinatra doesn't impose any concurrency model, but leaves that to the
|
3023
|
-
underlying Rack handler (server) like
|
3048
|
+
underlying Rack handler (server) like Puma or WEBrick. Sinatra
|
3024
3049
|
itself is thread-safe, so there won't be any problem if the Rack handler
|
3025
3050
|
uses a threaded model of concurrency. This would mean that when starting
|
3026
3051
|
the server, you'd have to specify the correct invocation method for the
|
3027
3052
|
specific Rack handler. The following example is a demonstration of how
|
3028
|
-
to start a multi-threaded
|
3053
|
+
to start a multi-threaded Rainbows server:
|
3029
3054
|
|
3030
3055
|
```ruby
|
3031
|
-
#
|
3056
|
+
# config.ru
|
3032
3057
|
|
3033
3058
|
require 'sinatra/base'
|
3034
3059
|
|
@@ -3038,23 +3063,31 @@ class App < Sinatra::Base
|
|
3038
3063
|
end
|
3039
3064
|
end
|
3040
3065
|
|
3041
|
-
App
|
3066
|
+
run App
|
3067
|
+
```
|
3042
3068
|
|
3069
|
+
```ruby
|
3070
|
+
# rainbows.conf
|
3071
|
+
|
3072
|
+
# Rainbows configurator is based on Unicorn.
|
3073
|
+
Rainbows! do
|
3074
|
+
use :ThreadSpawn
|
3075
|
+
end
|
3043
3076
|
```
|
3044
3077
|
|
3045
3078
|
To start the server, the command would be:
|
3046
3079
|
|
3047
3080
|
```shell
|
3048
|
-
|
3081
|
+
rainbows -c rainbows.conf
|
3049
3082
|
```
|
3050
3083
|
|
3051
3084
|
## Requirement
|
3052
3085
|
|
3053
3086
|
The following Ruby versions are officially supported:
|
3054
3087
|
<dl>
|
3055
|
-
<dt>Ruby 2.
|
3088
|
+
<dt>Ruby 2.3</dt>
|
3056
3089
|
<dd>
|
3057
|
-
2.
|
3090
|
+
2.3 is fully supported and recommended. There are currently no plans to
|
3058
3091
|
drop official support for it.
|
3059
3092
|
</dd>
|
3060
3093
|
|
@@ -3072,7 +3105,7 @@ The following Ruby versions are officially supported:
|
|
3072
3105
|
</dd>
|
3073
3106
|
</dl>
|
3074
3107
|
|
3075
|
-
Versions of Ruby prior to 2.
|
3108
|
+
Versions of Ruby prior to 2.3 are no longer supported as of Sinatra 2.1.0.
|
3076
3109
|
|
3077
3110
|
We also keep an eye on upcoming Ruby versions.
|
3078
3111
|
|
data/README.pt-br.md
CHANGED
@@ -444,7 +444,7 @@ Arquivos estáticos são disponibilizados a partir do diretório
|
|
444
444
|
`:public_folder`
|
445
445
|
|
446
446
|
```ruby
|
447
|
-
set :public_folder,
|
447
|
+
set :public_folder, __dir__ + '/estatico'
|
448
448
|
```
|
449
449
|
|
450
450
|
Note que o nome do diretório público não é incluido na URL. Um arquivo
|
data/README.pt-pt.md
CHANGED
@@ -121,7 +121,7 @@ Arquivos estáticos são disponibilizados a partir do directório
|
|
121
121
|
`:public_folder`
|
122
122
|
|
123
123
|
```ruby
|
124
|
-
set :public_folder,
|
124
|
+
set :public_folder, __dir__ + '/estatico'
|
125
125
|
```
|
126
126
|
|
127
127
|
Note que o nome do directório público não é incluido no URL. Um arquivo
|
@@ -134,7 +134,7 @@ Templates presumem-se estar localizados sob o directório `./views`. Para
|
|
134
134
|
utilizar um directório de views diferente:
|
135
135
|
|
136
136
|
```ruby
|
137
|
-
set :views,
|
137
|
+
set :views, __dir__ + '/modelo'
|
138
138
|
```
|
139
139
|
|
140
140
|
Uma coisa importante a ser lembrada é que você sempre tem as referências
|
@@ -757,7 +757,7 @@ Alternativamente, pode adicionar o directório do `sinatra/lib` no
|
|
757
757
|
`LOAD_PATH` do seu aplicativo:
|
758
758
|
|
759
759
|
```ruby
|
760
|
-
$LOAD_PATH.unshift
|
760
|
+
$LOAD_PATH.unshift __dir__ + '/sinatra/lib'
|
761
761
|
require 'rubygems'
|
762
762
|
require 'sinatra'
|
763
763
|
|
data/README.ru.md
CHANGED
@@ -431,7 +431,7 @@ end
|
|
431
431
|
месторасположение при помощи опции `:public_folder`:
|
432
432
|
|
433
433
|
```ruby
|
434
|
-
set :public_folder,
|
434
|
+
set :public_folder, __dir__ + '/static'
|
435
435
|
```
|
436
436
|
|
437
437
|
Учтите, что имя директории со статическими файлами не включено в URL.
|
@@ -3089,9 +3089,9 @@ thin --threaded start
|
|
3089
3089
|
|
3090
3090
|
Следующие версии Ruby официально поддерживаются:
|
3091
3091
|
<dl>
|
3092
|
-
<dt>Ruby 2.
|
3092
|
+
<dt>Ruby 2.3</dt>
|
3093
3093
|
<dd>
|
3094
|
-
Версия 2.
|
3094
|
+
Версия 2.3 полностью поддерживается и рекомендуется. В настоящее время нет
|
3095
3095
|
планов отказаться от официальной поддержки.
|
3096
3096
|
</dd>
|
3097
3097
|
|
data/README.zh.md
CHANGED
@@ -393,7 +393,7 @@ end
|
|
393
393
|
静态文件从 `./public` 目录提供服务。可以通过设置`:public_folder` 选项设定一个不同的位置:
|
394
394
|
|
395
395
|
```ruby
|
396
|
-
set :public_folder,
|
396
|
+
set :public_folder, __dir__ + '/static'
|
397
397
|
```
|
398
398
|
|
399
399
|
请注意 public 目录名并没有包含在 URL 中。文件 `./public/css/style.css` 可以通过
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0
|
1
|
+
2.1.0
|
data/examples/chat.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rainbows'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module Handler
|
5
|
+
class Rainbows
|
6
|
+
def self.run(app, **options)
|
7
|
+
rainbows_options = {
|
8
|
+
listeners: ["#{options[:Host]}:#{options[:Port]}"],
|
9
|
+
worker_processes: 1,
|
10
|
+
timeout: 30,
|
11
|
+
config_file: ::File.expand_path('rainbows.conf', __dir__),
|
12
|
+
}
|
13
|
+
|
14
|
+
::Rainbows::HttpServer.new(app, rainbows_options).start.join
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
register :rainbows, ::Rack::Handler::Rainbows
|
19
|
+
end
|
20
|
+
end
|
data/examples/stream.ru
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
#
|
3
3
|
# run *one* of these:
|
4
4
|
#
|
5
|
-
# rackup -s mongrel stream.ru
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
5
|
+
# rackup -s mongrel stream.ru # gem install mongrel
|
6
|
+
# unicorn stream.ru # gem install unicorn
|
7
|
+
# puma stream.ru # gem install puma
|
8
|
+
# rainbows -c rainbows.conf stream.ru # gem install rainbows eventmachine
|
9
9
|
|
10
10
|
require 'sinatra/base'
|
11
11
|
|
data/lib/sinatra/base.rb
CHANGED
@@ -43,12 +43,11 @@ module Sinatra
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def preferred_type(*types)
|
46
|
-
|
47
|
-
return accepts.first if types.empty?
|
46
|
+
return accept.first if types.empty?
|
48
47
|
types.flatten!
|
49
|
-
return types.first if
|
50
|
-
|
51
|
-
type = types.detect { |t|
|
48
|
+
return types.first if accept.empty?
|
49
|
+
accept.detect do |accept_header|
|
50
|
+
type = types.detect { |t| MimeTypeEntry.new(t).accepts?(accept_header) }
|
52
51
|
return type if type
|
53
52
|
end
|
54
53
|
end
|
@@ -81,8 +80,6 @@ module Sinatra
|
|
81
80
|
raise BadRequest, "Invalid query parameters: #{Rack::Utils.escape_html(e.message)}"
|
82
81
|
end
|
83
82
|
|
84
|
-
private
|
85
|
-
|
86
83
|
class AcceptEntry
|
87
84
|
attr_accessor :params
|
88
85
|
attr_reader :entry
|
@@ -125,6 +122,35 @@ module Sinatra
|
|
125
122
|
to_str.send(*args, &block)
|
126
123
|
end
|
127
124
|
end
|
125
|
+
|
126
|
+
class MimeTypeEntry
|
127
|
+
attr_reader :params
|
128
|
+
|
129
|
+
def initialize(entry)
|
130
|
+
params = entry.scan(HEADER_PARAM).map! do |s|
|
131
|
+
key, value = s.strip.split('=', 2)
|
132
|
+
value = value[1..-2].gsub(/\\(.)/, '\1') if value.start_with?('"')
|
133
|
+
[key, value]
|
134
|
+
end
|
135
|
+
|
136
|
+
@type = entry[/[^;]+/].delete(' ')
|
137
|
+
@params = Hash[params]
|
138
|
+
end
|
139
|
+
|
140
|
+
def accepts?(entry)
|
141
|
+
File.fnmatch(entry, self) && matches_params?(entry.params)
|
142
|
+
end
|
143
|
+
|
144
|
+
def to_str
|
145
|
+
@type
|
146
|
+
end
|
147
|
+
|
148
|
+
def matches_params?(params)
|
149
|
+
return true if @params.empty?
|
150
|
+
|
151
|
+
params.all? { |k,v| !@params.has_key?(k) || @params[k] == v }
|
152
|
+
end
|
153
|
+
end
|
128
154
|
end
|
129
155
|
|
130
156
|
# The response object. See Rack::Response and Rack::Response::Helpers for
|
@@ -133,10 +159,6 @@ module Sinatra
|
|
133
159
|
# http://rubydoc.info/github/rack/rack/master/Rack/Response/Helpers
|
134
160
|
class Response < Rack::Response
|
135
161
|
DROP_BODY_RESPONSES = [204, 304]
|
136
|
-
def initialize(*)
|
137
|
-
super
|
138
|
-
headers['Content-Type'] ||= 'text/html'
|
139
|
-
end
|
140
162
|
|
141
163
|
def body=(value)
|
142
164
|
value = value.body while Rack::Response === value
|
@@ -163,7 +185,7 @@ module Sinatra
|
|
163
185
|
if calculate_content_length?
|
164
186
|
# if some other code has already set Content-Length, don't muck with it
|
165
187
|
# currently, this would be the static file-handler
|
166
|
-
headers["Content-Length"] = body.
|
188
|
+
headers["Content-Length"] = body.map(&:bytesize).reduce(0, :+).to_s
|
167
189
|
end
|
168
190
|
|
169
191
|
[status.to_i, headers, result]
|
@@ -184,7 +206,7 @@ module Sinatra
|
|
184
206
|
end
|
185
207
|
end
|
186
208
|
|
187
|
-
# Some Rack handlers (
|
209
|
+
# Some Rack handlers (Rainbows!) implement an extended body object protocol, however,
|
188
210
|
# some middleware (namely Rack::Lint) will break it by not mirroring the methods in question.
|
189
211
|
# This middleware will detect an extended body object and will make sure it reaches the
|
190
212
|
# handler directly. We do this here, so our middleware and middleware set up by the app will
|
@@ -451,7 +473,7 @@ module Sinatra
|
|
451
473
|
#
|
452
474
|
# The close parameter specifies whether Stream#close should be called
|
453
475
|
# after the block has been executed. This is only relevant for evented
|
454
|
-
# servers like
|
476
|
+
# servers like Rainbows.
|
455
477
|
def stream(keep_open = false)
|
456
478
|
scheduler = env['async.callback'] ? EventMachine : Stream
|
457
479
|
current = @params.dup
|
@@ -647,8 +669,6 @@ module Sinatra
|
|
647
669
|
end
|
648
670
|
end
|
649
671
|
|
650
|
-
private
|
651
|
-
|
652
672
|
# Template rendering methods. Each method takes the name of a template
|
653
673
|
# to render as a Symbol and returns a String with the rendered output,
|
654
674
|
# as well as an optional hash with additional options.
|
@@ -900,6 +920,7 @@ module Sinatra
|
|
900
920
|
super()
|
901
921
|
@app = app
|
902
922
|
@template_cache = Tilt::Cache.new
|
923
|
+
@pinned_response = nil # whether a before! filter pinned the content-type
|
903
924
|
yield self if block_given?
|
904
925
|
end
|
905
926
|
|
@@ -915,15 +936,14 @@ module Sinatra
|
|
915
936
|
@response = Response.new
|
916
937
|
template_cache.clear if settings.reload_templates
|
917
938
|
|
918
|
-
@response['Content-Type'] = nil
|
919
939
|
invoke { dispatch! }
|
920
940
|
invoke { error_block!(response.status) } unless @env['sinatra.error']
|
921
941
|
|
922
942
|
unless @response['Content-Type']
|
923
|
-
if Array === body
|
943
|
+
if Array === body && body[0].respond_to?(:content_type)
|
924
944
|
content_type body[0].content_type
|
925
|
-
|
926
|
-
content_type
|
945
|
+
elsif default = settings.default_content_type
|
946
|
+
content_type default
|
927
947
|
end
|
928
948
|
end
|
929
949
|
|
@@ -973,15 +993,21 @@ module Sinatra
|
|
973
993
|
private
|
974
994
|
|
975
995
|
# Run filters defined on the class and all superclasses.
|
996
|
+
# Accepts an optional block to call after each filter is applied.
|
976
997
|
def filter!(type, base = settings)
|
977
998
|
filter! type, base.superclass if base.superclass.respond_to?(:filters)
|
978
|
-
base.filters[type].each
|
999
|
+
base.filters[type].each do |args|
|
1000
|
+
result = process_route(*args)
|
1001
|
+
yield result if block_given?
|
1002
|
+
end
|
979
1003
|
end
|
980
1004
|
|
981
1005
|
# Run routes defined on the class and all superclasses.
|
982
1006
|
def route!(base = settings, pass_block = nil)
|
983
1007
|
if routes = base.routes[@request.request_method]
|
984
1008
|
routes.each do |pattern, conditions, block|
|
1009
|
+
@response.delete_header('Content-Type') unless @pinned_response
|
1010
|
+
|
985
1011
|
returned_pass_block = process_route(pattern, conditions) do |*args|
|
986
1012
|
env['sinatra.route'] = "#{@request.request_method} #{pattern}"
|
987
1013
|
route_eval { block[*args] }
|
@@ -1059,7 +1085,10 @@ module Sinatra
|
|
1059
1085
|
# a matching file is found, returns nil otherwise.
|
1060
1086
|
def static!(options = {})
|
1061
1087
|
return if (public_dir = settings.public_folder).nil?
|
1062
|
-
path =
|
1088
|
+
path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}"
|
1089
|
+
return unless valid_path?(path)
|
1090
|
+
|
1091
|
+
path = File.expand_path(path)
|
1063
1092
|
return unless File.file?(path)
|
1064
1093
|
|
1065
1094
|
env['sinatra.static_file'] = path
|
@@ -1094,7 +1123,9 @@ module Sinatra
|
|
1094
1123
|
|
1095
1124
|
invoke do
|
1096
1125
|
static! if settings.static? && (request.get? || request.head?)
|
1097
|
-
filter! :before
|
1126
|
+
filter! :before do
|
1127
|
+
@pinned_response = !@response['Content-Type'].nil?
|
1128
|
+
end
|
1098
1129
|
route!
|
1099
1130
|
end
|
1100
1131
|
rescue ::Exception => boom
|
@@ -1124,19 +1155,27 @@ module Sinatra
|
|
1124
1155
|
|
1125
1156
|
status(500) unless status.between? 400, 599
|
1126
1157
|
|
1127
|
-
boom_message = boom.message if boom.message && boom.message != boom.class.name
|
1128
1158
|
if server_error?
|
1129
1159
|
dump_errors! boom if settings.dump_errors?
|
1130
1160
|
raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
|
1131
1161
|
elsif not_found?
|
1132
1162
|
headers['X-Cascade'] = 'pass' if settings.x_cascade?
|
1133
|
-
body boom_message || '<h1>Not Found</h1>'
|
1134
|
-
elsif bad_request?
|
1135
|
-
body boom_message || '<h1>Bad Request</h1>'
|
1136
1163
|
end
|
1137
1164
|
|
1138
|
-
res = error_block!(boom.class, boom) || error_block!(status, boom)
|
1139
|
-
|
1165
|
+
if res = error_block!(boom.class, boom) || error_block!(status, boom)
|
1166
|
+
return res
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
if not_found? || bad_request?
|
1170
|
+
if boom.message && boom.message != boom.class.name
|
1171
|
+
body boom.message
|
1172
|
+
else
|
1173
|
+
content_type 'text/html'
|
1174
|
+
body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>'
|
1175
|
+
end
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
return unless server_error?
|
1140
1179
|
raise boom if settings.raise_errors? or settings.show_exceptions?
|
1141
1180
|
error_block! Exception, boom
|
1142
1181
|
end
|
@@ -1403,7 +1442,7 @@ module Sinatra
|
|
1403
1442
|
# in `extensions` available to the handlers and templates
|
1404
1443
|
def helpers(*extensions, &block)
|
1405
1444
|
class_eval(&block) if block_given?
|
1406
|
-
|
1445
|
+
prepend(*extensions) if extensions.any?
|
1407
1446
|
end
|
1408
1447
|
|
1409
1448
|
# Register an extension. Alternatively take a block from which an
|
@@ -1446,7 +1485,7 @@ module Sinatra
|
|
1446
1485
|
alias_method :stop!, :quit!
|
1447
1486
|
|
1448
1487
|
# Run the Sinatra app as a self-hosted server using
|
1449
|
-
#
|
1488
|
+
# Puma, Mongrel, or WEBrick (in that order). If given a block, will call
|
1450
1489
|
# with the constructed handler once we have taken the stage.
|
1451
1490
|
def run!(options = {}, &block)
|
1452
1491
|
return if running?
|
@@ -1523,7 +1562,7 @@ module Sinatra
|
|
1523
1562
|
# behavior, by ensuring an instance exists:
|
1524
1563
|
prototype
|
1525
1564
|
# Run the instance we created:
|
1526
|
-
handler.run(self, server_settings) do |server|
|
1565
|
+
handler.run(self, **server_settings) do |server|
|
1527
1566
|
unless suppress_messages?
|
1528
1567
|
$stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}"
|
1529
1568
|
end
|
@@ -1777,6 +1816,7 @@ module Sinatra
|
|
1777
1816
|
set :add_charset, %w[javascript xml xhtml+xml].map { |t| "application/#{t}" }
|
1778
1817
|
settings.add_charset << /^text\//
|
1779
1818
|
set :mustermann_opts, {}
|
1819
|
+
set :default_content_type, 'text/html'
|
1780
1820
|
|
1781
1821
|
# explicitly generating a session secret eagerly to play nice with preforking
|
1782
1822
|
begin
|
@@ -1837,7 +1877,7 @@ module Sinatra
|
|
1837
1877
|
|
1838
1878
|
configure :development do
|
1839
1879
|
get '/__sinatra__/:image.png' do
|
1840
|
-
filename =
|
1880
|
+
filename = __dir__ + "/images/#{params[:image].to_i}.png"
|
1841
1881
|
content_type :png
|
1842
1882
|
send_file filename
|
1843
1883
|
end
|