1 /* 2 * Copyright 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.net.module.util; 18 19 import android.text.TextUtils; 20 21 import java.util.Arrays; 22 import java.util.Collections; 23 import java.util.List; 24 import java.util.Locale; 25 import java.util.regex.Matcher; 26 import java.util.regex.Pattern; 27 28 /** 29 * Collection of network common utilities. 30 * 31 * @hide 32 */ 33 public final class ProxyUtils { 34 35 public static final int PROXY_VALID = 0; 36 public static final int PROXY_HOSTNAME_EMPTY = 1; 37 public static final int PROXY_HOSTNAME_INVALID = 2; 38 public static final int PROXY_PORT_EMPTY = 3; 39 public static final int PROXY_PORT_INVALID = 4; 40 public static final int PROXY_EXCLLIST_INVALID = 5; 41 42 // Hostname / IP REGEX validation 43 // Matches blank input, ips, and domain names 44 private static final String NAME_IP_REGEX = 45 "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*"; 46 private static final Pattern HOSTNAME_PATTERN; 47 private static final String HOSTNAME_REGEXP = "^$|^" + NAME_IP_REGEX + "$"; 48 private static final Pattern EXCLLIST_PATTERN; 49 private static final String EXCL_REGEX = 50 "[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*(\\.[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*)*"; 51 private static final String EXCLLIST_REGEXP = "^$|^" + EXCL_REGEX + "(," + EXCL_REGEX + ")*$"; 52 static { 53 HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP); 54 EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP); 55 } 56 57 /** Converts exclusion list from String to List. */ exclusionStringAsList(String exclusionList)58 public static List<String> exclusionStringAsList(String exclusionList) { 59 if (exclusionList == null) { 60 return Collections.emptyList(); 61 } 62 return Arrays.asList(exclusionList.toLowerCase(Locale.ROOT).split(",")); 63 } 64 65 /** Converts exclusion list from List to string */ exclusionListAsString(String[] exclusionList)66 public static String exclusionListAsString(String[] exclusionList) { 67 if (exclusionList == null) { 68 return ""; 69 } 70 return TextUtils.join(",", exclusionList); 71 } 72 73 /** 74 * Validate syntax of hostname, port and exclusion list entries 75 */ validate(String hostname, String port, String exclList)76 public static int validate(String hostname, String port, String exclList) { 77 Matcher match = HOSTNAME_PATTERN.matcher(hostname); 78 Matcher listMatch = EXCLLIST_PATTERN.matcher(exclList); 79 80 if (!match.matches()) return PROXY_HOSTNAME_INVALID; 81 82 if (!listMatch.matches()) return PROXY_EXCLLIST_INVALID; 83 84 if (hostname.length() > 0 && port.length() == 0) return PROXY_PORT_EMPTY; 85 86 if (port.length() > 0) { 87 if (hostname.length() == 0) return PROXY_HOSTNAME_EMPTY; 88 int portVal = -1; 89 try { 90 portVal = Integer.parseInt(port); 91 } catch (NumberFormatException ex) { 92 return PROXY_PORT_INVALID; 93 } 94 if (portVal <= 0 || portVal > 0xFFFF) return PROXY_PORT_INVALID; 95 } 96 return PROXY_VALID; 97 } 98 } 99