记录一次okhttp2.5.0 的崩溃
程序员文章站
2022-05-31 11:30:43
...
上周日广告业务方用了一个url含有非法字符,直接造成应用崩溃,具体堆栈如下
url:http://ad.doubleclick.net/d.2106709/B23588639.262890003;dc_trk_aid=459253925;dc_trk_cid=126720019;u=REQUESTID;ord=[timestamp]?
java.lang.IllegalStateException: not valid as a java.net.URI: https://ad.doubleclick.net/d.2106709/B23588639.262890003;dc_trk_aid=459253925;dc_trk_cid=126720019;u=__REQUESTID__;ord=[timestamp%7C?
at com.squareup.okhttp.HttpUrl.uri(HttpUrl.java:336)
at com.squareup.okhttp.internal.http.RouteSelector.resetNextProxy(RouteSelector.java:135)
at com.squareup.okhttp.internal.http.RouteSelector.<init>(RouteSelector.java:71)
at com.squareup.okhttp.internal.http.RouteSelector.get(RouteSelector.java:76)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:321)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:245)
at com.squareup.okhttp.Call.getResponse(Call.java:267)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:224)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:195)
at com.squareup.okhttp.Call.execute(Call.java:79)```
但是在高版本的okhttp不会出现此崩溃。查了下源码,原因在这里
okhttp 2.5 HttpUrl类:
/**
* Attempt to convert this URL to a {@link URI java.net.URI}. This method throws an unchecked
* {@link IllegalStateException} if the URL it holds isn't valid by URI's overly-stringent
* standard. For example, URI rejects paths containing the '[' character. Consult that class for
* the exact rules of what URLs are permitted.
*/
public URI uri() {
try {
return new URI(url);
} catch (URISyntaxException e) {
throw new IllegalStateException("not valid as a java.net.URI: " + url);
}
}
okhttp 4.2.1 HttpUrl:
/**
* Returns this URL as a [java.net.URI][URI]. Because `URI` is more strict than this class, the
* returned URI may be semantically different from this URL:
*
* * Characters forbidden by URI like `[` and `|` will be escaped.
*
* * Invalid percent-encoded sequences like `%xx` will be encoded like `%25xx`.
*
* * Whitespace and control characters in the fragment will be stripped.
*
* These differences may have a significant consequence when the URI is interpreted by a
* web server. For this reason the [URI class][URI] and this method should be avoided.
*/
@JvmName("uri") fun toUri(): URI {
val uri = newBuilder().reencodeForUri().toString()
return try {
URI(uri)
} catch (e: URISyntaxException) {
// Unlikely edge case: the URI has a forbidden character in the fragment. Strip it & retry.
try {
val stripped = uri.replace(Regex("[\\u0000-\\u001F\\u007F-\\u009F\\p{javaWhitespace}]"), "")
URI.create(stripped)
} catch (e1: Exception) {
throw RuntimeException(e) // Unexpected!
}
}
}
高版本的okhttp HttpUrl 类的uri方法,对特殊字符又进行了转义,所以不会出现crash