Rails send_data passes plain text path as file - ruby-on-rails

I cant figure out what Im doing wrong here. Im using Carrierwave to allow users to upload PDF files to AWS. So far upload and record creation go off without a hitch and when browsing the S3 bucket Im able to download and read the file no problem.
The issue Im having is with the "send_data" function in my controller The file download is being triggered, but instead of the PDF thats in AWS im getting a txt file(with PDF extension), that contains only the path to the file.
here is my code, hopefully more experienced eyes will spot my error.
send_data #document.file.url.to_s, :type => "application/pdf", :disposition => "attachment", :filename => #document.title.to_s

Look at semantic for those methods:
send_data(data, options = {})
send_file(path, options = {})
For send_data() you should open and read the file, for send_file() you can use just a path to file.
send_data(File.read(#document.file.url.to_s), type: "application/pdf", disposition: "attachment", filename: #document.title.to_s)

Related

PDF file generated by Prawn throws "Failed - server error" when I try to download it from the browser's pdf viewer

I have a PDF file that is generated in ruby on rails with Prawn.
I used send_file with disposition: inline.
pdf = <A method is called to generate the PDF>
pdf.render_file file_path # file_path = public/assets/reports/test_report.pdf
send_file(file_path, filename: 'test_report.pdf', type: 'application/pdf', disposition: 'inline')
The pdf is displayed as expected but when I try to download it from the browser's pdf viewer after the pdf is displayed, it throws me an error saying "failed - server error".
Download button
error
Has anyone faced this issue or have a possible solution to it?
Tried using send_data instead of send_file the issue still remains. I have tried searching through the internet including stack overflow, didn't find a proper solution. I went through PrawnRails documentation, no luck there too.

How to handle when API returns PDF binary stream

I have an e-signature tool I'm using and when I want to download the executed file, it's a simple GET request. The issue is that it:
Returns PDF file binary stream of the document which you can save as PDF file.
When examining the file it looks something like this (this is only a snippet):
> r.body
=> "%PDF-1.4\n%\xE2\xE3\xCF\xD3\n77 0 obj\n<</ByteRange [0 141 16527 447870 ] /ContactInfo()/Contents <30820ffe06092a864886f70d010702a0820fef30820feb020101310f300d06096086480165030402010500300b06092a864886f70d010701a0820e393082042a30820312a00302010202043863def8300d06092a864886f70d01010505003081b431143012060355040a130b456e74727573742e6e65743140303e060355040b14377777772e656e74727573742e6e65742f4350535f3230343820696e636f72702e206279207265662e20286c696d697473206c6961622e2931253023060355040b131c286329203139393920456e74727573742e6e6574204c696d69746564313330310603550403132a456e74727573742e6e6574204365727469666963
What can I do with this data to present it on the screen as a PDF?
You can use send_data, this will download the file or open it in the browser depending on which browser your user is using:
send_data(r.body, type: 'application/pdf', disposition: 'attachment', filename: 'file.pdf')
See further: https://apidock.com/rails/ActionController/Streaming/send_data

combine_pdf not combining the pdfs

I think I am missing something simple. Using combine_pdf: I am attempting to combine two pdf files into one pdf, and then send that resulting pdf with send_data in my rails app.
Here is my code in a controller:
pdf = CombinePDF.new
# returns an array, each element is a string of an absolute path
# to the file I want to upload
absolute_upload_paths = #obj.attachments.collect {|obj| obj.my_attachment.path}
absolute_upload_paths.each {|upload_path| pdf << CombinePDF.load(upload_path)}
send_data pdf, filename: “my_combined_pdf”, type: "application/pdf"
What results is that a damaged pdf file gets sent which cannot be opened:
Adobe Acrobat Reader could not open 'VR_Voc_Eval-51.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).
What am I missing? How can I use this gem to combine two existing pdf files into one pdf and then send it to the user?
It looks like the README for that library calls .to_pdf when sending the data. Hopefully calling #to_pdf on the pdf object like in the example will fix your issue.
send_data pdf.to_pdf, filename: “my_combined_pdf”, type: "application/pdf"
https://github.com/boazsegev/combine_pdf#rendering-pdf-data

Converting .txt file to .xml ruby on rails

I have a custom file type (.map) that I am unzipping from a Gzip file and then writing to a new file in order to pass it along to Paperclip and upload to s3. My problem is that the type should be an xml, while it is saving as a text document instead with all xml formatting correct. I need a way to convert it into the xml type and then save that as a new File object before passing it along.
Here is my code so far:
Zlib::GzipReader.open(f.tempfile) do |gz|
puts gz.orig_name
#tmp = File.new(gz.orig_name, "w+")
while chunk = gz.read(16*1024) do
#tmp.write(chunk)
end
end
reader = #tmp.read
s = location.posts.create!(
subject: #email.subject,
from: #email.from[:email],
mapfile: #tmp)
}
ideally i will be passing mapfile the xml type file, but right now it seems to be text
Update:
So now I have set my post.rb to do this, and added a name attribute to post containing the original file name:
has_attached_file :mapfile,
:preserve_files => "true",
:path =>
':rails_root/non-public/system/:id/:basename.:extension',
:url => '/:class/:id/mapfiles',
:s3_headers => lambda { |attachment| {'Content-Disposition' => "attachment; filename = #{attachment.name}"}}
And this works perfectly!
It sounds like you are talking about `Content-Type'. When you save a file to the filesystem, you can't set this: the system will decide what to use based on the file extension and possibly by analysing the contents, if it's a text file.
However, you can set the content type when you serve a file to someone's browser, and when you upload it to S3. See here for the latter Setting the Content-Type in direct to S3 upload using Rails and jQuery File Upload

Sending zipped files as attachments

I have a rails application that creates a couple of csv file, zips them up and sends them to the client as an attachment(for download) using this line:
send_file t.path, :x_sendfile => true, :type => 'application/zip', :filename => "invited_friends_stats.zip"
When I view the zipped file created on the server, I'm able to use it, however, when I download the file through the application, it uncompresses into a .zip.cpgz file, while in turn compresses into a zip file which compresses into a .zip.cpgz file, etc, etc.
I then downloaded "The Unarchiver" app (on Mac OSX) and when I try and open the .zip file I get an error: "the contents cannot be extracted with this program"
Does anyone have any idea why this is happening? Encoding error, etc? Is there something I'm missing from the line above, or in my configuration that would fix this?
You try to stream the ZIP file. Try adding :disposition => 'attachment' to force the browser to download the complete file.
Try setting the Content-Disposition response header with something like this
response.headers['Content-Disposition'] = "attachment; filename=\"#{#filename}\""

Resources