working under webrick but not under passenger

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • nesko
    New Member
    • Apr 2010
    • 8

    working under webrick but not under passenger

    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 misconfiguratio n and was
    unable to complete your request.

    From the log:

    SQL (0.3ms) SET SQL_AUTO_IS_NUL L=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_red irected.
    Completed in 31ms (DB: 3) | 302 Found [https://******/]

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

    --------------------------------------------
    class LoginController < ApplicationCont roller

    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.authentica te(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(:ac tion => "login_page ")
    end

    def index
    end

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

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

    class ApplicationCont roller < ActionControlle r::Base
    before_filter :authorize, :except => :login_page
    helper :all # include all helpers, all the time
    protect_from_fo rgery # See ActionControlle r::RequestForge ryProtection
    for details
    def create_default_ variables(ctrl_ name)
    session[:ctrl_name] = ctrl_name
    end
    # Scrub sensitive parameters from your log
    # filter_paramete r_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(:co ntroller => "login", :action => "login_page ")
    end
    end
    end
    ------------------------------------------------
    require 'digest/sha1'

    class User < ActiveRecord::B ase
    validates_prese nce_of :name
    validates_uniqu eness_of :name
    attr_accessor :password_confi rmation
    validates_confi rmation_of :password

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

    def self.authentica te(name, password)
    user = self.find_by_na me(name)
    if user
    expected_passwo rd = encrypted_passw ord(password, user.salt)
    if user.hashed_pas sword != expected_passwo rd
    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_pas sword = User.encrypted_ password(self.p assword,
    self.salt)
    end

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

    private
    def self.encrypted_ password(passwo rd, salt)
    string_to_hash = password + "wibble" + salt # 'wibble' makes it
    harder to guess
    Digest::SHA1.he xdigest(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>Pleas e 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

    ActionControlle r::Routing::Rou tes.draw do |map|

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

    map.root :controller => "controller 1"

    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
    'LimitInternalR ecursion' to increase the limit if necessary. Use
    'LogLevel debug' to get a backtrace.

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

    Update:


    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.
  • improvcornartist
    Recognized Expert Contributor
    • May 2007
    • 303

    #2
    Have you checked your session variables after login to make sure they are saving accurately? If they aren't, it could be redirecting you back and forth between the original uri and login.

    Comment

    • nesko
      New Member
      • Apr 2010
      • 8

      #3
      Thanks for the reply! :)
      Could you please be more specific about where I should check session variables.
      And why doesn't this problem appear with explicit map.connect routes like
      map.connect 'login', :controller => 'login', :action => "login_page "
      I've checked for instance with:
      map.add_user 'add_user', :controller => "login", :action => "add_user"
      with
      <%= link_to 'Add user', add_user_path %>
      This is working with get but not with post.

      Comment

      • improvcornartist
        Recognized Expert Contributor
        • May 2007
        • 303

        #4
        I would check within login_page.
        Code:
        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
              # check here to see what is saved in session variables
              redirect_to(uri || { :action => "index" })
            else
              flash[:notice] = "Invalid user/password combination"
            end
          end
        end
        I'm not really sure why the problem doesn't appear with explicit map.connect routes.

        Comment

        • nesko
          New Member
          • Apr 2010
          • 8

          #5
          The problem is that I (the application) will never even come so far (to the login_page) if I try to use full path:
          <app>/login/login_page
          Just 500 Internal Server Error is shown.
          So the problem appears before any session variable is checked/used and therefor I don't see any point in checking session variables.
          What I could conclude is that there is clear routing problem because for instance
          map.connect 'login/add_user', :controller => "login", :action => "add_user"
          is never triggered or recognized.
          I have checked routes with
          rts = ActionControlle r::Routing::Rou tes
          logger.info(rts .routes)
          and this is the related part:

          ANY /login/ {:controller=>" login", :action=>"login _page"}
          ANY /login/list_users/ {:controller=>" login", :action=>"list_ users"}
          ANY /login/add_user/ {:controller=>" login", :action=>"add_u ser"}
          ANY /login/logout/ {:controller=>" login", :action=>"logou t"}
          but anyhow only first one is working.

          Comment

          • nesko
            New Member
            • Apr 2010
            • 8

            #6
            By the way I'm using session variables in the rest of the application (mostly for the layout/menu things) and those are working fine.

            Comment

            • improvcornartist
              Recognized Expert Contributor
              • May 2007
              • 303

              #7
              Is the line map.root :controller => "controller 1" still in your routes file? If so, does it behave as you think it should? When you try to go to login/add_user, you get the redirect error?

              Comment

              • nesko
                New Member
                • Apr 2010
                • 8

                #8
                Yes it is and it is redirecting to the login_page ... well with this routing in place:

                map.connect 'login', :controller => 'login', :action => "login_page "

                The problem here is that I'm running in test environment and have never got so far to make a proper user I can use to log in (though flash is showing right message so post back is working).
                What I tried was to exclude add_user from before_filter but then I get 500 error when posting back. add_user action is never triggered I guess because my logger comands are not writing anything in the log.

                So post back is trying the /login/add_user path even if it is called by /add_user and routed by

                map.add_user 'add_user', :controller => "login", :action => "add_user"

                Comment

                • nesko
                  New Member
                  • Apr 2010
                  • 8

                  #9
                  Update:

                  Sorry, I have just moved this
                  map.connect 'login/add_user', :controller => "login", :action => "add_user"
                  below
                  map.add_user 'add_user', :controller => "login", :action => "add_user"
                  and now add user is working and I can log in.
                  After that the rest of the application is working too.
                  Even redirect back and forth (to login when not logged in and back to the originated url) is working.

                  Thank you for the assistance because you gave me the idea how to circumvent the problem. I will be able to live with it using map.<action> shortcuts for the non scaffolding paths.
                  Though the problem remains and I would appreciate if you and/or other people can help me solve it completely.

                  Comment

                  • improvcornartist
                    Recognized Expert Contributor
                    • May 2007
                    • 303

                    #10
                    Sorry to keep asking questions. I'm not sure how to debug this one. When you go to add_user, are you passing any params? Does your log show any error details or backtrace?

                    Comment

                    • nesko
                      New Member
                      • Apr 2010
                      • 8

                      #11
                      No problem, I'm really pleased that you are asking questions. Just continue :)

                      Did you read my last post because it makes your first question a bit obsolete (with reordering routing rules I was able to add user and log in).

                      Now some more details how the error is manifested:

                      If I use direct path like /login/add_user I don't get anything in rails log - not a single row though I have config.log_leve l = :debug in environment.rb
                      The only thing I get is the same apache error log message:

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

                      That is why I feel so powerless. There is nothing to go on.
                      I have also posted this on 3 more rails forums but you are the only person (thank you :) ) that gave any response/comment.
                      Last edited by nesko; Apr 29 '10, 03:53 PM. Reason: misspelling

                      Comment

                      • improvcornartist
                        Recognized Expert Contributor
                        • May 2007
                        • 303

                        #12
                        No, I did not see your last post. I must have been writing a response when you posted it. And you are right, it is very hard to debug when it doesn't give you any details. Sounds like there is still something in the routing or redirects that it doesn't like, but I don't see what it would be. Sorry I can't be of more help there.

                        Comment

                        • nesko
                          New Member
                          • Apr 2010
                          • 8

                          #13
                          few last words ...

                          Thank you for all your help.

                          I have also got this list_users.html .erb:
                          Code:
                          <h2>Administrators</h2>
                          <ul>
                          	<% for user in @all_users %>
                          		<li><%= link_to "[X]", { # link_to options
                          					 :controller => 'login',
                          					 :action => 'delete_user',
                          					 :id => user
                          					},
                          					{ # html options
                          					:method => :post,
                          					:confirm => "Really delete #{user.name}?"
                          				} %>
                          			<%= h(user.name) %>
                          		</li>
                          	<% end %>
                          </ul>
                          to work together with this route:
                          Code:
                          map.delete_user 'delete_user', :controller => "login", :action => "delete_user"
                          it is producing links that are in this form:
                          Code:
                          http://<app>/delete_user?id=1
                          and routing is working.
                          In some strange way passenger recognize available routes and adapt the link_to to match them. Some light in the darkness at last :)

                          Comment

                          Working...