merb 0.0.3 → 0.0.4

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 (65) hide show
  1. data/README +68 -58
  2. data/Rakefile +7 -6
  3. data/TODO +18 -0
  4. data/bin/merb +2 -2
  5. data/doc/rdoc/classes/Hash.html +148 -0
  6. data/doc/rdoc/classes/Merb/Config.html +161 -0
  7. data/doc/rdoc/classes/Merb/Controller.html +488 -0
  8. data/doc/rdoc/classes/Merb/RouteMatcher.html +354 -0
  9. data/doc/rdoc/classes/Merb/Server.html +288 -0
  10. data/doc/rdoc/classes/Merb.html +143 -0
  11. data/doc/rdoc/classes/MerbHandler.html +404 -0
  12. data/doc/rdoc/classes/MerbHash.html +457 -0
  13. data/doc/rdoc/classes/Noroutefound.html +172 -0
  14. data/doc/rdoc/classes/Object.html +149 -0
  15. data/doc/rdoc/classes/String.html +200 -0
  16. data/doc/rdoc/classes/Symbol.html +172 -0
  17. data/doc/rdoc/created.rid +1 -0
  18. data/doc/rdoc/files/LICENSE.html +129 -0
  19. data/doc/rdoc/files/README.html +330 -0
  20. data/doc/rdoc/files/TODO.html +154 -0
  21. data/doc/rdoc/files/lib/merb/merb_controller_rb.html +101 -0
  22. data/doc/rdoc/files/lib/merb/merb_daemon_rb.html +113 -0
  23. data/doc/rdoc/files/lib/merb/merb_handler_rb.html +108 -0
  24. data/doc/rdoc/files/lib/merb/merb_router_rb.html +101 -0
  25. data/doc/rdoc/files/lib/merb/merb_utils_rb.html +101 -0
  26. data/doc/rdoc/files/lib/merb/noroutefound_rb.html +101 -0
  27. data/doc/rdoc/files/lib/merb_config_rb.html +101 -0
  28. data/doc/rdoc/files/lib/merb_rb.html +112 -0
  29. data/doc/rdoc/fr_class_index.html +38 -0
  30. data/doc/rdoc/fr_file_index.html +38 -0
  31. data/doc/rdoc/fr_method_index.html +78 -0
  32. data/doc/rdoc/index.html +24 -0
  33. data/doc/rdoc/rdoc-style.css +208 -0
  34. data/examples/sample_app/{app → dist/app}/controllers/posts.rb +8 -8
  35. data/examples/sample_app/{app → dist/app}/controllers/test.rb +8 -5
  36. data/examples/sample_app/{app → dist/app}/controllers/upload.rb +13 -5
  37. data/examples/sample_app/dist/app/models/post.rb +13 -0
  38. data/examples/sample_app/dist/app/views/layout/application.rhtml +6 -0
  39. data/examples/sample_app/dist/app/views/layout/foo.rhtml +6 -0
  40. data/examples/sample_app/dist/app/views/layout/posts.rhtml +6 -0
  41. data/examples/sample_app/{app → dist/app}/views/posts/list.rhtml +1 -7
  42. data/examples/sample_app/{app → dist/app}/views/posts/new.rhtml +1 -7
  43. data/examples/sample_app/{app → dist/app}/views/posts/show.rhtml +1 -8
  44. data/examples/sample_app/dist/app/views/test/foo.rhtml +2 -0
  45. data/examples/sample_app/{app → dist/app}/views/test/hello.rhtml +1 -8
  46. data/examples/sample_app/{app → dist/app}/views/upload/start.rhtml +0 -8
  47. data/examples/sample_app/{app → dist/app}/views/upload/upload.rhtml +0 -0
  48. data/examples/sample_app/{conf → dist/conf}/merb_init.rb +5 -2
  49. data/examples/sample_app/{conf → dist/conf}/router.rb +6 -8
  50. data/examples/sample_app/test/test_helper.rb +1 -0
  51. data/examples/skeleton/dist/conf/merb_init.rb +21 -0
  52. data/examples/skeleton/dist/conf/router.rb +23 -0
  53. data/examples/skeleton/test/test_helper.rb +1 -0
  54. data/lib/merb/merb_controller.rb +54 -15
  55. data/lib/merb/merb_daemon.rb +35 -20
  56. data/lib/merb/merb_handler.rb +49 -38
  57. data/lib/merb/merb_router.rb +25 -28
  58. data/lib/merb/merb_utils.rb +98 -9
  59. data/{examples/sample_app/app/controllers → lib/merb}/noroutefound.rb +1 -1
  60. data/lib/merb.rb +4 -4
  61. data/lib/merb_config.rb +1 -1
  62. data/test/unit/route_matcher_test.rb +12 -31
  63. metadata +109 -28
  64. data/examples/sample_app/app/models/post.rb +0 -2
  65. data/examples/sample_app/app/views/test/foo.rhtml +0 -6
