class Rack::Prerender::Fetcher
Attributes
env[R]
options[R]
Public Class Methods
new(options = {})
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 8 def initialize(options = {}) @options = options end
Public Instance Methods
after_render(env, response)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 159 def after_render(env, response) (callback = options[:after_render]) && callback.call(env, response) end
api_url(url)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 87 def api_url(url) if service_url.match?(/[=\/]$/) "#{service_url}#{url}" else "#{service_url}/#{url}" end end
before_render(env)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 43 def before_render(env) return unless callback = options[:before_render] cached_render = callback.call(env) if cached_render && cached_render.is_a?(String) Rack::Response.new(cached_render, 200, { 'Content-Type' => 'text/html; charset=utf-8' }) elsif cached_render && cached_render.is_a?(Rack::Response) cached_render else nil end end
build_rack_response_from_prerender(prerendered_response)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 147 def build_rack_response_from_prerender(prerendered_response) response = Rack::Response.new( prerendered_response.body, prerendered_response.code, prerendered_response, ) if callback = options[:build_rack_response_from_prerender] callback.call(response, prerendered_response) end response end
call(env)
click to toggle source
Entry point for automatic fetching via the middleware.
# File lib/rack/prerender/fetcher.rb, line 13 def call(env) cached_response = before_render(env) return cached_response.finish if cached_response if prerendered_response = fetch_env(env) response = build_rack_response_from_prerender(prerendered_response) after_render(env, prerendered_response) return response.finish end nil end
configure_protocol(env, protocol)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 128 def configure_protocol(env, protocol) return unless protocol == 'http' || protocol == 'https' env['rack.url_scheme'] = protocol env['HTTPS'] = protocol == 'https' env['SERVER_PORT'] = protocol == 'https' ? 443 : 80 end
decompress(response)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 136 def decompress(response) if response['Content-Encoding'] == 'gzip' response.body = Zlib::GzipReader.wrap(StringIO.new(response.body), &:read) response['Content-Length'] = response.body.bytesize response.delete('Content-Encoding') response.delete('Transfer-Encoding') end response end
fetch(arg)
click to toggle source
Entry point for manual fetching. Does not run callbacks.
# File lib/rack/prerender/fetcher.rb, line 27 def fetch(arg) case arg when String, Symbol, URI then fetch_url(arg.to_s) when Hash then fetch_env(arg) when Rack::Request then fetch_env(arg.env) else if defined?(ActiveModel::Naming) && ActiveModel::Naming === arg.class record_url = Rails.application.routes.url_helpers.url_for(arg) fetch_url(record_url) else raise ArgumentError, "expected URL, Request, env or record, got #{arg.class}" end end end
fetch_api_uri(uri, as: nil)
click to toggle source
This is just horrible, but replacing net/http would break compatibility because the response object is leaked to several callbacks :(
# File lib/rack/prerender/fetcher.rb, line 74 def fetch_api_uri(uri, as: nil) req = Net::HTTP::Get.new(uri.request_uri, headers(user_agent: as)) if options[:basic_auth] req.basic_auth(ENV['PRERENDER_USERNAME'], ENV['PRERENDER_PASSWORD']) end http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' response = http.request(req) decompress(response) rescue nil end
fetch_env(env)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 57 def fetch_env(env) fetch_url(request_url(env), as: env['HTTP_USER_AGENT']) end
fetch_url(url, as: nil)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 61 def fetch_url(url, as: nil) uri = try_uri_parse(api_url(url)) uri && fetch_api_uri(uri, as: as) end
headers(user_agent: nil)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 100 def headers(user_agent: nil) { 'Accept-Encoding' => 'gzip', 'User-Agent' => user_agent, 'X-Prerender-Token' => token, }.compact end
request_url(env)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 112 def request_url(env) if env['CF-VISITOR'] && protocol = env['CF-VISITOR'][/"scheme":"(http|https)"/, 1] configure_protocol(env, protocol) end if env['X-FORWARDED-PROTO'] && protocol = env["X-FORWARDED-PROTO"].split(',')[0] configure_protocol(env, protocol) end if protocol = options[:protocol] configure_protocol(env, protocol) end Rack::Request.new(env).url end
service_url()
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 95 def service_url options[:prerender_service_url] || ENV['PRERENDER_SERVICE_URL'] || 'http://service.prerender.io' end
token()
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 108 def token options[:prerender_token] || ENV['PRERENDER_TOKEN'] end
try_uri_parse(url)
click to toggle source
# File lib/rack/prerender/fetcher.rb, line 66 def try_uri_parse(url) URI.parse(url) rescue URI::InvalidURIError nil end