rails 0.13.1 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails might be problematic. Click here for more details.

Files changed (86) hide show
  1. data/CHANGELOG +105 -0
  2. data/Rakefile +39 -17
  3. data/bin/breakpointer +2 -2
  4. data/bin/console +2 -22
  5. data/bin/destroy +2 -6
  6. data/bin/generate +2 -6
  7. data/bin/performance/benchmarker +3 -0
  8. data/bin/performance/profiler +3 -0
  9. data/bin/process/reaper +3 -0
  10. data/bin/process/spawner +3 -0
  11. data/bin/process/spinner +3 -0
  12. data/bin/rails +4 -0
  13. data/bin/runner +2 -27
  14. data/bin/server +2 -48
  15. data/configs/apache.conf +8 -0
  16. data/configs/database.yml +8 -8
  17. data/environments/boot.rb +17 -0
  18. data/environments/development.rb +10 -7
  19. data/environments/environment.rb +37 -73
  20. data/environments/production.rb +15 -6
  21. data/environments/test.rb +12 -6
  22. data/fresh_rakefile +6 -198
  23. data/helpers/application.rb +2 -2
  24. data/helpers/application_helper.rb +1 -1
  25. data/helpers/test_helper.rb +6 -19
  26. data/html/javascripts/controls.js +427 -165
  27. data/html/javascripts/dragdrop.js +256 -277
  28. data/html/javascripts/effects.js +766 -277
  29. data/html/javascripts/prototype.js +903 -217
  30. data/html/javascripts/scriptaculous.js +47 -0
  31. data/html/javascripts/slider.js +258 -0
  32. data/html/robots.txt +1 -0
  33. data/lib/binding_of_caller.rb +3 -1
  34. data/lib/breakpoint.rb +5 -5
  35. data/lib/breakpoint_client.rb +1 -1
  36. data/lib/code_statistics.rb +7 -4
  37. data/lib/commands.rb +17 -0
  38. data/lib/commands/breakpointer.rb +1 -0
  39. data/lib/commands/console.rb +22 -0
  40. data/lib/commands/destroy.rb +6 -0
  41. data/lib/commands/generate.rb +6 -0
  42. data/{bin → lib/commands/ncgi}/listener +0 -0
  43. data/{bin → lib/commands/ncgi}/tracker +0 -0
  44. data/lib/commands/performance/benchmarker.rb +26 -0
  45. data/{bin/profiler → lib/commands/performance/profiler.rb} +3 -2
  46. data/lib/commands/process/reaper.rb +130 -0
  47. data/lib/commands/process/spawner.rb +52 -0
  48. data/lib/commands/process/spinner.rb +57 -0
  49. data/lib/commands/runner.rb +27 -0
  50. data/lib/commands/server.rb +59 -0
  51. data/{bin/update → lib/commands/update.rb} +1 -2
  52. data/lib/dispatcher.rb +20 -3
  53. data/lib/fcgi_handler.rb +59 -41
  54. data/lib/initializer.rb +479 -0
  55. data/lib/rails_generator/base.rb +2 -2
  56. data/lib/rails_generator/commands.rb +59 -7
  57. data/lib/rails_generator/generators/applications/app/app_generator.rb +26 -15
  58. data/lib/rails_generator/generators/components/controller/controller_generator.rb +3 -2
  59. data/lib/rails_generator/generators/components/controller/templates/view.rhtml +1 -1
  60. data/lib/rails_generator/generators/components/mailer/USAGE +2 -3
  61. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +1 -1
  62. data/lib/rails_generator/generators/components/migration/migration_generator.rb +3 -1
  63. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +32 -31
  64. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +1 -1
  65. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +1 -1
  66. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +1 -1
  67. data/lib/rails_generator/lookup.rb +3 -3
  68. data/lib/rails_generator/options.rb +1 -0
  69. data/lib/rails_generator/scripts.rb +1 -1
  70. data/lib/rails_version.rb +9 -0
  71. data/lib/railties_path.rb +1 -0
  72. data/lib/rubyprof_ext.rb +1 -1
  73. data/lib/tasks/databases.rake +152 -0
  74. data/lib/tasks/documentation.rake +44 -0
  75. data/lib/tasks/framework.rake +33 -0
  76. data/lib/tasks/javascripts.rake +6 -0
  77. data/lib/tasks/misc.rake +15 -0
  78. data/lib/tasks/rails.rb +7 -0
  79. data/lib/tasks/statistics.rake +16 -0
  80. data/lib/tasks/testing.rake +37 -0
  81. data/lib/test_help.rb +13 -0
  82. data/lib/webrick_server.rb +31 -9
  83. metadata +121 -85
  84. data/bin/benchmarker +0 -19
  85. data/bin/breakpointer_for_gem +0 -4
  86. data/bin/console_sandbox +0 -0
