sinatra 1.4.6 โ†’ 2.0.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.

Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHORS.md +5 -2
  3. data/{CHANGES โ†’ CHANGELOG.md} +126 -46
  4. data/CONTRIBUTING.md +100 -0
  5. data/Gemfile +12 -17
  6. data/LICENSE +5 -2
  7. data/MAINTENANCE.md +42 -0
  8. data/README.de.md +711 -466
  9. data/README.es.md +206 -171
  10. data/README.fr.md +370 -344
  11. data/README.hu.md +44 -10
  12. data/README.ja.md +300 -210
  13. data/README.ko.md +230 -191
  14. data/README.md +675 -528
  15. data/README.pt-br.md +149 -115
  16. data/README.pt-pt.md +65 -65
  17. data/README.ru.md +198 -97
  18. data/README.zh.md +1943 -1237
  19. data/Rakefile +72 -49
  20. data/SECURITY.md +35 -0
  21. data/lib/sinatra/base.rb +141 -207
  22. data/lib/sinatra/indifferent_hash.rb +150 -0
  23. data/lib/sinatra/main.rb +1 -0
  24. data/lib/sinatra/show_exceptions.rb +70 -56
  25. data/lib/sinatra/version.rb +1 -1
  26. data/sinatra.gemspec +19 -7
  27. metadata +32 -163
  28. data/test/asciidoctor_test.rb +0 -72
  29. data/test/base_test.rb +0 -167
  30. data/test/builder_test.rb +0 -91
  31. data/test/coffee_test.rb +0 -96
  32. data/test/compile_test.rb +0 -183
  33. data/test/contest.rb +0 -91
  34. data/test/creole_test.rb +0 -65
  35. data/test/delegator_test.rb +0 -160
  36. data/test/encoding_test.rb +0 -20
  37. data/test/erb_test.rb +0 -116
  38. data/test/extensions_test.rb +0 -98
  39. data/test/filter_test.rb +0 -487
  40. data/test/haml_test.rb +0 -109
  41. data/test/helper.rb +0 -132
  42. data/test/helpers_test.rb +0 -1917
  43. data/test/integration/app.rb +0 -79
  44. data/test/integration_helper.rb +0 -236
  45. data/test/integration_test.rb +0 -104
  46. data/test/less_test.rb +0 -69
  47. data/test/liquid_test.rb +0 -77
  48. data/test/mapped_error_test.rb +0 -285
  49. data/test/markaby_test.rb +0 -80
  50. data/test/markdown_test.rb +0 -85
  51. data/test/mediawiki_test.rb +0 -68
  52. data/test/middleware_test.rb +0 -68
  53. data/test/nokogiri_test.rb +0 -67
  54. data/test/public/favicon.ico +0 -0
  55. data/test/rabl_test.rb +0 -89
  56. data/test/rack_test.rb +0 -45
  57. data/test/radius_test.rb +0 -59
  58. data/test/rdoc_test.rb +0 -66
  59. data/test/readme_test.rb +0 -130
  60. data/test/request_test.rb +0 -100
  61. data/test/response_test.rb +0 -63
  62. data/test/result_test.rb +0 -76
  63. data/test/route_added_hook_test.rb +0 -59
  64. data/test/routing_test.rb +0 -1412
  65. data/test/sass_test.rb +0 -115
  66. data/test/scss_test.rb +0 -88
  67. data/test/server_test.rb +0 -56
  68. data/test/settings_test.rb +0 -582
  69. data/test/sinatra_test.rb +0 -12
  70. data/test/slim_test.rb +0 -102
  71. data/test/static_test.rb +0 -236
  72. data/test/streaming_test.rb +0 -149
  73. data/test/stylus_test.rb +0 -90
  74. data/test/templates_test.rb +0 -382
  75. data/test/textile_test.rb +0 -65
  76. data/test/views/a/in_a.str +0 -1
  77. data/test/views/ascii.erb +0 -2
  78. data/test/views/b/in_b.str +0 -1
  79. data/test/views/calc.html.erb +0 -1
  80. data/test/views/error.builder +0 -3
  81. data/test/views/error.erb +0 -3
  82. data/test/views/error.haml +0 -3
  83. data/test/views/error.sass +0 -2
  84. data/test/views/explicitly_nested.str +0 -1
  85. data/test/views/foo/hello.test +0 -1
  86. data/test/views/hello.asciidoc +0 -1
  87. data/test/views/hello.builder +0 -1
  88. data/test/views/hello.coffee +0 -1
  89. data/test/views/hello.creole +0 -1
  90. data/test/views/hello.erb +0 -1
  91. data/test/views/hello.haml +0 -1
  92. data/test/views/hello.less +0 -5
  93. data/test/views/hello.liquid +0 -1
  94. data/test/views/hello.mab +0 -1
  95. data/test/views/hello.md +0 -1
  96. data/test/views/hello.mediawiki +0 -1
  97. data/test/views/hello.nokogiri +0 -1
  98. data/test/views/hello.rabl +0 -2
  99. data/test/views/hello.radius +0 -1
  100. data/test/views/hello.rdoc +0 -1
  101. data/test/views/hello.sass +0 -2
  102. data/test/views/hello.scss +0 -3
  103. data/test/views/hello.slim +0 -1
  104. data/test/views/hello.str +0 -1
  105. data/test/views/hello.styl +0 -2
  106. data/test/views/hello.test +0 -1
  107. data/test/views/hello.textile +0 -1
  108. data/test/views/hello.wlang +0 -1
  109. data/test/views/hello.yajl +0 -1
  110. data/test/views/layout2.builder +0 -3
  111. data/test/views/layout2.erb +0 -2
  112. data/test/views/layout2.haml +0 -2
  113. data/test/views/layout2.liquid +0 -2
  114. data/test/views/layout2.mab +0 -2
  115. data/test/views/layout2.nokogiri +0 -3
  116. data/test/views/layout2.rabl +0 -3
  117. data/test/views/layout2.radius +0 -2
  118. data/test/views/layout2.slim +0 -3
  119. data/test/views/layout2.str +0 -2
  120. data/test/views/layout2.test +0 -1
  121. data/test/views/layout2.wlang +0 -2
  122. data/test/views/nested.str +0 -1
  123. data/test/views/utf8.erb +0 -2
  124. data/test/wlang_test.rb +0 -87
  125. data/test/yajl_test.rb +0 -86
data/README.ko.md CHANGED
@@ -3,9 +3,9 @@
3
3
  *์ฃผ์˜: ์ด ๋ฌธ์„œ๋Š” ์˜๋ฌธํŒ์˜ ๋ฒˆ์—ญ๋ณธ์ด๋ฉฐ ์ตœ์‹ ํŒ ๋ฌธ์„œ์™€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.*
4
4
 
5
5
  Sinatra๋Š” ์ตœ์†Œํ•œ์˜ ๋…ธ๋ ฅ์œผ๋กœ ๋ฃจ๋น„ ๊ธฐ๋ฐ˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹ ์†ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ
