I see there is a :user_ssl option in attachment_fu which checks the amazon_s3.yml file in order to serve files via https://

In the s3_backend.rb you have this method:

    def self.protocol
      @protocol ||= s3_config[:use_ssl] ? 'https://' : 'http://'

But this then makes it serve ALL s3 attachments with SSL. I'd like to make it dynamic depending if the current request was made with https:// i.e:

  if request.ssl?
    @protocol = "https://"
    @protocol = "http://"  

How can I make it work in this way? I've tried modifying the method and then get the NameError: undefined local variable or method `request' for Technoweenie::AttachmentFu::Backends::S3Backend:Module error


The problem is that the method you're modifying (Technoweenie::AttachmentFu::Backends::AWS::S3.protocol) is static and does not have access to the file or request in question. The one you want to modify is Technoweenie::AttachmentFu::Backends::AWS::S3#s3_url(thumbnail). You'll have to add an options argument so your controller can pass in whether it wants SSL or not, since this model-level package has no understanding of controller-level issues like "current request" (nor should it).

The real answer, though, is "you probably don't want to do this." If the customer is saying something like "we have a freemium model wherein only our paying customers get SSL transfers of their photos," you should push back: "it's actually harder to cripple SSL file transfers, and it's likely to just introduce bugs down the road. Let's think of another freemium option to offer." If the customer doesn't really care, you might as well just turn SSL on for all uploads.

James A. Rosen
I still run into issues with browsers not wanting to display images on a page if they are served over SSL while the page itself is not, keeping all of the references on the page as "http" or all as "https" fixes that nicely.
Mike Buckbee
Mike,That's pretty much the problem I'm trying to fix. Specifically regarding IE 7/8 security warning errors...
Marston A.
Gaius,Thanks, I'll give it a shot.
Marston A.

This is significant issue that needs to be solved correctly, or the implications are quite nasty (particularly if you don't test in IE, the errors and warnings may slip by you). My solution is to put the following in ApplicationController

around_filter :set_attachment_fu_protocol

def set_attachment_fu_protocol
  protocol = Technoweenie::AttachmentFu::Backends::S3Backend.instance_variable_get(:@protocol)
  Technoweenie::AttachmentFu::Backends::S3Backend.instance_variable_set(:@protocol, request.protocol)
  Technoweenie::AttachmentFu::Backends::S3Backend.instance_variable_set(:@protocol, protocol)

This solution was designed to have the following properties:

  • Doesn't require patching attachment_fu
  • Sets the protocol for S3 Backend per request
  • Resets the protocol even if an exception occurs
  • Preserves the default :use_ssl setting if you are running from the console
  • Doesn't require the around_filter to be universal since it always resets it to the original state after each request