Rails: asset 404 when served by apache - ruby-on-rails

I have an API that generate png files.
The user request the generation, and I reply with a path to the generated files.
This is how I generate the URL:
url_for(:controller => :anaction, :action => :download, :path => "#{#relative_dir}/face", :format => 'png'
This yeild an URL that looks like:
http://0.0.0.0:3000/anaction/aging/download/%2FTMP_20161128204315_346482_695%2Fface.png
That should be handled by
def download
send_file "#{Rails.public_path}/#{params[:path]}.#{params[:format]}"
end
According to my route
get '/anaction/aging/download/:path' => 'mpsynthesizer_aging#download'
It works like a charm on my dev environment, on my nginx server, but fail on my apache server.
I get a plain apache HTTP400 error, it seems that the request is never forwarded to rails.
I use rails 4.2.6
Is there something i misunderstood ?

I ended up using
render body: IO.binread(result_file), content_type: "image/png"

Related

Proxy pdf from s3 and render it out inline

I am using dragonfly to handle my attachments and s3 to store the assets.
I know i can serve directly from s3 but my client has locked down internet access so cant access them. So what i need to do is proxy the images through my domain.
data = open(#training_doc.upload.remote_url).read
send_data data, :filename => #training_doc.upload.name
Thats what I have but it doesn't allow me to render it inline (in the tab its self) rather it downloads it which isn't ideal.
I know i can do this to render it inline but this isn't proxied
redirect_to #training_doc.upload.remote_url(:expires => 2.hours.from_now, :query => {'response-content-disposition' => 'inline'})
I know in rails you can use send_file but that only works when you have it in the normal file system
Is their any other ways/ way to achieve this?
The send_data method has a disposition option that can be set to inline:
data = open(#training_doc.upload.remote_url).read
send_data(data,
:filename => #training_doc.upload.name,
:type => 'application/pdf',
:disposition => 'inline'
)

rails paperclip url wrong

Everything is fine, except URL of image it adds GET request to the of link
"/system/users/images/000/000/074/original/e742caf8bdfb1536e39060eb9d10a4ab.jpeg**?2015**"
Because of this, image is not available(even I open it by direct link), if I delete ?2015, everything works good. Why gem is adding to the end of link get request?
I used default :path, :url(in public/system folder)
and this one
:path => ":rails_root/app/assets/images/article_images/:id/:style_:basename.:extension"
:url => "/app/assets/images/article_images/:id/:style_:basename.:extension"
The problem is in both of ways((
Just add :use_timestamp => false to your paperclip configuration.

Image not found in paperclip (No route match [Get])

I am using paperclip for image upload:
I am getting the error:
Started GET "/assets/audios/thumbnails/7/thumb/4_X_4.jpg?1345530644"
for 127.0.0.1 at 2012-08-21 12:03:04 +0530
Served asset /audios/thumbnails/7/thumb/4_X_4.jpg - 404 Not Found (1ms)<br/>
ActionController::RoutingError (No route matches [GET] "/assets/audios/thumbnails/7/thumb/4_X_4.jpg"):<br/>
In my model as:
has_attached_file :thumbnail,
:styles => {:medium => "300x300>", :thumb => "100x100>"},
:url => "assets/:class/:attachment/:id/:style/:basename.:extension",
:path => ":rails_root/assets/:class/:attachment/:id/:style/:basename.:extension"
This
:url => "assets/...",
:path => ":rails_root/assets/..."
should be
:url => "/assets/...",
:path => ":rails_root/public/assets/..."
Although it's a terrible idea to save attachments in the assets dir. You can have another, like files inside public:
:url => "/files/:class/:attachment/:id/:style/:basename.:extension",
:path => ":rails_root/public/files/:class/:attachment/:id/:style/:basename.:extension"
Saving inside public/files and using /files url will make the webserver hit the files before rails (of course, correctly configuring your web server, e.g. nginx, is another issue)
I found the correct solution after searching on web continuously. I tried to handle this problem by all probabilities which I could think of like:- permissions, correcting paths,changing server from webrick to thin. Then I studied about the environments properties.
So, here is the correct answer inside your Production environment set:
config.serve_static_assets = true
This solved the problem.
Following link may help you:Upload image using paperclip

how to force send_data to download the file in the browser?

Well my problem is that I'm using send_data on my Rails 3 application to send to the user a file from AWS S3 service with something like
Base.establish_connection!( :access_key_id => 'my_key', :secret_access_key => 'my_super_secret_key')
s3File = S3Object.find dir+filename, "my_unique_bucket"
send_data(open(s3File.url).read,:filename=>filename, :disposition => 'attachment')
but seems like the browser is buffering the file and before buffering it sends the file to download taking no time on the download but at the buffering time it's taking as long as the file size .... but what i need is the user to view the download process as normal, they won't know what happening with the loader only on the browsers tab:
They'd rather see a download process i guess to figure out there's something happening there
is there any way i can do this with send_data?
It's not the browser that's buffering/delaying, it's your Ruby server code.
You're downloading the entire file from S3 before sending it back to the user as an attachment.
It may be better to serve this content to your user directly from S3 using a redirect. Here's a link to building temporary access URLs that will allow a download with a given token for a short period of time:
http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
Base.establish_connection!( :access_key_id => 'my_key', :secret_access_key => 'my_super_secret_key')
s3File = S3Object.find dir+filename, "my_unique_bucket"
redirect_to s3File.url(:expires_in => 30)
Set Your Content Disposition
You'll need to set the content-disposition of the S3 url for it download instead of opening up in the browser. Here is my basic implementation:
Think of attachment as your s3file.
In your attachment.rb
def download_url
s3 = AWS::S3.new.buckets[ 'bucket_name' ]
s3.url_for( :read,
expires_in: 60.minutes,
use_ssl: true,
response_content_disposition: "attachment; filename='#{file_name}'" ).to_s
end
In your views
<%= link_to 'Download Avicii by Avicii', attachment.download_url %>
Thanks to guilleva for his guidance.

Rails: generate a full URL in an ActionMailer view

I'm using ActionMailer to send a sign up confirmation email. The email needs to contain a link back to the site to verify the user, but I can't persuade Rails to generate a full URL (including the domain etc).
I'm using:
<%= url_for :controller => 'login', :action => 'verify', :guid => #user.new_user.guid, :only_path => false, :host => 'http://plantality.com' %>
in my view
Part b:
In development mode Rails gripes if I don't specify the host explicilty in the link above. But I don't want to do this in production. Any solutions?
To solve the problem to pass a host for generating URLs in ActionMailer, check out this plugin and the reason why I wrote it.
To solve the first issue, use named routes when applicable. Instead of
<%= url_for :controller => 'login', :action => 'verify', :guid => #user.new_user.guid, :only_path => false, :host => 'http://plantality.com' %>
assuming the route is called login, use
<%= login_url(:guid => #user.new_user.guid) %>
Note, I'm using login_url, not login_path.
I'm not sure if it is what you want but in config/environments/development.rb you can specify default options for mailer urls
config.action_mailer.default_url_options = {
:host => "your.host.org",
:port => 3000
}
you can do the same in config/environments/production.rb
I don't know why the previous solutions seem so complicated, but since I'm here why not give my 2 cents...
Go to /config/environments and add:
config.absolute_site_url = 'your site url'
for the respective environment (ie. in development.rb, test.rb, or production.rb). Restart web server.
This allows you to call Rails.application.config.absolute_site_url to get the desired URL. No need for plugins or weird cheat, just store the site url as an application wide variable.
I think its not 100% correct way but this can also be a solution :
See the Using asset hosts section in the documentation. You need to specify an asset_host. You can also construct it dynamically from the request chaining "#{request.protocol}#{request.host_with_port}/login/?guid=#{#user.new_user.guid}"
To generate url, try this
Rails.application.routes.url_helpers.user_url(User.first.id, host: 'yourhost.io')
this will generate url like this:
http://yourhost.io/users/1
As well you can pass some params
expires = Time.now + 2.days
params = {expires: expires}
u = User.first.id
Rails.application.routes.url_helpers.user_url(u, params, host: 'host.com')
will generate:
http://yourhost.io/users/1.expires=2018-08-12+15%253A52%253A15+%252B0300
so you can werifi in action if link is not expired

Resources