headius-mongrel 1.1.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/CHANGELOG +21 -0
  2. data/COPYING +55 -0
  3. data/LICENSE +55 -0
  4. data/Manifest +69 -0
  5. data/README +74 -0
  6. data/Rakefile +202 -0
  7. data/TODO +5 -0
  8. data/bin/mongrel_rails +283 -0
  9. data/examples/builder.rb +29 -0
  10. data/examples/camping/README +3 -0
  11. data/examples/camping/blog.rb +294 -0
  12. data/examples/camping/tepee.rb +149 -0
  13. data/examples/httpd.conf +474 -0
  14. data/examples/mime.yaml +3 -0
  15. data/examples/mongrel.conf +9 -0
  16. data/examples/mongrel_simple_ctrl.rb +92 -0
  17. data/examples/mongrel_simple_service.rb +116 -0
  18. data/examples/monitrc +57 -0
  19. data/examples/random_thrash.rb +19 -0
  20. data/examples/simpletest.rb +52 -0
  21. data/examples/webrick_compare.rb +20 -0
  22. data/ext/http11/ext_help.h +14 -0
  23. data/ext/http11/extconf.rb +6 -0
  24. data/ext/http11/http11.c +402 -0
  25. data/ext/http11/http11_parser.c +1221 -0
  26. data/ext/http11/http11_parser.h +49 -0
  27. data/ext/http11/http11_parser.java.rl +170 -0
  28. data/ext/http11/http11_parser.rl +152 -0
  29. data/ext/http11/http11_parser_common.rl +54 -0
  30. data/ext/http11_java/Http11Service.java +13 -0
  31. data/ext/http11_java/org/jruby/mongrel/Http11.java +353 -0
  32. data/ext/http11_java/org/jruby/mongrel/Http11Parser.java +572 -0
  33. data/lib/mongrel.rb +364 -0
  34. data/lib/mongrel/camping.rb +107 -0
  35. data/lib/mongrel/cgi.rb +181 -0
  36. data/lib/mongrel/command.rb +222 -0
  37. data/lib/mongrel/configurator.rb +388 -0
  38. data/lib/mongrel/const.rb +110 -0
  39. data/lib/mongrel/debug.rb +203 -0
  40. data/lib/mongrel/gems.rb +22 -0
  41. data/lib/mongrel/handlers.rb +468 -0
  42. data/lib/mongrel/header_out.rb +28 -0
  43. data/lib/mongrel/http_request.rb +155 -0
  44. data/lib/mongrel/http_response.rb +163 -0
  45. data/lib/mongrel/init.rb +10 -0
  46. data/lib/mongrel/mime_types.yml +616 -0
  47. data/lib/mongrel/rails.rb +192 -0
  48. data/lib/mongrel/stats.rb +89 -0
  49. data/lib/mongrel/tcphack.rb +18 -0
  50. data/lib/mongrel/uri_classifier.rb +76 -0
  51. data/mongrel-public_cert.pem +20 -0
  52. data/mongrel.gemspec +47 -0
  53. data/setup.rb +1585 -0
  54. data/test/mime.yaml +3 -0
  55. data/test/mongrel.conf +1 -0
  56. data/test/test_cgi_wrapper.rb +26 -0
  57. data/test/test_command.rb +86 -0
  58. data/test/test_conditional.rb +107 -0
  59. data/test/test_configurator.rb +88 -0
  60. data/test/test_debug.rb +25 -0
  61. data/test/test_handlers.rb +126 -0
  62. data/test/test_http11.rb +156 -0
  63. data/test/test_redirect_handler.rb +45 -0
  64. data/test/test_request_progress.rb +100 -0
  65. data/test/test_response.rb +127 -0
  66. data/test/test_stats.rb +35 -0
  67. data/test/test_uriclassifier.rb +261 -0
  68. data/test/test_ws.rb +115 -0
  69. data/test/testhelp.rb +79 -0
  70. data/tools/trickletest.rb +45 -0
  71. metadata +199 -0
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+
2
+ v1.2. Rewrite and merge mongrel cluster and mongrel_rails into something small and maintainable. Remove gem_plugin entirely.
3
+
4
+ v1.1.1. See if Java is setting the server version string in the request properly.
5
+
@@ -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
@@ -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,3 @@
1
+ To get these examples running, install Camping.
2
+
3
+ Instructions here: http://code.whytheluckystiff.net/camping/
@@ -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