headius-mongrel 1.1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +21 -0
- data/COPYING +55 -0
- data/LICENSE +55 -0
- data/Manifest +69 -0
- data/README +74 -0
- data/Rakefile +202 -0
- data/TODO +5 -0
- data/bin/mongrel_rails +283 -0
- data/examples/builder.rb +29 -0
- data/examples/camping/README +3 -0
- data/examples/camping/blog.rb +294 -0
- data/examples/camping/tepee.rb +149 -0
- data/examples/httpd.conf +474 -0
- data/examples/mime.yaml +3 -0
- data/examples/mongrel.conf +9 -0
- data/examples/mongrel_simple_ctrl.rb +92 -0
- data/examples/mongrel_simple_service.rb +116 -0
- data/examples/monitrc +57 -0
- data/examples/random_thrash.rb +19 -0
- data/examples/simpletest.rb +52 -0
- data/examples/webrick_compare.rb +20 -0
- data/ext/http11/ext_help.h +14 -0
- data/ext/http11/extconf.rb +6 -0
- data/ext/http11/http11.c +402 -0
- data/ext/http11/http11_parser.c +1221 -0
- data/ext/http11/http11_parser.h +49 -0
- data/ext/http11/http11_parser.java.rl +170 -0
- data/ext/http11/http11_parser.rl +152 -0
- data/ext/http11/http11_parser_common.rl +54 -0
- data/ext/http11_java/Http11Service.java +13 -0
- data/ext/http11_java/org/jruby/mongrel/Http11.java +353 -0
- data/ext/http11_java/org/jruby/mongrel/Http11Parser.java +572 -0
- data/lib/mongrel.rb +364 -0
- data/lib/mongrel/camping.rb +107 -0
- data/lib/mongrel/cgi.rb +181 -0
- data/lib/mongrel/command.rb +222 -0
- data/lib/mongrel/configurator.rb +388 -0
- data/lib/mongrel/const.rb +110 -0
- data/lib/mongrel/debug.rb +203 -0
- data/lib/mongrel/gems.rb +22 -0
- data/lib/mongrel/handlers.rb +468 -0
- data/lib/mongrel/header_out.rb +28 -0
- data/lib/mongrel/http_request.rb +155 -0
- data/lib/mongrel/http_response.rb +163 -0
- data/lib/mongrel/init.rb +10 -0
- data/lib/mongrel/mime_types.yml +616 -0
- data/lib/mongrel/rails.rb +192 -0
- data/lib/mongrel/stats.rb +89 -0
- data/lib/mongrel/tcphack.rb +18 -0
- data/lib/mongrel/uri_classifier.rb +76 -0
- data/mongrel-public_cert.pem +20 -0
- data/mongrel.gemspec +47 -0
- data/setup.rb +1585 -0
- data/test/mime.yaml +3 -0
- data/test/mongrel.conf +1 -0
- data/test/test_cgi_wrapper.rb +26 -0
- data/test/test_command.rb +86 -0
- data/test/test_conditional.rb +107 -0
- data/test/test_configurator.rb +88 -0
- data/test/test_debug.rb +25 -0
- data/test/test_handlers.rb +126 -0
- data/test/test_http11.rb +156 -0
- data/test/test_redirect_handler.rb +45 -0
- data/test/test_request_progress.rb +100 -0
- data/test/test_response.rb +127 -0
- data/test/test_stats.rb +35 -0
- data/test/test_uriclassifier.rb +261 -0
- data/test/test_ws.rb +115 -0
- data/test/testhelp.rb +79 -0
- data/tools/trickletest.rb +45 -0
- metadata +199 -0
data/TODO
ADDED
data/bin/mongrel_rails
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
# Copyright (c) 2005 Zed A. Shaw
|
2
|
+
# You can redistribute it and/or modify it under the same terms as Ruby.
|
3
|
+
#
|
4
|
+
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
5
|
+
# for more information.
|
6
|
+
|
7
|
+
require 'yaml'
|
8
|
+
require 'etc'
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
11
|
+
require 'mongrel'
|
12
|
+
require 'mongrel/rails'
|
13
|
+
|
14
|
+
Mongrel::Gems.require 'gem_plugin'
|
15
|
+
|
16
|
+
# require 'ruby-debug'
|
17
|
+
# Debugger.start
|
18
|
+
|
19
|
+
module Mongrel
|
20
|
+
class Start < GemPlugin::Plugin "/commands"
|
21
|
+
include Mongrel::Command::Base
|
22
|
+
|
23
|
+
def configure
|
24
|
+
options [
|
25
|
+
["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
|
26
|
+
["-d", "--daemonize", "Run daemonized in the background", :@daemon, false],
|
27
|
+
['-p', '--port PORT', "Which port to bind to", :@port, 3000],
|
28
|
+
['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
|
29
|
+
['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
|
30
|
+
['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
|
31
|
+
['-n', '--num-processors INT', "Number of processors active before clients denied", :@num_processors, 1024],
|
32
|
+
['-o', '--timeout TIME', "Time to wait (in seconds) before killing a stalled thread", :@timeout, 60],
|
33
|
+
['-t', '--throttle TIME', "Time to pause (in hundredths of a second) between accepting clients", :@throttle, 0],
|
34
|
+
['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
|
35
|
+
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
|
36
|
+
['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
|
37
|
+
['-B', '--debug', "Enable debugging mode", :@debug, false],
|
38
|
+
['-C', '--config PATH', "Use a config file", :@config_file, nil],
|
39
|
+
['-S', '--script PATH', "Load the given file as an extra config script", :@config_script, nil],
|
40
|
+
['-G', '--generate PATH', "Generate a config file for use with -C", :@generate, nil],
|
41
|
+
['', '--user USER', "User to run as", :@user, nil],
|
42
|
+
['', '--group GROUP', "Group to run as", :@group, nil],
|
43
|
+
['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
|
44
|
+
]
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate
|
48
|
+
if @config_file
|
49
|
+
valid_exists?(@config_file, "Config file not there: #@config_file")
|
50
|
+
return false unless @valid
|
51
|
+
@config_file = File.expand_path(@config_file)
|
52
|
+
load_config
|
53
|
+
return false unless @valid
|
54
|
+
end
|
55
|
+
|
56
|
+
@cwd = File.expand_path(@cwd)
|
57
|
+
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
|
58
|
+
|
59
|
+
# Change there to start, then we'll have to come back after daemonize
|
60
|
+
Dir.chdir(@cwd)
|
61
|
+
|
62
|
+
valid?(@prefix[0] == ?/ && @prefix[-1] != ?/, "Prefix must begin with / and not end in /") if @prefix
|
63
|
+
valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
|
64
|
+
valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
|
65
|
+
valid_dir? @docroot, "Path to docroot not valid: #@docroot"
|
66
|
+
valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
|
67
|
+
valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
|
68
|
+
valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate
|
69
|
+
valid_user? @user if @user
|
70
|
+
valid_group? @group if @group
|
71
|
+
|
72
|
+
return @valid
|
73
|
+
end
|
74
|
+
|
75
|
+
def run
|
76
|
+
if @generate
|
77
|
+
@generate = File.expand_path(@generate)
|
78
|
+
STDERR.puts "** Writing config to \"#@generate\"."
|
79
|
+
open(@generate, "w") {|f| f.write(settings.to_yaml) }
|
80
|
+
STDERR.puts "** Finished. Run \"mongrel_rails start -C #@generate\" to use the config file."
|
81
|
+
exit 0
|
82
|
+
end
|
83
|
+
|
84
|
+
config = Mongrel::Rails::RailsConfigurator.new(settings) do
|
85
|
+
if defaults[:daemon]
|
86
|
+
if File.exist? defaults[:pid_file]
|
87
|
+
log "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors."
|
88
|
+
log "!!! Exiting with error. You must stop mongrel and clear the .pid before I'll attempt a start."
|
89
|
+
exit 1
|
90
|
+
end
|
91
|
+
|
92
|
+
daemonize
|
93
|
+
log "Daemonized, any open files are closed. Look at #{defaults[:pid_file]} and #{defaults[:log_file]} for info."
|
94
|
+
log "Settings loaded from #{@config_file} (they override command line)." if @config_file
|
95
|
+
end
|
96
|
+
|
97
|
+
log "Starting Mongrel listening at #{defaults[:host]}:#{defaults[:port]}"
|
98
|
+
|
99
|
+
listener do
|
100
|
+
mime = {}
|
101
|
+
if defaults[:mime_map]
|
102
|
+
log "Loading additional MIME types from #{defaults[:mime_map]}"
|
103
|
+
mime = load_mime_map(defaults[:mime_map], mime)
|
104
|
+
end
|
105
|
+
|
106
|
+
if defaults[:debug]
|
107
|
+
log "Installing debugging prefixed filters. Look in log/mongrel_debug for the files."
|
108
|
+
debug "/"
|
109
|
+
end
|
110
|
+
|
111
|
+
log "Starting Rails with #{defaults[:environment]} environment..."
|
112
|
+
log "Mounting Rails at #{defaults[:prefix]}..." if defaults[:prefix]
|
113
|
+
uri defaults[:prefix] || "/", :handler => rails(:mime => mime, :prefix => defaults[:prefix])
|
114
|
+
log "Rails loaded."
|
115
|
+
|
116
|
+
log "Loading any Rails specific GemPlugins"
|
117
|
+
load_plugins
|
118
|
+
|
119
|
+
if defaults[:config_script]
|
120
|
+
log "Loading #{defaults[:config_script]} external config script"
|
121
|
+
run_config(defaults[:config_script])
|
122
|
+
end
|
123
|
+
|
124
|
+
setup_rails_signals
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
config.run
|
129
|
+
config.log "Mongrel #{Mongrel::Const::MONGREL_VERSION} available at #{@address}:#{@port}"
|
130
|
+
|
131
|
+
if config.defaults[:daemon]
|
132
|
+
config.write_pid_file
|
133
|
+
else
|
134
|
+
config.log "Use CTRL-C to stop."
|
135
|
+
end
|
136
|
+
|
137
|
+
config.join
|
138
|
+
|
139
|
+
if config.needs_restart
|
140
|
+
if RUBY_PLATFORM !~ /mswin/
|
141
|
+
cmd = "ruby #{__FILE__} start #{original_args.join(' ')}"
|
142
|
+
config.log "Restarting with arguments: #{cmd}"
|
143
|
+
config.stop(false, true)
|
144
|
+
config.remove_pid_file
|
145
|
+
|
146
|
+
if config.defaults[:daemon]
|
147
|
+
system cmd
|
148
|
+
else
|
149
|
+
STDERR.puts "Can't restart unless in daemon mode."
|
150
|
+
exit 1
|
151
|
+
end
|
152
|
+
else
|
153
|
+
config.log "Win32 does not support restarts. Exiting."
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def load_config
|
159
|
+
settings = {}
|
160
|
+
begin
|
161
|
+
settings = YAML.load_file(@config_file)
|
162
|
+
ensure
|
163
|
+
STDERR.puts "** Loading settings from #{@config_file} (they override command line)." unless @daemon || settings[:daemon]
|
164
|
+
end
|
165
|
+
|
166
|
+
settings[:includes] ||= ["mongrel"]
|
167
|
+
|
168
|
+
# Config file settings will override command line settings
|
169
|
+
settings.each do |key, value|
|
170
|
+
key = key.to_s
|
171
|
+
if config_keys.include?(key)
|
172
|
+
key = 'address' if key == 'host'
|
173
|
+
self.instance_variable_set("@#{key}", value)
|
174
|
+
else
|
175
|
+
failure "Unknown configuration setting: #{key}"
|
176
|
+
@valid = false
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def config_keys
|
182
|
+
@config_keys ||=
|
183
|
+
%w(address host port cwd log_file pid_file environment docroot mime_map daemon debug includes config_script num_processors timeout throttle user group prefix)
|
184
|
+
end
|
185
|
+
|
186
|
+
def settings
|
187
|
+
config_keys.inject({}) do |hash, key|
|
188
|
+
value = self.instance_variable_get("@#{key}")
|
189
|
+
key = 'host' if key == 'address'
|
190
|
+
hash[key.to_sym] ||= value
|
191
|
+
hash
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def Mongrel::send_signal(signal, pid_file)
|
197
|
+
pid = open(pid_file).read.to_i
|
198
|
+
print "Sending #{signal} to Mongrel at PID #{pid}..."
|
199
|
+
begin
|
200
|
+
Process.kill(signal, pid)
|
201
|
+
rescue Errno::ESRCH
|
202
|
+
puts "Process does not exist. Not running."
|
203
|
+
end
|
204
|
+
|
205
|
+
puts "Done."
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
class Stop < GemPlugin::Plugin "/commands"
|
210
|
+
include Mongrel::Command::Base
|
211
|
+
|
212
|
+
def configure
|
213
|
+
options [
|
214
|
+
['-c', '--chdir PATH', "Change to dir before starting (will be expanded).", :@cwd, "."],
|
215
|
+
['-f', '--force', "Force the shutdown (kill -9).", :@force, false],
|
216
|
+
['-w', '--wait SECONDS', "Wait SECONDS before forcing shutdown", :@wait, "0"],
|
217
|
+
['-P', '--pid FILE', "Where the PID file is located.", :@pid_file, "log/mongrel.pid"]
|
218
|
+
]
|
219
|
+
end
|
220
|
+
|
221
|
+
def validate
|
222
|
+
@cwd = File.expand_path(@cwd)
|
223
|
+
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
|
224
|
+
|
225
|
+
Dir.chdir @cwd
|
226
|
+
|
227
|
+
valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
|
228
|
+
return @valid
|
229
|
+
end
|
230
|
+
|
231
|
+
def run
|
232
|
+
if @force
|
233
|
+
@wait.to_i.times do |waiting|
|
234
|
+
exit(0) if not File.exist? @pid_file
|
235
|
+
sleep 1
|
236
|
+
end
|
237
|
+
|
238
|
+
Mongrel::send_signal("KILL", @pid_file) if File.exist? @pid_file
|
239
|
+
else
|
240
|
+
Mongrel::send_signal("TERM", @pid_file)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
class Restart < GemPlugin::Plugin "/commands"
|
247
|
+
include Mongrel::Command::Base
|
248
|
+
|
249
|
+
def configure
|
250
|
+
options [
|
251
|
+
['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, '.'],
|
252
|
+
['-s', '--soft', "Do a soft restart rather than a process exit restart", :@soft, false],
|
253
|
+
['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
|
254
|
+
]
|
255
|
+
end
|
256
|
+
|
257
|
+
def validate
|
258
|
+
@cwd = File.expand_path(@cwd)
|
259
|
+
valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
|
260
|
+
|
261
|
+
Dir.chdir @cwd
|
262
|
+
|
263
|
+
valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
|
264
|
+
return @valid
|
265
|
+
end
|
266
|
+
|
267
|
+
def run
|
268
|
+
if @soft
|
269
|
+
Mongrel::send_signal("HUP", @pid_file)
|
270
|
+
else
|
271
|
+
Mongrel::send_signal("USR2", @pid_file)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
GemPlugin::Manager.instance.load "mongrel" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE
|
279
|
+
|
280
|
+
|
281
|
+
if not Mongrel::Command::Registry.instance.run ARGV
|
282
|
+
exit 1
|
283
|
+
end
|
data/examples/builder.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'mongrel'
|
2
|
+
|
3
|
+
class TestPlugin < GemPlugin::Plugin "/handlers"
|
4
|
+
include Mongrel::HttpHandlerPlugin
|
5
|
+
|
6
|
+
def process(request, response)
|
7
|
+
STDERR.puts "My options are: #{options.inspect}"
|
8
|
+
STDERR.puts "Request Was:"
|
9
|
+
STDERR.puts request.params.to_yaml
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
config = Mongrel::Configurator.new :host => "127.0.0.1" do
|
14
|
+
load_plugins :includes => ["mongrel"], :excludes => ["rails"]
|
15
|
+
daemonize :cwd => Dir.pwd, :log_file => "mongrel.log", :pid_file => "mongrel.pid"
|
16
|
+
|
17
|
+
listener :port => 3000 do
|
18
|
+
uri "/app", :handler => plugin("/handlers/testplugin", :test => "that")
|
19
|
+
uri "/app", :handler => Mongrel::DirHandler.new(".")
|
20
|
+
load_plugins :includes => ["mongrel", "rails"]
|
21
|
+
end
|
22
|
+
|
23
|
+
trap("INT") { stop }
|
24
|
+
run
|
25
|
+
end
|
26
|
+
|
27
|
+
config.join
|
28
|
+
|
29
|
+
|
@@ -0,0 +1,294 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.dirname(__FILE__) + "/../../lib"
|
4
|
+
require 'rubygems'
|
5
|
+
require_gem 'camping', '>=1.4'
|
6
|
+
require 'camping/session'
|
7
|
+
|
8
|
+
Camping.goes :Blog
|
9
|
+
|
10
|
+
module Blog
|
11
|
+
include Camping::Session
|
12
|
+
end
|
13
|
+
|
14
|
+
module Blog::Models
|
15
|
+
def self.schema(&block)
|
16
|
+
@@schema = block if block_given?
|
17
|
+
@@schema
|
18
|
+
end
|
19
|
+
|
20
|
+
class Post < Base; belongs_to :user; end
|
21
|
+
class Comment < Base; belongs_to :user; end
|
22
|
+
class User < Base; end
|
23
|
+
end
|
24
|
+
|
25
|
+
Blog::Models.schema do
|
26
|
+
create_table :blog_posts, :force => true do |t|
|
27
|
+
t.column :id, :integer, :null => false
|
28
|
+
t.column :user_id, :integer, :null => false
|
29
|
+
t.column :title, :string, :limit => 255
|
30
|
+
t.column :body, :text
|
31
|
+
end
|
32
|
+
create_table :blog_users, :force => true do |t|
|
33
|
+
t.column :id, :integer, :null => false
|
34
|
+
t.column :username, :string
|
35
|
+
t.column :password, :string
|
36
|
+
end
|
37
|
+
create_table :blog_comments, :force => true do |t|
|
38
|
+
t.column :id, :integer, :null => false
|
39
|
+
t.column :post_id, :integer, :null => false
|
40
|
+
t.column :username, :string
|
41
|
+
t.column :body, :text
|
42
|
+
end
|
43
|
+
execute "INSERT INTO blog_users (username, password) VALUES ('admin', 'camping')"
|
44
|
+
end
|
45
|
+
|
46
|
+
module Blog::Controllers
|
47
|
+
class Index < R '/'
|
48
|
+
def get
|
49
|
+
@posts = Post.find :all
|
50
|
+
render :index
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Add
|
55
|
+
def get
|
56
|
+
unless @state.user_id.blank?
|
57
|
+
@user = User.find @state.user_id
|
58
|
+
@post = Post.new
|
59
|
+
end
|
60
|
+
render :add
|
61
|
+
end
|
62
|
+
def post
|
63
|
+
post = Post.create :title => input.post_title, :body => input.post_body,
|
64
|
+
:user_id => @state.user_id
|
65
|
+
redirect View, post
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Info < R '/info/(\d+)', '/info/(\w+)/(\d+)', '/info', '/info/(\d+)/(\d+)/(\d+)/([\w-]+)'
|
70
|
+
def get(*args)
|
71
|
+
div do
|
72
|
+
code args.inspect; br; br
|
73
|
+
code ENV.inspect; br
|
74
|
+
code "Link: #{R(Info, 1, 2)}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class View < R '/view/(\d+)'
|
80
|
+
def get post_id
|
81
|
+
@post = Post.find post_id
|
82
|
+
@comments = Models::Comment.find :all, :conditions => ['post_id = ?', post_id]
|
83
|
+
render :view
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Edit < R '/edit/(\d+)', '/edit'
|
88
|
+
def get post_id
|
89
|
+
unless @state.user_id.blank?
|
90
|
+
@user = User.find @state.user_id
|
91
|
+
end
|
92
|
+
@post = Post.find post_id
|
93
|
+
render :edit
|
94
|
+
end
|
95
|
+
|
96
|
+
def post
|
97
|
+
@post = Post.find input.post_id
|
98
|
+
@post.update_attributes :title => input.post_title, :body => input.post_body
|
99
|
+
redirect View, @post
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Comment
|
104
|
+
def post
|
105
|
+
Models::Comment.create(:username => input.post_username,
|
106
|
+
:body => input.post_body, :post_id => input.post_id)
|
107
|
+
redirect View, input.post_id
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class Login
|
112
|
+
def post
|
113
|
+
@user = User.find :first, :conditions => ['username = ? AND password = ?', input.username, input.password]
|
114
|
+
|
115
|
+
if @user
|
116
|
+
@login = 'login success !'
|
117
|
+
@state.user_id = @user.id
|
118
|
+
else
|
119
|
+
@login = 'wrong user name or password'
|
120
|
+
end
|
121
|
+
render :login
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class Logout
|
126
|
+
def get
|
127
|
+
@state.user_id = nil
|
128
|
+
render :logout
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class Style < R '/styles.css'
|
133
|
+
def get
|
134
|
+
@headers["Content-Type"] = "text/css; charset=utf-8"
|
135
|
+
@body = %{
|
136
|
+
body {
|
137
|
+
font-family: Utopia, Georga, serif;
|
138
|
+
}
|
139
|
+
h1.header {
|
140
|
+
background-color: #fef;
|
141
|
+
margin: 0; padding: 10px;
|
142
|
+
}
|
143
|
+
div.content {
|
144
|
+
padding: 10px;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
module Blog::Views
|
152
|
+
|
153
|
+
def layout
|
154
|
+
html do
|
155
|
+
head do
|
156
|
+
title 'blog'
|
157
|
+
link :rel => 'stylesheet', :type => 'text/css',
|
158
|
+
:href => '/styles.css', :media => 'screen'
|
159
|
+
end
|
160
|
+
body do
|
161
|
+
h1.header { a 'blog', :href => R(Index) }
|
162
|
+
div.content do
|
163
|
+
self << yield
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def index
|
170
|
+
if @posts.empty?
|
171
|
+
p 'No posts found.'
|
172
|
+
p { a 'Add', :href => R(Add) }
|
173
|
+
else
|
174
|
+
for post in @posts
|
175
|
+
_post(post)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def login
|
181
|
+
p { b @login }
|
182
|
+
p { a 'Continue', :href => R(Add) }
|
183
|
+
end
|
184
|
+
|
185
|
+
def logout
|
186
|
+
p "You have been logged out."
|
187
|
+
p { a 'Continue', :href => R(Index) }
|
188
|
+
end
|
189
|
+
|
190
|
+
def add
|
191
|
+
if @user
|
192
|
+
_form(post, :action => R(Add))
|
193
|
+
else
|
194
|
+
_login
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def edit
|
199
|
+
if @user
|
200
|
+
_form(post, :action => R(Edit))
|
201
|
+
else
|
202
|
+
_login
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def view
|
207
|
+
_post(post)
|
208
|
+
|
209
|
+
p "Comment for this post:"
|
210
|
+
for c in @comments
|
211
|
+
h1 c.username
|
212
|
+
p c.body
|
213
|
+
end
|
214
|
+
|
215
|
+
form :action => R(Comment), :method => 'post' do
|
216
|
+
label 'Name', :for => 'post_username'; br
|
217
|
+
input :name => 'post_username', :type => 'text'; br
|
218
|
+
label 'Comment', :for => 'post_body'; br
|
219
|
+
textarea :name => 'post_body' do; end; br
|
220
|
+
input :type => 'hidden', :name => 'post_id', :value => post.id
|
221
|
+
input :type => 'submit'
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# partials
|
226
|
+
def _login
|
227
|
+
form :action => R(Login), :method => 'post' do
|
228
|
+
label 'Username', :for => 'username'; br
|
229
|
+
input :name => 'username', :type => 'text'; br
|
230
|
+
|
231
|
+
label 'Password', :for => 'password'; br
|
232
|
+
input :name => 'password', :type => 'text'; br
|
233
|
+
|
234
|
+
input :type => 'submit', :name => 'login', :value => 'Login'
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def _post(post)
|
239
|
+
h1 post.title
|
240
|
+
p post.body
|
241
|
+
p do
|
242
|
+
a "Edit", :href => R(Edit, post)
|
243
|
+
a "View", :href => R(View, post)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def _form(post, opts)
|
248
|
+
p do
|
249
|
+
text "You are logged in as #{@user.username} | "
|
250
|
+
a 'Logout', :href => R(Logout)
|
251
|
+
end
|
252
|
+
form({:method => 'post'}.merge(opts)) do
|
253
|
+
label 'Title', :for => 'post_title'; br
|
254
|
+
input :name => 'post_title', :type => 'text',
|
255
|
+
:value => post.title; br
|
256
|
+
|
257
|
+
label 'Body', :for => 'post_body'; br
|
258
|
+
textarea post.body, :name => 'post_body'; br
|
259
|
+
|
260
|
+
input :type => 'hidden', :name => 'post_id', :value => post.id
|
261
|
+
input :type => 'submit'
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def Blog.create
|
267
|
+
Camping::Models::Session.create_schema
|
268
|
+
unless Blog::Models::Post.table_exists?
|
269
|
+
ActiveRecord::Schema.define(&Blog::Models.schema)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
if __FILE__ == $0
|
274
|
+
require 'mongrel/camping'
|
275
|
+
|
276
|
+
Blog::Models::Base.establish_connection :adapter => 'sqlite3', :database => 'blog.db'
|
277
|
+
Blog::Models::Base.logger = Logger.new('camping.log')
|
278
|
+
Blog::Models::Base.threaded_connections=false
|
279
|
+
Blog.create
|
280
|
+
|
281
|
+
# Use the Configurator as an example rather than Mongrel::Camping.start
|
282
|
+
config = Mongrel::Configurator.new :host => "0.0.0.0" do
|
283
|
+
listener :port => 3002 do
|
284
|
+
uri "/blog", :handler => Mongrel::Camping::CampingHandler.new(Blog)
|
285
|
+
uri "/favicon", :handler => Mongrel::Error404Handler.new("")
|
286
|
+
trap("INT") { stop }
|
287
|
+
run
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
puts "** Blog example is running at http://localhost:3002/blog"
|
292
|
+
puts "** Default username is `admin', password is `camping'"
|
293
|
+
config.join
|
294
|
+
end
|