webroar 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +48 -1
- data/README +11 -14
- data/Rakefile +1 -1
- data/conf/mime_type.yml +172 -166
- data/conf/server_internal_config.yml +30 -8
- data/doc/user-guide.html +294 -153
- data/doc/user-guide.txt +9 -13
- data/lib/command_runner.rb +1 -0
- data/lib/dependencies.rb +18 -15
- data/lib/installer.rb +115 -50
- data/src/admin_panel/app/controllers/admin_controller.rb +1 -15
- data/src/admin_panel/app/controllers/application_controller.rb +2 -2
- data/src/admin_panel/app/controllers/application_specification_controller.rb +2 -1
- data/src/admin_panel/app/controllers/headers_controller.rb +73 -0
- data/src/admin_panel/app/controllers/mail_specification_controller.rb +10 -0
- data/src/admin_panel/app/controllers/server_specification_controller.rb +14 -0
- data/src/admin_panel/app/helpers/admin_helper.rb +0 -85
- data/src/admin_panel/app/models/app.rb +1 -1
- data/src/admin_panel/app/models/application_specification.rb +33 -25
- data/src/admin_panel/app/models/headers.rb +116 -0
- data/src/admin_panel/app/models/mail_specification.rb +20 -5
- data/src/admin_panel/app/models/server_specification.rb +2 -7
- data/src/admin_panel/app/views/admin/configuration.html.erb +10 -5
- data/src/admin_panel/app/views/exceptions/_exception_list_partial.html.erb +4 -4
- data/src/admin_panel/app/views/graph/_graph_page.html.erb +3 -0
- data/src/admin_panel/app/views/headers/_add_expires_text_box.html.erb +35 -0
- data/src/admin_panel/app/views/headers/_expires_by_type_form.html.erb +65 -0
- data/src/admin_panel/app/views/headers/_headers_table.html.erb +113 -0
- data/src/admin_panel/app/views/mail_specification/_current_spec.html.erb +168 -0
- data/src/admin_panel/app/views/{admin → server_specification}/_add_div.html.erb +1 -1
- data/src/admin_panel/config/initializers/application_constants.rb +6 -0
- data/src/admin_panel/lib/control.rb +6 -3
- data/src/admin_panel/lib/scgi.rb +74 -21
- data/src/admin_panel/lib/yaml_writer.rb +51 -17
- data/src/admin_panel/public/javascripts/application.js +20 -1
- data/src/head/wr_access_log.c +2 -2
- data/src/head/wr_application.c +294 -236
- data/src/head/wr_application.h +8 -8
- data/src/head/wr_configurator.c +451 -517
- data/src/head/wr_configurator.h +10 -115
- data/src/head/wr_connection.c +26 -25
- data/src/head/wr_connection.h +2 -3
- data/src/head/wr_controller.c +110 -93
- data/src/head/wr_controller.h +6 -6
- data/src/head/wr_main.c +31 -24
- data/src/head/wr_request.c +70 -93
- data/src/head/wr_request.h +0 -4
- data/src/head/wr_resolver.c +21 -15
- data/src/head/wr_resolver.h +2 -2
- data/src/head/wr_server.c +36 -26
- data/src/head/wr_server.h +5 -5
- data/src/head/wr_worker.c +551 -512
- data/src/head/wr_worker.h +33 -20
- data/src/helper/wr_config.c +316 -0
- data/src/helper/wr_config.h +235 -0
- data/src/helper/wr_helper.h +1 -5
- data/src/helper/wr_logger.c +4 -4
- data/src/helper/wr_scgi.c +3 -4
- data/src/helper/wr_scgi.h +2 -0
- data/src/helper/wr_string.h +2 -2
- data/src/helper/wr_util.c +3 -1
- data/src/helper/wr_util.h +0 -0
- data/src/helper/wr_yaml_parser.c +30 -0
- data/src/helper/wr_yaml_parser.h +1 -0
- data/src/ruby_lib/exception_tracker/instrumentation/action_controller.rb +2 -1
- data/src/ruby_lib/mailer/smtpmail.rb +7 -4
- data/src/ruby_lib/profiler/instrumentation/action_controller.rb +2 -1
- data/src/ruby_lib/profiler/instrumentation/active_record.rb +3 -0
- data/src/ruby_lib/rack/adapter/rails.rb +14 -7
- data/src/ruby_lib/ruby_interface/client.rb +1 -1
- data/src/ruby_lib/ruby_interface/version.rb +2 -2
- data/src/ruby_lib/webroar_app_loader.rb +4 -2
- data/src/worker/wkr_controller.c +200 -140
- data/src/worker/wkr_http.c +14 -28
- data/src/worker/wkr_http.h +4 -4
- data/src/worker/wkr_http_request.c +12 -11
- data/src/worker/wkr_http_request.h +7 -8
- data/src/worker/wkr_http_response.c +10 -14
- data/src/worker/wkr_http_response.h +0 -1
- data/src/worker/wkr_main.c +74 -140
- data/src/worker/wkr_static.c +295 -108
- data/src/worker/wkr_static.h +20 -7
- data/src/worker/worker.c +245 -70
- data/src/worker/worker.h +46 -34
- data/tasks/compile.rake +128 -175
- data/tasks/test.rake +345 -469
- data/test/spec/webroar_command_spec.rb +23 -0
- metadata +173 -43
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/README +0 -34
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/Rakefile +0 -13
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/init.rb +0 -5
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/lib/action_mailer_tls.rb +0 -16
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/lib/smtp_tls.rb +0 -123
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/test/tls_test.rb +0 -42
- data/src/head/wr_config.h +0 -165
- data/src/ruby_lib/mailer/action_mailer_tls.rb +0 -16
- data/src/ruby_lib/mailer/smtp_tls.rb +0 -123
data/doc/user-guide.html
CHANGED
@@ -3,7 +3,8 @@
|
|
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.5.2" />
|
7
|
+
<title>WebROaR User Guide</title>
|
7
8
|
<style type="text/css">
|
8
9
|
/* Debug borders */
|
9
10
|
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
@@ -90,7 +91,7 @@ span#author {
|
|
90
91
|
}
|
91
92
|
span#email {
|
92
93
|
}
|
93
|
-
span#
|
94
|
+
span#revnumber, span#revdate, span#revremark {
|
94
95
|
font-family: sans-serif;
|
95
96
|
}
|
96
97
|
|
@@ -110,17 +111,21 @@ div#footer-badges {
|
|
110
111
|
padding-bottom: 0.5em;
|
111
112
|
}
|
112
113
|
|
113
|
-
div#preamble
|
114
|
+
div#preamble {
|
115
|
+
margin-top: 1.5em;
|
116
|
+
margin-bottom: 1.5em;
|
117
|
+
}
|
114
118
|
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
|
115
119
|
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
|
116
120
|
div.admonitionblock {
|
117
|
-
margin-
|
118
|
-
margin-top: 1.5em;
|
121
|
+
margin-top: 1.0em;
|
119
122
|
margin-bottom: 1.5em;
|
120
123
|
}
|
121
124
|
div.admonitionblock {
|
122
|
-
margin-top: 2.
|
123
|
-
margin-bottom: 2.
|
125
|
+
margin-top: 2.0em;
|
126
|
+
margin-bottom: 2.0em;
|
127
|
+
margin-right: 10%;
|
128
|
+
color: #606060;
|
124
129
|
}
|
125
130
|
|
126
131
|
div.content { /* Block element content. */
|
@@ -156,26 +161,25 @@ div.sidebarblock > div.content {
|
|
156
161
|
padding: 0.5em;
|
157
162
|
}
|
158
163
|
|
159
|
-
div.listingblock {
|
160
|
-
margin-right: 0%;
|
161
|
-
}
|
162
164
|
div.listingblock > div.content {
|
163
165
|
border: 1px solid silver;
|
164
166
|
background: #f4f4f4;
|
165
167
|
padding: 0.5em;
|
166
168
|
}
|
167
169
|
|
168
|
-
div.quoteblock {
|
169
|
-
padding-left:
|
170
|
+
div.quoteblock, div.verseblock {
|
171
|
+
padding-left: 1.0em;
|
172
|
+
margin-left: 1.0em;
|
173
|
+
margin-right: 10%;
|
174
|
+
border-left: 5px solid #dddddd;
|
175
|
+
color: #777777;
|
170
176
|
}
|
177
|
+
|
171
178
|
div.quoteblock > div.attribution {
|
172
179
|
padding-top: 0.5em;
|
173
180
|
text-align: right;
|
174
181
|
}
|
175
182
|
|
176
|
-
div.verseblock {
|
177
|
-
padding-left: 2.0em;
|
178
|
-
}
|
179
183
|
div.verseblock > div.content {
|
180
184
|
white-space: pre;
|
181
185
|
}
|
@@ -198,17 +202,17 @@ div.admonitionblock .icon {
|
|
198
202
|
}
|
199
203
|
div.admonitionblock td.content {
|
200
204
|
padding-left: 0.5em;
|
201
|
-
border-left:
|
205
|
+
border-left: 3px solid #dddddd;
|
202
206
|
}
|
203
207
|
|
204
208
|
div.exampleblock > div.content {
|
205
|
-
border-left:
|
206
|
-
padding: 0.5em;
|
209
|
+
border-left: 3px solid #dddddd;
|
210
|
+
padding-left: 0.5em;
|
207
211
|
}
|
208
212
|
|
209
213
|
div.imageblock div.content { padding-left: 0; }
|
210
|
-
div.imageblock img { border: 1px solid silver; }
|
211
214
|
span.image img { border-style: none; }
|
215
|
+
a.image:visited { color: white; }
|
212
216
|
|
213
217
|
dl {
|
214
218
|
margin-top: 0.8em;
|
@@ -218,6 +222,7 @@ dt {
|
|
218
222
|
margin-top: 0.5em;
|
219
223
|
margin-bottom: 0;
|
220
224
|
font-style: normal;
|
225
|
+
color: navy;
|
221
226
|
}
|
222
227
|
dd > *:first-child {
|
223
228
|
margin-top: 0.1em;
|
@@ -226,44 +231,123 @@ dd > *:first-child {
|
|
226
231
|
ul, ol {
|
227
232
|
list-style-position: outside;
|
228
233
|
}
|
229
|
-
|
234
|
+
ol.arabic {
|
230
235
|
list-style-type: decimal;
|
231
236
|
}
|
232
|
-
|
237
|
+
ol.loweralpha {
|
233
238
|
list-style-type: lower-alpha;
|
234
239
|
}
|
240
|
+
ol.upperalpha {
|
241
|
+
list-style-type: upper-alpha;
|
242
|
+
}
|
243
|
+
ol.lowerroman {
|
244
|
+
list-style-type: lower-roman;
|
245
|
+
}
|
246
|
+
ol.upperroman {
|
247
|
+
list-style-type: upper-roman;
|
248
|
+
}
|
249
|
+
|
250
|
+
div.compact ul, div.compact ol,
|
251
|
+
div.compact p, div.compact p,
|
252
|
+
div.compact div, div.compact div {
|
253
|
+
margin-top: 0.1em;
|
254
|
+
margin-bottom: 0.1em;
|
255
|
+
}
|
235
256
|
|
236
257
|
div.tableblock > table {
|
237
258
|
border: 3px solid #527bbd;
|
238
259
|
}
|
239
|
-
thead {
|
260
|
+
thead, p.table.header {
|
240
261
|
font-family: sans-serif;
|
241
262
|
font-weight: bold;
|
242
263
|
}
|
243
264
|
tfoot {
|
244
265
|
font-weight: bold;
|
245
266
|
}
|
267
|
+
td > div.verse {
|
268
|
+
white-space: pre;
|
269
|
+
}
|
270
|
+
p.table {
|
271
|
+
margin-top: 0;
|
272
|
+
}
|
273
|
+
/* Because the table frame attribute is overriden by CSS in most browsers. */
|
274
|
+
div.tableblock > table[frame="void"] {
|
275
|
+
border-style: none;
|
276
|
+
}
|
277
|
+
div.tableblock > table[frame="hsides"] {
|
278
|
+
border-left-style: none;
|
279
|
+
border-right-style: none;
|
280
|
+
}
|
281
|
+
div.tableblock > table[frame="vsides"] {
|
282
|
+
border-top-style: none;
|
283
|
+
border-bottom-style: none;
|
284
|
+
}
|
285
|
+
|
246
286
|
|
247
|
-
div.
|
287
|
+
div.hdlist {
|
248
288
|
margin-top: 0.8em;
|
249
289
|
margin-bottom: 0.8em;
|
250
290
|
}
|
251
|
-
div.
|
291
|
+
div.hdlist tr {
|
252
292
|
padding-bottom: 15px;
|
253
293
|
}
|
254
|
-
td.
|
294
|
+
dt.hdlist1.strong, td.hdlist1.strong {
|
295
|
+
font-weight: bold;
|
296
|
+
}
|
297
|
+
td.hdlist1 {
|
255
298
|
vertical-align: top;
|
256
299
|
font-style: normal;
|
257
300
|
padding-right: 0.8em;
|
301
|
+
color: navy;
|
258
302
|
}
|
259
|
-
td.
|
303
|
+
td.hdlist2 {
|
260
304
|
vertical-align: top;
|
261
305
|
}
|
306
|
+
div.hdlist.compact tr {
|
307
|
+
margin: 0;
|
308
|
+
padding-bottom: 0;
|
309
|
+
}
|
310
|
+
|
311
|
+
.comment {
|
312
|
+
background: yellow;
|
313
|
+
}
|
314
|
+
|
315
|
+
.footnote, .footnoteref {
|
316
|
+
font-size: 0.8em;
|
317
|
+
}
|
318
|
+
|
319
|
+
span.footnote, span.footnoteref {
|
320
|
+
vertical-align: super;
|
321
|
+
}
|
322
|
+
|
323
|
+
#footnotes {
|
324
|
+
margin: 20px 0 20px 0;
|
325
|
+
padding: 7px 0 0 0;
|
326
|
+
}
|
327
|
+
|
328
|
+
#footnotes div.footnote {
|
329
|
+
margin: 0 0 5px 0;
|
330
|
+
}
|
331
|
+
|
332
|
+
#footnotes hr {
|
333
|
+
border: none;
|
334
|
+
border-top: 1px solid silver;
|
335
|
+
height: 1px;
|
336
|
+
text-align: left;
|
337
|
+
margin-left: 0;
|
338
|
+
width: 20%;
|
339
|
+
min-width: 100px;
|
340
|
+
}
|
341
|
+
|
262
342
|
|
263
343
|
@media print {
|
264
344
|
div#footer-badges { display: none; }
|
265
345
|
}
|
266
346
|
|
347
|
+
div#toc {
|
348
|
+
margin-bottom: 2.5em;
|
349
|
+
}
|
350
|
+
|
267
351
|
div#toctitle {
|
268
352
|
color: #527bbd;
|
269
353
|
font-family: sans-serif;
|
@@ -324,24 +408,22 @@ div.verseblock-attribution {
|
|
324
408
|
}
|
325
409
|
|
326
410
|
div.exampleblock-content {
|
327
|
-
border-left:
|
411
|
+
border-left: 3px solid #dddddd;
|
328
412
|
padding-left: 0.5em;
|
329
413
|
}
|
330
414
|
|
331
415
|
/* IE6 sets dynamically generated links as visited. */
|
332
416
|
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
|
-
}
|
341
417
|
</style>
|
342
418
|
<script type="text/javascript">
|
343
419
|
/*<![CDATA[*/
|
344
|
-
window.onload = function(){
|
420
|
+
window.onload = function(){asciidoc.footnotes(); asciidoc.toc(3);}
|
421
|
+
var asciidoc = { // Namespace.
|
422
|
+
|
423
|
+
/////////////////////////////////////////////////////////////////////
|
424
|
+
// Table Of Contents generator
|
425
|
+
/////////////////////////////////////////////////////////////////////
|
426
|
+
|
345
427
|
/* Author: Mihai Bazon, September 2002
|
346
428
|
* http://students.infoiasi.ro/~mishoo
|
347
429
|
*
|
@@ -353,53 +435,55 @@ window.onload = function(){generateToc(3)}
|
|
353
435
|
*/
|
354
436
|
|
355
437
|
/* modified by Troy D. Hanson, September 2006. License: GPL */
|
356
|
-
/* modified by Stuart Rackham,
|
357
|
-
|
358
|
-
function getText(el) {
|
359
|
-
var text = "";
|
360
|
-
for (var i = el.firstChild; i != null; i = i.nextSibling) {
|
361
|
-
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
|
362
|
-
text += i.data;
|
363
|
-
else if (i.firstChild != null)
|
364
|
-
text += getText(i);
|
365
|
-
}
|
366
|
-
return text;
|
367
|
-
}
|
438
|
+
/* modified by Stuart Rackham, 2006, 2009. License: GPL */
|
368
439
|
|
369
|
-
|
370
|
-
|
371
|
-
this.text = text;
|
372
|
-
this.toclevel = toclevel;
|
373
|
-
}
|
440
|
+
// toclevels = 1..4.
|
441
|
+
toc: function (toclevels) {
|
374
442
|
|
375
|
-
function
|
376
|
-
|
377
|
-
var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
|
378
|
-
// Function that scans the DOM tree for header elements (the DOM2
|
379
|
-
// nodeIterator API would be a better technique but not supported by all
|
380
|
-
// browsers).
|
381
|
-
var iterate = function (el) {
|
443
|
+
function getText(el) {
|
444
|
+
var text = "";
|
382
445
|
for (var i = el.firstChild; i != null; i = i.nextSibling) {
|
383
|
-
if (i.nodeType ==
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
446
|
+
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
|
447
|
+
text += i.data;
|
448
|
+
else if (i.firstChild != null)
|
449
|
+
text += getText(i);
|
450
|
+
}
|
451
|
+
return text;
|
452
|
+
}
|
453
|
+
|
454
|
+
function TocEntry(el, text, toclevel) {
|
455
|
+
this.element = el;
|
456
|
+
this.text = text;
|
457
|
+
this.toclevel = toclevel;
|
458
|
+
}
|
459
|
+
|
460
|
+
function tocEntries(el, toclevels) {
|
461
|
+
var result = new Array;
|
462
|
+
var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
|
463
|
+
// Function that scans the DOM tree for header elements (the DOM2
|
464
|
+
// nodeIterator API would be a better technique but not supported by all
|
465
|
+
// browsers).
|
466
|
+
var iterate = function (el) {
|
467
|
+
for (var i = el.firstChild; i != null; i = i.nextSibling) {
|
468
|
+
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
|
469
|
+
var mo = re.exec(i.tagName);
|
470
|
+
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
|
471
|
+
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
|
472
|
+
}
|
473
|
+
iterate(i);
|
474
|
+
}
|
388
475
|
}
|
389
476
|
}
|
477
|
+
iterate(el);
|
478
|
+
return result;
|
390
479
|
}
|
391
|
-
iterate(el);
|
392
|
-
return result;
|
393
|
-
}
|
394
480
|
|
395
|
-
// This function does the work. toclevels = 1..4.
|
396
|
-
function generateToc(toclevels) {
|
397
481
|
var toc = document.getElementById("toc");
|
398
|
-
var entries = tocEntries(document.
|
482
|
+
var entries = tocEntries(document.getElementById("content"), toclevels);
|
399
483
|
for (var i = 0; i < entries.length; ++i) {
|
400
484
|
var entry = entries[i];
|
401
485
|
if (entry.element.id == "")
|
402
|
-
entry.element.id = "
|
486
|
+
entry.element.id = "_toc_" + i;
|
403
487
|
var a = document.createElement("a");
|
404
488
|
a.href = "#" + entry.element.id;
|
405
489
|
a.appendChild(document.createTextNode(entry.text));
|
@@ -409,11 +493,61 @@ function generateToc(toclevels) {
|
|
409
493
|
toc.appendChild(div);
|
410
494
|
}
|
411
495
|
if (entries.length == 0)
|
412
|
-
|
496
|
+
toc.parentNode.removeChild(toc);
|
497
|
+
},
|
498
|
+
|
499
|
+
|
500
|
+
/////////////////////////////////////////////////////////////////////
|
501
|
+
// Footnotes generator
|
502
|
+
/////////////////////////////////////////////////////////////////////
|
503
|
+
|
504
|
+
/* Based on footnote generation code from:
|
505
|
+
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
|
506
|
+
*/
|
507
|
+
|
508
|
+
footnotes: function () {
|
509
|
+
var cont = document.getElementById("content");
|
510
|
+
var noteholder = document.getElementById("footnotes");
|
511
|
+
var spans = cont.getElementsByTagName("span");
|
512
|
+
var refs = {};
|
513
|
+
var n = 0;
|
514
|
+
for (i=0; i<spans.length; i++) {
|
515
|
+
if (spans[i].className == "footnote") {
|
516
|
+
n++;
|
517
|
+
// Use [\s\S] in place of . so multi-line matches work.
|
518
|
+
// Because JavaScript has no s (dotall) regex flag.
|
519
|
+
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
|
520
|
+
noteholder.innerHTML +=
|
521
|
+
"<div class='footnote' id='_footnote_" + n + "'>" +
|
522
|
+
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
|
523
|
+
n + "</a>. " + note + "</div>";
|
524
|
+
spans[i].innerHTML =
|
525
|
+
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
|
526
|
+
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
527
|
+
var id =spans[i].getAttribute("id");
|
528
|
+
if (id != null) refs["#"+id] = n;
|
529
|
+
}
|
530
|
+
}
|
531
|
+
if (n == 0)
|
532
|
+
noteholder.parentNode.removeChild(noteholder);
|
533
|
+
else {
|
534
|
+
// Process footnoterefs.
|
535
|
+
for (i=0; i<spans.length; i++) {
|
536
|
+
if (spans[i].className == "footnoteref") {
|
537
|
+
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
|
538
|
+
href = href.match(/#.*/)[0]; // Because IE return full URL.
|
539
|
+
n = refs[href];
|
540
|
+
spans[i].innerHTML =
|
541
|
+
"[<a href='#_footnote_" + n +
|
542
|
+
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
543
|
+
}
|
544
|
+
}
|
545
|
+
}
|
546
|
+
}
|
547
|
+
|
413
548
|
}
|
414
549
|
/*]]>*/
|
415
550
|
</script>
|
416
|
-
<title>WebROaR User Guide</title>
|
417
551
|
</head>
|
418
552
|
<body>
|
419
553
|
<div id="header">
|
@@ -423,16 +557,17 @@ function generateToc(toclevels) {
|
|
423
557
|
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
|
424
558
|
</div>
|
425
559
|
</div>
|
560
|
+
<div id="content">
|
426
561
|
<h2 id="_introduction">1. Introduction</h2>
|
427
562
|
<div class="sectionbody">
|
428
|
-
<div class="
|
563
|
+
<div class="paragraph"><p><a href="http://webroar.in">WebROaR</a> is an application server that makes deployments of
|
429
564
|
ruby web applications extremely simple. It provides an integrated solution to
|
430
565
|
view the run time performance numbers and sends email notifications in case any
|
431
566
|
exceptions occur in any of the deployed applications.</p></div>
|
432
|
-
<div class="
|
567
|
+
<div class="paragraph"><p>It is 5 to 55% faster than all other comparable deployment stacks for
|
433
568
|
Ruby on Rails applications.</p></div>
|
434
569
|
<h3 id="_key_features">1.1. Key Features</h3><div style="clear:left"></div>
|
435
|
-
<div class="
|
570
|
+
<div class="ulist"><ul>
|
436
571
|
<li>
|
437
572
|
<p>
|
438
573
|
Maximum Performance.
|
@@ -478,6 +613,16 @@ Generates notifications in case any exceptions occur in any of the deployed
|
|
478
613
|
</li>
|
479
614
|
<li>
|
480
615
|
<p>
|
616
|
+
Zero Downtime Application Upgrades.
|
617
|
+
</p>
|
618
|
+
</li>
|
619
|
+
<li>
|
620
|
+
<p>
|
621
|
+
Static assets encoding.
|
622
|
+
</p>
|
623
|
+
</li>
|
624
|
+
<li>
|
625
|
+
<p>
|
481
626
|
SSL support.
|
482
627
|
</p>
|
483
628
|
</li>
|
@@ -485,15 +630,15 @@ SSL support.
|
|
485
630
|
</div>
|
486
631
|
<h2 id="_supported_operating_systems">2. Supported Operating Systems</h2>
|
487
632
|
<div class="sectionbody">
|
488
|
-
<div class="
|
489
|
-
(v10.5 & v10.6), Arch Linux 2009.08 and Cent OS 5.2. Basically, it
|
490
|
-
able to run on any *IX OS.</p></div>
|
491
|
-
<div class="
|
633
|
+
<div class="paragraph"><p>WebROaR has been tested on Ubuntu 8.10/9.04/9.10/10.04, Debian 5 (64 Bit),
|
634
|
+
Mac OS X (v10.5 & v10.6), Arch Linux 2009.08 and Cent OS 5.2. Basically, it
|
635
|
+
should be able to run on any *IX OS.</p></div>
|
636
|
+
<div class="paragraph"><p>Currently it does not support Microsoft® Windows.</p></div>
|
492
637
|
</div>
|
493
638
|
<h2 id="_install">3. Install</h2>
|
494
639
|
<div class="sectionbody">
|
495
640
|
<h3 id="_prerequisites">3.1. Prerequisites</h3><div style="clear:left"></div>
|
496
|
-
<div class="
|
641
|
+
<div class="ulist"><ul>
|
497
642
|
<li>
|
498
643
|
<p>
|
499
644
|
ruby 1.8.x or 1.9.x
|
@@ -545,26 +690,12 @@ gnutls-dev 2.4.1 or later (Only necessary in case SSL support is required)
|
|
545
690
|
</p>
|
546
691
|
</li>
|
547
692
|
</ul></div>
|
548
|
-
<div class="admonitionblock">
|
549
|
-
<table><tr>
|
550
|
-
<td class="icon">
|
551
|
-
<img src="./images/icons/note.png" alt="Note" />
|
552
|
-
</td>
|
553
|
-
<td class="content">
|
554
|
-
<div class="title">Ruby Shared Library</div>
|
555
|
-
<div class="para"><p>The server needs the shared library - libruby.so to run the ruby web
|
556
|
-
applications.</p></div>
|
557
|
-
<div class="para"><p>If you are building ruby from source, please ensure you pass the flag
|
558
|
-
<strong>—enable-shared</strong> while executing its ./configure script.</p></div>
|
559
|
-
</td>
|
560
|
-
</tr></table>
|
561
|
-
</div>
|
562
693
|
<h3 id="_procedure">3.2. Procedure</h3><div style="clear:left"></div>
|
563
|
-
<div class="
|
694
|
+
<div class="paragraph"><p>WebROaR can be installed through its gem or directly from its source code. One
|
564
695
|
can also use Capistrano to perform a non-interactive installation of the
|
565
696
|
server.</p></div>
|
566
697
|
<h4 id="_install_using_gem">3.2.1. Install using gem</h4>
|
567
|
-
<div class="
|
698
|
+
<div class="paragraph"><p>WebROaR can be installed using the following commands:</p></div>
|
568
699
|
<div class="listingblock">
|
569
700
|
<div class="content">
|
570
701
|
<pre><tt>sudo gem install webroar
|
@@ -577,21 +708,21 @@ sudo webroar install</tt></pre>
|
|
577
708
|
</td>
|
578
709
|
<td class="content">
|
579
710
|
<div class="title">SSL Support</div>
|
580
|
-
<div class="
|
711
|
+
<div class="paragraph"><p>In case you would like to setup SSL support for the server, use the following
|
581
712
|
command line switch with <strong>sudo webroar install</strong> command mentioned above.</p></div>
|
582
713
|
<div class="listingblock">
|
583
714
|
<div class="content">
|
584
715
|
<pre><tt>sudo webroar install --ssl-support</tt></pre>
|
585
716
|
</div></div>
|
586
|
-
<div class="
|
717
|
+
<div class="paragraph"><p>Configure further SSL options in the server’s admin panel
|
587
718
|
<strong>http://<yourservername>:<port>/admin-panel/configuration</strong></p></div>
|
588
|
-
<div class="
|
719
|
+
<div class="paragraph"><p>After restarting the server, admin panel would now also be accessible over SSL.
|
589
720
|
<strong>https://<yourservername>:<port>/admin-panel</strong></p></div>
|
590
721
|
</td>
|
591
722
|
</tr></table>
|
592
723
|
</div>
|
593
724
|
<h4 id="_install_from_source_code">3.2.2. Install from source code</h4>
|
594
|
-
<div class="
|
725
|
+
<div class="paragraph"><p>If you like living in the fast lane, you can install the edge version giving
|
595
726
|
the following commands:</p></div>
|
596
727
|
<div class="listingblock">
|
597
728
|
<div class="content">
|
@@ -606,23 +737,23 @@ sudo rake install</tt></pre>
|
|
606
737
|
</td>
|
607
738
|
<td class="content">
|
608
739
|
<div class="title">SSL Support</div>
|
609
|
-
<div class="
|
740
|
+
<div class="paragraph"><p>To build with SSL support, use the following additional switch with the
|
610
741
|
<strong>sudo rake install</strong> command:</p></div>
|
611
742
|
<div class="listingblock">
|
612
743
|
<div class="content">
|
613
744
|
<pre><tt>sudo rake install ssl=yes</tt></pre>
|
614
745
|
</div></div>
|
615
|
-
<div class="
|
746
|
+
<div class="paragraph"><p>Configure further SSL options in the server’s admin panel
|
616
747
|
<strong>http://<yourservername>:<port>/admin-panel/configuration</strong></p></div>
|
617
|
-
<div class="
|
748
|
+
<div class="paragraph"><p>After restarting the server, admin panel would now also be accessible over SSL.
|
618
749
|
<strong>https://<yourservername>:<port>/admin-panel</strong></p></div>
|
619
750
|
</td>
|
620
751
|
</tr></table>
|
621
752
|
</div>
|
622
753
|
<h4 id="_non_interactive_install_using_capistrano">3.2.3. Non-Interactive Install using Capistrano</h4>
|
623
|
-
<div class="
|
754
|
+
<div class="paragraph"><p>You can use following Capistrano script to install the edge version on a
|
624
755
|
remote machine</p></div>
|
625
|
-
<div class="olist"><ol>
|
756
|
+
<div class="olist arabic"><ol class="arabic">
|
626
757
|
<li>
|
627
758
|
<p>
|
628
759
|
Create folder <dir>, move to <dir> folder using <strong>cd <dir></strong>.
|
@@ -639,8 +770,7 @@ Replace the content of <strong>config/deploy.rb</strong> with the following scri
|
|
639
770
|
</p>
|
640
771
|
<div class="listingblock">
|
641
772
|
<div class="content">
|
642
|
-
<pre><tt>
|
643
|
-
set :application, "WebROaR"
|
773
|
+
<pre><tt>set :application, "WebROaR"
|
644
774
|
set :repository, "git://github.com/webroar/webroar.git"
|
645
775
|
|
646
776
|
set :scm, :git
|
@@ -759,7 +889,7 @@ installed gems. (If you use Ubuntu, you might be able to relate to this point
|
|
759
889
|
better.)</td>
|
760
890
|
</tr></table>
|
761
891
|
</div>
|
762
|
-
<div class="
|
892
|
+
<div class="ulist"><ul>
|
763
893
|
<li>
|
764
894
|
<p>
|
765
895
|
In case auto-installation of dependent gems fails (due to some prehistoric
|
@@ -774,7 +904,7 @@ rubygems version or any other reason), you can install the following dependent
|
|
774
904
|
<li>
|
775
905
|
<p>
|
776
906
|
After successful installation of the webroar gem, any errors that occur
|
777
|
-
during the setup are saved to the install.log created in the installed gem
|
907
|
+
during the setup are saved to the install.log created in the installed gem’s
|
778
908
|
directory. This can be used to troubleshoot the issues, if any.
|
779
909
|
</p>
|
780
910
|
</li>
|
@@ -786,9 +916,18 @@ dump file would be created in /tmp if <em>gcore</em> is available on that machin
|
|
786
916
|
</p>
|
787
917
|
</li>
|
788
918
|
</ul></div>
|
789
|
-
<h3 id="
|
790
|
-
<div class="
|
791
|
-
|
919
|
+
<h3 id="_know_issue">3.4. Know Issue</h3><div style="clear:left"></div>
|
920
|
+
<div class="ulist"><ul>
|
921
|
+
<li>
|
922
|
+
<p>
|
923
|
+
WebROaR with SSL build crashes on Ubuntu 10.04 upon execution of
|
924
|
+
<strong>gnutls_handshake</strong> by secure connection.
|
925
|
+
</p>
|
926
|
+
</li>
|
927
|
+
</ul></div>
|
928
|
+
<h3 id="_setting_up_database_for_server_admin_panel">3.5. Setting up database for server admin panel</h3><div style="clear:left"></div>
|
929
|
+
<div class="paragraph"><p>The server’s admin panel itself is a Ruby on Rails™ web application, and by
|
930
|
+
default uses sqlite as it’s database. You can edit
|
792
931
|
<strong>admin_panel/config/database.yml</strong> to setup a database of your liking and
|
793
932
|
follow it up by running these commands from the <strong>admin_panel</strong> directory.</p></div>
|
794
933
|
<div class="listingblock">
|
@@ -796,19 +935,19 @@ follow it up by running these commands from the <strong>admin_panel</strong> dir
|
|
796
935
|
<pre><tt>rake db:create
|
797
936
|
rake db:migrate</tt></pre>
|
798
937
|
</div></div>
|
799
|
-
<div class="
|
938
|
+
<div class="paragraph"><p><strong>admin_panel</strong> directory would be present under the server’s rubygem
|
800
939
|
directory.</p></div>
|
801
940
|
</div>
|
802
941
|
<h2 id="_usage">4. Usage</h2>
|
803
942
|
<div class="sectionbody">
|
804
|
-
<div class="
|
943
|
+
<div class="paragraph"><p>Start/Stop/Restart WebROaR:</p></div>
|
805
944
|
<div class="listingblock">
|
806
945
|
<div class="content">
|
807
946
|
<pre><tt>sudo webroar start
|
808
947
|
sudo webroar stop
|
809
948
|
sudo webroar restart</tt></pre>
|
810
949
|
</div></div>
|
811
|
-
<div class="
|
950
|
+
<div class="paragraph"><p>Start/Stop/Restart a deployed application:</p></div>
|
812
951
|
<div class="listingblock">
|
813
952
|
<div class="content">
|
814
953
|
<pre><tt>sudo webroar start <Application Name>
|
@@ -821,18 +960,18 @@ sudo webroar restart <Application Name></tt></pre>
|
|
821
960
|
<img src="./images/icons/note.png" alt="Note" />
|
822
961
|
</td>
|
823
962
|
<td class="content">
|
824
|
-
<div class="
|
963
|
+
<div class="paragraph"><p>You can stop the admin panel application of the server any time, to conserve
|
825
964
|
resources and ensure better security.</p></div>
|
826
965
|
<div class="listingblock">
|
827
966
|
<div class="content">
|
828
967
|
<pre><tt>sudo webroar stop "Admin Panel"</tt></pre>
|
829
968
|
</div></div>
|
830
|
-
<div class="
|
969
|
+
<div class="paragraph"><p>To start it whenever you want, use the following command:</p></div>
|
831
970
|
<div class="listingblock">
|
832
971
|
<div class="content">
|
833
972
|
<pre><tt>sudo webroar start "Admin Panel"</tt></pre>
|
834
973
|
</div></div>
|
835
|
-
<div class="
|
974
|
+
<div class="paragraph"><p>Please note that analytics data and exceptions are still captured by the
|
836
975
|
server even when the admin panel is stopped.</p></div>
|
837
976
|
</td>
|
838
977
|
</tr></table>
|
@@ -841,10 +980,10 @@ server even when the admin panel is stopped.</p></div>
|
|
841
980
|
<h2 id="_deploying_applications">5. Deploying applications</h2>
|
842
981
|
<div class="sectionbody">
|
843
982
|
<h3 id="_deploy_using_admin_panel">5.1. Deploy using Admin Panel</h3><div style="clear:left"></div>
|
844
|
-
<div class="
|
983
|
+
<div class="paragraph"><p>If the server got installed successfully, you should be able access it’s admin
|
845
984
|
panel using the link:<br />
|
846
985
|
<strong>http://<yourservername>:<port>/admin-panel</strong></p></div>
|
847
|
-
<div class="
|
986
|
+
<div class="paragraph"><p>You can log in with the administrator account username and password that you
|
848
987
|
had entered during server installation. Deploy the ruby web application of
|
849
988
|
your choice accessing the <strong>Configuration</strong> link of the admin panel.</p></div>
|
850
989
|
<div class="admonitionblock">
|
@@ -857,15 +996,15 @@ The application starts up automatically after deployment.</td>
|
|
857
996
|
</tr></table>
|
858
997
|
</div>
|
859
998
|
<h3 id="_deploy_using_capistrano">5.2. Deploy using Capistrano</h3><div style="clear:left"></div>
|
860
|
-
<div class="
|
999
|
+
<div class="paragraph"><p>WebROaR can be easily integrated with Capistrano using the following
|
861
1000
|
instructions.</p></div>
|
862
|
-
<div class="
|
1001
|
+
<div class="paragraph"><p>After installing Capistrano, run the following command in your application’s
|
863
1002
|
root directory:</p></div>
|
864
1003
|
<div class="listingblock">
|
865
1004
|
<div class="content">
|
866
1005
|
<pre><tt>capify .</tt></pre>
|
867
1006
|
</div></div>
|
868
|
-
<div class="
|
1007
|
+
<div class="paragraph"><p>It would create <strong>Capfile</strong> and <strong>config/deploy.rb</strong> files.
|
869
1008
|
Modify <strong>config/deploy.rb</strong> file as shown below:</p></div>
|
870
1009
|
<div class="listingblock">
|
871
1010
|
<div class="content">
|
@@ -931,23 +1070,23 @@ end
|
|
931
1070
|
|
932
1071
|
after "deploy:update", "deploy:restart"</tt></pre>
|
933
1072
|
</div></div>
|
934
|
-
<div class="
|
1073
|
+
<div class="paragraph"><p>Create the application directory structure by running setup command:</p></div>
|
935
1074
|
<div class="listingblock">
|
936
1075
|
<div class="content">
|
937
1076
|
<pre><tt>cap deploy:setup</tt></pre>
|
938
1077
|
</div></div>
|
939
|
-
<div class="
|
1078
|
+
<div class="paragraph"><p>Deploy the application using command:</p></div>
|
940
1079
|
<div class="listingblock">
|
941
1080
|
<div class="content">
|
942
1081
|
<pre><tt>cap deploy</tt></pre>
|
943
1082
|
</div></div>
|
944
|
-
<div class="
|
1083
|
+
<div class="paragraph"><p>Add the application to WebROaR:</p></div>
|
945
1084
|
<div class="listingblock">
|
946
1085
|
<div class="content">
|
947
1086
|
<pre><tt>cap deploy:add</tt></pre>
|
948
1087
|
</div></div>
|
949
|
-
<div class="
|
950
|
-
<div class="
|
1088
|
+
<div class="paragraph"><p>Please note that the application needs to be added to the server only once.</p></div>
|
1089
|
+
<div class="paragraph"><p>You can use the following commands for starting/stopping/restarting the
|
951
1090
|
application while upgrading it in the future:</p></div>
|
952
1091
|
<div class="listingblock">
|
953
1092
|
<div class="content">
|
@@ -956,9 +1095,9 @@ cap deploy:start
|
|
956
1095
|
cap deploy:restart</tt></pre>
|
957
1096
|
</div></div>
|
958
1097
|
<h3 id="_rack_applications_other_than_rails">5.3. Rack applications (other than Rails)</h3><div style="clear:left"></div>
|
959
|
-
<div class="
|
960
|
-
required in it
|
961
|
-
<div class="
|
1098
|
+
<div class="paragraph"><p>To deploy any Rack based application (other than Rails) the following are
|
1099
|
+
required in it’s root directory:</p></div>
|
1100
|
+
<div class="ulist"><ul>
|
962
1101
|
<li>
|
963
1102
|
<p>
|
964
1103
|
<strong>public</strong> folder containing static files like images and stylesheets
|
@@ -971,8 +1110,8 @@ contain the complete logic for initializing the application.
|
|
971
1110
|
</p>
|
972
1111
|
</li>
|
973
1112
|
</ul></div>
|
974
|
-
<div class="
|
975
|
-
<div class="
|
1113
|
+
<div class="paragraph"><p>Here are some examples of the Rackup files:</p></div>
|
1114
|
+
<div class="paragraph"><p><strong>Merb</strong></p></div>
|
976
1115
|
<div class="listingblock">
|
977
1116
|
<div class="content">
|
978
1117
|
<pre><tt> require 'rubygems'
|
@@ -985,7 +1124,7 @@ contain the complete logic for initializing the application.
|
|
985
1124
|
Merb::BootLoader.run
|
986
1125
|
run Merb::Rack::Application.new</tt></pre>
|
987
1126
|
</div></div>
|
988
|
-
<div class="
|
1127
|
+
<div class="paragraph"><p><strong>Sinatra</strong></p></div>
|
989
1128
|
<div class="listingblock">
|
990
1129
|
<div class="content">
|
991
1130
|
<pre><tt> require 'rubygems'
|
@@ -995,32 +1134,32 @@ contain the complete logic for initializing the application.
|
|
995
1134
|
set :raise_errors, true
|
996
1135
|
run Sinatra::Application</tt></pre>
|
997
1136
|
</div></div>
|
998
|
-
<div class="
|
1137
|
+
<div class="paragraph"><p>You can use following environment variables in <strong>config.ru</strong> to access the few
|
999
1138
|
application configuration parameters given at a time of application deployment
|
1000
1139
|
in WebROaR.</p></div>
|
1001
|
-
<div class="
|
1140
|
+
<div class="ulist"><ul>
|
1002
1141
|
<li>
|
1003
1142
|
<p>
|
1004
|
-
ENV['APP_ROOT'] - To get the application root
|
1143
|
+
ENV['APP_ROOT\'] - To get the application root
|
1005
1144
|
</p>
|
1006
1145
|
</li>
|
1007
1146
|
<li>
|
1008
1147
|
<p>
|
1009
|
-
ENV['APP_ENV'] - To get the application environment
|
1148
|
+
ENV['APP_ENV\'] - To get the application environment
|
1010
1149
|
</p>
|
1011
1150
|
</li>
|
1012
1151
|
<li>
|
1013
1152
|
<p>
|
1014
|
-
ENV['APP_BASE_URI'] - To get the baseuri
|
1153
|
+
ENV['APP_BASE_URI\'] - To get the baseuri
|
1015
1154
|
</p>
|
1016
1155
|
</li>
|
1017
1156
|
</ul></div>
|
1018
1157
|
</div>
|
1019
1158
|
<h2 id="_accessing_run_time_statistics">6. Accessing run time statistics</h2>
|
1020
1159
|
<div class="sectionbody">
|
1021
|
-
<div class="
|
1160
|
+
<div class="paragraph"><p>For those applications whose Analytics are <strong>Enabled</strong> in their configuration,
|
1022
1161
|
the following graphs are available under the <strong>Analytics</strong> link of the admin panel.</p></div>
|
1023
|
-
<div class="olist"><ol>
|
1162
|
+
<div class="olist arabic"><ol class="arabic">
|
1024
1163
|
<li>
|
1025
1164
|
<p>
|
1026
1165
|
URL Breakdown
|
@@ -1072,7 +1211,7 @@ Physical Memory Utilization
|
|
1072
1211
|
</p>
|
1073
1212
|
</li>
|
1074
1213
|
</ol></div>
|
1075
|
-
<div class="
|
1214
|
+
<div class="paragraph"><p>Additionally, CPU and Physical Memory usage graphs for the entire server are
|
1076
1215
|
also available.</p></div>
|
1077
1216
|
<div class="admonitionblock">
|
1078
1217
|
<table><tr>
|
@@ -1087,10 +1226,10 @@ about a minute for it’s data to show up in the graphs.</td>
|
|
1087
1226
|
</div>
|
1088
1227
|
<h2 id="_exception_tracking_and_notifications">7. Exception Tracking and Notifications</h2>
|
1089
1228
|
<div class="sectionbody">
|
1090
|
-
<div class="
|
1229
|
+
<div class="paragraph"><p>Any exceptions that occur in any of the deployed application are captured by
|
1091
1230
|
the server. An email notification is also sent out immediately with details of
|
1092
1231
|
the exception, if the mail settings have been configured in the admin panel.</p></div>
|
1093
|
-
<div class="
|
1232
|
+
<div class="paragraph"><p>All the exceptions can be seen under the <strong>Exceptions</strong> link of the server admin
|
1094
1233
|
panel.</p></div>
|
1095
1234
|
<div class="admonitionblock">
|
1096
1235
|
<table><tr>
|
@@ -1105,7 +1244,7 @@ after it has occurred.</td>
|
|
1105
1244
|
</div>
|
1106
1245
|
<h2 id="_uninstall">8. Uninstall</h2>
|
1107
1246
|
<div class="sectionbody">
|
1108
|
-
<div class="
|
1247
|
+
<div class="paragraph"><p>If you didn’t like the server, use the following commands in sequence to
|
1109
1248
|
uninstall it.</p></div>
|
1110
1249
|
<div class="listingblock">
|
1111
1250
|
<div class="content">
|
@@ -1115,16 +1254,16 @@ sudo gem uninstall webroar</tt></pre>
|
|
1115
1254
|
</div>
|
1116
1255
|
<h2 id="_test_suite">9. Test Suite</h2>
|
1117
1256
|
<div class="sectionbody">
|
1118
|
-
<div class="
|
1119
|
-
might like to use it
|
1120
|
-
<div class="
|
1257
|
+
<div class="paragraph"><p>If you are a programmer and wish to play around with the server’s code, you
|
1258
|
+
might like to use it’s test suite to test the robustness of your changes.</p></div>
|
1259
|
+
<div class="paragraph"><p>It can be run using the following command:</p></div>
|
1121
1260
|
<div class="listingblock">
|
1122
1261
|
<div class="content">
|
1123
1262
|
<pre><tt>sudo webroar test</tt></pre>
|
1124
1263
|
</div></div>
|
1125
|
-
<div class="
|
1264
|
+
<div class="paragraph"><p>We execute this suite on our nightly builds and it currently has the following
|
1126
1265
|
tests:</p></div>
|
1127
|
-
<div class="
|
1266
|
+
<div class="ulist"><ul>
|
1128
1267
|
<li>
|
1129
1268
|
<p>
|
1130
1269
|
Unit Tests
|
@@ -1369,9 +1508,11 @@ Build Tests
|
|
1369
1508
|
Run the test suite</tt></pre>
|
1370
1509
|
</div></div>
|
1371
1510
|
</div>
|
1511
|
+
</div>
|
1512
|
+
<div id="footnotes"><hr /></div>
|
1372
1513
|
<div id="footer">
|
1373
1514
|
<div id="footer-text">
|
1374
|
-
Last updated 2010-
|
1515
|
+
Last updated 2010-08-09 16:58:48 IST
|
1375
1516
|
</div>
|
1376
1517
|
</div>
|
1377
1518
|
</body>
|