sinatra 1.4.6 → 1.4.7

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.

@@ -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,7 +206,7 @@ end
205
206
 
206
207
  라우터는 정규표현식으로 매치할 수 있습니다.
207
208
 
208
- ``` ruby
209
+ ```ruby
209
210
  get /\A\/hello\/([\w]+)\z/ do
210
211
  "Hello, #{params['captures'].first}!"
211
212
  end
@@ -213,7 +214,7 @@ end
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,7 +373,7 @@ end
372
373
 
373
374
  또는 거꾸로 탐색(negative look ahead)할 수도 있습니다.
374
375
 
375
- ``` ruby
376
+ ```ruby
376
377
  get %r{^(?!/index$)} do
377
378
  # ...
378
379
  end
@@ -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'
@@ -1992,7 +1993,7 @@ end
1992
1993
 
1993
1994
  환경(RACK_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
  ```
@@ -2232,14 +2233,14 @@ set :protection, :session => true
2232
2233
 
2233
2234
  다른 환경으로 실행시키려면 `RACK_ENV` 환경 변수를 사용하세요.
2234
2235
 
2235
- ``` shell
2236
+ ```shell
2236
2237
  RACK_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'
@@ -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)