Webrick でSSLを使おう

■link_toを使う

 <%= link_to "セキュアページへ",{:action => "questionnaire",:only_path => false, :protocol => 'https://'},:accesskey=>"2" %>

Webrick on SSL
ローカルでSSLのテストをしてみる。
簡単に言うと、普段の場合と同じように、HTTPをポート80で、HTTPSを443で受ける
ようにすれば、httpsの時はポート443を勝手に見てくれる仕組みだ。


ここで、SSLの機能を備えたWebrickを用意する

  #!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/boot'

require 'active_support'
require 'fileutils'

puts "=> Booting WEBrick on SSL..."

%w(cache pids sessions sockets).each { |dir_to_make| 
FileUtils.mkdir_p(File.join(RAILS_ROOT, 'tmp', dir_to_make)) }

require 'webrick'
require 'webrick/https'
require 'optparse'

OPTIONS = {
  :port            => 3500,
  :ip              => "0.0.0.0",
  :environment     => (ENV['RAILS_ENV'] || "development").dup,
  :server_root     => File.expand_path(RAILS_ROOT + "/public/"),
  :server_type     => WEBrick::SimpleServer,
  :charset         => "UTF-8",
  :mime_types      => WEBrick::HTTPUtils::DefaultMimeTypes
}

ARGV.options do |opts|
  script_name = File.basename($0)
  opts.banner = "Usage: ruby #{script_name} [options]"

  opts.separator ""

  opts.on("-p", "--port=port", Integer,
          "Runs Rails on the specified port.",
          "Default: 3000") { |v| OPTIONS[:port] = v }
  opts.on("-b", "--binding=ip", String,
          "Binds Rails to the specified ip.",
          "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v }
  opts.on("-e", "--environment=name", String,
          "Specifies the environment to run this server under 
(test/development/production).",
          "Default: development") { |v| OPTIONS[:environment] = v }
  opts.on("-m", "--mime-types=filename", String,
                  "Specifies an Apache style mime.types configuration file 
to be used for mime types",
                  "Default: none") { |mime_types_file| OPTIONS[:mime_types] 
= WEBrick::HTTPUtils::load_mime_types(mime_types_file) }

  opts.on("-d", "--daemon",
          "Make Rails run as a Daemon (only works if fork is available --  
meaning on *nix)."
          ) { OPTIONS[:server_type] = WEBrick::Daemon }

  opts.on("-c", "--charset=charset", String,
          "Set default charset for output.",
          "Default: UTF-8") { |v| OPTIONS[:charset] = v }

  opts.separator ""

  opts.on("-h", "--help",
          "Show this help message.") { puts opts; exit }

  opts.parse!
end

ENV["RAILS_ENV"] = OPTIONS[:environment]
RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV)

require RAILS_ROOT + "/config/environment"
require 'webrick_server'

OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT)

puts "=> Rails application started on 
http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
puts "=> Ctrl-C to shutdown server; call with --help for options" if 
OPTIONS[:server_type] == WEBrick::SimpleServer

class DispatchServlet
  def self.dispatch(options = {})

      ssl_certificate =<<-EOS
-----BEGIN CERTIFICATE-----
MIIEhDCCA+2gAwIBAgIQDVDh7i3vBBVHizy/FJ0kSTANBgkqhkiG9w0BAQUFADCB
5zELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZGT1IgVEVTVCBQVVJQT1NFUyBPTkxZMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMUMwQQYDVQQLEzpUZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93d3cu
dmVyaXNpZ24uY29tL2Nwcy90ZXN0Y2EvIChjKTA3MTgwNgYDVQQDEy9WZXJpU2ln
biBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgMTAyNC1iaXQgVGVzdCBDQTAeFw0wNzA5
MjUwMDAwMDBaFw0wNzEwMDkyMzU5NTlaMIG9MQswCQYDVQQGEwJKUDEOMAwGA1UE
CBMFVG9reW8xDzANBgNVBAcUBk1pbmF0bzEhMB8GA1UEChQYTGl2ZSBSZXZvbHV0
aW9uIENvLixMdGQuMQ4wDAYDVQQLFAVhcml0czE6MDgGA1UECxQxVGVybXMgb2Yg
dXNlIGF0IHd3dy52ZXJpc2lnbi5jb20vY3BzL3Rlc3RjYSAoYykwNTEeMBwGA1UE
AxQVd3d3LmxpdmUtcGFzc3BvcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQD2TNfOINmgZUarNBgikRhPcVqyxBtT50e0I357Wu6wsvsdM6ISAH38sPy5
ZIVCvWuOQjVvK4k/5i1h6Of/k6Tl5uEiNhCUJybNUBdFxaNav9rbksvSGIDjXKX6
0IA6lPRqsKcj+HKCDGcTRLlqbOXR5UHgcubF9lsosFHwe5ZNEQIDAQABo4IBVzCC
AVMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwPQYDVR0fBDYwNDAyoDCgLoYsaHR0
cDovL2NybC52ZXJpc2lnbi5jb20vU1ZSMTAyNFRyaWFsMjAwNy5jcmwwSgYDVR0g
BEMwQTA/BgpghkgBhvhFAQcVMDEwLwYIKwYBBQUHAgEWI2h0dHBzOi8vd3d3LnZl
cmlzaWduLmNvbS9jcHMvdGVzdGNhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjAfBgNVHSMEGDAWgBTpdfZ6RbAM0pvjZ43SRBPUkcR9djBuBggrBgEFBQcB
DARiMGChXqBcMFowWDBWFglpbWFnZS9naWYwITAfMAcGBSsOAwIaBBRLa7kolgYM
u9BSOJsprEsHiyEFGDAmFiRodHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dv
MS5naWYwDQYJKoZIhvcNAQEFBQADgYEAfiPzmYzVmC7zvDkqAnCQEkid9i+7TZU9
x9LMgq2ono2F/B60r1bVFZ2cOBdi1RbLE2TRKgutH/+1Mksg/lrYo6aEub+btIyt
EYqrFFcMwHSCUzilCwKtHvhI8OAmOJOmNg+7wulAcFzUq5jMM5SEwlWQqY1goGOZ
qsjcJYgnWJM=
-----END CERTIFICATE-----
      EOS

      ssl_private_key =<<-EOS
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,ADD16CC93541BCF6

