Capcode 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/COPYING +340 -0
- data/README +53 -0
- data/doc/rdoc/classes/Capcode.html +434 -0
- data/doc/rdoc/classes/Capcode/HTTPError.html +125 -0
- data/doc/rdoc/classes/Capcode/Helpers.html +214 -0
- data/doc/rdoc/classes/Capcode/ParameterError.html +125 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/AUTHORS.html +100 -0
- data/doc/rdoc/files/COPYING.html +524 -0
- data/doc/rdoc/files/README.html +164 -0
- data/doc/rdoc/files/lib/capcode_rb.html +533 -0
- data/doc/rdoc/index.html +10 -0
- data/doc/rdoc/permalink.gif +0 -0
- data/doc/rdoc/rdoc-style.css +106 -0
- data/doc/rdoc/rubyfr.png +0 -0
- data/examples/blog.log +16 -0
- data/examples/blog.rb +62 -0
- data/examples/index.html +5 -0
- data/examples/sample.rb +61 -0
- data/examples/session.rb +47 -0
- data/lib/capcode.rb +293 -0
- data/lib/capcode/core_ext.rb +15 -0
- data/setup.rb +1585 -0
- metadata +106 -0
data/doc/rdoc/index.html
ADDED
Binary file
|
@@ -0,0 +1,106 @@
|
|
1
|
+
|
2
|
+
body {
|
3
|
+
font: normal 14px verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif;
|
4
|
+
line-height: 160%;
|
5
|
+
padding: 0; margin: 0;
|
6
|
+
margin-bottom: 30px;
|
7
|
+
/* background-color: #402; */
|
8
|
+
background-color: #CCCC99;
|
9
|
+
}
|
10
|
+
h1, h2, h3, h4 {
|
11
|
+
font-family: Utopia, Georgia, serif;
|
12
|
+
font-weight: bold;
|
13
|
+
letter-spacing: -0.018em;
|
14
|
+
}
|
15
|
+
h1 { font-size: 24px; margin: .15em 1em 0 0 }
|
16
|
+
h2 { font-size: 24px }
|
17
|
+
h3 { font-size: 19px }
|
18
|
+
h4 { font-size: 17px; font-weight: normal; }
|
19
|
+
h4.ruled { border-bottom: solid 1px #CC9; }
|
20
|
+
h2.ruled { padding-top: 35px; border-top: solid 1px #AA5; }
|
21
|
+
|
22
|
+
/* Link styles */
|
23
|
+
:link, :visited {
|
24
|
+
|
25
|
+
}
|
26
|
+
:link:hover, :visited:hover {
|
27
|
+
|
28
|
+
}
|
29
|
+
#fullpage {
|
30
|
+
width: 720px;
|
31
|
+
padding-top: 20px;
|
32
|
+
margin: 0 auto;
|
33
|
+
}
|
34
|
+
.page_shade, .page {
|
35
|
+
border-left: 1px solid black;
|
36
|
+
border-right: 1px solid black;
|
37
|
+
border-bottom: 1px solid black;
|
38
|
+
background-color: #FFFFFF;
|
39
|
+
}
|
40
|
+
.page {
|
41
|
+
padding: 20px 35px;
|
42
|
+
}
|
43
|
+
.page .header {
|
44
|
+
float: right;
|
45
|
+
color: #777;
|
46
|
+
font-size: 10px;
|
47
|
+
}
|
48
|
+
.page h1, .page h2, .page h3 {
|
49
|
+
clear: both;
|
50
|
+
text-align: center;
|
51
|
+
}
|
52
|
+
#pager {
|
53
|
+
background-color: #EEEEAE;
|
54
|
+
border-top: 2px solid black;
|
55
|
+
border-left: 2px solid black;
|
56
|
+
border-right: 2px solid black;
|
57
|
+
border-bottom: 1px dashed #999966;
|
58
|
+
padding: 20px 0 20px 20px;
|
59
|
+
color: #666633;
|
60
|
+
font-size: 11px;
|
61
|
+
}
|
62
|
+
#pager :link, #pager :visited {
|
63
|
+
color: #8E2400;
|
64
|
+
padding: 0px 5px;
|
65
|
+
}
|
66
|
+
#pager :link:hover, #pager :visited:hover {
|
67
|
+
color: #8E2400;
|
68
|
+
}
|
69
|
+
#pagertd {
|
70
|
+
font-size: 11px;
|
71
|
+
}
|
72
|
+
#logo { float: left; }
|
73
|
+
#menu {
|
74
|
+
padding: 4px 12px;
|
75
|
+
margin: 0;
|
76
|
+
}
|
77
|
+
#menu h3 { padding: 0; margin: 0; }
|
78
|
+
#menu #links { float: right; }
|
79
|
+
pre { font-weight: bold; color: black; }
|
80
|
+
tt { color: #703; font-size: 12pt; }
|
81
|
+
.dyn-source {
|
82
|
+
background-color: #EEEEEE;
|
83
|
+
border: 1px solid #CCCCCC;
|
84
|
+
padding: 4px 8px;
|
85
|
+
margin: 0;
|
86
|
+
display: none; }
|
87
|
+
.dyn-source pre {
|
88
|
+
color: #000000;
|
89
|
+
font-size: 8pt;
|
90
|
+
font-familly: monospace;
|
91
|
+
|
92
|
+
}
|
93
|
+
.source-link { text-align: right; font-size: 8pt; }
|
94
|
+
.ruby-comment { color: black; font-style: italic }
|
95
|
+
.ruby-constant { color: #123456; font-weight: bold; }
|
96
|
+
.ruby-identifier { color: #005599; }
|
97
|
+
.ruby-ivar { color: orange; }
|
98
|
+
.ruby-keyword { color: red; font-weight: bold }
|
99
|
+
.ruby-node { color: #FFFFFF; }
|
100
|
+
.ruby-operator { color: #055005; }
|
101
|
+
.ruby-regexp { color: #DDFFDD; }
|
102
|
+
.ruby-value { color: #FFAAAA; font-style: italic }
|
103
|
+
.kw { color: red; font-weight: bold }
|
104
|
+
.cmt { color: green; font-style: italic }
|
105
|
+
.str { color: #EECCCC; font-style: italic }
|
106
|
+
.re { color: #EECCCC; }
|
data/doc/rdoc/rubyfr.png
ADDED
Binary file
|
data/examples/blog.log
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Logfile created on Thu Mar 05 14:37:14 +0100 2009 by /
|
2
|
+
::1 - - [05/Mar/2009 14:37:17] "GET / HTTP/1.1" 200 424 0.0134
|
3
|
+
::1 - - [05/Mar/2009 14:37:17] "GET /favicon.ico HTTP/1.1" 200 424 0.0076
|
4
|
+
::1 - - [05/Mar/2009 14:37:19] "GET /8650ac90-ebb8-012b-4e10-002332b2a7fc/2808417976 HTTP/1.1" 302 - 0.0083
|
5
|
+
::1 - - [05/Mar/2009 14:37:19] "GET / HTTP/1.1" 200 246 0.0077
|
6
|
+
::1 - - [05/Mar/2009 14:37:20] "GET HTTP/1.1" 200 280 0.0015
|
7
|
+
::1 - - [05/Mar/2009 14:37:45] "POST HTTP/1.1" 500 101939 0.2057
|
8
|
+
::1 - - [05/Mar/2009 14:37:56] "POST HTTP/1.1" 500 102076 0.1473
|
9
|
+
::1 - - [05/Mar/2009 14:37:56] "GET /favicon.ico HTTP/1.1" 200 246 0.0068
|
10
|
+
::1 - - [05/Mar/2009 14:37:59] "GET / HTTP/1.1" 200 246 0.0064
|
11
|
+
::1 - - [05/Mar/2009 14:38:00] "GET HTTP/1.1" 200 280 0.0019
|
12
|
+
::1 - - [05/Mar/2009 14:38:08] "POST HTTP/1.1" 302 - 0.0093
|
13
|
+
::1 - - [05/Mar/2009 14:38:08] "GET / HTTP/1.1" 200 416 0.0110
|
14
|
+
::1 - - [05/Mar/2009 14:38:45] "GET HTTP/1.1" 200 280 0.0030
|
15
|
+
::1 - - [05/Mar/2009 14:39:23] "POST HTTP/1.1" 500 102140 0.1681
|
16
|
+
::1 - - [05/Mar/2009 14:41:01] "GET / HTTP/1.1" 200 416 0.0081
|
data/examples/blog.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
$:.unshift( "../lib" )
|
2
|
+
require 'rubygems'
|
3
|
+
require 'capcode'
|
4
|
+
require 'couch_foo'
|
5
|
+
|
6
|
+
CouchFoo::Base.set_database(:host => "http://localhost:5984", :database => "my_blog")
|
7
|
+
|
8
|
+
class Story < CouchFoo::Base
|
9
|
+
property :title, String
|
10
|
+
property :body, String
|
11
|
+
property :date, String
|
12
|
+
end
|
13
|
+
|
14
|
+
module Capcode
|
15
|
+
class HTTPError
|
16
|
+
def r404(f)
|
17
|
+
"Pas glop !!! #{f} est inconnu !!!"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Index < Route '/'
|
22
|
+
def get
|
23
|
+
r = "<html><body>"
|
24
|
+
|
25
|
+
story = Story.find( :all )
|
26
|
+
|
27
|
+
story.each do |s|
|
28
|
+
r += "<h2>#{s.title}</h2><small>#{s.date} - <a href='#{URL( Remove, s.id, s.rev )}'>Delete this entry</a></small><p>#{s.body}</p>"
|
29
|
+
end
|
30
|
+
|
31
|
+
r+"<hr /><a href='#{URL(Add)}'>Add a new entry</a></body></html>"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Remove < Route '/remove/([^\/]*)/(.*)'
|
36
|
+
def get( id, rev )
|
37
|
+
Story.delete(id, rev)
|
38
|
+
redirect( Index )
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Add < Route '/add'
|
43
|
+
def get
|
44
|
+
'
|
45
|
+
<html><body>
|
46
|
+
<h1>Add a new entry</h1>
|
47
|
+
<form method="POST">
|
48
|
+
Titre : <input type="text" name="title"><br />
|
49
|
+
<textarea name="body"></textarea><br />
|
50
|
+
<input type="submit">
|
51
|
+
</form>
|
52
|
+
</body></html>
|
53
|
+
'
|
54
|
+
end
|
55
|
+
def post
|
56
|
+
Story.create( :title => params['title'], :body => params['body'], :date => Time.now.to_s )
|
57
|
+
redirect( Index )
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Capcode.run( :port => 3001, :host => "localhost", :log => "blog.log" )
|
data/examples/index.html
ADDED
data/examples/sample.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
$:.unshift( "../lib" )
|
2
|
+
require 'capcode'
|
3
|
+
|
4
|
+
module Capcode
|
5
|
+
module Helpers
|
6
|
+
def bold( &b )
|
7
|
+
"<b>"+yield+"</b>"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Capcode
|
13
|
+
class HTTPError
|
14
|
+
def r404(f)
|
15
|
+
"Pas glop !!! #{f} est inconnu !!!"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Hello < Route '/hello/(.*)'
|
20
|
+
def get( you )
|
21
|
+
you = "you" if you.nil?
|
22
|
+
|
23
|
+
session = { :user => you }
|
24
|
+
|
25
|
+
"Hello " + bold { you } + " it's '#{Time.now} !"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Redir < Route '/r'
|
30
|
+
def get
|
31
|
+
redirect( Hello, "Greg" )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Glop < Route '/glop/(.*)', '/glop/code/([^\/]*)/(.*)'
|
36
|
+
def get( r, v )
|
37
|
+
"Glop receive #{r}, type #{r.class} and #{v}, type #{v.class} from #{URL(Glop)}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Js < Route '/toto'
|
42
|
+
def get
|
43
|
+
json( { :some => 'json', :stuff => ['here'] } )
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Env < Route '/env'
|
48
|
+
def get
|
49
|
+
x = env.map do |k,v|
|
50
|
+
"#{k} => #{v}"
|
51
|
+
end.join( "<br />\n" )
|
52
|
+
x
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Capcode.map( "/file" ) do
|
58
|
+
Rack::File.new( "." )
|
59
|
+
end
|
60
|
+
|
61
|
+
Capcode.run( :port => 3001, :host => "localhost" )
|
data/examples/session.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
$:.unshift( "../lib" )
|
2
|
+
require 'capcode'
|
3
|
+
|
4
|
+
module Capcode
|
5
|
+
class HTTPError
|
6
|
+
def r404(f)
|
7
|
+
"#{f} not found !!!"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Index < Route '/'
|
12
|
+
def get
|
13
|
+
redirect( Hello, session[:user] )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Hello < Route '/hello/(.*)'
|
18
|
+
def get( you )
|
19
|
+
if you.nil?
|
20
|
+
redirect( WhoAreYou )
|
21
|
+
else
|
22
|
+
"
|
23
|
+
Hello #{you}<br />
|
24
|
+
Clic <a href='#{URL(Hello)}'>here</a> if hou want to change your name
|
25
|
+
"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class WhoAreYou < Route '/who_are_you'
|
31
|
+
def get
|
32
|
+
'
|
33
|
+
Please, enter your name :<br />
|
34
|
+
<form method="POST">
|
35
|
+
<input type="text", name="user"><br />
|
36
|
+
<input type="submit">
|
37
|
+
</form>
|
38
|
+
'
|
39
|
+
end
|
40
|
+
def post
|
41
|
+
session[:user] = params['user']
|
42
|
+
redirect( Index )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Capcode.run( :port => 3000, :host => "localhost" )
|
data/lib/capcode.rb
ADDED
@@ -0,0 +1,293 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rack'
|
3
|
+
require 'json'
|
4
|
+
require 'logger'
|
5
|
+
require 'capcode/core_ext'
|
6
|
+
|
7
|
+
module Capcode
|
8
|
+
CAPCOD_VERION="0.2.0"
|
9
|
+
@@__ROUTES = {}
|
10
|
+
|
11
|
+
class ParameterError < ArgumentError
|
12
|
+
end
|
13
|
+
|
14
|
+
# Helpers contains methods available in your controllers
|
15
|
+
module Helpers
|
16
|
+
# Help you to return a JSON response
|
17
|
+
#
|
18
|
+
# module Capcode
|
19
|
+
# class JsonResponse < Route '/json/([^\/]*)/(.*)'
|
20
|
+
# def get( arg1, arg2 )
|
21
|
+
# json( { :1 => arg1, :2 => arg2 })
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
def json( d )
|
26
|
+
@response['Content-Type'] = 'application/json'
|
27
|
+
d.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
# Send a redirect response
|
31
|
+
#
|
32
|
+
# module Capcode
|
33
|
+
# class Hello < Route '/hello/(.*)'
|
34
|
+
# def get( you )
|
35
|
+
# if you.nil?
|
36
|
+
# redirect( WhoAreYou )
|
37
|
+
# else
|
38
|
+
# ...
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
def redirect( klass, *a )
|
44
|
+
[302, {'Location' => URL(klass, *a)}, '']
|
45
|
+
end
|
46
|
+
|
47
|
+
# Builds an URL route to a controller or a path
|
48
|
+
#
|
49
|
+
# if you declare the controller Hello :
|
50
|
+
#
|
51
|
+
# module Capcode
|
52
|
+
# class Hello < Route '/hello/(.*)'
|
53
|
+
# ...
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# then
|
58
|
+
#
|
59
|
+
# URL( Hello, "you" ) # => /hello/you
|
60
|
+
def URL( klass, *a )
|
61
|
+
path = nil
|
62
|
+
a = a.delete_if{ |x| x.nil? }
|
63
|
+
|
64
|
+
if klass.class == Class
|
65
|
+
Capcode.routes.each do |p, k|
|
66
|
+
path = p if k.class == klass
|
67
|
+
end
|
68
|
+
else
|
69
|
+
path = klass
|
70
|
+
end
|
71
|
+
|
72
|
+
path+((a.size>0)?("/"+a.join("/")):(""))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
include Rack
|
77
|
+
|
78
|
+
# HTTPError help you to create your own 404, 500 and/or 501 response
|
79
|
+
#
|
80
|
+
# To create a custom 404 reponse, create a fonction HTTPError.r404 in
|
81
|
+
# your application :
|
82
|
+
#
|
83
|
+
# module Capcode
|
84
|
+
# class HTTPError
|
85
|
+
# def r404(f)
|
86
|
+
# "#{f} not found :("
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# Do the same (r500 and r501) to customize 500 and 501 errors
|
92
|
+
class HTTPError
|
93
|
+
def initialize(app)#:nodoc:
|
94
|
+
@app = app
|
95
|
+
end
|
96
|
+
|
97
|
+
def call(env) #:nodoc:
|
98
|
+
status, headers, body = @app.call(env)
|
99
|
+
|
100
|
+
if self.methods.include? "r#{status}"
|
101
|
+
body = self.call "r#{status}", env['REQUEST_PATH']
|
102
|
+
headers['Content-Length'] = body.length.to_s
|
103
|
+
end
|
104
|
+
|
105
|
+
[status, headers, body]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class << self
|
110
|
+
# Add routes to a controller class
|
111
|
+
#
|
112
|
+
# module Capcode
|
113
|
+
# class Hello < Route '/hello/(.*)', '/hello/([^#]*)#(.*)'
|
114
|
+
# def get( arg1, arg2 )
|
115
|
+
# ...
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
# In the <tt>get</tt> method, you will receive the maximum of parameters declared
|
121
|
+
# by the routes. In this example, you will receive 2 parameters. So if you
|
122
|
+
# go to <tt>/hello/world#friend</tt> then <tt>arg1</tt> will be set to <tt>world</tt> and <tt>arg2</tt>
|
123
|
+
# will be set to <tt>friend</tt>. Now if you go to <tt>/hello/you</tt>, then <tt>arg1</tt> will
|
124
|
+
# be set to <tt>you</tt> and <tt>arg2</tt> will be set to <tt>nil</tt>
|
125
|
+
#
|
126
|
+
# If the regexp in the route does not match, all arguments will be <tt>nil</tt>
|
127
|
+
def Route *u
|
128
|
+
Class.new {
|
129
|
+
meta_def(:__urls__){
|
130
|
+
# < Route '/hello/world/([^\/]*)/id(\d*)', '/hello/(.*)'
|
131
|
+
# # => [ {'/hello/world' => '([^\/]*)/id(\d*)', '/hello' => '(.*)'}, 2, <Capcode::Klass> ]
|
132
|
+
h = {}
|
133
|
+
max = 0
|
134
|
+
u.each do |_u|
|
135
|
+
m = /\/([^\/]*\(.*)/.match( _u )
|
136
|
+
if m.nil?
|
137
|
+
h[_u] = ''
|
138
|
+
else
|
139
|
+
h[m.pre_match] = m.captures[0]
|
140
|
+
max = Regexp.new(m.captures[0]).number_of_captures if max < Regexp.new(m.captures[0]).number_of_captures
|
141
|
+
end
|
142
|
+
end
|
143
|
+
[h, max, self]
|
144
|
+
}
|
145
|
+
|
146
|
+
# Hash containing all the request parameters (GET or POST)
|
147
|
+
def params
|
148
|
+
@request.params
|
149
|
+
end
|
150
|
+
|
151
|
+
# Hash containing all the environment variables
|
152
|
+
def env
|
153
|
+
@env
|
154
|
+
end
|
155
|
+
|
156
|
+
# Hash session
|
157
|
+
def session
|
158
|
+
@env['rack.session']
|
159
|
+
end
|
160
|
+
|
161
|
+
# Return the Rack::Request object
|
162
|
+
def request
|
163
|
+
@request
|
164
|
+
end
|
165
|
+
|
166
|
+
# Return the Rack::Response object
|
167
|
+
def response
|
168
|
+
@response
|
169
|
+
end
|
170
|
+
|
171
|
+
def call( e ) #:nodoc:
|
172
|
+
@env = e
|
173
|
+
@response = Rack::Response.new
|
174
|
+
@request = Rack::Request.new(@env)
|
175
|
+
|
176
|
+
r = case @env["REQUEST_METHOD"]
|
177
|
+
when "GET"
|
178
|
+
sc = @request.script_name
|
179
|
+
sc = "/" if sc.size == 0
|
180
|
+
regexp = Regexp.new( self.class.__urls__[0][sc] )
|
181
|
+
nargs = self.class.__urls__[1]
|
182
|
+
|
183
|
+
args = regexp.match( Rack::Utils.unescape(@request.path_info).gsub( /^\//, "" ) )
|
184
|
+
if args.nil?
|
185
|
+
raise Capcode::ParameterError, "Path info `#{@request.path_info}' does not match route regexp `#{regexp.source}'"
|
186
|
+
else
|
187
|
+
args = args.captures
|
188
|
+
end
|
189
|
+
|
190
|
+
while args.size < nargs
|
191
|
+
args << nil
|
192
|
+
end
|
193
|
+
|
194
|
+
get( *args )
|
195
|
+
when "POST"
|
196
|
+
post
|
197
|
+
end
|
198
|
+
if r.respond_to?(:to_ary)
|
199
|
+
@response.status = r[0]
|
200
|
+
r[1].each do |k,v|
|
201
|
+
@response[k] = v
|
202
|
+
end
|
203
|
+
@response.body = r[2]
|
204
|
+
else
|
205
|
+
@response.write r
|
206
|
+
end
|
207
|
+
|
208
|
+
@response.finish
|
209
|
+
end
|
210
|
+
|
211
|
+
include Capcode::Helpers
|
212
|
+
}
|
213
|
+
end
|
214
|
+
|
215
|
+
# This method help you to map and URL to a Rack or What you want Helper
|
216
|
+
#
|
217
|
+
# Capcode.map( "/file" ) do
|
218
|
+
# Rack::File.new( "." )
|
219
|
+
# end
|
220
|
+
def map( r, &b )
|
221
|
+
@@__ROUTES[r] = yield
|
222
|
+
end
|
223
|
+
|
224
|
+
# Start your application.
|
225
|
+
#
|
226
|
+
# Options :
|
227
|
+
# * <tt>:port</tt> = Listen port
|
228
|
+
# * <tt>:host</tt> = Listen host
|
229
|
+
# * <tt>:server</tt> = Server type (webrick or mongrel)
|
230
|
+
# * <tt>:log</tt> = Output logfile (default: STDOUT)
|
231
|
+
# * <tt>:session</tt> = Session parameters. See Rack::Session for more informations
|
232
|
+
def run( args = {} )
|
233
|
+
conf = {
|
234
|
+
:port => args[:port]||3000,
|
235
|
+
:host => args[:host]||"localhost",
|
236
|
+
:server => args[:server]||nil,
|
237
|
+
:log => args[:log]||$stdout,
|
238
|
+
:session => args[:session]||{}
|
239
|
+
}
|
240
|
+
|
241
|
+
# Check that mongrel exists
|
242
|
+
if conf[:server].nil? || conf[:server] == "mongrel"
|
243
|
+
begin
|
244
|
+
require 'mongrel'
|
245
|
+
conf[:server] = "mongrel"
|
246
|
+
rescue LoadError
|
247
|
+
puts "!! could not load mongrel. Falling back to webrick."
|
248
|
+
conf[:server] = "webrick"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
Capcode.constants.each do |k|
|
253
|
+
begin
|
254
|
+
if eval "Capcode::#{k}.public_methods(true).include?( '__urls__' )"
|
255
|
+
u, m, c = eval "Capcode::#{k}.__urls__"
|
256
|
+
u.keys.each do |_u|
|
257
|
+
@@__ROUTES[_u] = c.new
|
258
|
+
end
|
259
|
+
end
|
260
|
+
rescue => e
|
261
|
+
raise e.message
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
app = Rack::URLMap.new(@@__ROUTES)
|
266
|
+
app = Rack::Session::Cookie.new( app, conf[:session] )
|
267
|
+
app = Capcode::HTTPError.new(app)
|
268
|
+
app = Rack::ContentLength.new(app)
|
269
|
+
app = Rack::Lint.new(app)
|
270
|
+
app = Rack::ShowExceptions.new(app)
|
271
|
+
# app = Rack::Reloader.new(app) ## -- NE RELOAD QUE capcode.rb -- So !!!
|
272
|
+
app = Rack::CommonLogger.new( app, Logger.new(conf[:log]) )
|
273
|
+
|
274
|
+
|
275
|
+
case conf[:server]
|
276
|
+
when "mongrel"
|
277
|
+
puts "** Starting Mongrel on #{conf[:host]}:#{conf[:port]}"
|
278
|
+
Rack::Handler::Mongrel.run( app, {:Port => conf[:port], :Host => conf[:host]} ) { |server|
|
279
|
+
trap "SIGINT", proc { server.stop }
|
280
|
+
}
|
281
|
+
when "webrick"
|
282
|
+
puts "** Starting WEBrick on #{conf[:host]}:#{conf[:port]}"
|
283
|
+
Rack::Handler::WEBrick.run( app, {:Port => conf[:port], :BindAddress => conf[:host]} ) { |server|
|
284
|
+
trap "SIGINT", proc { server.shutdown }
|
285
|
+
}
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def routes #:nodoc:
|
290
|
+
@@__ROUTES
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|