NoDisplayName
NoDisplayName

Reputation: 15736

Server side validation of file size

I am trying to find a way to limit the size of files that users can upload, and it seems to be possible with javascript, but what bothers me is that what happens if a user just turns javascript off and upload like 1GB file to the server, and I did find a way to validate it on server side but it takes place once the file has been uploaded, which isnt an option. So I am trying to find the right way to do it but the best thing I came up with is to create a form for file uploading with javascript and make validations on client side but I guess there is still a way around it...

I am using RoR and CarrierWave if that matters ...

EDIT

1)Everything I can find on this page is to use size validation which happens after the file has been uploaded

2) I use that validation by carrierwave but again, it takes place once the file has been uploaded, it doesnt make sense to wait an hour till some huge file gets uploaded just to know its too big

Upvotes: 0

Views: 3518

Answers (2)

NoDisplayName
NoDisplayName

Reputation: 15736

The problem was solved by nginx, which works like a buffer so if somebody is trying to upload a 1GB file, it will go to your buffer first so it won't block your unicorn instance until it's completely uploaded, so that's one good thing. The other is that you can set the max content-length parameter in your nginx config file, so if you set to 5 Megabytes and somebody is trying to upload 1 GB file, it'll be denied. But again, I am not sure how it works, if it just checks the http header, then I have a feeling that somebody can simply tamper with this value and fool your nginx.

Upvotes: 0

Abdul Baig
Abdul Baig

Reputation: 3721

You can use a Rails custom validator to verify your attachment meets specific file size requirements.

Grab a copy of the validator from https://gist.github.com/1009861 and save it to your lib/ folder as file_size_validator.rb. Add the error translations to config/locales/en.yml or wherever is appropriate for your setup. Then do this in your parent model:

# app/models/brand.rb 
require 'file_size_validator' 
class Brand < ActiveRecord::Base 
  mount_uploader :logo, BrandLogoUploader 
  validates :logo, 
    :presence => true, 
    :file_size => { 
      :maximum => 0.5.megabytes.to_i 
    } 
end 

Like validates_length_of, validates_file_size accepts :maximum, :minimum, :in [range], and :is options.


Another solution

A custom validator could also be used like this.

app/models/user.rb

class User< ActiveRecord::Base 
  attr_accessible :product_upload_limit
  has_many :products
end



app/models/brand.rb 
class Product < ActiveRecord::Base 
  mount_uploader :file, FileUploader
  belongs_to :user
  validate :file_size

  def file_size
    if file.file.size.to_f/(1000*1000) > user.product_upload_limit.to_f
      errors.add(:file, "You cannot upload a file greater than #{upload_limit.to_f}MB")
    end
  end
 end

Here, the upload limit varies from user to user & is saved in the user model.

Upvotes: 2

Related Questions