В моем приложении я использую HttpUrlConnection для загрузки файла на сервер, когда я хочу загрузить большой файл, nginx дает мне код исключения 413, но getResponseCode HttpUrlConnection не может поймать исключение, я получил еще одно сообщение об исключении. Вот сообщение об исключении:
error asyncExecute:Write error: ssl=0x7ec7b80008: I/O error during system call, Connection reset by peer
Вот мой код:
URL originUrl = new URL(url);
String protocol = originUrl.getProtocol();
if (TextUtils.equals(protocol, "http")) {
port = 80;
}
mURL = new URL(protocol, originUrl.getHost(), port, originUrl.getFile());
mConn = (HttpURLConnection) mURL.openConnection();
if (mConn instanceof HttpsURLConnection) {
selfSignedCertificate = true;
SSLCustomSocketFactory factory = new SSLCustomSocketFactory(selfSignedCertificate ? SSLCustomSocketFactory.getSocketFactory()
: (SSLSocketFactory) SSLSocketFactory.getDefault());
((HttpsURLConnection) mConn).setSSLSocketFactory(factory);
((HttpsURLConnection) mConn).setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
mConn.setRequestMethod("POST");
mConn.setDoOutput(true);
mConn.setDoInput(true);
mConn.setUseCaches(false);
mConn.setConnectTimeout(30000);
mConn.setReadTimeout(30000);
mConn.setRequestProperty("User-agent", "xxxx");//xxxx涉及到项目中信息不展示
mConn.setRequestProperty("Connection", "Keep-Alive");
mConn.setRequestProperty("Charset", "UTF-8");
mConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
mConn.setRequestProperty("Expect", "100-Continue");
mConn.setChunkedStreamingMode(0);
//request headers
for (Map.Entry<String, String> item : headers.entrySet()) {
mConn.setRequestProperty(item.getKey(), item.getValue());
}
mConn.connect();
//get outputStream
DataOutputStream out = new DataOutputStream(connect.getOutputStream());
//write params
out.write(params.getBytes());
out.flush();
StringBuffer strBuf = new StringBuffer();
for (String key : paramsMap.keySet()){
strBuf.append(TWO_HYPHENS);
strBuf.append(BOUNDARY);
strBuf.append(LINE_END);
strBuf.append("Content-Disposition: form-data; name=\"" + key + "\"");
strBuf.append(LINE_END);
strBuf.append("Content-Type: " + "text/plain" );
strBuf.append(LINE_END);
strBuf.append("Content-Length: "+paramsMap.get(key).length());
strBuf.append(LINE_END);
strBuf.append(LINE_END);
strBuf.append(paramsMap.get(key));
strBuf.append(LINE_END);
}
String paramsString = strBuf.toString();
out.write(paramsString.getBytes());
out.flush();
String fileName = UriUtils.getFileNameByUri(mContext, fileUri);
String mimeType = UriUtils.getMimeType(mContext, fileUri);
long fileLength = UriUtils.getFileLength(mContext, fileUri);
if(!TextUtils.isEmpty(filename)) {
fileName = filename;
}
//add file headers
out.write(getFileHeaderParamsString(fileKey, fileName, mimeType, fileLength).getBytes());
//add file body
String filePath = UriUtils.getFilePath(fileUri);
InputStream in = null;
try {
if (!TextUtils.isEmpty(filePath) && new File(filePath).exists()) {
in = new FileInputStream(new File(filePath));
} else {
in = mContext.getContentResolver().openInputStream(fileUri);
}
byte[] tmp = new byte[2048];
int l;
long sum = 0;
while ((l = in.read(tmp)) != -1) {
out.write(tmp, 0, l);
sum += l;
if (callback != null) {
callback.onProgress(fileLength, sum);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
//add file end
out.write(getFileEndString().getBytes());
out.flush();
HttpResponse response = new HttpResponse();
//can't get response code here
response.code = mConn.getResponseCode();
if(response.code == HttpURLConnection.HTTP_OK) {
response.contentLength = mConn.getContentLength();
response.inputStream = mConn.getInputStream();
response.content = parseStream(response.inputStream);
}else {
response.errorStream = mConn.getErrorStream();
response.content = parseStream(response.errorStream);
}
......
public static class SSLCustomSocketFactory extends SSLSocketFactory {
private static final String TAG = "SSLCustomSocketFactory";
private static final String[] TLS_SUPPORT_VERSION = {"TLSv1.1", "TLSv1.2"};
private static final String KEY_PASS = "";
final SSLSocketFactory delegate;
static SSLContext sslContext;
static SSLSocketFactory mSocketFactory;
public SSLCustomSocketFactory(SSLSocketFactory base) {
delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if(s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_SUPPORT_VERSION);
}
return s;
}
public static synchronized SSLSocketFactory getSocketFactory() {
if(mSocketFactory == null) {
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
AssetManager am = context().getAssets();
String[] certsPaths = am.list("xxx_certs");
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
for (int i = 0; i < certsPaths.length; i++) {
String certPath = certsPaths[i];
InputStream caInput = null;
try {
caInput = am.open("xxxx_certs/" + certPath);
Certificate ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
keyStore.setCertificateEntry("ca" + i, ca);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (caInput != null) {
caInput.close();
}
}
}
sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory tmf = TrustManagerFactory.
getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
sslContext.init(null, tmf.getTrustManagers(), null);
mSocketFactory = sslContext.getSocketFactory();
} catch (Throwable e) {
e.printStackTrace();
}
}
return mSocketFactory;
}
}
Вот результат nagix:
<html>
<head>
<title>413 Request Entity Too Large</title>
</head>
<body>
<center>
<h1>413 Request Entity Too Large</h1>
</center>
<hr>
<center>nginx/1.17.5</center>
</body>
<html>
Как я могу получить право код исключения и сообщение об исключении?