sinatra 1.4.8 → 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 +5 -5
- data/AUTHORS.md +1 -0
- data/CHANGELOG.md +272 -54
- data/CONTRIBUTING.md +8 -8
- data/Gemfile +48 -47
- data/LICENSE +4 -1
- data/MAINTENANCE.md +42 -0
- data/README.de.md +651 -443
- data/README.es.md +738 -357
- data/README.fr.md +197 -100
- data/README.hu.md +40 -6
- data/README.ja.md +125 -67
- data/README.ko.md +15 -15
- data/README.malayalam.md +3141 -0
- data/README.md +592 -432
- data/README.pt-br.md +2362 -335
- data/README.pt-pt.md +5 -5
- data/README.ru.md +857 -608
- data/README.zh.md +91 -29
- data/Rakefile +77 -51
- data/SECURITY.md +35 -0
- data/VERSION +1 -0
- 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 +243 -265
- data/lib/sinatra/indifferent_hash.rb +200 -0
- data/lib/sinatra/main.rb +30 -10
- data/lib/sinatra/show_exceptions.rb +67 -62
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +44 -8
- metadata +43 -167
- data/lib/sinatra/ext.rb +0 -17
- data/test/asciidoctor_test.rb +0 -72
- data/test/base_test.rb +0 -167
- data/test/builder_test.rb +0 -91
- data/test/coffee_test.rb +0 -96
- data/test/compile_test.rb +0 -183
- data/test/contest.rb +0 -91
- data/test/creole_test.rb +0 -65
- data/test/delegator_test.rb +0 -160
- data/test/encoding_test.rb +0 -20
- data/test/erb_test.rb +0 -116
- data/test/extensions_test.rb +0 -98
- data/test/filter_test.rb +0 -487
- data/test/haml_test.rb +0 -109
- data/test/helper.rb +0 -132
- data/test/helpers_test.rb +0 -1917
- data/test/integration/app.rb +0 -79
- data/test/integration_helper.rb +0 -236
- data/test/integration_test.rb +0 -104
- data/test/less_test.rb +0 -69
- data/test/liquid_test.rb +0 -77
- data/test/mapped_error_test.rb +0 -285
- data/test/markaby_test.rb +0 -80
- data/test/markdown_test.rb +0 -85
- data/test/mediawiki_test.rb +0 -68
- data/test/middleware_test.rb +0 -68
- data/test/nokogiri_test.rb +0 -67
- data/test/public/favicon.ico +0 -0
- data/test/public/hello+world.txt +0 -1
- data/test/rabl_test.rb +0 -89
- data/test/rack_test.rb +0 -45
- data/test/radius_test.rb +0 -59
- data/test/rdoc_test.rb +0 -66
- data/test/readme_test.rb +0 -130
- data/test/request_test.rb +0 -100
- data/test/response_test.rb +0 -63
- data/test/result_test.rb +0 -76
- data/test/route_added_hook_test.rb +0 -59
- data/test/routing_test.rb +0 -1456
- data/test/sass_test.rb +0 -115
- data/test/scss_test.rb +0 -88
- data/test/server_test.rb +0 -56
- data/test/settings_test.rb +0 -582
- data/test/sinatra_test.rb +0 -12
- data/test/slim_test.rb +0 -102
- data/test/static_test.rb +0 -266
- data/test/streaming_test.rb +0 -149
- data/test/stylus_test.rb +0 -90
- data/test/templates_test.rb +0 -382
- data/test/textile_test.rb +0 -65
- data/test/views/a/in_a.str +0 -1
- data/test/views/ascii.erb +0 -2
- data/test/views/b/in_b.str +0 -1
- data/test/views/calc.html.erb +0 -1
- data/test/views/error.builder +0 -3
- data/test/views/error.erb +0 -3
- data/test/views/error.haml +0 -3
- data/test/views/error.sass +0 -2
- data/test/views/explicitly_nested.str +0 -1
- data/test/views/foo/hello.test +0 -1
- data/test/views/hello.asciidoc +0 -1
- data/test/views/hello.builder +0 -1
- data/test/views/hello.coffee +0 -1
- data/test/views/hello.creole +0 -1
- data/test/views/hello.erb +0 -1
- data/test/views/hello.haml +0 -1
- data/test/views/hello.less +0 -5
- data/test/views/hello.liquid +0 -1
- data/test/views/hello.mab +0 -1
- data/test/views/hello.md +0 -1
- data/test/views/hello.mediawiki +0 -1
- data/test/views/hello.nokogiri +0 -1
- data/test/views/hello.rabl +0 -2
- data/test/views/hello.radius +0 -1
- data/test/views/hello.rdoc +0 -1
- data/test/views/hello.sass +0 -2
- data/test/views/hello.scss +0 -3
- data/test/views/hello.slim +0 -1
- data/test/views/hello.str +0 -1
- data/test/views/hello.styl +0 -2
- data/test/views/hello.test +0 -1
- data/test/views/hello.textile +0 -1
- data/test/views/hello.wlang +0 -1
- data/test/views/hello.yajl +0 -1
- data/test/views/layout2.builder +0 -3
- data/test/views/layout2.erb +0 -2
- data/test/views/layout2.haml +0 -2
- data/test/views/layout2.liquid +0 -2
- data/test/views/layout2.mab +0 -2
- data/test/views/layout2.nokogiri +0 -3
- data/test/views/layout2.rabl +0 -3
- data/test/views/layout2.radius +0 -2
- data/test/views/layout2.slim +0 -3
- data/test/views/layout2.str +0 -2
- data/test/views/layout2.test +0 -1
- data/test/views/layout2.wlang +0 -2
- data/test/views/nested.str +0 -1
- data/test/views/utf8.erb +0 -2
- data/test/wlang_test.rb +0 -87
- data/test/yajl_test.rb +0 -86
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Sinatra
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/sinatra.svg)](http://badge.fury.io/rb/sinatra)
|
4
|
+
[![Build Status](https://secure.travis-ci.org/sinatra/sinatra.svg)](https://travis-ci.org/sinatra/sinatra)
|
5
|
+
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sinatra&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sinatra&package-manager=bundler&version-scheme=semver)
|
6
|
+
|
3
7
|
Sinatra is a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for
|
4
8
|
quickly creating web applications in Ruby with minimal effort:
|
5
9
|
|
@@ -26,7 +30,11 @@ ruby myapp.rb
|
|
26
30
|
|
27
31
|
View at: [http://localhost:4567](http://localhost:4567)
|
28
32
|
|
29
|
-
|
33
|
+
The code you changed will not take effect until you restart the server.
|
34
|
+
Please restart the server every time you change or use
|
35
|
+
[sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
|
36
|
+
|
37
|
+
It is recommended to also run `gem install puma`, which Sinatra will
|
30
38
|
pick up if available.
|
31
39
|
|
32
40
|
## Table of Contents
|
@@ -73,6 +81,9 @@ pick up if available.
|
|
73
81
|
* [Filters](#filters)
|
74
82
|
* [Helpers](#helpers)
|
75
83
|
* [Using Sessions](#using-sessions)
|
84
|
+
* [Session Secret Security](#session-secret-security)
|
85
|
+
* [Session Config](#session-config)
|
86
|
+
* [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
|
76
87
|
* [Halting](#halting)
|
77
88
|
* [Passing](#passing)
|
78
89
|
* [Triggering Another Route](#triggering-another-route)
|
@@ -113,8 +124,6 @@ pick up if available.
|
|
113
124
|
* [Requirement](#requirement)
|
114
125
|
* [The Bleeding Edge](#the-bleeding-edge)
|
115
126
|
* [With Bundler](#with-bundler)
|
116
|
-
* [Roll Your Own](#roll-your-own)
|
117
|
-
* [Install Globally](#install-globally)
|
118
127
|
* [Versioning](#versioning)
|
119
128
|
* [Further Reading](#further-reading)
|
120
129
|
|
@@ -160,6 +169,14 @@ end
|
|
160
169
|
Routes are matched in the order they are defined. The first route that
|
161
170
|
matches the request is invoked.
|
162
171
|
|
172
|
+
Routes with trailing slashes are different from the ones without:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
get '/foo' do
|
176
|
+
# Does not match "GET /foo/"
|
177
|
+
end
|
178
|
+
```
|
179
|
+
|
163
180
|
Route patterns may include named parameters, accessible via the
|
164
181
|
`params` hash:
|
165
182
|
|
@@ -208,7 +225,7 @@ end
|
|
208
225
|
Route matching with Regular Expressions:
|
209
226
|
|
210
227
|
```ruby
|
211
|
-
get
|
228
|
+
get /\/hello\/([\w]+)/ do
|
212
229
|
"Hello, #{params['captures'].first}!"
|
213
230
|
end
|
214
231
|
```
|
@@ -241,8 +258,23 @@ get '/posts' do
|
|
241
258
|
end
|
242
259
|
```
|
243
260
|
|
244
|
-
By the way, unless you disable the path traversal attack protection (see
|
245
|
-
the request path might be modified before
|
261
|
+
By the way, unless you disable the path traversal attack protection (see
|
262
|
+
[below](#configuring-attack-protection)), the request path might be modified before
|
263
|
+
matching against your routes.
|
264
|
+
|
265
|
+
You may customize the [Mustermann](https://github.com/sinatra/mustermann#readme)
|
266
|
+
options used for a given route by passing in a `:mustermann_opts` hash:
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
get '\A/posts\z', :mustermann_opts => { :type => :regexp, :check_anchors => false } do
|
270
|
+
# matches /posts exactly, with explicit anchoring
|
271
|
+
"If you match an anchored pattern clap your hands!"
|
272
|
+
end
|
273
|
+
```
|
274
|
+
|
275
|
+
It looks like a [condition](#conditions), but it isn't one! These options will
|
276
|
+
be merged into the global `:mustermann_opts` hash described
|
277
|
+
[below](#available-settings).
|
246
278
|
|
247
279
|
## Conditions
|
248
280
|
|
@@ -311,21 +343,21 @@ end
|
|
311
343
|
|
312
344
|
## Return Values
|
313
345
|
|
314
|
-
The return value of a route block determines at least the response body
|
315
|
-
on to the HTTP client, or at least the next middleware in the
|
316
|
-
Most commonly, this is a string, as in the above examples.
|
317
|
-
also accepted.
|
346
|
+
The return value of a route block determines at least the response body
|
347
|
+
passed on to the HTTP client, or at least the next middleware in the
|
348
|
+
Rack stack. Most commonly, this is a string, as in the above examples.
|
349
|
+
But other values are also accepted.
|
318
350
|
|
319
351
|
You can return any object that would either be a valid Rack response, Rack
|
320
352
|
body object or HTTP status code:
|
321
353
|
|
322
|
-
* An Array with three elements: `[status (
|
354
|
+
* An Array with three elements: `[status (Integer), headers (Hash), response
|
323
355
|
body (responds to #each)]`
|
324
|
-
* An Array with two elements: `[status (
|
356
|
+
* An Array with two elements: `[status (Integer), response body (responds to
|
325
357
|
#each)]`
|
326
358
|
* An object that responds to `#each` and passes nothing but strings to
|
327
359
|
the given block
|
328
|
-
* A
|
360
|
+
* A Integer representing the status code
|
329
361
|
|
330
362
|
That way we can, for instance, easily implement a streaming example:
|
331
363
|
|
@@ -339,14 +371,14 @@ end
|
|
339
371
|
get('/') { Stream.new }
|
340
372
|
```
|
341
373
|
|
342
|
-
You can also use the `stream` helper method (described below) to reduce
|
343
|
-
plate and embed the streaming logic in the route.
|
374
|
+
You can also use the `stream` helper method ([described below](#streaming-responses)) to reduce
|
375
|
+
boiler plate and embed the streaming logic in the route.
|
344
376
|
|
345
377
|
## Custom Route Matchers
|
346
378
|
|
347
|
-
As shown above, Sinatra ships with built-in support for using String
|
348
|
-
and regular expressions as route matches. However, it does not
|
349
|
-
can easily define your own matchers:
|
379
|
+
As shown above, Sinatra ships with built-in support for using String
|
380
|
+
patterns and regular expressions as route matches. However, it does not
|
381
|
+
stop there. You can easily define your own matchers:
|
350
382
|
|
351
383
|
```ruby
|
352
384
|
class AllButPattern
|
@@ -384,7 +416,7 @@ end
|
|
384
416
|
Or, using negative look ahead:
|
385
417
|
|
386
418
|
```ruby
|
387
|
-
get %r{
|
419
|
+
get %r{(?!/index)} do
|
388
420
|
# ...
|
389
421
|
end
|
390
422
|
```
|
@@ -395,14 +427,14 @@ Static files are served from the `./public` directory. You can specify
|
|
395
427
|
a different location by setting the `:public_folder` option:
|
396
428
|
|
397
429
|
```ruby
|
398
|
-
set :public_folder,
|
430
|
+
set :public_folder, __dir__ + '/static'
|
399
431
|
```
|
400
432
|
|
401
433
|
Note that the public directory name is not included in the URL. A file
|
402
434
|
`./public/css/style.css` is made available as
|
403
435
|
`http://example.com/css/style.css`.
|
404
436
|
|
405
|
-
Use the `:static_cache_control` setting (see below) to add
|
437
|
+
Use the `:static_cache_control` setting (see [below](#cache-control)) to add
|
406
438
|
`Cache-Control` header info.
|
407
439
|
|
408
440
|
## Views / Templates
|
@@ -494,15 +526,17 @@ Available Options:
|
|
494
526
|
|
495
527
|
<dt>scope</dt>
|
496
528
|
<dd>
|
497
|
-
Scope to render template under. Defaults to the application
|
498
|
-
change this, instance variables and helper methods
|
529
|
+
Scope to render template under. Defaults to the application
|
530
|
+
instance. If you change this, instance variables and helper methods
|
531
|
+
will not be available.
|
499
532
|
</dd>
|
500
533
|
|
501
534
|
<dt>layout_engine</dt>
|
502
535
|
<dd>
|
503
|
-
Template engine to use for rendering the layout. Useful for
|
504
|
-
do not support layouts otherwise. Defaults to the
|
505
|
-
template. Example: <tt>set :rdoc, :layout_engine
|
536
|
+
Template engine to use for rendering the layout. Useful for
|
537
|
+
languages that do not support layouts otherwise. Defaults to the
|
538
|
+
engine used for the template. Example: <tt>set :rdoc, :layout_engine
|
539
|
+
=> :erb</tt>
|
506
540
|
</dd>
|
507
541
|
|
508
542
|
<dt>layout_options</dt>
|
@@ -512,19 +546,19 @@ Available Options:
|
|
512
546
|
</dd>
|
513
547
|
</dl>
|
514
548
|
|
515
|
-
Templates are assumed to be located directly under the `./views`
|
516
|
-
use a different views directory:
|
549
|
+
Templates are assumed to be located directly under the `./views`
|
550
|
+
directory. To use a different views directory:
|
517
551
|
|
518
552
|
```ruby
|
519
553
|
set :views, settings.root + '/templates'
|
520
554
|
```
|
521
555
|
|
522
556
|
|
523
|
-
One important thing to remember is that you always have to reference
|
524
|
-
with symbols, even if they're in a subdirectory (in this case,
|
525
|
-
`:'subdir/template'` or `'subdir/template'.to_sym`). You must use a
|
526
|
-
because otherwise rendering methods will render any strings
|
527
|
-
directly.
|
557
|
+
One important thing to remember is that you always have to reference
|
558
|
+
templates with symbols, even if they're in a subdirectory (in this case,
|
559
|
+
use: `:'subdir/template'` or `'subdir/template'.to_sym`). You must use a
|
560
|
+
symbol because otherwise rendering methods will render any strings
|
561
|
+
passed to them directly.
|
528
562
|
|
529
563
|
### Literal Templates
|
530
564
|
|
@@ -534,7 +568,15 @@ get '/' do
|
|
534
568
|
end
|
535
569
|
```
|
536
570
|
|
537
|
-
Renders the template string.
|
571
|
+
Renders the template string. You can optionally specify `:path` and
|
572
|
+
`:line` for a clearer backtrace if there is a filesystem path or line
|
573
|
+
associated with that string:
|
574
|
+
|
575
|
+
```ruby
|
576
|
+
get '/' do
|
577
|
+
haml '%div.title Hello World', :path => 'examples/file.haml', :line => 3
|
578
|
+
end
|
579
|
+
```
|
538
580
|
|
539
581
|
### Available Template Languages
|
540
582
|
|
@@ -569,13 +611,15 @@ get('/') { markdown :index }
|
|
569
611
|
<tr>
|
570
612
|
<td>Dependency</td>
|
571
613
|
<td>
|
572
|
-
<a href="
|
614
|
+
<a href="https://github.com/jeremyevans/erubi" title="erubi">erubi</a>
|
615
|
+
or <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
|
573
616
|
or erb (included in Ruby)
|
574
617
|
</td>
|
575
618
|
</tr>
|
576
619
|
<tr>
|
577
620
|
<td>File Extensions</td>
|
578
|
-
<td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.
|
621
|
+
<td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubi</tt> (Erubi only)
|
622
|
+
or <tt>.erubis</tt> (Erubis only)</td>
|
579
623
|
</tr>
|
580
624
|
<tr>
|
581
625
|
<td>Example</td>
|
@@ -602,7 +646,7 @@ get('/') { markdown :index }
|
|
602
646
|
</tr>
|
603
647
|
</table>
|
604
648
|
|
605
|
-
It also takes a block for inline templates (see example).
|
649
|
+
It also takes a block for inline templates (see [example](#inline-templates)).
|
606
650
|
|
607
651
|
#### Nokogiri Templates
|
608
652
|
|
@@ -621,14 +665,14 @@ It also takes a block for inline templates (see example).
|
|
621
665
|
</tr>
|
622
666
|
</table>
|
623
667
|
|
624
|
-
It also takes a block for inline templates (see example).
|
668
|
+
It also takes a block for inline templates (see [example](#inline-templates)).
|
625
669
|
|
626
670
|
#### Sass Templates
|
627
671
|
|
628
672
|
<table>
|
629
673
|
<tr>
|
630
674
|
<td>Dependency</td>
|
631
|
-
<td><a href="
|
675
|
+
<td><a href="https://sass-lang.com/" title="sass">sass</a></td>
|
632
676
|
</tr>
|
633
677
|
<tr>
|
634
678
|
<td>File Extension</td>
|
@@ -645,7 +689,7 @@ It also takes a block for inline templates (see example).
|
|
645
689
|
<table>
|
646
690
|
<tr>
|
647
691
|
<td>Dependency</td>
|
648
|
-
<td><a href="
|
692
|
+
<td><a href="https://sass-lang.com/" title="sass">sass</a></td>
|
649
693
|
</tr>
|
650
694
|
<tr>
|
651
695
|
<td>File Extension</td>
|
@@ -679,7 +723,7 @@ It also takes a block for inline templates (see example).
|
|
679
723
|
<table>
|
680
724
|
<tr>
|
681
725
|
<td>Dependency</td>
|
682
|
-
<td><a href="
|
726
|
+
<td><a href="https://shopify.github.io/liquid/" title="liquid">liquid</a></td>
|
683
727
|
</tr>
|
684
728
|
<tr>
|
685
729
|
<td>File Extension</td>
|
@@ -703,9 +747,11 @@ template, you almost always want to pass locals to it.
|
|
703
747
|
Anyone of:
|
704
748
|
<a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
|
705
749
|
<a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
|
706
|
-
<a href="
|
707
|
-
<a href="
|
750
|
+
<a href="https://github.com/ged/bluecloth" title="BlueCloth">BlueCloth</a>,
|
751
|
+
<a href="https://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
|
708
752
|
<a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
|
753
|
+
<a href="https://github.com/gjtorikian/commonmarker" title="commonmarker">commonmarker</a>
|
754
|
+
<a href="https://github.com/alphabetum/pandoc-ruby" title="pandoc">pandoc</a>
|
709
755
|
</td>
|
710
756
|
</tr>
|
711
757
|
<tr>
|
@@ -718,7 +764,7 @@ template, you almost always want to pass locals to it.
|
|
718
764
|
</tr>
|
719
765
|
</table>
|
720
766
|
|
721
|
-
It is not possible to call methods from
|
767
|
+
It is not possible to call methods from Markdown, nor to pass locals to it.
|
722
768
|
You therefore will usually use it in combination with another rendering
|
723
769
|
engine:
|
724
770
|
|
@@ -726,7 +772,8 @@ engine:
|
|
726
772
|
erb :overview, :locals => { :text => markdown(:introduction) }
|
727
773
|
```
|
728
774
|
|
729
|
-
Note that you may also call the `markdown` method from within other
|
775
|
+
Note that you may also call the `markdown` method from within other
|
776
|
+
templates:
|
730
777
|
|
731
778
|
```ruby
|
732
779
|
%h1 Hello From Haml!
|
@@ -754,8 +801,9 @@ template than for the layout by passing the `:layout_engine` option.
|
|
754
801
|
</tr>
|
755
802
|
</table>
|
756
803
|
|
757
|
-
It is not possible to call methods from
|
758
|
-
therefore will usually use it in combination with another
|
804
|
+
It is not possible to call methods from Textile, nor to pass locals to
|
805
|
+
it. You therefore will usually use it in combination with another
|
806
|
+
rendering engine:
|
759
807
|
|
760
808
|
```ruby
|
761
809
|
erb :overview, :locals => { :text => textile(:introduction) }
|
@@ -789,7 +837,7 @@ template than for the layout by passing the `:layout_engine` option.
|
|
789
837
|
</tr>
|
790
838
|
</table>
|
791
839
|
|
792
|
-
It is not possible to call methods from
|
840
|
+
It is not possible to call methods from RDoc, nor to pass locals to it. You
|
793
841
|
therefore will usually use it in combination with another rendering engine:
|
794
842
|
|
795
843
|
```ruby
|
@@ -844,15 +892,15 @@ almost always want to pass locals to it.
|
|
844
892
|
</tr>
|
845
893
|
</table>
|
846
894
|
|
847
|
-
Since you cannot call Ruby methods directly from a Radius template, you
|
848
|
-
always want to pass locals to it.
|
895
|
+
Since you cannot call Ruby methods directly from a Radius template, you
|
896
|
+
almost always want to pass locals to it.
|
849
897
|
|
850
898
|
#### Markaby Templates
|
851
899
|
|
852
900
|
<table>
|
853
901
|
<tr>
|
854
902
|
<td>Dependency</td>
|
855
|
-
<td><a href="
|
903
|
+
<td><a href="https://markaby.github.io/" title="Markaby">Markaby</a></td>
|
856
904
|
</tr>
|
857
905
|
<tr>
|
858
906
|
<td>File Extension</td>
|
@@ -864,7 +912,7 @@ always want to pass locals to it.
|
|
864
912
|
</tr>
|
865
913
|
</table>
|
866
914
|
|
867
|
-
It also takes a block for inline templates (see example).
|
915
|
+
It also takes a block for inline templates (see [example](#inline-templates)).
|
868
916
|
|
869
917
|
#### RABL Templates
|
870
918
|
|
@@ -917,7 +965,7 @@ It also takes a block for inline templates (see example).
|
|
917
965
|
</tr>
|
918
966
|
</table>
|
919
967
|
|
920
|
-
It is not possible to call methods from
|
968
|
+
It is not possible to call methods from Creole, nor to pass locals to it. You
|
921
969
|
therefore will usually use it in combination with another rendering engine:
|
922
970
|
|
923
971
|
```ruby
|
@@ -952,15 +1000,16 @@ template than for the layout by passing the `:layout_engine` option.
|
|
952
1000
|
</tr>
|
953
1001
|
</table>
|
954
1002
|
|
955
|
-
It is not possible to call methods from MediaWiki markup, nor to pass
|
956
|
-
it. You therefore will usually use it in combination with
|
957
|
-
engine:
|
1003
|
+
It is not possible to call methods from MediaWiki markup, nor to pass
|
1004
|
+
locals to it. You therefore will usually use it in combination with
|
1005
|
+
another rendering engine:
|
958
1006
|
|
959
1007
|
```ruby
|
960
1008
|
erb :overview, :locals => { :text => mediawiki(:introduction) }
|
961
1009
|
```
|
962
1010
|
|
963
|
-
Note that you may also call the `mediawiki` method from within other
|
1011
|
+
Note that you may also call the `mediawiki` method from within other
|
1012
|
+
templates:
|
964
1013
|
|
965
1014
|
```ruby
|
966
1015
|
%h1 Hello From Haml!
|
@@ -980,7 +1029,7 @@ template than for the layout by passing the `:layout_engine` option.
|
|
980
1029
|
<a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
|
981
1030
|
CoffeeScript
|
982
1031
|
</a> and a
|
983
|
-
<a href="https://github.com/sstephenson/execjs
|
1032
|
+
<a href="https://github.com/sstephenson/execjs" title="ExecJS">
|
984
1033
|
way to execute javascript
|
985
1034
|
</a>
|
986
1035
|
</td>
|
@@ -1004,7 +1053,7 @@ template than for the layout by passing the `:layout_engine` option.
|
|
1004
1053
|
<a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
|
1005
1054
|
Stylus
|
1006
1055
|
</a> and a
|
1007
|
-
<a href="https://github.com/sstephenson/execjs
|
1056
|
+
<a href="https://github.com/sstephenson/execjs" title="ExecJS">
|
1008
1057
|
way to execute javascript
|
1009
1058
|
</a>
|
1010
1059
|
</td>
|
@@ -1078,7 +1127,7 @@ present(resource);
|
|
1078
1127
|
<table>
|
1079
1128
|
<tr>
|
1080
1129
|
<td>Dependency</td>
|
1081
|
-
<td><a href="https://github.com/blambeau/wlang
|
1130
|
+
<td><a href="https://github.com/blambeau/wlang" title="WLang">WLang</a></td>
|
1082
1131
|
</tr>
|
1083
1132
|
<tr>
|
1084
1133
|
<td>File Extension</td>
|
@@ -1090,8 +1139,9 @@ present(resource);
|
|
1090
1139
|
</tr>
|
1091
1140
|
</table>
|
1092
1141
|
|
1093
|
-
Since calling ruby methods is not idiomatic in WLang, you almost always
|
1094
|
-
pass locals to it. Layouts written in WLang and `yield` are
|
1142
|
+
Since calling ruby methods is not idiomatic in WLang, you almost always
|
1143
|
+
want to pass locals to it. Layouts written in WLang and `yield` are
|
1144
|
+
supported, though.
|
1095
1145
|
|
1096
1146
|
### Accessing Variables in Templates
|
1097
1147
|
|
@@ -1131,7 +1181,8 @@ end
|
|
1131
1181
|
|
1132
1182
|
This code is mostly equivalent to `erb :index, :layout => :post`.
|
1133
1183
|
|
1134
|
-
Passing blocks to rendering methods is most useful for creating nested
|
1184
|
+
Passing blocks to rendering methods is most useful for creating nested
|
1185
|
+
layouts:
|
1135
1186
|
|
1136
1187
|
```ruby
|
1137
1188
|
erb :main_layout, :layout => false do
|
@@ -1232,8 +1283,8 @@ get '/' do
|
|
1232
1283
|
end
|
1233
1284
|
```
|
1234
1285
|
|
1235
|
-
Renders `./views/index.myat`.
|
1236
|
-
|
1286
|
+
Renders `./views/index.myat`. Learn more about
|
1287
|
+
[Tilt](https://github.com/rtomayko/tilt#readme).
|
1237
1288
|
|
1238
1289
|
### Using Custom Logic for Template Lookup
|
1239
1290
|
|
@@ -1242,7 +1293,7 @@ own `#find_template` method:
|
|
1242
1293
|
|
1243
1294
|
```ruby
|
1244
1295
|
configure do
|
1245
|
-
set :views [ './views/a', './views/b' ]
|
1296
|
+
set :views, [ './views/a', './views/b' ]
|
1246
1297
|
end
|
1247
1298
|
|
1248
1299
|
def find_template(views, name, engine, &block)
|
@@ -1254,8 +1305,8 @@ end
|
|
1254
1305
|
|
1255
1306
|
## Filters
|
1256
1307
|
|
1257
|
-
Before filters are evaluated before each request within the same
|
1258
|
-
|
1308
|
+
Before filters are evaluated before each request within the same context
|
1309
|
+
as the routes will be and can modify the request and response. Instance
|
1259
1310
|
variables set in filters are accessible by routes and templates:
|
1260
1311
|
|
1261
1312
|
```ruby
|
@@ -1270,9 +1321,10 @@ get '/foo/*' do
|
|
1270
1321
|
end
|
1271
1322
|
```
|
1272
1323
|
|
1273
|
-
After filters are evaluated after each request within the same context
|
1274
|
-
routes will be and can also modify the request and response.
|
1275
|
-
set in before filters and routes are accessible by
|
1324
|
+
After filters are evaluated after each request within the same context
|
1325
|
+
as the routes will be and can also modify the request and response.
|
1326
|
+
Instance variables set in before filters and routes are accessible by
|
1327
|
+
after filters:
|
1276
1328
|
|
1277
1329
|
```ruby
|
1278
1330
|
after do
|
@@ -1280,9 +1332,9 @@ after do
|
|
1280
1332
|
end
|
1281
1333
|
```
|
1282
1334
|
|
1283
|
-
Note: Unless you use the `body` method rather than just returning a
|
1284
|
-
the routes, the body will not yet be available in the after
|
1285
|
-
generated later on.
|
1335
|
+
Note: Unless you use the `body` method rather than just returning a
|
1336
|
+
String from the routes, the body will not yet be available in the after
|
1337
|
+
filter, since it is generated later on.
|
1286
1338
|
|
1287
1339
|
Filters optionally take a pattern, causing them to be evaluated only if the
|
1288
1340
|
request path matches that pattern:
|
@@ -1359,35 +1411,83 @@ get '/:value' do
|
|
1359
1411
|
end
|
1360
1412
|
```
|
1361
1413
|
|
1362
|
-
|
1363
|
-
might not always be what you want (storing lots of data will increase your
|
1364
|
-
traffic, for instance). You can use any Rack session middleware: in order to
|
1365
|
-
do so, do **not** call `enable :sessions`, but instead pull in your
|
1366
|
-
middleware of choice as you would any other middleware:
|
1414
|
+
#### Session Secret Security
|
1367
1415
|
|
1368
|
-
|
1369
|
-
|
1416
|
+
To improve security, the session data in the cookie is signed with a session
|
1417
|
+
secret using `HMAC-SHA1`. This session secret should optimally be a
|
1418
|
+
cryptographically secure random value of an appropriate length which for
|
1419
|
+
`HMAC-SHA1` is greater than or equal to 64 bytes (512 bits, 128 hex
|
1420
|
+
characters). You would be advised not to use a secret that is less than 32
|
1421
|
+
bytes of randomness (256 bits, 64 hex characters). It is therefore **very
|
1422
|
+
important** that you don't just make the secret up, but instead use a secure
|
1423
|
+
random number generator to create it. Humans are extremely bad at generating
|
1424
|
+
random values.
|
1370
1425
|
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1426
|
+
By default, a 32 byte secure random session secret is generated for you by
|
1427
|
+
Sinatra, but it will change with every restart of your application. If you
|
1428
|
+
have multiple instances of your application, and you let Sinatra generate the
|
1429
|
+
key, each instance would then have a different session key which is probably
|
1430
|
+
not what you want.
|
1374
1431
|
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1432
|
+
For better security and usability it's
|
1433
|
+
[recommended](https://12factor.net/config) that you generate a secure random
|
1434
|
+
secret and store it in an environment variable on each host running your
|
1435
|
+
application so that all of your application instances will share the same
|
1436
|
+
secret. You should periodically rotate this session secret to a new value.
|
1437
|
+
Here are some examples of how you might create a 64 byte secret and set it:
|
1438
|
+
|
1439
|
+
**Session Secret Generation**
|
1440
|
+
|
1441
|
+
```text
|
1442
|
+
$ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
|
1443
|
+
99ae8af...snip...ec0f262ac
|
1378
1444
|
```
|
1379
1445
|
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1446
|
+
**Session Secret Generation (Bonus Points)**
|
1447
|
+
|
1448
|
+
Use the [sysrandom gem](https://github.com/cryptosphere/sysrandom#readme) to
|
1449
|
+
prefer use of system RNG facilities to generate random values instead of
|
1450
|
+
userspace `OpenSSL` which MRI Ruby currently defaults to:
|
1451
|
+
|
1452
|
+
```text
|
1453
|
+
$ gem install sysrandom
|
1454
|
+
Building native extensions. This could take a while...
|
1455
|
+
Successfully installed sysrandom-1.x
|
1456
|
+
1 gem installed
|
1457
|
+
|
1458
|
+
$ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
|
1459
|
+
99ae8af...snip...ec0f262ac
|
1460
|
+
```
|
1461
|
+
|
1462
|
+
**Session Secret Environment Variable**
|
1463
|
+
|
1464
|
+
Set a `SESSION_SECRET` environment variable for Sinatra to the value you
|
1465
|
+
generated. Make this value persistent across reboots of your host. Since the
|
1466
|
+
method for doing this will vary across systems this is for illustrative
|
1467
|
+
purposes only:
|
1468
|
+
|
1469
|
+
```bash
|
1470
|
+
# echo "export SESSION_SECRET=99ae8af...snip...ec0f262ac" >> ~/.bashrc
|
1471
|
+
```
|
1472
|
+
|
1473
|
+
**Session Secret App Config**
|
1474
|
+
|
1475
|
+
Setup your app config to fail-safe to a secure random secret
|
1476
|
+
if the `SESSION_SECRET` environment variable is not available.
|
1477
|
+
|
1478
|
+
For bonus points use the [sysrandom
|
1479
|
+
gem](https://github.com/cryptosphere/sysrandom#readme) here as well:
|
1384
1480
|
|
1385
1481
|
```ruby
|
1386
|
-
|
1482
|
+
require 'securerandom'
|
1483
|
+
# -or- require 'sysrandom/securerandom'
|
1484
|
+
set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
|
1387
1485
|
```
|
1388
1486
|
|
1389
|
-
|
1390
|
-
|
1487
|
+
#### Session Config
|
1488
|
+
|
1489
|
+
If you want to configure it further, you may also store a hash with options
|
1490
|
+
in the `sessions` setting:
|
1391
1491
|
|
1392
1492
|
```ruby
|
1393
1493
|
set :sessions, :domain => 'foo.com'
|
@@ -1400,6 +1500,41 @@ domain with a *.* like this instead:
|
|
1400
1500
|
set :sessions, :domain => '.foo.com'
|
1401
1501
|
```
|
1402
1502
|
|
1503
|
+
#### Choosing Your Own Session Middleware
|
1504
|
+
|
1505
|
+
Note that `enable :sessions` actually stores all data in a cookie. This
|
1506
|
+
might not always be what you want (storing lots of data will increase your
|
1507
|
+
traffic, for instance). You can use any Rack session middleware in order to
|
1508
|
+
do so, one of the following methods can be used:
|
1509
|
+
|
1510
|
+
```ruby
|
1511
|
+
enable :sessions
|
1512
|
+
set :session_store, Rack::Session::Pool
|
1513
|
+
```
|
1514
|
+
|
1515
|
+
Or to set up sessions with a hash of options:
|
1516
|
+
|
1517
|
+
```ruby
|
1518
|
+
set :sessions, :expire_after => 2592000
|
1519
|
+
set :session_store, Rack::Session::Pool
|
1520
|
+
```
|
1521
|
+
|
1522
|
+
Another option is to **not** call `enable :sessions`, but instead pull in
|
1523
|
+
your middleware of choice as you would any other middleware.
|
1524
|
+
|
1525
|
+
It is important to note that when using this method, session based
|
1526
|
+
protection **will not be enabled by default**.
|
1527
|
+
|
1528
|
+
The Rack middleware to do that will also need to be added:
|
1529
|
+
|
1530
|
+
```ruby
|
1531
|
+
use Rack::Session::Pool, :expire_after => 2592000
|
1532
|
+
use Rack::Protection::RemoteToken
|
1533
|
+
use Rack::Protection::SessionHijacking
|
1534
|
+
```
|
1535
|
+
|
1536
|
+
See '[Configuring attack protection](#configuring-attack-protection)' for more information.
|
1537
|
+
|
1403
1538
|
### Halting
|
1404
1539
|
|
1405
1540
|
To immediately stop a request within a filter or route use:
|
@@ -1458,8 +1593,8 @@ matching route. If no matching route is found, a 404 is returned.
|
|
1458
1593
|
|
1459
1594
|
### Triggering Another Route
|
1460
1595
|
|
1461
|
-
Sometimes `pass` is not what you want, instead you would like to get the
|
1462
|
-
of calling another route. Simply use `call` to achieve this:
|
1596
|
+
Sometimes `pass` is not what you want, instead you would like to get the
|
1597
|
+
result of calling another route. Simply use `call` to achieve this:
|
1463
1598
|
|
1464
1599
|
```ruby
|
1465
1600
|
get '/foo' do
|
@@ -1472,21 +1607,22 @@ get '/bar' do
|
|
1472
1607
|
end
|
1473
1608
|
```
|
1474
1609
|
|
1475
|
-
Note that in the example above, you would ease testing and increase
|
1476
|
-
by simply moving `"bar"` into a helper used by both `/foo` and
|
1610
|
+
Note that in the example above, you would ease testing and increase
|
1611
|
+
performance by simply moving `"bar"` into a helper used by both `/foo` and
|
1612
|
+
`/bar`.
|
1477
1613
|
|
1478
|
-
If you want the request to be sent to the same application instance rather
|
1479
|
-
a duplicate, use `call!` instead of `call`.
|
1614
|
+
If you want the request to be sent to the same application instance rather
|
1615
|
+
than a duplicate, use `call!` instead of `call`.
|
1480
1616
|
|
1481
1617
|
Check out the Rack specification if you want to learn more about `call`.
|
1482
1618
|
|
1483
1619
|
### Setting Body, Status Code and Headers
|
1484
1620
|
|
1485
|
-
It is possible and recommended to set the status code and response body with
|
1486
|
-
return value of the route block. However, in some scenarios you might
|
1487
|
-
set the body at an arbitrary point in the execution flow. You can do
|
1488
|
-
`body` helper method. If you do so, you can use that method from
|
1489
|
-
access the body:
|
1621
|
+
It is possible and recommended to set the status code and response body with
|
1622
|
+
the return value of the route block. However, in some scenarios you might
|
1623
|
+
want to set the body at an arbitrary point in the execution flow. You can do
|
1624
|
+
so with the `body` helper method. If you do so, you can use that method from
|
1625
|
+
there on to access the body:
|
1490
1626
|
|
1491
1627
|
```ruby
|
1492
1628
|
get '/foo' do
|
@@ -1499,7 +1635,7 @@ end
|
|
1499
1635
|
```
|
1500
1636
|
|
1501
1637
|
It is also possible to pass a block to `body`, which will be executed by the
|
1502
|
-
Rack handler (this can be used to implement streaming, see "Return Values").
|
1638
|
+
Rack handler (this can be used to implement streaming, [see "Return Values"](#return-values)).
|
1503
1639
|
|
1504
1640
|
Similar to the body, you can also set the status code and headers:
|
1505
1641
|
|
@@ -1508,7 +1644,7 @@ get '/foo' do
|
|
1508
1644
|
status 418
|
1509
1645
|
headers \
|
1510
1646
|
"Allow" => "BREW, POST, GET, PROPFIND, WHEN",
|
1511
|
-
"Refresh" => "Refresh: 20;
|
1647
|
+
"Refresh" => "Refresh: 20; https://ietf.org/rfc/rfc2324.txt"
|
1512
1648
|
body "I'm a tea pot!"
|
1513
1649
|
end
|
1514
1650
|
```
|
@@ -1537,50 +1673,70 @@ end
|
|
1537
1673
|
|
1538
1674
|
This allows you to implement streaming APIs,
|
1539
1675
|
[Server Sent Events](https://w3c.github.io/eventsource/), and can be used as
|
1540
|
-
the basis for [WebSockets](https://en.wikipedia.org/wiki/WebSocket). It can
|
1541
|
-
used to increase throughput if some but not all content depends on a
|
1542
|
-
resource.
|
1676
|
+
the basis for [WebSockets](https://en.wikipedia.org/wiki/WebSocket). It can
|
1677
|
+
also be used to increase throughput if some but not all content depends on a
|
1678
|
+
slow resource.
|
1543
1679
|
|
1544
|
-
Note that the streaming behavior, especially the number of concurrent
|
1545
|
-
highly depends on the web server used to serve the application.
|
1546
|
-
might not even support streaming at all. If the server does not
|
1547
|
-
streaming, the body will be sent all at once after the block passed
|
1548
|
-
finishes executing. Streaming does not work at all with Shotgun.
|
1680
|
+
Note that the streaming behavior, especially the number of concurrent
|
1681
|
+
requests, highly depends on the web server used to serve the application.
|
1682
|
+
Some servers might not even support streaming at all. If the server does not
|
1683
|
+
support streaming, the body will be sent all at once after the block passed
|
1684
|
+
to `stream` finishes executing. Streaming does not work at all with Shotgun.
|
1549
1685
|
|
1550
1686
|
If the optional parameter is set to `keep_open`, it will not call `close` on
|
1551
1687
|
the stream object, allowing you to close it at any later point in the
|
1552
|
-
execution flow. This only works on evented servers, like
|
1688
|
+
execution flow. This only works on evented servers, like Rainbows.
|
1553
1689
|
Other servers will still close the stream:
|
1554
1690
|
|
1555
1691
|
```ruby
|
1556
|
-
#
|
1557
|
-
|
1558
|
-
set :server, :thin
|
1559
|
-
connections = []
|
1692
|
+
# config.ru
|
1693
|
+
require 'sinatra/base'
|
1560
1694
|
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
#
|
1566
|
-
|
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
|
1567
1705
|
end
|
1568
|
-
end
|
1569
1706
|
|
1570
|
-
post '
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
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
|
1574
1715
|
|
1575
|
-
#
|
1576
|
-
out.close
|
1716
|
+
204 # response without entity body
|
1577
1717
|
end
|
1718
|
+
end
|
1578
1719
|
|
1579
|
-
|
1580
|
-
|
1720
|
+
run App
|
1721
|
+
```
|
1722
|
+
|
1723
|
+
```ruby
|
1724
|
+
# rainbows.conf
|
1725
|
+
Rainbows! do
|
1726
|
+
use :EventMachine
|
1581
1727
|
end
|
1728
|
+
````
|
1729
|
+
|
1730
|
+
Run:
|
1731
|
+
|
1732
|
+
```shell
|
1733
|
+
rainbows -c rainbows.conf
|
1582
1734
|
```
|
1583
1735
|
|
1736
|
+
It's also possible for the client to close the connection when trying to
|
1737
|
+
write to the socket. Because of this, it's recommended to check
|
1738
|
+
`out.closed?` before trying to write.
|
1739
|
+
|
1584
1740
|
### Logging
|
1585
1741
|
|
1586
1742
|
In the request scope, the `logger` helper exposes a `Logger` instance:
|
@@ -1596,8 +1752,8 @@ This logger will automatically take your Rack handler's logging settings into
|
|
1596
1752
|
account. If logging is disabled, this method will return a dummy object, so
|
1597
1753
|
you do not have to worry about it in your routes and filters.
|
1598
1754
|
|
1599
|
-
Note that logging is only enabled for `Sinatra::Application` by default, so
|
1600
|
-
you inherit from `Sinatra::Base`, you probably want to enable it yourself:
|
1755
|
+
Note that logging is only enabled for `Sinatra::Application` by default, so
|
1756
|
+
if you inherit from `Sinatra::Base`, you probably want to enable it yourself:
|
1601
1757
|
|
1602
1758
|
```ruby
|
1603
1759
|
class MyApp < Sinatra::Base
|
@@ -1643,7 +1799,7 @@ Haml:
|
|
1643
1799
|
|
1644
1800
|
It takes reverse proxies and Rack routers into account, if present.
|
1645
1801
|
|
1646
|
-
This method is also aliased to `to` (see below for an example).
|
1802
|
+
This method is also aliased to `to` (see [below](#browser-redirect) for an example).
|
1647
1803
|
|
1648
1804
|
### Browser Redirect
|
1649
1805
|
|
@@ -1749,8 +1905,9 @@ etag @article.sha1, :weak
|
|
1749
1905
|
```
|
1750
1906
|
|
1751
1907
|
These helpers will not do any caching for you, but rather feed the necessary
|
1752
|
-
information to your cache. If you are looking for a quick
|
1753
|
-
solution, try
|
1908
|
+
information to your cache. If you are looking for a quick
|
1909
|
+
reverse-proxy caching solution, try
|
1910
|
+
[rack-cache](https://github.com/rtomayko/rack-cache#readme):
|
1754
1911
|
|
1755
1912
|
```ruby
|
1756
1913
|
require "rack/cache"
|
@@ -1765,15 +1922,16 @@ get '/' do
|
|
1765
1922
|
end
|
1766
1923
|
```
|
1767
1924
|
|
1768
|
-
Use the `:static_cache_control` setting (see below) to add
|
1925
|
+
Use the `:static_cache_control` setting (see [below](#cache-control)) to add
|
1769
1926
|
`Cache-Control` header info to static files.
|
1770
1927
|
|
1771
|
-
According to RFC 2616, your application should behave differently if the
|
1772
|
-
or If-None-Match header is set to `*`, depending on whether the
|
1773
|
-
requested is already in existence. Sinatra assumes resources for
|
1774
|
-
and idempotent (like put) requests are already in existence,
|
1775
|
-
resources (for instance post requests) are treated as new
|
1776
|
-
can change this behavior by passing in a `:new_resource`
|
1928
|
+
According to RFC 2616, your application should behave differently if the
|
1929
|
+
If-Match or If-None-Match header is set to `*`, depending on whether the
|
1930
|
+
resource requested is already in existence. Sinatra assumes resources for
|
1931
|
+
safe (like get) and idempotent (like put) requests are already in existence,
|
1932
|
+
whereas other resources (for instance post requests) are treated as new
|
1933
|
+
resources. You can change this behavior by passing in a `:new_resource`
|
1934
|
+
option:
|
1777
1935
|
|
1778
1936
|
```ruby
|
1779
1937
|
get '/create' do
|
@@ -1810,8 +1968,8 @@ The options are:
|
|
1810
1968
|
|
1811
1969
|
<dl>
|
1812
1970
|
<dt>filename</dt>
|
1813
|
-
<dd>File name to be used in the response,
|
1814
|
-
|
1971
|
+
<dd>File name to be used in the response,
|
1972
|
+
defaults to the real file name.</dd>
|
1815
1973
|
<dt>last_modified</dt>
|
1816
1974
|
<dd>Value for Last-Modified header, defaults to the file's mtime.</dd>
|
1817
1975
|
|
@@ -1830,18 +1988,17 @@ The options are:
|
|
1830
1988
|
|
1831
1989
|
<dt>status</dt>
|
1832
1990
|
<dd>
|
1833
|
-
Status code to be sent. Useful when sending a static file as an error
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
automatically handle range requests.
|
1991
|
+
Status code to be sent. Useful when sending a static file as an error
|
1992
|
+
page. If supported by the Rack handler, other means than streaming
|
1993
|
+
from the Ruby process will be used. If you use this helper method,
|
1994
|
+
Sinatra will automatically handle range requests.
|
1838
1995
|
</dd>
|
1839
1996
|
</dl>
|
1840
1997
|
|
1841
1998
|
### Accessing the Request Object
|
1842
1999
|
|
1843
|
-
The incoming request object can be accessed from request level (filter,
|
1844
|
-
error handlers) through the `request` method:
|
2000
|
+
The incoming request object can be accessed from request level (filter,
|
2001
|
+
routes, error handlers) through the `request` method:
|
1845
2002
|
|
1846
2003
|
```ruby
|
1847
2004
|
# app running on http://example.com/example
|
@@ -1898,8 +2055,8 @@ end
|
|
1898
2055
|
|
1899
2056
|
### Attachments
|
1900
2057
|
|
1901
|
-
You can use the `attachment` helper to tell the browser the response should
|
1902
|
-
stored on disk rather than displayed in the browser:
|
2058
|
+
You can use the `attachment` helper to tell the browser the response should
|
2059
|
+
be stored on disk rather than displayed in the browser:
|
1903
2060
|
|
1904
2061
|
```ruby
|
1905
2062
|
get '/' do
|
@@ -1919,19 +2076,20 @@ end
|
|
1919
2076
|
|
1920
2077
|
### Dealing with Date and Time
|
1921
2078
|
|
1922
|
-
Sinatra offers a `time_for` helper method that generates a Time object from
|
1923
|
-
given value. It is also able to convert `DateTime`, `Date` and similar
|
2079
|
+
Sinatra offers a `time_for` helper method that generates a Time object from
|
2080
|
+
the given value. It is also able to convert `DateTime`, `Date` and similar
|
2081
|
+
classes:
|
1924
2082
|
|
1925
2083
|
```ruby
|
1926
2084
|
get '/' do
|
1927
|
-
pass if Time.now > time_for('Dec 23,
|
2085
|
+
pass if Time.now > time_for('Dec 23, 2016')
|
1928
2086
|
"still time"
|
1929
2087
|
end
|
1930
2088
|
```
|
1931
2089
|
|
1932
|
-
This method is used internally by `expires`, `last_modified` and akin. You
|
1933
|
-
therefore easily extend the behavior of those methods by overriding
|
1934
|
-
in your application:
|
2090
|
+
This method is used internally by `expires`, `last_modified` and akin. You
|
2091
|
+
can therefore easily extend the behavior of those methods by overriding
|
2092
|
+
`time_for` in your application:
|
1935
2093
|
|
1936
2094
|
```ruby
|
1937
2095
|
helpers do
|
@@ -1961,9 +2119,9 @@ find_template settings.views, 'foo', Tilt[:haml] do |file|
|
|
1961
2119
|
end
|
1962
2120
|
```
|
1963
2121
|
|
1964
|
-
This is not really useful. But it is useful that you can actually override
|
1965
|
-
method to hook in your own lookup mechanism. For instance, if you want
|
1966
|
-
able to use more than one view directory:
|
2122
|
+
This is not really useful. But it is useful that you can actually override
|
2123
|
+
this method to hook in your own lookup mechanism. For instance, if you want
|
2124
|
+
to be able to use more than one view directory:
|
1967
2125
|
|
1968
2126
|
```ruby
|
1969
2127
|
set :views, ['views', 'templates']
|
@@ -1992,11 +2150,11 @@ end
|
|
1992
2150
|
You can also easily wrap this up in an extension and share with others!
|
1993
2151
|
|
1994
2152
|
Note that `find_template` does not check if the file really exists but
|
1995
|
-
rather calls the given block for all possible paths. This is not a
|
1996
|
-
issue, since `render` will use `break` as soon as a file is
|
1997
|
-
template locations (and content) will be cached if you are not
|
1998
|
-
development mode. You should keep that in mind if you write a
|
1999
|
-
method.
|
2153
|
+
rather calls the given block for all possible paths. This is not a
|
2154
|
+
performance issue, since `render` will use `break` as soon as a file is
|
2155
|
+
found. Also, template locations (and content) will be cached if you are not
|
2156
|
+
running in development mode. You should keep that in mind if you write a
|
2157
|
+
really crazy method.
|
2000
2158
|
|
2001
2159
|
## Configuration
|
2002
2160
|
|
@@ -2021,7 +2179,7 @@ configure do
|
|
2021
2179
|
end
|
2022
2180
|
```
|
2023
2181
|
|
2024
|
-
Run only when the environment (`
|
2182
|
+
Run only when the environment (`APP_ENV` environment variable) is set to
|
2025
2183
|
`:production`:
|
2026
2184
|
|
2027
2185
|
```ruby
|
@@ -2055,10 +2213,10 @@ end
|
|
2055
2213
|
### Configuring attack protection
|
2056
2214
|
|
2057
2215
|
Sinatra is using
|
2058
|
-
[Rack::Protection](https://github.com/sinatra/rack-protection#readme) to
|
2059
|
-
your application against common, opportunistic attacks. You can
|
2060
|
-
this behavior (which will open up your application to tons
|
2061
|
-
vulnerabilities):
|
2216
|
+
[Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme) to
|
2217
|
+
defend your application against common, opportunistic attacks. You can
|
2218
|
+
easily disable this behavior (which will open up your application to tons
|
2219
|
+
of common vulnerabilities):
|
2062
2220
|
|
2063
2221
|
```ruby
|
2064
2222
|
disable :protection
|
@@ -2076,12 +2234,12 @@ set :protection, :except => [:path_traversal, :session_hijacking]
|
|
2076
2234
|
```
|
2077
2235
|
|
2078
2236
|
By default, Sinatra will only set up session based protection if `:sessions`
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2237
|
+
have been enabled. See '[Using Sessions](#using-sessions)'. Sometimes you may want to set up
|
2238
|
+
sessions "outside" of the Sinatra app, such as in the config.ru or with a
|
2239
|
+
separate `Rack::Builder` instance. In that case you can still set up session
|
2240
|
+
based protection by passing the `:session` option:
|
2082
2241
|
|
2083
2242
|
```ruby
|
2084
|
-
use Rack::Session::Pool
|
2085
2243
|
set :protection, :session => true
|
2086
2244
|
```
|
2087
2245
|
|
@@ -2089,191 +2247,237 @@ set :protection, :session => true
|
|
2089
2247
|
|
2090
2248
|
<dl>
|
2091
2249
|
<dt>absolute_redirects</dt>
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2250
|
+
<dd>
|
2251
|
+
If disabled, Sinatra will allow relative redirects, however, Sinatra
|
2252
|
+
will no longer conform with RFC 2616 (HTTP 1.1), which only allows
|
2253
|
+
absolute redirects.
|
2254
|
+
</dd>
|
2255
|
+
<dd>
|
2256
|
+
Enable if your app is running behind a reverse proxy that has not been
|
2257
|
+
set up properly. Note that the <tt>url</tt> helper will still produce
|
2258
|
+
absolute URLs, unless you pass in <tt>false</tt> as the second
|
2259
|
+
parameter.
|
2260
|
+
</dd>
|
2261
|
+
<dd>Disabled by default.</dd>
|
2102
2262
|
|
2103
2263
|
<dt>add_charset</dt>
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2264
|
+
<dd>
|
2265
|
+
Mime types the <tt>content_type</tt> helper will automatically add the
|
2266
|
+
charset info to. You should add to it rather than overriding this
|
2267
|
+
option: <tt>settings.add_charset << "application/foobar"</tt>
|
2268
|
+
</dd>
|
2109
2269
|
|
2110
2270
|
<dt>app_file</dt>
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2271
|
+
<dd>
|
2272
|
+
Path to the main application file, used to detect project root, views
|
2273
|
+
and public folder and inline templates.
|
2274
|
+
</dd>
|
2115
2275
|
|
2116
2276
|
<dt>bind</dt>
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2277
|
+
<dd>
|
2278
|
+
IP address to bind to (default: <tt>0.0.0.0</tt> <em>or</em>
|
2279
|
+
<tt>localhost</tt> if your `environment` is set to development). Only
|
2280
|
+
used for built-in server.
|
2281
|
+
</dd>
|
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>
|
2120
2291
|
|
2121
2292
|
<dt>default_encoding</dt>
|
2122
|
-
|
2293
|
+
<dd>Encoding to assume if unknown (defaults to <tt>"utf-8"</tt>).</dd>
|
2123
2294
|
|
2124
2295
|
<dt>dump_errors</dt>
|
2125
|
-
|
2296
|
+
<dd>Display errors in the log.</dd>
|
2126
2297
|
|
2127
2298
|
<dt>environment</dt>
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2299
|
+
<dd>
|
2300
|
+
Current environment. Defaults to <tt>ENV['APP_ENV']</tt>, or
|
2301
|
+
<tt>"development"</tt> if not available.
|
2302
|
+
</dd>
|
2132
2303
|
|
2133
2304
|
<dt>logging</dt>
|
2134
|
-
|
2305
|
+
<dd>Use the logger.</dd>
|
2135
2306
|
|
2136
2307
|
<dt>lock</dt>
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2308
|
+
<dd>
|
2309
|
+
Places a lock around every request, only running processing on request
|
2310
|
+
per Ruby process concurrently.
|
2311
|
+
</dd>
|
2312
|
+
<dd>Enabled if your app is not thread-safe. Disabled by default.</dd>
|
2142
2313
|
|
2143
2314
|
<dt>method_override</dt>
|
2315
|
+
<dd>
|
2316
|
+
Use <tt>_method</tt> magic to allow put/delete forms in browsers that
|
2317
|
+
don't support it.
|
2318
|
+
</dd>
|
2319
|
+
|
2320
|
+
<dt>mustermann_opts</dt>
|
2144
2321
|
<dd>
|
2145
|
-
|
2146
|
-
|
2322
|
+
A default hash of options to pass to Mustermann.new when compiling routing
|
2323
|
+
paths.
|
2147
2324
|
</dd>
|
2148
2325
|
|
2149
2326
|
<dt>port</dt>
|
2150
|
-
|
2327
|
+
<dd>Port to listen on. Only used for built-in server.</dd>
|
2151
2328
|
|
2152
2329
|
<dt>prefixed_redirects</dt>
|
2153
|
-
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2330
|
+
<dd>
|
2331
|
+
Whether or not to insert <tt>request.script_name</tt> into redirects
|
2332
|
+
if no absolute path is given. That way <tt>redirect '/foo'</tt> would
|
2333
|
+
behave like <tt>redirect to('/foo')</tt>. Disabled by default.
|
2334
|
+
</dd>
|
2158
2335
|
|
2159
2336
|
<dt>protection</dt>
|
2160
|
-
|
2161
|
-
|
2337
|
+
<dd>
|
2338
|
+
Whether or not to enable web attack protections. See protection section
|
2339
|
+
above.
|
2340
|
+
</dd>
|
2162
2341
|
|
2163
2342
|
<dt>public_dir</dt>
|
2164
|
-
|
2343
|
+
<dd>Alias for <tt>public_folder</tt>. See below.</dd>
|
2165
2344
|
|
2166
2345
|
<dt>public_folder</dt>
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2346
|
+
<dd>
|
2347
|
+
Path to the folder public files are served from. Only used if static
|
2348
|
+
file serving is enabled (see <tt>static</tt> setting below). Inferred
|
2349
|
+
from <tt>app_file</tt> setting if not set.
|
2350
|
+
</dd>
|
2351
|
+
|
2352
|
+
<dt>quiet</dt>
|
2353
|
+
<dd>
|
2354
|
+
Disables logs generated by Sinatra's start and stop commands.
|
2355
|
+
<tt>false</tt> by default.
|
2356
|
+
</dd>
|
2172
2357
|
|
2173
2358
|
<dt>reload_templates</dt>
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2359
|
+
<dd>
|
2360
|
+
Whether or not to reload templates between requests. Enabled in
|
2361
|
+
development mode.
|
2362
|
+
</dd>
|
2178
2363
|
|
2179
2364
|
<dt>root</dt>
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2365
|
+
<dd>
|
2366
|
+
Path to project root folder. Inferred from <tt>app_file</tt> setting
|
2367
|
+
if not set.
|
2368
|
+
</dd>
|
2184
2369
|
|
2185
2370
|
<dt>raise_errors</dt>
|
2186
|
-
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
2371
|
+
<dd>
|
2372
|
+
Raise exceptions (will stop application). Enabled by default when
|
2373
|
+
<tt>environment</tt> is set to <tt>"test"</tt>, disabled otherwise.
|
2374
|
+
</dd>
|
2190
2375
|
|
2191
2376
|
<dt>run</dt>
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
2377
|
+
<dd>
|
2378
|
+
If enabled, Sinatra will handle starting the web server. Do not
|
2379
|
+
enable if using rackup or other means.
|
2380
|
+
</dd>
|
2196
2381
|
|
2197
2382
|
<dt>running</dt>
|
2198
|
-
|
2383
|
+
<dd>Is the built-in server running now? Do not change this setting!</dd>
|
2199
2384
|
|
2200
2385
|
<dt>server</dt>
|
2201
|
-
|
2202
|
-
|
2203
|
-
|
2204
|
-
|
2386
|
+
<dd>
|
2387
|
+
Server or list of servers to use for built-in server. Order indicates
|
2388
|
+
priority, default depends on Ruby implementation.
|
2389
|
+
</dd>
|
2390
|
+
|
2391
|
+
<dt>server_settings</dt>
|
2392
|
+
<dd>
|
2393
|
+
If you are using a WEBrick web server, presumably for your development
|
2394
|
+
environment, you can pass a hash of options to <tt>server_settings</tt>,
|
2395
|
+
such as <tt>SSLEnable</tt> or <tt>SSLVerifyClient</tt>. However, web
|
2396
|
+
servers such as Puma do not support this, so you can set
|
2397
|
+
<tt>server_settings</tt> by defining it as a method when you call
|
2398
|
+
<tt>configure</tt>.
|
2399
|
+
</dd>
|
2205
2400
|
|
2206
2401
|
<dt>sessions</dt>
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2402
|
+
<dd>
|
2403
|
+
Enable cookie-based sessions support using
|
2404
|
+
<tt>Rack::Session::Cookie</tt>. See 'Using Sessions' section for more
|
2405
|
+
information.
|
2406
|
+
</dd>
|
2407
|
+
|
2408
|
+
<dt>session_store</dt>
|
2409
|
+
<dd>
|
2410
|
+
The Rack session middleware used. Defaults to
|
2411
|
+
<tt>Rack::Session::Cookie</tt>. See 'Using Sessions' section for more
|
2412
|
+
information.
|
2413
|
+
</dd>
|
2211
2414
|
|
2212
2415
|
<dt>show_exceptions</dt>
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2416
|
+
<dd>
|
2417
|
+
Show a stack trace in the browser when an exception happens. Enabled by
|
2418
|
+
default when <tt>environment</tt> is set to <tt>"development"</tt>,
|
2419
|
+
disabled otherwise.
|
2420
|
+
</dd>
|
2421
|
+
<dd>
|
2422
|
+
Can also be set to <tt>:after_handler</tt> to trigger app-specified
|
2423
|
+
error handling before showing a stack trace in the browser.
|
2424
|
+
</dd>
|
2222
2425
|
|
2223
2426
|
<dt>static</dt>
|
2224
|
-
|
2225
|
-
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2427
|
+
<dd>Whether Sinatra should handle serving static files.</dd>
|
2428
|
+
<dd>Disable when using a server able to do this on its own.</dd>
|
2429
|
+
<dd>Disabling will boost performance.</dd>
|
2430
|
+
<dd>
|
2431
|
+
Enabled by default in classic style, disabled for modular apps.
|
2432
|
+
</dd>
|
2230
2433
|
|
2231
2434
|
<dt>static_cache_control</dt>
|
2232
|
-
|
2233
|
-
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2240
|
-
|
2435
|
+
<dd>
|
2436
|
+
When Sinatra is serving static files, set this to add
|
2437
|
+
<tt>Cache-Control</tt> headers to the responses. Uses the
|
2438
|
+
<tt>cache_control</tt> helper. Disabled by default.
|
2439
|
+
</dd>
|
2440
|
+
<dd>
|
2441
|
+
Use an explicit array when setting multiple values:
|
2442
|
+
<tt>set :static_cache_control, [:public, :max_age => 300]</tt>
|
2443
|
+
</dd>
|
2241
2444
|
|
2242
2445
|
<dt>threaded</dt>
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2446
|
+
<dd>
|
2447
|
+
If set to <tt>true</tt>, will tell server to use
|
2448
|
+
<tt>EventMachine.defer</tt> for processing the request.
|
2449
|
+
</dd>
|
2247
2450
|
|
2248
2451
|
<dt>traps</dt>
|
2249
|
-
|
2452
|
+
<dd>Whether Sinatra should handle system signals.</dd>
|
2250
2453
|
|
2251
2454
|
<dt>views</dt>
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2455
|
+
<dd>
|
2456
|
+
Path to the views folder. Inferred from <tt>app_file</tt> setting if
|
2457
|
+
not set.
|
2458
|
+
</dd>
|
2256
2459
|
|
2257
2460
|
<dt>x_cascade</dt>
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2461
|
+
<dd>
|
2462
|
+
Whether or not to set the X-Cascade header if no route matches.
|
2463
|
+
Defaults to <tt>true</tt>.
|
2464
|
+
</dd>
|
2262
2465
|
</dl>
|
2263
2466
|
|
2264
2467
|
## Environments
|
2265
2468
|
|
2266
|
-
There are three predefined `environments`: `"development"`,
|
2267
|
-
`"test"`. Environments can be set through the
|
2268
|
-
The default value is `"development"`.
|
2269
|
-
|
2270
|
-
|
2271
|
-
`"test"` environments,
|
2469
|
+
There are three predefined `environments`: `"development"`,
|
2470
|
+
`"production"` and `"test"`. Environments can be set through the
|
2471
|
+
`APP_ENV` environment variable. The default value is `"development"`.
|
2472
|
+
In the `"development"` environment all templates are reloaded between
|
2473
|
+
requests, and special `not_found` and `error` handlers display stack
|
2474
|
+
traces in your browser. In the `"production"` and `"test"` environments,
|
2475
|
+
templates are cached by default.
|
2272
2476
|
|
2273
|
-
To run different environments, set the `
|
2477
|
+
To run different environments, set the `APP_ENV` environment variable:
|
2274
2478
|
|
2275
2479
|
```shell
|
2276
|
-
|
2480
|
+
APP_ENV=production ruby my_app.rb
|
2277
2481
|
```
|
2278
2482
|
|
2279
2483
|
You can use predefined methods: `development?`, `test?` and `production?` to
|
@@ -2291,9 +2495,9 @@ end
|
|
2291
2495
|
|
2292
2496
|
## Error Handling
|
2293
2497
|
|
2294
|
-
Error handlers run within the same context as routes and before filters,
|
2295
|
-
means you get all the goodies it has to offer, like `haml`,
|
2296
|
-
`
|
2498
|
+
Error handlers run within the same context as routes and before filters,
|
2499
|
+
which means you get all the goodies it has to offer, like `haml`, `erb`,
|
2500
|
+
`halt`, etc.
|
2297
2501
|
|
2298
2502
|
### Not Found
|
2299
2503
|
|
@@ -2372,11 +2576,12 @@ and additional debugging information in your browser.
|
|
2372
2576
|
|
2373
2577
|
## Rack Middleware
|
2374
2578
|
|
2375
|
-
Sinatra rides on [Rack](
|
2376
|
-
interface for Ruby web frameworks. One of Rack's most interesting
|
2377
|
-
for application developers is support for "middleware" --
|
2378
|
-
between the server and your application monitoring
|
2379
|
-
HTTP request/response to provide various types
|
2579
|
+
Sinatra rides on [Rack](https://rack.github.io/), a minimal standard
|
2580
|
+
interface for Ruby web frameworks. One of Rack's most interesting
|
2581
|
+
capabilities for application developers is support for "middleware" --
|
2582
|
+
components that sit between the server and your application monitoring
|
2583
|
+
and/or manipulating the HTTP request/response to provide various types
|
2584
|
+
of common functionality.
|
2380
2585
|
|
2381
2586
|
Sinatra makes building Rack middleware pipelines a cinch via a top-level
|
2382
2587
|
`use` method:
|
@@ -2411,12 +2616,13 @@ typically don't have to `use` them explicitly.
|
|
2411
2616
|
|
2412
2617
|
You can find useful middleware in
|
2413
2618
|
[rack](https://github.com/rack/rack/tree/master/lib/rack),
|
2414
|
-
[rack-contrib](https://github.com/rack/rack-contrib#
|
2619
|
+
[rack-contrib](https://github.com/rack/rack-contrib#readme),
|
2415
2620
|
or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
|
2416
2621
|
|
2417
2622
|
## Testing
|
2418
2623
|
|
2419
|
-
Sinatra tests can be written using any Rack-based testing library or
|
2624
|
+
Sinatra tests can be written using any Rack-based testing library or
|
2625
|
+
framework.
|
2420
2626
|
[Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)
|
2421
2627
|
is recommended:
|
2422
2628
|
|
@@ -2442,7 +2648,7 @@ class MyAppTest < Minitest::Test
|
|
2442
2648
|
assert_equal 'Hello Frank!', last_response.body
|
2443
2649
|
end
|
2444
2650
|
|
2445
|
-
def
|
2651
|
+
def test_with_user_agent
|
2446
2652
|
get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
|
2447
2653
|
assert_equal "You're using Songbird!", last_response.body
|
2448
2654
|
end
|
@@ -2475,9 +2681,9 @@ class MyApp < Sinatra::Base
|
|
2475
2681
|
end
|
2476
2682
|
```
|
2477
2683
|
|
2478
|
-
The methods available to `Sinatra::Base` subclasses are exactly the same
|
2479
|
-
those available via the top-level DSL. Most top-level apps can be
|
2480
|
-
`Sinatra::Base` components with two modifications:
|
2684
|
+
The methods available to `Sinatra::Base` subclasses are exactly the same
|
2685
|
+
as those available via the top-level DSL. Most top-level apps can be
|
2686
|
+
converted to `Sinatra::Base` components with two modifications:
|
2481
2687
|
|
2482
2688
|
* Your file should require `sinatra/base` instead of `sinatra`;
|
2483
2689
|
otherwise, all of Sinatra's DSL methods are imported into the main
|
@@ -2486,12 +2692,11 @@ those available via the top-level DSL. Most top-level apps can be converted to
|
|
2486
2692
|
of `Sinatra::Base`.
|
2487
2693
|
|
2488
2694
|
`Sinatra::Base` is a blank slate. Most options are disabled by default,
|
2489
|
-
including the built-in server. See
|
2490
|
-
|
2491
|
-
|
2492
|
-
|
2493
|
-
|
2494
|
-
can subclass `Sinatra::Application`.
|
2695
|
+
including the built-in server. See [Configuring
|
2696
|
+
Settings](http://www.sinatrarb.com/configuration.html) for details on
|
2697
|
+
available options and their behavior. If you want behavior more similar
|
2698
|
+
to when you define your app at the top level (also known as Classic
|
2699
|
+
style), you can subclass `Sinatra::Application`:
|
2495
2700
|
|
2496
2701
|
```ruby
|
2497
2702
|
require 'sinatra/base'
|
@@ -2505,16 +2710,17 @@ end
|
|
2505
2710
|
|
2506
2711
|
### Modular vs. Classic Style
|
2507
2712
|
|
2508
|
-
Contrary to common belief, there is nothing wrong with the classic
|
2509
|
-
suits your application, you do not have to switch to a
|
2713
|
+
Contrary to common belief, there is nothing wrong with the classic
|
2714
|
+
style. If it suits your application, you do not have to switch to a
|
2715
|
+
modular application.
|
2510
2716
|
|
2511
|
-
The main disadvantage of using the classic style rather than the modular
|
2512
|
-
is that you will only have one Sinatra application per Ruby
|
2513
|
-
plan to use more than one, switch to the modular style.
|
2514
|
-
cannot mix the modular and the classic styles.
|
2717
|
+
The main disadvantage of using the classic style rather than the modular
|
2718
|
+
style is that you will only have one Sinatra application per Ruby
|
2719
|
+
process. If you plan to use more than one, switch to the modular style.
|
2720
|
+
There is no reason you cannot mix the modular and the classic styles.
|
2515
2721
|
|
2516
|
-
If switching from one style to the other, you should be aware of
|
2517
|
-
different default settings:
|
2722
|
+
If switching from one style to the other, you should be aware of
|
2723
|
+
slightly different default settings:
|
2518
2724
|
|
2519
2725
|
<table>
|
2520
2726
|
<tr>
|
@@ -2569,8 +2775,8 @@ different default settings:
|
|
2569
2775
|
|
2570
2776
|
### Serving a Modular Application
|
2571
2777
|
|
2572
|
-
There are two common options for starting a modular app, actively
|
2573
|
-
`run!`:
|
2778
|
+
There are two common options for starting a modular app, actively
|
2779
|
+
starting with `run!`:
|
2574
2780
|
|
2575
2781
|
```ruby
|
2576
2782
|
# my_app.rb
|
@@ -2633,16 +2839,16 @@ A `config.ru` file is recommended if:
|
|
2633
2839
|
* You want to use more than one subclass of `Sinatra::Base`.
|
2634
2840
|
* You want to use Sinatra only for middleware, and not as an endpoint.
|
2635
2841
|
|
2636
|
-
**There is no need to switch to a `config.ru` simply because you
|
2637
|
-
the modular style, and you don't have to use the modular
|
2638
|
-
a `config.ru`.**
|
2842
|
+
**There is no need to switch to a `config.ru` simply because you
|
2843
|
+
switched to the modular style, and you don't have to use the modular
|
2844
|
+
style for running with a `config.ru`.**
|
2639
2845
|
|
2640
2846
|
### Using Sinatra as Middleware
|
2641
2847
|
|
2642
|
-
Not only is Sinatra able to use other Rack middleware, any Sinatra
|
2643
|
-
can in turn be added in front of any Rack endpoint as
|
2644
|
-
endpoint could be another Sinatra application,
|
2645
|
-
application (Rails/
|
2848
|
+
Not only is Sinatra able to use other Rack middleware, any Sinatra
|
2849
|
+
application can in turn be added in front of any Rack endpoint as
|
2850
|
+
middleware itself. This endpoint could be another Sinatra application,
|
2851
|
+
or any other Rack-based application (Rails/Hanami/Roda/...):
|
2646
2852
|
|
2647
2853
|
```ruby
|
2648
2854
|
require 'sinatra/base'
|
@@ -2731,9 +2937,9 @@ available.
|
|
2731
2937
|
Every Sinatra application corresponds to a subclass of `Sinatra::Base`.
|
2732
2938
|
If you are using the top-level DSL (`require 'sinatra'`), then this
|
2733
2939
|
class is `Sinatra::Application`, otherwise it is the subclass you
|
2734
|
-
created explicitly. At class level you have methods like `get` or
|
2735
|
-
you cannot access the `request` or `session` objects, as
|
2736
|
-
single application class for all requests.
|
2940
|
+
created explicitly. At class level you have methods like `get` or
|
2941
|
+
`before`, but you cannot access the `request` or `session` objects, as
|
2942
|
+
there is only a single application class for all requests.
|
2737
2943
|
|
2738
2944
|
Options created via `set` are methods at class level:
|
2739
2945
|
|
@@ -2817,7 +3023,7 @@ being [extending the main object](https://github.com/sinatra/sinatra/blob/ca0636
|
|
2817
3023
|
Sinatra applications can be run directly:
|
2818
3024
|
|
2819
3025
|
```shell
|
2820
|
-
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
3026
|
+
ruby myapp.rb [-h] [-x] [-q] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
2821
3027
|
```
|
2822
3028
|
|
2823
3029
|
Options are:
|
@@ -2827,24 +3033,27 @@ Options are:
|
|
2827
3033
|
-p # set the port (default is 4567)
|
2828
3034
|
-o # set the host (default is 0.0.0.0)
|
2829
3035
|
-e # set the environment (default is development)
|
2830
|
-
-s # specify rack server/handler (default is
|
3036
|
+
-s # specify rack server/handler (default is puma)
|
3037
|
+
-q # turn on quiet mode for server (default is off)
|
2831
3038
|
-x # turn on the mutex lock (default is off)
|
2832
3039
|
```
|
2833
3040
|
|
2834
3041
|
### Multi-threading
|
2835
3042
|
|
2836
|
-
_Paraphrasing from
|
3043
|
+
_Paraphrasing from
|
3044
|
+
[this StackOverflow answer](https://stackoverflow.com/a/6282999/5245129)
|
3045
|
+
by Konstantin_
|
2837
3046
|
|
2838
3047
|
Sinatra doesn't impose any concurrency model, but leaves that to the
|
2839
|
-
underlying Rack handler (server) like
|
3048
|
+
underlying Rack handler (server) like Puma or WEBrick. Sinatra
|
2840
3049
|
itself is thread-safe, so there won't be any problem if the Rack handler
|
2841
3050
|
uses a threaded model of concurrency. This would mean that when starting
|
2842
3051
|
the server, you'd have to specify the correct invocation method for the
|
2843
3052
|
specific Rack handler. The following example is a demonstration of how
|
2844
|
-
to start a multi-threaded
|
3053
|
+
to start a multi-threaded Rainbows server:
|
2845
3054
|
|
2846
3055
|
```ruby
|
2847
|
-
#
|
3056
|
+
# config.ru
|
2848
3057
|
|
2849
3058
|
require 'sinatra/base'
|
2850
3059
|
|
@@ -2854,48 +3063,32 @@ class App < Sinatra::Base
|
|
2854
3063
|
end
|
2855
3064
|
end
|
2856
3065
|
|
2857
|
-
App
|
3066
|
+
run App
|
3067
|
+
```
|
3068
|
+
|
3069
|
+
```ruby
|
3070
|
+
# rainbows.conf
|
2858
3071
|
|
3072
|
+
# Rainbows configurator is based on Unicorn.
|
3073
|
+
Rainbows! do
|
3074
|
+
use :ThreadSpawn
|
3075
|
+
end
|
2859
3076
|
```
|
2860
3077
|
|
2861
3078
|
To start the server, the command would be:
|
2862
3079
|
|
2863
3080
|
```shell
|
2864
|
-
|
3081
|
+
rainbows -c rainbows.conf
|
2865
3082
|
```
|
2866
3083
|
|
2867
|
-
|
2868
|
-
[so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
|
2869
|
-
|
2870
3084
|
## Requirement
|
2871
3085
|
|
2872
3086
|
The following Ruby versions are officially supported:
|
2873
3087
|
<dl>
|
2874
|
-
<dt>Ruby
|
3088
|
+
<dt>Ruby 2.3</dt>
|
2875
3089
|
<dd>
|
2876
|
-
|
2877
|
-
|
2878
|
-
will not be dropped before Sinatra 2.0. Ruby 1.8.6 is no longer supported.
|
2879
|
-
</dd>
|
2880
|
-
|
2881
|
-
<dt>Ruby 1.9.2</dt>
|
2882
|
-
<dd>
|
2883
|
-
1.9.2 is fully supported. Do not use 1.9.2p0, as it is known to cause
|
2884
|
-
segmentation faults when running Sinatra. Official support will continue
|
2885
|
-
at least until the release of Sinatra 1.5.
|
2886
|
-
</dd>
|
2887
|
-
|
2888
|
-
<dt>Ruby 1.9.3</dt>
|
2889
|
-
<dd>
|
2890
|
-
1.9.3 is fully supported and recommended. Please note that switching to 1.9.3
|
2891
|
-
from an earlier version will invalidate all sessions. 1.9.3 will be supported
|
2892
|
-
until the release of Sinatra 2.0.
|
2893
|
-
</dd>
|
2894
|
-
|
2895
|
-
<dt>Ruby 2.x</dt>
|
2896
|
-
<dd>
|
2897
|
-
2.x is fully supported and recommended. There are currently no plans to drop
|
2898
|
-
official support for it.
|
3090
|
+
2.3 is fully supported and recommended. There are currently no plans to
|
3091
|
+
drop official support for it.
|
2899
3092
|
</dd>
|
2900
3093
|
|
2901
3094
|
<dt>Rubinius</dt>
|
@@ -2912,6 +3105,8 @@ The following Ruby versions are officially supported:
|
|
2912
3105
|
</dd>
|
2913
3106
|
</dl>
|
2914
3107
|
|
3108
|
+
Versions of Ruby prior to 2.3 are no longer supported as of Sinatra 2.1.0.
|
3109
|
+
|
2915
3110
|
We also keep an eye on upcoming Ruby versions.
|
2916
3111
|
|
2917
3112
|
The following Ruby implementations are not officially supported but still are
|
@@ -2925,9 +3120,9 @@ known to run Sinatra:
|
|
2925
3120
|
Not being officially supported means if things only break there and not on a
|
2926
3121
|
supported platform, we assume it's not our issue but theirs.
|
2927
3122
|
|
2928
|
-
We also run our CI against ruby-head (future releases of MRI), but we
|
2929
|
-
guarantee anything, since it is constantly moving. Expect upcoming
|
2930
|
-
to be fully supported.
|
3123
|
+
We also run our CI against ruby-head (future releases of MRI), but we
|
3124
|
+
can't guarantee anything, since it is constantly moving. Expect upcoming
|
3125
|
+
2.x releases to be fully supported.
|
2931
3126
|
|
2932
3127
|
Sinatra should work on any operating system supported by the chosen Ruby
|
2933
3128
|
implementation.
|
@@ -2935,12 +3130,13 @@ implementation.
|
|
2935
3130
|
If you run MacRuby, you should `gem install control_tower`.
|
2936
3131
|
|
2937
3132
|
Sinatra currently doesn't run on Cardinal, SmallRuby, BlueRuby or any
|
2938
|
-
Ruby version prior to
|
3133
|
+
Ruby version prior to 2.2.
|
2939
3134
|
|
2940
3135
|
## The Bleeding Edge
|
2941
3136
|
|
2942
|
-
If you would like to use Sinatra's latest bleeding-edge code, feel free
|
2943
|
-
application against the master branch, it should be rather
|
3137
|
+
If you would like to use Sinatra's latest bleeding-edge code, feel free
|
3138
|
+
to run your application against the master branch, it should be rather
|
3139
|
+
stable.
|
2944
3140
|
|
2945
3141
|
We also push out prerelease gems from time to time, so you can do a
|
2946
3142
|
|
@@ -2953,7 +3149,7 @@ to get some of the latest features.
|
|
2953
3149
|
### With Bundler
|
2954
3150
|
|
2955
3151
|
If you want to run your application with the latest Sinatra, using
|
2956
|
-
[Bundler](
|
3152
|
+
[Bundler](https://bundler.io) is the recommended way.
|
2957
3153
|
|
2958
3154
|
First, install bundler, if you haven't:
|
2959
3155
|
|
@@ -2965,16 +3161,15 @@ Then, in your project directory, create a `Gemfile`:
|
|
2965
3161
|
|
2966
3162
|
```ruby
|
2967
3163
|
source 'https://rubygems.org'
|
2968
|
-
gem 'sinatra', :github =>
|
3164
|
+
gem 'sinatra', :github => 'sinatra/sinatra'
|
2969
3165
|
|
2970
3166
|
# other dependencies
|
2971
3167
|
gem 'haml' # for instance, if you use haml
|
2972
|
-
gem 'activerecord', '~> 3.0' # maybe you also need ActiveRecord 3.x
|
2973
3168
|
```
|
2974
3169
|
|
2975
|
-
Note that you will have to list all your application's dependencies in
|
2976
|
-
Sinatra's direct dependencies (Rack and Tilt) will,
|
2977
|
-
fetched and added by Bundler.
|
3170
|
+
Note that you will have to list all your application's dependencies in
|
3171
|
+
the `Gemfile`. Sinatra's direct dependencies (Rack and Tilt) will,
|
3172
|
+
however, be automatically fetched and added by Bundler.
|
2978
3173
|
|
2979
3174
|
Now you can run your app like this:
|
2980
3175
|
|
@@ -2982,44 +3177,9 @@ Now you can run your app like this:
|
|
2982
3177
|
bundle exec ruby myapp.rb
|
2983
3178
|
```
|
2984
3179
|
|
2985
|
-
### Roll Your Own
|
2986
|
-
|
2987
|
-
Create a local clone and run your app with the `sinatra/lib` directory
|
2988
|
-
on the `$LOAD_PATH`:
|
2989
|
-
|
2990
|
-
```shell
|
2991
|
-
cd myapp
|
2992
|
-
git clone git://github.com/sinatra/sinatra.git
|
2993
|
-
ruby -I sinatra/lib myapp.rb
|
2994
|
-
```
|
2995
|
-
|
2996
|
-
To update the Sinatra sources in the future:
|
2997
|
-
|
2998
|
-
```shell
|
2999
|
-
cd myapp/sinatra
|
3000
|
-
git pull
|
3001
|
-
```
|
3002
|
-
|
3003
|
-
### Install Globally
|
3004
|
-
|
3005
|
-
You can build the gem on your own:
|
3006
|
-
|
3007
|
-
```shell
|
3008
|
-
git clone git://github.com/sinatra/sinatra.git
|
3009
|
-
cd sinatra
|
3010
|
-
rake sinatra.gemspec
|
3011
|
-
rake install
|
3012
|
-
```
|
3013
|
-
|
3014
|
-
If you install gems as root, the last step should be:
|
3015
|
-
|
3016
|
-
```shell
|
3017
|
-
sudo rake install
|
3018
|
-
```
|
3019
|
-
|
3020
3180
|
## Versioning
|
3021
3181
|
|
3022
|
-
Sinatra follows [Semantic Versioning](
|
3182
|
+
Sinatra follows [Semantic Versioning](https://semver.org/), both SemVer and
|
3023
3183
|
SemVerTag.
|
3024
3184
|
|
3025
3185
|
## Further Reading
|
@@ -3030,14 +3190,14 @@ SemVerTag.
|
|
3030
3190
|
help? Have a patch?
|
3031
3191
|
* [Issue tracker](https://github.com/sinatra/sinatra/issues)
|
3032
3192
|
* [Twitter](https://twitter.com/sinatra)
|
3033
|
-
* [Mailing List](
|
3034
|
-
* IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on
|
3035
|
-
* [Sinatra & Friends](https://sinatrarb.slack.com) on Slack
|
3036
|
-
[
|
3037
|
-
* [Sinatra Book](https://github.com/sinatra/sinatra-book
|
3038
|
-
* [Sinatra Recipes](http://recipes.sinatrarb.com/) Community
|
3039
|
-
|
3193
|
+
* [Mailing List](https://groups.google.com/forum/#!forum/sinatrarb)
|
3194
|
+
* IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on [Freenode](https://freenode.net)
|
3195
|
+
* [Sinatra & Friends](https://sinatrarb.slack.com) on Slack
|
3196
|
+
([get an invite](https://sinatra-slack.herokuapp.com/))
|
3197
|
+
* [Sinatra Book](https://github.com/sinatra/sinatra-book) - Cookbook Tutorial
|
3198
|
+
* [Sinatra Recipes](http://recipes.sinatrarb.com/) - Community contributed
|
3199
|
+
recipes
|
3040
3200
|
* API documentation for the [latest release](http://www.rubydoc.info/gems/sinatra)
|
3041
3201
|
or the [current HEAD](http://www.rubydoc.info/github/sinatra/sinatra) on
|
3042
|
-
http://www.rubydoc.info/
|
3202
|
+
[RubyDoc](http://www.rubydoc.info/)
|
3043
3203
|
* [CI server](https://travis-ci.org/sinatra/sinatra)
|