I''m looking to do something similar to the "secret URLs" in Rails Recipes, however, with file downloads. I want to avoid providing direct URLs to people if possible. I have files on disk in public/, so it would be good if each user got a "unique" URL to each file that they are permitted to see (dealt with by a user_id/file_id table). Then they are only allowed to download the file if they are logged in and the secret matches. Otherwise, anybody could simply point to http://.../example.pdf and download the file, whether logged in or not. I could do this with redirect_to I believe, but as far as I know that just sends a 3xx redirect to the browser which would point to the real file. Is there any easy way to do this? Cheers. -- Posted via http://www.ruby-forum.com/.
first off, if you don''t want someone to have direct access to the files (ie, http://www.yoursite.com/file1.xyz, where fie1.xyz is stored in the public dir), then don''t store them in public. move them outside of that directory and store the file information (path, name, etc) in the database. second, for a simple example, you could store a hash of the filename/mtime/etc in the database along with the file information. in the controller, make sure you have some sort of security in place that says the person has to be logged in and have access to the file, then you could have a url something like: http://www.yoursite.com/media/download/<hash goes here> so you might have: class MediaController < ApplicationController::Base def download media = Media.find_by_md5_hash(@params[:md5_hash]) unless media.nil? #make sure that the user has permission to get at this file send_file media.filepath else #oops, no file! end end end and your route might be: map.connect "/media/download/:md5_hash", :controller => "media", :action => "download", :md5_hash => /[0-9a-zA-Z]/ On 3/20/06, David <null@example.com> wrote:> > I''m looking to do something similar to the "secret URLs" in Rails > Recipes, however, with file downloads. I want to avoid providing direct > URLs to people if possible. > > I have files on disk in public/, so it would be good if each user got a > "unique" URL to each file that they are permitted to see (dealt with by > a user_id/file_id table). Then they are only allowed to download the > file if they are logged in and the secret matches. Otherwise, anybody > could simply point to http://.../example.pdf and download the file, > whether logged in or not. > > I could do this with redirect_to I believe, but as far as I know that > just sends a 3xx redirect to the browser which would point to the real > file. > > Is there any easy way to do this? > > Cheers. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060320/5105a9ac/attachment-0001.html
What if you don''t place them in public and use a pfd controller with a send_data action to push the image to the browser.. On 3/20/06, David <null@example.com> wrote:> > I''m looking to do something similar to the "secret URLs" in Rails > Recipes, however, with file downloads. I want to avoid providing direct > URLs to people if possible. > > I have files on disk in public/, so it would be good if each user got a > "unique" URL to each file that they are permitted to see (dealt with by > a user_id/file_id table). Then they are only allowed to download the > file if they are logged in and the secret matches. Otherwise, anybody > could simply point to http://.../example.pdf and download the file, > whether logged in or not. > > I could do this with redirect_to I believe, but as far as I know that > just sends a 3xx redirect to the browser which would point to the real > file. > > Is there any easy way to do this? > > Cheers. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Never be afraid to try something new. Remember, amateurs built the ark; professionals built the Titanic! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060320/fddb0210/attachment.html
I you use lighttpd, then I would use mod_secdownload, which does all you want and even more (the generated URLs are only valid for a certain time, you can set) On 3/20/06, David <null@example.com> wrote:> > I''m looking to do something similar to the "secret URLs" in Rails > Recipes, however, with file downloads. I want to avoid providing direct > URLs to people if possible. > > I have files on disk in public/, so it would be good if each user got a > "unique" URL to each file that they are permitted to see (dealt with by > a user_id/file_id table). Then they are only allowed to download the > file if they are logged in and the secret matches. Otherwise, anybody > could simply point to http://.../example.pdf and download the file, > whether logged in or not. > > I could do this with redirect_to I believe, but as far as I know that > just sends a 3xx redirect to the browser which would point to the real > file. > > Is there any easy way to do this? > > Cheers. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Roberto Saccon - http://rsaccon.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060320/df834770/attachment.html
On Mar 20, 2006, at 7:34 AM, Chris Hall wrote:> first off, if you don''t want someone to have direct access to the > files (ie, http://www.yoursite.com/file1.xyz, where fie1.xyz is > stored in the public dir), then don''t store them in public. move > them outside of that directory and store the file information > (path, name, etc) in the database. > > second, for a simple example, you could store a hash of the > filename/mtime/etc in the database along with the file > information. in the controller, make sure you have some sort of > security in place that says the person has to be logged in and have > access to the file, then you could have a url something like: > > http://www.yoursite.com/media/download/<hash goes here> > > so you might have: > > class MediaController < ApplicationController::Base > def download > media = Media.find_by_md5_hash(@params[:md5_hash]) > unless media.nil? > #make sure that the user has permission to get at this file > send_file media.filepath > else > #oops, no file! > end > end > end > > and your route might be: > > map.connect "/media/download/:md5_hash", :controller => > "media", :action => "download", :md5_hash => /[0-9a-zA-Z]/This is a great solution, IMHO. Only question is: Why make a new route? The default route would work just as well, and the hash would end up in param[:id] Never write a line of code if you can avoid it. :-) -- -- Tom Mornini -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060320/84d0b2f8/attachment.html
On Mar 20, 2006, at 10:58 AM, Tom Mornini wrote:>> map.connect "/media/download/:md5_hash", :controller => >> "media", :action => "download", :md5_hash => /[0-9a-zA-Z]/ > > This is a great solution, IMHO. > > Only question is: Why make a new route? > > The default route would work just as well, and the hash would end > up in param[:id] > > Never write a line of code if you can avoid it. :-)Fixing a typo! ...and the hash would end up in params[:id]... P.S. Do not use @params! That directly accesses the params hash, but I''ve heard core team members recommend the params method call to insulate yourself from possible future change to the internal representations. -- -- Tom Mornini
On Mar 20, 2006, at 10:58 AM, Tom Mornini wrote:> On Mar 20, 2006, at 7:34 AM, Chris Hall wrote: > >> first off, if you don''t want someone to have direct access to the >> files (ie, http://www.yoursite.com/file1.xyz, where fie1.xyz is >> stored in the public dir), then don''t store them in public. move >> them outside of that directory and store the file information >> (path, name, etc) in the database. >> >> second, for a simple example, you could store a hash of the >> filename/mtime/etc in the database along with the file >> information. in the controller, make sure you have some sort of >> security in place that says the person has to be logged in and >> have access to the file, then you could have a url something like: >> >> http://www.yoursite.com/media/download/<hash goes here> >> >> so you might have: >> >> class MediaController < ApplicationController::Base >> def download >> media = Media.find_by_md5_hash(@params[:md5_hash]) >> unless media.nil? >> #make sure that the user has permission to get at this file >> send_file media.filepath >> else >> #oops, no file! >> end >> end >> end >> >> and your route might be: >> >> map.connect "/media/download/:md5_hash", :controller => >> "media", :action => "download", :md5_hash => /[0-9a-zA-Z]/ > > This is a great solution, IMHO. > > Only question is: Why make a new route? > > The default route would work just as well, and the hash would end > up in param[:id] > > Never write a line of code if you can avoid it. :-) > > -- > -- Tom MorniniKeep in mind that using send_file like this with large files will ty up one fcgi listsner for each download that is happening for the length of the download. SO if you have five users downloading one large file each then you will have 5 fcgi processes tied up until finished! So mod_secdownload is a good option to look at if you are suing lighttpd. Otherwise you can easily run out of fcgi''s and lock up your whole app! Cheers- -Ezra -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060320/953aade8/attachment.html
On Mar 20, 2006, at 2:09 PM, Ezra Zygmuntowicz wrote:> On Mar 20, 2006, at 10:58 AM, Tom Mornini wrote: > >> On Mar 20, 2006, at 7:34 AM, Chris Hall wrote: >> >>> first off, if you don''t want someone to have direct access to the >>> files (ie, http://www.yoursite.com/file1.xyz, where fie1.xyz is >>> stored in the public dir), then don''t store them in public. move >>> them outside of that directory and store the file information >>> (path, name, etc) in the database. >>> >>> second, for a simple example, you could store a hash of the >>> filename/mtime/etc in the database along with the file >>> information. in the controller, make sure you have some sort of >>> security in place that says the person has to be logged in and >>> have access to the file, then you could have a url something like: >>> >>> http://www.yoursite.com/media/download/<hash goes here> >>> >>> so you might have: >>> >>> class MediaController < ApplicationController::Base >>> def download >>> media = Media.find_by_md5_hash(@params[:md5_hash]) >>> unless media.nil? >>> #make sure that the user has permission to get at this file >>> send_file media.filepath >>> else >>> #oops, no file! >>> end >>> end >>> end >>> >>> and your route might be: >>> >>> map.connect "/media/download/:md5_hash", :controller => >>> "media", :action => "download", :md5_hash => /[0-9a-zA-Z]/ >> >> This is a great solution, IMHO. >> >> Only question is: Why make a new route? >> >> The default route would work just as well, and the hash would end >> up in param[:id] >> >> Never write a line of code if you can avoid it. :-) >> >> -- >> -- Tom Mornini > > Keep in mind that using send_file like this with large files will > ty up one fcgi listsner for each download that is happening for the > length of the download. SO if you have five users downloading one > large file each then you will have 5 fcgi processes tied up until > finished! So mod_secdownload is a good option to look at if you are > suing lighttpd. Otherwise you can easily run out of fcgi''s and lock > up your whole app!If you''re using a front end proxy, this may not be the case. I seem to remember that Apache+mod_proxy allows you to specify the buffer size, and if the buffer was large enough, you could deliver large files into that buffer and free up the backend process quickly. Does anybody know how large Lighttpd''s FCGI buffer is, and whether or not it''s configurable? -- -- Tom Mornini -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060321/835beac3/attachment.html
never heard of mod_secdownload before this. neat. much better than my suggestion! :) kudos. Chris On 3/20/06, Roberto Saccon <rsaccon@gmail.com> wrote:> > I you use lighttpd, then I would use mod_secdownload, which does all you > want and even more (the generated URLs are only valid for a certain time, > you can set) > > On 3/20/06, David <null@example.com> wrote: > > > I''m looking to do something similar to the "secret URLs" in Rails > > Recipes, however, with file downloads. I want to avoid providing direct > > URLs to people if possible. > > > > I have files on disk in public/, so it would be good if each user got a > > "unique" URL to each file that they are permitted to see (dealt with by > > a user_id/file_id table). Then they are only allowed to download the > > file if they are logged in and the secret matches. Otherwise, anybody > > could simply point to http://.../example.pdf and download the file, > > whether logged in or not. > > > > I could do this with redirect_to I believe, but as far as I know that > > just sends a 3xx redirect to the browser which would point to the real > > file. > > > > Is there any easy way to do this? > > > > Cheers. > > > > -- > > Posted via http://www.ruby-forum.com/. > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > > -- > Roberto Saccon - http://rsaccon.com > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060321/8eb4a7ae/attachment.html
On Mar 20, 2006, at 4:20 PM, Tom Mornini wrote:> On Mar 20, 2006, at 2:09 PM, Ezra Zygmuntowicz wrote: > >> On Mar 20, 2006, at 10:58 AM, Tom Mornini wrote: >> >>> On Mar 20, 2006, at 7:34 AM, Chris Hall wrote: >>> >>>> first off, if you don''t want someone to have direct access to >>>> the files (ie, http://www.yoursite.com/file1.xyz, where fie1.xyz >>>> is stored in the public dir), then don''t store them in public. >>>> move them outside of that directory and store the file >>>> information (path, name, etc) in the database. >>>> >>>> second, for a simple example, you could store a hash of the >>>> filename/mtime/etc in the database along with the file >>>> information. in the controller, make sure you have some sort of >>>> security in place that says the person has to be logged in and >>>> have access to the file, then you could have a url something like: >>>> >>>> http://www.yoursite.com/media/download/<hash goes here> >>>> >>>> so you might have: >>>> >>>> class MediaController < ApplicationController::Base >>>> def download >>>> media = Media.find_by_md5_hash(@params[:md5_hash]) >>>> unless media.nil? >>>> #make sure that the user has permission to get at this file >>>> send_file media.filepath >>>> else >>>> #oops, no file! >>>> end >>>> end >>>> end >>>> >>>> and your route might be: >>>> >>>> map.connect "/media/download/:md5_hash", :controller => >>>> "media", :action => "download", :md5_hash => /[0-9a-zA-Z]/ >>> >>> This is a great solution, IMHO. >>> >>> Only question is: Why make a new route? >>> >>> The default route would work just as well, and the hash would end >>> up in param[:id] >>> >>> Never write a line of code if you can avoid it. :-) >>> >>> -- >>> -- Tom Mornini >> >> Keep in mind that using send_file like this with large files will >> ty up one fcgi listsner for each download that is happening for >> the length of the download. SO if you have five users downloading >> one large file each then you will have 5 fcgi processes tied up >> until finished! So mod_secdownload is a good option to look at if >> you are suing lighttpd. Otherwise you can easily run out of fcgi''s >> and lock up your whole app! > > If you''re using a front end proxy, this may not be the case. > > I seem to remember that Apache+mod_proxy allows you to specify the > buffer size, and if the > buffer was large enough, you could deliver large files into that > buffer and free up the > backend process quickly. > > Does anybody know how large Lighttpd''s FCGI buffer is, and whether > or not it''s configurable? > > -- > -- Tom MorniniI''m fairly certain that send_file with lighttpd will just ty up the fcgi proc''s but I would love to be proven wrong. I haven''t seen any options to configure fcgi buffers anywhere. -Ezra -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060321/11467a4a/attachment.html
On Mar 20, 2006, at 4:38 PM, Ezra Zygmuntowicz wrote:> On Mar 20, 2006, at 4:20 PM, Tom Mornini wrote: > >> On Mar 20, 2006, at 2:09 PM, Ezra Zygmuntowicz wrote: >> >>> On Mar 20, 2006, at 10:58 AM, Tom Mornini wrote: >>> >>>> On Mar 20, 2006, at 7:34 AM, Chris Hall wrote: >>>> >>>> This is a great solution, IMHO. >>>> >>>> Only question is: Why make a new route? >>>> >>>> The default route would work just as well, and the hash would >>>> end up in param[:id] >>>> >>>> Never write a line of code if you can avoid it. :-) >>>> >>>> -- >>>> -- Tom Mornini >>> >>> Keep in mind that using send_file like this with large files >>> will ty up one fcgi listsner for each download that is happening >>> for the length of the download. SO if you have five users >>> downloading one large file each then you will have 5 fcgi >>> processes tied up until finished! So mod_secdownload is a good >>> option to look at if you are suing lighttpd. Otherwise you can >>> easily run out of fcgi''s and lock up your whole app! >> >> If you''re using a front end proxy, this may not be the case. >> >> I seem to remember that Apache+mod_proxy allows you to specify the >> buffer size, and if the >> buffer was large enough, you could deliver large files into that >> buffer and free up the >> backend process quickly. >> >> Does anybody know how large Lighttpd''s FCGI buffer is, and whether >> or not it''s configurable? >> >> -- >> -- Tom Mornini > > I''m fairly certain that send_file with lighttpd will just ty up > the fcgi proc''s but I would love to be proven wrong. I haven''t seen > any options to configure fcgi buffers anywhere.I cannot prove this directly, but if Lighty properly implements the FCGI spec as recommended, then the FCGI response should be buffered by the HTTP server: from: http://www.fastcgi.com/devkit/doc/fcgi-spec.html> ...most FastCGI requests will have short response times, with the > Web server providing output buffering if the client is slow.-- -- Tom Mornini -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060321/5f4d27c1/attachment-0001.html
Chris Hall wrote:> first off, if you don''t want someone to have direct access to the files > (ie, > http://www.yoursite.com/file1.xyz, where fie1.xyz is stored in the > public > dir), then don''t store them in public. move them outside of that > directory > and store the file information (path, name, etc) in the database. > > second, for a simple example, you could store a hash of the > filename/mtime/etc in the database along with the file information. in > the > controller, make sure you have some sort of security in place that says > the > person has to be logged in and have access to the file, then you could > have > a url something like: > > http://www.yoursite.com/media/download/<hash goes here> > > so you might have: > > class MediaController < ApplicationController::Base > def download > media = Media.find_by_md5_hash(@params[:md5_hash]) > unless media.nil? > #make sure that the user has permission to get at this file > send_file media.filepath > else > #oops, no file! > end > endThanks very much for this. The site will be very low usage, so it doesn''t matter too much if the process is tied up for a while. I will investigate the other modules suggested too, to see whether they''re easy enough to use for the site. Thanks to everybody who responded, David -- Posted via http://www.ruby-forum.com/.
I''ve written an RSS feed parser/downloader using Ruby and ActiveRecord and http-access2 without Rails. I want this code to always be running in a loop and downloading feeds on a schedule. I started by coding the back-end (downloading feeds and putting the titles, links, and descriptions into a database). Now, I''m wondering, is there an easier way... I suppose it is possible to invoke this code as needed when a user loads a page, however, it seems like it''d be easier if there was a rails front-end that managed the feed urls, but not the actual feed data itself. I guess my question is, can a pure ruby process to handle this perpetual munging of rss data be spawned from within rails? Or is it better to just spawn this back end code and run a database updater in an infinite loop? Does anyone know how Odeo handles this? Tony http://involution.com
On 3/21/06, Tony Perrie <tony@involution.com> wrote:> I guess my question is, can a pure ruby process to handle this perpetual > munging of rss data be spawned from within rails? Or is it better to just > spawn this back end code and run a database updater in an infinite loop? > Does anyone know how Odeo handles this?I think that the wiki page <http://wiki.rubyonrails.com/rails/pages/HowToRunBackgroundJobsInRails> can help you some.> Tony > http://involution.comSincerely, Tom Lieber http://AllTom.com/ http://GadgetLife.org/
If you''re using Apache, mod_auth_token supports the same functionality and interface as mod_secdownload, eg. allowing you to secure and expire downloads without having to pipe the file through your script. http://www.synd.info/downloads/releases/ //Mikael David wrote:> I''m looking to do something similar to the "secret URLs" in Rails > Recipes, however, with file downloads. I want to avoid providing direct > URLs to people if possible. > > I have files on disk in public/, so it would be good if each user got a > "unique" URL to each file that they are permitted to see (dealt with by > a user_id/file_id table). Then they are only allowed to download the > file if they are logged in and the secret matches. Otherwise, anybody > could simply point to http://.../example.pdf and download the file, > whether logged in or not. > > I could do this with redirect_to I believe, but as far as I know that > just sends a 3xx redirect to the browser which would point to the real > file. > > Is there any easy way to do this? > > Cheers.-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
I may be missing something but here is how I may be solving a similar problem for an upcoming problem. Downloading files will be a large part of my application. Have two web servers, mapped to different IP''s. The application server IP: 192.168.2.1 myapp.mydomain.com will use one of the yet-to-be-determined scalable Rails implementations The download server IP: 192.168.2.2 Will use IIS or Apache I''ll use one of the Apache plugins to "expire" certain downloads or, in the case of IIS, will write a simple scheduled task to crawl the site and delete old files. For my purposes, I''m finding it easier to manage downloads on a separate non-Rails server. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
sorry for the noob question, but when you say "logged in" all that means is that you have a session file that is insync with the rails application? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---