passenger 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data/Rakefile +1 -1
- data/bin/passenger-memory-stats +42 -20
- data/doc/Security of user switching support.html +54 -16
- data/doc/Users guide.html +54 -16
- data/ext/apache2/Configuration.h +1 -1
- data/lib/passenger/spawn_manager.rb +1 -7
- data/lib/passenger/wsgi/request_handler.py +47 -15
- data/test/ApplicationPoolTest.cpp +12 -4
- data/test/stub/railsapp/app/controllers/foo_controller.rb +0 -0
- data/test/stub/vendor_rails/minimal/railties/lib/initializer.rb +1 -0
- data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
- metadata +3 -2
data/Rakefile
CHANGED
data/bin/passenger-memory-stats
CHANGED
@@ -53,7 +53,7 @@ class Table
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
format_string = max_column_widths.map{ |i| "
|
56
|
+
format_string = max_column_widths.map{ |i| "%#{-i}s" }.join(" ")
|
57
57
|
header = sprintf(format_string, *@column_names).rstrip << "\n"
|
58
58
|
if title
|
59
59
|
free_space = header.size - title.size - 2
|
@@ -83,12 +83,17 @@ class MemoryStats
|
|
83
83
|
attr_accessor :ppid
|
84
84
|
attr_accessor :threads
|
85
85
|
attr_accessor :vm_size # in KB
|
86
|
+
attr_accessor :rss # in KB
|
86
87
|
attr_accessor :name
|
87
88
|
attr_accessor :private_dirty_rss # in KB
|
88
89
|
|
89
90
|
def vm_size_in_mb
|
90
91
|
return sprintf("%.1f MB", vm_size / 1024.0)
|
91
92
|
end
|
93
|
+
|
94
|
+
def rss_in_mb
|
95
|
+
return sprintf("%.1f MB", rss / 1024.0)
|
96
|
+
end
|
92
97
|
|
93
98
|
def private_dirty_rss_in_mb
|
94
99
|
if private_dirty_rss.is_a?(Numeric)
|
@@ -99,7 +104,7 @@ class MemoryStats
|
|
99
104
|
end
|
100
105
|
|
101
106
|
def to_a
|
102
|
-
return [pid, ppid, threads, vm_size_in_mb, private_dirty_rss_in_mb, name]
|
107
|
+
return [pid, ppid, threads, vm_size_in_mb, private_dirty_rss_in_mb, rss_in_mb, name]
|
103
108
|
end
|
104
109
|
end
|
105
110
|
|
@@ -146,19 +151,25 @@ class MemoryStats
|
|
146
151
|
end
|
147
152
|
|
148
153
|
processes = []
|
149
|
-
list = `#{ps} -o pid,ppid,nlwp,vsz,command`.split("\n")
|
154
|
+
list = `#{ps} -w -o pid,ppid,nlwp,vsz,rss,command`.split("\n")
|
150
155
|
list.shift
|
151
156
|
list.each do |line|
|
152
157
|
line.gsub!(/^ */, '')
|
153
158
|
line.gsub!(/ *$/, '')
|
154
159
|
|
155
160
|
p = Process.new
|
156
|
-
p.pid, p.ppid, p.threads, p.vm_size, p.name = line.split(/ +/,
|
161
|
+
p.pid, p.ppid, p.threads, p.vm_size, p.rss, p.name = line.split(/ +/, 6)
|
162
|
+
p.name.sub!(/\Aruby: /, '')
|
163
|
+
p.name.sub!(/ \(ruby\)\Z/, '')
|
157
164
|
if p.name !~ /^ps/ && (!options[:match] || p.name.match(options[:match]))
|
158
|
-
|
165
|
+
# Convert some values to integer.
|
166
|
+
[:pid, :ppid, :threads, :vm_size, :rss].each do |attr|
|
159
167
|
p.send("#{attr}=", p.send(attr).to_i)
|
160
168
|
end
|
161
|
-
|
169
|
+
|
170
|
+
if platform_provides_private_dirty_rss_information?
|
171
|
+
p.private_dirty_rss = determine_private_dirty_rss(p.pid)
|
172
|
+
end
|
162
173
|
processes << p
|
163
174
|
end
|
164
175
|
end
|
@@ -166,6 +177,10 @@ class MemoryStats
|
|
166
177
|
end
|
167
178
|
|
168
179
|
private
|
180
|
+
def platform_provides_private_dirty_rss_information?
|
181
|
+
return RUBY_PLATFORM =~ /linux/
|
182
|
+
end
|
183
|
+
|
169
184
|
# Returns the private dirty RSS for the given process, in KB.
|
170
185
|
def determine_private_dirty_rss(pid)
|
171
186
|
total = 0
|
@@ -185,29 +200,36 @@ private
|
|
185
200
|
end
|
186
201
|
|
187
202
|
def print_process_list(title, processes, options = {})
|
188
|
-
table = Table.new(%w{PID PPID Threads VMSize Private Name})
|
203
|
+
table = Table.new(%w{PID PPID Threads VMSize Private Resident Name})
|
189
204
|
table.add_rows(processes)
|
190
205
|
if options.has_key?(:show_ppid) && !options[:show_ppid]
|
191
206
|
table.remove_column('PPID')
|
192
207
|
end
|
208
|
+
if platform_provides_private_dirty_rss_information?
|
209
|
+
table.remove_column('Resident')
|
210
|
+
else
|
211
|
+
table.remove_column('Private')
|
212
|
+
end
|
193
213
|
puts table.to_s(title)
|
194
214
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
215
|
+
if platform_provides_private_dirty_rss_information?
|
216
|
+
total_private_dirty_rss = 0
|
217
|
+
some_private_dirty_rss_cannot_be_determined = false
|
218
|
+
processes.each do |p|
|
219
|
+
if p.private_dirty_rss.is_a?(Numeric)
|
220
|
+
total_private_dirty_rss += p.private_dirty_rss
|
221
|
+
else
|
222
|
+
some_private_dirty_rss_cannot_be_determined = true
|
223
|
+
end
|
224
|
+
end
|
225
|
+
puts "### Processes: #{processes.size}"
|
226
|
+
printf "### Total private dirty RSS: %.2f MB", total_private_dirty_rss / 1024.0
|
227
|
+
if some_private_dirty_rss_cannot_be_determined
|
228
|
+
puts " (?)"
|
200
229
|
else
|
201
|
-
|
230
|
+
puts
|
202
231
|
end
|
203
232
|
end
|
204
|
-
puts "### Processes: #{processes.size}"
|
205
|
-
printf "### Total private dirty RSS: %.2f MB", total_private_dirty_rss / 1024.0
|
206
|
-
if some_private_dirty_rss_cannot_be_determined
|
207
|
-
puts " (?)"
|
208
|
-
else
|
209
|
-
puts
|
210
|
-
end
|
211
233
|
end
|
212
234
|
end
|
213
235
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
4
4
|
<head>
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
-
<meta name="generator" content="AsciiDoc 8.2.
|
6
|
+
<meta name="generator" content="AsciiDoc 8.2.7" />
|
7
7
|
<style type="text/css">
|
8
8
|
/* Debug borders */
|
9
9
|
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
@@ -26,10 +26,12 @@ a:visited {
|
|
26
26
|
|
27
27
|
em {
|
28
28
|
font-style: italic;
|
29
|
+
color: navy;
|
29
30
|
}
|
30
31
|
|
31
32
|
strong {
|
32
33
|
font-weight: bold;
|
34
|
+
color: #083194;
|
33
35
|
}
|
34
36
|
|
35
37
|
tt {
|
@@ -71,6 +73,10 @@ p {
|
|
71
73
|
margin-bottom: 0.5em;
|
72
74
|
}
|
73
75
|
|
76
|
+
ul, ol, li > p {
|
77
|
+
margin-top: 0;
|
78
|
+
}
|
79
|
+
|
74
80
|
pre {
|
75
81
|
padding: 0;
|
76
82
|
margin: 0;
|
@@ -123,6 +129,7 @@ div.content { /* Block element content. */
|
|
123
129
|
|
124
130
|
/* Block element titles. */
|
125
131
|
div.title, caption.title {
|
132
|
+
color: #527bbd;
|
126
133
|
font-family: sans-serif;
|
127
134
|
font-weight: bold;
|
128
135
|
text-align: left;
|
@@ -158,13 +165,25 @@ div.listingblock > div.content {
|
|
158
165
|
padding: 0.5em;
|
159
166
|
}
|
160
167
|
|
161
|
-
div.quoteblock
|
168
|
+
div.quoteblock {
|
162
169
|
padding-left: 2.0em;
|
163
170
|
}
|
164
|
-
|
165
|
-
|
171
|
+
div.quoteblock > div.attribution {
|
172
|
+
padding-top: 0.5em;
|
166
173
|
text-align: right;
|
167
174
|
}
|
175
|
+
|
176
|
+
div.verseblock {
|
177
|
+
padding-left: 2.0em;
|
178
|
+
}
|
179
|
+
div.verseblock > div.content {
|
180
|
+
white-space: pre;
|
181
|
+
}
|
182
|
+
div.verseblock > div.attribution {
|
183
|
+
padding-top: 0.75em;
|
184
|
+
text-align: left;
|
185
|
+
}
|
186
|
+
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
|
168
187
|
div.verseblock + div.attribution {
|
169
188
|
text-align: left;
|
170
189
|
}
|
@@ -187,10 +206,6 @@ div.exampleblock > div.content {
|
|
187
206
|
padding: 0.5em;
|
188
207
|
}
|
189
208
|
|
190
|
-
div.verseblock div.content {
|
191
|
-
white-space: pre;
|
192
|
-
}
|
193
|
-
|
194
209
|
div.imageblock div.content { padding-left: 0; }
|
195
210
|
div.imageblock img { border: 1px solid silver; }
|
196
211
|
span.image img { border-style: none; }
|
@@ -202,16 +217,19 @@ dl {
|
|
202
217
|
dt {
|
203
218
|
margin-top: 0.5em;
|
204
219
|
margin-bottom: 0;
|
205
|
-
font-style:
|
220
|
+
font-style: normal;
|
206
221
|
}
|
207
222
|
dd > *:first-child {
|
208
|
-
margin-top: 0;
|
223
|
+
margin-top: 0.1em;
|
209
224
|
}
|
210
225
|
|
211
226
|
ul, ol {
|
212
227
|
list-style-position: outside;
|
213
228
|
}
|
214
|
-
div.
|
229
|
+
div.olist > ol {
|
230
|
+
list-style-type: decimal;
|
231
|
+
}
|
232
|
+
div.olist2 > ol {
|
215
233
|
list-style-type: lower-alpha;
|
216
234
|
}
|
217
235
|
|
@@ -231,11 +249,11 @@ div.hlist {
|
|
231
249
|
margin-bottom: 0.8em;
|
232
250
|
}
|
233
251
|
div.hlist td {
|
234
|
-
padding-bottom:
|
252
|
+
padding-bottom: 15px;
|
235
253
|
}
|
236
254
|
td.hlist1 {
|
237
255
|
vertical-align: top;
|
238
|
-
font-style:
|
256
|
+
font-style: normal;
|
239
257
|
padding-right: 0.8em;
|
240
258
|
}
|
241
259
|
td.hlist2 {
|
@@ -279,6 +297,7 @@ div.sidebar-content {
|
|
279
297
|
padding: 0.5em;
|
280
298
|
}
|
281
299
|
div.sidebar-title, div.image-title {
|
300
|
+
color: #527bbd;
|
282
301
|
font-family: sans-serif;
|
283
302
|
font-weight: bold;
|
284
303
|
margin-top: 0.0em;
|
@@ -291,8 +310,17 @@ div.listingblock div.content {
|
|
291
310
|
padding: 0.5em;
|
292
311
|
}
|
293
312
|
|
294
|
-
div.quoteblock-
|
295
|
-
padding-
|
313
|
+
div.quoteblock-attribution {
|
314
|
+
padding-top: 0.5em;
|
315
|
+
text-align: right;
|
316
|
+
}
|
317
|
+
|
318
|
+
div.verseblock-content {
|
319
|
+
white-space: pre;
|
320
|
+
}
|
321
|
+
div.verseblock-attribution {
|
322
|
+
padding-top: 0.75em;
|
323
|
+
text-align: left;
|
296
324
|
}
|
297
325
|
|
298
326
|
div.exampleblock-content {
|
@@ -302,6 +330,14 @@ div.exampleblock-content {
|
|
302
330
|
|
303
331
|
/* IE6 sets dynamically generated links as visited. */
|
304
332
|
div#toc a:visited { color: blue; }
|
333
|
+
|
334
|
+
/* Because IE6 child selector is broken. */
|
335
|
+
div.olist2 ol {
|
336
|
+
list-style-type: lower-alpha;
|
337
|
+
}
|
338
|
+
div.olist2 div.olist ol {
|
339
|
+
list-style-type: decimal;
|
340
|
+
}
|
305
341
|
</style>
|
306
342
|
<script type="text/javascript">
|
307
343
|
/*<![CDATA[*/
|
@@ -372,6 +408,8 @@ function generateToc(toclevels) {
|
|
372
408
|
div.className = "toclevel" + entry.toclevel;
|
373
409
|
toc.appendChild(div);
|
374
410
|
}
|
411
|
+
if (entries.length == 0)
|
412
|
+
document.getElementById("header").removeChild(toc);
|
375
413
|
}
|
376
414
|
/*]]>*/
|
377
415
|
</script>
|
@@ -598,7 +636,7 @@ feel free to discuss it with us.</p></div>
|
|
598
636
|
</div>
|
599
637
|
<div id="footer">
|
600
638
|
<div id="footer-text">
|
601
|
-
Last updated 2008-
|
639
|
+
Last updated 2008-08-09 14:31:10 CEST
|
602
640
|
</div>
|
603
641
|
</div>
|
604
642
|
</body>
|
data/doc/Users guide.html
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
4
4
|
<head>
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
-
<meta name="generator" content="AsciiDoc 8.2.
|
6
|
+
<meta name="generator" content="AsciiDoc 8.2.7" />
|
7
7
|
<style type="text/css">
|
8
8
|
/* Debug borders */
|
9
9
|
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
@@ -26,10 +26,12 @@ a:visited {
|
|
26
26
|
|
27
27
|
em {
|
28
28
|
font-style: italic;
|
29
|
+
color: navy;
|
29
30
|
}
|
30
31
|
|
31
32
|
strong {
|
32
33
|
font-weight: bold;
|
34
|
+
color: #083194;
|
33
35
|
}
|
34
36
|
|
35
37
|
tt {
|
@@ -71,6 +73,10 @@ p {
|
|
71
73
|
margin-bottom: 0.5em;
|
72
74
|
}
|
73
75
|
|
76
|
+
ul, ol, li > p {
|
77
|
+
margin-top: 0;
|
78
|
+
}
|
79
|
+
|
74
80
|
pre {
|
75
81
|
padding: 0;
|
76
82
|
margin: 0;
|
@@ -123,6 +129,7 @@ div.content { /* Block element content. */
|
|
123
129
|
|
124
130
|
/* Block element titles. */
|
125
131
|
div.title, caption.title {
|
132
|
+
color: #527bbd;
|
126
133
|
font-family: sans-serif;
|
127
134
|
font-weight: bold;
|
128
135
|
text-align: left;
|
@@ -158,13 +165,25 @@ div.listingblock > div.content {
|
|
158
165
|
padding: 0.5em;
|
159
166
|
}
|
160
167
|
|
161
|
-
div.quoteblock
|
168
|
+
div.quoteblock {
|
162
169
|
padding-left: 2.0em;
|
163
170
|
}
|
164
|
-
|
165
|
-
|
171
|
+
div.quoteblock > div.attribution {
|
172
|
+
padding-top: 0.5em;
|
166
173
|
text-align: right;
|
167
174
|
}
|
175
|
+
|
176
|
+
div.verseblock {
|
177
|
+
padding-left: 2.0em;
|
178
|
+
}
|
179
|
+
div.verseblock > div.content {
|
180
|
+
white-space: pre;
|
181
|
+
}
|
182
|
+
div.verseblock > div.attribution {
|
183
|
+
padding-top: 0.75em;
|
184
|
+
text-align: left;
|
185
|
+
}
|
186
|
+
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
|
168
187
|
div.verseblock + div.attribution {
|
169
188
|
text-align: left;
|
170
189
|
}
|
@@ -187,10 +206,6 @@ div.exampleblock > div.content {
|
|
187
206
|
padding: 0.5em;
|
188
207
|
}
|
189
208
|
|
190
|
-
div.verseblock div.content {
|
191
|
-
white-space: pre;
|
192
|
-
}
|
193
|
-
|
194
209
|
div.imageblock div.content { padding-left: 0; }
|
195
210
|
div.imageblock img { border: 1px solid silver; }
|
196
211
|
span.image img { border-style: none; }
|
@@ -202,16 +217,19 @@ dl {
|
|
202
217
|
dt {
|
203
218
|
margin-top: 0.5em;
|
204
219
|
margin-bottom: 0;
|
205
|
-
font-style:
|
220
|
+
font-style: normal;
|
206
221
|
}
|
207
222
|
dd > *:first-child {
|
208
|
-
margin-top: 0;
|
223
|
+
margin-top: 0.1em;
|
209
224
|
}
|
210
225
|
|
211
226
|
ul, ol {
|
212
227
|
list-style-position: outside;
|
213
228
|
}
|
214
|
-
div.
|
229
|
+
div.olist > ol {
|
230
|
+
list-style-type: decimal;
|
231
|
+
}
|
232
|
+
div.olist2 > ol {
|
215
233
|
list-style-type: lower-alpha;
|
216
234
|
}
|
217
235
|
|
@@ -231,11 +249,11 @@ div.hlist {
|
|
231
249
|
margin-bottom: 0.8em;
|
232
250
|
}
|
233
251
|
div.hlist td {
|
234
|
-
padding-bottom:
|
252
|
+
padding-bottom: 15px;
|
235
253
|
}
|
236
254
|
td.hlist1 {
|
237
255
|
vertical-align: top;
|
238
|
-
font-style:
|
256
|
+
font-style: normal;
|
239
257
|
padding-right: 0.8em;
|
240
258
|
}
|
241
259
|
td.hlist2 {
|
@@ -279,6 +297,7 @@ div.sidebar-content {
|
|
279
297
|
padding: 0.5em;
|
280
298
|
}
|
281
299
|
div.sidebar-title, div.image-title {
|
300
|
+
color: #527bbd;
|
282
301
|
font-family: sans-serif;
|
283
302
|
font-weight: bold;
|
284
303
|
margin-top: 0.0em;
|
@@ -291,8 +310,17 @@ div.listingblock div.content {
|
|
291
310
|
padding: 0.5em;
|
292
311
|
}
|
293
312
|
|
294
|
-
div.quoteblock-
|
295
|
-
padding-
|
313
|
+
div.quoteblock-attribution {
|
314
|
+
padding-top: 0.5em;
|
315
|
+
text-align: right;
|
316
|
+
}
|
317
|
+
|
318
|
+
div.verseblock-content {
|
319
|
+
white-space: pre;
|
320
|
+
}
|
321
|
+
div.verseblock-attribution {
|
322
|
+
padding-top: 0.75em;
|
323
|
+
text-align: left;
|
296
324
|
}
|
297
325
|
|
298
326
|
div.exampleblock-content {
|
@@ -302,6 +330,14 @@ div.exampleblock-content {
|
|
302
330
|
|
303
331
|
/* IE6 sets dynamically generated links as visited. */
|
304
332
|
div#toc a:visited { color: blue; }
|
333
|
+
|
334
|
+
/* Because IE6 child selector is broken. */
|
335
|
+
div.olist2 ol {
|
336
|
+
list-style-type: lower-alpha;
|
337
|
+
}
|
338
|
+
div.olist2 div.olist ol {
|
339
|
+
list-style-type: decimal;
|
340
|
+
}
|
305
341
|
</style>
|
306
342
|
<script type="text/javascript">
|
307
343
|
/*<![CDATA[*/
|
@@ -372,6 +408,8 @@ function generateToc(toclevels) {
|
|
372
408
|
div.className = "toclevel" + entry.toclevel;
|
373
409
|
toc.appendChild(div);
|
374
410
|
}
|
411
|
+
if (entries.length == 0)
|
412
|
+
document.getElementById("header").removeChild(toc);
|
375
413
|
}
|
376
414
|
/*]]>*/
|
377
415
|
</script>
|
@@ -2059,7 +2097,7 @@ Attribution-Share Alike 3.0 Unported License</a>.</p></div>
|
|
2059
2097
|
</div>
|
2060
2098
|
<div id="footer">
|
2061
2099
|
<div id="footer-text">
|
2062
|
-
Last updated 2008-
|
2100
|
+
Last updated 2008-08-09 14:31:11 CEST
|
2063
2101
|
</div>
|
2064
2102
|
</div>
|
2065
2103
|
</body>
|
data/ext/apache2/Configuration.h
CHANGED
@@ -187,13 +187,7 @@ private
|
|
187
187
|
if spawn_method == "smart"
|
188
188
|
spawner_must_be_started = true
|
189
189
|
framework_version = Application.detect_framework_version(app_root)
|
190
|
-
if framework_version == :vendor
|
191
|
-
vendor_path = normalize_path("#{app_root}/vendor/rails")
|
192
|
-
key = "vendor:#{vendor_path}"
|
193
|
-
create_spawner = proc do
|
194
|
-
Railz::FrameworkSpawner.new(:vendor => vendor_path)
|
195
|
-
end
|
196
|
-
elsif framework_version.nil?
|
190
|
+
if framework_version.nil? || framework_version == :vendor
|
197
191
|
app_root = normalize_path(app_root)
|
198
192
|
key = "app:#{app_root}"
|
199
193
|
create_spawner = proc do
|
@@ -2,6 +2,8 @@
|
|
2
2
|
import socket, os, random, sys, struct, select, imp
|
3
3
|
import exceptions, traceback
|
4
4
|
|
5
|
+
from socket import _fileobject
|
6
|
+
|
5
7
|
class RequestHandler:
|
6
8
|
def __init__(self, socket_file, server, owner_pipe, app):
|
7
9
|
self.socket_file = socket_file
|
@@ -25,13 +27,17 @@ class RequestHandler:
|
|
25
27
|
done = True
|
26
28
|
break
|
27
29
|
try:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
try:
|
31
|
+
env, input_stream = self.parse_request(client)
|
32
|
+
if env:
|
33
|
+
self.process_request(env, input_stream, client)
|
34
|
+
else:
|
35
|
+
done = True
|
36
|
+
except KeyboardInterrupt:
|
37
|
+
done = True
|
38
|
+
except Exception, e:
|
39
|
+
traceback.print_tb(sys.exc_info()[2])
|
40
|
+
sys.stderr.write(str(e.__class__) + ": " + e.message + "\n")
|
35
41
|
finally:
|
36
42
|
try:
|
37
43
|
client.close()
|
@@ -51,12 +57,16 @@ class RequestHandler:
|
|
51
57
|
buf = ''
|
52
58
|
while len(buf) < 4:
|
53
59
|
tmp = client.recv(4 - len(buf))
|
60
|
+
if len(tmp) == 0:
|
61
|
+
return (None, None)
|
54
62
|
buf += tmp
|
55
63
|
header_size = struct.unpack('>I', buf)[0]
|
56
64
|
|
57
65
|
buf = ''
|
58
66
|
while len(buf) < header_size:
|
59
67
|
tmp = client.recv(header_size - len(buf))
|
68
|
+
if len(tmp) == 0:
|
69
|
+
return (None, None)
|
60
70
|
buf += tmp
|
61
71
|
|
62
72
|
headers = buf.split("\0")
|
@@ -70,16 +80,30 @@ class RequestHandler:
|
|
70
80
|
return (env, client)
|
71
81
|
|
72
82
|
def process_request(self, env, input_stream, output_stream):
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
83
|
+
# The WSGI speculation says that the input paramter object passed needs to
|
84
|
+
# implement a few file-like methods. This is the reason why we "wrap" the socket._socket
|
85
|
+
# into the _fileobject to solve this.
|
86
|
+
#
|
87
|
+
# Otherwise, the POST data won't be correctly retrieved by Django.
|
88
|
+
#
|
89
|
+
# See: http://www.python.org/dev/peps/pep-0333/#input-and-error-streams
|
90
|
+
env['wsgi.input'] = _fileobject(input_stream,'r',512)
|
91
|
+
env['wsgi.errors'] = sys.stderr
|
92
|
+
env['wsgi.version'] = (1, 0)
|
93
|
+
env['wsgi.multithread'] = False
|
77
94
|
env['wsgi.multiprocess'] = True
|
78
|
-
env['wsgi.run_once']
|
95
|
+
env['wsgi.run_once'] = True
|
79
96
|
if env.get('HTTPS','off') in ('on', '1'):
|
80
97
|
env['wsgi.url_scheme'] = 'https'
|
81
98
|
else:
|
82
99
|
env['wsgi.url_scheme'] = 'http'
|
100
|
+
|
101
|
+
|
102
|
+
# The following environment variables are required by WSCI PEP #333
|
103
|
+
# see: http://www.python.org/dev/peps/pep-0333/#environ-variables
|
104
|
+
if 'HTTP_CONTENT_LENGTH' in env:
|
105
|
+
env['CONTENT_LENGTH'] = env.get('HTTP_CONTENT_LENGTH')
|
106
|
+
|
83
107
|
|
84
108
|
headers_set = []
|
85
109
|
headers_sent = []
|
@@ -124,14 +148,22 @@ class RequestHandler:
|
|
124
148
|
if hasattr(result, 'close'):
|
125
149
|
result.close()
|
126
150
|
|
151
|
+
def import_error_handler(environ, start_response):
|
152
|
+
write = start_response('500 Import Error', [('Content-type', 'text/plain')])
|
153
|
+
write("An error occurred importing your passenger_wsgi.py")
|
154
|
+
raise KeyboardInterrupt # oh WEIRD.
|
155
|
+
|
127
156
|
if __name__ == "__main__":
|
128
157
|
socket_file = sys.argv[1]
|
129
158
|
server = socket.fromfd(int(sys.argv[2]), socket.AF_UNIX, socket.SOCK_STREAM)
|
130
159
|
owner_pipe = int(sys.argv[3])
|
131
160
|
|
132
|
-
|
133
|
-
|
134
|
-
|
161
|
+
try:
|
162
|
+
app_module = imp.load_source('passenger_wsgi', 'passenger_wsgi.py')
|
163
|
+
handler = RequestHandler(socket_file, server, owner_pipe, app_module.application)
|
164
|
+
except:
|
165
|
+
handler = RequestHandler(socket_file, server, owner_pipe, import_error_handler)
|
166
|
+
|
135
167
|
try:
|
136
168
|
handler.main_loop()
|
137
169
|
finally:
|
@@ -45,6 +45,14 @@
|
|
45
45
|
}
|
46
46
|
return result;
|
47
47
|
}
|
48
|
+
|
49
|
+
static Application::SessionPtr spawnRackApp(ApplicationPoolPtr pool, const char *appRoot) {
|
50
|
+
return pool->get(appRoot, true, "nobody", "production", "smart", "rack");
|
51
|
+
}
|
52
|
+
|
53
|
+
static Application::SessionPtr spawnWsgiApp(ApplicationPoolPtr pool, const char *appRoot) {
|
54
|
+
return pool->get(appRoot, true, "nobody", "production", "smart", "wsgi");
|
55
|
+
}
|
48
56
|
|
49
57
|
TEST_METHOD(1) {
|
50
58
|
// Calling ApplicationPool.get() once should return a valid Session.
|
@@ -162,7 +170,7 @@
|
|
162
170
|
}
|
163
171
|
|
164
172
|
void operator()() {
|
165
|
-
m_session = pool
|
173
|
+
m_session = spawnWsgiApp(pool, "stub/wsgi");
|
166
174
|
m_done = true;
|
167
175
|
}
|
168
176
|
};
|
@@ -173,8 +181,8 @@
|
|
173
181
|
// in the pool, then the pool will wait until enough sessions
|
174
182
|
// have been closed.
|
175
183
|
pool->setMax(2);
|
176
|
-
Application::SessionPtr session1(pool
|
177
|
-
Application::SessionPtr session2(pool2
|
184
|
+
Application::SessionPtr session1(spawnRackApp(pool, "stub/rack"));
|
185
|
+
Application::SessionPtr session2(spawnRackApp(pool2, "stub/rack"));
|
178
186
|
Application::SessionPtr session3;
|
179
187
|
bool done;
|
180
188
|
|
@@ -333,7 +341,7 @@
|
|
333
341
|
TEST_METHOD(16) {
|
334
342
|
// The cleaner thread should clean idle applications without crashing.
|
335
343
|
pool->setMaxIdleTime(1);
|
336
|
-
pool
|
344
|
+
spawnRackApp(pool, "stub/rack");
|
337
345
|
|
338
346
|
time_t begin = time(NULL);
|
339
347
|
while (pool->getCount() == 1u && time(NULL) - begin < 10) {
|
File without changes
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passenger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phusion - http://www.phusion.nl/
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-08-09 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -830,6 +830,7 @@ files:
|
|
830
830
|
- test/stub/railsapp2/tmp
|
831
831
|
- test/stub/railsapp2/vendor
|
832
832
|
- test/stub/wsgi/public
|
833
|
+
- test/stub/wsgi/passenger_wsgi.pyc
|
833
834
|
- test/stub/wsgi/tmp
|
834
835
|
- test/stub/wsgi/passenger_wsgi.py
|
835
836
|
- test/stub/rails_apps/mycook
|