Okay. But I am a beginner too, so I don’t know if this is the best way.
I’m assuming the path to your folder is:
/public/files_to_read
class PagesController < ApplicationController
def home
@title = “Home”
end
def get_files
dir_path = ‘public/files_to_read’
Dir.chdir(dir_path) do
@fnames = Dir.glob("*")
end
end
def download
dir_path = ‘public/files_to_read’
fname = params[:fname]
Dir.chdir(dir_path) do
allowed_fnames = Dir.glob("*")
if allowed_fnames.include?(fname)
send_file("#{RAILS_ROOT}/#{dir_path}/#{fname}",
:filename => fname)
else
@title = 'Home'
render 'home'
end
end
end
end
===
Test2App::Application.routes.draw do
root :to => “pages#home”
get ‘pages/get_files’
get ‘pages/download’
===
Pages#home
Find me in app/views/pages/home.html.erb
<%= link_to “Read a file”, {:controller => ‘pages’, :action =>
‘get_files’} %>
===
Pages#get_files
Find me in app/views/pages/get_files.html.erb
Click the file you want to download:
<% @fnames.each do |fname| %>
<%= link_to fname, :controller => 'pages', :action => 'download',
:fname => fname %>
<% end %>
===
<%= @title %>
<%= csrf_meta_tag %>
<%= yield %>
===
http://localhost:3000 => home.html.erb
click on Read file link => get_file.html.erb
click on a filename link => computer downloads the file
The reason for the code:
if allowed_names.include?( )
is to prevent a hacker from going to the page of links, and then instead
of clicking on a link, entering:
http://localhost:3000/pages/download?fname=/path/to/secrets.txt
If you don’t check the fname that the server receives, a hacker can
download any file they want.