Protecting Static content

Hi,

I want to build a rails backed site which, in addition to some dynamic
content, also comprises a number of static content files. There are
some static html pages, some powerpoint presentations, and some PDF
documents.

I want to make sure that the user is logged in before they can access
the protected content. I’ve gone through the ‘Agile development with
Rails’ depot example, and I can clearly see how to protect dynamic
content by forcing a login in the controller.

Ideally, I would like our web designer put the static content in a
particular tree, like /protected. Then, for any sort of request for a
document in that tree, make sure that the user is logged in first. If
they are, then access should be allowed, otherwise, they should be
directed to login.

New files will be added often, so I don’t want to have to change any
code when new files are simply added to the protected tree, if possible.

Accessing a bookmarked link in the protected tree should still force a
login to occur if the users session is expired.

Seems like this should be a no-brainer, but I’ve been googling about to
no avail. I also picked up a copy of the rails recipe book today,
because one of the recipes is supposed to cover static content, but the
recipe seems only marginally applicable to what I’m trying to do.

How should I proceed?

Thank you.

Regards,
Rich

Rich D. wrote:

Hi,

I want to build a rails backed site which, in addition to some dynamic
content, also comprises a number of static content files. There are
some static html pages, some powerpoint presentations, and some PDF
documents.

I want to make sure that the user is logged in before they can access
the protected content. I’ve gone through the ‘Agile development with
Rails’ depot example, and I can clearly see how to protect dynamic
content by forcing a login in the controller.

I do something similar like this:

before_filter :login_required

def get_pdf
requested_file = params[:filename]
source_file = “/protected/#{requested_file}”
if File.exist?(output_file)
send_file “#{output_file}”, :type=>“application/pdf”,
:filename=>"#{output_file}", :stream=>false, :disposition=>“attachment”
end
end

Craig wrote:

Rich D. wrote:

Hi,

I want to build a rails backed site which, in addition to some dynamic
content, also comprises a number of static content files. There are
some static html pages, some powerpoint presentations, and some PDF
documents.

I want to make sure that the user is logged in before they can access
the protected content. I’ve gone through the ‘Agile development with
Rails’ depot example, and I can clearly see how to protect dynamic
content by forcing a login in the controller.

I do something similar like this:

before_filter :login_required

def get_pdf
requested_file = params[:filename]
source_file = “/protected/#{requested_file}”
if File.exist?(output_file)
send_file “#{output_file}”, :type=>“application/pdf”,
:filename=>"#{output_file}", :stream=>false, :disposition=>“attachment”
end
end

Hmm, I played around with this and ran into a few problems.

  1. under webrick, I seem to have to give this an absolute file system
    URL like ‘c:/someplace/somedir/…/myfile.pdf’. Of course, dev and prod
    will be different. Is there any way to figure out where in the file
    system to start?

  2. I somehow have to figure out the mime type for every sort of file
    that the designer might put into the web. I suspect I could just build
    a list and based on the file extension, set the type accordingly. Is
    that the easiest way?

  3. And the showstopper, it gets weird when I attempt to serve an html
    file. In firefox, it prompts the user to download the file, even if I
    set the type to ‘text/html’ and disposition to ‘inline’. It then
    proceeds to display in the browser. Funky. So, I tried to render it,
    but that never works, just get an error that it can’t find the
    render_static.rhtml, which I don’t want to or intend to provide.

Here is the code I am testing with:
config/routes.rb

Static content control

map.connect ‘/protected/*path’, :controller => ‘protected’,
:action => ‘render_static’

app/controllers/protected_controller.rb
class ProtectedController < ApplicationController
before_filter :authorize

def render_static
requested_file = params[:path]

# Ok, I really don't want these to live in public, but under
# protected.  The main ugliness is that I have to give an absolute 

path!
# rails couldn’t find the file via any sort of relative path.
mypath = “c:/documents and settings/RDuzenbury.Panora/My
Documents/Source Code/depot/public”
output_file = “{mypath}/#{requested_file}”

# remove any dots
# I am a noob, because this throws a huge error.  Wonder why!
#requested_file.gsub!(/\./, '')

# compute app type
# This should be some type of table lookup
# And, this render doesn't work!
if requested_file =~ /\.(htm|html)$/ then
  apptype = "text/html"
  render(:file => output_file)
else
  if requested_file =~ /\.pdf$/ then
    apptype = "application/pdf"
  elsif requested_file =~ /\.ppt$/ then
    apptype = 'application/vnd.ms-powerpoint'
  elsif requested_file =~ /\.swf$/ then
    apptype = 'application/x-shockwave-flash'
  else
    apptype = 'octet/stream'
  end
  if File.exist?(output_file)
    send_file output_file,
              :type=> apptype,
              :disposition=>"attachment"
  else
    # hmm, how to throw a 404?
  end
end

end
end

So, it works for things like pdf, ppt, or swf, but doesn’t work for
html.

It also requires absolute paths, which I despise.

Any advice appreciated.

Thanks.

Regards,
Rich

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs