thin 1.8.2 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of thin might be problematic. Click here for more details.

Files changed (108) hide show
  1. data/.gitignore +9 -0
  2. data/CHANGELOG +29 -116
  3. data/Gemfile +8 -0
  4. data/README.md +44 -78
  5. data/Rakefile +28 -18
  6. data/bin/thin +4 -4
  7. data/examples/async.ru +21 -0
  8. data/examples/thin.conf.rb +39 -0
  9. data/lib/thin/async.rb +108 -0
  10. data/lib/thin/backends/prefork.rb +44 -0
  11. data/lib/thin/backends/single_process.rb +28 -0
  12. data/lib/thin/chunked_body.rb +28 -0
  13. data/lib/thin/configurator.rb +118 -0
  14. data/lib/thin/connection.rb +246 -172
  15. data/lib/thin/listener.rb +114 -0
  16. data/lib/thin/request.rb +94 -76
  17. data/lib/thin/response.rb +112 -45
  18. data/lib/thin/runner.rb +134 -197
  19. data/lib/thin/server.rb +203 -252
  20. data/lib/thin/system.rb +49 -0
  21. data/lib/thin/version.rb +12 -27
  22. data/lib/thin.rb +2 -44
  23. data/man/index.txt +3 -0
  24. data/man/thin-conf.5.ronn +121 -0
  25. data/man/thin.1.ronn +105 -0
  26. data/site/.gitignore +2 -0
  27. data/site/README.md +21 -0
  28. data/site/Rakefile +20 -0
  29. data/site/config.ru +4 -0
  30. data/site/public/images/grid.png +0 -0
  31. data/site/public/javascripts/dd_belatedpng.js +13 -0
  32. data/site/public/javascripts/modernizr-1.6.min.js +30 -0
  33. data/site/public/man/thin-conf.5.html +220 -0
  34. data/site/public/man/thin.1.html +177 -0
  35. data/site/site/assets/javascripts/main.coffee +2 -0
  36. data/site/site/assets/stylesheets/_config.scss +55 -0
  37. data/site/site/assets/stylesheets/main.scss +24 -0
  38. data/site/site/helpers.rb +17 -0
  39. data/site/site/layouts/base.erb +55 -0
  40. data/site/site/layouts/default.erb +17 -0
  41. data/site/site/pages/about.md +5 -0
  42. data/site/site/pages/index.erb +10 -0
  43. data/site/site/partials/.gitkeep +0 -0
  44. data/test/fixtures/big.txt +1 -0
  45. data/test/fixtures/small.txt +1 -0
  46. data/test/fixtures/thin.conf.rb +15 -0
  47. data/test/integration/async_test.rb +35 -0
  48. data/test/integration/big_request_test.rb +30 -0
  49. data/test/integration/config.ru +57 -0
  50. data/test/integration/daemonize_test.rb +26 -0
  51. data/test/integration/env_test.rb +44 -0
  52. data/test/integration/error_test.rb +37 -0
  53. data/test/integration/file_sending_test.rb +24 -0
  54. data/test/integration/keep_alive_test.rb +35 -0
  55. data/test/integration/robustness_test.rb +37 -0
  56. data/test/integration/single_process_test.rb +15 -0
  57. data/test/integration/socket_family_test.rb +38 -0
  58. data/test/integration/worker_test.rb +22 -0
  59. data/test/test_helper.rb +195 -0
  60. data/test/unit/configurator_test.rb +43 -0
  61. data/test/unit/connection_test.rb +94 -0
  62. data/test/unit/listener_test.rb +74 -0
  63. data/test/unit/request_test.rb +74 -0
  64. data/test/unit/response_test.rb +90 -0
  65. data/test/unit/server_test.rb +29 -0
  66. data/test/unit/system_test.rb +17 -0
  67. data/thin.gemspec +26 -0
  68. data/v2.todo +21 -0
  69. metadata +138 -93
  70. checksums.yaml +0 -7
  71. data/example/adapter.rb +0 -32
  72. data/example/async_app.ru +0 -126
  73. data/example/async_chat.ru +0 -247
  74. data/example/async_tailer.ru +0 -100
  75. data/example/config.ru +0 -22
  76. data/example/monit_sockets +0 -20
  77. data/example/monit_unixsock +0 -20
  78. data/example/myapp.rb +0 -1
  79. data/example/ramaze.ru +0 -12
  80. data/example/thin.god +0 -80
  81. data/example/thin_solaris_smf.erb +0 -36
  82. data/example/thin_solaris_smf.readme.txt +0 -150
  83. data/example/vlad.rake +0 -72
  84. data/ext/thin_parser/common.rl +0 -59
  85. data/ext/thin_parser/ext_help.h +0 -14
  86. data/ext/thin_parser/extconf.rb +0 -6
  87. data/ext/thin_parser/parser.c +0 -1447
  88. data/ext/thin_parser/parser.h +0 -49
  89. data/ext/thin_parser/parser.rl +0 -152
  90. data/ext/thin_parser/thin.c +0 -435
  91. data/lib/rack/adapter/loader.rb +0 -75
  92. data/lib/rack/adapter/rails.rb +0 -178
  93. data/lib/rack/handler/thin.rb +0 -38
  94. data/lib/thin/backends/base.rb +0 -169
  95. data/lib/thin/backends/swiftiply_client.rb +0 -66
  96. data/lib/thin/backends/tcp_server.rb +0 -34
  97. data/lib/thin/backends/unix_server.rb +0 -56
  98. data/lib/thin/command.rb +0 -53
  99. data/lib/thin/controllers/cluster.rb +0 -178
  100. data/lib/thin/controllers/controller.rb +0 -189
  101. data/lib/thin/controllers/service.rb +0 -76
  102. data/lib/thin/controllers/service.sh.erb +0 -39
  103. data/lib/thin/daemonizing.rb +0 -199
  104. data/lib/thin/headers.rb +0 -47
  105. data/lib/thin/logging.rb +0 -174
  106. data/lib/thin/stats.html.erb +0 -216
  107. data/lib/thin/stats.rb +0 -52
  108. data/lib/thin/statuses.rb +0 -48
