Jump to content

working under webrick but not under passenger

nesko's Photo
Posted Apr 27 2010 01:59 AM
5839 Views

Hi!

I have just added login feature to my rails application by following the
instructions from "Agile Web Development with Rails" but now I am getting
strange error (looks to me like some kind of routing problem) under the
passenger/apache. It is working fine under webrick.

The error is:
500 Internal Server Error
The server encountered an internal error or misconfiguration and was
unable to complete your request.

From the log:

SQL (0.3ms) SET SQL_AUTO_IS_NULL=0

Processing ****Controller#index (for 192.168.1.101 at 2010-04-26
18:56:24) [GET]
User Columns (1.7ms) SHOW FIELDS FROM `users`
User Load (0.7ms) SELECT * FROM `users` WHERE
(`users`.`id` IS NULL) LIMIT 1
Redirected to https://******/login/login_page
Filter chain halted as [:authorize] rendered_or_redirected.
Completed in 31ms (DB: 3) | 302 Found [https://******/]

Does anybody have any suggestion what I could do to fix this?

--------------------------------------------
class LoginController < ApplicationController

def add_user
@user = User.new(params[:user])
if request.post? and @user.save
flash.now[:notice] = "User #{@user.name} created"
@user = User.new
end
end

def login_page
session[:user_id] = nil
if request.post?
user = User.authenticate(params[:name], params[:password])
if user
session[:user_id] = user.id
session[:user_name] = user.name
uri = session[:original_uri]
session[:original_uri] = nil
redirect_to(uri || { :action => "index" })
else
flash[:notice] = "Invalid user/password combination"
end
end
end

def logout
session[:user_id] = nil
flash[:notice] = "Logged out"
redirect_to(:action => "login_page")
end

def index
end

def delete_user
if request.post?
user = User.find(params[:id])
if User.count == 1
flash[:notice] = "You can't remove last remaining user!"
else
user.destroy
end
end
redirect_to(:action => :list_users)
end

def list_users
@all_users = User.find(:all)
end
end
------------------------------------------

class ApplicationController < ActionController::Base
before_filter :authorize, :except => :login_page
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection
for details
def create_default_variables(ctrl_name)
session[:ctrl_name] = ctrl_name
end
# Scrub sensitive parameters from your log
# filter_parameter_logging :password
private
def authorize
unless User.find_by_id(session[:user_id])
session[:original_uri] = request.request_uri
flash[:notice] = "Please log in"
redirect_to(:controller => "login", :action => "login_page")
end
end
end
------------------------------------------------
require 'digest/sha1'

class User < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
attr_accessor :password_confirmation
validates_confirmation_of :password

def validate
errors.add_to_base("Missing password") if hashed_password.blank?
end

def self.authenticate(name, password)
user = self.find_by_name(name)
if user
expected_password = encrypted_password(password, user.salt)
if user.hashed_password != expected_password
user = nil
end
end
user
end

# 'password' is a virtual attribute
def password
@password
end
def password=(pwd)
@password = pwd
create_new_salt
self.hashed_password = User.encrypted_password(self.password,
self.salt)
end

def after_destroy
if User.count.zero?
raise "Can't delete last user"
end
end

private
def self.encrypted_password(password, salt)
string_to_hash = password + "wibble" + salt # 'wibble' makes it
harder to guess
Digest::SHA1.hexdigest(string_to_hash)
end

def create_new_salt
self.salt = self.object_id.to_s + rand.to_s
end
end
-----------------------------------------
login_page.html.erb

<div class="user-form">
<fieldset>
<legend>Please Log In</legend>
<% form_tag do %>
<p>
<label for="name">Name:</label>
<%= text_field_tag :name, params[:name] %>
</p>
<p>
<label for="password">Password:</label>
<%= password_field_tag :password, params[:password] %>
</p>
<p><%= submit_tag "Login" %></p>
<% end %>
</fieldset>
</div>
-------------------------------------------
routes.rb

ActionController::Routing::Routes.draw do |map|

map.resources :controller1
map.resources :controller2
...

map.root :controller => "controller1"

map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end

-------------------------------------------
and apache log:

[error] [client 192.168.1.101] Request exceeded the limit of 10 internal
redirects due to probable configuration error. Use
'LimitInternalRecursion' to increase the limit if necessary. Use
'LogLevel debug' to get a backtrace.

"LogLevel debug" didn't produce any more information.

Tags:
1 Subscribe


1 Reply

 : Apr 29 2010 04:27 AM
It is definitely routing problem.
I could partially solve the problem by adding this:

map.connect 'login', :controller => 'login', :action => "login_page"
map.connect 'login/list_users', :controller => "login", :action => "list_users"
map.connect 'login/add_user', :controller => "login", :action => "add_user"
map.connect 'login/logout', :controller => "login", :action => "logout"

to the routes.rb and just first line is working.
So redirecting to the <app>/login or typing it directly gives login_page action from the login controller.
The remaining problem is that I still can't use any action directly like /login/list_users or even login/login_page.