6
- ํ•ด ์ฃผ๋Š” [DSL](http://en.wikipedia.org/wiki/Domain-specific_language)์ž…๋‹ˆ๋‹ค.
6
+ ํ•ด ์ฃผ๋Š” [DSL](https://en.wikipedia.org/wiki/Domain-specific_language)์ž…๋‹ˆ๋‹ค.
7
7
 
8
- ``` ruby
8
+ ```ruby
9
9
  # myapp.rb
10
10
  require 'sinatra'
11
11
 
@@ -14,19 +14,19 @@ get '/' do
14
14
  end
15
15
  ```
16
16
 
17
- ์ ฌ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
17
+ ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋กœ ์ ฌ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
18
18
 
19
- ``` shell
19
+ ```shell
20
20
  gem install sinatra
21
21
  ```
22
22
 
23
- ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
23
+ ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
24
24
 
25
- ``` shell
25
+ ```shell
26
26
  ruby myapp.rb
27
27
  ```
28
28
 
29
- `http://localhost:4567`๋ฅผ ํ™•์ธํ•ด ๋ณด์„ธ์š”.
29
+ [http://localhost:4567](http://localhost:4567) ๋ฅผ ํ™•์ธํ•ด ๋ณด์„ธ์š”.
30
30
 
31
31
  `gem install thin`๋„ ํ•จ๊ป˜ ์‹คํ–‰ํ•˜๊ธฐ๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
32
32
  thin์ด ์„ค์น˜๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ Sinatra๋Š” thin์„ ํ†ตํ•ด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
@@ -111,6 +111,7 @@ thin์ด ์„ค์น˜๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ Sinatra๋Š” thin์„ ํ†ตํ•ด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
111
111
  * [์š”์ฒญ/์ธ์Šคํ„ด์Šค ๋ฒ”์œ„](#์š”์ฒญ์ธ์Šคํ„ด์Šค-๋ฒ”์œ„)
112
112
  * [์œ„์ž„ ๋ฒ”์œ„(Delegation Scope)](#์œ„์ž„-๋ฒ”์œ„delegation-scope)
113
113
  * [๋ช…๋ นํ–‰(Command Line)](#๋ช…๋ นํ–‰command-line)
114
+ * [๋‹ค์ค‘ ์Šค๋ ˆ๋“œ(Multi-threading)](#๋‹ค์ค‘-์Šค๋ ˆ๋“œmulti-threading)
114
115
  * [์š”๊ตฌ์‚ฌํ•ญ(Requirement)](#์š”๊ตฌ์‚ฌํ•ญrequirement)
115
116
  * [์ตœ์‹ (The Bleeding Edge)](#์ตœ์‹ the-bleeding-edge)
116
117
  * [Bundler๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ](#bundler๋ฅผ-์‚ฌ์šฉํ•˜์—ฌ)
@@ -124,7 +125,7 @@ thin์ด ์„ค์น˜๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ Sinatra๋Š” thin์„ ํ†ตํ•ด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
124
125
  Sinatra์—์„œ, ๋ผ์šฐํ„ฐ(route)๋Š” URL-๋งค์นญ ํŒจํ„ด๊ณผ ์Œ์„ ์ด๋ฃจ๋Š” HTTP ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
125
126
  ๊ฐ๊ฐ์˜ ๋ผ์šฐํ„ฐ๋Š” ๋ธ”๋ก๊ณผ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.
126
127
 
127
- ``` ruby
128
+ ```ruby
128
129
  get '/' do
129
130
  .. ๋ฌด์–ธ๊ฐ€ ๋ณด์—ฌ์ฃผ๊ธฐ(show) ..
130
131
  end
@@ -162,7 +163,7 @@ end
162
163
 
163
164
  ๋ผ์šฐํ„ฐ ํŒจํ„ด์—๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, `params` ํ•ด์‹œ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
164
165
 
165
- ``` ruby
166
+ ```ruby
166
167
  get '/hello/:name' do
167
168
  # "GET /hello/foo" ๋ฐ "GET /hello/bar"์™€ ๋งค์น˜
168
169
  # params['name']์€ 'foo' ๋˜๋Š” 'bar'
@@ -172,7 +173,7 @@ end
172
173
 
173
174
  ๋˜ํ•œ ๋ธ”๋ก ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•˜์—ฌ๋„ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
174
175
 
175
- ``` ruby
176
+ ```ruby
176
177
  get '/hello/:name' do |n|
177
178
  # "GET /hello/foo" ๋ฐ "GET /hello/bar"์™€ ๋งค์น˜
178
179
  # params['name']์€ 'foo' ๋˜๋Š” 'bar'
@@ -183,7 +184,7 @@ end
183
184
 
184
185
  ๋ผ์šฐํ„ฐ ํŒจํ„ด์—๋Š” ์Šคํ”Œ๋žซ(splat, ๋˜๋Š” ์™€์ผ๋“œ์นด๋“œ)๋„ ๋งค๊ฐœ๋ณ€์ˆ˜๋„ ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Ÿด ๊ฒฝ์šฐ `params['splat']` ๋ฐฐ์—ด์„ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
185
186
 
186
- ``` ruby
187
+ ```ruby
187
188
  get '/say/*/to/*' do
188
189
  # /say/hello/to/world์™€ ๋งค์น˜
189
190
  params['splat'] # => ["hello", "world"]
@@ -197,7 +198,7 @@ end
197
198
 
198
199
  ๋ธ”๋ก ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
199
200
 
200
- ``` ruby
201
+ ```ruby
201
202
  get '/download/*.*' do |path, ext|
202
203
  [path, ext] # => ["path/to/file", "xml"]
203
204
  end
@@ -205,15 +206,15 @@ end
205
206
 
206
207
  ๋ผ์šฐํ„ฐ๋Š” ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ๋งค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
207
208
 
208
- ``` ruby
209
- get /\A\/hello\/([\w]+)\z/ do
209
+ ```ruby
210
+ get /\/hello\/([\w]+)/ do
210
211
  "Hello, #{params['captures'].first}!"
211
212
  end
212
213
  ```
213
214
 
214
215
  ๋ธ”๋ก ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
215
216
 
216
- ``` ruby
217
+ ```ruby
217
218
  get %r{/hello/([\w]+)} do |c|
218
219
  # "GET /meta/hello/world", "GET /hello/world/1234" ๋“ฑ๊ณผ ๋งค์น˜
219
220
  "Hello, #{c}!"
@@ -222,15 +223,15 @@ end
222
223
 
223
224
  ๋ผ์šฐํ„ฐ ํŒจํ„ด์—๋Š” ์„ ํƒ์ ์ธ(optional) ๋งค๊ฐœ๋ณ€์ˆ˜๋„ ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
224
225
 
225
- ``` ruby
226
- get '/posts.?:format?' do
227
- # "GET /posts" ๋Š” ๋ฌผ๋ก  "GET /posts.json", "GET /posts.xml" ์™€ ๊ฐ™์€ ์–ด๋–ค ํ™•์žฅ์ž์™€๋„ ๋งค์นญ
226
+ ```ruby
227
+ get '/posts/:format?' do
228
+ # "GET /posts/" ๋Š” ๋ฌผ๋ก  "GET /posts/json", "GET /posts/xml" ์™€ ๊ฐ™์€ ์–ด๋–ค ํ™•์žฅ์ž์™€๋„ ๋งค์นญ
228
229
  end
229
230
  ```
230
231
 
231
232
  ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฉ”ํ„ฐ๋กœ๋„ ์ด์šฉ๊ฐ€๋Šฅ ํ•ฉ๋‹ˆ๋‹ค.
232
233
 
233
- ``` ruby
234
+ ```ruby
234
235
  get '/posts' do
235
236
  # matches "GET /posts?title=foo&author=bar"
236
237
  title = params['title']
@@ -246,7 +247,7 @@ end
246
247
 
247
248
  ๋ผ์šฐํ„ฐ๋Š” ์‚ฌ์šฉ์ž ์—์ด์ „ํŠธ(user agent)๊ฐ™์€ ๋‹ค์–‘ํ•œ ๋งค์นญ ์กฐ๊ฑด์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
248
249
 
249
- ``` ruby
250
+ ```ruby
250
251
  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
251
252
  "Songbird ๋ฒ„์ „ #{params['agent'][0]}์„ ์‚ฌ์šฉํ•˜๋Š”๊ตฐ์š”!"
252
253
  end
@@ -258,7 +259,7 @@ end
258
259
 
259
260
  ๋‹ค๋ฅธ ๊ฐ€๋Šฅํ•œ ์กฐ๊ฑด์—๋Š” `host_name`๊ณผ `provides`๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
260
261
 
261
- ``` ruby
262
+ ```ruby
262
263
  get '/', :host_name => /^admin\./ do
263
264
  "Admin Area, Access denied!"
264
265
  end
@@ -275,7 +276,7 @@ end
275
276
 
276
277
  ์‚ฌ์šฉ์ž ์ •์˜ ์กฐ๊ฑด๋„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
277
278
 
278
- ``` ruby
279
+ ```ruby
279
280
  set(:probability) { |value| condition { rand <= value } }
280
281
 
281
282
  get '/win_a_car', :probability => 0.1 do
@@ -289,7 +290,7 @@ end
289
290
 
290
291
  ์—ฌ๋Ÿฌ ๊ฐ’์„ ๋ฐ›๋Š” ์กฐ๊ฑด์—๋Š” ์Šคํ”Œ๋žซ(splat)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
291
292
 
292
- ``` ruby
293
+ ```ruby
293
294
  set(:auth) do |*roles| # <- ์ด๊ฒŒ ์Šคํ”Œ๋žซ
294
295
  condition do
295
296
  unless logged_in? && roles.any? {|role| current_user.in_role? role }
@@ -321,7 +322,7 @@ end
321
322
 
322
323
  ์ด๊ฒƒ์„ ์ด์šฉํ•œ ์˜ˆ๋ฅผ ๋“ค์ž๋ฉด, ์ŠคํŠธ๋ฆฌ๋ฐ(streaming) ์˜ˆ์ œ๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
323
324
 
324
- ``` ruby
325
+ ```ruby
325
326
  class Stream
326
327
  def each
327
328
  100.times { |i| yield "#{i}\n" }
@@ -338,7 +339,7 @@ get('/') { Stream.new }
338
339
  ์œ„์—์„œ ๋ณด๋“ฏ, Sinatra์—๋Š” ๋ฌธ์ž์—ด ํŒจํ„ด ๋ฐ ์ •๊ทœํ‘œํ˜„์‹์„ ์ด์šฉํ•œ ๋ผ์šฐํ„ฐ ๋งค์นญ ์ง€์›์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
339
340
  ํ•˜์ง€๋งŒ, ๊ทธ๊ฒŒ ๋์€ ์•„๋‹™๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„ ๋งŒ์˜ ๋งค์ฒ˜(matcher)๋„ ์‰ฝ๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
340
341
 
341
- ``` ruby
342
+ ```ruby
342
343
  class AllButPattern
343
344
  Match = Struct.new(:captures)
344
345
 
@@ -363,7 +364,7 @@ end
363
364
 
364
365
  ์‚ฌ์‹ค ์œ„์˜ ์˜ˆ์ œ๋Š” ์กฐ๊ธˆ ๊ณผํ•˜๊ฒŒ ์ž‘์„ฑ๋œ ๋ฉด์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜๋„ ์žˆ์–ด์š”.
365
366
 
366
- ``` ruby
367
+ ```ruby
367
368
  get // do
368
369
  pass if request.path_info == "/index"
369
370
  # ...
@@ -372,8 +373,8 @@ end
372
373
 
373
374
  ๋˜๋Š” ๊ฑฐ๊พธ๋กœ ํƒ์ƒ‰(negative look ahead)ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
374
375
 
375
- ``` ruby
376
- get %r{^(?!/index$)} do
376
+ ```ruby
377
+ get %r{(?!/index)} do
377
378
  # ...
378
379
  end
379
380
  ```
@@ -383,12 +384,12 @@ end
383
384
  ์ •์  ํŒŒ์ผ๋“ค์€ `./public` ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์œ„์น˜๋ฅผ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ
384
385
  ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด `:public_folder` ์˜ต์…˜์„ ์ง€์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
385
386
 
386
- ``` ruby
387
+ ```ruby
387
388
  set :public_folder, File.dirname(__FILE__) + '/static'
388
389
  ```
389
390
 
390
391
  public ๋””๋ ‰ํ„ฐ๋ฆฌ๋ช…์€ URL์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•˜์„ธ์š”.
391
- `./public/css/style.css` ํŒŒ์ผ์€ ์•„๋งˆ `http://example.com/css/style.css` ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
392
+ `./public/css/style.css` ํŒŒ์ผ์€ ์•„๋งˆ `http://example.com/css/style.css` ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
392
393
 
393
394
  `Cache-Control` ํ—ค๋” ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด `:static_cache_control` ์„ค์ •(์•„๋ž˜ ์ฐธ์กฐ)์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
394
395
 
@@ -397,7 +398,7 @@ public ๋””๋ ‰ํ„ฐ๋ฆฌ๋ช…์€ URL์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•˜์„ธ
397
398
  ํ…œํ”Œ๋ฆฟ ์–ธ์–ด๋“ค์€ ๊ฐ๊ฐ์˜ ๋ Œ๋”๋ง ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ‘œ์ถœ๋ฉ๋‹ˆ๋‹ค.
398
399
  ์ด๋“ค ๋ฉ”์„œ๋“œ๋Š” ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•  ๋ฟ์ž…๋‹ˆ๋‹ค.
399
400
 
400
- ``` ruby
401
+ ```ruby
401
402
  get '/' do
402
403
  erb :index
403
404
  end
@@ -407,7 +408,7 @@ end
407
408
 
408
409
  ํ…œํ”Œ๋ฆฟ ์ด๋ฆ„ ๋Œ€์‹  ํ…œํ”Œ๋ฆฟ์˜ ๋‚ด์šฉ์„ ์ง์ ‘ ๋„˜๊ธธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
409
410
 
410
- ``` ruby
411
+ ```ruby
411
412
  get '/' do
412
413
  code = "<%= Time.now %>"
413
414
  erb code
@@ -416,7 +417,7 @@ end
416
417
 
417
418
  ํ…œํ”Œ๋ฆฟ์€ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์˜ต์…˜๊ฐ’์˜ ํ•ด์‹œ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
418
419
 
419
- ``` ruby
420
+ ```ruby
420
421
  get '/' do
421
422
  erb :index, :layout => :post
422
423
  end
@@ -427,7 +428,7 @@ end
427
428
 
428
429
  Sinatra๊ฐ€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ชจ๋“  ์˜ต์…˜๊ฐ’๋“ค์€ ํ…œํ”Œ๋ฆฟ ์—”์ง„์œผ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.
429
430
 
430
- ``` ruby
431
+ ```ruby
431
432
  get '/' do
432
433
  haml :index, :format => :html5
433
434
  end
@@ -435,7 +436,7 @@ end
435
436
 
436
437
  ์˜ต์…˜๊ฐ’์€ ํ…œํ”Œ๋ฆฟ ์–ธ์–ด๋ณ„๋กœ ์ „์—ญ์ ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
437
438
 
438
- ``` ruby
439
+ ```ruby
439
440
  set :haml, :format => :html5
440
441
 
441
442
  get '/' do
@@ -495,7 +496,7 @@ render ๋ฉ”์„œ๋“œ์—์„œ ์ „๋‹ฌ๋œ ์˜ต์…˜๊ฐ’๋“ค์€ `set`์„ ํ†ตํ•ด ์„ค์ •ํ•œ ์˜ต
495
496
  ํ…œํ”Œ๋ฆฟ์€ `./views` ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ€์ •๋ฉ๋‹ˆ๋‹ค. ๋ทฐ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ
496
497
  ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ํ•˜๊ณ  ์‹ถ์œผ์‹œ๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜์„ธ์š”.
497
498
 
498
- ``` ruby
499
+ ```ruby
499
500
  set :views, settings.root + '/templates'
500
501
  ```
501
502
 
@@ -506,7 +507,7 @@ set :views, settings.root + '/templates'
506
507
 
507
508
  ### ๋ฆฌํ„ฐ๋Ÿด ํ…œํ”Œ๋ฆฟ(Literal Templates)
508
509
 
509
- ``` ruby
510
+ ```ruby
510
511
  get '/' do
511
512
  haml '%div.title Hello World'
512
513
  end
@@ -519,7 +520,7 @@ end
519
520
  ์ผ๋ถ€ ์–ธ์–ด๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ตฌํ˜„์ด ์žˆ์Šต๋‹ˆ๋‹ค. (์Šค๋ ˆ๋“œ์— ์•ˆ์ „ํ•˜๊ฒŒ thread-safe) ์–ด๋Š ๊ตฌํ˜„์„
520
521
  ์‚ฌ์šฉํ• ์ง€ ์ €์ •ํ•˜๋ ค๋ฉด, ๋จผ์ € require ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
521
522
 
522
- ``` ruby
523
+ ```ruby
523
524
  require 'rdiscount' # or require 'bluecloth'
524
525
  get('/') { markdown :index }
525
526
  ```
@@ -582,7 +583,7 @@ get('/') { markdown :index }
582
583
  <table>
583
584
  <tr>
584
585
  <td>์˜์กด์„ฑ</td>
585
- <td><a href="http://nokogiri.org/">nokogiri</a></td>
586
+ <td><a href="http://www.nokogiri.org/">nokogiri</a></td>
586
587
  </tr>
587
588
  <tr>
588
589
  <td>ํŒŒ์ผ ํ™•์žฅ์ž</td>
@@ -635,7 +636,7 @@ get('/') { markdown :index }
635
636
  <table>
636
637
  <tr>
637
638
  <td>์˜์กด์„ฑ</td>
638
- <td><a href="http://www.lesscss.org/">less</a></td>
639
+ <td><a href="http://lesscss.org/">less</a></td>
639
640
  </tr>
640
641
  <tr>
641
642
  <td>ํŒŒ์ผ ํ™•์žฅ์ž</td>
@@ -652,7 +653,7 @@ get('/') { markdown :index }
652
653
  <table>
653
654
  <tr>
654
655
  <td>์˜์กด์„ฑ</td>
655
- <td><a href="http://www.liquidmarkup.org/">liquid</a></td>
656
+ <td><a href="http://liquidmarkup.org/">liquid</a></td>
656
657
  </tr>
657
658
  <tr>
658
659
  <td>ํŒŒ์ผ ํ™•์žฅ์ž</td>
@@ -673,7 +674,7 @@ Liquid ํ…œํ”Œ๋ฆฟ์—์„œ๋Š” ๋ฃจ๋น„ ๋ฉ”์„œ๋“œ(`yield` ์ œ์™ธ)๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†
673
674
  <tr>
674
675
  <td>์˜์กด์„ฑ</td>
675
676
  <td>
676
- <a href="https://github.com/rtomayko/rdiscount" title="RDiscount">RDiscount</a>,
677
+ <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
677
678
  <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
678
679
  <a href="http://deveiate.org/projects/BlueCloth" title="BlueCloth">BlueCloth</a>,
679
680
  <a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
@@ -694,13 +695,13 @@ Liquid ํ…œํ”Œ๋ฆฟ์—์„œ๋Š” ๋ฃจ๋น„ ๋ฉ”์„œ๋“œ(`yield` ์ œ์™ธ)๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†
694
695
  Markdown์—์„œ๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋ฟ ์•„๋‹ˆ๋ผ locals ์ „๋‹ฌ๋„ ์•ˆ๋ฉ๋‹ˆ๋‹ค.
695
696
  ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๋‹ค๋ฅธ ๋ Œ๋”๋ง ์—”์ง„๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
696
697
 
697
- ``` ruby
698
+ ```ruby
698
699
  erb :overview, :locals => { :text => markdown(:introduction) }
699
700
  ```
700
701
 
701
702
  ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ ์†์—์„œ `markdown` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
702
703
 
703
- ``` ruby
704
+ ```ruby
704
705
  %h1 ์•ˆ๋…• Haml!
705
706
  %p= markdown(:greetings)
706
707
  ```
@@ -729,13 +730,13 @@ Markdown์—์„œ ๋ฃจ๋น„๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, Markdown์œผ๋กœ ์ž‘์„ฑ
729
730
  Textile์—์„œ๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋ฟ ์•„๋‹ˆ๋ผ locals ์ „๋‹ฌ๋„ ์•ˆ๋ฉ๋‹ˆ๋‹ค.
730
731
  ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๋‹ค๋ฅธ ๋ Œ๋”๋ง ์—”์ง„๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
731
732
 
732
- ``` ruby
733
+ ```ruby
733
734
  erb :overview, :locals => { :text => textile(:introduction) }
734
735
  ```
735
736
 
736
737
  ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ ์†์—์„œ `textile` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
737
738
 
738
- ``` ruby
739
+ ```ruby
739
740
  %h1 ์•ˆ๋…• Haml!
740
741
  %p= textile(:greetings)
741
742
  ```
@@ -764,13 +765,13 @@ Textile์—์„œ ๋ฃจ๋น„๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, Textile์œผ๋กœ ์ž‘์„ฑ๋œ
764
765
  RDoc์—์„œ๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋ฟ ์•„๋‹ˆ๋ผ locals ์ „๋‹ฌ๋„ ์•ˆ๋ฉ๋‹ˆ๋‹ค.
765
766
  ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๋‹ค๋ฅธ ๋ Œ๋”๋ง ์—”์ง„๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
766
767
 
767
- ``` ruby
768
+ ```ruby
768
769
  erb :overview, :locals => { :text => rdoc(:introduction) }
769
770
  ```
770
771
 
771
772
  ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ ์†์—์„œ `rdoc` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
772
773
 
773
- ``` ruby
774
+ ```ruby
774
775
  %h1 Hello From Haml!
775
776
  %p= rdoc(:greetings)
776
777
  ```
@@ -824,7 +825,7 @@ Radius ํ…œํ”Œ๋ฆฟ์—์„œ๋Š” ๋ฃจ๋น„ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ธฐ
824
825
  <table>
825
826
  <tr>
826
827
  <td>์˜์กด์„ฑ</td>
827
- <td><a href="http://markaby.github.com/">markaby</a></td>
828
+ <td><a href="http://markaby.github.io/">markaby</a></td>
828
829
  </tr>
829
830
  <tr>
830
831
  <td>ํŒŒ์ผํ™•์žฅ</td>
@@ -892,13 +893,13 @@ Radius ํ…œํ”Œ๋ฆฟ์—์„œ๋Š” ๋ฃจ๋น„ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ธฐ
892
893
  Creole์—์„œ๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋ฟ ์•„๋‹ˆ๋ผ locals ์ „๋‹ฌ๋„ ์•ˆ๋ฉ๋‹ˆ๋‹ค.
893
894
  ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๋‹ค๋ฅธ ๋ Œ๋”๋ง ์—”์ง„๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
894
895
 
895
- ``` ruby
896
+ ```ruby
896
897
  erb :overview, :locals => { :text => creole(:introduction) }
897
898
  ```
898
899
 
899
900
  ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ ์†์—์„œ `creole` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
900
901
 
901
- ``` ruby
902
+ ```ruby
902
903
  %h1 Hello From Haml!
903
904
  %p= creole(:greetings)
904
905
  ```
@@ -927,13 +928,13 @@ Creole์—์„œ ๋ฃจ๋น„๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, Creole์œผ๋กœ ์ž‘์„ฑ๋œ
927
928
  MediaWiki ๋งˆํฌ์—…์—์„œ๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋ฟ ์•„๋‹ˆ๋ผ locals ์ „๋‹ฌ๋„ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
928
929
  ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๋‹ค๋ฅธ ๋ Œ๋”๋ง ์—”์ง„๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
929
930
 
930
- ``` ruby
931
+ ```ruby
931
932
  erb :overview, :locals => { :text => mediawiki(:introduction) }
932
933
  ```
933
934
 
934
935
  ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ ์†์—์„œ `mediawiki` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
935
936
 
936
- ``` ruby
937
+ ```ruby
937
938
  %h1 Hello From Haml!
938
939
  %p= mediawiki(:greetings)
939
940
  ```
@@ -972,7 +973,7 @@ MediaWiki์—์„œ ๋ฃจ๋น„๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, MediaWiki์œผ๋กœ ์ž‘์„ฑ
972
973
  <tr>
973
974
  <td>์˜์กด์„ฑ</td>
974
975
  <td>
975
- <a href="https://github.com/lucasmazza/ruby-stylus" title="Ruby Stylus">
976
+ <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
976
977
  Stylus
977
978
  </a> ์™€
978
979
  <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
@@ -993,7 +994,7 @@ MediaWiki์—์„œ ๋ฃจ๋น„๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, MediaWiki์œผ๋กœ ์ž‘์„ฑ
993
994
  Stylus ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด, ๋จผ์ € `stylus`์™€ `stylus/tilt`๋ฅผ ๋กœ๋“œ
994
995
  ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
995
996
 
996
- ``` ruby
997
+ ```ruby
997
998
  require 'sinatra'
998
999
  require 'stylus'
999
1000
  require 'stylus/tilt'
@@ -1029,7 +1030,7 @@ end
1029
1030
 
1030
1031
  ํ…œํ”Œ๋ฆฟ ์†Œ์Šค๋Š” ๋ฃจ๋น„ ๋ฌธ์ž์—ด๋กœ ํ‰๊ฐ€(evaluate)๋˜๊ณ , ๊ฒฐ๊ณผ์ธ json ๋ณ€์ˆ˜๋Š” `#to_json`์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
1031
1032
 
1032
- ``` ruby
1033
+ ```ruby
1033
1034
  json = { :foo => 'bar' }
1034
1035
  json[:baz] = key
1035
1036
  ```
@@ -1067,7 +1068,7 @@ WLang์œผ๋กœ ์“ฐ์—ฌ์ง„ ๋ ˆ์ด์•„์›ƒ๊ณผ `yield`๋Š” ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
1067
1068
  ํ…œํ”Œ๋ฆฟ์€ ๋ผ์šฐํ„ฐ ํ•ธ๋“ค๋Ÿฌ์™€ ๊ฐ™์€ ๋งฅ๋ฝ(context)์—์„œ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ๋ผ์šฐํ„ฐ
1068
1069
  ํ•ธ๋“ค๋Ÿฌ์—์„œ ์„ค์ •ํ•œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋“ค์€ ํ…œํ”Œ๋ฆฟ์—์„œ ์ง์ ‘ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
1069
1070
 
1070
- ``` ruby
1071
+ ```ruby
1071
1072
  get '/:id' do
1072
1073
  @foo = Foo.find(params['id'])
1073
1074
  haml '%h1= @foo.name'
@@ -1076,7 +1077,7 @@ end
1076
1077
 
1077
1078
  ๋ช…์‹œ์ ์œผ๋กœ ๋กœ์ปฌ ๋ณ€์ˆ˜์˜ ํ•ด์‹œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1078
1079
 
1079
- ``` ruby
1080
+ ```ruby
1080
1081
  get '/:id' do
1081
1082
  foo = Foo.find(params['id'])
1082
1083
  haml '%h1= bar.name', :locals => { :bar => foo }
@@ -1092,7 +1093,7 @@ end
1092
1093
  ์œ„์— ์„ค๋ช…๋œ `:template` ์˜ต์…˜์„ ํ†ตํ•ด ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜,
1093
1094
  ๋‹ค์Œ ์˜ˆ์ œ์ฒ˜๋Ÿผ ๋ธ”๋ก์œผ๋กœ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1094
1095
 
1095
- ``` ruby
1096
+ ```ruby
1096
1097
  erb :post, :layout => false do
1097
1098
  erb :index
1098
1099
  end
@@ -1102,7 +1103,7 @@ end
1102
1103
 
1103
1104
  ๋ Œ๋”๋ง ๋ฉ”์„œ๋“œ์— ๋ธ”๋ก ๋„˜๊ธฐ๊ธฐ๋Š” ์ค‘์ฒฉ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
1104
1105
 
1105
- ``` ruby
1106
+ ```ruby
1106
1107
  erb :main_layout, :layout => false do
1107
1108
  erb :admin_layout do
1108
1109
  erb :user
@@ -1112,7 +1113,7 @@ end
1112
1113
 
1113
1114
  ์œ„์˜ ์ฝ”๋“œ๋„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1114
1115
 
1115
- ``` ruby
1116
+ ```ruby
1116
1117
  erb :admin_layout, :layout => :main_layout do
1117
1118
  erb :user
1118
1119
  end
@@ -1125,7 +1126,7 @@ end
1125
1126
 
1126
1127
  ํ…œํ”Œ๋ฆฟ์€ ์†Œ์Šค ํŒŒ์ผ์˜ ๋งˆ์ง€๋ง‰์—์„œ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1127
1128
 
1128
- ``` ruby
1129
+ ```ruby
1129
1130
  require 'sinatra'
1130
1131
 
1131
1132
  get '/' do
@@ -1150,7 +1151,7 @@ __END__
1150
1151
 
1151
1152
  ํ…œํ”Œ๋ฆฟ์€ ํ†ฑ ๋ ˆ๋ฒจ(top-level)์—์„œ `template`๋ฉ”์„œ๋“œ๋กœ๋„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1152
1153
 
1153
- ``` ruby
1154
+ ```ruby
1154
1155
  template :layout do
1155
1156
  "%html\n =yield\n"
1156
1157
  end
@@ -1169,7 +1170,7 @@ end
1169
1170
  ๋น„ํ™œ์„ฑ์‹œํ‚ค๊ฑฐ๋‚˜ `set :haml, :layout => false`์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์„ ๋น„ํ™œ์„ฑ์œผ๋กœ ๋‘˜ ์ˆ˜
1170
1171
  ์žˆ์Šต๋‹ˆ๋‹ค.
1171
1172
 
1172
- ``` ruby
1173
+ ```ruby
1173
1174
  get '/' do
1174
1175
  haml :index, :layout => !request.xhr?
1175
1176
  end
@@ -1181,7 +1182,7 @@ end
1181
1182
  ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `tt`๋ผ๋Š” ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ Textile ํ…œํ”Œ๋ฆฟ๊ณผ ์—ฐ๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด,
1182
1183
  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1183
1184
 
1184
- ``` ruby
1185
+ ```ruby
1185
1186
  Tilt.register :tt, Tilt[:textile]
1186
1187
  ```
1187
1188
 
@@ -1189,7 +1190,7 @@ Tilt.register :tt, Tilt[:textile]
1189
1190
 
1190
1191
  ์šฐ์„ , Tilt๋กœ ์—ฌ๋Ÿฌ๋ถ„ ์—”์ง„์„ ๋“ฑ๋กํ•˜๊ณ , ๋ Œ๋”๋ง ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
1191
1192
 
1192
- ``` ruby
1193
+ ```ruby
1193
1194
  Tilt.register :myat, MyAwesomeTemplateEngine
1194
1195
 
1195
1196
  helpers do
@@ -1208,7 +1209,7 @@ Tilt์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ https://github.com/rtomayko/tilt ์ฐธ์กฐ
1208
1209
 
1209
1210
  ๊ณ ์œ ํ•œ ํ…œํ”Œ๋ฆฟ ๋ฃฉ์—…์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” `#find_template` ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“œ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.
1210
1211
 
1211
- ``` ruby
1212
+ ```ruby
1212
1213
  configure do
1213
1214
  set :views [ './views/a', './views/b' ]
1214
1215
  end
@@ -1226,7 +1227,7 @@ end
1226
1227
  ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋ณ€ํ˜•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„ํ„ฐ์—์„œ ์„ค์ •๋œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋“ค์€ ๋ผ์šฐํ„ฐ์™€
1227
1228
  ํ…œํ”Œ๋ฆฟ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
1228
1229
 
1229
- ``` ruby
1230
+ ```ruby
1230
1231
  before do
1231
1232
  @note = 'Hi!'
1232
1233
  request.path_info = '/foo/bar/baz'
@@ -1242,7 +1243,7 @@ end
1242
1243
  ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋ณ€ํ˜•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ „ ํ•„ํ„ฐ์™€ ๋ผ์šฐํ„ฐ์—์„œ ์„ค์ •๋œ
1243
1244
  ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋“ค์€ ์‚ฌํ›„ ํ•„ํ„ฐ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
1244
1245
 
1245
- ``` ruby
1246
+ ```ruby
1246
1247
  after do
1247
1248
  puts response.status
1248
1249
  end
@@ -1255,7 +1256,7 @@ end
1255
1256
  ํ•„ํ„ฐ๋Š” ํŒจํ„ด์„ ์ทจํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ, ์ด ๊ฒฝ์šฐ ์š”์ฒญ ๊ฒฝ๋กœ๊ฐ€ ๊ทธ ํŒจํ„ด๊ณผ ๋งค์น˜ํ• 
1256
1257
  ๊ฒฝ์šฐ์—๋งŒ ํ•„ํ„ฐ๊ฐ€ ํ‰๊ฐ€๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
1257
1258
 
1258
- ``` ruby
1259
+ ```ruby
1259
1260
  before '/protected/*' do
1260
1261
  authenticate!
1261
1262
  end
@@ -1267,7 +1268,7 @@ end
1267
1268
 
1268
1269
  ๋ผ์šฐํ„ฐ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํ•„ํ„ฐ ์—ญ์‹œ ์กฐ๊ฑด์„ ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1269
1270
 
1270
- ``` ruby
1271
+ ```ruby
1271
1272
  before :agent => /Songbird/ do
1272
1273
  # ...
1273
1274
  end
@@ -1282,7 +1283,7 @@ end
1282
1283
  ํ†ฑ-๋ ˆ๋ฒจ์˜ `helpers` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ผ์šฐํ„ฐ ํ•ธ๋“ค๋Ÿฌ์™€ ํ…œํ”Œ๋ฆฟ์—์„œ ์‚ฌ์šฉํ•  ํ—ฌํผ
1283
1284
  ๋ฉ”์„œ๋“œ๋“ค์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1284
1285
 
1285
- ``` ruby
1286
+ ```ruby
1286
1287
  helpers do
1287
1288
  def bar(name)
1288
1289
  "#{name}bar"
@@ -1296,7 +1297,7 @@ end
1296
1297
 
1297
1298
  ๋˜๋Š”, ํ—ฌํผ ๋ฉ”์„œ๋“œ๋Š” ๋ณ„๋„์˜ ๋ชจ๋“ˆ ์†์— ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1298
1299
 
1299
- ``` ruby
1300
+ ```ruby
1300
1301
  module FooUtils
1301
1302
  def foo(name) "#{name}foo" end
1302
1303
  end
@@ -1315,7 +1316,7 @@ helpers FooUtils, BarUtils
1315
1316
  ์„ธ์…˜์€ ์š”์ฒญ ๋™์•ˆ์— ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
1316
1317
  ์„ธ์…˜์ด ํ™œ์„ฑํ™”๋˜๋ฉด, ์‚ฌ์šฉ์ž ์„ธ์…˜ ๋‹น ์„ธ์…˜ ํ•ด์‹œ ํ•˜๋‚˜์”ฉ์„ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
1317
1318
 
1318
- ``` ruby
1319
+ ```ruby
1319
1320
  enable :sessions
1320
1321
 
1321
1322
  get '/' do
@@ -1334,7 +1335,7 @@ end
1334
1335
  `enable :sessions`์„ ํ˜ธ์ถœํ•˜์ง€ **์•Š๋Š”** ๋Œ€์‹ ์—, ์„ ํƒํ•œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋‹ค๋ฅธ
1335
1336
  ๋ฏธ๋“ค์›จ์–ด๋“ค์ฒ˜๋Ÿผ ํฌํ•จ์‹œํ‚ค๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1336
1337
 
1337
- ``` ruby
1338
+ ```ruby
1338
1339
  use Rack::Session::Pool, :expire_after => 2592000
1339
1340
 
1340
1341
  get '/' do
@@ -1351,21 +1352,21 @@ end
1351
1352
  ์‹œํฌ๋ฆฟ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ๋งˆ๋‹ค ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜
1352
1353
  ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋“ค์ด ๊ณต์œ ํ•  ์‹œํฌ๋ฆฟ์„ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1353
1354
 
1354
- ``` ruby
1355
+ ```ruby
1355
1356
  set :session_secret, 'super secret'
1356
1357
  ```
1357
1358
 
1358
1359
  ์กฐ๊ธˆ ๋” ์„ธ๋ถ€์ ์ธ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, `sessions` ์„ค์ •์—์„œ ์˜ต์…˜์ด ์žˆ๋Š”
1359
1360
  ํ•ด์‹œ๋ฅผ ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1360
1361
 
1361
- ``` ruby
1362
+ ```ruby
1362
1363
  set :sessions, :domain => 'foo.com'
1363
1364
  ```
1364
1365
 
1365
1366
  ์„ธ์…˜์„ ๋‹ค๋ฅธ foo.com์˜ ์„œ๋ธŒ๋„๋ฉ”์ธ ๋“ค๊ณผ ๊ณต์œ ํ•˜๊ธฐ ์›ํ•œ๋‹ค๋ฉด, ๋‹ค์Œ์— ๋‚˜์˜ค๋Š”
1366
1367
  ๊ฒƒ ์ฒ˜๋Ÿผ ๋„๋ฉ”์ธ ์•ž์— *.*์„ ๋ถ™์ด์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.
1367
1368
 
1368
- ``` ruby
1369
+ ```ruby
1369
1370
  set :sessions, :domain => '.foo.com'
1370
1371
  ```
1371
1372
 
@@ -1373,37 +1374,37 @@ set :sessions, :domain => '.foo.com'
1373
1374
 
1374
1375
  ํ•„ํ„ฐ๋‚˜ ๋ผ์šฐํ„ฐ์—์„œ ์š”์ฒญ์„ ์ฆ‰๊ฐ ์ค‘๋‹จํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜ํ•ฉ๋‹ˆ๋‹ค.
1375
1376
 
1376
- ``` ruby
1377
+ ```ruby
1377
1378
  halt
1378
1379
  ```
1379
1380
 
1380
1381
  ์ค‘๋‹จํ•  ๋•Œ ์ƒํƒœ๋ฅผ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1381
1382
 
1382
- ``` ruby
1383
+ ```ruby
1383
1384
  halt 410
1384
1385
  ```
1385
1386
 
1386
1387
  ๋ณธ๋ฌธ์„ ๋„ฃ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1387
1388
 
1388
- ``` ruby
1389
+ ```ruby
1389
1390
  halt 'this will be the body'
1390
1391
  ```
1391
1392
 
1392
1393
  ๋‘˜ ๋‹ค ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1393
1394
 
1394
- ``` ruby
1395
+ ```ruby
1395
1396
  halt 401, 'go away!'
1396
1397
  ```
1397
1398
 
1398
1399
  ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1399
1400
 
1400
- ``` ruby
1401
+ ```ruby
1401
1402
  halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
1402
1403
  ```
1403
1404
 
1404
1405
  ๋‹น์—ฐํžˆ `halt`์™€ ํ…œํ”Œ๋ฆฟ์€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1405
1406
 
1406
- ``` ruby
1407
+ ```ruby
1407
1408
  halt erb(:error)
1408
1409
  ```
1409
1410
 
@@ -1411,7 +1412,7 @@ halt erb(:error)
1411
1412
 
1412
1413
  ๋ผ์šฐํ„ฐ๋Š” `pass`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ๋ฒˆ ๋งค์นญ๋˜๋Š” ๋ผ์šฐํ„ฐ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1413
1414
 
1414
- ``` ruby
1415
+ ```ruby
1415
1416
  get '/guess/:who' do
1416
1417
  pass unless params['who'] == 'Frank'
1417
1418
  'You got me!'
@@ -1430,7 +1431,7 @@ end
1430
1431
  ๋•Œ๋กœ๋Š” `pass`๊ฐ€ ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ๋ผ์šฐํ„ฐ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ณ  ์‹ถ์„ ๋•Œ๋„
1431
1432
  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด๋•Œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ `call`์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1432
1433
 
1433
- ``` ruby
1434
+ ```ruby
1434
1435
  get '/foo' do
1435
1436
  status, headers, body = call env.merge("PATH_INFO" => '/bar')
1436
1437
  [status, headers, body.map(&:upcase)]
@@ -1456,7 +1457,7 @@ end
1456
1457
  ์ง€์ ์—์„œ ์„ค์ •ํ•ด์•ผ ํ• ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ `body` ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด
1457
1458
  ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ๊ทธ ์ˆœ๊ฐ„๋ถ€ํ„ฐ ๋ณธ๋ฌธ์— ์ ‘๊ทผํ•  ๋•Œ ๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
1458
1459
 
1459
- ``` ruby
1460
+ ```ruby
1460
1461
  get '/foo' do
1461
1462
  body "bar"
1462
1463
  end
@@ -1472,7 +1473,7 @@ end
1472
1473
 
1473
1474
  ๋ณธ๋ฌธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ƒํƒœ์ฝ”๋“œ์™€ ํ—ค๋”๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1474
1475
 
1475
- ``` ruby
1476
+ ```ruby
1476
1477
  get '/foo' do
1477
1478
  status 418
1478
1479
  headers \
@@ -1492,7 +1493,7 @@ end
1492
1493
  ๊ณ„์† ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ด๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ๋„ ์žˆ์ฃ . ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ๋ž˜ํผ(wrapper)๋ฅผ
1493
1494
  ๋งŒ๋“ค์ง€ ์•Š์œผ๋ ค๋ฉด `stream` ํ—ฌํผ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1494
1495
 
1495
- ``` ruby
1496
+ ```ruby
1496
1497
  get '/' do
1497
1498
  stream do |out|
1498
1499
  out << "It's gonna be legen -\n"
@@ -1505,23 +1506,23 @@ end
1505
1506
  ```
1506
1507
 
1507
1508
  ์ด๋ ‡๊ฒŒ ์ŠคํŠธ๋ฆฌ๋ฐ API๋‚˜ [์„œ๋ฒ„ ๋ฐœ์†ก ์ด๋ฒคํŠธServer Sent
1508
- Events](http://dev.w3.org/html5/eventsource/)๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ณ , ์ด ๋ฐฉ๋ฒ•์€
1509
- [WebSockets](http://en.wikipedia.org/wiki/WebSocket)์„ ์œ„ํ•œ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
1509
+ Events](https://w3c.github.io/eventsource/)๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ณ , ์ด ๋ฐฉ๋ฒ•์€
1510
+ [WebSockets](https://en.wikipedia.org/wiki/WebSocket)์„ ์œ„ํ•œ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
1510
1511
  ์ด ๋ฐฉ๋ฒ•์€ ์ผ๋ถ€ ์ฝ˜ํ…์ธ ๊ฐ€ ๋Š๋ฆฐ ์ž์›์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ์— ์Šค๋กœํ’‹(throughtput)์„
1511
1512
  ๋†’์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
1512
1513
 
1513
1514
  ์ŠคํŠธ๋ฆฌ๋ฐ ๋™์ž‘, ํŠนํžˆ ๋™์‹œ ์š”์ฒญ์˜ ์ˆ˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„œ๋น™ํ•˜๋Š” ์›น์„œ๋ฒ„์— ํฌ๊ฒŒ
1514
- ์˜์กดํ•ฉ๋‹ˆ๋‹ค. WEBRick์„œ๋ฒ„ ๊ฐ™์€ ์ผ๋ถ€์˜ ๊ฒฝ์šฐ ์•„์˜ˆ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•˜์ง€ ์กฐ์ฐจ ์•Š์Šต๋‹ˆ๋‹ค.
1515
- ๋งŒ์•ฝ ์„œ๋ฒ„๊ฐ€ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋ณธ๋ฌธ์€ `stream` ์œผ๋กœ ์ „๋‹ฌ๋œ ๋ธ”๋ก์ด
1516
- ์ˆ˜ํ–‰์„ ๋งˆ์นœ ํ›„์— ํ•œ๊บผ๋ฒˆ์— ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ํ•œ๋ฒˆ์— ์˜๋Š” ์ƒท๊ฑด๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ๋Š”
1517
- ์ŠคํŠธ๋ฆฌ๋ฐ์€ ์›€์ง์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
1515
+ ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€์˜ ๊ฒฝ์šฐ ์•„์˜ˆ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•˜์ง€ ์กฐ์ฐจ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์„œ๋ฒ„๊ฐ€
1516
+ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋ณธ๋ฌธ์€ `stream` ์œผ๋กœ ์ „๋‹ฌ๋œ ๋ธ”๋ก์ด ์ˆ˜ํ–‰์„ ๋งˆ์นœ
1517
+ ํ›„์— ํ•œ๊บผ๋ฒˆ์— ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ํ•œ๋ฒˆ์— ์˜๋Š” ์ƒท๊ฑด๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ์€
1518
+ ์›€์ง์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
1518
1519
 
1519
1520
  ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜ `keep_open`์ด ์„ค์ •๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ŠคํŠธ๋ฆผ ๊ฐ์ฒด์—์„œ `close`๋ฅผ
1520
1521
  ํ˜ธ์ถœํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ณ , ๋‚˜์ค‘์— ์‹คํ–‰ ํ๋ฆ„ ์ƒ์˜ ์–ด๋Š ์‹œ์ ์—์„œ ์ŠคํŠธ๋ฆผ์„ ๋‹ซ์„ ์ˆ˜
1521
1522
  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์€ Thin๊ณผ Rainbow ๊ฐ™์€ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์„œ๋ฒ„์—์„œ๋งŒ ์ž‘๋™ํ•˜๊ณ 
1522
1523
  ๋‹ค๋ฅธ ์„œ๋ฒ„๋“ค์€ ์—ฌ์ „ํžˆ ์ŠคํŠธ๋ฆผ์„ ๋‹ซ์Šต๋‹ˆ๋‹ค.
1523
1524
 
1524
- ``` ruby
1525
+ ```ruby
1525
1526
  # long polling
1526
1527
 
1527
1528
  set :server, :thin
@@ -1555,7 +1556,7 @@ end
1555
1556
  ์š”์ฒญ ์Šค์ฝ”ํ”„(request scope) ๋‚ด์—์„œ, `Logger`์˜ ์ธ์Šคํ„ด์Šค์ธ `logger`
1556
1557
  ํ—ฌํผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1557
1558
 
1558
- ``` ruby
1559
+ ```ruby
1559
1560
  get '/' do
1560
1561
  logger.info "loading data"
1561
1562
  # ...
@@ -1569,7 +1570,7 @@ end
1569
1570
  ๋กœ๊น…์€ `Sinatra::Application`์—์„œ๋งŒ ๊ธฐ๋ณธ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Œ์— ์œ ์˜ํ•ฉ์‹œ๋‹ค.
1570
1571
  ๋งŒ์•ฝ `Sinatra::Base`๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์€ ๊ฒฝ์šฐ๋ผ๋ฉด ์ง์ ‘ ํ™œ์„ฑํ™”์‹œ์ผœ ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
1571
1572
 
1572
- ``` ruby
1573
+ ```ruby
1573
1574
  class MyApp < Sinatra::Base
1574
1575
  configure :production, :development do
1575
1576
  enable :logging
@@ -1588,7 +1589,7 @@ Sinatra๋Š” `env['rack.logger']`์—์„œ ์ฐพ์€ ๋กœ๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
1588
1589
  ๋งˆ์ž„ ํƒ€์ž…์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ `mime_type`์„ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ
1589
1590
  ํ™•์žฅ์ž๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
1590
1591
 
1591
- ``` ruby
1592
+ ```ruby
1592
1593
  configure do
1593
1594
  mime_type :foo, 'text/foo'
1594
1595
  end
@@ -1596,7 +1597,7 @@ end
1596
1597
 
1597
1598
  `content_type` ํ—ฌํผ๋กœ ์“ธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1598
1599
 
1599
- ``` ruby
1600
+ ```ruby
1600
1601
  get '/' do
1601
1602
  content_type :foo
1602
1603
  "foo foo foo"
@@ -1608,7 +1609,7 @@ end
1608
1609
  URL์„ ์ƒ์„ฑํ• ๋•Œ `url` ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Haml์—์„œ๋Š” ์ด๋ ‡๊ฒŒ
1609
1610
  ํ•ฉ๋‹ˆ๋‹ค.
1610
1611
 
1611
- ``` ruby
1612
+ ```ruby
1612
1613
  %a{:href => url('/foo')} foo
1613
1614
  ```
1614
1615
 
@@ -1620,7 +1621,7 @@ URL์„ ์ƒ์„ฑํ• ๋•Œ `url` ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Ham
1620
1621
 
1621
1622
  `redirect` ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1622
1623
 
1623
- ``` ruby
1624
+ ```ruby
1624
1625
  get '/foo' do
1625
1626
  redirect to('/bar')
1626
1627
  end
@@ -1628,15 +1629,15 @@ end
1628
1629
 
1629
1630
  ๋‹ค๋ฅธ ๋ถ€๊ฐ€์ ์ธ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์€ `halt`์— ์ „๋‹ฌํ•˜๋Š” ์ธ์ž๋“ค๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.
1630
1631
 
1631
- ``` ruby
1632
+ ```ruby
1632
1633
  redirect to('/bar'), 303
1633
- redirect 'http://google.com', 'wrong place, buddy'
1634
+ redirect 'http://www.google.com/', 'wrong place, buddy'
1634
1635
  ```
1635
1636
 
1636
1637
  `redirect back`์„ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ์‚ฌ์šฉ์ž๊ฐ€ ์™”๋˜ ํŽ˜์ด์ง€๋กœ ๋‹ค์‹œ ๋Œ์•„๊ฐ€๊ฒŒ
1637
1638
  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1638
1639
 
1639
- ``` ruby
1640
+ ```ruby
1640
1641
  get '/foo' do
1641
1642
  "<a href='/bar'>do something</a>"
1642
1643
  end
@@ -1649,13 +1650,13 @@ end
1649
1650
 
1650
1651
  ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ์™€ ํ•จ๊ป˜ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๋ ค๋ฉด, ์ฟผ๋ฆฌ๋กœ ๋ถ™์ด๊ฑฐ๋‚˜,
1651
1652
 
1652
- ``` ruby
1653
+ ```ruby
1653
1654
  redirect to('/bar?sum=42')
1654
1655
  ```
1655
1656
 
1656
1657
  ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1657
1658
 
1658
- ``` ruby
1659
+ ```ruby
1659
1660
  enable :sessions
1660
1661
 
1661
1662
  get '/foo' do
@@ -1674,7 +1675,7 @@ end
1674
1675
 
1675
1676
  Cache-Control ํ—ค๋”๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1676
1677
 
1677
- ``` ruby
1678
+ ```ruby
1678
1679
  get '/' do
1679
1680
  cache_control :public
1680
1681
  "cache it!"
@@ -1683,7 +1684,7 @@ end
1683
1684
 
1684
1685
  ํ”„๋กœ ํŒ: ์บ์‹ฑ์€ ์‚ฌ์ „ ํ•„ํ„ฐ์—์„œ ์„ค์ •ํ•˜์„ธ์š”.
1685
1686
 
1686
- ``` ruby
1687
+ ```ruby
1687
1688
  before do
1688
1689
  cache_control :public, :must_revalidate, :max_age => 60
1689
1690
  end
@@ -1692,7 +1693,7 @@ end
1692
1693
  `expires` ํ—ฌํผ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ์— ์ƒ์‘ํ•˜๋Š” ํ—ค๋”๋ฅผ ์„ค์ •ํ•œ๋‹ค๋ฉด,
1693
1694
  `Cache-Control`์ด ์ž๋™์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
1694
1695
 
1695
- ``` ruby
1696
+ ```ruby
1696
1697
  before do
1697
1698
  expires 500, :public, :must_revalidate
1698
1699
  end
@@ -1703,7 +1704,7 @@ end
1703
1704
  ํด๋ผ์ด์–ธํŠธ ์บ์‹œ์— ํ˜„์žฌ ๋ฒ„์ „์ด ์ด๋ฏธ ๋“ค์–ด ์žˆ์„ ๊ฒฝ์šฐ์—” ์ฆ‰๊ฐ ์‘๋‹ต์„
1704
1705
  ๋ฟŒ๋ฆด(flush) ๊ฒƒ์ž…๋‹ˆ๋‹ค.
1705
1706
 
1706
- ``` ruby
1707
+ ```ruby
1707
1708
  get "/article/:id" do
1708
1709
  @article = Article.find params['id']
1709
1710
  last_modified @article.updated_at
@@ -1712,10 +1713,10 @@ get "/article/:id" do
1712
1713
  end
1713
1714
  ```
1714
1715
 
1715
- [์•ฝํ•œ ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)๋ฅผ
1716
+ [์•ฝํ•œ ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)๋ฅผ
1716
1717
  ์‚ฌ์šฉํ•  ์ˆ˜ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1717
1718
 
1718
- ``` ruby
1719
+ ```ruby
1719
1720
  etag @article.sha1, :weak
1720
1721
  ```
1721
1722
 
@@ -1723,7 +1724,7 @@ etag @article.sha1, :weak
1723
1724
  ์†์‰ฌ์šด ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ(reverse-proxy) ์บ์‹ฑ ์†”๋ฃจ์…˜์„ ์ฐพ๊ณ  ์žˆ๋‹ค๋ฉด,
1724
1725
  [rack-cache](https://github.com/rtomayko/rack-cache)๋ฅผ ์จ๋ณด์„ธ์š”.
1725
1726
 
1726
- ``` ruby
1727
+ ```ruby
1727
1728
  require "rack/cache"
1728
1729
  require "sinatra"
1729
1730
 
@@ -1745,7 +1746,7 @@ RFC 2616์— ๋”ฐ๋ฅด๋ฉด If-Match ๋˜๋Š” If-None-Match ํ—ค๋”๊ฐ€ `*`๋กœ ์„ค์ •๋œ
1745
1746
  ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ง€๋งŒ, ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค(์˜ˆ๋ฅผ ๋“ค๋ฉด post ์š”์ฒญ ๊ฐ™์€)์˜ ๊ฒฝ์šฐ๋Š”
1746
1747
  ์ƒˆ ๋ฆฌ์†Œ์Šค๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ–‰๋™์€ `:new_resource` ์˜ต์…˜์„ ์ „๋‹ฌํ•˜์—ฌ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1747
1748
 
1748
- ``` ruby
1749
+ ```ruby
1749
1750
  get '/create' do
1750
1751
  etag '', :new_resource => true
1751
1752
  Article.create
@@ -1755,7 +1756,7 @@ end
1755
1756
 
1756
1757
  ์•ฝํ•œ ETag๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด, `:kind`์œผ๋กœ ์ „๋‹ฌํ•ฉ์‹œ๋‹ค.
1757
1758
 
1758
- ``` ruby
1759
+ ```ruby
1759
1760
  etag '', :new_resource => true, :kind => :weak
1760
1761
  ```
1761
1762
 
@@ -1763,7 +1764,7 @@ etag '', :new_resource => true, :kind => :weak
1763
1764
 
1764
1765
  ์‘๋‹ต(response)์œผ๋กœ ํŒŒ์ผ์˜ ์ปจํƒ ์ธ ๋ฅผ ๋ฆฌํ„ดํ•˜๋ ค๋ฉด, `send_file` ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1765
1766
 
1766
- ``` ruby
1767
+ ```ruby
1767
1768
  get '/' do
1768
1769
  send_file 'foo.png'
1769
1770
  end
@@ -1771,7 +1772,7 @@ end
1771
1772
 
1772
1773
  ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ช‡ ๊ฐ€์ง€ ์˜ต์…˜์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.
1773
1774
 
1774
- ``` ruby
1775
+ ```ruby
1775
1776
  send_file 'foo.png', :type => :jpg
1776
1777
  ```
1777
1778
 
@@ -1812,7 +1813,7 @@ send_file 'foo.png', :type => :jpg
1812
1813
  ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ ๊ฐ์—๋Š” ์š”์ฒญ ๋ ˆ๋ฒจ(ํ•„ํ„ฐ, ๋ผ์šฐํ„ฐ, ์˜ค๋ฅ˜ ํ•ธ๋“ค๋Ÿฌ)์—์„œ `request`
1813
1814
  ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
1814
1815
 
1815
- ``` ruby
1816
+ ```ruby
1816
1817
  # http://example.com/example ์ƒ์—์„œ ์‹คํ–‰ ์ค‘์ธ ์•ฑ
1817
1818
  get '/foo' do
1818
1819
  t = %w[text/css text/html application/javascript]
@@ -1847,7 +1848,7 @@ end
1847
1848
 
1848
1849
  `script_name`, `path_info`๊ฐ™์€ ์ผ๋ถ€ ์˜ต์…˜๋“ค์€ ์ด๋ ‡๊ฒŒ ์“ธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1849
1850
 
1850
- ``` ruby
1851
+ ```ruby
1851
1852
  before { request.path_info = "/" }
1852
1853
 
1853
1854
  get "/" do
@@ -1857,7 +1858,7 @@ end
1857
1858
 
1858
1859
  `request.body`๋Š” IO ๊ฐ์ฒด์ด๊ฑฐ๋‚˜ StringIO ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.
1859
1860
 
1860
- ``` ruby
1861
+ ```ruby
1861
1862
  post "/api" do
1862
1863
  request.body.rewind # ๋ˆ„๊ตฐ๊ฐ€ ์ด๋ฏธ ์ฝ์€ ๊ฒฝ์šฐ
1863
1864
  data = JSON.parse request.body.read
@@ -1870,7 +1871,7 @@ end
1870
1871
  `attachment` ํ—ฌํผ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‘๋‹ต์ด ๋ธŒ๋ผ์šฐ์ €์— ํ‘œ์‹œํ•˜๋Š” ๋Œ€์‹ 
1871
1872
  ๋””์Šคํฌ์— ์ €์žฅ๋˜์–ด์•ผ ํ•จ์„ ๋ธ”๋ผ์šฐ์ €์—๊ฒŒ ์•Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1872
1873
 
1873
- ``` ruby
1874
+ ```ruby
1874
1875
  get '/' do
1875
1876
  attachment
1876
1877
  "store it!"
@@ -1879,7 +1880,7 @@ end
1879
1880
 
1880
1881
  ํŒŒ์ผ๋ช…์„ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
1881
1882
 
1882
- ``` ruby
1883
+ ```ruby
1883
1884
  get '/' do
1884
1885
  attachment "info.txt"
1885
1886
  "store it!"
@@ -1892,7 +1893,7 @@ Sinatra๋Š” `time_for_` ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š”
1892
1893
  ์ฃผ์–ด์ง„ ๊ฐ’์œผ๋กœ๋ถ€ํ„ฐ Time ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. `DateTime`, `Date` ๊ฐ™์€
1893
1894
  ๋น„์Šทํ•œ ํด๋ž˜์Šค๋“ค๋„ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
1894
1895
 
1895
- ``` ruby
1896
+ ```ruby
1896
1897
  get '/' do
1897
1898
  pass if Time.now > time_for('Dec 23, 2012')
1898
1899
  "still time"
@@ -1903,7 +1904,7 @@ end
1903
1904
  ๋”ฐ๋ผ์„œ ์—ฌ๋Ÿฌ๋ถ„์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ `time_for`๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์—ฌ ์ด๋“ค ๋ฉ”์„œ๋“œ์˜
1904
1905
  ๋™์ž‘์„ ์‰ฝ๊ฒŒ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1905
1906
 
1906
- ``` ruby
1907
+ ```ruby
1907
1908
  helpers do
1908
1909
  def time_for(value)
1909
1910
  case value
@@ -1925,7 +1926,7 @@ end
1925
1926
 
1926
1927
  `find_template`๋Š” ๋ Œ๋”๋งํ•  ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ์ฐพ๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
1927
1928
 
1928
- ``` ruby
1929
+ ```ruby
1929
1930
  find_template settings.views, 'foo', Tilt[:haml] do |file|
1930
1931
  puts "could be #{file}"
1931
1932
  end
@@ -1935,7 +1936,7 @@ end
1935
1936
  ์ฐธ์กฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์—์„œ ๊ฐ€๋กœ์ฑ„๊ฒŒ ํ•˜๋ฉด ์œ ์šฉํ•ด์ง‘๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ทฐ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ
1936
1937
  ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜์„ธ์š”.
1937
1938
 
1938
- ``` ruby
1939
+ ```ruby
1939
1940
  set :views, ['views', 'templates']
1940
1941
 
1941
1942
  helpers do
@@ -1947,7 +1948,7 @@ end
1947
1948
 
1948
1949
  ๋‹ค๋ฅธ ์˜ˆ์ œ๋Š” ๊ฐ ์—”์ง„๋งˆ๋‹ค ๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.
1949
1950
 
1950
- ``` ruby
1951
+ ```ruby
1951
1952
  set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1952
1953
 
1953
1954
  helpers do
@@ -1971,7 +1972,7 @@ end
1971
1972
 
1972
1973
  ๋ชจ๋“  ํ™˜๊ฒฝ์—์„œ, ์‹œ์ž‘๋  ๋•Œ, ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋ ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1973
1974
 
1974
- ``` ruby
1975
+ ```ruby
1975
1976
  configure do
1976
1977
  # ์˜ต์…˜ ํ•˜๋‚˜ ์„ค์ •
1977
1978
  set :option, 'value'
@@ -1990,9 +1991,9 @@ configure do
1990
1991
  end
1991
1992
  ```
1992
1993
 
1993
- ํ™˜๊ฒฝ(RACK_ENV ํ™˜๊ฒฝ ๋ณ€์ˆ˜)์ด `:production`์ผ ๋•Œ๋งŒ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋ ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1994
+ ํ™˜๊ฒฝ(APP_ENV ํ™˜๊ฒฝ ๋ณ€์ˆ˜)์ด `:production`์ผ ๋•Œ๋งŒ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋ ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
1994
1995
 
1995
- ``` ruby
1996
+ ```ruby
1996
1997
  configure :production do
1997
1998
  ...
1998
1999
  end
@@ -2000,7 +2001,7 @@ end
2000
2001
 
2001
2002
  ํ™˜๊ฒฝ์ด `:production` ๋˜๋Š” `:test`์ผ ๋•Œ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋ ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
2002
2003
 
2003
- ``` ruby
2004
+ ```ruby
2004
2005
  configure :production, :test do
2005
2006
  ...
2006
2007
  end
@@ -2008,7 +2009,7 @@ end
2008
2009
 
2009
2010
  ์ด ์˜ต์…˜๋“ค์€ `settings`๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
2010
2011
 
2011
- ``` ruby
2012
+ ```ruby
2012
2013
  configure do
2013
2014
  set :foo, 'bar'
2014
2015
  end
@@ -2022,23 +2023,23 @@ end
2022
2023
 
2023
2024
  ### ๊ณต๊ฒฉ ๋ฐฉ์–ด ์„ค์ •ํ•˜๊ธฐ(Configuring attack protection)
2024
2025
 
2025
- Sinatra๋Š” [Rack::Protection](https://github.com/rkh/rack-protection#readme)์„ ์‚ฌ์šฉํ•˜์—ฌ
2026
+ Sinatra๋Š” [Rack::Protection](https://github.com/sinatra/rack-protection#readme)์„ ์‚ฌ์šฉํ•˜์—ฌ
2026
2027
  ์ผ๋ฐ˜์ ์ด๊ณ  ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฒฉ์— ๋Œ€๋น„ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋น„ํ™œ์„ฑ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2027
2028
  (ํ•˜์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ์ทจ์•ฝ์„ฑ์„ ์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค.)
2028
2029
 
2029
- ``` ruby
2030
+ ```ruby
2030
2031
  disable :protection
2031
2032
  ```
2032
2033
 
2033
2034
  ํ•˜๋‚˜์˜ ๋ฐฉ์–ด์ธต๋งŒ ์Šคํ‚ตํ•˜๋ ค๋ฉด, ์˜ต์…˜ ํ•ด์‹œ์— `protection`์„ ์„ค์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
2034
2035
 
2035
- ``` ruby
2036
+ ```ruby
2036
2037
  set :protection, :except => :path_traversal
2037
2038
  ```
2038
2039
 
2039
2040
  ๋ฐฐ์—ด๋กœ ๋„˜๊น€์œผ๋กœ์จ ๋ฐฉ์–ด์ธต ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2040
2041
 
2041
- ``` ruby
2042
+ ```ruby
2042
2043
  set :protection, :except => [:path_traversal, :session_hijacking]
2043
2044
  ```
2044
2045
 
@@ -2046,7 +2047,7 @@ set :protection, :except => [:path_traversal, :session_hijacking]
2046
2047
  ๋•Œ๋กœ๋Š” ์ž์‹ ๋งŒ์˜ ์„ธ์…˜์„ ์„ค์ •ํ•  ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ `:session` ์˜ต์…˜์„
2047
2048
  ๋„˜๊ฒจ์คŒ์œผ๋กœ์จ ์„ธ์…˜์„ ๊ธฐ๋ฐ˜์œผ๋กœํ•œ ๋ฐฉ์–ด์ธต์„ ์„ค์ • ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2048
2049
 
2049
- ``` ruby
2050
+ ```ruby
2050
2051
  use Rack::Session::Pool
2051
2052
  set :protection, :session => true
2052
2053
  ```
@@ -2093,7 +2094,7 @@ set :protection, :session => true
2093
2094
 
2094
2095
  <dt>environment</dt>
2095
2096
  <dd>
2096
- ํ˜„์žฌ ํ™˜๊ฒฝ, ๊ธฐ๋ณธ๊ฐ’์€ <tt>ENV['RACK_ENV']</tt> ENV์— ์—†์„ ๊ฒฝ์šฐ์—” "development".
2097
+ ํ˜„์žฌ ํ™˜๊ฒฝ, ๊ธฐ๋ณธ๊ฐ’์€ <tt>ENV['APP_ENV']</tt> ENV์— ์—†์„ ๊ฒฝ์šฐ์—” "development".
2097
2098
  </dd>
2098
2099
 
2099
2100
  <dt>logging</dt>
@@ -2224,22 +2225,22 @@ set :protection, :session => true
2224
2225
  ## ํ™˜๊ฒฝ(Environments)
2225
2226
 
2226
2227
  3๊ฐ€์ง€์˜ ๋ฏธ๋ฆฌ ์ •์˜๋œ `environments` `"development"`, `"production"`, `"test"`
2227
- ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ์€ `RACK_ENV` ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋„ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€
2228
+ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ์€ `APP_ENV` ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋„ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€
2228
2229
  `"development"`์ž…๋‹ˆ๋‹ค. `"development"` ๋ชจ๋“œ์—์„œ๋Š” ๋ชจ๋“  ํ…œํ”Œ๋ฆฟ๋“ค์€ ์š”์ฒญ ๊ฐ„์—
2229
2230
  ๋ฆฌ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ๋˜, `"development"` ๋ชจ๋“œ์—์„œ๋Š” ํŠน๋ณ„ํ•œ `not_found` ์™€ `error`
2230
2231
  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒํ•ฉ๋‹ˆ๋‹ค.
2231
2232
  `"production"`๊ณผ `"test"`์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ…œํ”Œ๋ฆฟ์€ ์บ์‹œ๋ฉ๋‹ˆ๋‹ค.
2232
2233
 
2233
- ๋‹ค๋ฅธ ํ™˜๊ฒฝ์œผ๋กœ ์‹คํ–‰์‹œํ‚ค๋ ค๋ฉด `RACK_ENV` ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
2234
+ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์œผ๋กœ ์‹คํ–‰์‹œํ‚ค๋ ค๋ฉด `APP_ENV` ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
2234
2235
 
2235
- ``` shell
2236
- RACK_ENV=production ruby my_app.rb
2236
+ ```shell
2237
+ APP_ENV=production ruby my_app.rb
2237
2238
  ```
2238
2239
 
2239
2240
  ํ˜„์žฌ ์„ค์ •๋œ ํ™˜๊ฒฝ์ด ๋ฌด์—‡์ธ์ง€ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ค€๋น„๋œ `development?`, `test?`,
2240
2241
  `production?` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2241
2242
 
2242
- ``` ruby
2243
+ ```ruby
2243
2244
  get '/' do
2244
2245
  if settings.development?
2245
2246
  "development!"
@@ -2260,7 +2261,7 @@ end
2260
2261
  `Sinatra::NotFound` ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋˜๋Š” ์‘๋‹ต์˜ ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ 404๋ผ๋ฉด,
2261
2262
  `not_found` ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
2262
2263
 
2263
- ``` ruby
2264
+ ```ruby
2264
2265
  not_found do
2265
2266
  '์•„๋ฌด ๊ณณ์—๋„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.'
2266
2267
  end
@@ -2272,13 +2273,13 @@ end
2272
2273
  ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” ์˜ˆ์™ธ ํ™•์ธ ์˜ต์…˜์„ `:after_handler`๋กœ ์„ค์ •๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ์—๋งŒ
2273
2274
  ์‹คํ–‰๋จ์„ ์ฃผ์˜ํ•˜์„ธ์š”.
2274
2275
 
2275
- ``` ruby
2276
+ ```ruby
2276
2277
  set :show_exceptions, :after_handler
2277
2278
  ```
2278
2279
 
2279
2280
  ์˜ˆ์™ธ ๊ฐ์ฒด๋Š” Rack ๋ณ€์ˆ˜ `sinatra.error`๋กœ๋ถ€ํ„ฐ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2280
2281
 
2281
- ``` ruby
2282
+ ```ruby
2282
2283
  error do
2283
2284
  '๊ณ ์•ฝํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ตฐ์š” - ' + env['sinatra.error'].message
2284
2285
  end
@@ -2286,7 +2287,7 @@ end
2286
2287
 
2287
2288
  ์‚ฌ์šฉ์ž ์ •์˜ ์˜ค๋ฅ˜๋Š” ์ด๋ ‡๊ฒŒ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
2288
2289
 
2289
- ``` ruby
2290
+ ```ruby
2290
2291
  error MyCustomError do
2291
2292
  '๋ฌด์Šจ ์ผ์ด ์ƒ๊ฒผ๋‚˜๋ฉด์š”...' + env['sinatra.error'].message
2292
2293
  end
@@ -2294,7 +2295,7 @@ end
2294
2295
 
2295
2296
  ๊ทธ๋Ÿฐ ๋‹ค์Œ, ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
2296
2297
 
2297
- ``` ruby
2298
+ ```ruby
2298
2299
  get '/' do
2299
2300
  raise MyCustomError, '์•ˆ์ข‹์€ ์ผ'
2300
2301
  end
@@ -2308,7 +2309,7 @@ end
2308
2309
 
2309
2310
  ์ƒํƒœ ์ฝ”๋“œ์— ๋Œ€ํ•ด ์˜ค๋ฅ˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์„ค์น˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
2310
2311
 
2311
- ``` ruby
2312
+ ```ruby
2312
2313
  error 403 do
2313
2314
  '์•ก์„ธ์Šค๊ฐ€ ๊ธˆ์ง€๋จ'
2314
2315
  end
@@ -2320,7 +2321,7 @@ end
2320
2321
 
2321
2322
  ๋ฒ”์œ„๋กœ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
2322
2323
 
2323
- ``` ruby
2324
+ ```ruby
2324
2325
  error 400..510 do
2325
2326
  '์–ด์ด์ฟ '
2326
2327
  end
@@ -2340,7 +2341,7 @@ Sinatra๋Š” [Rack](http://rack.github.io/) ์œ„์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, Rack์€ ๋ฃจ๋น„
2340
2341
  Sinatra๋Š” ํ†ฑ๋ ˆ๋ฒจ์˜ `use` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Rack ๋ฏธ๋“ค์›จ์–ด์˜ ํŒŒ์ดํ”„๋ผ์ธ์„ ๋งŒ๋“œ๋Š” ์ผ์„
2341
2342
  ์‹์€ ์ฃฝ ๋จน๊ธฐ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
2342
2343
 
2343
- ``` ruby
2344
+ ```ruby
2344
2345
  require 'sinatra'
2345
2346
  require 'my_custom_middleware'
2346
2347
 
@@ -2352,11 +2353,11 @@ get '/hello' do
2352
2353
  end
2353
2354
  ```
2354
2355
 
2355
- `use`๋ฌธ๋ฒ•์€ [Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) DSL
2356
+ `use`๋ฌธ๋ฒ•์€ [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL
2356
2357
  (rackup ํŒŒ์ผ์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ)์—์„œ ์ •์˜ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `use` ๋ฉ”์„œ๋“œ๋Š”
2357
2358
  ๋ธ”๋ก์ด๋‚˜ ์—ฌ๋Ÿฌ ๊ฐœ์˜/๊ฐ€๋ณ€์ ์ธ ์ธ์ž๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2358
2359
 
2359
- ``` ruby
2360
+ ```ruby
2360
2361
  use Rack::Auth::Basic do |username, password|
2361
2362
  username == 'admin' && password == 'secret'
2362
2363
  end
@@ -2375,9 +2376,9 @@ Rack์€ ๋กœ๊น…, ๋””๋ฒ„๊น…, URL ๋ผ์šฐํŒ…, ์ธ์ฆ, ๊ทธ๋ฆฌ๊ณ  ์„ธ์„ผ ํ•ธ๋“ค๋ง์„
2375
2376
  ## ํ…Œ์ŠคํŒ…(Testing)
2376
2377
 
2377
2378
  Sinatra ํ…Œ์ŠคํŠธ๋Š” ๋งŽ์€ Rack ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŒ… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
2378
- ๊ทธ ์ค‘ [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
2379
+ ๊ทธ ์ค‘ [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
2379
2380
 
2380
- ``` ruby
2381
+ ```ruby
2381
2382
  require 'my_sinatra_app'
2382
2383
  require 'minitest/autorun'
2383
2384
  require 'rack/test'
@@ -2399,7 +2400,7 @@ class MyAppTest < Minitest::Test
2399
2400
  assert_equal 'Hello Frank!', last_response.body
2400
2401
  end
2401
2402
 
2402
- def test_with_rack_env
2403
+ def test_with_user_agent
2403
2404
  get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2404
2405
  assert_equal "You're using Songbird!", last_response.body
2405
2406
  end
@@ -2418,7 +2419,7 @@ Rack ๋ฏธ๋“ค์›จ์–ด๋‚˜, Rails ๋ฉ”ํƒˆ(metal) ๋˜๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ–๋Š”
2418
2419
  ์ž…๋‹ˆ๋‹ค. (์ฆ‰, ํ•˜๋‚˜์˜ ๋‹จ์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒŒ์ผ๊ณผ `./public` ๋ฐ `./views` ๋””๋ ‰ํ„ฐ๋ฆฌ,
2419
2420
  ๋กœ๊น…, ์˜ˆ์™ธ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋“ฑ๋“ฑ). ์ด ๊ณณ์—์„œ `Sinatra::Base`๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
2420
2421
 
2421
- ``` ruby
2422
+ ```ruby
2422
2423
  require 'sinatra/base'
2423
2424
 
2424
2425
  class MyApp < Sinatra::Base
@@ -2443,7 +2444,7 @@ end
2443
2444
 
2444
2445
  `Sinatra::Base`๋Š” ๋ฐฑ์ง€์ƒํƒœ(blank slate)์ž…๋‹ˆ๋‹ค. ๋นŒํŠธ์ธ ์„œ๋ฒ„๋ฅผ ๋น„๋กฏํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์˜ต์…˜๋“ค์ด
2445
2446
  ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๊บผ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ์˜ต์…˜๋“ค๊ณผ ๊ทธ ์ž‘๋™์— ๋Œ€ํ•œ ์ƒ์„ธ๋Š” [์˜ต์…˜๊ณผ
2446
- ์„ค์ •](http://sinatra.github.com/configuration.html)์„ ์ฐธ์กฐํ•˜์„ธ์š”.
2447
+ ์„ค์ •](http://www.sinatrarb.com/configuration.html)์„ ์ฐธ์กฐํ•˜์„ธ์š”.
2447
2448
 
2448
2449
  ### ๋ชจ๋“ˆ(Modular) vs. ์ „ํ†ต์  ๋ฐฉ์‹(Classic Style)
2449
2450
 
@@ -2491,7 +2492,7 @@ end
2491
2492
  <tr>
2492
2493
  <td>static</td>
2493
2494
  <td>true</td>
2494
- <td>false</td>
2495
+ <td>File.exist?(public_folder)</td>
2495
2496
  </tr>
2496
2497
  </table>
2497
2498
 
@@ -2500,7 +2501,7 @@ end
2500
2501
  ๋ชจ๋“ˆ ์•ฑ์„ ์‹œ์ž‘ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.
2501
2502
  `run!`์œผ๋กœ ๋Šฅ๋™์ ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค.
2502
2503
 
2503
- ``` ruby
2504
+ ```ruby
2504
2505
  # my_app.rb
2505
2506
  require 'sinatra/base'
2506
2507
 
@@ -2514,14 +2515,14 @@ end
2514
2515
 
2515
2516
  ์ด๋ ‡๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
2516
2517
 
2517
- ``` shell
2518
+ ```shell
2518
2519
  ruby my_app.rb
2519
2520
  ```
2520
2521
 
2521
2522
  `config.ru`์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ• ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ๋Š” ์–ด๋– ํ•œ Rack ํ•ธ๋“ค๋Ÿฌ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก
2522
2523
  ํ—ˆ์šฉ ํ•ฉ๋‹ค.
2523
2524
 
2524
- ``` ruby
2525
+ ```ruby
2525
2526
  # config.ru
2526
2527
  require './my_app'
2527
2528
  run MyApp
@@ -2529,7 +2530,7 @@ run MyApp
2529
2530
 
2530
2531
  ์‹คํ–‰์€ ์ด๋ ‡๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
2531
2532
 
2532
- ``` shell
2533
+ ```shell
2533
2534
  rackup -p 4567
2534
2535
  ```
2535
2536
 
@@ -2537,7 +2538,7 @@ rackup -p 4567
2537
2538
 
2538
2539
  ์•ฑ ํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
2539
2540
 
2540
- ``` ruby
2541
+ ```ruby
2541
2542
  # app.rb
2542
2543
  require 'sinatra'
2543
2544
 
@@ -2548,7 +2549,7 @@ end
2548
2549
 
2549
2550
  ๋Œ€์‘ํ•˜๋Š” `config.ru`๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
2550
2551
 
2551
- ``` ruby
2552
+ ```ruby
2552
2553
  require './app'
2553
2554
  run Sinatra::Application
2554
2555
  ```
@@ -2572,7 +2573,7 @@ Sinatra์—์„œ ๋‹ค๋ฅธ Rack ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋ฟ ์•„๋‹ˆ๋ผ,
2572
2573
  ๋˜๋Š” Rack ๊ธฐ๋ฐ˜์˜ ์–ด๋– ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(Rails/Ramaze/Camping/...)์ด ๋  ์ˆ˜๋„
2573
2574
  ์žˆ์Šต๋‹ˆ๋‹ค.
2574
2575
 
2575
- ``` ruby
2576
+ ```ruby
2576
2577
  require 'sinatra/base'
2577
2578
 
2578
2579
  class LoginScreen < Sinatra::Base
@@ -2608,7 +2609,7 @@ end
2608
2609
  ์–ด๋–ค ์ƒ์ˆ˜์— ํ• ๋‹นํ•˜์ง€ ์•Š๊ณ  ๋Ÿฐํƒ€์ž„์—์„œ ์ƒˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด,
2609
2610
  `Sinatra.new`๋ฅผ ์“ฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
2610
2611
 
2611
- ``` ruby
2612
+ ```ruby
2612
2613
  require 'sinatra/base'
2613
2614
  my_app = Sinatra.new { get('/') { "hi" } }
2614
2615
  my_app.run!
@@ -2616,7 +2617,7 @@ my_app.run!
2616
2617
 
2617
2618
  ์„ ํƒ์  ์ธ์ž๋กœ ์ƒ์†ํ•  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2618
2619
 
2619
- ``` ruby
2620
+ ```ruby
2620
2621
  # config.ru
2621
2622
  require 'sinatra/base'
2622
2623
 
@@ -2639,7 +2640,7 @@ end
2639
2640
 
2640
2641
  ์ด ๋ฐฉ๋ฒ•์€ Sinatra๋ฅผ ๋ฏธ๋“ค์›จ์–ด๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์•„์ฃผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
2641
2642
 
2642
- ``` ruby
2643
+ ```ruby
2643
2644
  require 'sinatra/base'
2644
2645
 
2645
2646
  use Sinatra do
@@ -2664,7 +2665,7 @@ run RailsProject::Application
2664
2665
 
2665
2666
  `set`์œผ๋กœ ์ƒ์„ฑํ•œ ์˜ต์…˜๋“ค์€ ํด๋ž˜์Šค ๋ ˆ๋ฒจ์˜ ๋ฉ”์„œ๋“œ๋“ค์ž…๋‹ˆ๋‹ค.
2666
2667
 
2667
- ``` ruby
2668
+ ```ruby
2668
2669
  class MyApp < Sinatra::Base
2669
2670
  # ์ €๊ธฐ์š”, ์ €๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฒ”์œ„์— ์žˆ๋‹ค๊ตฌ์š”!
2670
2671
  set :foo, 42
@@ -2696,7 +2697,7 @@ end
2696
2697
  ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ `erb` ๋‚˜ `haml` ๊ฐ™์€ ๋ Œ๋”๋ง ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญ ๋ฒ”์œ„
2697
2698
  ๋‚ด์—์„œ `settings` ํ—ฌํผ๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฒ”์œ„์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
2698
2699
 
2699
- ``` ruby
2700
+ ```ruby
2700
2701
  class MyApp < Sinatra::Base
2701
2702
  # ์ด๋ด์š”, ์ „ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฒ”์œ„์— ์žˆ๋‹ค๊ตฌ์š”!
2702
2703
  get '/define_route/:name' do
@@ -2736,13 +2737,13 @@ end
2736
2737
 
2737
2738
  ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.
2738
2739
  [Sinatra::Delegator ๋ฏน์Šค์ธ](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633)
2739
- ์€ [๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ํ™•์žฅํ•œ ๊ฒƒ](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30) ์ž…๋‹ˆ๋‹ค.
2740
+ ์€ [๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ํ™•์žฅํ•œ ๊ฒƒ](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30)์ž…๋‹ˆ๋‹ค.
2740
2741
 
2741
2742
  ## ๋ช…๋ นํ–‰(Command Line)
2742
2743
 
2743
2744
  Sinatra ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2744
2745
 
2745
- ``` shell
2746
+ ```shell
2746
2747
  ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
2747
2748
  ```
2748
2749
 
@@ -2757,6 +2758,40 @@ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
2757
2758
  -x # mutex ์ž ๊ธˆ ์ผœ๊ธฐ (๊ธฐ๋ณธ๊ฐ’์€ off)
2758
2759
  ```
2759
2760
 
2761
+ ### ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ(Multi-threading)
2762
+
2763
+ _Konstantin์˜ [StackOverflow์˜ ๋‹ต๋ณ€][so-answer]์—์„œ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค_
2764
+
2765
+ ์‹œ๋‚˜ํŠธ๋ผ๋Š” ๋™์‹œ์„ฑ ๋ชจ๋ธ์„ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ, Thin, Puma, WEBrick ๊ฐ™์€
2766
+ ๊ธฐ์ €์˜ Rack ํ•ธ๋“ค๋Ÿฌ(์„œ๋ฒ„)๋Š” ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‹œ๋‚˜ํŠธ๋ผ ์ž์‹ ์€ ์Šค๋ ˆ๋“œ์— ์•ˆ์ „ํ•˜๋ฏ€๋กœ
2767
+ ๋ž™ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์‹œ์„ฑ ์Šค๋ ˆ๋“œ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ ํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.
2768
+ ์ด๋Š” ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ, ์„œ๋ฒ„์— ๋”ฐ๋ฅธ ์ •ํ™•ํ•œ ํ˜ธ์ถœ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์˜
2769
+ ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค. ๋ฐ‘์˜ ์˜ˆ์ œ๋Š” ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ Thin ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
2770
+
2771
+ ```ruby
2772
+ # app.rb
2773
+
2774
+ require 'sinatra/base'
2775
+
2776
+ class App < Sinatra::Base
2777
+ get '/' do
2778
+ "Hello, World"
2779
+ end
2780
+ end
2781
+
2782
+ App.run!
2783
+
2784
+ ```
2785
+
2786
+ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ช…๋ น์–ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
2787
+
2788
+ ```shell
2789
+ thin --threaded start
2790
+ ```
2791
+
2792
+
2793
+ [so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
2794
+
2760
2795
  ## ์š”๊ตฌ์‚ฌํ•ญ(Requirement)
2761
2796
 
2762
2797
  ๋‹ค์Œ์˜ ๋ฃจ๋น„ ๋ฒ„์ „์€ ๊ณต์‹์ ์œผ๋กœ ์ง€์›๋ฉ๋‹ˆ๋‹ค.
@@ -2812,8 +2847,8 @@ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
2812
2847
  * MacRuby, Maglev, IronRuby
2813
2848
  * Ruby 1.9.0 ๋ฐ 1.9.1 (์ด ๋ฒ„์ „๋“ค์€ ์‚ฌ์šฉํ•˜์ง€ ๋ง ๊ฒƒ์„ ๊ถŒํ•ฉ๋‹ˆ๋‹ค)
2814
2849
 
2815
- ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์˜ ์˜๋ฏธ๋Š” ๋ฌด์–ธ๊ฐ€๊ฐ€ ๊ทธ ํ”Œ๋žซํผ์—์„œ๋งŒ ์ž˜๋ชป๋˜๊ณ 
2816
- ์ง€์›๋˜๋Š” ํ”Œ๋žซํผ์—์„œ๋Š” ๊ทธ๋Ÿฌ์ง€ ์•Š์„ ๊ฒฝ์šฐ, ์šฐ๋ฆฌ์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ทธ ํ”Œ๋žซํผ์˜ ๋ฌธ์ œ๋กœ
2850
+ ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์˜ ์˜๋ฏธ๋Š” ๋ฌด์–ธ๊ฐ€๊ฐ€ ๊ทธ ํ”Œ๋žซํผ์—์„œ๋งŒ ์ž˜๋ชป ๋™์ž‘ํ•˜๊ณ ,
2851
+ ์ง€์›๋˜๋Š” ํ”Œ๋žซํผ์—์„œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•  ๊ฒฝ์šฐ, ์šฐ๋ฆฌ์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ทธ ํ”Œ๋žซํผ์˜ ๋ฌธ์ œ๋กœ
2817
2852
  ๊ฐ„์ฃผํ•œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.
2818
2853
 
2819
2854
  ๋˜ํ•œ ์šฐ๋ฆฌ๋Š” CI๋ฅผ ruby-head (MRI์˜ ์ดํ›„ ๋ฆด๋ฆฌ์ฆˆ) ๋ธŒ๋žœ์น˜์— ๋งž์ถฐ ์‹คํ–‰ํ•˜์ง€๋งŒ,
@@ -2823,35 +2858,37 @@ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
2823
2858
  Sinatra๋Š” ์„ ํƒํ•œ ๋ฃจ๋น„ ๊ตฌํ˜„์ฒด๊ฐ€ ์ง€์›ํ•˜๋Š” ์–ด๋– ํ•œ ์šด์˜์ฒด์ œ์—์„œ๋„ ์ž‘๋™ํ•ด์•ผ
2824
2859
  ํ•ฉ๋‹ˆ๋‹ค.
2825
2860
 
2861
+ MacRuby๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, gem install control_tower ๋ฅผ ์‹คํ–‰ํ•ด ์ฃผ์„ธ์š”.
2862
+
2826
2863
  ํ˜„์žฌ Cardinal, SmallRuby, BlueRuby ๋˜๋Š” 1.8.7 ์ด์ „์˜ ๋ฃจ๋น„ ๋ฒ„์ „์—์„œ๋Š”
2827
2864
  Sinatra๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
2828
2865
 
2829
2866
  ## ์ตœ์‹ (The Bleeding Edge)
2830
2867
 
2831
2868
  Sinatra์˜ ๊ฐ€์žฅ ์ตœ๊ทผ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜์— ๋งž์ถฐ
2832
- ์‹คํ–‰ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๋ถ€๋‹ด๊ฐ€์ง€์ง€ ๋งˆ์„ธ์š”. ํ•˜์ง€๋งŒ ๋œ ์•ˆ์ •์ ์ผ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
2869
+ ์‹คํ–‰ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๋ถ€๋‹ด๊ฐ€์ง€์ง€ ๋งˆ์„ธ์š”. ํ•˜์ง€๋งŒ ๋œ ์•ˆ์ •์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
2833
2870
 
2834
2871
  ์ฃผ๊ธฐ์ ์œผ๋กœ ์‚ฌ์ „๋ฐฐํฌ(prerelease) ์ ฌ์„ ํ‘ธ์‹œํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ตœ์‹  ๊ธฐ๋Šฅ๋“ค์„ ์–ป๊ธฐ ์œ„ํ•ด
2835
2872
  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
2836
2873
 
2837
- ``` shell
2874
+ ```shell
2838
2875
  gem install sinatra --pre
2839
2876
  ```
2840
2877
 
2841
2878
  ### Bundler๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ
2842
2879
 
2843
2880
  ์—ฌ๋Ÿฌ๋ถ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ตœ์‹  Sinatra๋กœ ์‹คํ–‰ํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด,
2844
- [Bundler](http://gembundler.com/)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
2881
+ [Bundler](http://bundler.io)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
2845
2882
 
2846
2883
  ์šฐ์„ , ์•„์ง ์„ค์น˜ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด bundler๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
2847
2884
 
2848
- ``` shell
2885
+ ```shell
2849
2886
  gem install bundler
2850
2887
  ```
2851
2888
 
2852
2889
  ๊ทธ๋Ÿฐ ๋‹ค์Œ, ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ, `Gemfile`์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
2853
2890
 
2854
- ``` ruby
2891
+ ```ruby
2855
2892
  source 'https://rubygems.org'
2856
2893
  gem 'sinatra', :github => "sinatra/sinatra"
2857
2894
 
@@ -2866,7 +2903,7 @@ Bundler๊ฐ€ ์ž๋™์œผ๋กœ ์ฐพ์•„์„œ ์ถ”๊ฐ€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
2866
2903
 
2867
2904
  ์ด์ œ ์•ฑ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2868
2905
 
2869
- ``` shell
2906
+ ```shell
2870
2907
  bundle exec ruby myapp.rb
2871
2908
  ```
2872
2909
 
@@ -2875,7 +2912,7 @@ bundle exec ruby myapp.rb
2875
2912
  ๋กœ์ปฌ ํด๋ก (clone)์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ `$LOAD_PATH`์— `sinatra/lib` ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ฃผ๊ณ 
2876
2913
  ์—ฌ๋Ÿฌ๋ถ„ ์•ฑ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
2877
2914
 
2878
- ``` shell
2915
+ ```shell
2879
2916
  cd myapp
2880
2917
  git clone git://github.com/sinatra/sinatra.git
2881
2918
  ruby -I sinatra/lib myapp.rb
@@ -2883,7 +2920,7 @@ ruby -I sinatra/lib myapp.rb
2883
2920
 
2884
2921
  ์ดํ›„์— Sinatra ์†Œ์Šค๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜์„ธ์š”.
2885
2922
 
2886
- ``` shell
2923
+ ```shell
2887
2924
  cd myapp/sinatra
2888
2925
  git pull
2889
2926
  ```
@@ -2892,7 +2929,7 @@ git pull
2892
2929
 
2893
2930
  ์ ฌ์„ ์ง์ ‘ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
2894
2931
 
2895
- ``` shell
2932
+ ```shell
2896
2933
  git clone git://github.com/sinatra/sinatra.git
2897
2934
  cd sinatra
2898
2935
  rake sinatra.gemspec
@@ -2901,7 +2938,7 @@ rake install
2901
2938
 
2902
2939
  ๋งŒ์•ฝ ์ ฌ์„ ๋ฃจํŠธ๋กœ ์„ค์น˜ํ•œ๋‹ค๋ฉด, ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
2903
2940
 
2904
- ``` shell
2941
+ ```shell
2905
2942
  sudo rake install
2906
2943
  ```
2907
2944
 
@@ -2917,12 +2954,14 @@ SemVerTag๋ฅผ ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.
2917
2954
  ๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค๋“ค์— ๋Œ€ํ•œ ๋งํฌ.
2918
2955
  * [๊ธฐ์—ฌํ•˜๊ธฐ](http://www.sinatrarb.com/contributing) - ๋ฒ„๊ทธ๋ฅผ ์ฐพ์•˜๋‚˜์š”?
2919
2956
  ๋„์›€์ด ํ•„์š”ํ•œ๊ฐ€์š”? ํŒจ์น˜๋ฅผ ํ•˜์…จ๋‚˜์š”?
2920
- * [์ด์Šˆ ํŠธ๋ž˜์ปค](http://github.com/sinatra/sinatra/issues)
2921
- * [ํŠธ์œ„ํ„ฐ](http://twitter.com/sinatra)
2957
+ * [์ด์Šˆ ํŠธ๋ž˜์ปค](https://github.com/sinatra/sinatra/issues)
2958
+ * [ํŠธ์œ„ํ„ฐ](https://twitter.com/sinatra)
2922
2959
  * [๋ฉ”์ผ๋ง ๋ฆฌ์ŠคํŠธ](http://groups.google.com/group/sinatrarb/topics)
2923
2960
  * IRC: [#sinatra](irc://chat.freenode.net/#sinatra) http://freenode.net
2961
+ * ์Šฌ๋ž™์˜ [Sinatra & Friends](https://sinatrarb.slack.com)์ž…๋‹ˆ๋‹ค.
2962
+ [์—ฌ๊ธฐ](https://sinatra-slack.herokuapp.com/)์—์„œ ๊ฐ€์ž…๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
2924
2963
  * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Cookbook ํŠœํ† ๋ฆฌ์–ผ
2925
2964
  * [Sinatra Recipes](http://recipes.sinatrarb.com/) ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ๋งŒ๋“œ๋Š” ๋ ˆ์‹œํ”ผ
2926
- * http://rubydoc.info์— ์žˆ๋Š” [์ตœ์ข… ๋ฆด๋ฆฌ์Šค](http://rubydoc.info/gems/sinatra)
2927
- ๋˜๋Š” [current HEAD](http://rubydoc.info/github/sinatra/sinatra)์— ๋Œ€ํ•œ API ๋ฌธ์„œ
2928
- * [CI server](http://travis-ci.org/sinatra/sinatra)
2965
+ * http://www.rubydoc.info/์— ์žˆ๋Š” [์ตœ์ข… ๋ฆด๋ฆฌ์Šค](http://www.rubydoc.info/gems/sinatra)
2966
+ ๋˜๋Š” [current HEAD](http://www.rubydoc.info/github/sinatra/sinatra)์— ๋Œ€ํ•œ API ๋ฌธ์„œ
2967
+ * [CI server](https://travis-ci.org/sinatra/sinatra)