add a preference to allow user to set a network proxy

Some networks require a proxy to get internet beyond the firewall, and
proxies are also useful for channeling all traffic through circumvention
and privacy proxies like Tor, I2P, Psiphon, etc.  In places where the
connection to download tiles might be blocked, using a proxy can give the
user access.
This commit is contained in:
Hans-Christoph Steiner 2015-01-20 15:12:04 +01:00
parent 41f356a11a
commit 2da1458999
13 changed files with 119 additions and 13 deletions

View file

@ -9,6 +9,9 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Map; import java.util.Map;
@ -21,12 +24,15 @@ import org.apache.commons.logging.Log;
public class NetworkUtils { public class NetworkUtils {
private static final Log log = PlatformUtil.getLog(NetworkUtils.class); private static final Log log = PlatformUtil.getLog(NetworkUtils.class);
private static Proxy proxy = null;
public static String sendGetRequest(String urlText, String userNamePassword){ public static String sendGetRequest(String urlText, String userNamePassword){
URL url; URL url;
try { try {
log.info("GET : " + urlText); log.info("GET : " + urlText);
url = new URL(urlText); url = new URL(urlText);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpURLConnection conn = getHttpURLConnection(urlText);
conn.setDoInput(true); conn.setDoInput(true);
conn.setDoOutput(false); conn.setDoOutput(false);
conn.setRequestMethod("GET"); conn.setRequestMethod("GET");
@ -151,4 +157,24 @@ public class NetworkUtils {
} }
} }
public static void setProxy(String host, int port) {
if(host != null && port > 0) {
InetSocketAddress isa = new InetSocketAddress(host, port);
proxy = new Proxy(Proxy.Type.HTTP, isa);
} else {
proxy = null;
}
}
public static HttpURLConnection getHttpURLConnection(String urlString) throws MalformedURLException, IOException {
return getHttpURLConnection(new URL(urlString));
}
public static HttpURLConnection getHttpURLConnection(URL url) throws IOException {
if (proxy != null) {
return (HttpURLConnection) url.openConnection(proxy);
} else {
return (HttpURLConnection) url.openConnection();
}
}
} }

View file

@ -155,6 +155,13 @@
<string name="save_track_interval_descr">Choose logging interval for track recording during navigation</string> <string name="save_track_interval_descr">Choose logging interval for track recording during navigation</string>
<string name="voice_provider_descr">Select voice guidance for navigation</string> <string name="voice_provider_descr">Select voice guidance for navigation</string>
<string name="voice_provider">Voice guidance</string> <string name="voice_provider">Voice guidance</string>
<string name="proxy_pref_title">Proxy</string>
<string name="enable_proxy_title">Enable HTTP Proxy</string>
<string name="enable_proxy_descr">Configure HTTP Proxy for all network requests</string>
<string name="proxy_host_title">Proxy Host</string>
<string name="proxy_host_descr">Configure your proxy\'s hostname (e.g. 127.0.0.1)</string>
<string name="proxy_port_title">Proxy Port</string>
<string name="proxy_port_descr">Configure your proxy\'s port number (e.g. 8118)</string>
<string name="tips_and_tricks">Help</string> <string name="tips_and_tricks">Help</string>
<string name="tip_initial">Help</string> <string name="tip_initial">Help</string>
<string name="tip_initial_t">OsmAnd is a navigation application with many features. <string name="tip_initial_t">OsmAnd is a navigation application with many features.

View file

@ -13,6 +13,16 @@
<PreferenceCategory android:title="@string/voice_pref_title" android:key="voice"> <PreferenceCategory android:title="@string/voice_pref_title" android:key="voice">
<ListPreference android:title="@string/voice_provider" android:key="voice_provider" android:summary="@string/voice_provider_descr"></ListPreference> <ListPreference android:title="@string/voice_provider" android:key="voice_provider" android:summary="@string/voice_provider_descr"></ListPreference>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/proxy_pref_title" android:key="proxy">
<CheckBoxPreference
android:key="enable_proxy" android:title="@string/enable_proxy_title" android:summary="@string/enable_proxy_descr" android:defaultValue="false" />
<EditTextPreference
android:key="proxy_host" android:title="@string/proxy_host_title" android:summary="@string/proxy_host_descr" android:dependency="enable_proxy"
android:defaultValue="127.0.0.1" />
<EditTextPreference
android:key="proxy_port" android:title="@string/proxy_port_title" android:summary="@string/proxy_port_descr" android:dependency="enable_proxy"
android:defaultValue="8118" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/misc_pref_title" android:key="misc"> <PreferenceCategory android:title="@string/misc_pref_title" android:key="misc">
<ListPreference android:key="osmand_theme" android:title="@string/choose_osmand_theme" android:summary="@string/choose_osmand_theme_descr"></ListPreference> <ListPreference android:key="osmand_theme" android:title="@string/choose_osmand_theme" android:summary="@string/choose_osmand_theme_descr"></ListPreference>
</PreferenceCategory> </PreferenceCategory>

View file

@ -796,6 +796,9 @@ public class OsmandSettings {
public final CommonPreference<Boolean> INTERRUPT_MUSIC = new BooleanPreference("interrupt_music", false).makeGlobal(); public final CommonPreference<Boolean> INTERRUPT_MUSIC = new BooleanPreference("interrupt_music", false).makeGlobal();
public final CommonPreference<Boolean> ENABLE_PROXY = new BooleanPreference("enable_proxy", false).makeGlobal();
public final CommonPreference<String> PROXY_HOST = new StringPreference("proxy_host", "127.0.0.1").makeGlobal();
public final CommonPreference<Integer> PROXY_PORT = new IntPreference("proxy_port", 8118).makeGlobal();
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public static final String SAVE_CURRENT_TRACK = "save_current_track"; //$NON-NLS-1$ public static final String SAVE_CURRENT_TRACK = "save_current_track"; //$NON-NLS-1$

View file

@ -14,6 +14,7 @@ import net.osmand.CallbackWithObject;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.access.AccessibleToast; import net.osmand.access.AccessibleToast;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
@ -43,6 +44,7 @@ import android.media.AudioManager;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceChangeListener;
@ -94,6 +96,7 @@ public class SettingsGeneralActivity extends SettingsBaseActivity {
addLocalPrefs((PreferenceGroup) screen.findPreference("localization")); addLocalPrefs((PreferenceGroup) screen.findPreference("localization"));
addVoicePrefs((PreferenceGroup) screen.findPreference("voice")); addVoicePrefs((PreferenceGroup) screen.findPreference("voice"));
addProxyPrefs((PreferenceGroup) screen.findPreference("proxy"));
addMiscPreferences((PreferenceGroup) screen.findPreference("misc")); addMiscPreferences((PreferenceGroup) screen.findPreference("misc"));
@ -264,6 +267,54 @@ public class SettingsGeneralActivity extends SettingsBaseActivity {
private void addProxyPrefs(PreferenceGroup proxy) {
CheckBoxPreference enableProxyPref = (CheckBoxPreference) proxy.findPreference(settings.ENABLE_PROXY.getId());
enableProxyPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if ((Boolean) newValue)
NetworkUtils.setProxy(settings.PROXY_HOST.get(), settings.PROXY_PORT.get());
else
NetworkUtils.setProxy(null, 0);
return true;
}
});
EditTextPreference hostPref = (EditTextPreference) proxy.findPreference(settings.PROXY_HOST.getId());
hostPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
System.out.println("PROXY newValue: " + newValue);
settings.PROXY_HOST.set((String) newValue);
NetworkUtils.setProxy((String) newValue, settings.PROXY_PORT.get());
return true;
}
});
EditTextPreference portPref = (EditTextPreference) proxy.findPreference(settings.PROXY_PORT.getId());
portPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
System.out.println("PROXY newValue: " + newValue);
int port = -1;
String portString = (String) newValue;
try {
port = Integer.valueOf(portString.replaceAll("[^0-9]", ""));
} catch (NumberFormatException e1) {
}
settings.PROXY_PORT.set(port);
NetworkUtils.setProxy(settings.PROXY_HOST.get(), port);
return true;
}
});
}
private void addMiscPreferences(PreferenceGroup misc) { private void addMiscPreferences(PreferenceGroup misc) {
if (!Version.isBlackberry(getMyApplication())) { if (!Version.isBlackberry(getMyApplication())) {
applicationDir = new Preference(this); applicationDir = new Preference(this);

View file

@ -14,6 +14,7 @@ import java.util.zip.ZipInputStream;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
@ -66,7 +67,7 @@ public class DownloadFileHelper {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpURLConnection conn = NetworkUtils.getHttpURLConnection(url);
conn.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$ conn.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$
conn.setReadTimeout(30000); conn.setReadTimeout(30000);
if (fileread > 0) { if (fileread > 0) {

View file

@ -4,6 +4,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -12,6 +13,7 @@ import java.util.zip.GZIPInputStream;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
@ -104,9 +106,9 @@ public class DownloadOsmandIndexesHelper {
String strUrl = ctx.getAppCustomization().getIndexesUrl(); String strUrl = ctx.getAppCustomization().getIndexesUrl();
log.info(strUrl); log.info(strUrl);
URL url = new URL(strUrl );
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(new GZIPInputStream(url.openStream()), "UTF-8"); //$NON-NLS-1$ URLConnection connection = NetworkUtils.getHttpURLConnection(strUrl);
parser.setInput(new GZIPInputStream(connection.getInputStream()), "UTF-8"); //$NON-NLS-1$
int next; int next;
while((next = parser.next()) != XmlPullParser.END_DOCUMENT) { while((next = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (next == XmlPullParser.START_TAG) { if (next == XmlPullParser.START_TAG) {

View file

@ -13,6 +13,7 @@ import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.Version; import net.osmand.plus.Version;
@ -102,8 +103,7 @@ public class DownloadTracker {
} }
log.debug(urlString); log.debug(urlString);
URL url = new URL(urlString.toString()); HttpURLConnection conn = NetworkUtils.getHttpURLConnection(urlString.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000); conn.setConnectTimeout(5000);
conn.setDoInput(false); conn.setDoInput(false);
conn.setDoOutput(false); conn.setDoOutput(false);

View file

@ -103,7 +103,7 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
private String sendRequest(String url, String requestMethod, String requestBody, String userOperation, boolean doAuthenticate) { private String sendRequest(String url, String requestMethod, String requestBody, String userOperation, boolean doAuthenticate) {
log.info("Sending request " + url); //$NON-NLS-1$ log.info("Sending request " + url); //$NON-NLS-1$
try { try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
connection.setConnectTimeout(15000); connection.setConnectTimeout(15000);
connection.setRequestMethod(requestMethod); connection.setRequestMethod(requestMethod);

View file

@ -11,6 +11,7 @@ import java.net.URLEncoder;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.osm.io.Base64; import net.osmand.osm.io.Base64;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -76,7 +77,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
private String editingPOI(String url, String requestMethod, String userOperation) { private String editingPOI(String url, String requestMethod, String userOperation) {
try { try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
log.info("Editing poi " + url); log.info("Editing poi " + url);
connection.setConnectTimeout(15000); connection.setConnectTimeout(15000);
connection.setRequestMethod(requestMethod); connection.setRequestMethod(requestMethod);

View file

@ -3,6 +3,7 @@ package net.osmand.plus.poi;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -11,6 +12,7 @@ import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.AmenityType; import net.osmand.data.AmenityType;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.R.string; import net.osmand.plus.R.string;
@ -76,8 +78,8 @@ public class NameFinderPoiFilter extends PoiLegacyFilter {
lastError = ""; lastError = "";
String urlq = NOMINATIM_API + URLEncoder.encode(query)+ "?format=xml&addressdetails=1&limit="+LIMIT+"&bounded=1&"+viewbox; String urlq = NOMINATIM_API + URLEncoder.encode(query)+ "?format=xml&addressdetails=1&limit="+LIMIT+"&bounded=1&"+viewbox;
log.info(urlq); log.info(urlq);
URL url = new URL(urlq); //$NON-NLS-1$ URLConnection connection = NetworkUtils.getHttpURLConnection(urlq); //$NON-NLS-1$
InputStream stream = url.openStream(); InputStream stream = connection.getInputStream();
XmlPullParser parser = PlatformUtil.newXMLPullParser(); XmlPullParser parser = PlatformUtil.newXMLPullParser();
parser.setInput(stream, "UTF-8"); //$NON-NLS-1$ parser.setInput(stream, "UTF-8"); //$NON-NLS-1$
int eventType; int eventType;

View file

@ -27,6 +27,7 @@ import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint; import net.osmand.data.LocationPoint;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.GPXFile;
@ -1103,8 +1104,7 @@ public class RouteProvider {
log.info("URL route " + uri); log.info("URL route " + uri);
URL url = new URL(uri.toString()); URLConnection connection = NetworkUtils.getHttpURLConnection(uri.toString());
URLConnection connection = url.openConnection();
connection.setRequestProperty("User-Agent", Version.getFullVersion(params.ctx)); connection.setRequestProperty("User-Agent", Version.getFullVersion(params.ctx));
// StringBuilder content = new StringBuilder(); // StringBuilder content = new StringBuilder();
// BufferedReader rs = new BufferedReader(new InputStreamReader(connection.getInputStream())); // BufferedReader rs = new BufferedReader(new InputStreamReader(connection.getInputStream()));

View file

@ -6,10 +6,12 @@ import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.map.TileSourceManager.TileSourceTemplate;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -65,7 +67,8 @@ public class YandexTrafficAdapter extends MapTileAdapter {
if (mTimestamp == null || (System.currentTimeMillis() - lastTimestampUpdated) > DELTA) { if (mTimestamp == null || (System.currentTimeMillis() - lastTimestampUpdated) > DELTA) {
log.info("Updating timestamp"); //$NON-NLS-1$ log.info("Updating timestamp"); //$NON-NLS-1$
try { try {
BufferedInputStream in = new BufferedInputStream(new URL(YANDEX_BASE_URL + "/trf/stat.js").openStream(), 1024); //$NON-NLS-1$ URLConnection connection = NetworkUtils.getHttpURLConnection(YANDEX_BASE_URL + "/trf/stat.js");
BufferedInputStream in = new BufferedInputStream(connection.getInputStream(), 1024); //$NON-NLS-1$
ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
BufferedOutputStream out = new BufferedOutputStream(dataStream, 1024); BufferedOutputStream out = new BufferedOutputStream(dataStream, 1024);
Algorithms.streamCopy(in, out); Algorithms.streamCopy(in, out);