mongrel 0.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +24 -28
- data/Rakefile +11 -4
- data/bin/mongrel_rails +82 -25
- data/doc/rdoc/classes/FactoryError.html +144 -0
- data/doc/rdoc/classes/FactoryError.src/M000001.html +23 -0
- data/doc/rdoc/classes/Mongrel.html +5 -5
- data/doc/rdoc/classes/Mongrel.src/{M000001.html → M000015.html} +4 -4
- data/doc/rdoc/classes/Mongrel/Const.html +2 -2
- data/doc/rdoc/classes/Mongrel/DirHandler.html +26 -26
- data/doc/rdoc/classes/Mongrel/DirHandler.src/{M000009.html → M000023.html} +0 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/{M000010.html → M000024.html} +5 -2
- data/doc/rdoc/classes/Mongrel/DirHandler.src/{M000011.html → M000025.html} +26 -26
- data/doc/rdoc/classes/Mongrel/DirHandler.src/{M000012.html → M000026.html} +17 -17
- data/doc/rdoc/classes/Mongrel/DirHandler.src/{M000013.html → M000027.html} +24 -24
- data/doc/rdoc/classes/Mongrel/Error404Handler.html +10 -10
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000033.html → M000047.html} +0 -0
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000034.html → M000048.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HeaderOut.html +10 -10
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000019.html → M000033.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000020.html → M000034.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpHandler.html +5 -5
- data/doc/rdoc/classes/Mongrel/HttpHandler.src/{M000025.html → M000039.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.html +35 -35
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000002.html → M000016.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000003.html → M000017.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000004.html → M000018.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000005.html → M000019.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000006.html → M000020.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000007.html → M000021.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000008.html → M000022.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpRequest.html +5 -5
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000035.html → M000049.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.html +36 -36
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000026.html → M000040.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000027.html → M000041.html} +1 -1
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000028.html → M000042.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000029.html → M000043.html} +1 -1
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000030.html → M000044.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000031.html → M000045.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000032.html → M000046.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.html +28 -28
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000014.html → M000028.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000015.html → M000029.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000016.html → M000030.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000017.html → M000031.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000018.html → M000032.html} +0 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.html +20 -20
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000021.html → M000035.html} +0 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000022.html → M000036.html} +0 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000023.html → M000037.html} +0 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000024.html → M000038.html} +0 -0
- data/doc/rdoc/classes/PluginFactory.html +409 -0
- data/doc/rdoc/classes/PluginFactory.src/M000002.html +18 -0
- data/doc/rdoc/classes/PluginFactory.src/M000003.html +18 -0
- data/doc/rdoc/classes/PluginFactory.src/M000004.html +22 -0
- data/doc/rdoc/classes/PluginFactory.src/M000005.html +22 -0
- data/doc/rdoc/classes/PluginFactory.src/M000006.html +33 -0
- data/doc/rdoc/classes/PluginFactory.src/M000007.html +32 -0
- data/doc/rdoc/classes/PluginFactory.src/M000008.html +18 -0
- data/doc/rdoc/classes/PluginFactory.src/M000009.html +24 -0
- data/doc/rdoc/classes/PluginFactory.src/M000010.html +40 -0
- data/doc/rdoc/classes/PluginFactory.src/M000011.html +39 -0
- data/doc/rdoc/classes/PluginFactory.src/M000012.html +24 -0
- data/doc/rdoc/classes/PluginFactory.src/M000013.html +70 -0
- data/doc/rdoc/classes/PluginFactory.src/M000014.html +34 -0
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/README.html +29 -37
- data/doc/rdoc/files/lib/mongrel_rb.html +1 -1
- data/doc/rdoc/files/lib/pluginfactory_rb.html +132 -0
- data/doc/rdoc/fr_class_index.html +2 -0
- data/doc/rdoc/fr_file_index.html +1 -0
- data/doc/rdoc/fr_method_index.html +49 -35
- data/examples/simpletest.rb +10 -3
- data/lib/mongrel.rb +6 -3
- data/lib/mongrel/command.rb +192 -0
- data/lib/pluginfactory.rb +384 -0
- data/tools/rakehelp.rb +33 -29
- metadata +71 -41
@@ -0,0 +1,132 @@
|
|
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>File: pluginfactory.rb</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="fileHeader">
|
50
|
+
<h1>pluginfactory.rb</h1>
|
51
|
+
<table class="header-table">
|
52
|
+
<tr class="top-aligned-row">
|
53
|
+
<td><strong>Path:</strong></td>
|
54
|
+
<td>lib/pluginfactory.rb
|
55
|
+
</td>
|
56
|
+
</tr>
|
57
|
+
<tr class="top-aligned-row">
|
58
|
+
<td><strong>Last Update:</strong></td>
|
59
|
+
<td>Sat Feb 11 22:57:24 EST 2006</td>
|
60
|
+
</tr>
|
61
|
+
</table>
|
62
|
+
</div>
|
63
|
+
<!-- banner header -->
|
64
|
+
|
65
|
+
<div id="bodyContent">
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
<div id="contextContent">
|
70
|
+
|
71
|
+
<div id="description">
|
72
|
+
<p>
|
73
|
+
This module contains the <a
|
74
|
+
href="../../classes/PluginFactory.html">PluginFactory</a> mixin. Including
|
75
|
+
<a href="../../classes/PluginFactory.html">PluginFactory</a> in your class
|
76
|
+
turns it into a factory for its derivatives, capable of searching for and
|
77
|
+
loading them by name. This is useful when you have an abstract base class
|
78
|
+
which defines an interface and basic functionality for a part of a larger
|
79
|
+
system, and a collection of subclasses which implement the interface for
|
80
|
+
different underlying functionality.
|
81
|
+
</p>
|
82
|
+
<p>
|
83
|
+
An example of where this might be useful is in a program which talks to a
|
84
|
+
database. To avoid coupling it to a specific database, you use a Driver
|
85
|
+
class which encapsulates your program’s interaction with the database
|
86
|
+
behind a useful interface. Now you can create a concrete implementation of
|
87
|
+
the Driver class for each kind of database you wish to talk to. If you make
|
88
|
+
the base Driver class a <a
|
89
|
+
href="../../classes/PluginFactory.html">PluginFactory</a>, too, you can add
|
90
|
+
new drivers simply by dropping them in a directory and using the
|
91
|
+
Driver’s <tt>create</tt> method to instantiate them:
|
92
|
+
</p>
|
93
|
+
<h2>Creation Argument Variants</h2>
|
94
|
+
<p>
|
95
|
+
The <tt>create</tt> class method added to your class by <a
|
96
|
+
href="../../classes/PluginFactory.html">PluginFactory</a> searches for your
|
97
|
+
module using
|
98
|
+
</p>
|
99
|
+
<h2>Synopsis</h2>
|
100
|
+
|
101
|
+
</div>
|
102
|
+
|
103
|
+
|
104
|
+
</div>
|
105
|
+
|
106
|
+
|
107
|
+
</div>
|
108
|
+
|
109
|
+
|
110
|
+
<!-- if includes -->
|
111
|
+
|
112
|
+
<div id="section">
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
<!-- if method_list -->
|
122
|
+
|
123
|
+
|
124
|
+
</div>
|
125
|
+
|
126
|
+
|
127
|
+
<div id="validator-badges">
|
128
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
129
|
+
</div>
|
130
|
+
|
131
|
+
</body>
|
132
|
+
</html>
|
@@ -20,6 +20,7 @@
|
|
20
20
|
<div id="index">
|
21
21
|
<h1 class="section-bar">Classes</h1>
|
22
22
|
<div id="index-entries">
|
23
|
+
<a href="classes/FactoryError.html">FactoryError</a><br />
|
23
24
|
<a href="classes/Mongrel.html">Mongrel</a><br />
|
24
25
|
<a href="classes/Mongrel/Const.html">Mongrel::Const</a><br />
|
25
26
|
<a href="classes/Mongrel/DirHandler.html">Mongrel::DirHandler</a><br />
|
@@ -31,6 +32,7 @@
|
|
31
32
|
<a href="classes/Mongrel/HttpResponse.html">Mongrel::HttpResponse</a><br />
|
32
33
|
<a href="classes/Mongrel/HttpServer.html">Mongrel::HttpServer</a><br />
|
33
34
|
<a href="classes/Mongrel/URIClassifier.html">Mongrel::URIClassifier</a><br />
|
35
|
+
<a href="classes/PluginFactory.html">PluginFactory</a><br />
|
34
36
|
</div>
|
35
37
|
</div>
|
36
38
|
</body>
|
data/doc/rdoc/fr_file_index.html
CHANGED
@@ -25,6 +25,7 @@
|
|
25
25
|
<a href="files/README.html">README</a><br />
|
26
26
|
<a href="files/ext/http11/http11_c.html">ext/http11/http11.c</a><br />
|
27
27
|
<a href="files/lib/mongrel_rb.html">lib/mongrel.rb</a><br />
|
28
|
+
<a href="files/lib/pluginfactory_rb.html">lib/pluginfactory.rb</a><br />
|
28
29
|
</div>
|
29
30
|
</div>
|
30
31
|
</body>
|
@@ -20,41 +20,55 @@
|
|
20
20
|
<div id="index">
|
21
21
|
<h1 class="section-bar">Methods</h1>
|
22
22
|
<div id="index-entries">
|
23
|
-
<a href="classes/Mongrel/HeaderOut.html#
|
24
|
-
<a href="classes/Mongrel.html#
|
25
|
-
<a href="classes/Mongrel/DirHandler.html#
|
26
|
-
<a href="classes/
|
27
|
-
<a href="classes/
|
28
|
-
<a href="classes/
|
29
|
-
<a href="classes/Mongrel/
|
30
|
-
<a href="classes/Mongrel/HttpParser.html#
|
31
|
-
<a href="classes/
|
32
|
-
<a href="classes/
|
33
|
-
<a href="classes/Mongrel/
|
34
|
-
<a href="classes/Mongrel/
|
35
|
-
<a href="classes/Mongrel/HttpParser.html#
|
36
|
-
<a href="classes/
|
37
|
-
<a href="classes/
|
38
|
-
<a href="classes/
|
39
|
-
<a href="classes/
|
40
|
-
<a href="classes/
|
41
|
-
<a href="classes/
|
42
|
-
<a href="classes/
|
43
|
-
<a href="classes/
|
44
|
-
<a href="classes/Mongrel/
|
45
|
-
<a href="classes/Mongrel/
|
46
|
-
<a href="classes/Mongrel/HttpParser.html#
|
47
|
-
<a href="classes/Mongrel/
|
48
|
-
<a href="classes/Mongrel/URIClassifier.html#
|
49
|
-
<a href="classes/Mongrel/
|
50
|
-
<a href="classes/Mongrel/
|
51
|
-
<a href="classes/Mongrel/
|
52
|
-
<a href="classes/Mongrel/
|
53
|
-
<a href="classes/Mongrel/
|
54
|
-
<a href="classes/Mongrel/
|
55
|
-
<a href="classes/Mongrel/
|
56
|
-
<a href="classes/Mongrel/
|
57
|
-
<a href="classes/Mongrel/HttpServer.html#
|
23
|
+
<a href="classes/Mongrel/HeaderOut.html#M000034">[]= (Mongrel::HeaderOut)</a><br />
|
24
|
+
<a href="classes/Mongrel.html#M000015">add_mime_type (Mongrel)</a><br />
|
25
|
+
<a href="classes/Mongrel/DirHandler.html#M000024">can_serve (Mongrel::DirHandler)</a><br />
|
26
|
+
<a href="classes/PluginFactory.html#M000009">create (PluginFactory)</a><br />
|
27
|
+
<a href="classes/PluginFactory.html#M000008">derivativeClasses (PluginFactory)</a><br />
|
28
|
+
<a href="classes/PluginFactory.html#M000005">derivatives (PluginFactory)</a><br />
|
29
|
+
<a href="classes/Mongrel/HttpParser.html#M000020">error? (Mongrel::HttpParser)</a><br />
|
30
|
+
<a href="classes/Mongrel/HttpParser.html#M000019">execute (Mongrel::HttpParser)</a><br />
|
31
|
+
<a href="classes/PluginFactory.html#M000004">extend_object (PluginFactory)</a><br />
|
32
|
+
<a href="classes/PluginFactory.html#M000006">factoryType (PluginFactory)</a><br />
|
33
|
+
<a href="classes/Mongrel/HttpParser.html#M000018">finish (Mongrel::HttpParser)</a><br />
|
34
|
+
<a href="classes/Mongrel/HttpResponse.html#M000046">finished (Mongrel::HttpResponse)</a><br />
|
35
|
+
<a href="classes/Mongrel/HttpParser.html#M000021">finished? (Mongrel::HttpParser)</a><br />
|
36
|
+
<a href="classes/PluginFactory.html#M000012">getModuleName (PluginFactory)</a><br />
|
37
|
+
<a href="classes/PluginFactory.html#M000010">getSubclass (PluginFactory)</a><br />
|
38
|
+
<a href="classes/PluginFactory.html#M000003">included (PluginFactory)</a><br />
|
39
|
+
<a href="classes/PluginFactory.html#M000007">inherited (PluginFactory)</a><br />
|
40
|
+
<a href="classes/PluginFactory.html#M000011">loadDerivative (PluginFactory)</a><br />
|
41
|
+
<a href="classes/PluginFactory.html#M000002">log (PluginFactory)</a><br />
|
42
|
+
<a href="classes/PluginFactory.html#M000014">makeRequirePath (PluginFactory)</a><br />
|
43
|
+
<a href="classes/FactoryError.html#M000001">new (FactoryError)</a><br />
|
44
|
+
<a href="classes/Mongrel/HttpResponse.html#M000040">new (Mongrel::HttpResponse)</a><br />
|
45
|
+
<a href="classes/Mongrel/DirHandler.html#M000023">new (Mongrel::DirHandler)</a><br />
|
46
|
+
<a href="classes/Mongrel/HttpParser.html#M000016">new (Mongrel::HttpParser)</a><br />
|
47
|
+
<a href="classes/Mongrel/HeaderOut.html#M000033">new (Mongrel::HeaderOut)</a><br />
|
48
|
+
<a href="classes/Mongrel/URIClassifier.html#M000035">new (Mongrel::URIClassifier)</a><br />
|
49
|
+
<a href="classes/Mongrel/Error404Handler.html#M000047">new (Mongrel::Error404Handler)</a><br />
|
50
|
+
<a href="classes/Mongrel/HttpServer.html#M000028">new (Mongrel::HttpServer)</a><br />
|
51
|
+
<a href="classes/Mongrel/HttpRequest.html#M000049">new (Mongrel::HttpRequest)</a><br />
|
52
|
+
<a href="classes/Mongrel/HttpParser.html#M000022">nread (Mongrel::HttpParser)</a><br />
|
53
|
+
<a href="classes/Mongrel/Error404Handler.html#M000048">process (Mongrel::Error404Handler)</a><br />
|
54
|
+
<a href="classes/Mongrel/HttpHandler.html#M000039">process (Mongrel::HttpHandler)</a><br />
|
55
|
+
<a href="classes/Mongrel/DirHandler.html#M000027">process (Mongrel::DirHandler)</a><br />
|
56
|
+
<a href="classes/Mongrel/HttpServer.html#M000029">process_client (Mongrel::HttpServer)</a><br />
|
57
|
+
<a href="classes/Mongrel/HttpServer.html#M000031">register (Mongrel::HttpServer)</a><br />
|
58
|
+
<a href="classes/Mongrel/URIClassifier.html#M000036">register (Mongrel::URIClassifier)</a><br />
|
59
|
+
<a href="classes/PluginFactory.html#M000013">requireDerivative (PluginFactory)</a><br />
|
60
|
+
<a href="classes/Mongrel/HttpResponse.html#M000042">reset (Mongrel::HttpResponse)</a><br />
|
61
|
+
<a href="classes/Mongrel/HttpParser.html#M000017">reset (Mongrel::HttpParser)</a><br />
|
62
|
+
<a href="classes/Mongrel/URIClassifier.html#M000038">resolve (Mongrel::URIClassifier)</a><br />
|
63
|
+
<a href="classes/Mongrel/HttpServer.html#M000030">run (Mongrel::HttpServer)</a><br />
|
64
|
+
<a href="classes/Mongrel/HttpResponse.html#M000045">send_body (Mongrel::HttpResponse)</a><br />
|
65
|
+
<a href="classes/Mongrel/DirHandler.html#M000025">send_dir_listing (Mongrel::DirHandler)</a><br />
|
66
|
+
<a href="classes/Mongrel/DirHandler.html#M000026">send_file (Mongrel::DirHandler)</a><br />
|
67
|
+
<a href="classes/Mongrel/HttpResponse.html#M000044">send_header (Mongrel::HttpResponse)</a><br />
|
68
|
+
<a href="classes/Mongrel/HttpResponse.html#M000043">send_status (Mongrel::HttpResponse)</a><br />
|
69
|
+
<a href="classes/Mongrel/HttpResponse.html#M000041">start (Mongrel::HttpResponse)</a><br />
|
70
|
+
<a href="classes/Mongrel/HttpServer.html#M000032">unregister (Mongrel::HttpServer)</a><br />
|
71
|
+
<a href="classes/Mongrel/URIClassifier.html#M000037">unregister (Mongrel::URIClassifier)</a><br />
|
58
72
|
</div>
|
59
73
|
</div>
|
60
74
|
</body>
|
data/examples/simpletest.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
require 'mongrel'
|
2
2
|
require 'yaml'
|
3
|
+
require 'zlib'
|
3
4
|
|
4
5
|
class SimpleHandler < Mongrel::HttpHandler
|
5
6
|
def process(request, response)
|
6
7
|
response.start do |head,out|
|
7
8
|
head["Content-Type"] = "text/html"
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
results = "<html><body>Your request:<br /><pre>#{request.params.to_yaml}</pre><a href=\"/files\">View the files.</a></body></html>"
|
10
|
+
if not request.params["HTTP_ACCEPT_ENCODING"] == "gzip,deflate"
|
11
|
+
head["Content-Encoding"] = "deflate"
|
12
|
+
# send it back deflated
|
13
|
+
out << Zlib::Deflate.deflate(results)
|
14
|
+
else
|
15
|
+
# no gzip supported, send it back normal
|
16
|
+
out << results
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
data/lib/mongrel.rb
CHANGED
@@ -229,7 +229,7 @@ module Mongrel
|
|
229
229
|
# the socket in the proper order. This lets you intermix header and
|
230
230
|
# body content as needed.
|
231
231
|
def start(status=200)
|
232
|
-
@status = status
|
232
|
+
@status = status.to_i
|
233
233
|
yield @header, @body
|
234
234
|
finished
|
235
235
|
end
|
@@ -242,7 +242,7 @@ module Mongrel
|
|
242
242
|
end
|
243
243
|
|
244
244
|
def send_status
|
245
|
-
@socket.write("HTTP/1.1 #{@status} #{HTTP_STATUS_CODES[@status]}\r\nContent-Length
|
245
|
+
@socket.write("HTTP/1.1 #{@status.to_i} #{HTTP_STATUS_CODES[@status.to_i]}\r\nContent-Length:#{body.length}\r\nConnection: close\r\n")
|
246
246
|
end
|
247
247
|
|
248
248
|
def send_header
|
@@ -256,7 +256,7 @@ module Mongrel
|
|
256
256
|
|
257
257
|
# connection: close is also added to ensure that the client does not pipeline.
|
258
258
|
@socket.write(@body.read)
|
259
|
-
end
|
259
|
+
end
|
260
260
|
|
261
261
|
# This takes whatever has been done to header and body and then writes it in the
|
262
262
|
# proper format to make an HTTP/1.1 response.
|
@@ -489,6 +489,9 @@ module Mongrel
|
|
489
489
|
# it's a file and it's there
|
490
490
|
return req
|
491
491
|
end
|
492
|
+
else
|
493
|
+
# does not exist or isn't in the right spot
|
494
|
+
return nil
|
492
495
|
end
|
493
496
|
end
|
494
497
|
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'optparse'
|
3
|
+
require 'pluginfactory'
|
4
|
+
|
5
|
+
|
6
|
+
module Mongrel
|
7
|
+
|
8
|
+
# Contains all of the various commands that are used with
|
9
|
+
# Mongrel servers.
|
10
|
+
|
11
|
+
module Command
|
12
|
+
|
13
|
+
|
14
|
+
# A Command pattern implementation used to create the set of command available to the user
|
15
|
+
# from Mongrel. The script uses objects which implement this interface to do the
|
16
|
+
# user's bidding.
|
17
|
+
#
|
18
|
+
# Creating a new command is very easy, and you can do it without modifying the source
|
19
|
+
# of Mongrel thanks to PluginFactory. What you do is the following:
|
20
|
+
#
|
21
|
+
# 1.
|
22
|
+
class Command
|
23
|
+
include PluginFactory
|
24
|
+
|
25
|
+
attr_reader :valid, :done_validating
|
26
|
+
|
27
|
+
# Called by the implemented command to set the options for that command.
|
28
|
+
# Every option has a short and long version, a description, a variable to
|
29
|
+
# set, and a default value. No exceptions.
|
30
|
+
def options(opts)
|
31
|
+
# process the given options array
|
32
|
+
opts.each do |short, long, help, variable, default|
|
33
|
+
self.instance_variable_set(variable, default)
|
34
|
+
@opt.on(short, long, help) do |arg|
|
35
|
+
self.instance_variable_set(variable, arg)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Called by the subclass to setup the command and parse the argv arguments.
|
41
|
+
# The call is destructive on argv since it uses the OptionParser#parse! function.
|
42
|
+
def initialize(argv)
|
43
|
+
@opt = OptionParser.new
|
44
|
+
@valid = true
|
45
|
+
# this is retarded, but it has to be done this way because -h and -v exit
|
46
|
+
@done_validating = false
|
47
|
+
|
48
|
+
configure
|
49
|
+
|
50
|
+
# I need to add my own -h definition to prevent the -h by default from exiting.
|
51
|
+
@opt.on_tail("-h", "--help", "Show this message") do
|
52
|
+
@done_validating = true
|
53
|
+
puts @opt
|
54
|
+
end
|
55
|
+
|
56
|
+
# I need to add my own -v definition to prevent the -h from exiting by default as well.
|
57
|
+
@opt.on_tail("--version", "Show version") do
|
58
|
+
@done_validating = true
|
59
|
+
if VERSION
|
60
|
+
puts "Version #{VERSION}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
@opt.parse! argv
|
65
|
+
end
|
66
|
+
|
67
|
+
# Tells the PluginFactory where to look for additional commands. By default
|
68
|
+
# it's just a "plugins" directory wherever we are located.
|
69
|
+
def self.derivativeDirs
|
70
|
+
return ["plugins"]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns true/false depending on whether the command is configured properly.
|
74
|
+
def validate
|
75
|
+
return @valid
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns a help message. Defaults to OptionParser#help which should be good.
|
79
|
+
def help
|
80
|
+
@opt.help
|
81
|
+
end
|
82
|
+
|
83
|
+
# Runs the command doing it's job. You should implement this otherwise it will
|
84
|
+
# throw a NotImplementedError as a reminder.
|
85
|
+
def run
|
86
|
+
raise NotImplementedError
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
# Validates the given expression is true and prints the message if not, exiting.
|
91
|
+
def valid?(exp, message)
|
92
|
+
if not @done_validating and (not exp)
|
93
|
+
failure message
|
94
|
+
@valid = false
|
95
|
+
@done_validating = true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Validates that a file exists and if not displays the message
|
100
|
+
def valid_exists?(file, message)
|
101
|
+
valid?(file != nil && File.exist?(file), message)
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Validates that the file is a file and not a directory or something else.
|
106
|
+
def valid_file?(file, message)
|
107
|
+
valid?(file != nil && File.file?(file), message)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Validates that the given directory exists
|
111
|
+
def valid_dir?(file, message)
|
112
|
+
valid?(file != nil && File.directory?(file), message)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Just a simple method to display failure until something better is developed.
|
116
|
+
def failure(message)
|
117
|
+
STDERR.puts "!!! #{message}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
# A Singleton class that manages all of the available commands
|
124
|
+
# and handles running them.
|
125
|
+
class Registry
|
126
|
+
include Singleton
|
127
|
+
|
128
|
+
# Builds a list of possible commands from the Command derivates list
|
129
|
+
def commands
|
130
|
+
list = Command.derivatives()
|
131
|
+
match = Regexp.new("(.*::.*)|(.*command.*)", Regexp::IGNORECASE)
|
132
|
+
|
133
|
+
results = []
|
134
|
+
list.keys.each do |key|
|
135
|
+
results << key.to_s unless match.match(key.to_s)
|
136
|
+
end
|
137
|
+
|
138
|
+
return results.sort
|
139
|
+
end
|
140
|
+
|
141
|
+
# Prints a list of available commands.
|
142
|
+
def print_command_list
|
143
|
+
puts "Available commands are:\n\n"
|
144
|
+
|
145
|
+
self.commands.each do |name|
|
146
|
+
puts " - #{name}\n"
|
147
|
+
end
|
148
|
+
|
149
|
+
puts "\nEach command takes -h as an option to get help."
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
# Runs the args against the first argument as the command name.
|
155
|
+
# If it has any errors it returns a false, otherwise it return true.
|
156
|
+
def run(args)
|
157
|
+
# find the command and change the program's name to reflect it
|
158
|
+
cmd_name = args.shift
|
159
|
+
$0 = "#{cmd_name}"
|
160
|
+
|
161
|
+
if cmd_name == "?" or cmd_name == "help"
|
162
|
+
print_command_list
|
163
|
+
return true
|
164
|
+
end
|
165
|
+
|
166
|
+
# command exists, set it up and validate it
|
167
|
+
begin
|
168
|
+
command = Command.create(cmd_name, args)
|
169
|
+
rescue FactoryError
|
170
|
+
STDERR.puts "INVALID COMMAND: #$!"
|
171
|
+
print_command_list
|
172
|
+
return
|
173
|
+
end
|
174
|
+
|
175
|
+
# Normally the command is NOT valid right after being created
|
176
|
+
# but sometimes (like with -h or -v) there's no further processing
|
177
|
+
# needed so the command is already valid so we can skip it.
|
178
|
+
if not command.done_validating
|
179
|
+
if not command.validate
|
180
|
+
STDERR.puts "#{cmd_name} reported an error. Use -h to get help."
|
181
|
+
return false
|
182
|
+
else
|
183
|
+
command.run
|
184
|
+
end
|
185
|
+
end
|
186
|
+
return true
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|