scout_realtime 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (563) hide show
  1. data/.gitignore +21 -0
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +37 -0
  6. data/Rakefile +16 -0
  7. data/Vagrantfile +7 -0
  8. data/bin/scout_realtime +117 -0
  9. data/lib/scout_realtime/lib/aggregator.rb +8 -0
  10. data/lib/scout_realtime/lib/metric.rb +36 -0
  11. data/lib/scout_realtime/lib/multi_aggregator.rb +12 -0
  12. data/lib/scout_realtime/lib/ring_buffer.rb +25 -0
  13. data/lib/scout_realtime/lib/trollop.rb +782 -0
  14. data/lib/scout_realtime/main.rb +76 -0
  15. data/lib/scout_realtime/models/cpu.rb +21 -0
  16. data/lib/scout_realtime/models/disk.rb +21 -0
  17. data/lib/scout_realtime/models/memory.rb +17 -0
  18. data/lib/scout_realtime/models/network.rb +14 -0
  19. data/lib/scout_realtime/models/processes.rb +13 -0
  20. data/lib/scout_realtime/runner.rb +34 -0
  21. data/lib/scout_realtime/version.rb +5 -0
  22. data/lib/scout_realtime/web/favicon.ico +0 -0
  23. data/lib/scout_realtime/web/images/logo.png +0 -0
  24. data/lib/scout_realtime/web/images/pause.png +0 -0
  25. data/lib/scout_realtime/web/images/play.png +0 -0
  26. data/lib/scout_realtime/web/javascripts/application.js +265 -0
  27. data/lib/scout_realtime/web/javascripts/bootstrap.min.js +7 -0
  28. data/lib/scout_realtime/web/javascripts/charts.js +189 -0
  29. data/lib/scout_realtime/web/javascripts/d3.barchart.js +210 -0
  30. data/lib/scout_realtime/web/javascripts/d3.linechart.js +168 -0
  31. data/lib/scout_realtime/web/javascripts/d3.v3.min.js +5 -0
  32. data/lib/scout_realtime/web/javascripts/handlebars-v1.1.0.js +2563 -0
  33. data/lib/scout_realtime/web/javascripts/jquery.js +3010 -0
  34. data/lib/scout_realtime/web/javascripts/metrics_for_development.js +6 -0
  35. data/lib/scout_realtime/web/stylesheets/bootstrap-theme.min.css +7 -0
  36. data/lib/scout_realtime/web/stylesheets/bootstrap.min.css +7 -0
  37. data/lib/scout_realtime/web/stylesheets/styles.css +254 -0
  38. data/lib/scout_realtime/web/views/graph.erb +6 -0
  39. data/lib/scout_realtime/web/views/header.erb +8 -0
  40. data/lib/scout_realtime/web/views/index.erb +21 -0
  41. data/lib/scout_realtime/web/views/layout.erb +33 -0
  42. data/lib/scout_realtime/web/views/overview_charts.erb +30 -0
  43. data/lib/scout_realtime/web/views/processes.erb +31 -0
  44. data/lib/scout_realtime/web/views/sidebar.erb +19 -0
  45. data/lib/scout_realtime/web_app.rb +59 -0
  46. data/lib/scout_realtime.rb +58 -0
  47. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/bytes.rb +1 -0
  48. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/chars.rb +1 -0
  49. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/each.rb +3 -0
  50. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/each_byte.rb +9 -0
  51. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/each_char.rb +35 -0
  52. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/each_line.rb +3 -0
  53. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/getbyte.rb +5 -0
  54. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/lines.rb +5 -0
  55. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf/readbyte.rb +5 -0
  56. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/argf.rb +3 -0
  57. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/collect.rb +3 -0
  58. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/combination.rb +24 -0
  59. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/cycle.rb +16 -0
  60. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/delete_if.rb +3 -0
  61. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/each.rb +3 -0
  62. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/each_index.rb +3 -0
  63. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/find_index.rb +1 -0
  64. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/flatten.rb +47 -0
  65. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/index.rb +15 -0
  66. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/map.rb +3 -0
  67. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/permutation.rb +30 -0
  68. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/pop.rb +15 -0
  69. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/product.rb +32 -0
  70. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/reject.rb +3 -0
  71. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/reverse_each.rb +3 -0
  72. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/rindex.rb +15 -0
  73. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/select.rb +3 -0
  74. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/shift.rb +13 -0
  75. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array/shuffle.rb +17 -0
  76. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/array.rb +3 -0
  77. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/binding/eval.rb +7 -0
  78. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/binding.rb +3 -0
  79. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/dir/each.rb +7 -0
  80. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/dir/foreach.rb +9 -0
  81. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/dir.rb +3 -0
  82. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/count.rb +17 -0
  83. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/cycle.rb +24 -0
  84. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/detect.rb +3 -0
  85. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/drop.rb +13 -0
  86. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/drop_while.rb +16 -0
  87. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/each_cons.rb +4 -0
  88. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/each_slice.rb +4 -0
  89. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/each_with_index.rb +3 -0
  90. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/entries.rb +11 -0
  91. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/find.rb +3 -0
  92. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/find_all.rb +3 -0
  93. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/find_index.rb +21 -0
  94. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/first.rb +21 -0
  95. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/group_by.rb +14 -0
  96. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/inject.rb +14 -0
  97. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/max_by.rb +16 -0
  98. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/min_by.rb +16 -0
  99. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/minmax.rb +21 -0
  100. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/minmax_by.rb +19 -0
  101. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/none.rb +7 -0
  102. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/one.rb +23 -0
  103. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/partition.rb +3 -0
  104. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/reduce.rb +1 -0
  105. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/reject.rb +3 -0
  106. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/reverse_each.rb +12 -0
  107. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/select.rb +3 -0
  108. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/sort_by.rb +3 -0
  109. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/take.rb +9 -0
  110. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/take_while.rb +14 -0
  111. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable/to_a.rb +12 -0
  112. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerable.rb +3 -0
  113. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerator/each.rb +6 -0
  114. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerator/next.rb +15 -0
  115. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerator/rewind.rb +13 -0
  116. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerator/with_index.rb +14 -0
  117. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/enumerator.rb +3 -0
  118. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env/delete_if.rb +3 -0
  119. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env/each.rb +3 -0
  120. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env/each_key.rb +3 -0
  121. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env/each_pair.rb +3 -0
  122. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env/each_value.rb +3 -0
  123. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env/reject.rb +4 -0
  124. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env/select.rb +3 -0
  125. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/env.rb +3 -0
  126. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/fixnum/div.rb +7 -0
  127. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/fixnum/fdiv.rb +7 -0
  128. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/fixnum.rb +3 -0
  129. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/float/fdiv.rb +3 -0
  130. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/float.rb +3 -0
  131. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/gc/stress.rb +9 -0
  132. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/gc.rb +3 -0
  133. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/constructor.rb +25 -0
  134. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/delete_if.rb +3 -0
  135. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/each.rb +3 -0
  136. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/each_key.rb +3 -0
  137. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/each_pair.rb +3 -0
  138. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/each_value.rb +3 -0
  139. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/eql.rb +1 -0
  140. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/hash.rb +17 -0
  141. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/reject.rb +3 -0
  142. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash/select.rb +3 -0
  143. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/hash.rb +3 -0
  144. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer/downto.rb +3 -0
  145. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer/even.rb +7 -0
  146. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer/odd.rb +7 -0
  147. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer/ord.rb +7 -0
  148. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer/pred.rb +7 -0
  149. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer/times.rb +3 -0
  150. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer/upto.rb +3 -0
  151. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/integer.rb +3 -0
  152. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/bytes.rb +1 -0
  153. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/chars.rb +1 -0
  154. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/each.rb +3 -0
  155. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/each_byte.rb +6 -0
  156. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/each_char.rb +34 -0
  157. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/each_line.rb +6 -0
  158. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/foreach.rb +7 -0
  159. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/getbyte.rb +3 -0
  160. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/lines.rb +1 -0
  161. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io/readbyte.rb +3 -0
  162. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/io.rb +3 -0
  163. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/kernel/__method__.rb +8 -0
  164. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/kernel/instance_exec.rb +10 -0
  165. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/kernel/tap.rb +8 -0
  166. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/kernel.rb +3 -0
  167. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/method/name.rb +49 -0
  168. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/method.rb +3 -0
  169. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/module/class_exec.rb +1 -0
  170. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/module/module_exec.rb +11 -0
  171. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/module.rb +3 -0
  172. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/numeric/step.rb +3 -0
  173. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/numeric.rb +3 -0
  174. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/object_space/each_object.rb +5 -0
  175. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/object_space.rb +3 -0
  176. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/process/exec.rb +3 -0
  177. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/process.rb +3 -0
  178. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/range/each.rb +3 -0
  179. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/range/step.rb +3 -0
  180. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/range.rb +3 -0
  181. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/regexp/union.rb +11 -0
  182. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/regexp.rb +3 -0
  183. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/stdlib/tmpdir.rb +44 -0
  184. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/stdlib.rb +1 -0
  185. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/stop_iteration.rb +14 -0
  186. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/bytes.rb +1 -0
  187. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/bytesize.rb +3 -0
  188. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/each.rb +3 -0
  189. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/each_byte.rb +5 -0
  190. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/each_char.rb +13 -0
  191. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/each_line.rb +5 -0
  192. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/end_with.rb +12 -0
  193. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/lines.rb +1 -0
  194. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/partition.rb +20 -0
  195. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/rpartition.rb +19 -0
  196. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/start_with.rb +12 -0
  197. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string/upto.rb +15 -0
  198. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/string.rb +3 -0
  199. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/struct/each.rb +3 -0
  200. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/struct/each_pair.rb +3 -0
  201. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/struct.rb +3 -0
  202. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/symbol/to_proc.rb +8 -0
  203. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7/symbol.rb +3 -0
  204. data/lib/vendor/backports-3.3.5/lib/backports/1.8.7.rb +3 -0
  205. data/lib/vendor/backports-3.3.5/lib/backports/1.8.8.rb +2 -0
  206. data/lib/vendor/backports-3.3.5/lib/backports/1.8.rb +2 -0
  207. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/array/sample.rb +19 -0
  208. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/array/try_convert.rb +7 -0
  209. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/array.rb +3 -0
  210. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/dir/to_path.rb +3 -0
  211. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/dir.rb +3 -0
  212. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/enumerable/each_with_index.rb +14 -0
  213. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/enumerable/each_with_object.rb +9 -0
  214. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/enumerable.rb +3 -0
  215. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/enumerator/new.rb +40 -0
  216. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/enumerator/with_object.rb +6 -0
  217. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/enumerator.rb +3 -0
  218. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/env/key.rb +5 -0
  219. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/env.rb +3 -0
  220. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/atime.rb +5 -0
  221. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/basename.rb +5 -0
  222. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/binary.rb +6 -0
  223. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/blockdev.rb +5 -0
  224. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/chardev.rb +5 -0
  225. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/chmod.rb +5 -0
  226. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/chown.rb +5 -0
  227. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/ctime.rb +5 -0
  228. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/delete.rb +5 -0
  229. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/directory.rb +5 -0
  230. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/dirname.rb +5 -0
  231. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/executable.rb +5 -0
  232. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/executable_real.rb +5 -0
  233. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/exist.rb +5 -0
  234. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/exists.rb +5 -0
  235. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/expand_path.rb +14 -0
  236. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/extname.rb +5 -0
  237. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/file.rb +5 -0
  238. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/ftype.rb +5 -0
  239. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/grpowned.rb +5 -0
  240. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/join.rb +5 -0
  241. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/lchmod.rb +5 -0
  242. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/lchown.rb +5 -0
  243. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/link.rb +5 -0
  244. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/lstat.rb +5 -0
  245. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/mtime.rb +5 -0
  246. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/new.rb +5 -0
  247. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/open.rb +23 -0
  248. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/owned.rb +5 -0
  249. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/pipe.rb +5 -0
  250. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/readable.rb +5 -0
  251. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/readable_real.rb +5 -0
  252. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/readlink.rb +5 -0
  253. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/rename.rb +5 -0
  254. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/setgid.rb +5 -0
  255. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/setuid.rb +5 -0
  256. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/size.rb +14 -0
  257. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/socket.rb +5 -0
  258. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/split.rb +5 -0
  259. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/stat.rb +5 -0
  260. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/sticky.rb +5 -0
  261. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/symlink.rb +6 -0
  262. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/to_path.rb +3 -0
  263. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/truncate.rb +5 -0
  264. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/unlink.rb +5 -0
  265. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/writable.rb +5 -0
  266. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/writable_real.rb +5 -0
  267. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file/zero.rb +5 -0
  268. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/file.rb +3 -0
  269. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/float/round.rb +21 -0
  270. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/float.rb +3 -0
  271. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/hash/assoc.rb +12 -0
  272. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/hash/default_proc.rb +14 -0
  273. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/hash/key.rb +3 -0
  274. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/hash/rassoc.rb +9 -0
  275. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/hash/try_convert.rb +7 -0
  276. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/hash.rb +3 -0
  277. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/integer/magnitude.rb +3 -0
  278. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/integer/round.rb +24 -0
  279. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/integer.rb +3 -0
  280. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/io/binread.rb +10 -0
  281. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/io/open.rb +21 -0
  282. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/io/try_convert.rb +7 -0
  283. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/io/ungetbyte.rb +3 -0
  284. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/io.rb +3 -0
  285. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/kernel/__callee__.rb +7 -0
  286. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/kernel/define_singleton_method.rb +9 -0
  287. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/kernel/public_method.rb +11 -0
  288. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/kernel/public_send.rb +13 -0
  289. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/kernel/require_relative.rb +14 -0
  290. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/kernel.rb +3 -0
  291. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/math/log.rb +20 -0
  292. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/math/log2.rb +5 -0
  293. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/math.rb +3 -0
  294. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/numeric/round.rb +11 -0
  295. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/numeric.rb +3 -0
  296. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/proc/case_compare.rb +6 -0
  297. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/proc/curry.rb +24 -0
  298. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/proc/lambda.rb +40 -0
  299. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/proc/yield.rb +3 -0
  300. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/proc.rb +3 -0
  301. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/range/cover.rb +3 -0
  302. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/range.rb +3 -0
  303. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/regexp/try_convert.rb +7 -0
  304. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/regexp.rb +3 -0
  305. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/stdlib/prime.rb +497 -0
  306. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/stdlib.rb +1 -0
  307. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/ascii_only.rb +7 -0
  308. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/chr.rb +7 -0
  309. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/clear.rb +8 -0
  310. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/codepoints.rb +8 -0
  311. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/each_codepoint.rb +3 -0
  312. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/getbyte.rb +3 -0
  313. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/ord.rb +7 -0
  314. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/setbyte.rb +3 -0
  315. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string/try_convert.rb +7 -0
  316. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/string.rb +3 -0
  317. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/capitalize.rb +7 -0
  318. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/casecmp.rb +8 -0
  319. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/comparable.rb +7 -0
  320. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/comparison.rb +8 -0
  321. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/downcase.rb +7 -0
  322. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/element_reference.rb +7 -0
  323. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/empty.rb +7 -0
  324. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/length.rb +7 -0
  325. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/match.rb +9 -0
  326. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/next.rb +1 -0
  327. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/size.rb +7 -0
  328. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/succ.rb +8 -0
  329. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/swapcase.rb +7 -0
  330. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol/upcase.rb +7 -0
  331. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1/symbol.rb +3 -0
  332. data/lib/vendor/backports-3.3.5/lib/backports/1.9.1.rb +3 -0
  333. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/keep_if.rb +8 -0
  334. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/product.rb +26 -0
  335. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/repeated_combination.rb +25 -0
  336. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/repeated_permutation.rb +26 -0
  337. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/rotate.rb +17 -0
  338. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/select.rb +8 -0
  339. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/sort_by.rb +9 -0
  340. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array/uniq.rb +30 -0
  341. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/array.rb +3 -0
  342. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/complex/to_r.rb +10 -0
  343. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/complex.rb +3 -0
  344. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/dir/home.rb +5 -0
  345. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/dir.rb +3 -0
  346. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/enumerable/chunk.rb +39 -0
  347. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/enumerable/collect_concat.rb +1 -0
  348. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/enumerable/each_entry.rb +11 -0
  349. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/enumerable/flat_map.rb +11 -0
  350. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/enumerable/slice_before.rb +30 -0
  351. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/enumerable.rb +3 -0
  352. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/float/infinity.rb +3 -0
  353. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/float/nan.rb +3 -0
  354. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/float.rb +3 -0
  355. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/hash/keep_if.rb +8 -0
  356. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/hash/select.rb +9 -0
  357. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/hash.rb +3 -0
  358. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/kernel/singleton_class.rb +7 -0
  359. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/kernel.rb +3 -0
  360. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/random.rb +1 -0
  361. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/stdlib/matrix/eigenvalue_decomposition.rb +886 -0
  362. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/stdlib/matrix/lup_decomposition.rb +218 -0
  363. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/stdlib/matrix.rb +1871 -0
  364. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/stdlib/set.rb +13 -0
  365. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2/stdlib.rb +1 -0
  366. data/lib/vendor/backports-3.3.5/lib/backports/1.9.2.rb +3 -0
  367. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/file/null.rb +16 -0
  368. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/file.rb +3 -0
  369. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/io/advise.rb +24 -0
  370. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/io/binwrite.rb +7 -0
  371. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/io/write.rb +7 -0
  372. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/io.rb +3 -0
  373. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/string/byteslice.rb +36 -0
  374. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/string/prepend.rb +10 -0
  375. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3/string.rb +3 -0
  376. data/lib/vendor/backports-3.3.5/lib/backports/1.9.3.rb +3 -0
  377. data/lib/vendor/backports-3.3.5/lib/backports/1.9.rb +2 -0
  378. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/array/bsearch.rb +32 -0
  379. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/array.rb +3 -0
  380. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/enumerable/lazy.rb +216 -0
  381. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/enumerable.rb +3 -0
  382. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/enumerator/lazy.rb +1 -0
  383. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/enumerator.rb +3 -0
  384. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/env/to_h.rb +5 -0
  385. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/env.rb +3 -0
  386. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/hash/default_proc.rb +16 -0
  387. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/hash/to_h.rb +7 -0
  388. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/hash.rb +3 -0
  389. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/nil/to_h.rb +7 -0
  390. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/nil.rb +3 -0
  391. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/range/bsearch.rb +49 -0
  392. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/range.rb +3 -0
  393. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/stdlib/abbrev.rb +1 -0
  394. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/stdlib/fake_stdlib_lib.rb +1 -0
  395. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/stdlib/ostruct.rb +27 -0
  396. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/stdlib.rb +1 -0
  397. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/struct/to_h.rb +9 -0
  398. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0/struct.rb +3 -0
  399. data/lib/vendor/backports-3.3.5/lib/backports/2.0.0.rb +3 -0
  400. data/lib/vendor/backports-3.3.5/lib/backports/2.0.rb +2 -0
  401. data/lib/vendor/backports-3.3.5/lib/backports/basic_object.rb +53 -0
  402. data/lib/vendor/backports-3.3.5/lib/backports/extra/random/MT19937.rb +76 -0
  403. data/lib/vendor/backports-3.3.5/lib/backports/extra/random/bits_and_bytes.rb +91 -0
  404. data/lib/vendor/backports-3.3.5/lib/backports/extra/random/implementation.rb +93 -0
  405. data/lib/vendor/backports-3.3.5/lib/backports/extra/random/load.rb +17 -0
  406. data/lib/vendor/backports-3.3.5/lib/backports/force/array_map.rb +1 -0
  407. data/lib/vendor/backports-3.3.5/lib/backports/force/enumerable_map.rb +3 -0
  408. data/lib/vendor/backports-3.3.5/lib/backports/force/hash_select.rb +9 -0
  409. data/lib/vendor/backports-3.3.5/lib/backports/force/string_length.rb +10 -0
  410. data/lib/vendor/backports-3.3.5/lib/backports/force/string_size.rb +1 -0
  411. data/lib/vendor/backports-3.3.5/lib/backports/rails/array.rb +6 -0
  412. data/lib/vendor/backports-3.3.5/lib/backports/rails/enumerable.rb +12 -0
  413. data/lib/vendor/backports-3.3.5/lib/backports/rails/hash.rb +31 -0
  414. data/lib/vendor/backports-3.3.5/lib/backports/rails/kernel.rb +6 -0
  415. data/lib/vendor/backports-3.3.5/lib/backports/rails/module.rb +6 -0
  416. data/lib/vendor/backports-3.3.5/lib/backports/rails/string.rb +42 -0
  417. data/lib/vendor/backports-3.3.5/lib/backports/rails.rb +4 -0
  418. data/lib/vendor/backports-3.3.5/lib/backports/tools.rb +343 -0
  419. data/lib/vendor/backports-3.3.5/lib/backports/version.rb +3 -0
  420. data/lib/vendor/backports-3.3.5/lib/backports.rb +4 -0
  421. data/lib/vendor/dante-0.2.0/lib/dante/runner.rb +275 -0
  422. data/lib/vendor/dante-0.2.0/lib/dante/version.rb +3 -0
  423. data/lib/vendor/dante-0.2.0/lib/dante.rb +26 -0
  424. data/lib/vendor/rack-1.5.2/lib/rack/auth/abstract/handler.rb +37 -0
  425. data/lib/vendor/rack-1.5.2/lib/rack/auth/abstract/request.rb +43 -0
  426. data/lib/vendor/rack-1.5.2/lib/rack/auth/basic.rb +58 -0
  427. data/lib/vendor/rack-1.5.2/lib/rack/auth/digest/md5.rb +129 -0
  428. data/lib/vendor/rack-1.5.2/lib/rack/auth/digest/nonce.rb +51 -0
  429. data/lib/vendor/rack-1.5.2/lib/rack/auth/digest/params.rb +53 -0
  430. data/lib/vendor/rack-1.5.2/lib/rack/auth/digest/request.rb +41 -0
  431. data/lib/vendor/rack-1.5.2/lib/rack/backports/uri/common_18.rb +56 -0
  432. data/lib/vendor/rack-1.5.2/lib/rack/backports/uri/common_192.rb +52 -0
  433. data/lib/vendor/rack-1.5.2/lib/rack/backports/uri/common_193.rb +29 -0
  434. data/lib/vendor/rack-1.5.2/lib/rack/body_proxy.rb +39 -0
  435. data/lib/vendor/rack-1.5.2/lib/rack/builder.rb +149 -0
  436. data/lib/vendor/rack-1.5.2/lib/rack/cascade.rb +52 -0
  437. data/lib/vendor/rack-1.5.2/lib/rack/chunked.rb +58 -0
  438. data/lib/vendor/rack-1.5.2/lib/rack/commonlogger.rb +64 -0
  439. data/lib/vendor/rack-1.5.2/lib/rack/conditionalget.rb +67 -0
  440. data/lib/vendor/rack-1.5.2/lib/rack/config.rb +20 -0
  441. data/lib/vendor/rack-1.5.2/lib/rack/content_length.rb +33 -0
  442. data/lib/vendor/rack-1.5.2/lib/rack/content_type.rb +29 -0
  443. data/lib/vendor/rack-1.5.2/lib/rack/deflater.rb +116 -0
  444. data/lib/vendor/rack-1.5.2/lib/rack/directory.rb +161 -0
  445. data/lib/vendor/rack-1.5.2/lib/rack/etag.rb +64 -0
  446. data/lib/vendor/rack-1.5.2/lib/rack/file.rb +138 -0
  447. data/lib/vendor/rack-1.5.2/lib/rack/handler/cgi.rb +61 -0
  448. data/lib/vendor/rack-1.5.2/lib/rack/handler/evented_mongrel.rb +8 -0
  449. data/lib/vendor/rack-1.5.2/lib/rack/handler/fastcgi.rb +98 -0
  450. data/lib/vendor/rack-1.5.2/lib/rack/handler/lsws.rb +61 -0
  451. data/lib/vendor/rack-1.5.2/lib/rack/handler/mongrel.rb +100 -0
  452. data/lib/vendor/rack-1.5.2/lib/rack/handler/scgi.rb +67 -0
  453. data/lib/vendor/rack-1.5.2/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  454. data/lib/vendor/rack-1.5.2/lib/rack/handler/thin.rb +27 -0
  455. data/lib/vendor/rack-1.5.2/lib/rack/handler/webrick.rb +81 -0
  456. data/lib/vendor/rack-1.5.2/lib/rack/handler.rb +107 -0
  457. data/lib/vendor/rack-1.5.2/lib/rack/head.rb +22 -0
  458. data/lib/vendor/rack-1.5.2/lib/rack/lint.rb +699 -0
  459. data/lib/vendor/rack-1.5.2/lib/rack/lobster.rb +65 -0
  460. data/lib/vendor/rack-1.5.2/lib/rack/lock.rb +26 -0
  461. data/lib/vendor/rack-1.5.2/lib/rack/logger.rb +18 -0
  462. data/lib/vendor/rack-1.5.2/lib/rack/methodoverride.rb +31 -0
  463. data/lib/vendor/rack-1.5.2/lib/rack/mime.rb +677 -0
  464. data/lib/vendor/rack-1.5.2/lib/rack/mock.rb +190 -0
  465. data/lib/vendor/rack-1.5.2/lib/rack/multipart/generator.rb +93 -0
  466. data/lib/vendor/rack-1.5.2/lib/rack/multipart/parser.rb +176 -0
  467. data/lib/vendor/rack-1.5.2/lib/rack/multipart/uploaded_file.rb +34 -0
  468. data/lib/vendor/rack-1.5.2/lib/rack/multipart.rb +34 -0
  469. data/lib/vendor/rack-1.5.2/lib/rack/nulllogger.rb +18 -0
  470. data/lib/vendor/rack-1.5.2/lib/rack/recursive.rb +61 -0
  471. data/lib/vendor/rack-1.5.2/lib/rack/reloader.rb +109 -0
  472. data/lib/vendor/rack-1.5.2/lib/rack/request.rb +380 -0
  473. data/lib/vendor/rack-1.5.2/lib/rack/response.rb +155 -0
  474. data/lib/vendor/rack-1.5.2/lib/rack/rewindable_input.rb +104 -0
  475. data/lib/vendor/rack-1.5.2/lib/rack/runtime.rb +27 -0
  476. data/lib/vendor/rack-1.5.2/lib/rack/sendfile.rb +155 -0
  477. data/lib/vendor/rack-1.5.2/lib/rack/server.rb +362 -0
  478. data/lib/vendor/rack-1.5.2/lib/rack/session/abstract/id.rb +398 -0
  479. data/lib/vendor/rack-1.5.2/lib/rack/session/cookie.rb +178 -0
  480. data/lib/vendor/rack-1.5.2/lib/rack/session/memcache.rb +93 -0
  481. data/lib/vendor/rack-1.5.2/lib/rack/session/pool.rb +79 -0
  482. data/lib/vendor/rack-1.5.2/lib/rack/showexceptions.rb +378 -0
  483. data/lib/vendor/rack-1.5.2/lib/rack/showstatus.rb +113 -0
  484. data/lib/vendor/rack-1.5.2/lib/rack/static.rb +153 -0
  485. data/lib/vendor/rack-1.5.2/lib/rack/urlmap.rb +76 -0
  486. data/lib/vendor/rack-1.5.2/lib/rack/utils/okjson.rb +599 -0
  487. data/lib/vendor/rack-1.5.2/lib/rack/utils.rb +628 -0
  488. data/lib/vendor/rack-1.5.2/lib/rack.rb +87 -0
  489. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/authenticity_token.rb +31 -0
  490. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/base.rb +119 -0
  491. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/escaped_params.rb +87 -0
  492. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/form_token.rb +23 -0
  493. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/frame_options.rb +37 -0
  494. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/http_origin.rb +32 -0
  495. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/ip_spoofing.rb +23 -0
  496. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/json_csrf.rb +35 -0
  497. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/path_traversal.rb +47 -0
  498. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/remote_referrer.rb +20 -0
  499. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/remote_token.rb +22 -0
  500. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/session_hijacking.rb +36 -0
  501. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/version.rb +16 -0
  502. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection/xss_header.rb +25 -0
  503. data/lib/vendor/rack-protection-1.5.1/lib/rack/protection.rb +40 -0
  504. data/lib/vendor/rack-protection-1.5.1/lib/rack-protection.rb +1 -0
  505. data/lib/vendor/sinatra-1.4.4/.yardopts +5 -0
  506. data/lib/vendor/sinatra-1.4.4/lib/sinatra/base.rb +2034 -0
  507. data/lib/vendor/sinatra-1.4.4/lib/sinatra/images/404.png +0 -0
  508. data/lib/vendor/sinatra-1.4.4/lib/sinatra/images/500.png +0 -0
  509. data/lib/vendor/sinatra-1.4.4/lib/sinatra/main.rb +34 -0
  510. data/lib/vendor/sinatra-1.4.4/lib/sinatra/show_exceptions.rb +345 -0
  511. data/lib/vendor/sinatra-1.4.4/lib/sinatra/version.rb +3 -0
  512. data/lib/vendor/sinatra-1.4.4/lib/sinatra.rb +4 -0
  513. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/capture.rb +124 -0
  514. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/config_file.rb +167 -0
  515. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/content_for.rb +125 -0
  516. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/contrib/all.rb +2 -0
  517. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/contrib/setup.rb +53 -0
  518. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/contrib/version.rb +17 -0
  519. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/contrib.rb +39 -0
  520. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/cookies.rb +331 -0
  521. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/decompile.rb +121 -0
  522. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/engine_tracking.rb +96 -0
  523. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/extension.rb +95 -0
  524. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/json.rb +131 -0
  525. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/link_header.rb +132 -0
  526. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/multi_route.rb +87 -0
  527. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/namespace.rb +284 -0
  528. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/reloader.rb +394 -0
  529. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/respond_with.rb +247 -0
  530. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/streaming.rb +243 -0
  531. data/lib/vendor/sinatra-contrib-1.4.1/lib/sinatra/test_helpers.rb +87 -0
  532. data/lib/vendor/tilt-1.4.1/lib/tilt/asciidoc.rb +34 -0
  533. data/lib/vendor/tilt-1.4.1/lib/tilt/builder.rb +40 -0
  534. data/lib/vendor/tilt-1.4.1/lib/tilt/coffee.rb +54 -0
  535. data/lib/vendor/tilt-1.4.1/lib/tilt/css.rb +80 -0
  536. data/lib/vendor/tilt-1.4.1/lib/tilt/csv.rb +71 -0
  537. data/lib/vendor/tilt-1.4.1/lib/tilt/erb.rb +110 -0
  538. data/lib/vendor/tilt-1.4.1/lib/tilt/etanni.rb +27 -0
  539. data/lib/vendor/tilt-1.4.1/lib/tilt/haml.rb +64 -0
  540. data/lib/vendor/tilt-1.4.1/lib/tilt/liquid.rb +45 -0
  541. data/lib/vendor/tilt-1.4.1/lib/tilt/markaby.rb +52 -0
  542. data/lib/vendor/tilt-1.4.1/lib/tilt/markdown.rb +214 -0
  543. data/lib/vendor/tilt-1.4.1/lib/tilt/nokogiri.rb +43 -0
  544. data/lib/vendor/tilt-1.4.1/lib/tilt/plain.rb +20 -0
  545. data/lib/vendor/tilt-1.4.1/lib/tilt/radius.rb +55 -0
  546. data/lib/vendor/tilt-1.4.1/lib/tilt/rdoc.rb +47 -0
  547. data/lib/vendor/tilt-1.4.1/lib/tilt/string.rb +21 -0
  548. data/lib/vendor/tilt-1.4.1/lib/tilt/template.rb +292 -0
  549. data/lib/vendor/tilt-1.4.1/lib/tilt/textile.rb +30 -0
  550. data/lib/vendor/tilt-1.4.1/lib/tilt/wiki.rb +58 -0
  551. data/lib/vendor/tilt-1.4.1/lib/tilt/yajl.rb +94 -0
  552. data/lib/vendor/tilt-1.4.1/lib/tilt.rb +204 -0
  553. data/scout_realtime.gemspec +30 -0
  554. data/test/data_for_testing.rb +1 -0
  555. data/test/lib/metric_test.rb +48 -0
  556. data/test/models/cpu_test.rb +24 -0
  557. data/test/models/disk_test.rb +24 -0
  558. data/test/models/memory_test.rb +24 -0
  559. data/test/models/network_test.rb +24 -0
  560. data/test/models/processes_test.rb +24 -0
  561. data/test/runner_test.rb +30 -0
  562. data/test/test_helper.rb +4 -0
  563. metadata +730 -0
