serverside 0.1.59

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/CHANGELOG +97 -0
  2. data/COPYING +18 -0
  3. data/README +51 -0
  4. data/Rakefile +92 -0
  5. data/bin/serverside +74 -0
  6. data/doc/rdoc/classes/Daemon.html +253 -0
  7. data/doc/rdoc/classes/Daemon/Base.html +146 -0
  8. data/doc/rdoc/classes/Daemon/Cluster.html +308 -0
  9. data/doc/rdoc/classes/Daemon/Cluster/PidFile.html +228 -0
  10. data/doc/rdoc/classes/Daemon/PidFile.html +178 -0
  11. data/doc/rdoc/classes/ServerSide.html +160 -0
  12. data/doc/rdoc/classes/ServerSide/Application.html +147 -0
  13. data/doc/rdoc/classes/ServerSide/Application/Base.html +196 -0
  14. data/doc/rdoc/classes/ServerSide/Application/Static.html +154 -0
  15. data/doc/rdoc/classes/ServerSide/Connection.html +128 -0
  16. data/doc/rdoc/classes/ServerSide/Connection/Base.html +343 -0
  17. data/doc/rdoc/classes/ServerSide/Connection/Const.html +229 -0
  18. data/doc/rdoc/classes/ServerSide/Connection/Static.html +172 -0
  19. data/doc/rdoc/classes/ServerSide/Server.html +162 -0
  20. data/doc/rdoc/classes/ServerSide/StaticFiles.html +208 -0
  21. data/doc/rdoc/classes/ServerSide/StaticFiles/Const.html +179 -0
  22. data/doc/rdoc/classes/String.html +210 -0
  23. data/doc/rdoc/classes/Symbol.html +156 -0
  24. data/doc/rdoc/created.rid +1 -0
  25. data/doc/rdoc/files/CHANGELOG.html +260 -0
  26. data/doc/rdoc/files/COPYING.html +129 -0
  27. data/doc/rdoc/files/README.html +171 -0
  28. data/doc/rdoc/files/lib/serverside/application_rb.html +109 -0
  29. data/doc/rdoc/files/lib/serverside/cluster_rb.html +101 -0
  30. data/doc/rdoc/files/lib/serverside/connection_rb.html +101 -0
  31. data/doc/rdoc/files/lib/serverside/core_ext_rb.html +107 -0
  32. data/doc/rdoc/files/lib/serverside/daemon_rb.html +108 -0
  33. data/doc/rdoc/files/lib/serverside/server_rb.html +108 -0
  34. data/doc/rdoc/files/lib/serverside/static_rb.html +101 -0
  35. data/doc/rdoc/files/lib/serverside_rb.html +131 -0
  36. data/doc/rdoc/fr_class_index.html +44 -0
  37. data/doc/rdoc/fr_file_index.html +37 -0
  38. data/doc/rdoc/fr_method_index.html +60 -0
  39. data/doc/rdoc/index.html +24 -0
  40. data/doc/rdoc/rdoc-style.css +208 -0
  41. data/lib/serverside.rb +13 -0
  42. data/lib/serverside/application.rb +40 -0
  43. data/lib/serverside/cluster.rb +72 -0
  44. data/lib/serverside/connection.rb +115 -0
  45. data/lib/serverside/core_ext.rb +27 -0
  46. data/lib/serverside/daemon.rb +67 -0
  47. data/lib/serverside/server.rb +18 -0
  48. data/lib/serverside/static.rb +96 -0
  49. data/test/functional/primitive_static_server_test.rb +37 -0
  50. data/test/functional/static_profile.rb +17 -0
  51. data/test/functional/static_rfuzz.rb +67 -0
  52. data/test/functional/static_server_test.rb +25 -0
  53. data/test/test_helper.rb +2 -0
  54. data/test/unit/application_test.rb +16 -0
  55. data/test/unit/cluster_test.rb +129 -0
  56. data/test/unit/connection_test.rb +193 -0
  57. data/test/unit/core_ext_test.rb +32 -0
  58. data/test/unit/daemon_test.rb +75 -0
  59. data/test/unit/server_test.rb +26 -0
  60. data/test/unit/static_test.rb +143 -0
  61. metadata +140 -0
