Ruby on Rails Webrick server on HTTPS protocol stopped after few hours - ruby-on-rails

I am using the below environments:
Server: Webrick
Rails: 3.2.6
Ruby: 1.9.3p555
I have added the below code in /script/rails :
require 'rails/commands/server'
require 'rack'
require 'webrick'
require 'webrick/https'
if ENV['SSL'] == "true"
module Rails
class Server < ::Rack::Server
def default_options
super.merge({
:Port => 443,
:environment => (ENV['RAILS_ENV'] || "production").dup,
:daemonize => false,
:debugger => false,
:pid => File.expand_path("tmp/pids/server.pid"),
:config => File.expand_path("config.ru"),
:SSLEnable => true,
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
:SSLPrivateKey => OpenSSL::PKey::RSA.new(
File.open("certs/project.key").read),
:SSLCertificate => OpenSSL::X509::Certificate.new(
File.open("certs/project.crt").read),
:SSLCertName => [["CN", WEBrick::Utils::getservername]],
})
end
end
end
end
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
I have added the below line in /config/environments/production.rb:
config.force_ssl = true
Start rails on 80 and 443 both using two different pid:
SSL=true rails s -p 443 -e production
rails s -p 80 -P SERVER2 -e production
Everything is working fine however after 10-12 hours https protocol stop to respond to the browser and even there is nothing add in the log file.
Could you please confirm what is the issue and how could it be corrected?

Related

Starting Faye With Rails Automatically

I am trying to start Faye when starting my rails server. I have a faye.ru file in my app root that looks like:
require 'faye'
faye_server = Faye::RackAdapter.new(:mount => '/queue-listener', :timeout => 45)
run faye_server
And whenever I start my rails server, Faye / thin tries to open on the same port as my rails server. I can add something like:
Thread.new do
system("rackup faye.ru -s thin -E production")
end
into an initializer (found this on SO), but then thin starts on both the rails app port and then the default (9292) port. I think it fails to start on the rails port though. I am just confused about how to start up the thin / faye server on a separate port than the rails server. Any ideas?
You can do the following in development. In production I suggesting implementing it as a standalone server w/monitoring:
if Rails.env.development?
require 'eventmachine'
require 'rack'
require 'thin'
require 'faye'
Faye.logger = Logger.new(Rails.root.join('log/faye.log'))
Faye::WebSocket.load_adapter('thin')
thread = Thread.new do
EM.run {
thin = Rack::Handler.get('thin')
app = Faye::RackAdapter.new(mount: '/faye', timeout: 10)
thin.run(app, :Port => 8000) do |server|
## Set SSL if needed:
# server.ssl_options = {
# :private_key_file => 'path/to/ssl.key',
# :cert_chain_file => 'path/to/ssl.crt'
# }
# server.ssl = true
end
}
end
at_exit { thread.exit }
end

Resque on Heroku Cedar not working

