FileDocCategorySizeDatePackage
UrlRules.javaAPI DocAndroid 1.5 API8782Wed May 06 22:41:56 BST 2009com.google.android.net

UrlRules

public class UrlRules extends Object
A set of rules rewriting and blocking URLs. Used to offer a point of control for redirecting HTTP requests, often to the Android proxy server.

Each rule has the following format:

url-prefix [REWRITE new-prefix] [BLOCK]

Any URL which starts with url-prefix will trigger the rule. If BLOCK is specified, requests to that URL will be blocked and fail. If REWRITE is specified, the matching prefix will be removed and replaced with new-prefix. (If both are specified, BLOCK wins.) Case is insensitive for the REWRITE and BLOCK keywords, but sensitive for URLs.

In Gservices, the value of any key that starts with "url:" will be interpreted as a rule. The full name of the key is unimportant (but can be used to document the intent of the rule, and must be unique). Example gservices keys:

url:use_proxy_for_calendar = "http://www.google.com/calendar/ REWRITE http://android.clients.google.com/proxy/calendar/"
url:stop_crash_reports = "http://android.clients.google.com/crash/ BLOCK"
url:use_ssl_for_contacts = "http://www.google.com/m8/ REWRITE https://www.google.com/m8/"

Fields Summary
private static UrlRules
sCachedRules
Cached rule set from Gservices.
private static final Pattern
PATTERN_SPACE_PLUS
private static final Pattern
RULE_PATTERN
private static String
sCachedDigest
Gservices digest when sCachedRules was cached.
private final Rule[]
mRules
Currently active set of Rules.
private final Pattern
mPattern
Regular expression with one capturing group for each Rule.
Constructors Summary
public UrlRules(Rule[] rules)
Create a rewriter from an array of Rules. Normally used only for testing. Instead, use {@link #getRules} to get rules from Gservices.

param
rules to use.


                                     
       
        // Sort the rules to put the most specific rules first.
        Arrays.sort(rules);

        // Construct a regular expression, escaping all the prefix strings.
        StringBuilder pattern = new StringBuilder("(");
        for (int i = 0; i < rules.length; ++i) {
            if (i > 0) pattern.append(")|(");
            pattern.append(RULE_PATTERN.matcher(rules[i].mPrefix).replaceAll("\\\\$0"));
        }
        mPattern = Pattern.compile(pattern.append(")").toString());
        mRules = rules;
    
Methods Summary
public static synchronized com.google.android.net.UrlRulesgetRules(android.content.ContentResolver resolver)
Get the (possibly cached) UrlRules based on the rules in Gservices.

param
resolver to use for accessing the Gservices database.
return
an updated UrlRules instance

        String digest = Settings.Gservices.getString(resolver,
                Settings.Gservices.PROVISIONING_DIGEST);
        if (sCachedDigest != null && sCachedDigest.equals(digest)) {
            // The digest is the same, so the rules are the same.
            return sCachedRules;
        }

        // Get all the Gservices settings with names starting with "url:".
        Cursor cursor = resolver.query(Settings.Gservices.CONTENT_URI,
                new String[] {
                    Settings.Gservices.NAME,
                    Settings.Gservices.VALUE
                },
                Settings.Gservices.NAME + " like \"url:%\"", null,
                Settings.Gservices.NAME);
        try {
            ArrayList<Rule> rules = new ArrayList<Rule>();
            while (cursor.moveToNext()) {
                try {
                    String name = cursor.getString(0).substring(4);  // "url:X"
                    String value = cursor.getString(1);
                    if (value == null || value.length() == 0) continue;
                    rules.add(new Rule(name, value));
                } catch (RuleFormatException e) {
                    // Oops, Gservices has an invalid rule!  Skip it.
                    Log.e("UrlRules", "Invalid rule from Gservices", e);
                    Checkin.logEvent(resolver,
                        Checkin.Events.Tag.GSERVICES_ERROR, e.toString());
                }
            }
            sCachedRules = new UrlRules(rules.toArray(new Rule[rules.size()]));
            sCachedDigest = digest;
        } finally {
            cursor.close();
        }

        return sCachedRules;
    
public com.google.android.net.UrlRules$RulematchRule(java.lang.String url)
Match a string against every Rule and find one that matches.

param
uri to match against the Rules in the rewriter.
return
the most specific matching Rule, or Rule.DEFAULT if none match.

        Matcher matcher = mPattern.matcher(url);
        if (matcher.lookingAt()) {
            for (int i = 0; i < mRules.length; ++i) {
                if (matcher.group(i + 1) != null) {
                    return mRules[i];  // Rules are sorted most specific first.
                }
            }
        }
        return Rule.DEFAULT;