Class: Rack::SEO4Ajax

Inherits:
Object
  • Object
show all
Defined in:
lib/seo4ajax_rails.rb

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ SEO4Ajax

Returns a new instance of SEO4Ajax.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/seo4ajax_rails.rb', line 6

def initialize(app, options={})
  @crawler_user_agents = [
    'googlebot',
    'yahoo',
    'bingbot',
    'baiduspider',
    'facebookexternalhit',
    'twitterbot',
    'rogerbot',
    'linkedinbot',
    'embedly',
    'bufferbot',
    'quora link preview',
    'showyoubot',
    'outbrain',
    'pinterest/0.',
    'developers.google.com/+/web/snippet',
    'www.google.com/webmasters/tools/richsnippets',
    'slackbot',
    'vkShare',
    'W3C_Validator',
    'redditbot',
    'Applebot',
    'WhatsApp',
    'flipboard',
    'tumblr',
    'bitlybot',
    'SkypeUriPreview',
    'nuzzel',
    'Discordbot',
    'Google Page Speed',
    'Qwantify'
  ]

  @extensions_to_ignore = [
    '.js',
    '.css',
    '.xml',
    '.less',
    '.png',
    '.jpg',
    '.jpeg',
    '.gif',
    '.pdf',
    '.doc',
    '.txt',
    '.ico',
    '.rss',
    '.zip',
    '.mp3',
    '.rar',
    '.exe',
    '.wmv',
    '.doc',
    '.avi',
    '.ppt',
    '.mpg',
    '.mpeg',
    '.tif',
    '.wav',
    '.mov',
    '.psd',
    '.ai',
    '.xls',
    '.mp4',
    '.m4a',
    '.swf',
    '.dat',
    '.dmg',
    '.iso',
    '.flv',
    '.m4v',
    '.torrent'
  ]

  @options = options
  @extensions_to_ignore = @options[:extensions_to_ignore] if @options[:extensions_to_ignore]
  @crawler_user_agents = @options[:crawler_user_agents] if @options[:crawler_user_agents]
  @app = app
end

Instance Method Details

#build_api_url(env) ⇒ Object



137
138
139
140
141
142
143
144
# File 'lib/seo4ajax_rails.rb', line 137

def build_api_url(env)
  fullpath = Rack::Request.new(env).fullpath
  seo4ajax_url = @options[:seo4ajax_service_url] || ENV['SEO4AJAX_SERVICE_URL'] || 'http://api.seo4ajax.com/'
  forward_slash = seo4ajax_url[-1, 1] == '/' ? '' : '/'
  token = ENV['SEO4AJAX_TOKEN'] if ENV['SEO4AJAX_TOKEN']
  token = @options[:seo4ajax_token] if @options[:seo4ajax_token]      
  "#{seo4ajax_url}#{forward_slash}#{token}#{fullpath}"
end

#build_rack_response_from_seo4ajax(snapshot) ⇒ Object



147
148
149
# File 'lib/seo4ajax_rails.rb', line 147

def build_rack_response_from_seo4ajax(snapshot)
  Rack::Response.new(snapshot.body, snapshot.code, snapshot.header)
end

#call(env) ⇒ Object



88
89
90
91
92
93
94
95
96
97
# File 'lib/seo4ajax_rails.rb', line 88

def call(env)
  if should_show_snapshot(env)
    snapshot = get_snapshot_response(env)
    if snapshot
      response = build_rack_response_from_seo4ajax(snapshot)
      return response.finish
    end
  end
  @app.call(env)
end

#get_snapshot_response(env) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/seo4ajax_rails.rb', line 113

def get_snapshot_response(env)
  begin
    url = URI.parse(build_api_url(env))        
    headers = {
      'User-Agent' => env['HTTP_USER_AGENT'],
      'Accept-Encoding' => 'gzip'
    }
    req = Net::HTTP::Get.new(url.request_uri, headers)
    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true if url.scheme == 'https'
    response = http.request(req)
    if response['Content-Encoding'] == 'gzip'
      response.body = ActiveSupport::Gzip.decompress(response.body)
      response['Content-Length'] = response.body.length
      response.delete('Content-Encoding')
      response.delete('Transfer-Encoding')
    end
    response
  rescue
    nil
  end  
end

#should_show_snapshot(env) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/seo4ajax_rails.rb', line 100

def should_show_snapshot(env)
  user_agent = env['HTTP_USER_AGENT']
  is_requesting_snapshot = false
  return false if !user_agent
  return false if env['REQUEST_METHOD'] != 'GET'
  request = Rack::Request.new(env)
  is_requesting_snapshot = true if Rack::Utils.parse_query(request.query_string).has_key?('_escaped_fragment_')
  is_requesting_snapshot = true if @crawler_user_agents.any? { |crawler_user_agent| user_agent.downcase.include?(crawler_user_agent.downcase) }
  return false if @extensions_to_ignore.any? { |extension| request.fullpath.include? extension }
  return is_requesting_snapshot
end