I've been trying to figure what the issue is for couple days now but no luck, I'm running Rails 3.1.3 on Heroku Cedar with Unicorn and using Resque 1.20 for background jobs.
Redis add-on as been added and REDISTOGO_URL set, I have resque.rb initializer as
require 'resque'
Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }
uri = URI.parse(ENV["REDISTOGO_URL"])
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
Resque.redis = REDIS
I also tried
Resque.redis = Redis.connect(:url => ENV['REDISTOGO_URL'])
Also this, from the official RedisToGo site
ENV["REDISTOGO_URL"] ||= "redis://username:password#host:1234/"
uri = URI.parse(ENV["REDISTOGO_URL"])
Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password, :thread_safe => true)
Heroku worker as:
bundle exec rake resque:work QUEUE='*'
Everything works fine locally and in Heroku console; but when I try to queue from Rails
Resque.enqueue(EmailQueue, id)
I get
NoMethodError (undefined method `sadd' for nil:NilClass):
Please any help will be appreciated, thank you.
Figured it out, since I was on Unicorn; I had to set config/unicorn.rb as below to connect or Redis.
after_fork do |server, worker|
# Replace with MongoDB or whatever
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
Rails.logger.info('Connected to ActiveRecord')
end
# If you are using Redis but not Resque, change this
if defined?(Resque)
Resque.redis = ENV['REDISTOGO_URL']
Rails.logger.info('Connected to Redis')
end
end
Hopes this helps someone else.

How to use Rack::URLMap with Rack::Cascade to mount Resque in Rails 2.3

I have been running a rails 2.3 app with a rackup config.ru file to load some grape API middleware.
I recently have a need to run a resque server.
My config.ru is set up like this.
require File.dirname(__FILE__) + '/config/environment'
my_app = Rack::Builder.new do
use Rails::Rack::LogTailer #optional
use Rails::Rack::Static # optional
run ActionController::Dispatcher.new
end
Resque::Server.class_eval do
use Rack::Auth::Basic do |user, password|
begin
if user == "admin" and password == "bandana"
true
else
false
end
end
end
end
run Rack::URLMap.new([
"/" => my_app,
"/resque" => Resque::Server.new
])
run Rack::Cascade.new([
GrapeAPI_entry_1,
GrapeAPI_entry_2,
my_app
])
This doesn't give me the desired effect and I don't know why.
I actually found the answer. It turned out that redis was not running, and yes, you can use cascade with map
My final config.ru looks like this.
re File.dirname(__FILE__) + '/config/environment'
require 'resque/server'
my_app = Rack::Builder.new do
use Rails::Rack::LogTailer #optional
use Rails::Rack::Static # optional
run ActionController::Dispatcher.new
end
Resque::Server.class_eval do
use Rack::Auth::Basic do |user, password|
begin
if user == "admin" and password == "bandana"
true
else
false
end
end
end
end
app = Rack::Builder.new {
use Rails::Rack::Static
map "/resque" do
run Resque::Server
end
map "/" do
run my_app
end
}.to_app
run Rack::Cascade.new([
Grape_API_1,
Grape_API_2,
my_app
])
I recently added similar access to resque on one of my rails servers. It works great -- here is how I did it:
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
require 'resque/server'
run Rack::URLMap.new \
"/" => MyApp::Application,
"/resque" => Resque::Server.new
My app is based on rails 3.2, however. I'm not sure what the difference is in the rack version you're running.
Are you requiring the resque server code?

Thin with SSL support and ruby-debug

Does anyone know of a way to run the ruby debugger and SSL at the same time with Thin?
I've been using Thin successfully with Rails 3.0.10.
I start it using rails server --debugger, and I can debug my code.
Recently, I have also needed to add SSL support to my application, and I'd like to be able to test it locally with a self-signed certificate.
Unfortunately, I have not found a way to start Thin with SSL support when using rails server.
I can successfully start Thin with SSL support by using:
thin start --ssl --ssl-verify --ssl-key-file ssllocal/server.key
--ssl-cert-file ssllocal/server.crt
However, I have not found a way to activate the debugger using thin start.
So it seems like I have the choice of running the debugger (rails server) or SSL (thin start), but not both.
It seems possible to get Webrick to run SSL using rails server by modifying the rails/script file (see here). I experimented with this approach, but I have not had success. Here's one of the attempts:
#!/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'
Note: for those who might be wondering, I created an 'ssllocal' directory off my root application directory, and that's where I store the ssl keys and certs.
You could try just requiring the debugger yourself in your development environment.
In your Gemfile:
if RUBY_VERSION =~ /^1.9/
gem "ruby-debug19", :group => :development
else
gem "ruby-debug", :group => :development
end
And within the config block of your config/environments/development.rb:
require 'ruby-debug'
Debugger.start
This permits you to place the debugger statement anywhere in your code.
Here's my solution - I hacked the Thin TcpServer to load my self-signed SSL certs, only in the development environment. My script/rails looks like this:
#!/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'
Here's how I got it to finally work on production using Thin:
rvmsudo thin start -p 443 --ssl --ssl-key-file ssl/server.key --ssl-cert-file ssl/server.crt
If you are having issues with your KEY file, make sure you validate the CSR by using a site like:
https://ssl-tools.verisign.com
If your CSR fails, then the certificate you receive from your signing authority will fail too.
My site would refuse to load with the SSL certs, only to find out that I abbreviated my State name to "TX" instead of "Texas" while creating my private key. That was the reason it wasn't working all along! SSL certs are a pain in the ass!
I was able to successfully get the debugging working with ssl enabled thin, using the solution suggested by nathan. Though I had to do one small change of deferring initialization of #ssl after the call of initialize_without_ssl (an alias method for the original TcpServer's initialize)
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
In the above code snippett, #ssl is set to true after calling the original initialize call of Thin::Backend::TcpServer. I had to do this since the TcpServer invokes its parent's initialize (Thin::Backend:Base) that sets the #ssl to 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
As noted in nathan's code block, the whole solution appears to be a hack around. In my opinion, I am fine with the snippet considering the code is done within the context of env.development and most importantly it allows debugging with ssl enabled.

Rails send mail with GMail

I am on rails 2.3.5 and have the latest Ruby installed and my application is running well, except, GMail emails.
I am trying to setup my gmail imap connection which has worked previously but now doesnt want to know.
This is my code:
# Be sure to restart your server when you modify this file
# Uncomment below to force Rails into production mode when
# you don't control web/app server and can't set it the proper way
# ENV['RAILS_ENV'] ||= 'production'
# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
Rails::Initializer.run do |config|
# Gems
config.gem "capistrano-ext", :lib => "capistrano"
config.gem "configatron"
# Make Time.zone default to the specified zone, and make Active Record store time values
# in the database in UTC, and return them converted to the specified local zone.
config.time_zone = "London"
# The internationalization framework can be changed to have another default locale (standard is :en) or more load paths.
# All files from config/locales/*.rb,yml are added automatically.
# config.i18n.load_path << Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]
#config.i18n.default_locale = :de
# Your secret key for verifying cookie session data integrity.
# If you change this key, all old sessions will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
config.action_controller.session = {
:session_key => '_base_session',
:secret => '7389ea9180b15f1495a5e73a69a893311f859ccff1ffd0fa2d7ea25fdf1fa324f280e6ba06e3e5ba612e71298d8fbe7f15fd7da2929c45a9c87fe226d2f77347'
}
config.active_record.observers = :user_observer
end
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:default => '%d/%m/%Y')
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(:default => '%d/%m/%Y')
require "will_paginate"
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => 587,
:domain => "XXXXXXXX.XXX",
:authentication => :plain,
:user_name => "XXXXXXXXXX.XXXXXXXXXX.XXX",
:password => "XXXXX"
}
But the above just results in an SMTP auth error in the production log.
I have read varied reports of this not working in Rails 2.2.2 but nothing for 2.3.5, anyone got any ideas?
Thanks,
Danny
Use action mailer optional tls

Resources