https for rails 2

Posted by Joel Jensen Tue, 28 Aug 2007 05:27:00 GMT

Heres some tips for rails https.

First – use the plugin SslRequirement. But REMEMBER this ONLY works on controllers that are listed in the routes.rb file as RESOURCES

map.resources :blahblah

IE they only work on resources. Period. For non resource controllers, you will have to stick it in the links.

<%= button_to "Checkout", {:action => :checkout,:controller=>"catalog",:protocol=>"https://",:only_path=>false },{}%>

Here is how to use the ssl plugin

ruby script/plugin install ssl_requirement


class ApplicationController < ActiveRecord::Base
    include SslRequirement
end


class AccountController < ApplicationController
    ssl_required :signup, :payment
    ssl_allowed :index

    def signup
      # Non-SSL access will be redirected to SSL
    end

    def payment
      # Non-SSL access will be redirected to SSL
    end

    def index
      # This action will work either with or without SSL
    end

    def other
      # SSL access will be redirected to non-SSL
    end
end

Next Here is a working apache / mongrel config for a https ssl virtualhost. REMEMBER enable proxy, rewrite, and headers in the apache modules stanza

<IfDefine SSL>
<IfDefine !NOSSL>
<VirtualHost 192.168.1.42:443>
    DocumentRoot /srv/www/site-name/current/public
    ServerName www.site-name.com:443
    ServerAdmin webmaster@site-name.com
    ErrorLog /var/log/apache2/site-name.com-error_log
    CustomLog  /var/log/apache2/site-name.com-access_log combined
    HostnameLookups Off
    UseCanonicalName Off
    ServerSignature Off

    SSLEngine on
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL 
    SSLCertificateFile    /etc/apache2/site-name-ssl/www.site-name.com.crt
    SSLCertificateKeyFile /etc/apache2/site-name-ssl/site-name.key
    SSLCertificateChainFile  /etc/apache2/site-name-ssl/gd_intermediate_bundle.crt
    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0

    <Directory "/srv/www/site-name/current/public">
        Options FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>

    RewriteEngine On


    # Don't do forward proxying
    ProxyRequests Off

    # Enable reverse proxying
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>


    RequestHeader set X_FORWARDED_PROTO 'https'

    RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
    RewriteCond %{SCRIPT_FILENAME} !maintenance.html
    RewriteRule ^.*$ /system/maintenance.html [L]

    RewriteRule ^/$ /index.html [QSA] 
    RewriteRule ^([^.]+)$ $1.html [QSA]


    # Redirect all non-static requests to cluster
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
    RewriteRule .* http://127.0.0.1:3000%{REQUEST_URI} [L,P,QSA]

    # Deflate
    AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml application/xml application/xhtml+xml text/javascript 
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

</VirtualHost>                                  

</IfDefine>
</IfDefine>

My pain is your gain.

Nested Java classes from jruby

Posted by Joel Jensen Thu, 02 Aug 2007 17:06:00 GMT

I needed to get at a nested java class from jruby.

It’s tricky. Here’s How I did it

Java class ‘Fonzie’ has a nested public class ‘Hair’

include_class 'com.als.Fonzie'
Hishair = Fonzie::Hair
folicle = Hishair.new(nil)   # if the constructor takes no arguments you must include nil here.

# view that it's really a nested class

folicle.java_class 

# returns com.als.Fonzie$Hair

Send HUGE files from rails

Posted by Joel Jensen Fri, 23 Mar 2007 12:11:00 GMT

I had to send large files with rails, so huge that it was killing rails.

Here is the solution, note the allow-x-send-file NOT allow-x-sendfile, this wasted a few hours of mine.

Make sure that “mod_fastcgi” is in the server.modules stanza of the lighttpd.conf file

Here is the vhosts.conf file

$HTTP["host"] =~ "www.yoursite.com" {
    server.document-root        = base + "/domains/yoursite.com/web/public/"
    server.error-handler-404 = "/dispatch.fcgi"
    compress.filetype        = ( "text/plain", "text/html", "text/css", "text/javascript" )
    compress.cache-dir       = base + "/domains/yoursite.com/web/tmp/cache"
    fastcgi.server = ( ".fcgi" =>
        ( "localhost" =>
            ( "socket" => base + "/var/run/yoursite-0.socket",
                "allow-x-send-file" => "enable",
                "bin-environment"   => ("RAILS_ENV" => "production")
            )
        )
    )
}

rails controller code

def send_this_file
    # this will force rails to read the entire file then stream it out BAD
    #send_file "#{RAILS_ROOT}/public/pdf/#{params[:id]}" , :type => mime_for(params[:id]), :disposition => 'inline', :stream => false

    # this will pass the headers to lighttpd and force it to handle the large static file, rails doesn't read the large file.
    filename = "#{RAILS_ROOT}/public/pdf/#{params[:id]}"
    response.headers['Content-Type'] = "application/force-download"
    response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\"" 
    response.headers["X-LIGHTTPD-send-file"] = filename
    response.headers['Content-length'] = File.size(filename)
    render :nothing => true
