diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index ceff160e34b..bd812f535b0 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -4,8 +4,7 @@ class UploadsController < ApplicationController
   def create
     file = params[:file] || params[:files].first
 
-    # only supports images for now
-    return render status: 415, json: failed_json unless file.content_type =~ /^image\/.+/
+    return render status: 415, json: failed_json unless SiteSetting.authorized_file?(file)
 
     upload = Upload.create_for(current_user.id, file)
 
diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index 3a961ebb821..021eb2d4702 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -274,6 +274,23 @@ class SiteSetting < ActiveRecord::Base
     top_menu_items.map { |item| item.name }.select{ |item| list.include?(item) }.first
   end
 
+  def self.authorized_file?(file)
+    file.original_filename =~ /\.(#{authorized_extensions.tr(". ", "")})$/i
+  end
+
+  def self.images
+    @images ||= ["jpg", "jpeg", "png", "gif", "tif", "tiff", "bmp"]
+  end
+
+  def self.authorized_image?(file)
+    authorized_images = authorized_extensions
+                          .tr(". ", "")
+                          .split("|")
+                          .select { |extension| images.include?(extension) }
+                          .join("|")
+    file.original_filename =~ /\.(#{authorized_images})$/i
+  end
+
 end
 
 # == Schema Information
diff --git a/app/models/upload.rb b/app/models/upload.rb
index 38d5a8592b2..02c3d0c2fba 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -1,9 +1,9 @@
 require 'digest/sha1'
 require 'image_sizer'
-require 's3'
-require 'local_store'
 require 'tempfile'
 require 'pathname'
+require_dependency 's3'
+require_dependency 'local_store'
 
 class Upload < ActiveRecord::Base
   belongs_to :user
@@ -48,24 +48,25 @@ class Upload < ActiveRecord::Base
     sha1 = Digest::SHA1.file(file.tempfile).hexdigest
     # check if the file has already been uploaded
     unless upload = Upload.where(sha1: sha1).first
-      # retrieve image info
-      image_info = FastImage.new(file.tempfile, raise_on_failure: true)
-      # compute image aspect ratio
-      width, height = ImageSizer.resize(*image_info.size)
       # create a db record (so we can use the id)
       upload = Upload.create!({
         user_id: user_id,
         original_filename: file.original_filename,
         filesize: File.size(file.tempfile),
         sha1: sha1,
-        width: width,
-        height: height,
         url: ""
       })
-      # make sure we're at the beginning of the file (FastImage is moving the pointer)
-      file.rewind
+      # deal with width & heights for images
+      if SiteSetting.authorized_image?(file)
+        # retrieve image info
+        image_info = FastImage.new(file.tempfile, raise_on_failure: true)
+        # compute image aspect ratio
+        upload.width, upload.height = ImageSizer.resize(*image_info.size)
+        # make sure we're at the beginning of the file (FastImage is moving the pointer)
+        file.rewind
+      end
       # store the file and update its url
-      upload.url = Upload.store_file(file, sha1, image_info, upload.id)
+      upload.url = Upload.store_file(file, sha1, upload.id)
       # save the url
       upload.save
     end
@@ -73,9 +74,9 @@ class Upload < ActiveRecord::Base
     upload
   end
 
-  def self.store_file(file, sha1, image_info, upload_id)
-    return S3.store_file(file, sha1, image_info, upload_id) if SiteSetting.enable_s3_uploads?
-    return LocalStore.store_file(file, sha1, image_info, upload_id)
+  def self.store_file(file, sha1, upload_id)
+    return S3.store_file(file, sha1, upload_id) if SiteSetting.enable_s3_uploads?
+    return LocalStore.store_file(file, sha1, upload_id)
   end
 
   def self.remove_file(url)
@@ -92,29 +93,15 @@ class Upload < ActiveRecord::Base
   end
 
   def self.is_local?(url)
-    url.start_with?(base_url)
+    !SiteSetting.enable_s3_uploads? && url.start_with?(LocalStore.base_url)
   end
 
   def self.is_on_s3?(url)
     SiteSetting.enable_s3_uploads? && url.start_with?(S3.base_url)
   end
 
-  def self.base_url
-    asset_host.present? ? asset_host : Discourse.base_url_no_prefix
-  end
-
-  def self.asset_host
-    ActionController::Base.asset_host
-  end
-
   def self.get_from_url(url)
-    if has_been_uploaded?(url)
-      if m = LocalStore.uploaded_regex.match(url)
-        Upload.where(id: m[:upload_id]).first
-      elsif is_on_s3?(url)
-        Upload.where(url: url).first
-      end
-    end
+    Upload.where(url: url).first if has_been_uploaded?(url)
   end
 
 end
diff --git a/lib/local_store.rb b/lib/local_store.rb
index f893461daed..a87ff8a0ea7 100644
--- a/lib/local_store.rb
+++ b/lib/local_store.rb
@@ -1,18 +1,21 @@
 module LocalStore
 
-  def self.store_file(file, sha1, image_info, upload_id)
-    clean_name = Digest::SHA1.hexdigest("#{Time.now.to_s}#{file.original_filename}")[0,16] + ".#{image_info.type}"
+  def self.store_file(file, sha1, upload_id)
+    unique_sha1 = Digest::SHA1.hexdigest("#{Time.now.to_s}#{file.original_filename}")[0,16]
+    extension = File.extname(file.original_filename)
+    clean_name = "#{unique_sha1}#{extension}"
     url_root = "/uploads/#{RailsMultisite::ConnectionManagement.current_db}/#{upload_id}"
     path = "#{Rails.root}/public#{url_root}"
 
     FileUtils.mkdir_p path
+
     # not using cause mv, cause permissions are no good on move
     File.open("#{path}/#{clean_name}", "wb") do |f|
       f.write File.read(file.tempfile)
     end
 
     # url
-    return Discourse::base_uri + "#{url_root}/#{clean_name}"
+    Discourse::base_uri + "#{url_root}/#{clean_name}"
   end
 
   def self.remove_file(url)
@@ -24,4 +27,21 @@ module LocalStore
     /\/uploads\/#{RailsMultisite::ConnectionManagement.current_db}\/(?<upload_id>\d+)\/[0-9a-f]{16}\.(png|jpg|jpeg|gif|tif|tiff|bmp)/
   end
 
+  def self.base_url
+    url = asset_host.present? ? asset_host : Discourse.base_url_no_prefix
+    "#{url}#{directory}"
+  end
+
+  def self.base_path
+    "#{Rails.root}/public#{directory}"
+  end
+
+  def self.directory
+    "/uploads/#{RailsMultisite::ConnectionManagement.current_db}"
+  end
+
+  def self.asset_host
+    ActionController::Base.asset_host
+  end
+
 end
diff --git a/lib/s3.rb b/lib/s3.rb
index a880cfd0ec3..09d485a72da 100644
--- a/lib/s3.rb
+++ b/lib/s3.rb
@@ -1,11 +1,11 @@
 module S3
 
-  def self.store_file(file, sha1, image_info, upload_id)
+  def self.store_file(file, sha1, upload_id)
     S3.check_missing_site_settings
 
     directory = S3.get_or_create_directory(SiteSetting.s3_upload_bucket)
-
-    remote_filename = "#{upload_id}#{sha1}.#{image_info.type}"
+    extension = File.extname(file.original_filename)
+    remote_filename = "#{upload_id}#{sha1}#{extension}"
 
     # if this fails, it will throw an exception
     file = S3.upload(file, remote_filename, directory)