@@ -0,0 +1,128 @@
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>Module: ServerSide::Connection</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>Module</strong></td>
53
+ <td class="class-name-in-header">ServerSide::Connection</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../../files/lib/serverside/connection_rb.html">
59
+ lib/serverside/connection.rb
60
+ </a>
61
+ <br />
62
+ <a href="../../files/lib/serverside/static_rb.html">
63
+ lib/serverside/static.rb
64
+ </a>
65
+ <br />
66
+ </td>
67
+ </tr>
68
+
69
+ </table>
70
+ </div>
71
+ <!-- banner header -->
72
+
73
+ <div id="bodyContent">
74
+
75
+
76
+
77
+ <div id="contextContent">
78
+
79
+ <div id="description">
80
+ <p>
81
+ The <a href="Connection.html">Connection</a> module takes care of HTTP
82
+ connection. While most HTTP servers (at least the OO ones) will define
83
+ separate classes for request and response, I chose to use the concept of a
84
+ connection both for better performance, and also because a single
85
+ connection might handle multiple requests, if using HTTP 1.1 persistent
86
+ connection.
87
+ </p>
88
+
89
+ </div>
90
+
91
+
92
+ </div>
93
+
94
+
95
+ </div>
96
+
97
+
98
+ <!-- if includes -->
99
+
100
+ <div id="section">
101
+
102
+ <div id="class-list">
103
+ <h3 class="section-bar">Classes and Modules</h3>
104
+
105
+ Module <a href="Connection/Const.html" class="link">ServerSide::Connection::Const</a><br />
106
+ Class <a href="Connection/Base.html" class="link">ServerSide::Connection::Base</a><br />
107
+ Class <a href="Connection/Static.html" class="link">ServerSide::Connection::Static</a><br />
108
+
109
+ </div>
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+ <!-- if method_list -->
118
+
119
+
120
+ </div>
121
+
122
+
123
+ <div id="validator-badges">
124
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
125
+ </div>
126
+
127
+ </body>
128
+ </html>
@@ -0,0 +1,343 @@
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: ServerSide::Connection::Base</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">ServerSide::Connection::Base</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../../../files/lib/serverside/connection_rb.html">
59
+ lib/serverside/connection.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
+ Object
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
+ <div id="description">
82
+ <p>
83
+ This is the base request class. When a new request is created, it starts a
84
+ thread in which it is parsed and processed.
85
+ </p>
86
+ <p>
87
+ <a href="Base.html">Connection::Base</a> is overriden by applications to
88
+ create application-specific behavior.
89
+ </p>
90
+
91
+ </div>
92
+
93
+
94
+ </div>
95
+
96
+ <div id="method-list">
97
+ <h3 class="section-bar">Methods</h3>
98
+
99
+ <div class="name-list">
100
+ <a href="#M000027">new</a>&nbsp;&nbsp;
101
+ <a href="#M000030">parse_parameters</a>&nbsp;&nbsp;
102
+ <a href="#M000029">parse_request</a>&nbsp;&nbsp;
103
+ <a href="#M000028">process</a>&nbsp;&nbsp;
104
+ <a href="#M000031">send_response</a>&nbsp;&nbsp;
105
+ <a href="#M000032">stream</a>&nbsp;&nbsp;
106
+ </div>
107
+ </div>
108
+
109
+ </div>
110
+
111
+
112
+ <!-- if includes -->
113
+
114
+ <div id="section">
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+ <!-- if method_list -->
124
+ <div id="methods">
125
+ <h3 class="section-bar">Public Class methods</h3>
126
+
127
+ <div id="method-M000027" class="method-detail">
128
+ <a name="M000027"></a>
129
+
130
+ <div class="method-heading">
131
+ <a href="#M000027" class="method-signature">
132
+ <span class="method-name">new</span><span class="method-args">(conn)</span>
133
+ </a>
134
+ </div>
135
+
136
+ <div class="method-description">
137
+ <p>
138
+ Initializes the request instance. A new thread is created for processing
139
+ requests.
140
+ </p>
141
+ <p><a class="source-toggle" href="#"
142
+ onclick="toggleCode('M000027-source');return false;">[Source]</a></p>
143
+ <div class="method-source-code" id="M000027-source">
144
+ <pre>
145
+ <span class="ruby-comment cmt"># File lib/serverside/connection.rb, line 40</span>
146
+ 40: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">conn</span>)
147
+ 41: <span class="ruby-ivar">@conn</span> = <span class="ruby-identifier">conn</span>
148
+ 42: <span class="ruby-ivar">@thread</span> = <span class="ruby-constant">Thread</span>.<span class="ruby-identifier">new</span> {<span class="ruby-identifier">process</span>}
149
+ 43: <span class="ruby-keyword kw">end</span>
150
+ </pre>
151
+ </div>
152
+ </div>
153
+ </div>
154
+
155
+ <h3 class="section-bar">Public Instance methods</h3>
156
+
157
+ <div id="method-M000030" class="method-detail">
158
+ <a name="M000030"></a>
159
+
160
+ <div class="method-heading">
161
+ <a href="#M000030" class="method-signature">
162
+ <span class="method-name">parse_parameters</span><span class="method-args">(query)</span>
163
+ </a>
164
+ </div>
165
+
166
+ <div class="method-description">
167
+ <p>
168
+ Parses query parameters by splitting the query string and unescaping
169
+ parameter values.
170
+ </p>
171
+ <p><a class="source-toggle" href="#"
172
+ onclick="toggleCode('M000030-source');return false;">[Source]</a></p>
173
+ <div class="method-source-code" id="M000030-source">
174
+ <pre>
175
+ <span class="ruby-comment cmt"># File lib/serverside/connection.rb, line 82</span>
176
+ 82: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parse_parameters</span>(<span class="ruby-identifier">query</span>)
177
+ 83: <span class="ruby-identifier">query</span>.<span class="ruby-identifier">split</span>(<span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">Ampersand</span>).<span class="ruby-identifier">inject</span>({}) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">m</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
178
+ 84: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">=~</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">ParameterRegexp</span>
179
+ 85: <span class="ruby-identifier">m</span>[<span class="ruby-identifier">$1</span>.<span class="ruby-identifier">to_sym</span>] = <span class="ruby-identifier">$2</span>.<span class="ruby-identifier">uri_unescape</span>
180
+ 86: <span class="ruby-keyword kw">end</span>
181
+ 87: <span class="ruby-identifier">m</span>
182
+ 88: <span class="ruby-keyword kw">end</span>
183
+ 89: <span class="ruby-keyword kw">end</span>
184
+ </pre>
185
+ </div>
186
+ </div>
187
+ </div>
188
+
189
+ <div id="method-M000029" class="method-detail">
190
+ <a name="M000029"></a>
191
+
192
+ <div class="method-heading">
193
+ <a href="#M000029" class="method-signature">
194
+ <span class="method-name">parse_request</span><span class="method-args">()</span>
195
+ </a>
196
+ </div>
197
+
198
+ <div class="method-description">
199
+ <p>
200
+ Parses an HTTP request. If the request is not valid, nil is returned.
201
+ Otherwise, the HTTP headers are returned. Also determines whether the
202
+ connection is persistent (by checking the HTTP version and the &#8216;<a
203
+ href="../Connection.html">Connection</a>&#8217; header).
204
+ </p>
205
+ <p><a class="source-toggle" href="#"
206
+ onclick="toggleCode('M000029-source');return false;">[Source]</a></p>
207
+ <div class="method-source-code" id="M000029-source">
208
+ <pre>
209
+ <span class="ruby-comment cmt"># File lib/serverside/connection.rb, line 64</span>
210
+ 64: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parse_request</span>
211
+ 65: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">nil</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@conn</span>.<span class="ruby-identifier">gets</span> <span class="ruby-operator">=~</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">RequestRegexp</span>
212
+ 66: <span class="ruby-ivar">@method</span>, <span class="ruby-ivar">@path</span>, <span class="ruby-ivar">@query</span>, <span class="ruby-ivar">@version</span> = <span class="ruby-identifier">$1</span>.<span class="ruby-identifier">downcase</span>.<span class="ruby-identifier">to_sym</span>, <span class="ruby-identifier">$2</span>, <span class="ruby-identifier">$5</span>, <span class="ruby-identifier">$6</span>
213
+ 67: <span class="ruby-ivar">@parameters</span> = <span class="ruby-ivar">@query</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">parse_parameters</span>(<span class="ruby-ivar">@query</span>) <span class="ruby-operator">:</span> {}
214
+ 68: <span class="ruby-ivar">@headers</span> = {}
215
+ 69: <span class="ruby-keyword kw">while</span> (<span class="ruby-identifier">line</span> = <span class="ruby-ivar">@conn</span>.<span class="ruby-identifier">gets</span>)
216
+ 70: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">line</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">||</span> (<span class="ruby-identifier">line</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">LineBreak</span>)
217
+ 71: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">line</span> <span class="ruby-operator">=~</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">HeaderRegexp</span>
218
+ 72: <span class="ruby-ivar">@headers</span>[<span class="ruby-identifier">$1</span>.<span class="ruby-identifier">freeze</span>] = <span class="ruby-identifier">$2</span>.<span class="ruby-identifier">freeze</span>
219
+ 73: <span class="ruby-keyword kw">end</span>
220
+ 74: <span class="ruby-keyword kw">end</span>
221
+ 75: <span class="ruby-ivar">@persistent</span> = (<span class="ruby-ivar">@version</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">Version_1_1</span>) <span class="ruby-operator">&amp;&amp;</span>
222
+ 76: (<span class="ruby-ivar">@headers</span>[<span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">Connection</span>] <span class="ruby-operator">!=</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">Close</span>)
223
+ 77: <span class="ruby-ivar">@headers</span>
224
+ 78: <span class="ruby-keyword kw">end</span>
225
+ </pre>
226
+ </div>
227
+ </div>
228
+ </div>
229
+
230
+ <div id="method-M000028" class="method-detail">
231
+ <a name="M000028"></a>
232
+
233
+ <div class="method-heading">
234
+ <a href="#M000028" class="method-signature">
235
+ <span class="method-name">process</span><span class="method-args">()</span>
236
+ </a>
237
+ </div>
238
+
239
+ <div class="method-description">
240
+ <p>
241
+ Processes incoming requests by parsing them and then responding. If any
242
+ error occurs, or the connection is not persistent, the connection is
243
+ closed.
244
+ </p>
245
+ <p><a class="source-toggle" href="#"
246
+ onclick="toggleCode('M000028-source');return false;">[Source]</a></p>
247
+ <div class="method-source-code" id="M000028-source">
248
+ <pre>
249
+ <span class="ruby-comment cmt"># File lib/serverside/connection.rb, line 48</span>
250
+ 48: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">process</span>
251
+ 49: <span class="ruby-keyword kw">while</span> <span class="ruby-keyword kw">true</span>
252
+ 50: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">parse_request</span>
253
+ 51: <span class="ruby-identifier">respond</span>
254
+ 52: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@persistent</span>
255
+ 53: <span class="ruby-keyword kw">end</span>
256
+ 54: <span class="ruby-keyword kw">rescue</span>
257
+ 55: <span class="ruby-comment cmt"># We don't care. Just close the connection.</span>
258
+ 56: <span class="ruby-keyword kw">ensure</span>
259
+ 57: <span class="ruby-ivar">@conn</span>.<span class="ruby-identifier">close</span>
260
+ 58: <span class="ruby-keyword kw">end</span>
261
+ </pre>
262
+ </div>
263
+ </div>
264
+ </div>
265
+
266
+ <div id="method-M000031" class="method-detail">
267
+ <a name="M000031"></a>
268
+
269
+ <div class="method-heading">
270
+ <a href="#M000031" class="method-signature">
271
+ <span class="method-name">send_response</span><span class="method-args">(status, content_type, body = nil, content_length = nil, headers = nil)</span>
272
+ </a>
273
+ </div>
274
+
275
+ <div class="method-description">
276
+ <p>
277
+ Sends an HTTP response.
278
+ </p>
279
+ <p><a class="source-toggle" href="#"
280
+ onclick="toggleCode('M000031-source');return false;">[Source]</a></p>
281
+ <div class="method-source-code" id="M000031-source">
282
+ <pre>
283
+ <span class="ruby-comment cmt"># File lib/serverside/connection.rb, line 92</span>
284
+ 92: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">send_response</span>(<span class="ruby-identifier">status</span>, <span class="ruby-identifier">content_type</span>, <span class="ruby-identifier">body</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">content_length</span> = <span class="ruby-keyword kw">nil</span>,
285
+ 93: <span class="ruby-identifier">headers</span> = <span class="ruby-keyword kw">nil</span>)
286
+ 94: <span class="ruby-identifier">h</span> = <span class="ruby-identifier">headers</span> <span class="ruby-value">? </span>
287
+ 95: <span class="ruby-identifier">headers</span>.<span class="ruby-identifier">inject</span>(<span class="ruby-value str">''</span>) {<span class="ruby-operator">|</span><span class="ruby-identifier">m</span>, <span class="ruby-identifier">kv</span><span class="ruby-operator">|</span> <span class="ruby-identifier">m</span> <span class="ruby-operator">&lt;&lt;</span> (<span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">Header</span> <span class="ruby-operator">%</span> <span class="ruby-identifier">kv</span>)} <span class="ruby-operator">:</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">Empty</span>
288
+ 96:
289
+ 97: <span class="ruby-identifier">content_length</span> = <span class="ruby-identifier">body</span>.<span class="ruby-identifier">length</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">content_length</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">body</span>
290
+ 98: <span class="ruby-ivar">@persistent</span> = <span class="ruby-keyword kw">false</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">content_length</span>.<span class="ruby-identifier">nil?</span>
291
+ 99:
292
+ 100: <span class="ruby-comment cmt"># Select the right format to use according to circumstances.</span>
293
+ 101: <span class="ruby-ivar">@conn</span> <span class="ruby-operator">&lt;&lt;</span> ((<span class="ruby-ivar">@persistent</span> <span class="ruby-operator">?</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">StatusPersist</span> <span class="ruby-operator">:</span>
294
+ 102: (<span class="ruby-identifier">body</span> <span class="ruby-value">? </span><span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">StatusClose</span> <span class="ruby-operator">:</span> <span class="ruby-constant">Const</span><span class="ruby-operator">::</span><span class="ruby-constant">StatusStream</span>)) <span class="ruby-operator">%</span>
295
+ 103: [<span class="ruby-identifier">status</span>, <span class="ruby-identifier">content_type</span>, <span class="ruby-identifier">h</span>, <span class="ruby-identifier">content_length</span>])
296
+ 104: <span class="ruby-ivar">@conn</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">body</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">body</span>
297
+ 105: <span class="ruby-keyword kw">rescue</span>
298
+ 106: <span class="ruby-ivar">@persistent</span> = <span class="ruby-keyword kw">false</span>
299
+ 107: <span class="ruby-keyword kw">end</span>
300
+ </pre>
301
+ </div>
302
+ </div>
303
+ </div>
304
+
305
+ <div id="method-M000032" class="method-detail">
306
+ <a name="M000032"></a>
307
+
308
+ <div class="method-heading">
309
+ <a href="#M000032" class="method-signature">
310
+ <span class="method-name">stream</span><span class="method-args">(body)</span>
311
+ </a>
312
+ </div>
313
+
314
+ <div class="method-description">
315
+ <p>
316
+ Streams additional data to the client.
317
+ </p>
318
+ <p><a class="source-toggle" href="#"
319
+ onclick="toggleCode('M000032-source');return false;">[Source]</a></p>
320
+ <div class="method-source-code" id="M000032-source">
321
+ <pre>
322
+ <span class="ruby-comment cmt"># File lib/serverside/connection.rb, line 110</span>
323
+ 110: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">stream</span>(<span class="ruby-identifier">body</span>)
324
+ 111: (<span class="ruby-ivar">@conn</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">body</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">body</span>) <span class="ruby-keyword kw">rescue</span> (<span class="ruby-ivar">@persistent</span> = <span class="ruby-keyword kw">false</span>)
325
+ 112: <span class="ruby-keyword kw">end</span>
326
+ </pre>
327
+ </div>
328
+ </div>
329
+ </div>
330
+
331
+
332
+ </div>
333
+
334
+
335
+ </div>
336
+
337
+
338
+ <div id="validator-badges">
339
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
340
+ </div>
341
+
342
+ </body>
343
+ </html>