fphilipe / premailer-rails

CSS styled emails without the hassle.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow NetworkLoader to be configured with support for proxied requests

plasticine opened this issue · comments

Hey there 👋

Currently it’s not possible to configure premailer-rails to proxy requests that NetworkLoader makes when fetching remote CSS, leading us to have to use monkey-patching like the following in order for Premailer to work;

# config/initializers/premailer_rails.rb

Premailer::Rails.config.merge!(
  # Snip!
  network_proxy_host: ENV['egress_proxy_host'],
  network_proxy_port: ENV['egress_proxy_port'],
)

class Premailer
  module Rails
    module CSSLoaders
      module NetworkLoader
        def load(url)
          uri = uri_for_url(url)

          if uri.present?
            request = Net::HTTP.new(uri.host, uri.port, Rails.config[:network_proxy_host], Rails.config[:network_proxy_port])
            request.use_ssl = uri.scheme == 'https'
            response = request.get(uri.request_uri)
            response.body
          end
        end
      end
    end
  end
end

It’d be pretty awesome to have premailer-rails take care of this for us though, allowing us to remove this monkey-patch — I believe the code above should pretty much work as is if you’re interested in making this change.

Thanks 🙃

I have a similar monkey patch for ignoring a self-signed certificate in development.

Perhaps it would be better to use a "downloader proc" instead of providing individual parameters.

Something like this:

def load(url)
  uri = uri_for_url(url) || return
  downloader = Rails.config[:network_downloader] || ->(uri) { Net::HTTP.get(uri) }
  downloader.call(uri)
end
Premailer::Rails.config.merge!(
  # With SSL options:
  network_downloader: lambda do |uri|
    request = Net::HTTP::Get.new(uri.path)
    response = Net::HTTP.start(
        uri.host, uri.port, 
        use_ssl: uri.scheme == 'https', 
        verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
      https.request(request)
    end
    response.body
  end,

  # With proxy:
  network_downloader: lambda do |uri|
    request = Net::HTTP.new(uri.host, uri.port, ENV['egress_proxy_host'], ENV['egress_proxy_port'])
    request.use_ssl = uri.scheme == 'https'
    response = request.get(uri.request_uri)
    response.body  
  end
)

Not going to support this. But you have a working solution 😊 🐒🩹