| Index: src/org/adblockplus/android/AdblockPlus.java |
| =================================================================== |
| --- a/src/org/adblockplus/android/AdblockPlus.java |
| +++ b/src/org/adblockplus/android/AdblockPlus.java |
| @@ -23,7 +23,14 @@ |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| +import java.util.ArrayList; |
| import java.util.Calendar; |
| +import java.util.Collections; |
| +import java.util.HashMap; |
| +import java.util.HashSet; |
| +import java.util.List; |
| +import java.util.Map; |
| +import java.util.Set; |
| import java.util.TimeZone; |
| import java.util.regex.Pattern; |
| @@ -82,6 +89,8 @@ |
| private static AdblockPlus instance; |
| + private Map<String, Set<String>> referrerMapping = new HashMap<String, Set<String>>(); |
| + |
| /** |
| * Returns pointer to itself (singleton pattern). |
| */ |
| @@ -314,6 +323,9 @@ |
| */ |
| public boolean matches(String url, String query, String referrer, String accept) |
| { |
| + if (referrer != null) |
| + recordReferrer(url, referrer); |
| + |
| if (!filteringEnabled) |
| return false; |
| @@ -344,7 +356,51 @@ |
| if (!"".equals(query)) |
| url = url + "?" + query; |
| - return abpEngine.matches(url, contentType, referrer); |
| + final List<List<String>> referrerChains = referrer != null |
| + ? buildReferrerChains(referrer) |
| + : Collections.singletonList(Collections.<String>emptyList()); |
| + for (List<String> referrerChain : referrerChains) |
| + { |
| + Log.d("Referrer chain", url + ": " + referrerChain.toString()); |
| + String[] referrerChainArray = referrerChain.toArray(new String[referrerChain.size()]); |
| + if (abpEngine.matches(url, contentType, referrerChainArray)) |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + private void recordReferrer(String url, String referrer) |
| + { |
| + // TODO: Garbage collect the mapping - currently it will grow out of control. |
| + // In addition, we might have to persist mappings, because clients are |
| + // likely to cache some requests in the chain. |
| + if (!referrerMapping.containsKey(url)) |
| + referrerMapping.put(url, new HashSet<String>()); |
| + Set<String> referrers = referrerMapping.get(url); |
| + referrers.add(referrer); |
|
Wladimir Palant
2013/11/25 10:24:41
Do you think that this is really necessary? We are
Felix Dahlke
2013/11/27 12:19:32
Yes, I think it makes sense to not have a single c
Wladimir Palant
2013/11/27 12:59:01
Not with the same parameters - they have to know s
Felix Dahlke
2013/11/27 13:38:59
Alright, didn't think of that. Makes the code much
|
| + } |
| + |
| + private List<List<String>> buildReferrerChains(String url) |
| + { |
| + List<List<String>> referrerChains = new ArrayList<List<String>>(); |
| + Set<String> referrers = referrerMapping.get(url); |
| + if (referrers == null) |
| + { |
| + List<String> referrerChain = new ArrayList<String>(); |
| + referrerChain.add(url); |
| + referrerChains.add(referrerChain); |
| + return referrerChains; |
| + } |
| + |
| + for (String referrer : referrers) { |
| + List<List<String>> currentReferrerChains = buildReferrerChains(referrer); |
| + for (List<String> referrerChain : currentReferrerChains) |
| + { |
| + referrerChain.add(0, url); |
| + referrerChains.add(referrerChain); |
| + } |
| + } |
| + return referrerChains; |
| } |
| /** |