1 module hunt.service.util.UrlHelper; 2 3 import hunt.service.util.UrlInfo; 4 import hunt.collection.ArrayList; 5 import hunt.collection.HashMap; 6 import hunt.collection.List; 7 import hunt.collection.Map; 8 import hunt.Exceptions; 9 import hunt.text.StringBuilder; 10 import std.string; 11 import std.conv; 12 import hunt.text.Common; 13 import hunt.text.StringUtils; 14 import hunt.service.util.CommonUtils; 15 16 17 enum UrlInfoAttrs 18 { 19 ATTR_RPC_VERSION = "rpcVer", 20 ATTR_SERIALIZATION = "serialization", 21 ATTR_WEIGHT = "weight", 22 } 23 24 public class UrlHelper { 25 26 27 /** 28 * Compare two provider list, return add list and remove list 29 * 30 * @param oldList old Provider list 31 * @param newList new provider list 32 * @param add provider list need add 33 * @param remove provider list need remove 34 */ 35 // public static void compareProviders(List!(UrlInfo) oldList, List!(UrlInfo) newList, 36 // List!(UrlInfo) add, List!(UrlInfo) remove) { 37 // // 比较老列表和当前列表 38 // if (oldList is null || oldList.size == 0) { 39 // // 空变成非空 40 // if (newList !is null) { 41 // add.addAll(newList); 42 // } 43 // // 空到空,忽略 44 // } else { 45 // // 非空变成空 46 // if (newList is null || newList.size == 0) { 47 // remove.addAll(oldList); 48 // } else { 49 // // 非空变成非空,比较 50 // if (oldList !is null) { 51 // List!(UrlInfo) tmpList = new ArrayList!(UrlInfo)(); 52 // foreach(value; newList) { 53 // tmpList.add(value); 54 // } 55 // // 遍历老的 56 // foreach (UrlInfo oldProvider ; oldList) { 57 // if (tmpList.contains(oldProvider)) { 58 // tmpList.remove(oldProvider); 59 // } else { 60 // // 新的没有,老的有,删掉 61 // remove.add(oldProvider); 62 // } 63 // } 64 // add.addAll(tmpList); 65 // } 66 // } 67 // } 68 // } 69 70 /** 71 * Write provider info to url string 72 * 73 * @param providerInfo Provide info 74 * @return the string 75 */ 76 public static string toUrl(UrlInfo providerInfo) { 77 string uri = providerInfo.getProtocolType() ~ "://" ~ providerInfo.getHost().to!string ~ ":" ~ providerInfo.getPort().to!string; 78 uri ~= strip(providerInfo.getPath()); 79 StringBuilder sb = new StringBuilder(); 80 if (providerInfo.getRpcVersion() > 0) { 81 sb.append("&").append(UrlInfoAttrs.ATTR_RPC_VERSION).append("=").append(providerInfo.getRpcVersion()); 82 } 83 if (providerInfo.getSerializationType() != null) { 84 sb.append("&").append(UrlInfoAttrs.ATTR_SERIALIZATION).append("=") 85 .append(providerInfo.getSerializationType()); 86 } 87 foreach(string k , string v ; providerInfo.getStaticAttrs()) { 88 sb.append("&").append(k).append("=").append(v); 89 } 90 if (sb.length() > 0) { 91 uri ~= sb.replace(0, 1, "?").toString(); 92 } 93 return uri; 94 } 95 96 /** 97 * Parse url string to UrlInfo. 98 * 99 * @param url the url 100 * @return UrlInfo 101 */ 102 public static UrlInfo toProviderInfo(string url) { 103 UrlInfo providerInfo = new UrlInfo(); 104 providerInfo.setOriginUrl(url); 105 try { 106 int protocolIndex = cast(int)(url.indexOf("://")); 107 string remainUrl; 108 if (protocolIndex > -1) { 109 string protocol = url.substring(0, protocolIndex).toLower(); 110 providerInfo.setProtocolType(protocol); 111 remainUrl = url.substring(protocolIndex + 3); 112 } else { // 默认 113 remainUrl = url; 114 } 115 116 int addressIndex = cast(int)(remainUrl.indexOf("/")); 117 string address; 118 if (addressIndex > -1) { 119 address = remainUrl.substring(0, addressIndex); 120 remainUrl = remainUrl.substring(addressIndex); 121 } else { 122 int itfIndex = cast(int)(remainUrl.indexOf('?')); 123 if (itfIndex > -1) { 124 address = remainUrl.substring(0, itfIndex); 125 remainUrl = remainUrl.substring(itfIndex); 126 } else { 127 address = remainUrl; 128 remainUrl = ""; 129 } 130 } 131 string[] ipAndPort = StringUtils.split(address,":", -1); // TODO 不支持ipv6 132 providerInfo.setHost(ipAndPort[0]); 133 if (ipAndPort.length > 1) { 134 providerInfo.setPort(CommonUtils.parseInt(ipAndPort[1], providerInfo.getPort())); 135 } 136 137 // 后面可以解析remainUrl得到interface等 /xxx?a=1&b=2 138 if (remainUrl.length > 0) { 139 int itfIndex = cast(int)(remainUrl.indexOf('?')); 140 if (itfIndex > -1) { 141 string itf = remainUrl.substring(0, itfIndex); 142 providerInfo.setPath(itf); 143 // 剩下是params,例如a=1&b=2 144 remainUrl = remainUrl.substring(itfIndex + 1); 145 string[] params = StringUtils.split(remainUrl,"&", -1); 146 foreach (string parm ; params) { 147 string[] kvpair = StringUtils.split(parm,"=", -1); 148 if (UrlInfoAttrs.ATTR_WEIGHT.equals(kvpair[0]) && CommonUtils.isNotEmpty(kvpair[1])) { 149 int weight = CommonUtils.parseInt(kvpair[1], providerInfo.getWeight()); 150 providerInfo.setWeight(weight); 151 providerInfo.setStaticAttr(UrlInfoAttrs.ATTR_WEIGHT, to!string(weight)); 152 } else if (UrlInfoAttrs.ATTR_RPC_VERSION == kvpair[0] && CommonUtils.isNotEmpty(kvpair[1])) { 153 providerInfo.setRpcVersion(CommonUtils.parseInt(kvpair[1], providerInfo.getRpcVersion())); 154 } else if (UrlInfoAttrs.ATTR_SERIALIZATION == kvpair[0] && 155 CommonUtils.isNotEmpty(kvpair[1])) { 156 providerInfo.setSerializationType(kvpair[1]); 157 } else { 158 providerInfo.getStaticAttrs().put(kvpair[0], kvpair[1]); 159 } 160 161 } 162 } else { 163 providerInfo.setPath(remainUrl); 164 } 165 } else { 166 providerInfo.setPath(""); 167 } 168 } catch (Exception e) { 169 throw new IllegalArgumentException("Failed to convert url to provider, the wrong url is:" ~ url, e); 170 } 171 return providerInfo; 172 } 173 }