scout_realtime 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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