custom redirect logic

// FREEBIE
This commit is contained in:
Jake McGinty 2014-09-10 00:20:07 -04:00
parent e5bad2746f
commit b8a3e87f3d
3 changed files with 92 additions and 57 deletions

View File

@ -44,6 +44,8 @@ import java.util.List;
public class MmsCommunication { public class MmsCommunication {
private static final String TAG = "MmsCommunication"; private static final String TAG = "MmsCommunication";
public static final int MAX_REDIRECTS = 10;
protected static MmsConnectionParameters getLocallyConfiguredMmsConnectionParameters(Context context) protected static MmsConnectionParameters getLocallyConfiguredMmsConnectionParameters(Context context)
throws ApnUnavailableException throws ApnUnavailableException
{ {
@ -180,7 +182,7 @@ public class MmsCommunication {
urlConnection = (HttpURLConnection) url.openConnection(); urlConnection = (HttpURLConnection) url.openConnection();
} }
urlConnection.setInstanceFollowRedirects(true); urlConnection.setInstanceFollowRedirects(false);
urlConnection.setConnectTimeout(20*1000); urlConnection.setConnectTimeout(20*1000);
urlConnection.setReadTimeout(20*1000); urlConnection.setReadTimeout(20*1000);
urlConnection.setUseCaches(false); urlConnection.setUseCaches(false);

View File

@ -18,12 +18,15 @@ package org.thoughtcrime.securesms.mms;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import ws.com.google.android.mms.pdu.PduParser; import ws.com.google.android.mms.pdu.PduParser;
import ws.com.google.android.mms.pdu.RetrieveConf; import ws.com.google.android.mms.pdu.RetrieveConf;
@ -36,29 +39,45 @@ public class MmsDownloadHelper extends MmsCommunication {
{ {
HttpURLConnection client = null; HttpURLConnection client = null;
try { int redirects = MAX_REDIRECTS;
client = constructHttpClient(url, proxy, proxyPort); final Set<String> previousUrls = new HashSet<String>();
String currentUrl = url;
client.setDoInput(true); while (redirects-- > 0) {
client.setRequestMethod("GET"); if (previousUrls.contains(currentUrl)) {
client.setRequestProperty("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic"); throw new IOException("redirect loop detected");
Log.w(TAG, "Connecting to " + url);
client.connect();
final InputStream is = client.getInputStream();
final int responseCode = client.getResponseCode();
Log.w(TAG, "Response code: " + responseCode + "/" + client.getResponseMessage());
if (responseCode != 200) {
throw new IOException("non-200 response");
} }
try {
client = constructHttpClient(currentUrl, proxy, proxyPort);
return parseResponse(is); client.setDoInput(true);
} finally { client.setRequestMethod("GET");
if (client != null) client.disconnect(); client.setRequestProperty("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
Log.w(TAG, "connecting to " + currentUrl);
client.connect();
int responseCode = client.getResponseCode();
Log.w(TAG, "* response code: " + responseCode + "/" + client.getResponseMessage());
if (responseCode == 301 || responseCode == 302) {
final String redirectUrl = client.getHeaderField("Location");
Log.w(TAG, "* Location: " + redirectUrl);
if (TextUtils.isEmpty(redirectUrl)) {
throw new IOException("Got redirect response code, but Location header was empty or missing");
}
previousUrls.add(currentUrl);
currentUrl = redirectUrl;
} else if (responseCode == 200) {
final InputStream is = client.getInputStream();
return parseResponse(is);
} else {
throw new IOException("unhandled response code");
}
} finally {
if (client != null) client.disconnect();
}
} }
throw new IOException("max redirects hit");
} }
public static boolean isMmsConnectionParametersAvailable(Context context, String apn) { public static boolean isMmsConnectionParametersAvailable(Context context, String apn) {

View File

@ -20,17 +20,15 @@ import android.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.Uri; import android.net.Uri;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.whispersystems.textsecure.util.Util;
import java.io.BufferedOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URI; import java.util.HashSet;
import java.net.URISyntaxException; import java.util.Set;
import ws.com.google.android.mms.pdu.PduParser; import ws.com.google.android.mms.pdu.PduParser;
import ws.com.google.android.mms.pdu.SendConf; import ws.com.google.android.mms.pdu.SendConf;
@ -45,40 +43,56 @@ public class MmsSendHelper extends MmsCommunication {
HttpURLConnection client = null; HttpURLConnection client = null;
try { int redirects = MAX_REDIRECTS;
client = constructHttpClient(url, proxy, proxyPort); final Set<String> previousUrls = new HashSet<String>();
client.setFixedLengthStreamingMode(mms.length); String currentUrl = url;
client.setDoInput(true); while (redirects-- > 0) {
client.setDoOutput(true); if (previousUrls.contains(currentUrl)) {
client.setRequestMethod("POST"); throw new IOException("redirect loop detected");
client.setRequestProperty("Content-Type", "application/vnd.wap.mms-message");
client.setRequestProperty("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
client.setRequestProperty("x-wap-profile", "http://www.google.com/oha/rdf/ua-profile-kila.xml");
Log.w(TAG, "Connecting to " + url);
client.connect();
Log.w(TAG, "Writing mms payload, " + mms.length + " bytes");
OutputStream out = client.getOutputStream();
out.write(mms);
out.flush();
out.close();
Log.w(TAG, "Payload sent");
final InputStream is = client.getInputStream();
final int responseCode = client.getResponseCode();
Log.w(TAG, "Response code: " + responseCode + "/" + client.getResponseMessage());
if (responseCode != 200) {
throw new IOException("non-200 response");
} }
try {
client = constructHttpClient(currentUrl, proxy, proxyPort);
client.setFixedLengthStreamingMode(mms.length);
client.setDoInput(true);
client.setDoOutput(true);
client.setRequestMethod("POST");
client.setRequestProperty("Content-Type", "application/vnd.wap.mms-message");
client.setRequestProperty("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
client.setRequestProperty("x-wap-profile", "http://www.google.com/oha/rdf/ua-profile-kila.xml");
return parseResponse(is); Log.w(TAG, "connecting to " + currentUrl);
} finally { client.connect();
if (client != null) client.disconnect();
Log.w(TAG, "* writing mms payload, " + mms.length + " bytes");
OutputStream out = client.getOutputStream();
out.write(mms);
out.flush();
out.close();
Log.w(TAG, "* payload sent");
int responseCode = client.getResponseCode();
Log.w(TAG, "* response code: " + responseCode + "/" + client.getResponseMessage());
if (responseCode == 301 || responseCode == 302) {
final String redirectUrl = client.getHeaderField("Location");
Log.w(TAG, "* Location: " + redirectUrl);
if (TextUtils.isEmpty(redirectUrl)) {
throw new IOException("Got redirect response code, but Location header was empty or missing");
}
previousUrls.add(currentUrl);
currentUrl = redirectUrl;
} else if (responseCode == 200) {
final InputStream is = client.getInputStream();
return parseResponse(is);
} else {
throw new IOException("unhandled response code");
}
} finally {
if (client != null) client.disconnect();
}
} }
throw new IOException("max redirects hit");
} }
public static void sendNotificationReceived(Context context, byte[] mms, String apn, public static void sendNotificationReceived(Context context, byte[] mms, String apn,