Thanks a lot for the help Ben :)

On Nov 4, 4:07 am, Ben Hoskings <[email protected]> wrote:
> Yeah, it doesn't work without nginx.
>
> (I babushka up nginx and friends in production, and I use the same deps on my 
> MacBook to build my dev stack. But at the moment I'm running things with pow, 
> since I'm not working on an app with any X-Accel-Redirect downloads.)
>
> You could just test that the correct headers are being set - testing nginx's 
> config is outside the scope of your app's suite, and I think if you automate 
> the process of adding the nginx config on production, then you don't need to 
> worry about testing the whole path. IMO YMMV IANAL and so on.
>
> (That's part of the point of babushka: e.g. the nginx vhost deps verify the 
> config is the one you think it is.)
>
> - Ben
>
> On 04/11/2011, at 9:35 AM, markbrown4 wrote:
>
>
>
>
>
>
>
> > Thanks Ben,
>
> > One more question, How does this work in a dev environment without
> > unicorn / nginx ?
> > I'm just running the default "rails s" WEBrick server on dev.
>
> > I'm guessing the answer will be "dev & production should run an
> > identical stack" so you can test / debug these things before deploy.
>
> > Cheers,
>
> > On Nov 4, 9:22 am, Ben Hoskings <[email protected]> wrote:
> >> You should move the files outside of the public/ directory, into something 
> >> like data/ or assets/ at the top level of your app, and serve them through 
> >> authenticated requests with nginx.
>
> >> The way it works is that instead of rails sending the data itself, it adds 
> >> a header to the response containing the filesystem path to the file. The 
> >> header is one that nginx recognises, and it inserts the file data into the 
> >> response.
>
> >> This is far better than serving the file with rails because serving static 
> >> content is what nginx is built to do, extremely fast; doing it with rails 
> >> is really inefficient because you have to load the contents of the file 
> >> into ruby land. It's slow and your rails process' resident size will 
> >> balloon. When nginx serves the content, however, it streams the file from 
> >> disk in the fastest way possible on your OS, using a fixed amount of 
> >> memory no matter how large the file is.
>
> >> You serve them from an internal location in nginx. This is a location that 
> >> isn't accessible publicly, but that nginx will serve from if asked to by 
> >> the upstream. Add something like this to your vhost config (replace 
> >> /assets with the path within your app (outside public/) that you chose for 
> >> the images):
>
> >> location /assets {
> >>   internal;
> >>   root /srv/http/your.app/current; # don't include public/
>
> >> }
>
> >> Then, to serve a file within the action on one of your routes, you just 
> >> set the right headers for nginx, and render an empty response:
>
> >>   def photo
> >>     # The model and paths are totally made up cause I haven't seen your 
> >> app :)
> >>     photo = Photo.find(params[:id])
> >>     x_accel_redirect "/assets/photos/#{photo.id}/#{photo.style}.jpg",
> >>       :disposition => 'attachment',
> >>       :filename => photo.filename,
> >>       :type => photo.content_type
> >>   end
>
> >>   private
>
> >>   # Maybe put this private method in application_controller or
> >>   # in a module if you want to use it in a few different places.
> >>   def x_accel_redirect path, opts
> >>     send_file_headers!({
> >>       :disposition => 'attachment'
> >>     }.merge(opts))
> >>     response.headers['X-Accel-Redirect'] = path
> >>     render :nothing => true
> >>   end
>
> >> There's a way to do this by instructing rails to, using 
> >> "config.action_dispatch.x_sendfile_header", but I can't remember it 
> >> offhand. I prefer to just explicitly set the headers anyway, it's easy and 
> >> there are no shenanigans that way.
>
> >> - Ben
>
> >> On 03/11/2011, at 10:28 PM, markbrown4 wrote:
>
> >>> Yes, the routes were setup so photo's & documents are only accessible
> >>> to logged in users.
> >>> The files are in a /private/ directory.
>
> >>> I'm new to nginx and rails so I need to take baby steps through this
> >>> one.
> >>> If I delete the routes how else can I authenticate and serve the
> >>> images with the headers?
>
> >>> Here's the current config
> >>> --
> >>> server_name <%= var :domain %> <%= var :extra_domains, :default => ''
> >>> %> <%= var :www_aliases %>;
> >>> root <%= var(:app_root) / 'public' %>;
>
> >>> if ($host !~ ^<%= var(:domain).gsub('.', '\.') %>$) {
> >>>  rewrite ^(.*)$ http://<%= var(:domain) %>$1 permanent;
> >>> }
>
> >>> location ~* \.(js|css|jpe?g|png|gif|ico|eot|woff|ttf|swf)$ {
> >>>  if ($request_uri ~ "\?[0-9]+$") {
> >>>    expires max; # cache timestamped assets forever...
> >>>    break;
> >>>  }
> >>>  if ($request_uri !~ "\?[0-9]+$") {
> >>>    expires 1d; # ...and others for 1 day
> >>>    break;
> >>>  }
> >>> }
>
> >>> error_page 503 /system/maintenance.html;
> >>> location /system/maintenance.html { return 503; }
>
> >>> try_files /system/maintenance.html $uri/index.html $uri.html $uri
> >>> @app;
>
> >>> location @app {
> >>>  proxy_pass            http://<%= upstream_name %>;
> >>>  proxy_redirect        off;
>
> >>>  proxy_buffer_size     64k;
> >>>  proxy_buffers         32 16k;
> >>>  client_max_body_size  128m;
>
> >>>  proxy_set_header      Host            $host;
> >>>  proxy_set_header      X-Real-IP       $remote_addr;
> >>>  proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
> >>> }
> >>> --
>
> >>> Here's an example of the current action.
>
> >>> class ResourceController < ActionController::Base
>
> >>>  def resume
> >>>    head(:not_found) and return if (user =
> >>> Person.find_by_id(params[:id])).nil?
> >>>    head(:forbidden) and return unless user.downloadable?
> >>> (current_person)
>
> >>>    path = user.resume.path(params[:style])
>
> >>>    if File.exist? path
> >>>      send_file(path, :type => user.resume.content_type)
> >>>    end
> >>>  end
>
> >>> end
>
> >>> --
>
> >>> Thanks,
>
> >>> On Nov 3, 5:48 pm, Ben Hoskings <[email protected]> wrote:
> >>>> Do you need to serve those assets through the stack? Serving them with 
> >>>> nginx will be orders of magnitude more efficient (i.e. webscale).
>
> >>>> Anything that would otherwise 404 will be passed to your app. If nginx 
> >>>> is serving them then they're present on disk, so I'd delete the routes 
> >>>> and let nginx take care of it :)
>
> >>>> If you want authentication in front of those routes, then you should 
> >>>> move them outside public/, and use the 'X-Accel-Redirect' header to 
> >>>> serve them with nginx on authenticated requests.
>
> >>>> - Ben
>
> >>>> On 03/11/2011, at 11:02 AM, markbrown4 wrote:
>
> >>>>> Hi,
>
> >>>>> We have routes setup for downloading images / documents
>
> >>>>> get  'photo/:id/:style.:format',  :controller => 'resource', :action
> >>>>> => 'photo'
> >>>>> get  'photos/thumb/missing.png',  :controller => 'resource', :action
> >>>>> => 'photo_missing'
> >>>>> get  'resume/:id/:style.:format', :controller => 'resource', :action
> >>>>> => 'resume'
> >>>>> get  'file/:id/:style.:format',   :controller => 'resource', :action
> >>>>> => 'file'
>
> >>>>> Nginx config is skipping the routing though.
>
> >>>>> Do I need to prevent all images from being served directly to resolve
> >>>>> it or is there a better way?
> >>>>> location ~* \.(js|css|jpe?g|png|gif|ico|eot|woff|ttf|swf)$
>
> >>>>> Thanks,
>
> >>>>> --
> >>>>> You received this message because you are subscribed to the Google 
> >>>>> Groups "Ruby or Rails Oceania" group.
> >>>>> To post to this group, send email to [email protected].
> >>>>> To unsubscribe from this group, send email to 
> >>>>> [email protected].
> >>>>> For more options, visit this group 
> >>>>> athttp://groups.google.com/group/rails-oceania?hl=en.
>
> >>> --
> >>> You received this message because you are subscribed to the Google Groups 
> >>> "Ruby or Rails Oceania" group.
> >>> To post to this group, send email to [email protected].
> >>> To unsubscribe from this group, send email to 
> >>> [email protected].
> >>> For more options, visit this group 
> >>> athttp://groups.google.com/group/rails-oceania?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Ruby or Rails Oceania" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to 
> > [email protected].
> > For more options, visit this group 
> > athttp://groups.google.com/group/rails-oceania?hl=en.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
or Rails Oceania" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rails-oceania?hl=en.

Reply via email to