瘦,支持SSL和ruby调试



有人知道用Thin同时运行ruby调试器和SSL的方法吗?

我已经在Rails 3.0.10中成功地使用了Thin。

我使用rails server --debugger启动它,并且我可以调试我的代码。

最近,我还需要为我的应用程序添加SSL支持,我希望能够使用自签名证书在本地对其进行测试。

不幸的是,在使用rails server时,我还没有找到一种方法来启动支持SSL的瘦。

我可以通过使用成功启动支持SSL的瘦

thin start --ssl --ssl-verify --ssl-key-file ssllocal/server.key
    --ssl-cert-file ssllocal/server.crt

但是,我还没有找到使用thin start激活调试器的方法。

因此,我似乎可以选择运行调试器(rails server)或SSL(thin start),但不能同时运行两者

似乎可以通过修改rails/脚本文件(请参阅此处),让Webrick使用rails server运行SSL。我尝试过这种方法,但没有成功。以下是其中一个尝试:

#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3
# gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application',  __FILE__)
require File.expand_path('../../config/boot',  __FILE__)

# THIS IS NEW:
require "rails/commands/server"
require 'rack'
require 'thin'
module Rails
  class Server
    def default_options
      super.merge({
        :Port        => 3000,
        :environment => (ENV['RAILS_ENV'] || "development").dup,
        :daemonize   => false,
        :debugger    => false,
        :pid         => File.expand_path("tmp/pids/server.pid"),
        :config      => File.expand_path("config.ru"),
        :SSLEnable   => true
        :ssl => true,
        "ssl-verify" => true,
        "ssl-key-file" => File.expand_path("ssllocal/server.key"),
        "ssl-cert-file" => File.expand_path("ssllocal/server.crt")       
      })
    end
  end
end

require 'rails/commands'

注意:对于那些可能想知道的人,我在根应用程序目录下创建了一个"sslocal"目录,这就是我存储ssl密钥和证书的地方。

您可以尝试在开发环境中只需要调试器。

在您的Gemfile:

if RUBY_VERSION =~ /^1.9/
  gem "ruby-debug19", :group => :development
else
  gem "ruby-debug", :group => :development
end

在config/environments/development.rb:的配置块中

require 'ruby-debug'
Debugger.start

这允许您将调试器语句放置在代码中的任何位置。

这是我的解决方案-我入侵了Thin TcpServer,只在开发环境中加载我的自签名SSL证书。我的script/rails看起来像这样:

#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application',  __FILE__)
require File.expand_path('../../config/boot',  __FILE__)
# Hack our SSL certs into Thin TcpServer, only in development environment
require 'thin'
module Thin
  module Backends
    TcpServer.class_eval do
      def initialize_with_SSL(host, port)
        if Rails.env.development?
          Rails.logger.info "Loading SSL certs from ./ssl_dev..."
          @ssl = true
          @ssl_options = {
            :private_key_file => File.expand_path("../../ssl_dev/server.key", __FILE__),
            :cert_chain_file  => File.expand_path("../../ssl_dev/server.crt", __FILE__),
            :verify_peer => nil
          }
        end
        initialize_without_SSL(host, port)
      end
      alias_method :initialize_without_SSL, :initialize
      alias_method :initialize, :initialize_with_SSL      
    end
  end
end
# Must load 'rails/commands' after Thin SSL hack
require 'rails/commands'

以下是我如何最终使用Thin:进行生产的

rvmsudo thin start -p 443 --ssl --ssl-key-file ssl/server.key --ssl-cert-file ssl/server.crt

如果您的KEY文件有问题,请确保使用以下网站验证CSR:

https://ssl-tools.verisign.com

如果您的CSR失败,那么您从签名机构收到的证书也将失败。我的网站会拒绝加载SSL证书,结果发现我在创建私钥时将州名缩写为"TX"而不是"Texas"。这就是它一直不起作用的原因!SSL证书让人头疼!

使用nathan建议的解决方案,我能够成功地使用启用ssl的瘦版进行调试。尽管在调用initialize_without_ssl(原始TcpServer的initialize的别名方法)之后,我不得不推迟@ssl的初始化

require 'thin'
module Thin
  module Backends
    TcpServer.class_eval do
      def initialize_with_SSL(host, port)
        if Rails.env.development?
          Rails.logger.info "Loading SSL certs from ./ssl_dev..."
          @ssl_options = {
            :private_key_file => File.expand_path("../../ssl_dev/server.key", __FILE__),
            :cert_chain_file  => File.expand_path("../../ssl_dev/server.crt", __FILE__),
            :verify_peer => nil
          }
        end
        initialize_without_SSL(host, port)
        # @ssl initialized after calling the original initialize of TcpServer
        @ssl = true if Rails.env.development? 
      end
      alias_method :initialize_without_SSL, :initialize
      alias_method :initialize, :initialize_with_SSL      
    end
  end
end
  alias_method :initialize_without_SSL, :initialize
  alias_method :initialize, :initialize_with_SSL      
end

在上面的代码snippett中,@ssl在调用Thin::Backend::TcpServer的原始初始化调用后被设置为true。我必须这样做,因为TcpServer调用其父级的initialize(Thin::Backend:Base),将@ssl设置为nil

  #Base initialize method. Thin gem version 1.5.0
  def initialize
    @connections                    = []
    @timeout                        = Server::DEFAULT_TIMEOUT
    @persistent_connection_count    = 0
    @maximum_connections            = Server::DEFAULT_MAXIMUM_CONNECTIONS
    @maximum_persistent_connections = Server::DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS
    @no_epoll                       = false
    @ssl                            = nil
    @threaded                       = nil
  end

正如nathan的代码块中所指出的,整个解决方案似乎是一次破解。在我看来,我对这个片段很满意,因为代码是在env.development的上下文中完成的,最重要的是,它允许在启用ssl的情况下进行调试。

最新更新