nondisposable 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +123 -0
- data/Rakefile +5 -0
- data/data/email_providers.txt +276 -0
- data/data/iana_tlds.txt +1439 -0
- data/lib/generators/nondisposable/templates/nondisposable.rb +44 -0
- data/lib/nondisposable/email_validator.rb +52 -1
- data/lib/nondisposable/suggestion.rb +166 -0
- data/lib/nondisposable/tld.rb +185 -0
- data/lib/nondisposable/tld_list_updater.rb +101 -0
- data/lib/nondisposable/version.rb +1 -1
- data/lib/nondisposable.rb +92 -0
- data/lib/tasks/nondisposable.rake +37 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d2c949362fe7f9506247f3ae809ced6dca5a842086fa540346c8e89ea5dc5fd
|
|
4
|
+
data.tar.gz: a13fa7bec1531089fe68895529ecab5d9f05a2653292e2e39a1f4dfdeb818cf7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 696ce476987cdd1a90008b8065a9f8af9d6c19035e42cbd3cb0b03cf9b36ec0bf3fd9158d474552a8d2729e4d454ec19ac7ee31e24af844f17a42e27346532bc
|
|
7
|
+
data.tar.gz: 1a220333975bbd3ba6229a29172e42b4e9c91ddc6cc4ee97aca417ab743c3756c5ff024f70d57963f0c7643378d4d1a4153135632d7f65cd4a96068bb3bb3dc0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## [0.4.0] - 2026-08-25
|
|
2
|
+
|
|
3
|
+
Catching the other kind of bad address. A disposable address is someone hiding from you; a typo is someone who wanted to reach you and can't. `user@gmail.con` isn't a throwaway — it's a real person whose account nobody will ever be able to reach, because `.con` has never existed. Both new checks are **opt-in**: upgrading this gem will not start rejecting addresses that were fine yesterday.
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **TLD validation** (`config.check_tld`, default `false`): rejects addresses whose TLD isn't in the IANA root zone. The gem now bundles a snapshot of [data.iana.org/TLD/tlds-alpha-by-domain.txt](https://data.iana.org/TLD/tlds-alpha-by-domain.txt) (~1,438 entries, ~9 KB) loaded once into a frozen `Set` — no migration, no table, no query per signup, and it can't be empty on a fresh install. A domain with no dot at all (`example@gmailmcom`) has no TLD and is rejected too; IP literals and unicode TLDs are deliberately left alone.
|
|
8
|
+
- **`config.additional_tlds`**: accept a TLD delegated after your installed version shipped, without waiting for a release. This is the escape hatch that keeps a stale snapshot from ever locking anyone out.
|
|
9
|
+
- **`Nondisposable::Tld::SPECIAL_USE`**: the RFC 6761 / RFC 2606 reserved names (`test`, `example`, `invalid`, `localhost`, `local`, `onion`). ⚠️ **Heads up when you switch `check_tld` on**: these are reserved so they can never be delegated, so they aren't in the root zone and are rejected — which is correct for a signup form, and will also turn your fixtures at `user@example.test` red. One line, scoped to where it belongs: `config.additional_tlds = Nondisposable::Tld::SPECIAL_USE if Rails.env.local?`
|
|
10
|
+
- **`config.blocked_tlds`** and **`config.allowed_tlds`**: refuse real TLDs you don't want (the free Freenom set `tk ml ga cf gq` is the usual reason), or invert it into an allowlist.
|
|
11
|
+
- **Lookalike detection**: `Nondisposable.suggestion_for("someone@gmial.com") # => "someone@gmail.com"`, matching against a bundled list of ~240 well-known providers using optimal string alignment distance, so an adjacent swap counts as the one mistake a human actually made. This catches what a TLD check structurally cannot — `.co`, `.cm` and `.om` are Colombia, Cameroon and Oman, all real. Always available, never blocks anything.
|
|
12
|
+
- **`config.reject_lookalike_domains`** (default `false`): turns that suggestion into a validation error naming the correction. Off by default on purpose — a suggestion is a guess about intent, and a wrong guess stops a real person signing up with their real address. `config.lookalike_distance` (default `1`) and `config.additional_email_providers` tune it.
|
|
13
|
+
- **`Nondisposable.valid_tld?(email)`** and **`Nondisposable.suggestion_for(email)`** as direct checks, alongside the existing `disposable?`.
|
|
14
|
+
- **`rake nondisposable:tlds:update`**: refreshes the bundled snapshot from IANA. A maintenance task for a checkout of this gem, not something host apps run — it refuses to overwrite a good list with an implausibly short one, writes atomically, and preserves IANA's version header (readable via `Nondisposable::Tld.version`).
|
|
15
|
+
- New error messages: `invalid_tld_error_message`, `blocked_tld_error_message`, `lookalike_error_message` (which interpolates `%{suggestion}`).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- The validator now adds **at most one error** however many checks fire, and prefers the most useful message available: whenever the gem can name a correction, that phrasing wins over the generic "doesn't look like a real email address". The disposable check still takes precedence over both — a correct spelling wouldn't help a throwaway provider.
|
|
20
|
+
|
|
1
21
|
## [0.3.0] - 2026-08-09
|
|
2
22
|
|
|
3
23
|
### Added
|
data/README.md
CHANGED
|
@@ -17,6 +17,17 @@ That's it! You're done.
|
|
|
17
17
|
|
|
18
18
|
The gem also provides a job you can run daily to keep your disposable domain list up to date.
|
|
19
19
|
|
|
20
|
+
It can also catch the other kind of bad address — the typo. `user@gmail.con` isn't a throwaway, it's a real person whose account nobody will ever be able to reach, because `.con` doesn't exist. Two opt-in checks:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
Nondisposable.configure do |config|
|
|
24
|
+
config.check_tld = true # reject TLDs that aren't in the IANA root zone
|
|
25
|
+
config.reject_lookalike_domains = true # and addresses one keystroke from a real provider
|
|
26
|
+
end
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
See [Catching typos](#catching-typos).
|
|
30
|
+
|
|
20
31
|
## Installation
|
|
21
32
|
|
|
22
33
|
Add this line to your application's Gemfile:
|
|
@@ -103,6 +114,23 @@ Nondisposable.configure do |config|
|
|
|
103
114
|
# Also match parent domains: an email at x.tempmail.com is blocked when
|
|
104
115
|
# tempmail.com is on the list. Set to false for exact matches only.
|
|
105
116
|
config.check_parent_domains = true
|
|
117
|
+
|
|
118
|
+
# --- Catching typos (both OFF by default) ---
|
|
119
|
+
|
|
120
|
+
# Reject addresses whose TLD isn't in the IANA root zone: gmail.con, outlook.ed
|
|
121
|
+
config.check_tld = true
|
|
122
|
+
config.additional_tlds = [] # accept a TLD newer than this gem
|
|
123
|
+
config.blocked_tlds = %w[tk ml ga cf gq] # refuse real TLDs you don't want
|
|
124
|
+
config.allowed_tlds = nil # or allowlist: %w[es com] rejects everything else
|
|
125
|
+
|
|
126
|
+
# Reject addresses one keystroke from a well-known provider: gmail.co, gmial.com
|
|
127
|
+
config.reject_lookalike_domains = false
|
|
128
|
+
config.lookalike_distance = 1 # edits that still count as a typo
|
|
129
|
+
config.additional_email_providers = [] # your own domains / regional providers
|
|
130
|
+
|
|
131
|
+
config.invalid_tld_error_message = "doesn't look like a real email address"
|
|
132
|
+
config.blocked_tld_error_message = "domain ending is not allowed"
|
|
133
|
+
config.lookalike_error_message = "looks like a typo. Did you mean %{suggestion}?"
|
|
106
134
|
end
|
|
107
135
|
```
|
|
108
136
|
|
|
@@ -116,6 +144,81 @@ This is a deliberately minimal, dependency-free approximation of "registrable do
|
|
|
116
144
|
|
|
117
145
|
By default (`on_check_failure = :allow`), if the disposable check raises — say, the database is briefly unavailable — the signup goes through and an error is logged. This is availability-first: a broken check should not lock everyone out of signup. If you'd rather fail closed (reject signups whenever the check cannot run, as versions before 0.3.0 did), set `config.on_check_failure = :reject`.
|
|
118
146
|
|
|
147
|
+
### Catching typos
|
|
148
|
+
|
|
149
|
+
A disposable address is someone hiding from you. A typo is someone who wanted to reach you and won't be able to. Both leave you with a useless row in the users table, so `nondisposable` can catch both — but the typo checks are **opt-in**, because upgrading a gem should never start rejecting addresses that were fine yesterday.
|
|
150
|
+
|
|
151
|
+
#### `config.check_tld` — is that a real domain ending?
|
|
152
|
+
|
|
153
|
+
Every TLD that exists is in the [IANA root zone database](https://data.iana.org/TLD/tlds-alpha-by-domain.txt), and the gem ships a snapshot of it (~1,438 entries, about 9 KB, loaded once into a frozen `Set`). `.con` has never been in it, and never will be.
|
|
154
|
+
|
|
155
|
+
```ruby
|
|
156
|
+
config.check_tld = true
|
|
157
|
+
|
|
158
|
+
Nondisposable.valid_tld?("user@gmail.com") # => true
|
|
159
|
+
Nondisposable.valid_tld?("user@gmail.con") # => false
|
|
160
|
+
Nondisposable.valid_tld?("example@gmailmcom") # => false (no TLD at all)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Details worth knowing:
|
|
164
|
+
|
|
165
|
+
- **No dot, no TLD.** `example@gmailmcom` models a typo observed in production: the dot was missed entirely. A domain with no TLD can't end in a real one, so it's rejected. If your app accepts single-label intranet addresses like `you@localhost`, leave this off for that model.
|
|
166
|
+
- **IP literals are left alone.** `user@192.168.0.1` and `user@[10.0.0.1]` are a format question, and a TLD check has no business answering it. Pair with `format:` if you care.
|
|
167
|
+
- **Unicode TLDs are never rejected.** IANA lists internationalised TLDs in punycode (`XN--FIQS8S`), and converting `例え.テスト` to that form needs an IDN library this gem deliberately doesn't depend on. Rather than reject every unicode address, it declines to judge them. Punycode-form addresses — what mail clients actually send — are checked normally.
|
|
168
|
+
- **A stale snapshot can't trap you.** If ICANN delegates a TLD after your gem version shipped, `config.additional_tlds = %w[newtld]` accepts it immediately, with no release to wait for.
|
|
169
|
+
|
|
170
|
+
> [!IMPORTANT]
|
|
171
|
+
> **`.test` and `.example` are rejected, and that will turn your test suite red.**
|
|
172
|
+
>
|
|
173
|
+
> RFC 6761 and RFC 2606 reserve `test`, `example`, `invalid` and `localhost` precisely so they can never be delegated — which is why they aren't in the root zone, and why your fixtures live at `user@example.test` in the first place. Rejecting them is right for a signup form (no human types `me@home.test`, and mail could never be delivered there), but it's a configuration question, not a bug:
|
|
174
|
+
>
|
|
175
|
+
> ```ruby
|
|
176
|
+
> # config/initializers/nondisposable.rb
|
|
177
|
+
> config.additional_tlds = Nondisposable::Tld::SPECIAL_USE if Rails.env.local?
|
|
178
|
+
> ```
|
|
179
|
+
>
|
|
180
|
+
> Scope it to your non-production environments, so production still refuses an address nobody could ever answer.
|
|
181
|
+
|
|
182
|
+
`blocked_tlds` refuses TLDs that are perfectly real but that you'd rather not see — the historically free Freenom set (`tk`, `ml`, `ga`, `cf`, `gq`) is the usual suspect. `allowed_tlds` inverts it into an allowlist; be careful, `%w[es]` turns away every `.com` customer you have.
|
|
183
|
+
|
|
184
|
+
#### `config.reject_lookalike_domains` — did they mean gmail.com?
|
|
185
|
+
|
|
186
|
+
A TLD check structurally **cannot** catch the most common typos, because `.co` (Colombia), `.cm` (Cameroon) and `.om` (Oman) are all real, delegated TLDs. `user@gmail.co` is a well-formed address at a real TLD and still almost always a finger that slipped off the `m`.
|
|
187
|
+
|
|
188
|
+
So the second check asks a different question: is this domain one edit away from a well-known provider, while not being one itself?
|
|
189
|
+
|
|
190
|
+
```ruby
|
|
191
|
+
Nondisposable.suggestion_for("someone@gmial.com") # => "someone@gmail.com"
|
|
192
|
+
Nondisposable.suggestion_for("someone@gmail.co") # => "someone@gmail.com"
|
|
193
|
+
Nondisposable.suggestion_for("someone@gmail.com") # => nil
|
|
194
|
+
Nondisposable.suggestion_for("someone@mail.com") # => nil (a real provider)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`suggestion_for` is always available and **never blocks anything** — show it as a hint and let the human decide. That's the gentler way to use this, and the one to reach for first:
|
|
198
|
+
|
|
199
|
+
```erb
|
|
200
|
+
<% if (did_you_mean = Nondisposable.suggestion_for(@user.email)) %>
|
|
201
|
+
<p>Did you mean <%= did_you_mean %>?</p>
|
|
202
|
+
<% end %>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Setting `reject_lookalike_domains = true` turns the same guess into a validation error naming the correction. Do that deliberately: a suggestion is a guess about intent, and a wrong guess stops a real person signing up with their real address. Two things keep that rare — matching stops at **one** edit by default (`lookalike_distance`), and an exact match against the bundled provider list always wins, which is why that list includes awkward pairs like `mail.com` (one insertion from `gmail.com`). Add anything we've missed with `config.additional_email_providers`; doing so both makes it a suggestion candidate and stops its users being told they mistyped.
|
|
206
|
+
|
|
207
|
+
The matching uses optimal string alignment distance rather than plain Levenshtein, so an adjacent swap counts as the one mistake a human actually made: `gmial.com` is distance 1, not 2.
|
|
208
|
+
|
|
209
|
+
#### How the two combine
|
|
210
|
+
|
|
211
|
+
At most one error is added, however many checks fire — and whenever the gem can name a correction, that phrasing wins:
|
|
212
|
+
|
|
213
|
+
| Address | `check_tld` only | with `reject_lookalike_domains` |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| `user@gmail.con` | "looks like a typo. Did you mean user@gmail.com?" | same |
|
|
216
|
+
| `user@zzz.con` | "doesn't look like a real email address" | same |
|
|
217
|
+
| `user@gmail.co` | accepted | "looks like a typo. Did you mean user@gmail.com?" |
|
|
218
|
+
| `user@tempmail.com` | "provider is not allowed" | same |
|
|
219
|
+
|
|
220
|
+
"Doesn't look like a real email address" is true but useless when we know what they meant, so a nameable correction always outranks the generic message.
|
|
221
|
+
|
|
119
222
|
### Direct Check
|
|
120
223
|
|
|
121
224
|
You can also check if an email is disposable directly:
|
|
@@ -123,6 +226,8 @@ You can also check if an email is disposable directly:
|
|
|
123
226
|
```ruby
|
|
124
227
|
Nondisposable.disposable?('user@example.com') # => false
|
|
125
228
|
Nondisposable.disposable?('user@disposable-email.com') # => true
|
|
229
|
+
Nondisposable.valid_tld?('user@example.con') # => false
|
|
230
|
+
Nondisposable.suggestion_for('user@gmial.com') # => "user@gmail.com"
|
|
126
231
|
```
|
|
127
232
|
|
|
128
233
|
## Updating disposable domains
|
|
@@ -148,6 +253,24 @@ production:
|
|
|
148
253
|
schedule: every day at 3am US/Pacific
|
|
149
254
|
```
|
|
150
255
|
|
|
256
|
+
## Updating the TLD list
|
|
257
|
+
|
|
258
|
+
The TLD snapshot is the deliberate opposite of the disposable list: it ships **inside the gem**, not in your database, and there is nothing for your app to schedule. Disposable domains number in the thousands and change every few days; TLDs are ~1,438 strings that change a handful of times a year, so a frozen `Set` costs one file read at boot, answers in O(1) with no query per signup, needs no migration, and can't be empty on a fresh install.
|
|
259
|
+
|
|
260
|
+
If ICANN delegates a TLD your installed version doesn't know about, don't wait for a release — that's what `config.additional_tlds` is for.
|
|
261
|
+
|
|
262
|
+
Maintainers refresh the snapshot from a checkout of this gem:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
rake nondisposable:tlds:update # rewrites data/iana_tlds.txt from data.iana.org
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
It refuses to overwrite a good list with an implausibly short one (a captive portal or a truncated body served with a `200`), writes to a temp file and moves it into place so an interrupted run can't leave half a root zone behind, and keeps IANA's own version header so you can always see which root zone you're shipping:
|
|
269
|
+
|
|
270
|
+
```ruby
|
|
271
|
+
Nondisposable::Tld.version # => "2026082301, Last Updated Mon Aug 24 07:07:01 2026 UTC"
|
|
272
|
+
```
|
|
273
|
+
|
|
151
274
|
## Troubleshooting
|
|
152
275
|
|
|
153
276
|
### SSL certificate verify failed (unable to get certificate CRL)
|
data/Rakefile
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
require "bundler/gem_tasks"
|
|
4
4
|
require "rake/testtask"
|
|
5
5
|
|
|
6
|
+
# nondisposable:tlds:update — refreshes data/iana_tlds.txt from the IANA root
|
|
7
|
+
# zone. A maintenance task for this checkout, not something host apps run; see
|
|
8
|
+
# the header of lib/nondisposable/tld_list_updater.rb.
|
|
9
|
+
Dir.glob("lib/tasks/*.rake").each { |task| load task }
|
|
10
|
+
|
|
6
11
|
Rake::TestTask.new(:test) do |t|
|
|
7
12
|
t.libs << "lib"
|
|
8
13
|
t.libs << "test"
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Well-known consumer email domains, used by Nondisposable::Suggestion.
|
|
2
|
+
#
|
|
3
|
+
# This list does TWO jobs, and the second one is the reason it needs to be
|
|
4
|
+
# generous rather than short:
|
|
5
|
+
#
|
|
6
|
+
# 1. It supplies the candidates a typo can be corrected TO. A domain one edit
|
|
7
|
+
# away from an entry here is very probably a slip of the finger.
|
|
8
|
+
# 2. It is the false-positive guard. An EXACT match here is never flagged, so
|
|
9
|
+
# every real provider that happens to sit one edit from another real one
|
|
10
|
+
# must be present. `mail.com` is the canonical example: it is one insertion
|
|
11
|
+
# away from `gmail.com`, and leaving it out would tell every one of its
|
|
12
|
+
# users they had made a typo.
|
|
13
|
+
#
|
|
14
|
+
# Hosts add their own with `config.additional_email_providers`. Order is
|
|
15
|
+
# irrelevant; comments and blank lines are ignored.
|
|
16
|
+
|
|
17
|
+
# --- global ---
|
|
18
|
+
gmail.com
|
|
19
|
+
googlemail.com
|
|
20
|
+
outlook.com
|
|
21
|
+
hotmail.com
|
|
22
|
+
live.com
|
|
23
|
+
msn.com
|
|
24
|
+
passport.com
|
|
25
|
+
yahoo.com
|
|
26
|
+
ymail.com
|
|
27
|
+
rocketmail.com
|
|
28
|
+
icloud.com
|
|
29
|
+
me.com
|
|
30
|
+
mac.com
|
|
31
|
+
aol.com
|
|
32
|
+
mail.com
|
|
33
|
+
email.com
|
|
34
|
+
usa.com
|
|
35
|
+
gmx.com
|
|
36
|
+
gmx.net
|
|
37
|
+
gmx.de
|
|
38
|
+
gmx.at
|
|
39
|
+
gmx.ch
|
|
40
|
+
zoho.com
|
|
41
|
+
zohomail.com
|
|
42
|
+
fastmail.com
|
|
43
|
+
fastmail.fm
|
|
44
|
+
hushmail.com
|
|
45
|
+
protonmail.com
|
|
46
|
+
protonmail.ch
|
|
47
|
+
proton.me
|
|
48
|
+
pm.me
|
|
49
|
+
tutanota.com
|
|
50
|
+
tutanota.de
|
|
51
|
+
tuta.com
|
|
52
|
+
tuta.io
|
|
53
|
+
hey.com
|
|
54
|
+
mailfence.com
|
|
55
|
+
posteo.de
|
|
56
|
+
disroot.org
|
|
57
|
+
riseup.net
|
|
58
|
+
runbox.com
|
|
59
|
+
migadu.com
|
|
60
|
+
purelymail.com
|
|
61
|
+
skiff.com
|
|
62
|
+
duck.com
|
|
63
|
+
|
|
64
|
+
# --- Spain ---
|
|
65
|
+
hotmail.es
|
|
66
|
+
outlook.es
|
|
67
|
+
yahoo.es
|
|
68
|
+
live.com.es
|
|
69
|
+
telefonica.net
|
|
70
|
+
movistar.es
|
|
71
|
+
terra.es
|
|
72
|
+
terra.com
|
|
73
|
+
ya.com
|
|
74
|
+
wanadoo.es
|
|
75
|
+
orange.es
|
|
76
|
+
jazzfree.com
|
|
77
|
+
jazztel.es
|
|
78
|
+
euskaltel.net
|
|
79
|
+
euskalnet.net
|
|
80
|
+
ono.com
|
|
81
|
+
vodafone.es
|
|
82
|
+
telecable.es
|
|
83
|
+
mundo-r.com
|
|
84
|
+
airtel.net
|
|
85
|
+
navegalia.com
|
|
86
|
+
eresmas.com
|
|
87
|
+
inicia.es
|
|
88
|
+
teleline.es
|
|
89
|
+
|
|
90
|
+
# --- Portugal / Latin America ---
|
|
91
|
+
sapo.pt
|
|
92
|
+
netcabo.pt
|
|
93
|
+
clix.pt
|
|
94
|
+
uol.com.br
|
|
95
|
+
bol.com.br
|
|
96
|
+
ig.com.br
|
|
97
|
+
terra.com.br
|
|
98
|
+
globo.com
|
|
99
|
+
globomail.com
|
|
100
|
+
prodigy.net.mx
|
|
101
|
+
hotmail.com.ar
|
|
102
|
+
hotmail.com.mx
|
|
103
|
+
yahoo.com.ar
|
|
104
|
+
yahoo.com.mx
|
|
105
|
+
yahoo.com.br
|
|
106
|
+
|
|
107
|
+
# --- France ---
|
|
108
|
+
orange.fr
|
|
109
|
+
wanadoo.fr
|
|
110
|
+
free.fr
|
|
111
|
+
sfr.fr
|
|
112
|
+
laposte.net
|
|
113
|
+
bbox.fr
|
|
114
|
+
neuf.fr
|
|
115
|
+
aliceadsl.fr
|
|
116
|
+
club-internet.fr
|
|
117
|
+
numericable.fr
|
|
118
|
+
hotmail.fr
|
|
119
|
+
outlook.fr
|
|
120
|
+
yahoo.fr
|
|
121
|
+
live.fr
|
|
122
|
+
|
|
123
|
+
# --- Germany / Austria / Switzerland ---
|
|
124
|
+
web.de
|
|
125
|
+
t-online.de
|
|
126
|
+
freenet.de
|
|
127
|
+
arcor.de
|
|
128
|
+
1und1.de
|
|
129
|
+
online.de
|
|
130
|
+
gmx.info
|
|
131
|
+
hotmail.de
|
|
132
|
+
outlook.de
|
|
133
|
+
yahoo.de
|
|
134
|
+
live.de
|
|
135
|
+
bluewin.ch
|
|
136
|
+
sunrise.ch
|
|
137
|
+
gmail.ch
|
|
138
|
+
|
|
139
|
+
# --- United Kingdom / Ireland ---
|
|
140
|
+
btinternet.com
|
|
141
|
+
sky.com
|
|
142
|
+
virginmedia.com
|
|
143
|
+
talktalk.net
|
|
144
|
+
ntlworld.com
|
|
145
|
+
blueyonder.co.uk
|
|
146
|
+
hotmail.co.uk
|
|
147
|
+
outlook.co.uk
|
|
148
|
+
yahoo.co.uk
|
|
149
|
+
live.co.uk
|
|
150
|
+
googlemail.co.uk
|
|
151
|
+
eircom.net
|
|
152
|
+
|
|
153
|
+
# --- Italy ---
|
|
154
|
+
libero.it
|
|
155
|
+
virgilio.it
|
|
156
|
+
alice.it
|
|
157
|
+
tiscali.it
|
|
158
|
+
tin.it
|
|
159
|
+
fastwebnet.it
|
|
160
|
+
hotmail.it
|
|
161
|
+
outlook.it
|
|
162
|
+
yahoo.it
|
|
163
|
+
live.it
|
|
164
|
+
pec.it
|
|
165
|
+
|
|
166
|
+
# --- Benelux / Nordics / other Europe ---
|
|
167
|
+
telenet.be
|
|
168
|
+
skynet.be
|
|
169
|
+
proximus.be
|
|
170
|
+
ziggo.nl
|
|
171
|
+
kpnmail.nl
|
|
172
|
+
home.nl
|
|
173
|
+
planet.nl
|
|
174
|
+
xs4all.nl
|
|
175
|
+
telia.com
|
|
176
|
+
telia.se
|
|
177
|
+
bredband.net
|
|
178
|
+
spray.se
|
|
179
|
+
hotmail.se
|
|
180
|
+
online.no
|
|
181
|
+
broadpark.no
|
|
182
|
+
tele2.no
|
|
183
|
+
elisanet.fi
|
|
184
|
+
luukku.com
|
|
185
|
+
suomi24.fi
|
|
186
|
+
seznam.cz
|
|
187
|
+
centrum.cz
|
|
188
|
+
wp.pl
|
|
189
|
+
o2.pl
|
|
190
|
+
onet.pl
|
|
191
|
+
interia.pl
|
|
192
|
+
gazeta.pl
|
|
193
|
+
abv.bg
|
|
194
|
+
mail.bg
|
|
195
|
+
freemail.hu
|
|
196
|
+
citromail.hu
|
|
197
|
+
t-online.hu
|
|
198
|
+
|
|
199
|
+
# --- Russia / Eastern Europe ---
|
|
200
|
+
mail.ru
|
|
201
|
+
inbox.ru
|
|
202
|
+
list.ru
|
|
203
|
+
bk.ru
|
|
204
|
+
internet.ru
|
|
205
|
+
yandex.ru
|
|
206
|
+
yandex.com
|
|
207
|
+
ya.ru
|
|
208
|
+
rambler.ru
|
|
209
|
+
ukr.net
|
|
210
|
+
i.ua
|
|
211
|
+
meta.ua
|
|
212
|
+
|
|
213
|
+
# --- Asia ---
|
|
214
|
+
qq.com
|
|
215
|
+
foxmail.com
|
|
216
|
+
163.com
|
|
217
|
+
126.com
|
|
218
|
+
yeah.net
|
|
219
|
+
sina.com
|
|
220
|
+
sina.cn
|
|
221
|
+
sohu.com
|
|
222
|
+
aliyun.com
|
|
223
|
+
naver.com
|
|
224
|
+
daum.net
|
|
225
|
+
hanmail.net
|
|
226
|
+
nate.com
|
|
227
|
+
kakao.com
|
|
228
|
+
docomo.ne.jp
|
|
229
|
+
ezweb.ne.jp
|
|
230
|
+
softbank.ne.jp
|
|
231
|
+
yahoo.co.jp
|
|
232
|
+
ybb.ne.jp
|
|
233
|
+
nifty.com
|
|
234
|
+
biglobe.ne.jp
|
|
235
|
+
so-net.ne.jp
|
|
236
|
+
rediffmail.com
|
|
237
|
+
sify.com
|
|
238
|
+
|
|
239
|
+
# --- North America ISPs ---
|
|
240
|
+
comcast.net
|
|
241
|
+
xfinity.com
|
|
242
|
+
verizon.net
|
|
243
|
+
att.net
|
|
244
|
+
sbcglobal.net
|
|
245
|
+
bellsouth.net
|
|
246
|
+
ameritech.net
|
|
247
|
+
pacbell.net
|
|
248
|
+
cox.net
|
|
249
|
+
charter.net
|
|
250
|
+
spectrum.net
|
|
251
|
+
earthlink.net
|
|
252
|
+
juno.com
|
|
253
|
+
netzero.net
|
|
254
|
+
optonline.net
|
|
255
|
+
roadrunner.com
|
|
256
|
+
rr.com
|
|
257
|
+
windstream.net
|
|
258
|
+
frontier.com
|
|
259
|
+
centurylink.net
|
|
260
|
+
shaw.ca
|
|
261
|
+
rogers.com
|
|
262
|
+
sympatico.ca
|
|
263
|
+
telus.net
|
|
264
|
+
videotron.ca
|
|
265
|
+
bell.net
|
|
266
|
+
|
|
267
|
+
# --- Oceania / Africa ---
|
|
268
|
+
bigpond.com
|
|
269
|
+
bigpond.net.au
|
|
270
|
+
optusnet.com.au
|
|
271
|
+
iinet.net.au
|
|
272
|
+
tpg.com.au
|
|
273
|
+
xtra.co.nz
|
|
274
|
+
webmail.co.za
|
|
275
|
+
telkomsa.net
|
|
276
|
+
mweb.co.za
|