控制台报错
java.lang.IllegalArgumentException: The character [_] is never valid in a domain name.
at org.apache.tomcat.util.http.parser.HttpParser$DomainParseState.next(HttpParser.java:752)
at org.apache.tomcat.util.http.parser.HttpParser.readHostDomainName(HttpParser.java:605)
at org.apache.tomcat.util.http.parser.Test.main(Test.java:17)
bug复现
public class Test {
public static void main(String[] args) {
String domain="kk_ms.luoluo.com";
StringReader reader=new StringReader(domain);
try {
HttpParser.readHostDomainName(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
}
分析得原因为域名中包含下划线,在tomcat中HttpParser会对域名进行效验,有下划线会报错
解决方案
在项目中插入包 org.apache.tomcat.util.http.parser,复制HttpParser类并修改
public class HttpParser {
...
private static enum DomainParseState {
NEW(true, false, false, false, "http.invalidCharacterDomain.atStart"),
ALPHA(true, true, true, true, "http.invalidCharacterDomain.afterLetter"),
NUMERIC(true, true, true, true, "http.invalidCharacterDomain.afterNumber"),
PERIOD(true, false, false, true, "http.invalidCharacterDomain.afterPeriod"),
HYPHEN(true, true, false, false, "http.invalidCharacterDomain.afterHyphen"),
//在此添加下环线匹配
UNDERSCORE(true, false, false, false, "http.invalidCharacterDomain.afterUnderScore"),
COLON(false, false, false, false, "http.invalidCharacterDomain.afterColon"),
END(false, false, false, false, "http.invalidCharacterDomain.atEnd");
private final boolean mayContinue;
private final boolean allowsHyphen;
private final boolean allowsPeriod;
private final boolean allowsEnd;
private final String errorMsg;
private DomainParseState(boolean mayContinue, boolean allowsHyphen, boolean allowsPeriod, boolean allowsEnd, String errorMsg) {
this.mayContinue = mayContinue;
this.allowsHyphen = allowsHyphen;
this.allowsPeriod = allowsPeriod;
this.allowsEnd = allowsEnd;
this.errorMsg = errorMsg;
}
public boolean mayContinue() {
return this.mayContinue;
}
public HttpParser.DomainParseState next(int c) {
if (c == -1) {
if (this.allowsEnd) {
return END;
} else {
throw new IllegalArgumentException(HttpParser.sm.getString("http.invalidSegmentEndState", new Object[]{this.name()}));
}
} else if (HttpParser.isAlpha(c)) {
return ALPHA;
} else if (HttpParser.isNumeric(c)) {
return NUMERIC;
} else if (c == 46) {
if (this.allowsPeriod) {
return PERIOD;
} else {
throw new IllegalArgumentException(HttpParser.sm.getString(this.errorMsg, new Object[]{Character.toString((char)c)}));
}
} else if (c == 58) {
if (this.allowsEnd) {
return COLON;
} else {
throw new IllegalArgumentException(HttpParser.sm.getString(this.errorMsg, new Object[]{Character.toString((char)c)}));
}
} else if (c == 45) {
if (this.allowsHyphen) {
return HYPHEN;
} else {
throw new IllegalArgumentException(HttpParser.sm.getString(this.errorMsg, new Object[]{Character.toString((char)c)}));
}
}
//匹配表达式
else if (c == 95){
return UNDERSCORE;
}
else{
throw new IllegalArgumentException(HttpParser.sm.getString("http.illegalCharacterDomain", new Object[]{Character.toString((char)c)}));
}
}
}
}
...
到此就结束了,还是很简单的。