@@ -0,0 +1,2034 @@
1
+ # external dependencies
2
+ require 'rack'
3
+ require 'tilt'
4
+ require 'rack/protection'
5
+
6
+ # stdlib dependencies
7
+ require 'thread'
8
+ require 'time'
9
+ require 'uri'
10
+
11
+ # other files we need
12
+ require 'sinatra/show_exceptions'
13
+ require 'sinatra/version'
14
+
15
+ module Sinatra
16
+ # The request object. See Rack::Request for more info:
17
+ # http://rack.rubyforge.org/doc/classes/Rack/Request.html
18
+ class Request < Rack::Request
19
+ HEADER_PARAM = /\s*[\w.]+=(?:[\w.]+|"(?:[^"\\]|\\.)*")?\s*/
20
+ HEADER_VALUE_WITH_PARAMS = /(?:(?:\w+|\*)\/(?:\w+(?:\.|\-|\+)?|\*)*)\s*(?:;#{HEADER_PARAM})*/
21
+
22
+ # Returns an array of acceptable media types for the response
23
+ def accept
24
+ @env['sinatra.accept'] ||= begin
25
+ if @env.include? 'HTTP_ACCEPT' and @env['HTTP_ACCEPT'].to_s != ''
26
+ @env['HTTP_ACCEPT'].to_s.scan(HEADER_VALUE_WITH_PARAMS).
27
+ map! { |e| AcceptEntry.new(e) }.sort
28
+ else
29
+ [AcceptEntry.new('*/*')]
30
+ end
31
+ end
32
+ end
33
+
34
+ def accept?(type)
35
+ preferred_type(type).include?(type)
36
+ end
37
+
38
+ def preferred_type(*types)
39
+ accepts = accept # just evaluate once
40
+ return accepts.first if types.empty?
41
+ types.flatten!
42
+ return types.first if accepts.empty?
43
+ accepts.detect do |pattern|
44
+ type = types.detect { |t| File.fnmatch(pattern, t) }
45
+ return type if type
46
+ end
47
+ end
48
+
49
+ alias secure? ssl?
50
+
51
+ def forwarded?
52
+ @env.include? "HTTP_X_FORWARDED_HOST"
53
+ end
54
+
55
+ def safe?
56
+ get? or head? or options? or trace?
57
+ end
58
+
59
+ def idempotent?
60
+ safe? or put? or delete? or link? or unlink?
61
+ end
62
+
63
+ def link?
64
+ request_method == "LINK"
65
+ end
66
+
67
+ def unlink?
68
+ request_method == "UNLINK"
69
+ end
70
+
71
+ private
72
+
73
+ class AcceptEntry
74
+ attr_accessor :params
75
+
76
+ def initialize(entry)
77
+ params = entry.scan(HEADER_PARAM).map! do |s|
78
+ key, value = s.strip.split('=', 2)
79
+ value = value[1..-2].gsub(/\\(.)/, '\1') if value.start_with?('"')
80
+ [key, value]
81
+ end
82
+
83
+ @entry = entry
84
+ @type = entry[/[^;]+/].delete(' ')
85
+ @params = Hash[params]
86
+ @q = @params.delete('q') { 1.0 }.to_f
87
+ end
88
+
89
+ def <=>(other)
90
+ other.priority <=> self.priority
91
+ end
92
+
93
+ def priority
94
+ # We sort in descending order; better matches should be higher.
95
+ [ @q, -@type.count('*'), @params.size ]
96
+ end
97
+
98
+ def to_str
99
+ @type
100
+ end
101
+
102
+ def to_s(full = false)
103
+ full ? entry : to_str
104
+ end
105
+
106
+ def respond_to?(*args)
107
+ super or to_str.respond_to?(*args)
108
+ end
109
+
110
+ def method_missing(*args, &block)
111
+ to_str.send(*args, &block)
112
+ end
113
+ end
114
+ end
115
+
116
+ # The response object. See Rack::Response and Rack::Response::Helpers for
117
+ # more info:
118
+ # http://rack.rubyforge.org/doc/classes/Rack/Response.html
119
+ # http://rack.rubyforge.org/doc/classes/Rack/Response/Helpers.html
120
+ class Response < Rack::Response
121
+ DROP_BODY_RESPONSES = [204, 205, 304]
122
+ def initialize(*)
123
+ super
124
+ headers['Content-Type'] ||= 'text/html'
125
+ end
126
+
127
+ def body=(value)
128
+ value = value.body while Rack::Response === value
129
+ @body = String === value ? [value.to_str] : value
130
+ end
131
+
132
+ def each
133
+ block_given? ? super : enum_for(:each)
134
+ end
135
+
136
+ def finish
137
+ result = body
138
+
139
+ if drop_content_info?
140
+ headers.delete "Content-Length"
141
+ headers.delete "Content-Type"
142
+ end
143
+
144
+ if drop_body?
145
+ close
146
+ result = []
147
+ end
148
+
149
+ if calculate_content_length?
150
+ # if some other code has already set Content-Length, don't muck with it
151
+ # currently, this would be the static file-handler
152
+ headers["Content-Length"] = body.inject(0) { |l, p| l + Rack::Utils.bytesize(p) }.to_s
153
+ end
154
+
155
+ [status.to_i, headers, result]
156
+ end
157
+
158
+ private
159
+
160
+ def calculate_content_length?
161
+ headers["Content-Type"] and not headers["Content-Length"] and Array === body
162
+ end
163
+
164
+ def drop_content_info?
165
+ status.to_i / 100 == 1 or drop_body?
166
+ end
167
+
168
+ def drop_body?
169
+ DROP_BODY_RESPONSES.include?(status.to_i)
170
+ end
171
+ end
172
+
173
+ # Some Rack handlers (Thin, Rainbows!) implement an extended body object protocol, however,
174
+ # some middleware (namely Rack::Lint) will break it by not mirroring the methods in question.
175
+ # This middleware will detect an extended body object and will make sure it reaches the
176
+ # handler directly. We do this here, so our middleware and middleware set up by the app will
177
+ # still be able to run.
178
+ class ExtendedRack < Struct.new(:app)
179
+ def call(env)
180
+ result, callback = app.call(env), env['async.callback']
181
+ return result unless callback and async?(*result)
182
+ after_response { callback.call result }
183
+ setup_close(env, *result)
184
+ throw :async
185
+ end
186
+
187
+ private
188
+
189
+ def setup_close(env, status, headers, body)
190
+ return unless body.respond_to? :close and env.include? 'async.close'
191
+ env['async.close'].callback { body.close }
192
+ env['async.close'].errback { body.close }
193
+ end
194
+
195
+ def after_response(&block)
196
+ raise NotImplementedError, "only supports EventMachine at the moment" unless defined? EventMachine
197
+ EventMachine.next_tick(&block)
198
+ end
199
+
200
+ def async?(status, headers, body)
201
+ return true if status == -1
202
+ body.respond_to? :callback and body.respond_to? :errback
203
+ end
204
+ end
205
+
206
+ # Behaves exactly like Rack::CommonLogger with the notable exception that it does nothing,
207
+ # if another CommonLogger is already in the middleware chain.
208
+ class CommonLogger < Rack::CommonLogger
209
+ def call(env)
210
+ env['sinatra.commonlogger'] ? @app.call(env) : super
211
+ end
212
+
213
+ superclass.class_eval do
214
+ alias call_without_check call unless method_defined? :call_without_check
215
+ def call(env)
216
+ env['sinatra.commonlogger'] = true
217
+ call_without_check(env)
218
+ end
219
+ end
220
+ end
221
+
222
+ class NotFound < NameError #:nodoc:
223
+ def http_status; 404 end
224
+ end
225
+
226
+ # Methods available to routes, before/after filters, and views.
227
+ module Helpers
228
+ # Set or retrieve the response status code.
229
+ def status(value = nil)
230
+ response.status = value if value
231
+ response.status
232
+ end
233
+
234
+ # Set or retrieve the response body. When a block is given,
235
+ # evaluation is deferred until the body is read with #each.
236
+ def body(value = nil, &block)
237
+ if block_given?
238
+ def block.each; yield(call) end
239
+ response.body = block
240
+ elsif value
241
+ headers.delete 'Content-Length' unless request.head? || value.is_a?(Rack::File) || value.is_a?(Stream)
242
+ response.body = value
243
+ else
244
+ response.body
245
+ end
246
+ end
247
+
248
+ # Halt processing and redirect to the URI provided.
249
+ def redirect(uri, *args)
250
+ if env['HTTP_VERSION'] == 'HTTP/1.1' and env["REQUEST_METHOD"] != 'GET'
251
+ status 303
252
+ else
253
+ status 302
254
+ end
255
+
256
+ # According to RFC 2616 section 14.30, "the field value consists of a
257
+ # single absolute URI"
258
+ response['Location'] = uri(uri.to_s, settings.absolute_redirects?, settings.prefixed_redirects?)
259
+ halt(*args)
260
+ end
261
+
262
+ # Generates the absolute URI for a given path in the app.
263
+ # Takes Rack routers and reverse proxies into account.
264
+ def uri(addr = nil, absolute = true, add_script_name = true)
265
+ return addr if addr =~ /\A[A-z][A-z0-9\+\.\-]*:/
266
+ uri = [host = ""]
267
+ if absolute
268
+ host << "http#{'s' if request.secure?}://"
269
+ if request.forwarded? or request.port != (request.secure? ? 443 : 80)
270
+ host << request.host_with_port
271
+ else
272
+ host << request.host
273
+ end
274
+ end
275
+ uri << request.script_name.to_s if add_script_name
276
+ uri << (addr ? addr : request.path_info).to_s
277
+ File.join uri
278
+ end
279
+
280
+ alias url uri
281
+ alias to uri
282
+
283
+ # Halt processing and return the error status provided.
284
+ def error(code, body = nil)
285
+ code, body = 500, code.to_str if code.respond_to? :to_str
286
+ response.body = body unless body.nil?
287
+ halt code
288
+ end
289
+
290
+ # Halt processing and return a 404 Not Found.
291
+ def not_found(body = nil)
292
+ error 404, body
293
+ end
294
+
295
+ # Set multiple response headers with Hash.
296
+ def headers(hash = nil)
297
+ response.headers.merge! hash if hash
298
+ response.headers
299
+ end
300
+
301
+ # Access the underlying Rack session.
302
+ def session
303
+ request.session
304
+ end
305
+
306
+ # Access shared logger object.
307
+ def logger
308
+ request.logger
309
+ end
310
+
311
+ # Look up a media type by file extension in Rack's mime registry.
312
+ def mime_type(type)
313
+ Base.mime_type(type)
314
+ end
315
+
316
+ # Set the Content-Type of the response body given a media type or file
317
+ # extension.
318
+ def content_type(type = nil, params = {})
319
+ return response['Content-Type'] unless type
320
+ default = params.delete :default
321
+ mime_type = mime_type(type) || default
322
+ fail "Unknown media type: %p" % type if mime_type.nil?
323
+ mime_type = mime_type.dup
324
+ unless params.include? :charset or settings.add_charset.all? { |p| not p === mime_type }
325
+ params[:charset] = params.delete('charset') || settings.default_encoding
326
+ end
327
+ params.delete :charset if mime_type.include? 'charset'
328
+ unless params.empty?
329
+ mime_type << (mime_type.include?(';') ? ', ' : ';')
330
+ mime_type << params.map do |key, val|
331
+ val = val.inspect if val =~ /[";,]/
332
+ "#{key}=#{val}"
333
+ end.join(', ')
334
+ end
335
+ response['Content-Type'] = mime_type
336
+ end
337
+
338
+ # Set the Content-Disposition to "attachment" with the specified filename,
339
+ # instructing the user agents to prompt to save.
340
+ def attachment(filename = nil, disposition = 'attachment')
341
+ response['Content-Disposition'] = disposition.to_s
342
+ if filename
343
+ params = '; filename="%s"' % File.basename(filename)
344
+ response['Content-Disposition'] << params
345
+ ext = File.extname(filename)
346
+ content_type(ext) unless response['Content-Type'] or ext.empty?
347
+ end
348
+ end
349
+
350
+ # Use the contents of the file at +path+ as the response body.
351
+ def send_file(path, opts = {})
352
+ if opts[:type] or not response['Content-Type']
353
+ content_type opts[:type] || File.extname(path), :default => 'application/octet-stream'
354
+ end
355
+
356
+ disposition = opts[:disposition]
357
+ filename = opts[:filename]
358
+ disposition = 'attachment' if disposition.nil? and filename
359
+ filename = path if filename.nil?
360
+ attachment(filename, disposition) if disposition
361
+
362
+ last_modified opts[:last_modified] if opts[:last_modified]
363
+
364
+ file = Rack::File.new nil
365
+ file.path = path
366
+ result = file.serving env
367
+ result[1].each { |k,v| headers[k] ||= v }
368
+ headers['Content-Length'] = result[1]['Content-Length']
369
+ opts[:status] &&= Integer(opts[:status])
370
+ halt opts[:status] || result[0], result[2]
371
+ rescue Errno::ENOENT
372
+ not_found
373
+ end
374
+
375
+ # Class of the response body in case you use #stream.
376
+ #
377
+ # Three things really matter: The front and back block (back being the
378
+ # block generating content, front the one sending it to the client) and
379
+ # the scheduler, integrating with whatever concurrency feature the Rack
380
+ # handler is using.
381
+ #
382
+ # Scheduler has to respond to defer and schedule.
383
+ class Stream
384
+ def self.schedule(*) yield end
385
+ def self.defer(*) yield end
386
+
387
+ def initialize(scheduler = self.class, keep_open = false, &back)
388
+ @back, @scheduler, @keep_open = back.to_proc, scheduler, keep_open
389
+ @callbacks, @closed = [], false
390
+ end
391
+
392
+ def close
393
+ return if @closed
394
+ @closed = true
395
+ @scheduler.schedule { @callbacks.each { |c| c.call }}
396
+ end
397
+
398
+ def each(&front)
399
+ @front = front
400
+ @scheduler.defer do
401
+ begin
402
+ @back.call(self)
403
+ rescue Exception => e
404
+ @scheduler.schedule { raise e }
405
+ end
406
+ close unless @keep_open
407
+ end
408
+ end
409
+
410
+ def <<(data)
411
+ @scheduler.schedule { @front.call(data.to_s) }
412
+ self
413
+ end
414
+
415
+ def callback(&block)
416
+ return yield if @closed
417
+ @callbacks << block
418
+ end
419
+
420
+ alias errback callback
421
+
422
+ def closed?
423
+ @closed
424
+ end
425
+ end
426
+
427
+ # Allows to start sending data to the client even though later parts of
428
+ # the response body have not yet been generated.
429
+ #
430
+ # The close parameter specifies whether Stream#close should be called
431
+ # after the block has been executed. This is only relevant for evented
432
+ # servers like Thin or Rainbows.
433
+ def stream(keep_open = false)
434
+ scheduler = env['async.callback'] ? EventMachine : Stream
435
+ current = @params.dup
436
+ body Stream.new(scheduler, keep_open) { |out| with_params(current) { yield(out) } }
437
+ end
438
+
439
+ # Specify response freshness policy for HTTP caches (Cache-Control header).
440
+ # Any number of non-value directives (:public, :private, :no_cache,
441
+ # :no_store, :must_revalidate, :proxy_revalidate) may be passed along with
442
+ # a Hash of value directives (:max_age, :min_stale, :s_max_age).
443
+ #
444
+ # cache_control :public, :must_revalidate, :max_age => 60
445
+ # => Cache-Control: public, must-revalidate, max-age=60
446
+ #
447
+ # See RFC 2616 / 14.9 for more on standard cache control directives:
448
+ # http://tools.ietf.org/html/rfc2616#section-14.9.1
449
+ def cache_control(*values)
450
+ if values.last.kind_of?(Hash)
451
+ hash = values.pop
452
+ hash.reject! { |k,v| v == false }
453
+ hash.reject! { |k,v| values << k if v == true }
454
+ else
455
+ hash = {}
456
+ end
457
+
458
+ values.map! { |value| value.to_s.tr('_','-') }
459
+ hash.each do |key, value|
460
+ key = key.to_s.tr('_', '-')
461
+ value = value.to_i if key == "max-age"
462
+ values << "#{key}=#{value}"
463
+ end
464
+
465
+ response['Cache-Control'] = values.join(', ') if values.any?
466
+ end
467
+
468
+ # Set the Expires header and Cache-Control/max-age directive. Amount
469
+ # can be an integer number of seconds in the future or a Time object
470
+ # indicating when the response should be considered "stale". The remaining
471
+ # "values" arguments are passed to the #cache_control helper:
472
+ #
473
+ # expires 500, :public, :must_revalidate
474
+ # => Cache-Control: public, must-revalidate, max-age=60
475
+ # => Expires: Mon, 08 Jun 2009 08:50:17 GMT
476
+ #
477
+ def expires(amount, *values)
478
+ values << {} unless values.last.kind_of?(Hash)
479
+
480
+ if amount.is_a? Integer
481
+ time = Time.now + amount.to_i
482
+ max_age = amount
483
+ else
484
+ time = time_for amount
485
+ max_age = time - Time.now
486
+ end
487
+
488
+ values.last.merge!(:max_age => max_age)
489
+ cache_control(*values)
490
+
491
+ response['Expires'] = time.httpdate
492
+ end
493
+
494
+ # Set the last modified time of the resource (HTTP 'Last-Modified' header)
495
+ # and halt if conditional GET matches. The +time+ argument is a Time,
496
+ # DateTime, or other object that responds to +to_time+.
497
+ #
498
+ # When the current request includes an 'If-Modified-Since' header that is
499
+ # equal or later than the time specified, execution is immediately halted
500
+ # with a '304 Not Modified' response.
501
+ def last_modified(time)
502
+ return unless time
503
+ time = time_for time
504
+ response['Last-Modified'] = time.httpdate
505
+ return if env['HTTP_IF_NONE_MATCH']
506
+
507
+ if status == 200 and env['HTTP_IF_MODIFIED_SINCE']
508
+ # compare based on seconds since epoch
509
+ since = Time.httpdate(env['HTTP_IF_MODIFIED_SINCE']).to_i
510
+ halt 304 if since >= time.to_i
511
+ end
512
+
513
+ if (success? or status == 412) and env['HTTP_IF_UNMODIFIED_SINCE']
514
+ # compare based on seconds since epoch
515
+ since = Time.httpdate(env['HTTP_IF_UNMODIFIED_SINCE']).to_i
516
+ halt 412 if since < time.to_i
517
+ end
518
+ rescue ArgumentError
519
+ end
520
+
521
+ ETAG_KINDS = [:strong, :weak]
522
+ # Set the response entity tag (HTTP 'ETag' header) and halt if conditional
523
+ # GET matches. The +value+ argument is an identifier that uniquely
524
+ # identifies the current version of the resource. The +kind+ argument
525
+ # indicates whether the etag should be used as a :strong (default) or :weak
526
+ # cache validator.
527
+ #
528
+ # When the current request includes an 'If-None-Match' header with a
529
+ # matching etag, execution is immediately halted. If the request method is
530
+ # GET or HEAD, a '304 Not Modified' response is sent.
531
+ def etag(value, options = {})
532
+ # Before touching this code, please double check RFC 2616 14.24 and 14.26.
533
+ options = {:kind => options} unless Hash === options
534
+ kind = options[:kind] || :strong
535
+ new_resource = options.fetch(:new_resource) { request.post? }
536
+
537
+ unless ETAG_KINDS.include?(kind)
538
+ raise ArgumentError, ":strong or :weak expected"
539
+ end
540
+
541
+ value = '"%s"' % value
542
+ value = "W/#{value}" if kind == :weak
543
+ response['ETag'] = value
544
+
545
+ if success? or status == 304
546
+ if etag_matches? env['HTTP_IF_NONE_MATCH'], new_resource
547
+ halt(request.safe? ? 304 : 412)
548
+ end
549
+
550
+ if env['HTTP_IF_MATCH']
551
+ halt 412 unless etag_matches? env['HTTP_IF_MATCH'], new_resource
552
+ end
553
+ end
554
+ end
555
+
556
+ # Sugar for redirect (example: redirect back)
557
+ def back
558
+ request.referer
559
+ end
560
+
561
+ # whether or not the status is set to 1xx
562
+ def informational?
563
+ status.between? 100, 199
564
+ end
565
+
566
+ # whether or not the status is set to 2xx
567
+ def success?
568
+ status.between? 200, 299
569
+ end
570
+
571
+ # whether or not the status is set to 3xx
572
+ def redirect?
573
+ status.between? 300, 399
574
+ end
575
+
576
+ # whether or not the status is set to 4xx
577
+ def client_error?
578
+ status.between? 400, 499
579
+ end
580
+
581
+ # whether or not the status is set to 5xx
582
+ def server_error?
583
+ status.between? 500, 599
584
+ end
585
+
586
+ # whether or not the status is set to 404
587
+ def not_found?
588
+ status == 404
589
+ end
590
+
591
+ # Generates a Time object from the given value.
592
+ # Used by #expires and #last_modified.
593
+ def time_for(value)
594
+ if value.respond_to? :to_time
595
+ value.to_time
596
+ elsif value.is_a? Time
597
+ value
598
+ elsif value.respond_to? :new_offset
599
+ # DateTime#to_time does the same on 1.9
600
+ d = value.new_offset 0
601
+ t = Time.utc d.year, d.mon, d.mday, d.hour, d.min, d.sec + d.sec_fraction
602
+ t.getlocal
603
+ elsif value.respond_to? :mday
604
+ # Date#to_time does the same on 1.9
605
+ Time.local(value.year, value.mon, value.mday)
606
+ elsif value.is_a? Numeric
607
+ Time.at value
608
+ else
609
+ Time.parse value.to_s
610
+ end
611
+ rescue ArgumentError => boom
612
+ raise boom
613
+ rescue Exception
614
+ raise ArgumentError, "unable to convert #{value.inspect} to a Time object"
615
+ end
616
+
617
+ private
618
+
619
+ # Helper method checking if a ETag value list includes the current ETag.
620
+ def etag_matches?(list, new_resource = request.post?)
621
+ return !new_resource if list == '*'
622
+ list.to_s.split(/\s*,\s*/).include? response['ETag']
623
+ end
624
+
625
+ def with_params(temp_params)
626
+ original, @params = @params, temp_params
627
+ yield
628
+ ensure
629
+ @params = original if original
630
+ end
631
+ end
632
+
633
+ private
634
+
635
+ # Template rendering methods. Each method takes the name of a template
636
+ # to render as a Symbol and returns a String with the rendered output,
637
+ # as well as an optional hash with additional options.
638
+ #
639
+ # `template` is either the name or path of the template as symbol
640
+ # (Use `:'subdir/myview'` for views in subdirectories), or a string
641
+ # that will be rendered.
642
+ #
643
+ # Possible options are:
644
+ # :content_type The content type to use, same arguments as content_type.
645
+ # :layout If set to something falsy, no layout is rendered, otherwise
646
+ # the specified layout is used (Ignored for `sass` and `less`)
647
+ # :layout_engine Engine to use for rendering the layout.
648
+ # :locals A hash with local variables that should be available
649
+ # in the template
650
+ # :scope If set, template is evaluate with the binding of the given
651
+ # object rather than the application instance.
652
+ # :views Views directory to use.
653
+ module Templates
654
+ module ContentTyped
655
+ attr_accessor :content_type
656
+ end
657
+
658
+ def initialize
659
+ super
660
+ @default_layout = :layout
661
+ end
662
+
663
+ def erb(template, options = {}, locals = {}, &block)
664
+ render(:erb, template, options, locals, &block)
665
+ end
666
+
667
+ def erubis(template, options = {}, locals = {})
668
+ warn "Sinatra::Templates#erubis is deprecated and will be removed, use #erb instead.\n" \
669
+ "If you have Erubis installed, it will be used automatically."
670
+ render :erubis, template, options, locals
671
+ end
672
+
673
+ def haml(template, options = {}, locals = {}, &block)
674
+ render(:haml, template, options, locals, &block)
675
+ end
676
+
677
+ def sass(template, options = {}, locals = {})
678
+ options.merge! :layout => false, :default_content_type => :css
679
+ render :sass, template, options, locals
680
+ end
681
+
682
+ def scss(template, options = {}, locals = {})
683
+ options.merge! :layout => false, :default_content_type => :css
684
+ render :scss, template, options, locals
685
+ end
686
+
687
+ def less(template, options = {}, locals = {})
688
+ options.merge! :layout => false, :default_content_type => :css
689
+ render :less, template, options, locals
690
+ end
691
+
692
+ def stylus(template, options={}, locals={})
693
+ options.merge! :layout => false, :default_content_type => :css
694
+ render :styl, template, options, locals
695
+ end
696
+
697
+ def builder(template = nil, options = {}, locals = {}, &block)
698
+ options[:default_content_type] = :xml
699
+ render_ruby(:builder, template, options, locals, &block)
700
+ end
701
+
702
+ def liquid(template, options = {}, locals = {}, &block)
703
+ render(:liquid, template, options, locals, &block)
704
+ end
705
+
706
+ def markdown(template, options = {}, locals = {})
707
+ render :markdown, template, options, locals
708
+ end
709
+
710
+ def textile(template, options = {}, locals = {})
711
+ render :textile, template, options, locals
712
+ end
713
+
714
+ def rdoc(template, options = {}, locals = {})
715
+ render :rdoc, template, options, locals
716
+ end
717
+
718
+ def radius(template, options = {}, locals = {})
719
+ render :radius, template, options, locals
720
+ end
721
+
722
+ def markaby(template = nil, options = {}, locals = {}, &block)
723
+ render_ruby(:mab, template, options, locals, &block)
724
+ end
725
+
726
+ def coffee(template, options = {}, locals = {})
727
+ options.merge! :layout => false, :default_content_type => :js
728
+ render :coffee, template, options, locals
729
+ end
730
+
731
+ def nokogiri(template = nil, options = {}, locals = {}, &block)
732
+ options[:default_content_type] = :xml
733
+ render_ruby(:nokogiri, template, options, locals, &block)
734
+ end
735
+
736
+ def slim(template, options = {}, locals = {}, &block)
737
+ render(:slim, template, options, locals, &block)
738
+ end
739
+
740
+ def creole(template, options = {}, locals = {})
741
+ render :creole, template, options, locals
742
+ end
743
+
744
+ def wlang(template, options = {}, locals = {}, &block)
745
+ render(:wlang, template, options, locals, &block)
746
+ end
747
+
748
+ def yajl(template, options = {}, locals = {})
749
+ options[:default_content_type] = :json
750
+ render :yajl, template, options, locals
751
+ end
752
+
753
+ def rabl(template, options = {}, locals = {})
754
+ Rabl.register!
755
+ render :rabl, template, options, locals
756
+ end
757
+
758
+ # Calls the given block for every possible template file in views,
759
+ # named name.ext, where ext is registered on engine.
760
+ def find_template(views, name, engine)
761
+ yield ::File.join(views, "#{name}.#{@preferred_extension}")
762
+ Tilt.mappings.each do |ext, engines|
763
+ next unless ext != @preferred_extension and engines.include? engine
764
+ yield ::File.join(views, "#{name}.#{ext}")
765
+ end
766
+ end
767
+
768
+ private
769
+
770
+ # logic shared between builder and nokogiri
771
+ def render_ruby(engine, template, options = {}, locals = {}, &block)
772
+ options, template = template, nil if template.is_a?(Hash)
773
+ template = Proc.new { block } if template.nil?
774
+ render engine, template, options, locals
775
+ end
776
+
777
+ def render(engine, data, options = {}, locals = {}, &block)
778
+ # merge app-level options
779
+ engine_options = settings.respond_to?(engine) ? settings.send(engine) : {}
780
+ options.merge!(engine_options) { |key, v1, v2| v1 }
781
+
782
+ # extract generic options
783
+ locals = options.delete(:locals) || locals || {}
784
+ views = options.delete(:views) || settings.views || "./views"
785
+ layout = options[:layout]
786
+ layout = false if layout.nil? && options.include?(:layout)
787
+ eat_errors = layout.nil?
788
+ layout = engine_options[:layout] if layout.nil? or (layout == true && engine_options[:layout] != false)
789
+ layout = @default_layout if layout.nil? or layout == true
790
+ layout_options = options.delete(:layout_options) || {}
791
+ content_type = options.delete(:content_type) || options.delete(:default_content_type)
792
+ layout_engine = options.delete(:layout_engine) || engine
793
+ scope = options.delete(:scope) || self
794
+ options.delete(:layout)
795
+
796
+ # set some defaults
797
+ options[:outvar] ||= '@_out_buf'
798
+ options[:default_encoding] ||= settings.default_encoding
799
+
800
+ # compile and render template
801
+ begin
802
+ layout_was = @default_layout
803
+ @default_layout = false
804
+ template = compile_template(engine, data, options, views)
805
+ output = template.render(scope, locals, &block)
806
+ ensure
807
+ @default_layout = layout_was
808
+ end
809
+
810
+ # render layout
811
+ if layout
812
+ options.merge!(:views => views, :layout => false, :eat_errors => eat_errors, :scope => scope).
813
+ merge!(layout_options)
814
+ catch(:layout_missing) { return render(layout_engine, layout, options, locals) { output } }
815
+ end
816
+
817
+ output.extend(ContentTyped).content_type = content_type if content_type
818
+ output
819
+ end
820
+
821
+ def compile_template(engine, data, options, views)
822
+ eat_errors = options.delete :eat_errors
823
+ template_cache.fetch engine, data, options, views do
824
+ template = Tilt[engine]
825
+ raise "Template engine not found: #{engine}" if template.nil?
826
+
827
+ case data
828
+ when Symbol
829
+ body, path, line = settings.templates[data]
830
+ if body
831
+ body = body.call if body.respond_to?(:call)
832
+ template.new(path, line.to_i, options) { body }
833
+ else
834
+ found = false
835
+ @preferred_extension = engine.to_s
836
+ find_template(views, data, template) do |file|
837
+ path ||= file # keep the initial path rather than the last one
838
+ if found = File.exists?(file)
839
+ path = file
840
+ break
841
+ end
842
+ end
843
+ throw :layout_missing if eat_errors and not found
844
+ template.new(path, 1, options)
845
+ end
846
+ when Proc, String
847
+ body = data.is_a?(String) ? Proc.new { data } : data
848
+ path, line = settings.caller_locations.first
849
+ template.new(path, line.to_i, options, &body)
850
+ else
851
+ raise ArgumentError, "Sorry, don't know how to render #{data.inspect}."
852
+ end
853
+ end
854
+ end
855
+ end
856
+
857
+ # Base class for all Sinatra applications and middleware.
858
+ class Base
859
+ include Rack::Utils
860
+ include Helpers
861
+ include Templates
862
+
863
+ URI_INSTANCE = URI.const_defined?(:Parser) ? URI::Parser.new : URI
864
+
865
+ attr_accessor :app, :env, :request, :response, :params
866
+ attr_reader :template_cache
867
+
868
+ def initialize(app = nil)
869
+ super()
870
+ @app = app
871
+ @template_cache = Tilt::Cache.new
872
+ yield self if block_given?
873
+ end
874
+
875
+ # Rack call interface.
876
+ def call(env)
877
+ dup.call!(env)
878
+ end
879
+
880
+ def call!(env) # :nodoc:
881
+ @env = env
882
+ @request = Request.new(env)
883
+ @response = Response.new
884
+ @params = indifferent_params(@request.params)
885
+ template_cache.clear if settings.reload_templates
886
+ force_encoding(@params)
887
+
888
+ @response['Content-Type'] = nil
889
+ invoke { dispatch! }
890
+ invoke { error_block!(response.status) } unless @env['sinatra.error']
891
+
892
+ unless @response['Content-Type']
893
+ if Array === body and body[0].respond_to? :content_type
894
+ content_type body[0].content_type
895
+ else
896
+ content_type :html
897
+ end
898
+ end
899
+
900
+ @response.finish
901
+ end
902
+
903
+ # Access settings defined with Base.set.
904
+ def self.settings
905
+ self
906
+ end
907
+
908
+ # Access settings defined with Base.set.
909
+ def settings
910
+ self.class.settings
911
+ end
912
+
913
+ def options
914
+ warn "Sinatra::Base#options is deprecated and will be removed, " \
915
+ "use #settings instead."
916
+ settings
917
+ end
918
+
919
+ # Exit the current block, halts any further processing
920
+ # of the request, and returns the specified response.
921
+ def halt(*response)
922
+ response = response.first if response.length == 1
923
+ throw :halt, response
924
+ end
925
+
926
+ # Pass control to the next matching route.
927
+ # If there are no more matching routes, Sinatra will
928
+ # return a 404 response.
929
+ def pass(&block)
930
+ throw :pass, block
931
+ end
932
+
933
+ # Forward the request to the downstream app -- middleware only.
934
+ def forward
935
+ fail "downstream app not set" unless @app.respond_to? :call
936
+ status, headers, body = @app.call env
937
+ @response.status = status
938
+ @response.body = body
939
+ @response.headers.merge! headers
940
+ nil
941
+ end
942
+
943
+ private
944
+
945
+ # Run filters defined on the class and all superclasses.
946
+ def filter!(type, base = settings)
947
+ filter! type, base.superclass if base.superclass.respond_to?(:filters)
948
+ base.filters[type].each { |args| process_route(*args) }
949
+ end
950
+
951
+ # Run routes defined on the class and all superclasses.
952
+ def route!(base = settings, pass_block = nil)
953
+ if routes = base.routes[@request.request_method]
954
+ routes.each do |pattern, keys, conditions, block|
955
+ returned_pass_block = process_route(pattern, keys, conditions) do |*args|
956
+ env['sinatra.route'] = block.instance_variable_get(:@route_name)
957
+ route_eval { block[*args] }
958
+ end
959
+
960
+ # don't wipe out pass_block in superclass
961
+ pass_block = returned_pass_block if returned_pass_block
962
+ end
963
+ end
964
+
965
+ # Run routes defined in superclass.
966
+ if base.superclass.respond_to?(:routes)
967
+ return route!(base.superclass, pass_block)
968
+ end
969
+
970
+ route_eval(&pass_block) if pass_block
971
+ route_missing
972
+ end
973
+
974
+ # Run a route block and throw :halt with the result.
975
+ def route_eval
976
+ throw :halt, yield
977
+ end
978
+
979
+ # If the current request matches pattern and conditions, fill params
980
+ # with keys and call the given block.
981
+ # Revert params afterwards.
982
+ #
983
+ # Returns pass block.
984
+ def process_route(pattern, keys, conditions, block = nil, values = [])
985
+ route = @request.path_info
986
+ route = '/' if route.empty? and not settings.empty_path_info?
987
+ return unless match = pattern.match(route)
988
+ values += match.captures.map! { |v| force_encoding URI_INSTANCE.unescape(v) if v }
989
+
990
+ if values.any?
991
+ original, @params = params, params.merge('splat' => [], 'captures' => values)
992
+ keys.zip(values) { |k,v| Array === @params[k] ? @params[k] << v : @params[k] = v if v }
993
+ end
994
+
995
+ catch(:pass) do
996
+ conditions.each { |c| throw :pass if c.bind(self).call == false }
997
+ block ? block[self, values] : yield(self, values)
998
+ end
999
+ ensure
1000
+ @params = original if original
1001
+ end
1002
+
1003
+ # No matching route was found or all routes passed. The default
1004
+ # implementation is to forward the request downstream when running
1005
+ # as middleware (@app is non-nil); when no downstream app is set, raise
1006
+ # a NotFound exception. Subclasses can override this method to perform
1007
+ # custom route miss logic.
1008
+ def route_missing
1009
+ if @app
1010
+ forward
1011
+ else
1012
+ raise NotFound
1013
+ end
1014
+ end
1015
+
1016
+ # Attempt to serve static files from public directory. Throws :halt when
1017
+ # a matching file is found, returns nil otherwise.
1018
+ def static!
1019
+ return if (public_dir = settings.public_folder).nil?
1020
+ path = File.expand_path("#{public_dir}#{unescape(request.path_info)}" )
1021
+ return unless File.file?(path)
1022
+
1023
+ env['sinatra.static_file'] = path
1024
+ cache_control(*settings.static_cache_control) if settings.static_cache_control?
1025
+ send_file path, :disposition => nil
1026
+ end
1027
+
1028
+ # Enable string or symbol key access to the nested params hash.
1029
+ def indifferent_params(object)
1030
+ case object
1031
+ when Hash
1032
+ new_hash = indifferent_hash
1033
+ object.each { |key, value| new_hash[key] = indifferent_params(value) }
1034
+ new_hash
1035
+ when Array
1036
+ object.map { |item| indifferent_params(item) }
1037
+ else
1038
+ object
1039
+ end
1040
+ end
1041
+
1042
+ # Creates a Hash with indifferent access.
1043
+ def indifferent_hash
1044
+ Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
1045
+ end
1046
+
1047
+ # Run the block with 'throw :halt' support and apply result to the response.
1048
+ def invoke
1049
+ res = catch(:halt) { yield }
1050
+ res = [res] if Fixnum === res or String === res
1051
+ if Array === res and Fixnum === res.first
1052
+ res = res.dup
1053
+ status(res.shift)
1054
+ body(res.pop)
1055
+ headers(*res)
1056
+ elsif res.respond_to? :each
1057
+ body res
1058
+ end
1059
+ nil # avoid double setting the same response tuple twice
1060
+ end
1061
+
1062
+ # Dispatch a request with error handling.
1063
+ def dispatch!
1064
+ invoke do
1065
+ static! if settings.static? && (request.get? || request.head?)
1066
+ filter! :before
1067
+ route!
1068
+ end
1069
+ rescue ::Exception => boom
1070
+ invoke { handle_exception!(boom) }
1071
+ ensure
1072
+ begin
1073
+ filter! :after unless env['sinatra.static_file']
1074
+ rescue ::Exception => boom
1075
+ invoke { handle_exception!(boom) } unless @env['sinatra.error']
1076
+ end
1077
+ end
1078
+
1079
+ # Error handling during requests.
1080
+ def handle_exception!(boom)
1081
+ @env['sinatra.error'] = boom
1082
+
1083
+ if boom.respond_to? :http_status
1084
+ status(boom.http_status)
1085
+ elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599
1086
+ status(boom.code)
1087
+ else
1088
+ status(500)
1089
+ end
1090
+
1091
+ status(500) unless status.between? 400, 599
1092
+
1093
+ if server_error?
1094
+ dump_errors! boom if settings.dump_errors?
1095
+ raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
1096
+ end
1097
+
1098
+ if not_found?
1099
+ headers['X-Cascade'] = 'pass' if settings.x_cascade?
1100
+ body '<h1>Not Found</h1>'
1101
+ end
1102
+
1103
+ res = error_block!(boom.class, boom) || error_block!(status, boom)
1104
+ return res if res or not server_error?
1105
+ raise boom if settings.raise_errors? or settings.show_exceptions?
1106
+ error_block! Exception, boom
1107
+ end
1108
+
1109
+ # Find an custom error block for the key(s) specified.
1110
+ def error_block!(key, *block_params)
1111
+ base = settings
1112
+ while base.respond_to?(:errors)
1113
+ next base = base.superclass unless args_array = base.errors[key]
1114
+ args_array.reverse_each do |args|
1115
+ first = args == args_array.first
1116
+ args += [block_params]
1117
+ resp = process_route(*args)
1118
+ return resp unless resp.nil? && !first
1119
+ end
1120
+ end
1121
+ return false unless key.respond_to? :superclass and key.superclass < Exception
1122
+ error_block!(key.superclass, *block_params)
1123
+ end
1124
+
1125
+ def dump_errors!(boom)
1126
+ msg = ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t")
1127
+ @env['rack.errors'].puts(msg)
1128
+ end
1129
+
1130
+ class << self
1131
+ CALLERS_TO_IGNORE = [ # :nodoc:
1132
+ /\/sinatra(\/(base|main|showexceptions))?\.rb$/, # all sinatra code
1133
+ /lib\/tilt.*\.rb$/, # all tilt code
1134
+ /^\(.*\)$/, # generated code
1135
+ /rubygems\/(custom|core_ext\/kernel)_require\.rb$/, # rubygems require hacks
1136
+ /active_support/, # active_support require hacks
1137
+ /bundler(\/runtime)?\.rb/, # bundler require hacks
1138
+ /<internal:/, # internal in ruby >= 1.9.2
1139
+ /src\/kernel\/bootstrap\/[A-Z]/ # maglev kernel files
1140
+ ]
1141
+
1142
+ # contrary to what the comment said previously, rubinius never supported this
1143
+ if defined?(RUBY_IGNORE_CALLERS)
1144
+ warn "RUBY_IGNORE_CALLERS is deprecated and will no longer be supported by Sinatra 2.0"
1145
+ CALLERS_TO_IGNORE.concat(RUBY_IGNORE_CALLERS)
1146
+ end
1147
+
1148
+ attr_reader :routes, :filters, :templates, :errors
1149
+
1150
+ # Removes all routes, filters, middleware and extension hooks from the
1151
+ # current class (not routes/filters/... defined by its superclass).
1152
+ def reset!
1153
+ @conditions = []
1154
+ @routes = {}
1155
+ @filters = {:before => [], :after => []}
1156
+ @errors = {}
1157
+ @middleware = []
1158
+ @prototype = nil
1159
+ @extensions = []
1160
+
1161
+ if superclass.respond_to?(:templates)
1162
+ @templates = Hash.new { |hash,key| superclass.templates[key] }
1163
+ else
1164
+ @templates = {}
1165
+ end
1166
+ end
1167
+
1168
+ # Extension modules registered on this class and all superclasses.
1169
+ def extensions
1170
+ if superclass.respond_to?(:extensions)
1171
+ (@extensions + superclass.extensions).uniq
1172
+ else
1173
+ @extensions
1174
+ end
1175
+ end
1176
+
1177
+ # Middleware used in this class and all superclasses.
1178
+ def middleware
1179
+ if superclass.respond_to?(:middleware)
1180
+ superclass.middleware + @middleware
1181
+ else
1182
+ @middleware
1183
+ end
1184
+ end
1185
+
1186
+ # Sets an option to the given value. If the value is a proc,
1187
+ # the proc will be called every time the option is accessed.
1188
+ def set(option, value = (not_set = true), ignore_setter = false, &block)
1189
+ raise ArgumentError if block and !not_set
1190
+ value, not_set = block, false if block
1191
+
1192
+ if not_set
1193
+ raise ArgumentError unless option.respond_to?(:each)
1194
+ option.each { |k,v| set(k, v) }
1195
+ return self
1196
+ end
1197
+
1198
+ if respond_to?("#{option}=") and not ignore_setter
1199
+ return __send__("#{option}=", value)
1200
+ end
1201
+
1202
+ setter = proc { |val| set option, val, true }
1203
+ getter = proc { value }
1204
+
1205
+ case value
1206
+ when Proc
1207
+ getter = value
1208
+ when Symbol, Fixnum, FalseClass, TrueClass, NilClass
1209
+ getter = value.inspect
1210
+ when Hash
1211
+ setter = proc do |val|
1212
+ val = value.merge val if Hash === val
1213
+ set option, val, true
1214
+ end
1215
+ end
1216
+
1217
+ define_singleton("#{option}=", setter) if setter
1218
+ define_singleton(option, getter) if getter
1219
+ define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
1220
+ self
1221
+ end
1222
+
1223
+ # Same as calling `set :option, true` for each of the given options.
1224
+ def enable(*opts)
1225
+ opts.each { |key| set(key, true) }
1226
+ end
1227
+
1228
+ # Same as calling `set :option, false` for each of the given options.
1229
+ def disable(*opts)
1230
+ opts.each { |key| set(key, false) }
1231
+ end
1232
+
1233
+ # Define a custom error handler. Optionally takes either an Exception
1234
+ # class, or an HTTP status code to specify which errors should be
1235
+ # handled.
1236
+ def error(*codes, &block)
1237
+ args = compile! "ERROR", //, block
1238
+ codes = codes.map { |c| Array(c) }.flatten
1239
+ codes << Exception if codes.empty?
1240
+ codes.each { |c| (@errors[c] ||= []) << args }
1241
+ end
1242
+
1243
+ # Sugar for `error(404) { ... }`
1244
+ def not_found(&block)
1245
+ error(404, &block)
1246
+ error(Sinatra::NotFound, &block)
1247
+ end
1248
+
1249
+ # Define a named template. The block must return the template source.
1250
+ def template(name, &block)
1251
+ filename, line = caller_locations.first
1252
+ templates[name] = [block, filename, line.to_i]
1253
+ end
1254
+
1255
+ # Define the layout template. The block must return the template source.
1256
+ def layout(name = :layout, &block)
1257
+ template name, &block
1258
+ end
1259
+
1260
+ # Load embedded templates from the file; uses the caller's __FILE__
1261
+ # when no file is specified.
1262
+ def inline_templates=(file = nil)
1263
+ file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file
1264
+
1265
+ begin
1266
+ io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file)
1267
+ app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
1268
+ rescue Errno::ENOENT
1269
+ app, data = nil
1270
+ end
1271
+
1272
+ if data
1273
+ if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m
1274
+ encoding = $2
1275
+ else
1276
+ encoding = settings.default_encoding
1277
+ end
1278
+ lines = app.count("\n") + 1
1279
+ template = nil
1280
+ force_encoding data, encoding
1281
+ data.each_line do |line|
1282
+ lines += 1
1283
+ if line =~ /^@@\s*(.*\S)\s*$/
1284
+ template = force_encoding('', encoding)
1285
+ templates[$1.to_sym] = [template, file, lines]
1286
+ elsif template
1287
+ template << line
1288
+ end
1289
+ end
1290
+ end
1291
+ end
1292
+
1293
+ # Lookup or register a mime type in Rack's mime registry.
1294
+ def mime_type(type, value = nil)
1295
+ return type if type.nil?
1296
+ return type.to_s if type.to_s.include?('/')
1297
+ type = ".#{type}" unless type.to_s[0] == ?.
1298
+ return Rack::Mime.mime_type(type, nil) unless value
1299
+ Rack::Mime::MIME_TYPES[type] = value
1300
+ end
1301
+
1302
+ # provides all mime types matching type, including deprecated types:
1303
+ # mime_types :html # => ['text/html']
1304
+ # mime_types :js # => ['application/javascript', 'text/javascript']
1305
+ def mime_types(type)
1306
+ type = mime_type type
1307
+ type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type]
1308
+ end
1309
+
1310
+ # Define a before filter; runs before all requests within the same
1311
+ # context as route handlers and may access/modify the request and
1312
+ # response.
1313
+ def before(path = nil, options = {}, &block)
1314
+ add_filter(:before, path, options, &block)
1315
+ end
1316
+
1317
+ # Define an after filter; runs after all requests within the same
1318
+ # context as route handlers and may access/modify the request and
1319
+ # response.
1320
+ def after(path = nil, options = {}, &block)
1321
+ add_filter(:after, path, options, &block)
1322
+ end
1323
+
1324
+ # add a filter
1325
+ def add_filter(type, path = nil, options = {}, &block)
1326
+ path, options = //, path if path.respond_to?(:each_pair)
1327
+ filters[type] << compile!(type, path || //, block, options)
1328
+ end
1329
+
1330
+ # Add a route condition. The route is considered non-matching when the
1331
+ # block returns false.
1332
+ def condition(name = "#{caller.first[/`.*'/]} condition", &block)
1333
+ @conditions << generate_method(name, &block)
1334
+ end
1335
+
1336
+ def public=(value)
1337
+ warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead"
1338
+ set(:public_folder, value)
1339
+ end
1340
+
1341
+ def public_dir=(value)
1342
+ self.public_folder = value
1343
+ end
1344
+
1345
+ def public_dir
1346
+ public_folder
1347
+ end
1348
+
1349
+ # Defining a `GET` handler also automatically defines
1350
+ # a `HEAD` handler.
1351
+ def get(path, opts = {}, &block)
1352
+ conditions = @conditions.dup
1353
+ route('GET', path, opts, &block)
1354
+
1355
+ @conditions = conditions
1356
+ route('HEAD', path, opts, &block)
1357
+ end
1358
+
1359
+ def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
1360
+ def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
1361
+ def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
1362
+ def head(path, opts = {}, &bk) route 'HEAD', path, opts, &bk end
1363
+ def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
1364
+ def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
1365
+ def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
1366
+ def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
1367
+
1368
+ # Makes the methods defined in the block and in the Modules given
1369
+ # in `extensions` available to the handlers and templates
1370
+ def helpers(*extensions, &block)
1371
+ class_eval(&block) if block_given?
1372
+ include(*extensions) if extensions.any?
1373
+ end
1374
+
1375
+ # Register an extension. Alternatively take a block from which an
1376
+ # extension will be created and registered on the fly.
1377
+ def register(*extensions, &block)
1378
+ extensions << Module.new(&block) if block_given?
1379
+ @extensions += extensions
1380
+ extensions.each do |extension|
1381
+ extend extension
1382
+ extension.registered(self) if extension.respond_to?(:registered)
1383
+ end
1384
+ end
1385
+
1386
+ def development?; environment == :development end
1387
+ def production?; environment == :production end
1388
+ def test?; environment == :test end
1389
+
1390
+ # Set configuration options for Sinatra and/or the app.
1391
+ # Allows scoping of settings for certain environments.
1392
+ def configure(*envs)
1393
+ yield self if envs.empty? || envs.include?(environment.to_sym)
1394
+ end
1395
+
1396
+ # Use the specified Rack middleware
1397
+ def use(middleware, *args, &block)
1398
+ @prototype = nil
1399
+ @middleware << [middleware, args, block]
1400
+ end
1401
+
1402
+ # Stop the self-hosted server if running.
1403
+ def quit!
1404
+ return unless running?
1405
+ # Use Thin's hard #stop! if available, otherwise just #stop.
1406
+ running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop
1407
+ $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/i
1408
+ set :running_server, nil
1409
+ set :handler_name, nil
1410
+ end
1411
+
1412
+ alias_method :stop!, :quit!
1413
+
1414
+ # Run the Sinatra app as a self-hosted server using
1415
+ # Thin, Puma, Mongrel, or WEBrick (in that order). If given a block, will call
1416
+ # with the constructed handler once we have taken the stage.
1417
+ def run!(options = {}, &block)
1418
+ return if running?
1419
+ set options
1420
+ handler = detect_rack_handler
1421
+ handler_name = handler.name.gsub(/.*::/, '')
1422
+ server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
1423
+ server_settings.merge!(:Port => port, :Host => bind)
1424
+
1425
+ begin
1426
+ start_server(handler, server_settings, handler_name, &block)
1427
+ rescue Errno::EADDRINUSE
1428
+ $stderr.puts "== Someone is already performing on port #{port}!"
1429
+ raise
1430
+ ensure
1431
+ quit!
1432
+ end
1433
+ end
1434
+
1435
+ alias_method :start!, :run!
1436
+
1437
+ # Check whether the self-hosted server is running or not.
1438
+ def running?
1439
+ running_server?
1440
+ end
1441
+
1442
+ # The prototype instance used to process requests.
1443
+ def prototype
1444
+ @prototype ||= new
1445
+ end
1446
+
1447
+ # Create a new instance without middleware in front of it.
1448
+ alias new! new unless method_defined? :new!
1449
+
1450
+ # Create a new instance of the class fronted by its middleware
1451
+ # pipeline. The object is guaranteed to respond to #call but may not be
1452
+ # an instance of the class new was called on.
1453
+ def new(*args, &bk)
1454
+ instance = new!(*args, &bk)
1455
+ Wrapper.new(build(instance).to_app, instance)
1456
+ end
1457
+
1458
+ # Creates a Rack::Builder instance with all the middleware set up and
1459
+ # the given +app+ as end point.
1460
+ def build(app)
1461
+ builder = Rack::Builder.new
1462
+ setup_default_middleware builder
1463
+ setup_middleware builder
1464
+ builder.run app
1465
+ builder
1466
+ end
1467
+
1468
+ def call(env)
1469
+ synchronize { prototype.call(env) }
1470
+ end
1471
+
1472
+ # Like Kernel#caller but excluding certain magic entries and without
1473
+ # line / method information; the resulting array contains filenames only.
1474
+ def caller_files
1475
+ cleaned_caller(1).flatten
1476
+ end
1477
+
1478
+ # Like caller_files, but containing Arrays rather than strings with the
1479
+ # first element being the file, and the second being the line.
1480
+ def caller_locations
1481
+ cleaned_caller 2
1482
+ end
1483
+
1484
+ private
1485
+
1486
+ # Starts the server by running the Rack Handler.
1487
+ def start_server(handler, server_settings, handler_name)
1488
+ handler.run(self, server_settings) do |server|
1489
+ unless handler_name =~ /cgi/i
1490
+ $stderr.puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
1491
+ "on #{port} for #{environment} with backup from #{handler_name}"
1492
+ end
1493
+
1494
+ setup_traps
1495
+ set :running_server, server
1496
+ set :handler_name, handler_name
1497
+ server.threaded = settings.threaded if server.respond_to? :threaded=
1498
+
1499
+ yield server if block_given?
1500
+ end
1501
+ end
1502
+
1503
+ def setup_traps
1504
+ if traps?
1505
+ at_exit { quit! }
1506
+
1507
+ [:INT, :TERM].each do |signal|
1508
+ old_handler = trap(signal) do
1509
+ quit!
1510
+ old_handler.call if old_handler.respond_to?(:call)
1511
+ end
1512
+ end
1513
+
1514
+ set :traps, false
1515
+ end
1516
+ end
1517
+
1518
+ # Dynamically defines a method on settings.
1519
+ def define_singleton(name, content = Proc.new)
1520
+ # replace with call to singleton_class once we're 1.9 only
1521
+ (class << self; self; end).class_eval do
1522
+ undef_method(name) if method_defined? name
1523
+ String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
1524
+ end
1525
+ end
1526
+
1527
+ # Condition for matching host name. Parameter might be String or Regexp.
1528
+ def host_name(pattern)
1529
+ condition { pattern === request.host }
1530
+ end
1531
+
1532
+ # Condition for matching user agent. Parameter should be Regexp.
1533
+ # Will set params[:agent].
1534
+ def user_agent(pattern)
1535
+ condition do
1536
+ if request.user_agent.to_s =~ pattern
1537
+ @params[:agent] = $~[1..-1]
1538
+ true
1539
+ else
1540
+ false
1541
+ end
1542
+ end
1543
+ end
1544
+ alias_method :agent, :user_agent
1545
+
1546
+ # Condition for matching mimetypes. Accepts file extensions.
1547
+ def provides(*types)
1548
+ types.map! { |t| mime_types(t) }
1549
+ types.flatten!
1550
+ condition do
1551
+ if type = response['Content-Type']
1552
+ types.include? type or types.include? type[/^[^;]+/]
1553
+ elsif type = request.preferred_type(types)
1554
+ params = (type.respond_to?(:params) ? type.params : {})
1555
+ content_type(type, params)
1556
+ true
1557
+ else
1558
+ false
1559
+ end
1560
+ end
1561
+ end
1562
+
1563
+ def route(verb, path, options = {}, &block)
1564
+ # Because of self.options.host
1565
+ host_name(options.delete(:host)) if options.key?(:host)
1566
+ enable :empty_path_info if path == "" and empty_path_info.nil?
1567
+ signature = compile!(verb, path, block, options)
1568
+ (@routes[verb] ||= []) << signature
1569
+ invoke_hook(:route_added, verb, path, block)
1570
+ signature
1571
+ end
1572
+
1573
+ def invoke_hook(name, *args)
1574
+ extensions.each { |e| e.send(name, *args) if e.respond_to?(name) }
1575
+ end
1576
+
1577
+ def generate_method(method_name, &block)
1578
+ define_method(method_name, &block)
1579
+ method = instance_method method_name
1580
+ remove_method method_name
1581
+ method
1582
+ end
1583
+
1584
+ def compile!(verb, path, block, options = {})
1585
+ options.each_pair { |option, args| send(option, *args) }
1586
+ method_name = "#{verb} #{path}"
1587
+ unbound_method = generate_method(method_name, &block)
1588
+ pattern, keys = compile path
1589
+ conditions, @conditions = @conditions, []
1590
+
1591
+ wrapper = block.arity != 0 ?
1592
+ proc { |a,p| unbound_method.bind(a).call(*p) } :
1593
+ proc { |a,p| unbound_method.bind(a).call }
1594
+ wrapper.instance_variable_set(:@route_name, method_name)
1595
+
1596
+ [ pattern, keys, conditions, wrapper ]
1597
+ end
1598
+
1599
+ def compile(path)
1600
+ if path.respond_to? :to_str
1601
+ keys = []
1602
+
1603
+ # We append a / at the end if there was one.
1604
+ # Reason: Splitting does not split off an empty
1605
+ # string at the end if the split separator
1606
+ # is at the end.
1607
+ #
1608
+ postfix = '/' if path =~ /\/\z/
1609
+
1610
+ # Split the path into pieces in between forward slashes.
1611
+ #
1612
+ segments = path.split('/').map! do |segment|
1613
+ ignore = []
1614
+
1615
+ # Special character handling.
1616
+ #
1617
+ pattern = segment.to_str.gsub(/[^\?\%\\\/\:\*\w]/) do |c|
1618
+ ignore << escaped(c).join if c.match(/[\.@]/)
1619
+ patt = encoded(c)
1620
+ patt.gsub(/%[\da-fA-F]{2}/) do |match|
1621
+ match.split(//).map! {|char| char =~ /[A-Z]/ ? "[#{char}#{char.tr('A-Z', 'a-z')}]" : char}.join
1622
+ end
1623
+ end
1624
+
1625
+ ignore = ignore.uniq.join
1626
+
1627
+ # Key handling.
1628
+ #
1629
+ pattern.gsub(/((:\w+)|\*)/) do |match|
1630
+ if match == "*"
1631
+ keys << 'splat'
1632
+ "(.*?)"
1633
+ else
1634
+ keys << $2[1..-1]
1635
+ ignore_pattern = safe_ignore(ignore)
1636
+
1637
+ ignore_pattern
1638
+ end
1639
+ end
1640
+ end
1641
+
1642
+ # Special case handling.
1643
+ #
1644
+ if segment = segments.pop
1645
+ if segment.match(/\[\^\\\./)
1646
+ parts = segment.rpartition(/\[\^\\\./)
1647
+ parts[1] = '[^'
1648
+ segments << parts.join
1649
+ else
1650
+ segments << segment
1651
+ end
1652
+ end
1653
+ [/\A#{segments.join('/')}#{postfix}\z/, keys]
1654
+ elsif path.respond_to?(:keys) && path.respond_to?(:match)
1655
+ [path, path.keys]
1656
+ elsif path.respond_to?(:names) && path.respond_to?(:match)
1657
+ [path, path.names]
1658
+ elsif path.respond_to? :match
1659
+ [path, []]
1660
+ else
1661
+ raise TypeError, path
1662
+ end
1663
+ end
1664
+
1665
+ def encoded(char)
1666
+ enc = URI_INSTANCE.escape(char)
1667
+ enc = "(?:#{escaped(char, enc).join('|')})" if enc == char
1668
+ enc = "(?:#{enc}|#{encoded('+')})" if char == " "
1669
+ enc
1670
+ end
1671
+
1672
+ def escaped(char, enc = URI_INSTANCE.escape(char))
1673
+ [Regexp.escape(enc), URI_INSTANCE.escape(char, /./)]
1674
+ end
1675
+
1676
+ def safe_ignore(ignore)
1677
+ unsafe_ignore = []
1678
+ ignore = ignore.gsub(/%[\da-fA-F]{2}/) do |hex|
1679
+ unsafe_ignore << hex[1..2]
1680
+ ''
1681
+ end
1682
+ unsafe_patterns = unsafe_ignore.map! do |unsafe|
1683
+ chars = unsafe.split(//).map! do |char|
1684
+ if char =~ /[A-Z]/
1685
+ char <<= char.tr('A-Z', 'a-z')
1686
+ end
1687
+ char
1688
+ end
1689
+
1690
+ "|(?:%[^#{chars[0]}].|%[#{chars[0]}][^#{chars[1]}])"
1691
+ end
1692
+ if unsafe_patterns.length > 0
1693
+ "((?:[^#{ignore}/?#%]#{unsafe_patterns.join()})+)"
1694
+ else
1695
+ "([^#{ignore}/?#]+)"
1696
+ end
1697
+ end
1698
+
1699
+ def setup_default_middleware(builder)
1700
+ builder.use ExtendedRack
1701
+ builder.use ShowExceptions if show_exceptions?
1702
+ builder.use Rack::MethodOverride if method_override?
1703
+ builder.use Rack::Head
1704
+ setup_logging builder
1705
+ setup_sessions builder
1706
+ setup_protection builder
1707
+ end
1708
+
1709
+ def setup_middleware(builder)
1710
+ middleware.each { |c,a,b| builder.use(c, *a, &b) }
1711
+ end
1712
+
1713
+ def setup_logging(builder)
1714
+ if logging?
1715
+ setup_common_logger(builder)
1716
+ setup_custom_logger(builder)
1717
+ elsif logging == false
1718
+ setup_null_logger(builder)
1719
+ end
1720
+ end
1721
+
1722
+ def setup_null_logger(builder)
1723
+ builder.use Rack::NullLogger
1724
+ end
1725
+
1726
+ def setup_common_logger(builder)
1727
+ builder.use Sinatra::CommonLogger
1728
+ end
1729
+
1730
+ def setup_custom_logger(builder)
1731
+ if logging.respond_to? :to_int
1732
+ builder.use Rack::Logger, logging
1733
+ else
1734
+ builder.use Rack::Logger
1735
+ end
1736
+ end
1737
+
1738
+ def setup_protection(builder)
1739
+ return unless protection?
1740
+ options = Hash === protection ? protection.dup : {}
1741
+ protect_session = options.fetch(:session) { sessions? }
1742
+ options[:except] = Array options[:except]
1743
+ options[:except] += [:session_hijacking, :remote_token] unless protect_session
1744
+ options[:reaction] ||= :drop_session
1745
+ builder.use Rack::Protection, options
1746
+ end
1747
+
1748
+ def setup_sessions(builder)
1749
+ return unless sessions?
1750
+ options = {}
1751
+ options[:secret] = session_secret if session_secret?
1752
+ options.merge! sessions.to_hash if sessions.respond_to? :to_hash
1753
+ builder.use Rack::Session::Cookie, options
1754
+ end
1755
+
1756
+ def detect_rack_handler
1757
+ servers = Array(server)
1758
+ servers.each do |server_name|
1759
+ begin
1760
+ return Rack::Handler.get(server_name.to_s)
1761
+ rescue LoadError, NameError
1762
+ end
1763
+ end
1764
+ fail "Server handler (#{servers.join(',')}) not found."
1765
+ end
1766
+
1767
+ def inherited(subclass)
1768
+ subclass.reset!
1769
+ subclass.set :app_file, caller_files.first unless subclass.app_file?
1770
+ super
1771
+ end
1772
+
1773
+ @@mutex = Mutex.new
1774
+ def synchronize(&block)
1775
+ if lock?
1776
+ @@mutex.synchronize(&block)
1777
+ else
1778
+ yield
1779
+ end
1780
+ end
1781
+
1782
+ # used for deprecation warnings
1783
+ def warn(message)
1784
+ super message + "\n\tfrom #{cleaned_caller.first.join(':')}"
1785
+ end
1786
+
1787
+ # Like Kernel#caller but excluding certain magic entries
1788
+ def cleaned_caller(keep = 3)
1789
+ caller(1).
1790
+ map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
1791
+ reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
1792
+ end
1793
+ end
1794
+
1795
+ # Fixes encoding issues by
1796
+ # * defaulting to UTF-8
1797
+ # * casting params to Encoding.default_external
1798
+ #
1799
+ # The latter might not be necessary if Rack handles it one day.
1800
+ # Keep an eye on Rack's LH #100.
1801
+ def force_encoding(*args) settings.force_encoding(*args) end
1802
+ if defined? Encoding
1803
+ def self.force_encoding(data, encoding = default_encoding)
1804
+ return if data == settings || data.is_a?(Tempfile)
1805
+ if data.respond_to? :force_encoding
1806
+ data.force_encoding(encoding).encode!
1807
+ elsif data.respond_to? :each_value
1808
+ data.each_value { |v| force_encoding(v, encoding) }
1809
+ elsif data.respond_to? :each
1810
+ data.each { |v| force_encoding(v, encoding) }
1811
+ end
1812
+ data
1813
+ end
1814
+ else
1815
+ def self.force_encoding(data, *) data end
1816
+ end
1817
+
1818
+ reset!
1819
+
1820
+ set :environment, (ENV['RACK_ENV'] || :development).to_sym
1821
+ set :raise_errors, Proc.new { test? }
1822
+ set :dump_errors, Proc.new { !test? }
1823
+ set :show_exceptions, Proc.new { development? }
1824
+ set :sessions, false
1825
+ set :logging, false
1826
+ set :protection, true
1827
+ set :method_override, false
1828
+ set :use_code, false
1829
+ set :default_encoding, "utf-8"
1830
+ set :x_cascade, true
1831
+ set :add_charset, %w[javascript xml xhtml+xml json].map { |t| "application/#{t}" }
1832
+ settings.add_charset << /^text\//
1833
+
1834
+ # explicitly generating a session secret eagerly to play nice with preforking
1835
+ begin
1836
+ require 'securerandom'
1837
+ set :session_secret, SecureRandom.hex(64)
1838
+ rescue LoadError, NotImplementedError
1839
+ # SecureRandom raises a NotImplementedError if no random device is available
1840
+ set :session_secret, "%064x" % Kernel.rand(2**256-1)
1841
+ end
1842
+
1843
+ class << self
1844
+ alias_method :methodoverride?, :method_override?
1845
+ alias_method :methodoverride=, :method_override=
1846
+ end
1847
+
1848
+ set :run, false # start server via at-exit hook?
1849
+ set :running_server, nil
1850
+ set :handler_name, nil
1851
+ set :traps, true
1852
+ set :server, %w[HTTP webrick]
1853
+ set :bind, Proc.new { development? ? 'localhost' : '0.0.0.0' }
1854
+ set :port, Integer(ENV['PORT'] && !ENV['PORT'].empty? ? ENV['PORT'] : 4567)
1855
+
1856
+ ruby_engine = defined?(RUBY_ENGINE) && RUBY_ENGINE
1857
+
1858
+ if ruby_engine == 'macruby'
1859
+ server.unshift 'control_tower'
1860
+ else
1861
+ server.unshift 'reel'
1862
+ server.unshift 'mongrel' if ruby_engine.nil?
1863
+ server.unshift 'puma' if ruby_engine != 'rbx'
1864
+ server.unshift 'thin' if ruby_engine != 'jruby'
1865
+ server.unshift 'puma' if ruby_engine == 'rbx'
1866
+ server.unshift 'trinidad' if ruby_engine == 'jruby'
1867
+ end
1868
+
1869
+ set :absolute_redirects, true
1870
+ set :prefixed_redirects, false
1871
+ set :empty_path_info, nil
1872
+
1873
+ set :app_file, nil
1874
+ set :root, Proc.new { app_file && File.expand_path(File.dirname(app_file)) }
1875
+ set :views, Proc.new { root && File.join(root, 'views') }
1876
+ set :reload_templates, Proc.new { development? }
1877
+ set :lock, false
1878
+ set :threaded, true
1879
+
1880
+ set :public_folder, Proc.new { root && File.join(root, 'public') }
1881
+ set :static, Proc.new { public_folder && File.exist?(public_folder) }
1882
+ set :static_cache_control, false
1883
+
1884
+ error ::Exception do
1885
+ response.status = 500
1886
+ content_type 'text/html'
1887
+ '<h1>Internal Server Error</h1>'
1888
+ end
1889
+
1890
+ configure :development do
1891
+ get '/__sinatra__/:image.png' do
1892
+ filename = File.dirname(__FILE__) + "/images/#{params[:image]}.png"
1893
+ content_type :png
1894
+ send_file filename
1895
+ end
1896
+
1897
+ error NotFound do
1898
+ content_type 'text/html'
1899
+
1900
+ if self.class == Sinatra::Application
1901
+ code = <<-RUBY.gsub(/^ {12}/, '')
1902
+ #{request.request_method.downcase} '#{request.path_info}' do
1903
+ "Hello World"
1904
+ end
1905
+ RUBY
1906
+ else
1907
+ code = <<-RUBY.gsub(/^ {12}/, '')
1908
+ class #{self.class}
1909
+ #{request.request_method.downcase} '#{request.path_info}' do
1910
+ "Hello World"
1911
+ end
1912
+ end
1913
+ RUBY
1914
+
1915
+ file = settings.app_file.to_s.sub(settings.root.to_s, '').sub(/^\//, '')
1916
+ code = "# in #{file}\n#{code}" unless file.empty?
1917
+ end
1918
+
1919
+ (<<-HTML).gsub(/^ {10}/, '')
1920
+ <!DOCTYPE html>
1921
+ <html>
1922
+ <head>
1923
+ <style type="text/css">
1924
+ body { text-align:center;font-family:helvetica,arial;font-size:22px;
1925
+ color:#888;margin:20px}
1926
+ #c {margin:0 auto;width:500px;text-align:left}
1927
+ </style>
1928
+ </head>
1929
+ <body>
1930
+ <h2>Sinatra doesn&rsquo;t know this ditty.</h2>
1931
+ <img src='#{uri "/__sinatra__/404.png"}'>
1932
+ <div id="c">
1933
+ Try this:
1934
+ <pre>#{code}</pre>
1935
+ </div>
1936
+ </body>
1937
+ </html>
1938
+ HTML
1939
+ end
1940
+ end
1941
+ end
1942
+
1943
+ # Execution context for classic style (top-level) applications. All
1944
+ # DSL methods executed on main are delegated to this class.
1945
+ #
1946
+ # The Application class should not be subclassed, unless you want to
1947
+ # inherit all settings, routes, handlers, and error pages from the
1948
+ # top-level. Subclassing Sinatra::Base is highly recommended for
1949
+ # modular applications.
1950
+ class Application < Base
1951
+ set :logging, Proc.new { ! test? }
1952
+ set :method_override, true
1953
+ set :run, Proc.new { ! test? }
1954
+ set :session_secret, Proc.new { super() unless development? }
1955
+ set :app_file, nil
1956
+
1957
+ def self.register(*extensions, &block) #:nodoc:
1958
+ added_methods = extensions.map {|m| m.public_instance_methods }.flatten
1959
+ Delegator.delegate(*added_methods)
1960
+ super(*extensions, &block)
1961
+ end
1962
+ end
1963
+
1964
+ # Sinatra delegation mixin. Mixing this module into an object causes all
1965
+ # methods to be delegated to the Sinatra::Application class. Used primarily
1966
+ # at the top-level.
1967
+ module Delegator #:nodoc:
1968
+ def self.delegate(*methods)
1969
+ methods.each do |method_name|
1970
+ define_method(method_name) do |*args, &block|
1971
+ return super(*args, &block) if respond_to? method_name
1972
+ Delegator.target.send(method_name, *args, &block)
1973
+ end
1974
+ private method_name
1975
+ end
1976
+ end
1977
+
1978
+ delegate :get, :patch, :put, :post, :delete, :head, :options, :link, :unlink,
1979
+ :template, :layout, :before, :after, :error, :not_found, :configure,
1980
+ :set, :mime_type, :enable, :disable, :use, :development?, :test?,
1981
+ :production?, :helpers, :settings, :register
1982
+
1983
+ class << self
1984
+ attr_accessor :target
1985
+ end
1986
+
1987
+ self.target = Application
1988
+ end
1989
+
1990
+ class Wrapper
1991
+ def initialize(stack, instance)
1992
+ @stack, @instance = stack, instance
1993
+ end
1994
+
1995
+ def settings
1996
+ @instance.settings
1997
+ end
1998
+
1999
+ def helpers
2000
+ @instance
2001
+ end
2002
+
2003
+ def call(env)
2004
+ @stack.call(env)
2005
+ end
2006
+
2007
+ def inspect
2008
+ "#<#{@instance.class} app_file=#{settings.app_file.inspect}>"
2009
+ end
2010
+ end
2011
+
2012
+ # Create a new Sinatra application. The block is evaluated in the new app's
2013
+ # class scope.
2014
+ def self.new(base = Base, &block)
2015
+ base = Class.new(base)
2016
+ base.class_eval(&block) if block_given?
2017
+ base
2018
+ end
2019
+
2020
+ # Extend the top-level DSL with the modules provided.
2021
+ def self.register(*extensions, &block)
2022
+ Delegator.target.register(*extensions, &block)
2023
+ end
2024
+
2025
+ # Include the helper modules provided in Sinatra's request context.
2026
+ def self.helpers(*extensions, &block)
2027
+ Delegator.target.helpers(*extensions, &block)
2028
+ end
2029
+
2030
+ # Use the middleware for classic applications.
2031
+ def self.use(*args, &block)
2032
+ Delegator.target.use(*args, &block)
2033
+ end
2034
+ end