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,30 +39,46 @@ public class MmsDownloadHelper extends MmsCommunication {
{ {
HttpURLConnection client = null; HttpURLConnection client = null;
int redirects = MAX_REDIRECTS;
final Set<String> previousUrls = new HashSet<String>();
String currentUrl = url;
while (redirects-- > 0) {
if (previousUrls.contains(currentUrl)) {
throw new IOException("redirect loop detected");
}
try { try {
client = constructHttpClient(url, proxy, proxyPort); client = constructHttpClient(currentUrl, proxy, proxyPort);
client.setDoInput(true); client.setDoInput(true);
client.setRequestMethod("GET"); client.setRequestMethod("GET");
client.setRequestProperty("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic"); client.setRequestProperty("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
Log.w(TAG, "Connecting to " + url); Log.w(TAG, "connecting to " + currentUrl);
client.connect(); client.connect();
final InputStream is = client.getInputStream(); int responseCode = client.getResponseCode();
final int responseCode = client.getResponseCode(); Log.w(TAG, "* response code: " + responseCode + "/" + client.getResponseMessage());
Log.w(TAG, "Response code: " + responseCode + "/" + client.getResponseMessage()); if (responseCode == 301 || responseCode == 302) {
final String redirectUrl = client.getHeaderField("Location");
if (responseCode != 200) { Log.w(TAG, "* Location: " + redirectUrl);
throw new IOException("non-200 response"); 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); return parseResponse(is);
} else {
throw new IOException("unhandled response code");
}
} finally { } finally {
if (client != null) client.disconnect(); 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) {
try { try {

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,8 +43,15 @@ public class MmsSendHelper extends MmsCommunication {
HttpURLConnection client = null; HttpURLConnection client = null;
int redirects = MAX_REDIRECTS;
final Set<String> previousUrls = new HashSet<String>();
String currentUrl = url;
while (redirects-- > 0) {
if (previousUrls.contains(currentUrl)) {
throw new IOException("redirect loop detected");
}
try { try {
client = constructHttpClient(url, proxy, proxyPort); client = constructHttpClient(currentUrl, proxy, proxyPort);
client.setFixedLengthStreamingMode(mms.length); client.setFixedLengthStreamingMode(mms.length);
client.setDoInput(true); client.setDoInput(true);
client.setDoOutput(true); client.setDoOutput(true);
@ -55,31 +60,40 @@ public class MmsSendHelper extends MmsCommunication {
client.setRequestProperty("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic"); 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"); client.setRequestProperty("x-wap-profile", "http://www.google.com/oha/rdf/ua-profile-kila.xml");
Log.w(TAG, "Connecting to " + url); Log.w(TAG, "connecting to " + currentUrl);
client.connect(); client.connect();
Log.w(TAG, "Writing mms payload, " + mms.length + " bytes"); Log.w(TAG, "* writing mms payload, " + mms.length + " bytes");
OutputStream out = client.getOutputStream(); OutputStream out = client.getOutputStream();
out.write(mms); out.write(mms);
out.flush(); out.flush();
out.close(); out.close();
Log.w(TAG, "Payload sent"); Log.w(TAG, "* payload sent");
final InputStream is = client.getInputStream(); int responseCode = client.getResponseCode();
final int responseCode = client.getResponseCode(); Log.w(TAG, "* response code: " + responseCode + "/" + client.getResponseMessage());
Log.w(TAG, "Response code: " + responseCode + "/" + client.getResponseMessage()); if (responseCode == 301 || responseCode == 302) {
final String redirectUrl = client.getHeaderField("Location");
if (responseCode != 200) { Log.w(TAG, "* Location: " + redirectUrl);
throw new IOException("non-200 response"); 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); return parseResponse(is);
} else {
throw new IOException("unhandled response code");
}
} finally { } finally {
if (client != null) client.disconnect(); 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,
boolean usingMmsRadio, boolean useProxyIfAvailable) boolean usingMmsRadio, boolean useProxyIfAvailable)