@@ -0,0 +1,404 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Class: MerbHandler</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <table class="header-table">
51
+ <tr class="top-aligned-row">
52
+ <td><strong>Class</strong></td>
53
+ <td class="class-name-in-header">MerbHandler</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../files/lib/merb/merb_handler_rb.html">
59
+ lib/merb/merb_handler.rb
60
+ </a>
61
+ <br />
62
+ </td>
63
+ </tr>
64
+
65
+ <tr class="top-aligned-row">
66
+ <td><strong>Parent:</strong></td>
67
+ <td>
68
+ Mongrel::HttpHandler
69
+ </td>
70
+ </tr>
71
+ </table>
72
+ </div>
73
+ <!-- banner header -->
74
+
75
+ <div id="bodyContent">
76
+
77
+
78
+
79
+ <div id="contextContent">
80
+
81
+
82
+
83
+ </div>
84
+
85
+ <div id="method-list">
86
+ <h3 class="section-bar">Methods</h3>
87
+
88
+ <div class="name-list">
89
+ <a href="#M000007">exception</a>&nbsp;&nbsp;
90
+ <a href="#M000005">handle</a>&nbsp;&nbsp;
91
+ <a href="#M000006">instantiate_controller</a>&nbsp;&nbsp;
92
+ <a href="#M000003">new</a>&nbsp;&nbsp;
93
+ <a href="#M000004">process</a>&nbsp;&nbsp;
94
+ </div>
95
+ </div>
96
+
97
+ </div>
98
+
99
+
100
+ <!-- if includes -->
101
+
102
+ <div id="section">
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+ <!-- if method_list -->
112
+ <div id="methods">
113
+ <h3 class="section-bar">Public Class methods</h3>
114
+
115
+ <div id="method-M000003" class="method-detail">
116
+ <a name="M000003"></a>
117
+
118
+ <div class="method-heading">
119
+ <a href="#M000003" class="method-signature">
120
+ <span class="method-name">new</span><span class="method-args">(dir, opts = {})</span>
121
+ </a>
122
+ </div>
123
+
124
+ <div class="method-description">
125
+ <p>
126
+ take the name of a directory and use that as the doc root or public
127
+ directory of your site. This is set to the root of your merb app +
128
+ &#8217;/public&#8217; by default. See merb_daemon.rb if you want to change
129
+ this.
130
+ </p>
131
+ <p><a class="source-toggle" href="#"
132
+ onclick="toggleCode('M000003-source');return false;">[Source]</a></p>
133
+ <div class="method-source-code" id="M000003-source">
134
+ <pre>
135
+ <span class="ruby-comment cmt"># File lib/merb/merb_handler.rb, line 8</span>
136
+ 8: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">dir</span>, <span class="ruby-identifier">opts</span> = {})
137
+ 9: <span class="ruby-ivar">@files</span> = <span class="ruby-constant">Mongrel</span><span class="ruby-operator">::</span><span class="ruby-constant">DirHandler</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">dir</span>,<span class="ruby-keyword kw">false</span>)
138
+ 10: <span class="ruby-ivar">@guard</span> = <span class="ruby-constant">Sync</span>.<span class="ruby-identifier">new</span>
139
+ 11: <span class="ruby-keyword kw">end</span>
140
+ </pre>
141
+ </div>
142
+ </div>
143
+ </div>
144
+
145
+ <h3 class="section-bar">Public Instance methods</h3>
146
+
147
+ <div id="method-M000007" class="method-detail">
148
+ <a name="M000007"></a>
149
+
150
+ <div class="method-heading">
151
+ <a href="#M000007" class="method-signature">
152
+ <span class="method-name">exception</span><span class="method-args">(e)</span>
153
+ </a>
154
+ </div>
155
+
156
+ <div class="method-description">
157
+ <p>
158
+ format <a href="MerbHandler.html#M000007">exception</a> message for browser
159
+ display
160
+ </p>
161
+ <p><a class="source-toggle" href="#"
162
+ onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
163
+ <div class="method-source-code" id="M000007-source">
164
+ <pre>
165
+ <span class="ruby-comment cmt"># File lib/merb/merb_handler.rb, line 143</span>
166
+ 143: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">exception</span>(<span class="ruby-identifier">e</span>)
167
+ 144: <span class="ruby-node">&quot;&lt;html&gt;&lt;h2&gt;Merb Error!&lt;/h2&gt;&lt;p&gt;#{ e.message } - (#{ e.class })\n&quot;</span> <span class="ruby-operator">&lt;&lt;</span>
168
+ 145: <span class="ruby-node">&quot;#{(e.backtrace or []).join('&lt;br /&gt;')}&lt;/p&gt;&lt;/html&gt;&quot;</span>
169
+ 146: <span class="ruby-keyword kw">end</span>
170
+ </pre>
171
+ </div>
172
+ </div>
173
+ </div>
174
+
175
+ <div id="method-M000005" class="method-detail">
176
+ <a name="M000005"></a>
177
+
178
+ <div class="method-heading">
179
+ <a href="#M000005" class="method-signature">
180
+ <span class="method-name">handle</span><span class="method-args">(request)</span>
181
+ </a>
182
+ </div>
183
+
184
+ <div class="method-description">
185
+ <p>
186
+ This is where we grab the incoming request PATH_INFO and use that in the
187
+ merb routematcher to determine which controller and method to run. returns
188
+ a 2 element tuple of: [controller_object, method]
189
+ </p>
190
+ <p><a class="source-toggle" href="#"
191
+ onclick="toggleCode('M000005-source');return false;">[Source]</a></p>
192
+ <div class="method-source-code" id="M000005-source">
193
+ <pre>
194
+ <span class="ruby-comment cmt"># File lib/merb/merb_handler.rb, line 111</span>
195
+ 111: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">handle</span>(<span class="ruby-identifier">request</span>)
196
+ 112: <span class="ruby-identifier">path</span> = <span class="ruby-identifier">request</span>.<span class="ruby-identifier">params</span>[<span class="ruby-constant">Mongrel</span><span class="ruby-operator">::</span><span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">PATH_INFO</span>].<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/\/+/</span>, <span class="ruby-value str">'/'</span>)
197
+ 113: <span class="ruby-identifier">path</span> = <span class="ruby-identifier">path</span>[<span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">-2</span>] <span class="ruby-keyword kw">if</span> (<span class="ruby-identifier">path</span>[<span class="ruby-value">-1</span>] <span class="ruby-operator">==</span> <span class="ruby-value">?/</span>)
198
+ 114: <span class="ruby-identifier">route</span> = <span class="ruby-constant">Merb</span><span class="ruby-operator">::</span><span class="ruby-constant">RouteMatcher</span>.<span class="ruby-identifier">new</span>.<span class="ruby-identifier">route_request</span>(<span class="ruby-identifier">path</span>)
199
+ 115: <span class="ruby-identifier">puts</span> <span class="ruby-identifier">route</span>.<span class="ruby-identifier">inspect</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">$DEBUG</span>
200
+ 116: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">route</span>
201
+ 117: [ <span class="ruby-identifier">instantiate_controller</span>(<span class="ruby-identifier">route</span>[<span class="ruby-identifier">:controller</span>], <span class="ruby-identifier">request</span>.<span class="ruby-identifier">body</span>, <span class="ruby-identifier">request</span>.<span class="ruby-identifier">params</span>,
202
+ 118: <span class="ruby-identifier">route</span>.<span class="ruby-identifier">dup</span>.<span class="ruby-identifier">delete_if</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>,<span class="ruby-identifier">v</span><span class="ruby-operator">|</span> [<span class="ruby-identifier">:controller</span>, <span class="ruby-identifier">:action</span>].<span class="ruby-identifier">include?</span> <span class="ruby-identifier">k</span>}),
203
+ 119: <span class="ruby-identifier">route</span>[<span class="ruby-identifier">:action</span>]]
204
+ 120: <span class="ruby-keyword kw">else</span>
205
+ 121: [<span class="ruby-value str">&quot;&lt;html&gt;&lt;body&gt;Error: no route matches!&lt;/body&gt;&lt;/html&gt;&quot;</span>, <span class="ruby-keyword kw">nil</span>]
206
+ 122: <span class="ruby-keyword kw">end</span>
207
+ 123: <span class="ruby-keyword kw">end</span>
208
+ </pre>
209
+ </div>
210
+ </div>
211
+ </div>
212
+
213
+ <div id="method-M000006" class="method-detail">
214
+ <a name="M000006"></a>
215
+
216
+ <div class="method-heading">
217
+ <a href="#M000006" class="method-signature">
218
+ <span class="method-name">instantiate_controller</span><span class="method-args">(controller_name, req, env, params)</span>
219
+ </a>
220
+ </div>
221
+
222
+ <div class="method-description">
223
+ <p>
224
+ take a controller class name string and reload or require the right
225
+ controller file then upcase the first letter and trun it into a <a
226
+ href="MerbHandler.html#M000003">new</a> object passing in the request and
227
+ response. this is where your <a
228
+ href="Merb/Controller.html">Merb::Controller</a> is instantiated.
229
+ </p>
230
+ <p><a class="source-toggle" href="#"
231
+ onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
232
+ <div class="method-source-code" id="M000006-source">
233
+ <pre>
234
+ <span class="ruby-comment cmt"># File lib/merb/merb_handler.rb, line 129</span>
235
+ 129: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">instantiate_controller</span>(<span class="ruby-identifier">controller_name</span>, <span class="ruby-identifier">req</span>, <span class="ruby-identifier">env</span>, <span class="ruby-identifier">params</span>)
236
+ 130: <span class="ruby-keyword kw">if</span> <span class="ruby-operator">!</span><span class="ruby-constant">File</span>.<span class="ruby-identifier">exist?</span>(<span class="ruby-constant">Merb</span><span class="ruby-operator">::</span><span class="ruby-constant">Server</span>.<span class="ruby-identifier">config</span>[<span class="ruby-identifier">:dist_root</span>]<span class="ruby-operator">+</span><span class="ruby-node">&quot;/app/controllers/#{controller_name.snake_case}.rb&quot;</span>)
237
+ 131: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">Object</span>.<span class="ruby-identifier">const_get</span>(<span class="ruby-identifier">:Noroutefound</span>).<span class="ruby-identifier">new</span>(<span class="ruby-identifier">req</span>, <span class="ruby-identifier">env</span>, <span class="ruby-identifier">params</span>)
238
+ 132: <span class="ruby-keyword kw">end</span>
239
+ 133: <span class="ruby-keyword kw">begin</span>
240
+ 134: <span class="ruby-identifier">controller_name</span>.<span class="ruby-identifier">import</span>
241
+ 135: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">Object</span>.<span class="ruby-identifier">const_get</span>( <span class="ruby-identifier">controller_name</span>.<span class="ruby-identifier">camel_case</span> ).<span class="ruby-identifier">new</span>(<span class="ruby-identifier">req</span>, <span class="ruby-identifier">env</span>, <span class="ruby-identifier">params</span>)
242
+ 136: <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">Exception</span>
243
+ 137: <span class="ruby-identifier">warn</span> <span class="ruby-node">&quot;Error getting instance of '#{controller_name.camel_case}': #{$!}&quot;</span>
244
+ 138: <span class="ruby-identifier">raise</span> <span class="ruby-identifier">$!</span>
245
+ 139: <span class="ruby-keyword kw">end</span>
246
+ 140: <span class="ruby-keyword kw">end</span>
247
+ </pre>
248
+ </div>
249
+ </div>
250
+ </div>
251
+
252
+ <div id="method-M000004" class="method-detail">
253
+ <a name="M000004"></a>
254
+
255
+ <div class="method-heading">
256
+ <a href="#M000004" class="method-signature">
257
+ <span class="method-name">process</span><span class="method-args">(request, response)</span>
258
+ </a>
259
+ </div>
260
+
261
+ <div class="method-description">
262
+ <p>
263
+ <a href="MerbHandler.html#M000004">process</a> incoming http requests and
264
+ do a number of things
265
+ </p>
266
+ <ol>
267
+ <li>check for rails style cached pages. add .html to the
268
+
269
+ </li>
270
+ </ol>
271
+ <p>
272
+ url and see if there is a static file in public that matches. serve that
273
+ file directly without invoking <a href="Merb.html">Merb</a> and be done
274
+ with it.
275
+ </p>
276
+ <ol>
277
+ <li>Serve static asset and html files directly from public/ if
278
+
279
+ </li>
280
+ </ol>
281
+ <p>
282
+ they exist and fall back to <a href="Merb.html">Merb</a> otherwise
283
+ </p>
284
+ <ol>
285
+ <li>If none of the above apply, we take apart the request url
286
+
287
+ </li>
288
+ </ol>
289
+ <p>
290
+ and feed it into <a href="Merb/RouteMatcher.html">Merb::RouteMatcher</a> to
291
+ let it decide which controller and method will serve the request.
292
+ </p>
293
+ <ol>
294
+ <li>after the controller has done its thing, we check for the
295
+
296
+ </li>
297
+ </ol>
298
+ <p>
299
+ X-SENDFILE header. if you set this header to the path to a file in your
300
+ controller then mongrel will serve the file directly and your controller
301
+ can go on processing other requests.
302
+ </p>
303
+ <p><a class="source-toggle" href="#"
304
+ onclick="toggleCode('M000004-source');return false;">[Source]</a></p>
305
+ <div class="method-source-code" id="M000004-source">
306
+ <pre>
307
+ <span class="ruby-comment cmt"># File lib/merb/merb_handler.rb, line 26</span>
308
+ 26: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">process</span>(<span class="ruby-identifier">request</span>, <span class="ruby-identifier">response</span>)
309
+ 27:
310
+ 28: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">response</span>.<span class="ruby-identifier">socket</span>.<span class="ruby-identifier">closed?</span>
311
+ 29: <span class="ruby-keyword kw">return</span>
312
+ 30: <span class="ruby-keyword kw">end</span>
313
+ 31:
314
+ 32: <span class="ruby-comment cmt"># Rails style page caching. Check the public dir first for</span>
315
+ 33: <span class="ruby-comment cmt"># .html pages and serve directly. Otherwise fall back to Merb </span>
316
+ 34: <span class="ruby-comment cmt"># routing and request dispatching. </span>
317
+ 35: <span class="ruby-identifier">path_info</span> = <span class="ruby-identifier">request</span>.<span class="ruby-identifier">params</span>[<span class="ruby-constant">Mongrel</span><span class="ruby-operator">::</span><span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">PATH_INFO</span>]
318
+ 36: <span class="ruby-identifier">page_cached</span> = <span class="ruby-identifier">path_info</span> <span class="ruby-operator">+</span> <span class="ruby-value str">&quot;.html&quot;</span>
319
+ 37: <span class="ruby-identifier">get_or_head</span> = <span class="ruby-ivar">@@file_only_methods</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">request</span>.<span class="ruby-identifier">params</span>[<span class="ruby-constant">Mongrel</span><span class="ruby-operator">::</span><span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">REQUEST_METHOD</span>]
320
+ 38:
321
+ 39: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">get_or_head</span> <span class="ruby-keyword kw">and</span> <span class="ruby-ivar">@files</span>.<span class="ruby-identifier">can_serve</span>(<span class="ruby-identifier">path_info</span>)
322
+ 40: <span class="ruby-comment cmt"># File exists as-is so serve it up</span>
323
+ 41: <span class="ruby-ivar">@files</span>.<span class="ruby-identifier">process</span>(<span class="ruby-identifier">request</span>,<span class="ruby-identifier">response</span>)
324
+ 42: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">get_or_head</span> <span class="ruby-keyword kw">and</span> <span class="ruby-ivar">@files</span>.<span class="ruby-identifier">can_serve</span>(<span class="ruby-identifier">page_cached</span>)
325
+ 43: <span class="ruby-comment cmt"># Possible cached page, serve it up</span>
326
+ 44: <span class="ruby-identifier">request</span>.<span class="ruby-identifier">params</span>[<span class="ruby-constant">Mongrel</span><span class="ruby-operator">::</span><span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">PATH_INFO</span>] = <span class="ruby-identifier">page_cached</span>
327
+ 45: <span class="ruby-ivar">@files</span>.<span class="ruby-identifier">process</span>(<span class="ruby-identifier">request</span>,<span class="ruby-identifier">response</span>)
328
+ 46: <span class="ruby-keyword kw">else</span>
329
+ 47: <span class="ruby-keyword kw">begin</span>
330
+ 48: <span class="ruby-comment cmt"># This handles parsing the query string and post/file upload</span>
331
+ 49: <span class="ruby-comment cmt"># params and is outside of the synchronize call so that</span>
332
+ 50: <span class="ruby-comment cmt"># multiple file uploads can be done at once.</span>
333
+ 51: <span class="ruby-identifier">controller</span>, <span class="ruby-identifier">action</span> = <span class="ruby-identifier">handle</span>(<span class="ruby-identifier">request</span>)
334
+ 52: <span class="ruby-identifier">p</span> <span class="ruby-identifier">controller</span>, <span class="ruby-identifier">action</span>
335
+ 53: <span class="ruby-identifier">output</span> = <span class="ruby-keyword kw">nil</span>
336
+ 54: <span class="ruby-comment cmt"># synchronize here because this is where ActiveRecord or your db</span>
337
+ 55: <span class="ruby-comment cmt"># calls will be run in your controller methods.</span>
338
+ 56: <span class="ruby-ivar">@guard</span>.<span class="ruby-identifier">synchronize</span>(<span class="ruby-identifier">:EX</span>) {
339
+ 57: <span class="ruby-identifier">output</span> = <span class="ruby-keyword kw">if</span> (<span class="ruby-identifier">controller</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Merb</span><span class="ruby-operator">::</span><span class="ruby-constant">Controller</span>))
340
+ 58: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">action</span>
341
+ 59: <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">send</span>(<span class="ruby-identifier">action</span>)
342
+ 60: <span class="ruby-keyword kw">else</span>
343
+ 61: <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">to_s</span>
344
+ 62: <span class="ruby-keyword kw">end</span>
345
+ 63: <span class="ruby-keyword kw">else</span>
346
+ 64: <span class="ruby-keyword kw">nil</span>
347
+ 65: <span class="ruby-keyword kw">end</span>
348
+ 66: }
349
+ 67: <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">Exception</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">e</span>
350
+ 68: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">start</span>(<span class="ruby-value">500</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">head</span>,<span class="ruby-identifier">out</span><span class="ruby-operator">|</span>
351
+ 69: <span class="ruby-identifier">head</span>[<span class="ruby-value str">&quot;Content-Type&quot;</span>] = <span class="ruby-value str">&quot;text/html&quot;</span>
352
+ 70: <span class="ruby-identifier">out</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">exception</span>(<span class="ruby-identifier">e</span>)
353
+ 71: <span class="ruby-keyword kw">end</span>
354
+ 72: <span class="ruby-keyword kw">return</span>
355
+ 73: <span class="ruby-keyword kw">end</span>
356
+ 74:
357
+ 75: <span class="ruby-identifier">sendfile</span>, <span class="ruby-identifier">clength</span> = <span class="ruby-keyword kw">nil</span>
358
+ 76: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">status</span> = <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">status</span>
359
+ 77:
360
+ 78: <span class="ruby-comment cmt"># check for the X-SENDFILE header from your Merb::Controller</span>
361
+ 79: <span class="ruby-comment cmt"># and serve the file directly instead of buffering.</span>
362
+ 80: <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">headers</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">k</span>, <span class="ruby-identifier">v</span><span class="ruby-operator">|</span>
363
+ 81: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">k</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^X-SENDFILE$/i</span>
364
+ 82: <span class="ruby-identifier">sendfile</span> = <span class="ruby-identifier">v</span>
365
+ 83: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">k</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^CONTENT-LENGTH$/i</span>
366
+ 84: <span class="ruby-identifier">clength</span> = <span class="ruby-identifier">v</span>.<span class="ruby-identifier">to_i</span>
367
+ 85: <span class="ruby-keyword kw">else</span>
368
+ 86: [<span class="ruby-operator">*</span><span class="ruby-identifier">v</span>].<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">vi</span><span class="ruby-operator">|</span>
369
+ 87: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">header</span>[<span class="ruby-identifier">k</span>] = <span class="ruby-identifier">vi</span>
370
+ 88: <span class="ruby-keyword kw">end</span>
371
+ 89: <span class="ruby-keyword kw">end</span>
372
+ 90: <span class="ruby-keyword kw">end</span>
373
+ 91:
374
+ 92: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">sendfile</span>
375
+ 93: <span class="ruby-comment cmt"># send X-SENDFILE header to mongrel</span>
376
+ 94: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">send_status</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">size</span>(<span class="ruby-identifier">sendfile</span>))
377
+ 95: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">send_header</span>
378
+ 96: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">send_file</span>(<span class="ruby-identifier">sendfile</span>)
379
+ 97: <span class="ruby-keyword kw">else</span>
380
+ 98: <span class="ruby-comment cmt"># render response from successful controller</span>
381
+ 99: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">send_status</span>(<span class="ruby-identifier">output</span>.<span class="ruby-identifier">length</span>)
382
+ 100: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">send_header</span>
383
+ 101: <span class="ruby-identifier">response</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">output</span>)
384
+ 102: <span class="ruby-keyword kw">end</span>
385
+ 103: <span class="ruby-keyword kw">end</span>
386
+ 104: <span class="ruby-keyword kw">end</span>
387
+ </pre>
388
+ </div>
389
+ </div>
390
+ </div>
391
+
392
+
393
+ </div>
394
+
395
+
396
+ </div>
397
+
398
+
399
+ <div id="validator-badges">
400
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
401
+ </div>
402
+
403
+ </body>
404
+ </html>