@@ -0,0 +1,9 @@
1
+ module Rails
2
+ module Version #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 14
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ RAILTIES_PATH = File.expand_path(File.dirname(__FILE__))
@@ -1,6 +1,6 @@
1
1
  require 'prof'
2
2
 
3
- module Prof
3
+ module Prof #:nodoc:
4
4
  # Adapted from Shugo Maeda's unprof.rb
5
5
  def self.print_profile(results, io = $stderr)
6
6
  total = results.detect { |i|
@@ -0,0 +1,152 @@
1
+ desc "Migrate the database according to the migrate scripts in db/migrate (only supported on PG/MySQL). A specific version can be targetted with VERSION=x"
2
+ task :migrate => :environment do
3
+ ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
4
+ Rake::Task[:db_schema_dump].invoke if ActiveRecord::Base.schema_format == :ruby
5
+ end
6
+
7
+ desc "Load fixtures into the current environment's database"
8
+ task :load_fixtures => :environment do
9
+ require 'active_record/fixtures'
10
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
11
+ Dir.glob(File.join(RAILS_ROOT, 'test', 'fixtures', '*.yml')).each do |fixture_file|
12
+ Fixtures.create_fixtures('test/fixtures', File.basename(fixture_file, '.*'))
13
+ end
14
+ end
15
+
16
+ desc "Create a db/schema.rb file that can be portably used against any DB supported by AR."
17
+ task :db_schema_dump => :environment do
18
+ require 'active_record/schema_dumper'
19
+ File.open("db/schema.rb", "w") do |file|
20
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
21
+ end
22
+ end
23
+
24
+ desc "Import a schema.rb file into the database."
25
+ task :db_schema_import => :environment do
26
+ file = ENV['SCHEMA'] || "db/schema.rb"
27
+ load file
28
+ end
29
+
30
+ desc "Recreate the test database from the current environment's database schema."
31
+ task :clone_schema_to_test => :db_schema_dump do
32
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
33
+ Rake::Task[:db_schema_import].invoke
34
+ end
35
+
36
+ desc "Dump the database structure to a SQL file"
37
+ task :db_structure_dump => :environment do
38
+ abcs = ActiveRecord::Base.configurations
39
+ case abcs[RAILS_ENV]["adapter"]
40
+ when "mysql", "oci"
41
+ ActiveRecord::Base.establish_connection(abcs[RAILS_ENV])
42
+ File.open("db/#{RAILS_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
43
+ when "postgresql"
44
+ ENV['PGHOST'] = abcs[RAILS_ENV]["host"] if abcs[RAILS_ENV]["host"]
45
+ ENV['PGPORT'] = abcs[RAILS_ENV]["port"].to_s if abcs[RAILS_ENV]["port"]
46
+ ENV['PGPASSWORD'] = abcs[RAILS_ENV]["password"].to_s if abcs[RAILS_ENV]["password"]
47
+ `pg_dump -U "#{abcs[RAILS_ENV]["username"]}" -s -x -O -f db/#{RAILS_ENV}_structure.sql #{abcs[RAILS_ENV]["database"]}`
48
+ when "sqlite", "sqlite3"
49
+ `#{abcs[RAILS_ENV]["adapter"]} #{abcs[RAILS_ENV]["dbfile"]} .schema > db/#{RAILS_ENV}_structure.sql`
50
+ when "sqlserver"
51
+ `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /f db\\#{RAILS_ENV}_structure.sql /q /A /r`
52
+ `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /F db\ /q /A /r`
53
+ else
54
+ raise "Task not supported by '#{abcs["test"]["adapter"]}'"
55
+ end
56
+
57
+ if ActiveRecord::Base.connection.supports_migrations?
58
+ File.open("db/#{RAILS_ENV}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
59
+ end
60
+ end
61
+
62
+ desc "Recreate the test databases from the development structure"
63
+ task :clone_structure_to_test => [ :db_structure_dump, :purge_test_database ] do
64
+ abcs = ActiveRecord::Base.configurations
65
+ case abcs["test"]["adapter"]
66
+ when "mysql"
67
+ ActiveRecord::Base.establish_connection(:test)
68
+ ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
69
+ IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split("\n\n").each do |table|
70
+ ActiveRecord::Base.connection.execute(table)
71
+ end
72
+ when "postgresql"
73
+ ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
74
+ ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
75
+ ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
76
+ `psql -U "#{abcs["test"]["username"]}" -f db/#{RAILS_ENV}_structure.sql #{abcs["test"]["database"]}`
77
+ when "sqlite", "sqlite3"
78
+ `#{abcs["test"]["adapter"]} #{abcs["test"]["dbfile"]} < db/#{RAILS_ENV}_structure.sql`
79
+ when "sqlserver"
80
+ `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql`
81
+ when "oci",
82
+ ActiveRecord::Base.establish_connection(:test)
83
+ IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split(";\n\n").each do |ddl|
84
+ ActiveRecord::Base.connection.execute(ddl)
85
+ end
86
+ else
87
+ raise "Task not supported by '#{abcs["test"]["adapter"]}'"
88
+ end
89
+ end
90
+
91
+ desc "Empty the test database"
92
+ task :purge_test_database => :environment do
93
+ abcs = ActiveRecord::Base.configurations
94
+ case abcs["test"]["adapter"]
95
+ when "mysql"
96
+ ActiveRecord::Base.establish_connection(:test)
97
+ ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"])
98
+ when "postgresql"
99
+ ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
100
+ ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
101
+ ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
102
+ `dropdb -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}`
103
+ `createdb -T template0 -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}`
104
+ when "sqlite","sqlite3"
105
+ File.delete(abcs["test"]["dbfile"]) if File.exist?(abcs["test"]["dbfile"])
106
+ when "sqlserver"
107
+ dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-')
108
+ `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}`
109
+ `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql`
110
+ when "oci"
111
+ ActiveRecord::Base.establish_connection(:test)
112
+ ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
113
+ ActiveRecord::Base.connection.execute(ddl)
114
+ end
115
+ else
116
+ raise "Task not supported by '#{abcs["test"]["adapter"]}'"
117
+ end
118
+ end
119
+
120
+ def prepare_test_database_task
121
+ {:sql => :clone_structure_to_test,
122
+ :ruby => :clone_schema_to_test}[ActiveRecord::Base.schema_format]
123
+ end
124
+
125
+ desc 'Prepare the test database and load the schema'
126
+ task :prepare_test_database => :environment do
127
+ Rake::Task[prepare_test_database_task].invoke
128
+ end
129
+
130
+ desc "Creates a sessions table for use with CGI::Session::ActiveRecordStore"
131
+ task :create_sessions_table => :environment do
132
+ raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
133
+
134
+ ActiveRecord::Base.connection.create_table :sessions do |t|
135
+ t.column :session_id, :string
136
+ t.column :data, :text
137
+ t.column :updated_at, :datetime
138
+ end
139
+
140
+ ActiveRecord::Base.connection.add_index :sessions, :session_id
141
+ end
142
+
143
+ desc "Drop the sessions table"
144
+ task :drop_sessions_table => :environment do
145
+ raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
146
+
147
+ ActiveRecord::Base.connection.drop_table :sessions
148
+ end
149
+
150
+ desc "Drop and recreate the session table (much faster than 'DELETE * FROM sessions')"
151
+ task :purge_sessions_table => [ :drop_sessions_table, :create_sessions_table ] do
152
+ end
@@ -0,0 +1,44 @@
1
+ desc "Generate documentation for the application"
2
+ Rake::RDocTask.new("appdoc") { |rdoc|
3
+ rdoc.rdoc_dir = 'doc/app'
4
+ rdoc.title = "Rails Application Documentation"
5
+ rdoc.options << '--line-numbers --inline-source'
6
+ rdoc.rdoc_files.include('doc/README_FOR_APP')
7
+ rdoc.rdoc_files.include('app/**/*.rb')
8
+ }
9
+
10
+ desc "Generate documentation for the Rails framework"
11
+ Rake::RDocTask.new("apidoc") { |rdoc|
12
+ rdoc.rdoc_dir = 'doc/api'
13
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
14
+ rdoc.title = "Rails Framework Documentation"
15
+ rdoc.options << '--line-numbers --inline-source'
16
+ rdoc.rdoc_files.include('README')
17
+ rdoc.rdoc_files.include('CHANGELOG')
18
+ rdoc.rdoc_files.include('vendor/rails/railties/CHANGELOG')
19
+ rdoc.rdoc_files.include('vendor/rails/railties/MIT-LICENSE')
20
+ rdoc.rdoc_files.include('vendor/rails/activerecord/README')
21
+ rdoc.rdoc_files.include('vendor/rails/activerecord/CHANGELOG')
22
+ rdoc.rdoc_files.include('vendor/rails/activerecord/lib/active_record/**/*.rb')
23
+ rdoc.rdoc_files.exclude('vendor/rails/activerecord/lib/active_record/vendor/*')
24
+ rdoc.rdoc_files.include('vendor/rails/actionpack/README')
25
+ rdoc.rdoc_files.include('vendor/rails/actionpack/CHANGELOG')
26
+ rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_controller/**/*.rb')
27
+ rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_view/**/*.rb')
28
+ rdoc.rdoc_files.include('vendor/rails/actionmailer/README')
29
+ rdoc.rdoc_files.include('vendor/rails/actionmailer/CHANGELOG')
30
+ rdoc.rdoc_files.include('vendor/rails/actionmailer/lib/action_mailer/base.rb')
31
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/README')
32
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/CHANGELOG')
33
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service.rb')
34
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/*.rb')
35
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/api/*.rb')
36
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/client/*.rb')
37
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/container/*.rb')
38
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/dispatcher/*.rb')
39
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/protocol/*.rb')
40
+ rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/support/*.rb')
41
+ rdoc.rdoc_files.include('vendor/rails/activesupport/README')
42
+ rdoc.rdoc_files.include('vendor/rails/activesupport/CHANGELOG')
43
+ rdoc.rdoc_files.include('vendor/rails/activesupport/lib/active_support/**/*.rb')
44
+ }
@@ -0,0 +1,33 @@
1
+ desc "Lock this application to the current gems (by unpacking them into vendor/rails)"
2
+ task :freeze_gems do
3
+ rm_rf "vendor/rails"
4
+ mkdir_p "vendor/rails"
5
+
6
+ for gem in %w( actionpack activerecord actionmailer activesupport actionwebservice )
7
+ system "cd vendor/rails; gem unpack #{gem}"
8
+ FileUtils.mv(Dir.glob("vendor/rails/#{gem}*").first, "vendor/rails/#{gem}")
9
+ end
10
+
11
+ system "cd vendor/rails; gem unpack rails"
12
+ FileUtils.mv(Dir.glob("vendor/rails/rails*").first, "vendor/rails/railties")
13
+ end
14
+
15
+ desc "Lock this application to the Edge Rails (by exporting from Subversion)"
16
+ task :freeze_edge do
17
+ $stderr.close
18
+ svn_available = `svn --version`.size > 0
19
+ raise "Subversion is not installed" unless svn_available
20
+
21
+ rm_rf "vendor/rails"
22
+ mkdir_p "vendor/rails"
23
+
24
+ for framework in %w( railties actionpack activerecord actionmailer activesupport actionwebservice )
25
+ mkdir_p "vendor/rails/#{framework}"
26
+ system "svn export http://dev.rubyonrails.org/svn/rails/trunk/#{framework}/lib vendor/rails/#{framework}/lib"
27
+ end
28
+ end
29
+
30
+ desc "Unlock this application from freeze of gems or edge and return to a fluid use of system gems"
31
+ task :unfreeze_rails do
32
+ rm_rf "vendor/rails"
33
+ end
@@ -0,0 +1,6 @@
1
+
2
+ desc "Update your javascripts from your current rails install."
3
+ task :update_javascripts do
4
+ require 'railties_path'
5
+ FileUtils.cp(Dir[RAILTIES_PATH + '/../html/javascripts/*.js'], RAILS_ROOT + '/public/javascripts/')
6
+ end
@@ -0,0 +1,15 @@
1
+ desc "Run all the tests on a fresh test database"
2
+ task :default => [ :test_units, :test_functional ]
3
+
4
+ task :environment do
5
+ require(File.join(RAILS_ROOT, 'config', 'environment'))
6
+ end
7
+
8
+
9
+ desc "Clears all *.log files in log/"
10
+ task :clear_logs do
11
+ FileList["log/*.log"].each do |log_file|
12
+ f = File.open(log_file, "w")
13
+ f.close
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ $VERBOSE = nil
2
+
3
+ # Load Rails rakefile extensions
4
+ Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext }
5
+
6
+ # Load any custom rakefile extensions
7
+ Dir["./lib/tasks/**/*.rake"].each { |ext| load ext }
@@ -0,0 +1,16 @@
1
+ STATS_DIRECTORIES = [
2
+ %w(Helpers app/helpers),
3
+ %w(Controllers app/controllers),
4
+ %w(APIs app/apis),
5
+ %w(Components components),
6
+ %w(Functional\ tests test/functional),
7
+ %w(Models app/models),
8
+ %w(Unit\ tests test/unit),
9
+ %w(Libraries lib/)
10
+ ].collect { |name, dir| [ name, "#{RAILS_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) }
11
+
12
+ desc "Report code statistics (KLOCs, etc) from the application"
13
+ task :stats do
14
+ require 'code_statistics'
15
+ CodeStatistics.new(*STATS_DIRECTORIES).to_s
16
+ end
@@ -0,0 +1,37 @@
1
+ TEST_CHANGES_SINCE = Time.now - 600
2
+
3
+ # Look up tests for recently modified sources.
4
+ def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago)
5
+ FileList[source_pattern].map do |path|
6
+ if File.mtime(path) > touched_since
7
+ test = "#{test_path}/#{File.basename(path, '.rb')}_test.rb"
8
+ test if File.exists?(test)
9
+ end
10
+ end.compact
11
+ end
12
+
13
+ desc 'Test recent changes'
14
+ Rake::TestTask.new(:recent => [ :prepare_test_database ]) do |t|
15
+ since = TEST_CHANGES_SINCE
16
+ touched = FileList['test/**/*_test.rb'].select { |path| File.mtime(path) > since } +
17
+ recent_tests('app/models/*.rb', 'test/unit', since) +
18
+ recent_tests('app/controllers/*.rb', 'test/functional', since)
19
+
20
+ t.libs << 'test'
21
+ t.verbose = true
22
+ t.test_files = touched.uniq
23
+ end
24
+
25
+ desc "Run the unit tests in test/unit"
26
+ Rake::TestTask.new(:test_units => [ :prepare_test_database ]) do |t|
27
+ t.libs << "test"
28
+ t.pattern = 'test/unit/**/*_test.rb'
29
+ t.verbose = true
30
+ end
31
+
32
+ desc "Run the functional tests in test/functional"
33
+ Rake::TestTask.new(:test_functional => [ :prepare_test_database ]) do |t|
34
+ t.libs << "test"
35
+ t.pattern = 'test/functional/**/*_test.rb'
36
+ t.verbose = true
37
+ end
@@ -0,0 +1,13 @@
1
+ require 'application'
2
+
3
+ require 'test/unit'
4
+ require 'active_record/fixtures'
5
+ require 'action_controller/test_process'
6
+ require 'action_web_service/test_invoke'
7
+ require 'breakpoint'
8
+
9
+ Test::Unit::TestCase.fixture_path = RAILS_ROOT + "/test/fixtures/"
10
+
11
+ def create_fixtures(*table_names)
12
+ Fixtures.create_fixtures(RAILS_ROOT + "/test/fixtures", table_names)
13
+ end
@@ -10,7 +10,7 @@ ABSOLUTE_RAILS_ROOT = File.expand_path(RAILS_ROOT)
10
10
 
11
11
  ActiveRecord::Base.threaded_connections = false
12
12
 
13
- class CGI
13
+ class CGI #:nodoc:
14
14
  def stdinput
15
15
  @stdin || $stdin
16
16
  end
@@ -40,13 +40,25 @@ class CGI
40
40
  end
41
41
  end
42
42
 
43
+ # A custom dispatch servlet for use with WEBrick. It dispatches requests
44
+ # (using the Rails Dispatcher) to the appropriate controller/action. By default,
45
+ # it restricts WEBrick to a managing a single Rails request at a time, but you
46
+ # can change this behavior by setting ActionController::Base.allow_concurrency
47
+ # to true.
43
48
  class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
44
49
  REQUEST_MUTEX = Mutex.new
45
50
 
51
+ # Start the WEBrick server with the given options, mounting the
52
+ # DispatchServlet at <tt>/</tt>.
46
53
  def self.dispatch(options = {})
47
54
  Socket.do_not_reverse_lookup = true # patch for OS X
48
55
 
49
- server = WEBrick::HTTPServer.new(:Port => options[:port].to_i, :ServerType => options[:server_type], :BindAddress => options[:ip])
56
+ params = { :Port => options[:port].to_i,
57
+ :ServerType => options[:server_type],
58
+ :BindAddress => options[:ip] }
59
+ params[:MimeTypes] = options[:mime_types] if options[:mime_types]
60
+
61
+ server = WEBrick::HTTPServer.new(params)
50
62
  server.mount('/', DispatchServlet, options)
51
63
 
52
64
  trap("INT") { server.shutdown }
@@ -57,14 +69,14 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
57
69
  server.start
58
70
  end
59
71
 
60
- def initialize(server, options)
72
+ def initialize(server, options) #:nodoc:
61
73
  @server_options = options
62
74
  @file_handler = WEBrick::HTTPServlet::FileHandler.new(server, options[:server_root])
63
75
  Dir.chdir(ABSOLUTE_RAILS_ROOT)
64
76
  super
65
77
  end
66
78
 
67
- def service(req, res)
79
+ def service(req, res) #:nodoc:
68
80
  begin
69
81
  unless handle_file(req, res)
70
82
  REQUEST_MUTEX.lock unless ActionController::Base.allow_concurrency
@@ -79,7 +91,7 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
79
91
  end
80
92
  end
81
93
 
82
- def handle_file(req, res)
94
+ def handle_file(req, res) #:nodoc:
83
95
  begin
84
96
  req = req.dup
85
97
  path = req.path.dup
@@ -89,8 +101,8 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
89
101
  path.gsub!('+', ' ') # Unescape + since FileHandler doesn't do so.
90
102
 
91
103
  req.instance_variable_set(:@path_info, path) # Set the modified path...
92
-
93
- @file_handler.send(:service, req, res)
104
+
105
+ @file_handler.send(:service, req, res)
94
106
  return true
95
107
  rescue HTTPStatus::PartialContent, HTTPStatus::NotModified => err
96
108
  res.set_error(err)
@@ -100,7 +112,7 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
100
112
  end
101
113
  end
102
114
 
103
- def handle_dispatch(req, res, origin = nil)
115
+ def handle_dispatch(req, res, origin = nil) #:nodoc:
104
116
  data = StringIO.new
105
117
  Dispatcher.dispatch(
106
118
  CGI.new("query", create_env_table(req, origin), StringIO.new(req.body || "")),
@@ -109,8 +121,10 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
109
121
  )
110
122
 
111
123
  header, body = extract_header_and_body(data)
124
+
125
+ set_charset(header)
112
126
  assign_status(res, header)
113
- res.cookies.concat(header.delete('set-cookie'))
127
+ res.cookies.concat(header.delete('set-cookie') || [])
114
128
  header.each { |key, val| res[key] = val.join(", ") }
115
129
 
116
130
  res.body = body
@@ -138,6 +152,14 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
138
152
 
139
153
  return header, body
140
154
  end
155
+
156
+ def set_charset(header)
157
+ ct = header["content-type"]
158
+ if ct.any? { |x| x =~ /^text\// } && ! ct.any? { |x| x =~ /charset=/ }
159
+ ch = @server_options[:charset] || "UTF-8"
160
+ ct.find { |x| x =~ /^text\// } << ("; charset=" + ch)
161
+ end
162
+ end
141
163
 
142
164
  def assign_status(res, header)
143
165
  if /^(\d+)/ =~ header['status'][0]