rack-referrals 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +61 -0
- data/Rakefile +7 -0
- data/lib/rack-referrals/version.rb +5 -0
- data/lib/rack-referrals.rb +65 -0
- data/rack-referrals.gemspec +26 -0
- data/test/test_referrals.rb +39 -0
- metadata +99 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
Rack::Referrals
|
2
|
+
=============
|
3
|
+
|
4
|
+
Rack::Referrals is a rack middleware that extracts information about the referring website from each request. Specifically, it parses the HTTP-REFERER header and tells you if the request came from a known search engine (and if so, what the search terms were). It was inspired by the [search_sniffer](https://github.com/squeejee/search_sniffer) plugin, but provides that functionality as a middleware.
|
5
|
+
|
6
|
+
|
7
|
+
Purpose
|
8
|
+
-------
|
9
|
+
|
10
|
+
Ever wanted to know if the user viewing the current page got there via a search engine? If so, ever wanted to show them a link like "Click here to browse additional widgets related to *[search term*]"?
|
11
|
+
|
12
|
+
Yeah, this'll help.
|
13
|
+
|
14
|
+
|
15
|
+
Installation
|
16
|
+
------------
|
17
|
+
|
18
|
+
Quick and easy:
|
19
|
+
|
20
|
+
gem install rack-referrals
|
21
|
+
|
22
|
+
|
23
|
+
Example Usage (Rails 3 App)
|
24
|
+
-------------------------
|
25
|
+
|
26
|
+
Just add it to your middleware stack:
|
27
|
+
|
28
|
+
class Application < Rails::Application
|
29
|
+
...
|
30
|
+
config.middleware.use Rack::Referrals
|
31
|
+
...
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
Getting Fancy
|
36
|
+
-------------
|
37
|
+
|
38
|
+
This knows about a number of search engines by default (Google, Yahoo, Bing, some big Russian ones... check the <code>DEFAULT_ENGINES</code> constant in <code>lib/rack-referrals.rb</code> for the current list).
|
39
|
+
|
40
|
+
You can add in support for additional search engines by passing the <code>:additional_engines</code> parameter:
|
41
|
+
|
42
|
+
class Application < Rails::Application
|
43
|
+
...
|
44
|
+
config.middleware.use Rack::Referrals.new :additional_engines => {
|
45
|
+
:my_engine_name => [/domain_regular_expression/, 'search-term-parameter'],
|
46
|
+
:another_name => [/domain_regular_expression/, 'search-term-parameter'],
|
47
|
+
}
|
48
|
+
...
|
49
|
+
end
|
50
|
+
|
51
|
+
You can also just completely clear the default ones and use _only_ those you define with the <code>:engines</code> parameter:
|
52
|
+
|
53
|
+
class Application < Rails::Application
|
54
|
+
...
|
55
|
+
config.middleware.use Rack::Referrals.new :engines => {
|
56
|
+
:only_engine_i_like => [/domain_regular_expression/, 'search-term-parameter']
|
57
|
+
}
|
58
|
+
...
|
59
|
+
end
|
60
|
+
|
61
|
+
In either case, <code>domain_regular_expression</code> is a regular expression used to identify this search engine, like <code>/^https?:\/\/(www\.)?google.*/</code>, and <code>search-term-parameter</code> is the parameter that the search engine uses to store the user's search (for Google, that's <code>q</code>).
|
data/Rakefile
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "rack-referrals/version"
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
|
5
|
+
#
|
6
|
+
# Rack Middleware for extracting information from the HTTP-REFERER header.
|
7
|
+
# Specifically, it populates +env['referring.search_engine']+ and
|
8
|
+
# +env['referring.search_phrase']+ if it detects a request came from a known
|
9
|
+
# search engine.
|
10
|
+
#
|
11
|
+
class Referrals
|
12
|
+
|
13
|
+
DEFAULT_ENGINES = {
|
14
|
+
# Tested myself
|
15
|
+
:google => [/^https?:\/\/(www\.)?google.*/, 'q'],
|
16
|
+
:yahoo => [/^https?:\/\/([^\.]+.)?search\.yahoo.*/, 'p'],
|
17
|
+
:bing => [/^https?:\/\/search\.bing.*/, 'q'],
|
18
|
+
:biadu => [/^https?:\/\/(www\.)?baidu.*/, 'wd'],
|
19
|
+
:rambler => [/^https?:\/\/([^\.]+.)?rambler.ru/, 'query'],
|
20
|
+
:yandex => [/^https?:\/\/(www\.)?yandex.ru/, 'text'],
|
21
|
+
|
22
|
+
# Borrowed from https://github.com/squeejee/search_sniffer
|
23
|
+
:msn => [/^https?:\/\/search\.msn.*/, 'q'],
|
24
|
+
:aol => [/^https?:\/\/(www\.)?\.aol.*/, 'query'],
|
25
|
+
:altavista => [/^https?:\/\/(www\.)?altavista.*/, 'q'],
|
26
|
+
:feedster => [/^https?:\/\/(www\.)?feedster.*/, 'q'],
|
27
|
+
:lycos => [/^https?:\/\/search\.lycos.*/, 'query'],
|
28
|
+
:alltheweb => [/^https?:\/\/(www\.)?alltheweb.*/, 'q']
|
29
|
+
|
30
|
+
# Want to add support for more? A good place to start would be this list (note that they
|
31
|
+
# give example domains, though, not anything we can use to construct a reliable reg exp):
|
32
|
+
# http://code.google.com/apis/analytics/docs/tracking/gaTrackingTraffic.html#searchEngine
|
33
|
+
}
|
34
|
+
|
35
|
+
def initialize(app, opts = {})
|
36
|
+
@app = app
|
37
|
+
|
38
|
+
@engines = opts[:engines]
|
39
|
+
@engines ||= DEFAULT_ENGINES.merge(opts[:additional_engines] || {})
|
40
|
+
end
|
41
|
+
|
42
|
+
def call(env)
|
43
|
+
request = Rack::Request.new(env)
|
44
|
+
from = request.env["HTTP_REFERER"]
|
45
|
+
|
46
|
+
if from.to_s.length > 0
|
47
|
+
if engine = @engines.detect {|name, data| from =~ data[0] }
|
48
|
+
env["referring.search_engine"] = engine[0].to_s
|
49
|
+
reg, param_name = engine[1]
|
50
|
+
|
51
|
+
# Pull out the query string from the referring search engine
|
52
|
+
query_string = begin
|
53
|
+
URI.split(from)[7]
|
54
|
+
rescue URI::InvalidURIError; nil
|
55
|
+
end
|
56
|
+
|
57
|
+
env["referring.search_phrase"] = query_string && Rack::Utils.parse_query(query_string)[param_name]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
@app.call(env)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rack-referrals/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rack-referrals"
|
7
|
+
s.version = Rack::Referrals::VERSION
|
8
|
+
s.authors = ["Kali Donovan"]
|
9
|
+
s.email = ["kali@deviantech.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Extracts referring search engine info.}
|
12
|
+
s.description = %q{If the user clicked through from a search engine, this middleware will detect the engine used and the terms searched.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "rack-referrals"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "minitest"
|
23
|
+
s.add_development_dependency "rack-test"
|
24
|
+
s.add_development_dependency "rake"
|
25
|
+
s.add_dependency 'rack'
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "rack/test"
|
3
|
+
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/rack-referrals')
|
5
|
+
|
6
|
+
class ReferralTest < MiniTest::Unit::TestCase
|
7
|
+
include Rack::Test::Methods
|
8
|
+
|
9
|
+
def app
|
10
|
+
hello_world_app = lambda do |env|
|
11
|
+
[200, {}, "Hello World"]
|
12
|
+
end
|
13
|
+
|
14
|
+
Rack::Referrals.new(hello_world_app)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_parses_google
|
18
|
+
get '/', nil, 'HTTP_REFERER' => "http://www.google.com/search?q=ruby+on+rails&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a"
|
19
|
+
|
20
|
+
assert_equal "google", last_request.env['referring.search_engine']
|
21
|
+
assert_equal "ruby on rails", last_request.env['referring.search_phrase']
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_handles_missing_params
|
25
|
+
get '/', nil, 'HTTP_REFERER' => "http://www.google.com/search?ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a"
|
26
|
+
|
27
|
+
assert_equal "google", last_request.env['referring.search_engine']
|
28
|
+
assert_equal nil, last_request.env['referring.search_phrase']
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_handles_no_referer
|
32
|
+
get '/'
|
33
|
+
|
34
|
+
assert_equal nil, last_request.env['referring.search_engine']
|
35
|
+
assert_equal nil, last_request.env['referring.search_phrase']
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-referrals
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kali Donovan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-07 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
requirement: &70197710584540 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70197710584540
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rack-test
|
27
|
+
requirement: &70197710583960 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70197710583960
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70197710583240 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70197710583240
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rack
|
49
|
+
requirement: &70197710582340 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70197710582340
|
58
|
+
description: If the user clicked through from a search engine, this middleware will
|
59
|
+
detect the engine used and the terms searched.
|
60
|
+
email:
|
61
|
+
- kali@deviantech.com
|
62
|
+
executables: []
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- .gitignore
|
67
|
+
- Gemfile
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- lib/rack-referrals.rb
|
71
|
+
- lib/rack-referrals/version.rb
|
72
|
+
- rack-referrals.gemspec
|
73
|
+
- test/test_referrals.rb
|
74
|
+
homepage: ''
|
75
|
+
licenses: []
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project: rack-referrals
|
94
|
+
rubygems_version: 1.8.10
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Extracts referring search engine info.
|
98
|
+
test_files:
|
99
|
+
- test/test_referrals.rb
|