Class: Rack::Prerender::Fetcher
- Inherits:
-
Object
- Object
- Rack::Prerender::Fetcher
- Defined in:
- lib/rack/prerender/fetcher.rb
Instance Attribute Summary collapse
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Instance Method Summary collapse
- #after_render(env, response) ⇒ Object
- #api_url(url) ⇒ Object
- #before_render(env) ⇒ Object
- #build_rack_response_from_prerender(prerendered_response) ⇒ Object
-
#call(env) ⇒ Object
Entry point for automatic fetching via the middleware.
- #configure_protocol(env, protocol) ⇒ Object
- #decompress(response) ⇒ Object
-
#fetch(arg) ⇒ Object
Entry point for manual fetching.
-
#fetch_api_uri(uri, as: nil) ⇒ Object
This is just horrible, but replacing net/http would break compatibility because the response object is leaked to several callbacks :(.
- #fetch_env(env) ⇒ Object
- #fetch_url(url, as: nil) ⇒ Object
- #headers(user_agent: nil) ⇒ Object
-
#initialize(options = {}) ⇒ Fetcher
constructor
A new instance of Fetcher.
- #request_url(env) ⇒ Object
- #service_url ⇒ Object
- #token ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Fetcher
Returns a new instance of Fetcher.
8 9 10 |
# File 'lib/rack/prerender/fetcher.rb', line 8 def initialize( = {}) @options = end |
Instance Attribute Details
#env ⇒ Object (readonly)
Returns the value of attribute env.
6 7 8 |
# File 'lib/rack/prerender/fetcher.rb', line 6 def env @env end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
6 7 8 |
# File 'lib/rack/prerender/fetcher.rb', line 6 def @options end |
Instance Method Details
#after_render(env, response) ⇒ Object
146 147 148 |
# File 'lib/rack/prerender/fetcher.rb', line 146 def after_render(env, response) (callback = [:after_render]) && callback.call(env, response) end |
#api_url(url) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/rack/prerender/fetcher.rb', line 75 def api_url(url) if service_url.match?(/[=\/]$/) "#{service_url}#{url}" else "#{service_url}/#{url}" end end |
#before_render(env) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/rack/prerender/fetcher.rb', line 37 def before_render(env) return unless callback = [: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) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/rack/prerender/fetcher.rb', line 134 def build_rack_response_from_prerender(prerendered_response) response = Rack::Response.new( prerendered_response.body, prerendered_response.code, prerendered_response, ) if callback = [:build_rack_response_from_prerender] callback.call(response, prerendered_response) end response end |
#call(env) ⇒ Object
Entry point for automatic fetching via the middleware.
13 14 15 16 17 18 19 20 21 22 23 24 |
# 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) ⇒ Object
116 117 118 119 120 121 122 |
# File 'lib/rack/prerender/fetcher.rb', line 116 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) ⇒ Object
124 125 126 127 128 129 130 131 132 |
# File 'lib/rack/prerender/fetcher.rb', line 124 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') end response end |
#fetch(arg) ⇒ Object
Entry point for manual fetching. Does not run callbacks.
27 28 29 30 31 32 33 34 35 |
# 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 raise ArgumentError, "expected a URL, Request or env, got #{arg.class}" end end |
#fetch_api_uri(uri, as: nil) ⇒ Object
This is just horrible, but replacing net/http would break compatibility because the response object is leaked to several callbacks :(
62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rack/prerender/fetcher.rb', line 62 def fetch_api_uri(uri, as: nil) req = Net::HTTP::Get.new(uri.request_uri, headers(user_agent: as)) if [: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) ⇒ Object
51 52 53 |
# File 'lib/rack/prerender/fetcher.rb', line 51 def fetch_env(env) fetch_url(request_url(env), as: env['HTTP_USER_AGENT']) end |
#fetch_url(url, as: nil) ⇒ Object
55 56 57 58 |
# File 'lib/rack/prerender/fetcher.rb', line 55 def fetch_url(url, as: nil) uri = URI.parse(api_url(url)) fetch_api_uri(uri, as: as) end |
#headers(user_agent: nil) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/rack/prerender/fetcher.rb', line 88 def headers(user_agent: nil) { 'Accept-Encoding' => 'gzip', 'User-Agent' => user_agent, 'X-Prerender-Token' => token, }.compact end |
#request_url(env) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rack/prerender/fetcher.rb', line 100 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 = [:protocol] configure_protocol(env, protocol) end Rack::Request.new(env).url end |
#service_url ⇒ Object
83 84 85 86 |
# File 'lib/rack/prerender/fetcher.rb', line 83 def service_url [:prerender_service_url] || ENV['PRERENDER_SERVICE_URL'] || 'http://service.prerender.io' end |
#token ⇒ Object
96 97 98 |
# File 'lib/rack/prerender/fetcher.rb', line 96 def token [:prerender_token] || ENV['PRERENDER_TOKEN'] end |