I need to inspect the bits of an uploaded file before it's ever saved off to the file system. PHP's documentation has a nice page that tells me exactly what properties are available for me to use (http://us3.php.net/manual/en/features.file-upload.post-method.php), but I can't find something similar for Ruby and/or Rails.
I've also tried logging a JSON-formatted string of the upload, but that just gives me a redundant UTF-8 error. I can't think of anything else to try.
Can anyone offer any insight or point me to the right place?
Thanks.
UPDATE: I'm running Apache 2.2.11 on OS X (Leopard) in case Peter is right (see below).
UPDATE: In case it helps, my input parameter is logged as "upload"=>#<File:/tmp/RackMultipart.64239.1>. I'm just not sure how to access it to get to its "parts".
As far as I've been able to tell or find, there is no physical file until an upload is read. This is inline with derfred's reply. The only metadata that can be accessed is:
uploaded_file.content_type # the uploaded file's MIME type
uploaded_file.original_path # which is really just the name of the file
Additionally, there's a read method on the uploaded_file that allows the file' content to be accessed and, presumably, written to the permanent file system.
Something else that I've noticed is that the only means Ruby offers to inspect the MIME type of a file is in this content_type property of an uploaded file. Once the file is on the file system, there's no longer any way of accessing or determining the MIME type.
I think this depends on the web server you're using. I remember having different fields for mongrel, apache and nginx.
AFAIK Rails and the various app servers totally abstract the upload part. However here is a thorough discussion of the topic:
http://www.jedi.be/blog/2009/04/10/rails-and-large-large-file-uploads-looking-at-the-alternatives/
This is just a File object, something that you can duplicate by going:
File.open("some_file")
The /tmp/RackMultipart.64239.1 is just a filename.
If you want to see/output its contents from the controller:
puts params[:upload].read
Related
I am working on a web application using Rails which user can upload a zip file which contains its data/file/docs and etc. But I'm concerned with security right now, I want to scan the uploaded zip file and remove all kind of executable such exe, bash and etc how can I do this?
Edit: I am aware of clamav API for rails but it would only scan the file for malicious files not removing the executable, just imagine opening a wrong uploaded executable file in the server and the cost of this action server/business-wide!
First, it would be better and more robust to whitelist allowed file types, and not blacklist disallowed ones (eg. executables). So you should have a list of types you allow if that is possible in your application.
Then the question is how you determine the type of a file.
The trivial way is checking the file extension, but that's not very strong. It may still be good for a first check to avoid spending precious cpu time on further checks.
After that, you can use the filemagic database to quite reliably find the type of uploaded files. You have two options:
If your application runs on linux, you can call the file tool directly, something like filetype = `file -Ib #{filename}` to get the filetype. Note that filename in this example needs to be sanitized to avoid OS command injection!
If you want to support Windows too (or just want to avoid calling shell commands and have nicer code), you can use the ruby-filemagic gem:
require 'filemagic'
filename = 'yourfile.ext'
magic = FileMagic.new
filetype = magic.file(filename)
The problem with ruby-filemagic is that it's not maintained anymore, but it would probably still work fine to find executables.
I am working on an App, in which I want to upload images and pdf to the FTP server. I am using this reference ref.All is working good. The images and pdf are getting uploaded on the server with proper names and sizes.
But, now I want to check if the directory is already exists on the server or not. I am not able to get it to work with this library.
So my question is that how to check directory on ftp,if directory is there then upload the files if not then first create directory on ftp and then upload files onto that directory?
Any Ideas.. ? Any help will be appreciated.
Different FTP servers will answer the LIST request in differing ways, so there is no single answer to this question. RFC959 says on the matter:
Since the information on a file may vary widely from system
to system, this information may be hard to use automatically
in a program, but may be quite useful to a human user.
Using the CWD request to change into the directory in question, and detecting a successful response will detect the directory, however that leaves you in that directory as a potentially unrequired side effect.
For these reasons, as well as others, you may find more modern protocols such as SSH (which includes a file transfer feature) to be more useful. You may find the DLSFTPClient CocoaPod useful.
M.
I'm writing a Rails application that serves files stored on a remote server to the end user.
In my case the files are stored on S3 but the user requests the file via the Rails-application (hiding the actual URL). If the file was on my servers local file-system, I could use the Apache header X-Sendfile to free up the Ruby process for other requests while Apache took over the task of sending the file to the client. But in my case - where the file is not on the local file-system, but on S3 - it seems that I'm forced to download it temporarily inside Rails before sending it to the client.
Isn't there a way for Apache to serve a "remote" file to the client that is not actually on the server it self. I don't mind if Apache has to download the file for this to work, as long as I don't have to tie up the Ruby process while it's going on.
Any suggestions?
Thomas, I have similar requirements/issues and I think I can answer your problem. First (and I'm not 100% sure you care for this part), hiding the S3 url is quite easy as Amazon allows you to point CNAMES to your bucket and use a custom URL instead of the amazon URL. To do that, you need to point your DNS to the correct amazon URL. When I set mine up it was similar to this: files.domain.com points to files.domain.com.s3.amazonaws.com. Then you need to create the bucket with the name of your custom URL (files.domain.com in this example). How to call that URL will be different depending on which gem you use, but a word of warning was that the attachment_fu plugin I was using was incorrectly sending me to files.domain.com/files.domain.com/name_of_file.... I couldn't find the setting to fix it, so a simple .sub method for the S3 portion of the plugin fixed it.
On to your other questions, to execute some rails code (like recording the hit in the db) before downloading you can simply do this:
def download
file = File.find(...
# code to record 'hit' to database
redirect_to 3Object.url_for(file.filename,
bucket,
:expires_in => 3.hours)
end
That code will still cause the file to be served by S3, but and still give you the ability to run some ruby. (Of course the above code won't work as is, you will need to point it to the correct file and bucket and my amazon keys are saved in a config file. The above is also using the syntax for the AWS::S3 gem - http://amazon.rubyforge.org/).
Second, the Content-Disposition: attachment issue is a bit more tricky. Hopefully, your situation is a bit more simple than mine and the following solution can work. Assuming the object 'file' (in this example) is the correct S3 object, you can set the disposition to attachment by
file.content_disposition = "attachment"
file.save
The above code can be executed after the file exists on the S3 server (unlike some other headers and permissions), which is nice and it can also be added when you upload the file (syntax depends on your plugin). I'm still trying to find a way to tell S3 to send it as an attachment and only when requested (not every time), and if you find that, please let me know your solution. I need to be able to sometimes download it and other times save embed images (for example) into HTML. I'm not using the above mentioned redirect but fortunately it seems that if you embed (such as a HTML image tag) a file with the content-disposition/attachment header, and the browser still displays the image normally (but I haven't throughly tested that across enough browsers to send it in the wild).
Hope that helps! Good luck.
Good day lovely computer peoples!
I've uploaded a .dmg file to my server, but when I test to see if it is downloadable by pointing the web browser to it's place in the directory (i.e. using it's URL) I get a 404.
Any possible ideas of why this could be happening?
Thanks
EDIT 1
I realize that the 404 means that it can't find the item, but I'm staring at both addresses (the one in the browser and the one in the FTP client that I use) and they seem identical. I have some underscores in the name of the .dmg. Could that be the problem?
You need to make sure you add a mime type for the file extension. Most servers now days do not allow access to files that don't have explicit file extension declarations in their list of mime types.
You didn't say what server you're using so I can't give you specific instructions on how to do it but in most servers it's fairly easy. Just google your webserver name and "add mime type" with the quotes.
The myfile.dmg is not found. Double check the file location and the URL you are pointing to.
I have a Rails application setup to receive file attachments using Paperclip.
Now I need to allow a .net/C# cell phone application to post files along with the XML in the same way (or some other way if necessary: they could encode the image as base64 and send - they tried that initially - including the binary data in the tag that would normally be a file field in the web application, but it did not work.
I have found nothing in the way of documentation and wondering if anybody has experience or advice.
Surprising that there is apparently no documentation for doing this anywhere to be found. I ended up stumbling across a document on the Basecamp website describing how their file attachment process works for API users and used it as a guideline.
http://developer.37signals.com/basecamp/
with help from this article about posting files:
http://www.codevil.com/index.php/2009/05/23/posting-and-getting-files-in-rubyrails/
I modified my initial setup so that, rather than passing the tag in the XML, they first post a file and receive an file ID in response.
Then they post the XML with that reference and their .
Then I use before_validation and after_save callbacks to set the file with Paperclip, and remove the tmp file after the save.