Reputation: 13063
I'm trying to run my Ruby Sinatra application in test and production. Here is the main class:
class Main < Sinatra::Application
helpers Sinatra::ContentFor
helpers Sinatra::Partials
helpers Sinatra::Auth
use Rack::Session::Cookie, :secret => 'supersecret' , :expire_after => 360000
set :environment, :production
configure :development do
enable :sessions, :logging, :dump_errors, :inline_templates
enable :methodoverride
set :root, $_APP_PATH
set :static, true
logger = Logger.new($stdout)
end
configure :production do
enable :logging, :dump_errors, :inline_templates
enable :methodoverride
set :root, $_APP_PATH
set :static, true
logger = Logger.new($stdout)
end
get "/2configure" do
haml :'2configure'
end
end
This works for set :environment, :development
, but in "test" and "production" it gives the following error:
!! Unexpected error while processing request: undefined method `bytesize' for nil:NilClass
This is the top part of the stack trace:
NoMethodError - undefined method `bytesize' for nil:NilClass:
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/utils.rb:291:in `bytesize'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/utils.rb:351:in `secure_compare'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/cookie.rb:115:in `unpacked_cookie_data'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/cookie.rb:105:in `extract_session_id'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/abstract/id.rb:43:in `load_session_id!'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/abstract/id.rb:32:in `[]'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/abstract/id.rb:252:in `current_session_id'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/abstract/id.rb:258:in `session_exists?'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/abstract/id.rb:104:in `exists?'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/abstract/id.rb:114:in `load_for_read!'
/home/id833541/.rvm/gems/ruby-1.9.3-p392/gems/rack-1.3.10/lib/rack/session/abstract/id.rb:59:in `[]'
I'm almost certain it's something to do with sessions. For some reason this is a pain in the rectum to get right in Sinatra. I had this problem before but then I got it working by using enable :sessions
. Now even that doesn't work anymore.
I've confirmed that the error occurs when accessing the session. In a HAML file I have:
%p="Welcome #{session[:full_name]}"
Which is empty the first time. But should that give an error?
It happens for any request, even in requests where I don't try to access the session
object, but then there is no stack trace.
I'm using the Thin web server.
Upvotes: 2
Views: 1353
Reputation: 12251
I believe it's because you've got use Rack::Session::Cookie
and enable :sessions
too. Use one or the other (I don't know why both won't work, just that it's one or the other).
By the way, have you tried using https://rubygems.org/gems/encrypted_cookie instead of Cookie? It's more secure.
Quick addendum: I notice you're inheriting from Sinatra::Application
. If you're going to inherit to make a modular app then:
require 'sinatra/base'
class Main < Sinatra::Base
If you want to use it as a classic application then it's just:
require 'sinatra'
# no `class` statement
get "/blah" do # etc
Further to the comments:
If you're using a rackup file and Rack middleware, then this is how I structure an app:
root_of_project/
config.ru # This is just to start up the app via `rackup`.
app/ # This will be the `root` setting in Sinatra
config.rb # This is where the logic of the Rack app lives.
main.rb # This is where your main Sinatra app lives
models/
views/
2configure.haml
public/
require 'rubygems'
require 'bundler'
Bundler.setup(:default) # and anything else you want added in
root = File.expand_path File.dirname(__FILE__)
require File.join( root , "./app/config.rb" )
map "/" do
run MY_APP_NAMESPACE.app
end
require_relative "./main.rb" # Sinatra app
module MY_APP_NAMESPACE
require 'encrypted_cookie'
# standard cookie settings
COOKIE_SETTINGS = {
:path => "/",
:expire_after => 86400, # In seconds, 1 day
:secret => ENV["COOKIE_KEY"], # I load this into the server's environment.
:httponly => true
}
# This gets called in the config.ru. Doing it this way
# makes it easy to include in specs.
def self.app
Rack::Builder.app do
logger = Logger.new($stdout)
cookie_settings = COOKIE_SETTINGS
# more security if in production
cookie_settings.merge!( :secure => true ) if ENV["RACK_ENV"] == "production"
# AES encryption of cookies
use Rack::Session::EncryptedCookie, cookie_settings
# any other Rack middleware I put here.
run Main
end
end
end # module
require 'sinatra/base'
module MY_APP_NAMESPACE
class Main < Sinatra::Base
helpers Sinatra::ContentFor
helpers Sinatra::Partials
helpers Sinatra::Auth
# no need for this here
# use Rack::Session::Cookie, :secret => 'supersecret' , :expire_after => 360000
# no need for this
# set :environment, :production
configure :development do
#enable :sessions, # no need
enable :logging, :dump_errors, :inline_templates
enable :methodoverride
# Sinatra will work this out
# set :root, $_APP_PATH
# set :static, true # no need if you have a public directory
end
configure :production do
enable :dump_errors, :inline_templates
enable :methodoverride
# set :root, $_APP_PATH
# set :static, true
# logger = Logger.new($stdout) # no need for this, as far as I remember
# see http://www.sinatrarb.com/intro#Logging
end
get "/2configure" do
haml :'2configure'
end
end
Hopefully that will give you some ideas to try.
Upvotes: 3
Reputation: 13063
Apparently the problem is within Rack::Session::Cookie
somewhere.
I can use the following instead for now:
use Rack::Session::Pool, :secret => 'super secret' , :expire_after => 360000
But my application is later to be integrated with another one where Rack::Session::Cookie
is currently used.
I would still like to know why Cookie
doesn't work.
Upvotes: 1