end

Restful authentication

Posted by Joel Jensen Sat, 24 Feb 2007 15:11:00 GMT

Set up restful authentication for rails

cd site-root/vendors/plugins
svn export http://svn.techno-weenie.net/projects/plugins/restful_authentication/
cd ../../
script/generate authenticated user sessions --include-activation

# add this line to /config/environment.rb
config.active_record.observers = :user_observer

# add the resource routes in config/routes.rb.  
map.resources :users, :sessions

# activate the changes in the database
rake db:migrate

Non integer ID and rails with ActiveResource

Posted by Joel Jensen Thu, 11 Jan 2007 22:26:00 GMT

I have been fighting with ActiveResource for the last couple of days. Here at work we are using this huge Object Cache to stuff data into. The front end is a rails app that talks to the cache through ActiveResource and REST. The issue I had was that the ID which was returned wasn’t an INT, the cache assigns a UUID as the id. The error kept saying it was in: /vendor/rails/actionpack/lib/action_controller/mime_responds.rb:163:in `respond’ Basicly the mimetype discovery for my controller is hosed with string id’s Broken: respond_to do |format| if @vendor.update_attributes(params[:vendor]) flash[:notice] = ‘Vendor was successfully updated.’ redirect_to edit_vendor_url(@vendor) format.html { redirect_to edit_vendor_url(@vendor) } format.xml { head :ok } else … end Once I changed it to: if @vendor.update_attributes(params[:vendor]) flash[:notice] = ‘Vendor was successfully updated.’ redirect_to edit_vendor_url(@vendor) else … end It worked just fine.

Active Resource on OSX

Posted by Joel Jensen Tue, 19 Dec 2006 17:05:00 GMT

I am making a site which uses an object datastore cache and rails. The only feasable way of getting data to rails is via XML. The simplest way is to use ActiveResource , which is still way way beta.

Here’s how I did it.

from http://reprocessed.org/blog/archives/2006/08/01/active_resource_on_edge.html

You may be tempted to use edge rails

rake rails:freeze:edge

This won’t work, ActiveResource is not included in Edge, only Trunk. Here is how to set up a rails instance that uses ActiveResource.

mkdir -p some_name/vendor; cd some_name
svn co http://dev.rubyonrails.org/svn/rails/trunk vendor/rails
rails .

Then, add this line to your config/environment.rb file, somewhere inside the Rails::Initializer.run do |config| block:

config.load_paths += %W( #{RAILS_ROOT}/vendor/rails/activeresource/lib )

You are running on trunk now, this is the latest version of rails, and may be flakey.

Here is how to use it

From http://weblog.techno-weenie.net/2006/12/13/taking-ares-out-for-a-test-drive

I created two rails sites on my local machine, one is the server. One is the client. ActiveResource needs to be on the client. On the server I made a RESTful site which hooked up to MySQL

Here is the Migration for the database.

class CreateParts < ActiveRecord::Migration
  def self.up
    create_table :parts do |t|
      t.column :date, :date
      t.column :customer, :string
      t.column :customer_part_number, :string
      t.column :manufacturer, :string
      t.column :factory_part_number, :string
      t.column :description, :string
      t.column :cost, :string
      t.column :selling_price, :string
      t.column :notes, :text
    end
  end

  def self.down
    drop_table :parts
  end
end

This command generates the restful scaffolding to view the data.

ruby script/generate scaffold_resource part date:date customer:string customer_part_number:string manufacturer:string factory_part_number:string description:string cost:string selling_price:string notes:text

Then on the client site I did the same. Except there is no database, just the previous classes.

In the Models section on the client, use this as your model for the part
class PartResource < ActiveResource::Base
  self.site = 'http://localhost:3000'
  # site.user = 'username'
  # site.password = 'secret_sauce'
end

class Part < PartResource
end

When I started each server up on a different port, the client can query the server and the server queries the database.

script/server lighttpd -p3000    # server
script/server lighttpd -p3001    # client

Pull up a page at http://localhost:3001/parts/1000 and check it out.

Enjoy

Rails Depot Application "Agile web development in rails" 2

Posted by Joel Jensen Mon, 18 Dec 2006 21:43:42 GMT

I am playing with the various applications in the new rails book. and came upon this issue.

rake db:migrate doesn't work

Solution ( from site root )

rake rails:freeze:edge
rake db:migrate

Yay! it works now.

Web Services on Rails 2

Posted by Joel Jensen Fri, 27 Oct 2006 11:25:37 GMT

Here are some code examples:

I had difficulty consuming a webservice from a currently running server. ( maybe edit concurrent connections might fix this )

Make the site” test” and code it up.

Copy the site to "test2" 

cd test1
script/server --port=3000

cd test2
script/server --port=3001

open http://localhost:3001/ws

Publishing soap webservices from rails

File app:apis:subscription_api

class SubscriptionApi < ActionWebService::API::Base
  api_method :subscribe,:expects=>[:string],:returns=>[:string]
end

File app:controllers:subscription_controller

class SubscriptionController < ApplicationController wsdlservicename ‘subscription’

def subscribe(blib) return “You sent: ” + blib end end

Consuming soap webservices from rails

Here are 3 examples of consuming web services. make a controller called ws The wsdl and api are automaticly generated for you by rails at runtime

require 'soap/wsdlDriver'
class WsController < ApplicationController
    def index
        factory = SOAP::WSDLDriverFactory.new("http://localhost:3000/subscription/wsdl")
        service = factory.create_rpc_driver
        render :text => service.subscribe("hey there")
    end
end

# no require needed
class WsController < ApplicationController
    web_client_api :subscription, :soap, "http://localhost:3000/subscription/api" 
    def index
        render :text => subscription.subscribe("in")
    end
end


# no require needed
class WsController < ApplicationController
    def index
        subscription = ActionWebService::Client::Soap.new(SubscriptionApi,"http://localhost:3000/subscription/api")
        render :text => subscription.subscribe("in")
    end
end

Consuming soap webservices from ruby.

require 'soap/wsdlDriver'
factory = SOAP::WSDLDriverFactory.new("http://localhost:3000/subscription/wsdl")
service = factory.create_rpc_driver
p service.subscribe("hey there")

Poseidon's punishment. The adventures of Ajax

Posted by Joel Jensen Wed, 04 Oct 2006 21:49:11 GMT

I’ve been finishing this rather large, heavy on the ajax rails site. And been nagged by this persistent untraceable bug for the last while.

So I went out for most excellent Thai food. When I came back refreshed, the solution was apparent. It turns out to be a combination of a few things. First off, the bug only appears in IE windows, not Firefox, not Mac. Damn majority of browser users. Hmph.

Anyway. Here is a tip.

When updating a page using inline RJS templates – or – Ajax dynamicly setting form fields from an auto complete use this:

def get_agent_info
    # by converting the :id to an integer I strip out the letters. if the text_field returns "100 joel jensen" the id becomes 100
    @agent = Agent.find(params[:id].to_i)

    # this section does an inline .rjs template
    # I am sending back javascript that will update the required fields to the new values.
    if request.xhr? 
        render :update do |page|
            page << "document.getElementById('appointment_office_phone').value = '#{number_to_phone(@agent.office.office_phone, :area_code => true)}'"
            page << "document.getElementById('appointment_showing_agent_id').value = '#{@agent.id}'"
            page << "document.getElementById('appointment_showingagent').value = '#{@agent.fullname}'"
        end
    else
        render :text => 'javascript update failed.'
    end
end

not this:

def get_agent_info
    # by converting the :id to an integer I strip out the letters. if the text_field returns "100 joel jensen" the id becomes 100
    @agent = Agent.find(params[:id].to_i)

    # this section does an inline .rjs template
    # I am sending back javascript that will update the required fields to the new values.
    if request.xhr? 
        render :update do |page|
            page << "appointment_office_phone'.value = '#{number_to_phone(@agent.office.office_phone, :area_code => true)}'"
            page << "appointment_showing_agent_id'.value = '#{@agent.id}'"
            page << "appointment_showingagent'.value = '#{@agent.fullname}'"
        end
    else
        render :text => 'javascript update failed.'
    end
end

Also– lighttpd will compress javascript files. Great for deployment. However IE will cache these zip files, and prefer them to newer js textfiles. Use webrick for testing on ie or turn off mod_compress on lighty.

Why is this a problem?

I had to upgrade the prototype js files to get the dynamic table rendering ajax stuff to work, cached old versions of prototype were lingering around and messing things up.

I should relax more.

Setting up fastcgi and lighttpd in Fedora Core 5

Posted by Joel Jensen Thu, 21 Sep 2006 20:30:00 GMT

Don’t install the fcgi gem. If you did, run:

gem uninstall fcgi

Install FastCGI

wget http://www.fastcgi.com/dist/fcgi-2.4.0.tar.gz
cd fcgi-2.4.0
./configure
make
sudo make install

Go to the homepage http://raa.ruby-lang.org/project/fcgi

Download the tarball read the README and follow the install instructions

wget http://www.moonwolf.com/ruby/archive/ruby-fcgi-0.8.7.tar.gz
ruby install.rb config -- --with-fcgi-include=/usr/local/include --with-fcgi-lib=/usr/local/lib
ruby install.rb setup
ruby install.rb install

Get lighttpd installed

yum install lighttpd-fastcgi

Set your security level

If your were unfortunate enough to install SeLinux ( Security Enhanced ), I feel your pain.

Go to the “Security level and firewall” settings, disable SeLinux

Configure Lighttpd

Go to rails root. Run “script/server lighttpd” it should fail the first time but it generates a /config/lighttpd.conf file. Use the config/lighttpd.conf, modify it and put in /etc/lighttpd/lighttpd.conf. It didn’t like the cwd part so I hardcoded all paths.

Set lighttpd to start automatically in the “Systems/Services” application

Older posts: 1 2