Retrofit、OkHttp3 和 Spring 偶发错误请求被拒绝,因为 URL 包含潜在的恶意字符串“;”
Retrofit, OkHttp3 and Spring occasional error The request was rejected because the URL contained a potentially malicious String ";"
我们遇到网络错误,不确定是什么原因导致的。我们从 Android 应用程序上传数据,大多数情况下效果很好。
使用接口通过 Retrofit 和 OKHttp3 发送数据:
private static String BASE_URL = "https://backend.ourapp.com/api/";
private static String cert1 = ...;
private static String cert2 = ...;
private static String cert3 = ...;
public static Retrofit retrofit;
static Gson gson = new GsonBuilder()
.setLenient()
.create();
static CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("backend.ourapp.com", cert1)
.add("backend.ourapp.com", cert2)
.add("backend.ourapp.com", cert3)
.build();
public static HttpLoggingInterceptor logging =
new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
public static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(180, TimeUnit.SECONDS)
.connectTimeout(180, TimeUnit.SECONDS)
.certificatePinner(certificatePinner)
.addInterceptor(logging)
.build();
public static Retrofit getClient(String url) {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
}
return retrofit;
}
public static ApiInterface apiInterface() {
retrofit = null;
return ApiClient.getClient(BASE_URL).create(ApiInterface.class);
}
但突然间,随机地,我们开始遇到问题。来自后端日志的错误是:
ERROR org.apache.juli.logging.DirectJDKLog [http-nio-7200-exec-1] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
我们知道这是 StrictHttpFirewall
的一部分,不打算使用 .setAllowSemicolon(true);
。
但我们很困惑为什么会发生这种情况,因为据我们所知,我们没有向我们的 URL 附加任何内容。这个错误似乎也是随机弹出,然后随机消失。它也不是普遍的——一个用户会开始遇到问题,而其他人还好,然后他们就会没事。它通常发生在移动数据网络而不是 wifi 上。
建议??其他我们应该看的东西?不要以为它可能以某种方式与证书相关?我们已经相当宽松地设置超时,因为我们的应用程序在通常很慢的网络上使用,但如果没有发生此特定错误,上传通常会成功。我们正在使用 retrofit 2.4
和 okhttp3 3.10
.
谢谢
似乎只需将 Retrofit 更新为 2.9.0 并将 OkHttp3 更新为 4.9.1 即可解决问题。
我们遇到网络错误,不确定是什么原因导致的。我们从 Android 应用程序上传数据,大多数情况下效果很好。
使用接口通过 Retrofit 和 OKHttp3 发送数据:
private static String BASE_URL = "https://backend.ourapp.com/api/";
private static String cert1 = ...;
private static String cert2 = ...;
private static String cert3 = ...;
public static Retrofit retrofit;
static Gson gson = new GsonBuilder()
.setLenient()
.create();
static CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("backend.ourapp.com", cert1)
.add("backend.ourapp.com", cert2)
.add("backend.ourapp.com", cert3)
.build();
public static HttpLoggingInterceptor logging =
new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
public static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(180, TimeUnit.SECONDS)
.connectTimeout(180, TimeUnit.SECONDS)
.certificatePinner(certificatePinner)
.addInterceptor(logging)
.build();
public static Retrofit getClient(String url) {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
}
return retrofit;
}
public static ApiInterface apiInterface() {
retrofit = null;
return ApiClient.getClient(BASE_URL).create(ApiInterface.class);
}
但突然间,随机地,我们开始遇到问题。来自后端日志的错误是:
ERROR org.apache.juli.logging.DirectJDKLog [http-nio-7200-exec-1] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
我们知道这是 StrictHttpFirewall
的一部分,不打算使用 .setAllowSemicolon(true);
。
但我们很困惑为什么会发生这种情况,因为据我们所知,我们没有向我们的 URL 附加任何内容。这个错误似乎也是随机弹出,然后随机消失。它也不是普遍的——一个用户会开始遇到问题,而其他人还好,然后他们就会没事。它通常发生在移动数据网络而不是 wifi 上。
建议??其他我们应该看的东西?不要以为它可能以某种方式与证书相关?我们已经相当宽松地设置超时,因为我们的应用程序在通常很慢的网络上使用,但如果没有发生此特定错误,上传通常会成功。我们正在使用 retrofit 2.4
和 okhttp3 3.10
.
谢谢
似乎只需将 Retrofit 更新为 2.9.0 并将 OkHttp3 更新为 4.9.1 即可解决问题。