ESZhwkw7ogr12sPp49ntQMxnMCFPAP219VcGfroyHEThX3P+2TYJV0+4rM9WULmg
N+lmOw211RDGunEjHlZw7HyEE9mAuFjuCLx4xhfRiaEEXPZuyUeSDf7gETOrJSLz
Lrdoz+9DWBp21QBXtRtJ4Q6gEY8v0h24/juIdb7uNPSfDbE9J+BWZnojQ3+81qTN
5drd+gZEBu0drQXTg2bFFrt0sVC8I0eWOHdMGe6iboR7QGbm2jU+yHfWEQa8j84l
r2vnYevIWdP53fq1aeGdB0Nu+BFkGLAPzH7OYlo1BSmosE4bFdlw3Y9vYSbkotIy
0P6Ym0YdZDqwCWKWx05cL3MWmyKjUTHv8U9Xtd208KxZWO2fcJrsxRabe3vk9ygF
ciEw63EEtxq5TzxJoatvEogSP/w/walVwQCwmNIjzD8WhkjvOMXO6KzWRg5slULB
pQtnyjlyHkGypbDu1KReAGcucAfQ4CTUaCAAeYmSFJ0vglVPM1vGu+wQB6c39wE5
6bjNrE78Z7LeOhTwBvuHd3OH0enBxY8s4SQxNM0TnlmrbAl8NtlC8WTwDXC6GzAp
alYphxOwNBAbK8EjQ3TqHZt5qIoNgdyUGCp2fUqRg57iXVhMzoZqo+VoDWzlfJcn
cUDTGj23tOlKmZCdAE/hJkaIEgT7rqe1V3D5/nGv3rP7+1a9yGQqF9VSmQrylNDe
EY5I82keZigp8lYeanvQ25wxzWFG6YirmL5d6va9sLZR9l99xAGo4EFNiffo9z9X
5jWHr75kQoOo3zp1MjLiVA++mMXfAt3Wp942x+rZoI4QnZu+Ni+5cA==
-----END RSA PRIVATE KEY-----
      EOS

      Socket.do_not_reverse_lookup = true # patch for OS X

      params = { :Port        => options[:port].to_i,
                 :ServerType  => options[:server_type],
                 :BindAddress => options[:ip],
                 :SSLEnable        => true,
                 :SSLCertificate => 
OpenSSL::X509::Certificate.new(ssl_certificate),
                 :SSLPrivateKey  => OpenSSL::PKey::RSA.new(ssl_private_key)
               }
      params[:MimeTypes] = options[:mime_types] if options[:mime_types]

      server = WEBrick::HTTPServer.new(params)
      server.mount('/', DispatchServlet, options)

      trap("INT") { server.shutdown }

      server.start
  end
end

DispatchServlet.dispatch(OPTIONS)


これを、webrick_sslとして、script下に設置する。これで準備完了。

あとは、Webrickを-p 80、webrick_sslを-p 443で立ち上げる。
assert_redirected_to :protocol => “https://”
とすれば、3600番になるし、--daemon と指定すれば、デーモンとして起動する。
ここらへんは、普通の server コマンドと同じ。

もしこれが動作しないなら、プロンプトを2つ立ち上げて各々で動作させる。

■テスト
テストの場合、これでhttpsリクエストをシミュレートできる。
@request.env["HTTPS"] = "on"

プラグイン
ssl_recuirementが便利

参考:http://d.hatena.ne.jp/elm200/20070428/1177752908