@@ -0,0 +1,177 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
6
+ <title>thin(1) - high performance Ruby server</title>
7
+ <style type='text/css' media='all'>
8
+ /* style: man */
9
+ body#manpage {margin:0}
10
+ .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
11
+ .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
12
+ .mp h2 {margin:10px 0 0 0}
13
+ .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
14
+ .mp h3 {margin:0 0 0 4ex}
15
+ .mp dt {margin:0;clear:left}
16
+ .mp dt.flush {float:left;width:8ex}
17
+ .mp dd {margin:0 0 0 9ex}
18
+ .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
19
+ .mp pre {margin-bottom:20px}
20
+ .mp pre+h2,.mp pre+h3 {margin-top:22px}
21
+ .mp h2+pre,.mp h3+pre {margin-top:5px}
22
+ .mp img {display:block;margin:auto}
23
+ .mp h1.man-title {display:none}
24
+ .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
25
+ .mp h2 {font-size:16px;line-height:1.25}
26
+ .mp h1 {font-size:20px;line-height:2}
27
+ .mp {text-align:justify;background:#fff}
28
+ .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
29
+ .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
30
+ .mp u {text-decoration:underline}
31
+ .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
32
+ .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
33
+ .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
34
+ .mp b.man-ref {font-weight:normal;color:#434241}
35
+ .mp pre {padding:0 4ex}
36
+ .mp pre code {font-weight:normal;color:#434241}
37
+ .mp h2+pre,h3+pre {padding-left:0}
38
+ ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
39
+ ol.man-decor {width:100%}
40
+ ol.man-decor li.tl {text-align:left}
41
+ ol.man-decor li.tc {text-align:center;letter-spacing:4px}
42
+ ol.man-decor li.tr {text-align:right;float:right}
43
+ </style>
44
+ <style type='text/css' media='all'>
45
+ /* style: toc */
46
+ .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
47
+ .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
48
+ .man-navigation a:hover {color:#111;text-decoration:underline}
49
+ </style>
50
+ </head>
51
+ <!--
52
+ The following styles are deprecated and will be removed at some point:
53
+ div#man, div#man ol.man, div#man ol.head, div#man ol.man.
54
+
55
+ The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
56
+ .man-navigation should be used instead.
57
+ -->
58
+ <body id='manpage'>
59
+ <div class='mp' id='man'>
60
+
61
+ <div class='man-navigation' style='display:none'>
62
+ <a href="#NAME">NAME</a>
63
+ <a href="#SYNOPSIS">SYNOPSIS</a>
64
+ <a href="#DESCRIPTION">DESCRIPTION</a>
65
+ <a href="#FILES">FILES</a>
66
+ <a href="#OPTIONS">OPTIONS</a>
67
+ <a href="#SIGNALS">SIGNALS</a>
68
+ <a href="#MODES">MODES</a>
69
+ <a href="#COPYRIGHT">COPYRIGHT</a>
70
+ <a href="#SEE-ALSO">SEE ALSO</a>
71
+ </div>
72
+
73
+ <ol class='man-decor man-head man head'>
74
+ <li class='tl'>thin(1)</li>
75
+ <li class='tc'>Thin Manual</li>
76
+ <li class='tr'>thin(1)</li>
77
+ </ol>
78
+
79
+ <h2 id="NAME">NAME</h2>
80
+ <p class="man-name">
81
+ <code>thin</code> - <span class="man-whatis">high performance Ruby server</span>
82
+ </p>
83
+
84
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
85
+
86
+ <p><code>thin</code> [options] [&lt;config.ru>]<br />
87
+ <code>thin</code> <code>-c</code> &lt;thin.conf.rb> [&lt;config.ru>]</p>
88
+
89
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
90
+
91
+ <p>Thin is a high performance Ruby server. Thin is generally used as an app server for serving <a href="http://rack.rubyforge.org/doc/SPEC.html">Rack applications</a> behind full blown HTTP servers such as <a href="http://nginx.org">nginx</a>.</p>
92
+
93
+ <h2 id="FILES">FILES</h2>
94
+
95
+ <p>The <code>thin</code> command will load the Rack application defined in a rackup config file. The default behaviour is to look for a file named <code>config.ru</code> that lives at the root of the application if the argument is omitted. This file is evaluated in the context of a <a href="http://rack.rubyforge.org/doc/Rack/Builder.html">Rack::Builder</a> class.</p>
96
+
97
+ <p>The <code>thin</code> command can also take a server configuration file with the <code>-c</code> option. See <a class="man-ref" href="thin-conf.5.html">thin-conf<span class="s">(5)</span></a> for the format of this file.</p>
98
+
99
+ <h2 id="OPTIONS">OPTIONS</h2>
100
+
101
+ <p>These options control the Ruby environment and are the same as the <code>ruby</code> and <code>rackup</code> commands.</p>
102
+
103
+ <dl>
104
+ <dt><code>-e</code>, <code>--eval</code> <var>LINE</var></dt><dd><p>Evaluate a LINE of Ruby code.</p></dd>
105
+ <dt><code>-d</code>, <code>--debug</code></dt><dd><p>Set debugging flags (set $DEBUG to true). This is also output the request and response to stdout.</p></dd>
106
+ <dt><code>-w</code>, <code>--warn</code></dt><dd><p>Turn warnings on for your script.</p></dd>
107
+ <dt><code>-I</code>, <code>--include</code> <var>PATH</var></dt><dd><p>Add a path to the $LOAD_PATH. May be used more than once.</p></dd>
108
+ <dt><code>-r</code>, <code>--require</code> <var>LIBRARY</var></dt><dd><p>Require the library, before executing your script. May be used more than once.</p></dd>
109
+ </dl>
110
+
111
+
112
+ <p>These options control the Thin server.</p>
113
+
114
+ <dl>
115
+ <dt><code>-o</code>, <code>--host</code> <var>HOST</var></dt><dd><p>Bind to HOST. Leave blank to bind to any address. Use <em>[...]</em> to specify IPv6 addresses.</p></dd>
116
+ <dt><code>-p</code>, <code>--PORT</code> <var>PORT</var></dt><dd><p>Bind to PORT.</p></dd>
117
+ <dt><code>-E</code>, <code>--env</code> <var>ENVIRONMENT</var></dt><dd><p>Use the Rack ENVIRONMENT.</p>
118
+
119
+ <p><em>deployment</em>:
120
+ will load the <em>ContentLength</em>, <em>Chunked</em> and <em>CommonLogger</em> middlewares.<br />
121
+ <em>development</em>:
122
+ will load the sames middlewares as <em>deployment</em> with the addition of <em>ShowExceptions</em> and <em>Lint</em>.</p>
123
+
124
+ <p>Any other environment will not load any middleware. This option will also set the <em>RACK_ENV</em> environment variable.</p></dd>
125
+ <dt><code>-D</code>, <code>--daemonize</code></dt><dd><p>Run daemonized in the background.</p></dd>
126
+ <dt><code>-P</code>, <code>--pid</code> <var>FILE</var></dt><dd><p>File to store the process ID in.</p></dd>
127
+ <dt><code>-l</code>, <code>--log</code> <var>FILE</var></dt><dd><p>File to redirect stdout and stderr to.</p></dd>
128
+ <dt><code>-c</code>, <code>--config</code> <var>FILE</var></dt><dd><p>Configure the Thin server by evaling this configuration file. See <a class="man-ref" href="thin-conf.5.html">thin-conf<span class="s">(5)</span></a> for the format of that file.</p></dd>
129
+ </dl>
130
+
131
+
132
+ <h2 id="SIGNALS">SIGNALS</h2>
133
+
134
+ <p>Thin master process can handle the following signals.</p>
135
+
136
+ <dl>
137
+ <dt class="flush"><code>WINCH</code></dt><dd><p>Gracefully kill all workers but keep master alive</p></dd>
138
+ <dt class="flush"><code>TTIN</code></dt><dd><p>Increase number of workers</p></dd>
139
+ <dt class="flush"><code>TTOU</code></dt><dd><p>Decrease number of workers</p></dd>
140
+ <dt class="flush"><code>QUIT</code></dt><dd><p>Kill workers and master in a graceful way</p></dd>
141
+ <dt><code>TERM</code>, <code>INT</code></dt><dd><p>Kill workers and master immediately</p></dd>
142
+ </dl>
143
+
144
+
145
+ <h2 id="MODES">MODES</h2>
146
+
147
+ <p>By default Thin is a preforking server like Nginx and Unicorn. On systems where <span class="man-ref">fork<span class="s">(2)</span></span> is not supported, Thin will fallback to running in a single process. While running in this mode, a number of features are not supported.</p>
148
+
149
+ <p>Here is the list of features that do <strong>NOT</strong> work when running in single process mode.</p>
150
+
151
+ <ul>
152
+ <li>Signals, except <code>TERM</code> and <code>INT</code>.</li>
153
+ <li>Run daemonized in the background (<code>-D</code> option).</li>
154
+ <li>Log file (<code>-l</code> option).</li>
155
+ </ul>
156
+
157
+
158
+ <p>Single process mode can also be forced by setting the number of worker processes to <em>0</em>.</p>
159
+
160
+ <h2 id="COPYRIGHT">COPYRIGHT</h2>
161
+
162
+ <p>Thin is Copyright (C) 2012 Marc-Andre Cournoyer <a href="http://macournoyer.com/" data-bare-link="true">http://macournoyer.com/</a></p>
163
+
164
+ <h2 id="SEE-ALSO">SEE ALSO</h2>
165
+
166
+ <p><a class="man-ref" href="thin-conf.5.html">thin-conf<span class="s">(5)</span></a>, <a href="http://rack.rubyforge.org/doc/SPEC.html">Rack spec</a></p>
167
+
168
+
169
+ <ol class='man-decor man-foot man foot'>
170
+ <li class='tl'>Thin 2.0.0.pre</li>
171
+ <li class='tc'>August 2012</li>
172
+ <li class='tr'>thin(1)</li>
173
+ </ol>
174
+
175
+ </div>
176
+ </body>
177
+ </html>
@@ -0,0 +1,2 @@
1
+ $ ->
2
+ # Your code ...
@@ -0,0 +1,55 @@
1
+ // See doc on http://compass-style.org/reference/compass/
2
+
3
+ // Here is where you can define your constants for your application and to configure the blueprint framework.
4
+ // Feel free to delete these if you want keep the defaults:
5
+
6
+ $blueprint-grid-columns: 24;
7
+ $blueprint-grid-width: 30px;
8
+ $blueprint-grid-margin: 10px;
9
+
10
+ // If you change your grid column dimensions
11
+ // you can make a new grid background image from the command line like this:
12
+ // compass grid-img 30+10x16
13
+
14
+ // Fonts
15
+ $blueprint-font-family: Georgia, sans-serif;
16
+ // $blueprint-fixed-font-family: "andale mono", "lucida console", monospace;
17
+ $blueprint-font-size: 16px;
18
+
19
+ // Colors
20
+ // $font-color: #333333;
21
+ // $quiet-color: lighten($font-color, 20%);
22
+ // $loud-color: darken($font-color, 13.33%);
23
+ // $header-color: darken($font-color, 6.67%);
24
+ // $alt-text-color: #666666;
25
+ // $blueprint-background-color: #eeeeee;
26
+ // $blueprint-border-color: #ddd;
27
+ //
28
+ // $link-color: #06c;
29
+ // $link-hover-color: #09f;
30
+ // $link-focus-color: $link-hover-color;
31
+ // $link-active-color: lighten(adjust-hue($link-color, 75deg), 10%);
32
+ // $link-visited-color: darken($link-color, 10%);
33
+ //
34
+ // $feedback-border-color: #dddddd;
35
+ // $success-color: #264409;
36
+ // $success-bg-color: #e6efc2;
37
+ // $success-border-color: #c6d880;
38
+ // $notice-color: #514721;
39
+ // $notice-bg-color: #fff6bf;
40
+ // $notice-border-color: #ffd324;
41
+ // $info-color: #205791;
42
+ // $info-bg-color: #d5edf8;
43
+ // $info-border-color: #92cae4;
44
+ // $error-color: #8a1f11;
45
+ // $error-bg-color: #fbe3e4;
46
+ // $error-border-color: #fbc2c4;
47
+ //
48
+ // $highlight-color: yellow;
49
+ // $added-color: white;
50
+ // $added-bg-color: #006600;
51
+ // $removed-color: white;
52
+ // $removed-bg-color: #990000;
53
+ //
54
+ // $blueprint-table-header-color: #c3d9ff;
55
+ // $blueprint-table-stripe-color: #e5ecf9;
@@ -0,0 +1,24 @@
1
+ @import "compass";
2
+ @import "blueprint/reset";
3
+ @import "config";
4
+ @import "blueprint";
5
+ @import "blueprint/scaffolding";
6
+
7
+ @include blueprint;
8
+ @include blueprint-scaffolding;
9
+
10
+ header {
11
+ font-size: 300%;
12
+ text-align: center;
13
+ }
14
+
15
+ .content {
16
+ @include container;
17
+
18
+ padding: 30px 0;
19
+ }
20
+
21
+ footer {
22
+ font-size: 70%;
23
+ text-align: center;
24
+ }
@@ -0,0 +1,17 @@
1
+ module Helpers
2
+ def google_analytics_account_id
3
+ nil
4
+ end
5
+
6
+ def site_name
7
+ "Thin - The high performance Ruby server"
8
+ end
9
+
10
+ def title
11
+ @title || page.title
12
+ end
13
+
14
+ def description
15
+ @description || title
16
+ end
17
+ end
@@ -0,0 +1,55 @@
1
+ <%# Base layout wrapped arround each layout %>
2
+ <!doctype html>
3
+ <!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
4
+ <!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
5
+ <!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]-->
6
+ <!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]-->
7
+ <!--[if IE 9 ]> <html lang="en" class="no-js ie9"> <![endif]-->
8
+ <!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]-->
9
+ <head>
10
+ <meta charset="utf-8">
11
+
12
+ <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
13
+ Remove this if you use the .htaccess -->
14
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
15
+
16
+ <title><%= title %> - <%= site_name %></title>
17
+ <meta name="description" content="<%= description %>">
18
+
19
+ <!-- Mobile viewport optimized: j.mp/bplateviewport -->
20
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
21
+
22
+ <!-- CSS for all media -->
23
+ <link href="/stylesheets/main.css" rel="stylesheet" type="text/css" />
24
+
25
+ <!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
26
+ <script src="/javascripts/modernizr-1.6.min.js"></script>
27
+ </head>
28
+
29
+ <body>
30
+ <%= yield %>
31
+
32
+ <!-- Javascript at the bottom for fast page loading -->
33
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
34
+ <script src="/javascripts/main.js"></script>
35
+
36
+ <!--[if lt IE 7 ]>
37
+ <script src="/javascripts/dd_belatedpng.js"></script>
38
+ <script> DD_belatedPNG.fix('img, .png_bg'); //fix any <img> or .png_bg background-images </script>
39
+ <![endif]-->
40
+
41
+ <% if google_analytics_account_id %>
42
+ <!-- asynchronous google analytics: mathiasbynens.be/notes/async-analytics-snippet -->
43
+ <script>
44
+ var _gaq = [['_setAccount', '<%= google_analytics_account_id %>'], ['_trackPageview']];
45
+ (function(d, t) {
46
+ var g = d.createElement(t),
47
+ s = d.getElementsByTagName(t)[0];
48
+ g.async = true;
49
+ g.src = ('https:' == location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
50
+ s.parentNode.insertBefore(g, s);
51
+ })(document, 'script');
52
+ </script>
53
+ <% end %>
54
+ </body>
55
+ </html>
@@ -0,0 +1,17 @@
1
+ <header>
2
+ <div class="content">
3
+ <%= site_name %>
4
+ </div>
5
+ </header>
6
+
7
+ <div id="content">
8
+ <div class="content">
9
+ <%= yield %>
10
+ </div>
11
+ </div>
12
+
13
+ <footer>
14
+ <div class="content">
15
+ &copy; Me
16
+ </div>
17
+ </footer>
@@ -0,0 +1,5 @@
1
+ # <%= @title = "About this site" %>
2
+
3
+ This site was and still is, awesome. Edit me in <code>pages/about.md</code>.
4
+
5
+ <%= link_to "Back", :back %>
@@ -0,0 +1,10 @@
1
+ <h2>Index</h2>
2
+
3
+ <p>Oh pretty please! Edit me in <code>pages/index.erb</code>.</p>
4
+
5
+ <h3>Pages</h3>
6
+ <ul>
7
+ <% site.pages.each do |page| %>
8
+ <li><%= link_to page.title, page %></li>
9
+ <% end %>
10
+ </ul>
File without changes
@@ -0,0 +1 @@
1
+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -0,0 +1 @@
1
+ hi
@@ -0,0 +1,15 @@
1
+ worker_processes 4
2
+
3
+ worker_connections 1024
4
+
5
+ listen 3000, :backlog => 128
6
+ listen "*:8080"
7
+ listen "0.0.0.0:8081"
8
+
9
+ before_fork do
10
+ puts "Preparing to fork a new worker ..."
11
+ end
12
+
13
+ after_fork do
14
+ puts "Worker forked!"
15
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class AsyncTest < IntegrationTestCase
4
+ def test_get
5
+ thin :env => "none"
6
+
7
+ socket do |s|
8
+ s.write("GET /async HTTP/1.1\r\n")
9
+ s.write("\r\n")
10
+ s.flush
11
+
12
+ term = "\r\n"
13
+ assert_match "HTTP/1.1 200 OK", s.readpartial(1024)
14
+ assert_equal "4#{term}one\n#{term}", s.readpartial(20)
15
+ sleep 0.1
16
+ assert_equal "4#{term}two\n#{term}" +
17
+ "0#{term}#{term}", s.readpartial(20)
18
+ end
19
+ end
20
+
21
+ def test_get_without_chunked_encoding
22
+ thin :env => "none"
23
+
24
+ socket do |s|
25
+ s.write("GET /async HTTP/1.0\r\n")
26
+ s.write("\r\n")
27
+ s.flush
28
+
29
+ assert_match "HTTP/1.0 200 OK", s.readpartial(1024)
30
+ assert_equal "one\n", s.readpartial(20)
31
+ sleep 0.1
32
+ assert_equal "two\n", s.readpartial(20)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+ require "thin/request"
3
+
4
+ class BigRequestTest < IntegrationTestCase
5
+ def setup
6
+ thin :env => "production" # to disable Lint
7
+ end
8
+
9
+ def test_big_body_is_stored_in_tempfile
10
+ post "/eval?code=request.body.class", :big => "X" * (Thin::Request::MAX_BODY + 1)
11
+
12
+ assert_status 200
13
+ assert_response_equals "Tempfile"
14
+ end
15
+
16
+ def test_big_body_is_read_from_tempfile
17
+ size = Thin::Request::MAX_BODY + 1
18
+ post "/eval?code=request.body.read", :big => "X" * size
19
+
20
+ assert_status 200
21
+ assert_equal size + "big=".size, @response.body.size
22
+ end
23
+
24
+ def test_small_body_is_not_stored_in_tempfile
25
+ post "/eval?code=request.body.class", :small => "X" * 1024
26
+
27
+ assert_status 200
28
+ assert_response_equals "StringIO"
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ require "thin/async"
2
+
3
+ class App
4
+ def call(env)
5
+ request = Rack::Request.new(env)
6
+
7
+ case request.path_info
8
+ when "/"
9
+ Rack::Response.new do |response|
10
+ response.write "ok"
11
+ end.finish
12
+
13
+ when "/env"
14
+ Rack::Response.new do |response|
15
+ env.each_pair do |key, value|
16
+ response.write "#{key}: #{value}\n"
17
+ end
18
+ response.write "\n" + request.body.read
19
+ end.finish
20
+
21
+ when "/eval"
22
+ Rack::Response.new do |response|
23
+ response.write eval(request["code"]).to_s
24
+ end.finish
25
+
26
+ when "/raise"
27
+ raise "ouch"
28
+
29
+ when "/exit"
30
+ exit!
31
+
32
+ when "/sleep"
33
+ sleep request["sec"].to_f
34
+
35
+ when "/async"
36
+ Thin::AsyncResponse.new(env) do |response|
37
+ response << "one\n"
38
+ EM.next_tick do
39
+ response << "two\n"
40
+ response.done # close the connection
41
+ end
42
+ end.finish
43
+
44
+ else
45
+ Rack::Response.new do |response|
46
+ response.status = 404
47
+ response.write "not found"
48
+ end.finish
49
+
50
+ end
51
+ end
52
+ end
53
+
54
+ use Rack::Static, :urls => ["/small.txt", "/big.txt"],
55
+ :root => File.expand_path("../../fixtures", __FILE__)
56
+
57
+ run App.new
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ class DaemonizeTest < IntegrationTestCase
4
+ def test_do_not_daemonize
5
+ pid = thin
6
+
7
+ assert_equal @pid, pid, "Launcher PID should be the same as master PID"
8
+ Process.kill 0, @pid
9
+
10
+ get "/"
11
+
12
+ assert_status 200
13
+ end
14
+
15
+ def test_daemonize
16
+ pid = thin :daemonize => true
17
+
18
+ assert_not_equal @pid, pid, "Launcher PID should not be the same as master PID"
19
+ Process.kill 0, pid
20
+ Process.kill 0, @pid
21
+
22
+ get "/"
23
+
24
+ assert_status 200
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+
3
+ class EnvTest < IntegrationTestCase
4
+ def test_get
5
+ thin
6
+
7
+ get '/env?hi=there'
8
+
9
+ assert_status 200
10
+ assert_response_includes "REMOTE_ADDR: 127.0.0.1"
11
+ assert_response_includes "SERVER_SOFTWARE: thin"
12
+ assert_response_includes "HTTP_HOST: localhost:8181"
13
+ assert_response_includes "SERVER_PORT: 8181"
14
+ assert_response_includes "SERVER_NAME: localhost"
15
+ assert_response_includes "REQUEST_METHOD: GET"
16
+ assert_response_includes "PATH_INFO: /env"
17
+ assert_response_includes "QUERY_STRING: hi=there"
18
+ assert_response_includes "rack.url_scheme: http"
19
+ assert_response_includes "rack.multithread: false"
20
+ assert_response_includes "rack.multiprocess: true"
21
+ assert_response_includes "rack.run_once: false"
22
+ end
23
+
24
+ def test_post
25
+ thin
26
+
27
+ post '/env', :hi => "there"
28
+
29
+ assert_status 200
30
+ assert_response_includes "REMOTE_ADDR: 127.0.0.1"
31
+ assert_response_includes "SERVER_SOFTWARE: thin"
32
+ assert_response_includes "HTTP_HOST: localhost:8181"
33
+ assert_response_includes "SERVER_PORT: 8181"
34
+ assert_response_includes "SERVER_NAME: localhost"
35
+ assert_response_includes "REQUEST_METHOD: POST"
36
+ assert_response_includes "PATH_INFO: /env"
37
+ assert_response_includes "QUERY_STRING: \n"
38
+ assert_response_includes "rack.url_scheme: http"
39
+ assert_response_includes "rack.multithread: false"
40
+ assert_response_includes "rack.multiprocess: true"
41
+ assert_response_includes "rack.run_once: false"
42
+ assert_response_includes "\n\nhi=there"
43
+ end
44
+ end