mirror of
https://gitlab.com/oeffi/public-transport-enabler.git
synced 2025-07-19 16:59:51 +00:00
Migrate all HTTP calls to use OkHttp rather than URLConnection.
This commit is contained in:
parent
4c64746e75
commit
74d552d187
16 changed files with 2135 additions and 2062 deletions
|
@ -2,6 +2,8 @@ apply plugin: 'java'
|
|||
apply plugin: 'eclipse'
|
||||
|
||||
dependencies {
|
||||
compile 'com.squareup.okhttp3:okhttp:3.4.1'
|
||||
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
|
||||
compile 'com.google.guava:guava:18.0'
|
||||
compile 'org.slf4j:slf4j-api:1.7.12'
|
||||
compile 'com.google.code.findbugs:jsr305:3.0.0'
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -66,6 +66,8 @@ import de.schildbach.pte.exception.NotFoundException;
|
|||
import de.schildbach.pte.exception.ParserException;
|
||||
import de.schildbach.pte.util.ParserUtils;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Antonio El Khoury
|
||||
* @author Andreas Schildbach
|
||||
|
@ -641,7 +643,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
|
||||
private String getStopAreaId(final String stopPointId) throws IOException {
|
||||
final String uri = uri() + "stop_points/" + ParserUtils.urlEncode(stopPointId) + "?depth=1";
|
||||
final CharSequence page = httpClient.get(uri);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri));
|
||||
|
||||
try {
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
@ -698,7 +700,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
if (maxLocations > 0)
|
||||
queryUri.append("&count=").append(maxLocations);
|
||||
queryUri.append("&depth=3");
|
||||
final CharSequence page = httpClient.get(queryUri.toString());
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(queryUri.toString()));
|
||||
|
||||
try {
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
@ -773,7 +775,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
queryUri.append("&duration=86400");
|
||||
queryUri.append("&depth=0");
|
||||
|
||||
final CharSequence page = httpClient.get(queryUri.toString());
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(queryUri.toString()));
|
||||
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
||||
|
@ -821,7 +823,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
throw new ParserException(parseExc);
|
||||
} catch (final NotFoundException fnfExc) {
|
||||
try {
|
||||
final JSONObject head = new JSONObject(fnfExc.scrapeErrorStream().toString());
|
||||
final JSONObject head = new JSONObject(fnfExc.getBodyPeek().toString());
|
||||
final JSONObject error = head.getJSONObject("error");
|
||||
final String id = error.getString("id");
|
||||
|
||||
|
@ -841,7 +843,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
|
||||
final String queryUri = uri() + "places?q=" + ParserUtils.urlEncode(nameCstr)
|
||||
+ "&type[]=stop_area&type[]=address&type[]=poi&type[]=administrative_region" + "&depth=1";
|
||||
final CharSequence page = httpClient.get(queryUri);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(queryUri));
|
||||
|
||||
try {
|
||||
final List<SuggestedLocation> locations = new ArrayList<SuggestedLocation>();
|
||||
|
@ -945,7 +947,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
}
|
||||
}
|
||||
|
||||
final CharSequence page = httpClient.get(queryUri.toString());
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(queryUri.toString()));
|
||||
|
||||
try {
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
@ -1013,7 +1015,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
return new QueryTripsResult(resultHeader, QueryTripsResult.Status.NO_TRIPS);
|
||||
} catch (final NotFoundException fnfExc) {
|
||||
try {
|
||||
final JSONObject head = new JSONObject(fnfExc.scrapeErrorStream().toString());
|
||||
final JSONObject head = new JSONObject(fnfExc.getBodyPeek().toString());
|
||||
final JSONObject error = head.getJSONObject("error");
|
||||
final String id = error.getString("id");
|
||||
|
||||
|
@ -1046,7 +1048,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
final Location from = context.from;
|
||||
final Location to = context.to;
|
||||
final String queryUri = later ? context.nextQueryUri : context.prevQueryUri;
|
||||
final CharSequence page = httpClient.get(queryUri);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(queryUri));
|
||||
|
||||
try {
|
||||
if (from.isIdentified() && to.isIdentified()) {
|
||||
|
@ -1076,7 +1078,7 @@ public abstract class AbstractNavitiaProvider extends AbstractNetworkProvider {
|
|||
@Override
|
||||
public Point[] getArea() throws IOException {
|
||||
final String queryUri = uri();
|
||||
final CharSequence page = httpClient.get(queryUri);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(queryUri));
|
||||
|
||||
try {
|
||||
// Get shape string.
|
||||
|
|
|
@ -59,6 +59,8 @@ import de.schildbach.pte.dto.Trip;
|
|||
import de.schildbach.pte.exception.ParserException;
|
||||
import de.schildbach.pte.util.ParserUtils;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Kjell Braden <afflux@pentabarf.de>
|
||||
*/
|
||||
|
@ -197,7 +199,7 @@ public abstract class AbstractTsiProvider extends AbstractNetworkProvider {
|
|||
final StringBuilder uri = new StringBuilder(stopFinderEndpoint);
|
||||
uri.append(parameters);
|
||||
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
try {
|
||||
final List<SuggestedLocation> locations = new ArrayList<SuggestedLocation>();
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
@ -277,7 +279,7 @@ public abstract class AbstractTsiProvider extends AbstractNetworkProvider {
|
|||
final StringBuilder uri = new StringBuilder(stopFinderEndpoint);
|
||||
uri.append(parameters);
|
||||
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
try {
|
||||
final List<Location> stations = new ArrayList<Location>();
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
@ -315,7 +317,7 @@ public abstract class AbstractTsiProvider extends AbstractNetworkProvider {
|
|||
final StringBuilder uri = new StringBuilder(stopFinderEndpoint);
|
||||
uri.append(parameters);
|
||||
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
try {
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
||||
|
@ -674,7 +676,7 @@ public abstract class AbstractTsiProvider extends AbstractNetworkProvider {
|
|||
|
||||
final StringBuilder uri = new StringBuilder(tripEndpoint);
|
||||
uri.append(parameters);
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
try {
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package de.schildbach.pte;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -33,6 +32,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -63,6 +63,9 @@ import de.schildbach.pte.exception.ParserException;
|
|||
import de.schildbach.pte.util.HttpClient;
|
||||
import de.schildbach.pte.util.XmlPullUtil;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
/**
|
||||
* @author Mats Sjöberg <mats@sjoberg.fi>
|
||||
*/
|
||||
|
@ -137,34 +140,32 @@ public class HslProvider extends AbstractNetworkProvider {
|
|||
|
||||
private Location queryStop(final String stationId) throws IOException {
|
||||
final StringBuilder uri = apiUri("stop");
|
||||
|
||||
uri.append("&code=").append(stationId);
|
||||
uri.append(String.format("&dep_limit=1"));
|
||||
final AtomicReference<Location> result = new AtomicReference<Location>();
|
||||
|
||||
InputStream is = null;
|
||||
String firstChars = null;
|
||||
final HttpClient.Callback callback = new HttpClient.Callback() {
|
||||
@Override
|
||||
public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException {
|
||||
try {
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(body.charStream());
|
||||
|
||||
try {
|
||||
is = httpClient.getInputStream(uri.toString());
|
||||
firstChars = HttpClient.peekFirstChars(is);
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(is, null);
|
||||
final String id = xmlValueTag(pp, "code");
|
||||
final String name = xmlValueTag(pp, "name_fi");
|
||||
final Point pt = coordStrToPoint(xmlValueTag(pp, "coords"));
|
||||
result.set(new Location(LocationType.STATION, id, pt.lat, pt.lon, null, name));
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + bodyPeek, x);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
final String id = xmlValueTag(pp, "code");
|
||||
final String name = xmlValueTag(pp, "name_fi");
|
||||
final Point pt = coordStrToPoint(xmlValueTag(pp, "coords"));
|
||||
|
||||
return new Location(LocationType.STATION, id, pt.lat, pt.lon, null, name);
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + firstChars, x);
|
||||
} finally {
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
httpClient.getInputStream(callback, HttpUrl.parse(uri.toString()));
|
||||
return result.get();
|
||||
}
|
||||
|
||||
// Determine stations near to given location. At least one of
|
||||
|
@ -174,7 +175,6 @@ public class HslProvider extends AbstractNetworkProvider {
|
|||
public NearbyLocationsResult queryNearbyLocations(EnumSet<LocationType> types, Location location, int maxDistance,
|
||||
int maxStations) throws IOException {
|
||||
final StringBuilder uri = apiUri("stops_area");
|
||||
|
||||
if (!location.hasLocation()) {
|
||||
if (location.type != LocationType.STATION)
|
||||
throw new IllegalArgumentException("cannot handle: " + location.type);
|
||||
|
@ -185,42 +185,42 @@ public class HslProvider extends AbstractNetworkProvider {
|
|||
uri.append("¢er_coordinate=").append(locationToCoords(location));
|
||||
uri.append(String.format("&limit=%d", maxStations));
|
||||
uri.append(String.format("&diameter=%d", maxDistance * 2));
|
||||
final AtomicReference<NearbyLocationsResult> result = new AtomicReference<NearbyLocationsResult>();
|
||||
|
||||
InputStream is = null;
|
||||
String firstChars = null;
|
||||
final HttpClient.Callback callback = new HttpClient.Callback() {
|
||||
@Override
|
||||
public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException {
|
||||
try {
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(body.charStream());
|
||||
|
||||
try {
|
||||
is = httpClient.getInputStream(uri.toString());
|
||||
firstChars = HttpClient.peekFirstChars(is);
|
||||
final List<Location> stations = new ArrayList<Location>();
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(is, null);
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
|
||||
final List<Location> stations = new ArrayList<Location>();
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
final String id = xmlValueTag(pp, "code");
|
||||
final String name = xmlValueTag(pp, "name");
|
||||
final Point pt = coordStrToPoint(xmlValueTag(pp, "coords"));
|
||||
final String place = xmlValueTag(pp, "address");
|
||||
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
final String id = xmlValueTag(pp, "code");
|
||||
final String name = xmlValueTag(pp, "name");
|
||||
final Point pt = coordStrToPoint(xmlValueTag(pp, "coords"));
|
||||
final String place = xmlValueTag(pp, "address");
|
||||
stations.add(new Location(LocationType.STATION, id, pt.lat, pt.lon, place, name));
|
||||
}
|
||||
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
stations.add(new Location(LocationType.STATION, id, pt.lat, pt.lon, place, name));
|
||||
result.set(new NearbyLocationsResult(header, stations));
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + bodyPeek, x);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return new NearbyLocationsResult(header, stations);
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + firstChars, x);
|
||||
} finally {
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
httpClient.getInputStream(callback, HttpUrl.parse(uri.toString()));
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private Line newLine(String code, int type, String message) {
|
||||
|
@ -254,78 +254,75 @@ public class HslProvider extends AbstractNetworkProvider {
|
|||
|
||||
// Get departures at a given station, probably live
|
||||
@Override
|
||||
public QueryDeparturesResult queryDepartures(String stationId, @Nullable Date queryDate, int maxDepartures,
|
||||
public QueryDeparturesResult queryDepartures(String stationId, @Nullable Date queryDate, final int maxDepartures,
|
||||
boolean equivs) throws IOException {
|
||||
final StringBuilder uri = apiUri("stop");
|
||||
|
||||
uri.append("&code=").append(stationId);
|
||||
if (queryDate != null) {
|
||||
uri.append("&date=").append(new SimpleDateFormat("yyyyMMdd").format(queryDate));
|
||||
uri.append("&time=").append(new SimpleDateFormat("HHmm").format(queryDate));
|
||||
}
|
||||
uri.append(String.format("&dep_limit=%d", maxDepartures));
|
||||
final AtomicReference<QueryDeparturesResult> result = new AtomicReference<QueryDeparturesResult>();
|
||||
|
||||
InputStream is = null;
|
||||
String firstChars = null;
|
||||
final HttpClient.Callback callback = new HttpClient.Callback() {
|
||||
@Override
|
||||
public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException {
|
||||
try {
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(body.charStream());
|
||||
|
||||
try {
|
||||
is = httpClient.getInputStream(uri.toString());
|
||||
firstChars = HttpClient.peekFirstChars(is);
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(is, null);
|
||||
// FIXME: id is never used!?
|
||||
final String id = xmlValueTag(pp, "code");
|
||||
final String name = xmlValueTag(pp, "name_fi");
|
||||
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
final Map<String, Line> lines = new HashMap<String, Line>();
|
||||
|
||||
// FIXME: id is never used!?
|
||||
final String id = xmlValueTag(pp, "code");
|
||||
final String name = xmlValueTag(pp, "name_fi");
|
||||
XmlPullUtil.skipUntil(pp, "lines");
|
||||
XmlPullUtil.enter(pp, "lines");
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
final String[] parts = XmlPullUtil.valueTag(pp, "node").split(":");
|
||||
lines.put(parts[0], newLine(parts[0], 0, parts[1]));
|
||||
}
|
||||
XmlPullUtil.skipExit(pp, "lines");
|
||||
|
||||
final Map<String, Line> lines = new HashMap<String, Line>();
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
final QueryDeparturesResult r = new QueryDeparturesResult(header);
|
||||
|
||||
XmlPullUtil.skipUntil(pp, "lines");
|
||||
XmlPullUtil.enter(pp, "lines");
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
final String[] parts = XmlPullUtil.valueTag(pp, "node").split(":");
|
||||
lines.put(parts[0], newLine(parts[0], 0, parts[1]));
|
||||
XmlPullUtil.skipUntil(pp, "departures");
|
||||
XmlPullUtil.enter(pp, "departures");
|
||||
|
||||
final List<Departure> departures = new ArrayList<Departure>(maxDepartures);
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
final String code = xmlValueTag(pp, "code");
|
||||
final String time = xmlValueTag(pp, "time");
|
||||
final String date = xmlValueTag(pp, "date");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
|
||||
Date depDate = sdf.parse(date + time, new ParsePosition(0));
|
||||
|
||||
final Line line = lines.get(code);
|
||||
final Location destination = new Location(LocationType.ANY, line.message, null, null);
|
||||
final Departure departure = new Departure(depDate, null, line, null, destination, null, null);
|
||||
departures.add(departure);
|
||||
}
|
||||
|
||||
Location station = new Location(LocationType.STATION, id, null, name);
|
||||
r.stationDepartures.add(new StationDepartures(station, departures, null));
|
||||
result.set(r);
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + bodyPeek, x);
|
||||
}
|
||||
}
|
||||
XmlPullUtil.skipExit(pp, "lines");
|
||||
};
|
||||
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
final QueryDeparturesResult result = new QueryDeparturesResult(header);
|
||||
|
||||
XmlPullUtil.skipUntil(pp, "departures");
|
||||
XmlPullUtil.enter(pp, "departures");
|
||||
|
||||
final List<Departure> departures = new ArrayList<Departure>(maxDepartures);
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
final String code = xmlValueTag(pp, "code");
|
||||
final String time = xmlValueTag(pp, "time");
|
||||
final String date = xmlValueTag(pp, "date");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
|
||||
Date depDate = sdf.parse(date + time, new ParsePosition(0));
|
||||
|
||||
final Line line = lines.get(code);
|
||||
final Location destination = new Location(LocationType.ANY, line.message, null, null);
|
||||
final Departure departure = new Departure(depDate, null, line, null, destination, null, null);
|
||||
departures.add(departure);
|
||||
}
|
||||
|
||||
Location station = new Location(LocationType.STATION, id, null, name);
|
||||
result.stationDepartures.add(new StationDepartures(station, departures, null));
|
||||
|
||||
return result;
|
||||
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + firstChars, x);
|
||||
} finally {
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
httpClient.getInputStream(callback, HttpUrl.parse(uri.toString()));
|
||||
return result.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -339,71 +336,68 @@ public class HslProvider extends AbstractNetworkProvider {
|
|||
@Override
|
||||
public SuggestLocationsResult suggestLocations(CharSequence constraint) throws IOException {
|
||||
final StringBuilder uri = apiUri("geocode");
|
||||
|
||||
// Since HSL is picky about the input we clean out any
|
||||
// character that isn't alphabetic, numeral, -, ', /
|
||||
// or a space. Those should be all chars needed for a
|
||||
// name.
|
||||
String constraintStr = constraint.toString().replaceAll("[^\\p{Ll}\\p{Lu}\\p{Lt}\\p{Lo}\\p{Nd}\\d-'/ ]", "");
|
||||
uri.append("&key=").append(URLEncoder.encode(constraintStr, "utf-8"));
|
||||
final AtomicReference<SuggestLocationsResult> result = new AtomicReference<SuggestLocationsResult>();
|
||||
|
||||
InputStream is = null;
|
||||
String firstChars = null;
|
||||
final HttpClient.Callback callback = new HttpClient.Callback() {
|
||||
@Override
|
||||
public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException {
|
||||
try {
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
final List<SuggestedLocation> locations = new ArrayList<SuggestedLocation>();
|
||||
|
||||
try {
|
||||
is = httpClient.getInputStream(uri.toString());
|
||||
firstChars = HttpClient.peekFirstChars(is);
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(body.charStream());
|
||||
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
final List<SuggestedLocation> locations = new ArrayList<SuggestedLocation>();
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
|
||||
if (firstChars.isEmpty())
|
||||
return new SuggestLocationsResult(header, locations);
|
||||
int weight = 10000;
|
||||
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(is, null);
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
final String locType = xmlValueTag(pp, "locType");
|
||||
String name = xmlValueTag(pp, "name");
|
||||
final Point pt = coordStrToPoint(xmlValueTag(pp, "coords"));
|
||||
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
LocationType type = LocationType.ANY;
|
||||
if (locType.equals("poi"))
|
||||
type = LocationType.POI;
|
||||
if (locType.equals("address"))
|
||||
type = LocationType.ADDRESS;
|
||||
if (locType.equals("stop"))
|
||||
type = LocationType.STATION;
|
||||
|
||||
int weight = 10000;
|
||||
XmlPullUtil.skipUntil(pp, "details");
|
||||
XmlPullUtil.enter(pp, "details");
|
||||
XmlPullUtil.optSkip(pp, "address");
|
||||
final String id = XmlPullUtil.optValueTag(pp, "code", null);
|
||||
final String shortCode = XmlPullUtil.optValueTag(pp, "shortCode", null);
|
||||
XmlPullUtil.skipExit(pp, "details");
|
||||
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
final String locType = xmlValueTag(pp, "locType");
|
||||
String name = xmlValueTag(pp, "name");
|
||||
final Point pt = coordStrToPoint(xmlValueTag(pp, "coords"));
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
LocationType type = LocationType.ANY;
|
||||
if (locType.equals("poi"))
|
||||
type = LocationType.POI;
|
||||
if (locType.equals("address"))
|
||||
type = LocationType.ADDRESS;
|
||||
if (locType.equals("stop"))
|
||||
type = LocationType.STATION;
|
||||
if (shortCode != null)
|
||||
name = name + " (" + shortCode + ")";
|
||||
|
||||
XmlPullUtil.skipUntil(pp, "details");
|
||||
XmlPullUtil.enter(pp, "details");
|
||||
XmlPullUtil.optSkip(pp, "address");
|
||||
final String id = XmlPullUtil.optValueTag(pp, "code", null);
|
||||
final String shortCode = XmlPullUtil.optValueTag(pp, "shortCode", null);
|
||||
XmlPullUtil.skipExit(pp, "details");
|
||||
locations
|
||||
.add(new SuggestedLocation(new Location(type, id, pt.lat, pt.lon, null, name), weight));
|
||||
weight -= 1;
|
||||
}
|
||||
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
if (shortCode != null)
|
||||
name = name + " (" + shortCode + ")";
|
||||
|
||||
locations.add(new SuggestedLocation(new Location(type, id, pt.lat, pt.lon, null, name), weight));
|
||||
weight -= 1;
|
||||
result.set(new SuggestLocationsResult(header, locations));
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + bodyPeek, x);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return new SuggestLocationsResult(header, locations);
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + firstChars, x);
|
||||
} finally {
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
httpClient.getInputStream(callback, HttpUrl.parse(uri.toString()));
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
|
@ -553,165 +547,166 @@ public class HslProvider extends AbstractNetworkProvider {
|
|||
}
|
||||
|
||||
private QueryTripsResult queryHslTrips(final Location from, final Location via, final Location to,
|
||||
QueryTripsHslContext context, Date date, boolean later) throws IOException {
|
||||
final QueryTripsHslContext context, Date date, final boolean later) throws IOException {
|
||||
final StringBuilder uri = new StringBuilder(context.uri);
|
||||
|
||||
uri.append("&date=").append(new SimpleDateFormat("yyyyMMdd").format(date));
|
||||
uri.append("&time=").append(new SimpleDateFormat("HHmm").format(date));
|
||||
final AtomicReference<QueryTripsResult> result = new AtomicReference<QueryTripsResult>();
|
||||
|
||||
InputStream is = null;
|
||||
String firstChars = null;
|
||||
final HttpClient.Callback callback = new HttpClient.Callback() {
|
||||
@Override
|
||||
public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException {
|
||||
try {
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(body.charStream());
|
||||
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
|
||||
final List<Trip> trips = new ArrayList<Trip>(context.trips);
|
||||
|
||||
// we use this for quick checking if trip already exists
|
||||
Set<String> tripSet = new HashSet<String>();
|
||||
for (Trip t : trips)
|
||||
tripSet.add(t.getId());
|
||||
|
||||
int insert = later ? trips.size() : 0;
|
||||
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
List<Trip.Leg> legs = new ArrayList<Trip.Leg>();
|
||||
|
||||
XmlPullUtil.skipUntil(pp, "legs");
|
||||
XmlPullUtil.enter(pp, "legs");
|
||||
int numTransfers = 0;
|
||||
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
int distance = Integer.parseInt(xmlValueTag(pp, "length"));
|
||||
String legType = xmlValueTag(pp, "type");
|
||||
String lineCode = XmlPullUtil.optValueTag(pp, "code", null);
|
||||
|
||||
List<Point> path = new ArrayList<Point>();
|
||||
|
||||
Location departure = null;
|
||||
Date departureTime = null;
|
||||
Stop departureStop = null;
|
||||
|
||||
Location arrival = null;
|
||||
Date arrivalTime = null;
|
||||
|
||||
LinkedList<Stop> stops = new LinkedList<Stop>();
|
||||
|
||||
XmlPullUtil.skipUntil(pp, "locs");
|
||||
XmlPullUtil.enter(pp, "locs");
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
Point pt = xmlCoordsToPoint(pp);
|
||||
|
||||
String arrTime = xmlValueTag(pp, "arrTime");
|
||||
String depTime = xmlValueTag(pp, "depTime");
|
||||
String name = XmlPullUtil.optValueTag(pp, "name", null);
|
||||
String code = XmlPullUtil.optValueTag(pp, "code", null);
|
||||
String shortCode = XmlPullUtil.optValueTag(pp, "shortCode", null);
|
||||
String stopAddress = XmlPullUtil.optValueTag(pp, "stopAddress", null);
|
||||
|
||||
if (name == null) {
|
||||
name = (path.size() == 0 && from != null && from.name != null) ? from.name : null;
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
|
||||
Date arrDate = sdf.parse(arrTime, new ParsePosition(0));
|
||||
Date depDate = sdf.parse(depTime, new ParsePosition(0));
|
||||
|
||||
LocationType type = LocationType.ANY;
|
||||
if (code != null)
|
||||
type = LocationType.STATION;
|
||||
Location loc = new Location(type, code, pt.lat, pt.lon, stopAddress, name);
|
||||
|
||||
if (path.size() == 0) {
|
||||
departure = loc;
|
||||
departureTime = depDate;
|
||||
if (type == LocationType.STATION)
|
||||
departureStop = new Stop(loc, true, departureTime, null, null, null);
|
||||
|
||||
} else {
|
||||
arrival = loc;
|
||||
arrivalTime = arrDate;
|
||||
if (type == LocationType.STATION) {
|
||||
stops.add(new Stop(loc, arrDate, null, depDate, null));
|
||||
}
|
||||
}
|
||||
|
||||
path.add(pt);
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
}
|
||||
XmlPullUtil.skipExit(pp, "locs");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
if (legType.equals("walk")) {
|
||||
// ugly hack to set the name of the last arrival
|
||||
if (arrival != null && arrival.name == null) {
|
||||
arrival = new Location(arrival.type, arrival.id, arrival.lat, arrival.lon,
|
||||
arrival.place, to.name);
|
||||
}
|
||||
|
||||
legs.add(new Trip.Individual(Trip.Individual.Type.WALK, departure, departureTime,
|
||||
arrival, arrivalTime, path, distance));
|
||||
} else {
|
||||
Stop arrivalStop = null;
|
||||
if (stops.size() > 0) {
|
||||
Stop last = stops.getLast();
|
||||
arrivalStop = new Stop(last.location, false, last.plannedArrivalTime, null, null,
|
||||
null);
|
||||
stops.removeLast();
|
||||
}
|
||||
|
||||
Line line = null;
|
||||
if (lineCode != null)
|
||||
line = newLine(lineCode, Integer.parseInt(legType), null);
|
||||
|
||||
legs.add(new Trip.Public(line, null, departureStop, arrivalStop, stops, path, null));
|
||||
numTransfers++;
|
||||
}
|
||||
}
|
||||
XmlPullUtil.skipExit(pp, "legs");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
Trip t = new Trip(null, from, to, legs, null, null, numTransfers - 1);
|
||||
if (!tripSet.contains(t.getId())) {
|
||||
Date thisTime = t.getFirstDepartureTime();
|
||||
while (insert < trips.size() && thisTime.after(trips.get(insert).getFirstDepartureTime()))
|
||||
insert++;
|
||||
|
||||
trips.add(insert++, t);
|
||||
tripSet.add(t.getId());
|
||||
}
|
||||
}
|
||||
|
||||
Date lastDate = trips.get(trips.size() - 1).getFirstDepartureTime();
|
||||
Date firstDate = trips.get(0).getFirstDepartureTime();
|
||||
if (context.nextDate == null || lastDate.after(context.nextDate))
|
||||
context.nextDate = lastDate;
|
||||
if (context.prevDate == null || firstDate.before(context.prevDate))
|
||||
context.prevDate = firstDate;
|
||||
context.trips = trips;
|
||||
|
||||
result.set(new QueryTripsResult(header, uri.toString(), from, via, to, context, trips));
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + bodyPeek, x);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
context.date = date;
|
||||
|
||||
try {
|
||||
is = httpClient.getInputStream(uri.toString());
|
||||
firstChars = HttpClient.peekFirstChars(is);
|
||||
|
||||
final XmlPullParser pp = parserFactory.newPullParser();
|
||||
pp.setInput(is, null);
|
||||
|
||||
XmlPullUtil.enter(pp, "response");
|
||||
|
||||
final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT);
|
||||
|
||||
final List<Trip> trips = new ArrayList<Trip>(context.trips);
|
||||
|
||||
// we use this for quick checking if trip already exists
|
||||
Set<String> tripSet = new HashSet<String>();
|
||||
for (Trip t : trips)
|
||||
tripSet.add(t.getId());
|
||||
|
||||
int insert = later ? trips.size() : 0;
|
||||
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
List<Trip.Leg> legs = new ArrayList<Trip.Leg>();
|
||||
|
||||
XmlPullUtil.skipUntil(pp, "legs");
|
||||
XmlPullUtil.enter(pp, "legs");
|
||||
int numTransfers = 0;
|
||||
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
|
||||
int distance = Integer.parseInt(xmlValueTag(pp, "length"));
|
||||
String legType = xmlValueTag(pp, "type");
|
||||
String lineCode = XmlPullUtil.optValueTag(pp, "code", null);
|
||||
|
||||
List<Point> path = new ArrayList<Point>();
|
||||
|
||||
Location departure = null;
|
||||
Date departureTime = null;
|
||||
Stop departureStop = null;
|
||||
|
||||
Location arrival = null;
|
||||
Date arrivalTime = null;
|
||||
|
||||
LinkedList<Stop> stops = new LinkedList<Stop>();
|
||||
|
||||
XmlPullUtil.skipUntil(pp, "locs");
|
||||
XmlPullUtil.enter(pp, "locs");
|
||||
while (XmlPullUtil.test(pp, "node")) {
|
||||
XmlPullUtil.enter(pp, "node");
|
||||
Point pt = xmlCoordsToPoint(pp);
|
||||
|
||||
String arrTime = xmlValueTag(pp, "arrTime");
|
||||
String depTime = xmlValueTag(pp, "depTime");
|
||||
String name = XmlPullUtil.optValueTag(pp, "name", null);
|
||||
String code = XmlPullUtil.optValueTag(pp, "code", null);
|
||||
String shortCode = XmlPullUtil.optValueTag(pp, "shortCode", null);
|
||||
String stopAddress = XmlPullUtil.optValueTag(pp, "stopAddress", null);
|
||||
|
||||
if (name == null) {
|
||||
name = (path.size() == 0 && from != null && from.name != null) ? from.name : null;
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
|
||||
Date arrDate = sdf.parse(arrTime, new ParsePosition(0));
|
||||
Date depDate = sdf.parse(depTime, new ParsePosition(0));
|
||||
|
||||
LocationType type = LocationType.ANY;
|
||||
if (code != null)
|
||||
type = LocationType.STATION;
|
||||
Location loc = new Location(type, code, pt.lat, pt.lon, stopAddress, name);
|
||||
|
||||
if (path.size() == 0) {
|
||||
departure = loc;
|
||||
departureTime = depDate;
|
||||
if (type == LocationType.STATION)
|
||||
departureStop = new Stop(loc, true, departureTime, null, null, null);
|
||||
|
||||
} else {
|
||||
arrival = loc;
|
||||
arrivalTime = arrDate;
|
||||
if (type == LocationType.STATION) {
|
||||
stops.add(new Stop(loc, arrDate, null, depDate, null));
|
||||
}
|
||||
}
|
||||
|
||||
path.add(pt);
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
}
|
||||
XmlPullUtil.skipExit(pp, "locs");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
if (legType.equals("walk")) {
|
||||
// ugly hack to set the name of the last arrival
|
||||
if (arrival != null && arrival.name == null) {
|
||||
arrival = new Location(arrival.type, arrival.id, arrival.lat, arrival.lon, arrival.place,
|
||||
to.name);
|
||||
}
|
||||
|
||||
legs.add(new Trip.Individual(Trip.Individual.Type.WALK, departure, departureTime, arrival,
|
||||
arrivalTime, path, distance));
|
||||
} else {
|
||||
Stop arrivalStop = null;
|
||||
if (stops.size() > 0) {
|
||||
Stop last = stops.getLast();
|
||||
arrivalStop = new Stop(last.location, false, last.plannedArrivalTime, null, null, null);
|
||||
stops.removeLast();
|
||||
}
|
||||
|
||||
Line line = null;
|
||||
if (lineCode != null)
|
||||
line = newLine(lineCode, Integer.parseInt(legType), null);
|
||||
|
||||
legs.add(new Trip.Public(line, null, departureStop, arrivalStop, stops, path, null));
|
||||
numTransfers++;
|
||||
}
|
||||
}
|
||||
XmlPullUtil.skipExit(pp, "legs");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
XmlPullUtil.skipExit(pp, "node");
|
||||
|
||||
Trip t = new Trip(null, from, to, legs, null, null, numTransfers - 1);
|
||||
if (!tripSet.contains(t.getId())) {
|
||||
Date thisTime = t.getFirstDepartureTime();
|
||||
while (insert < trips.size() && thisTime.after(trips.get(insert).getFirstDepartureTime()))
|
||||
insert++;
|
||||
|
||||
trips.add(insert++, t);
|
||||
tripSet.add(t.getId());
|
||||
}
|
||||
}
|
||||
|
||||
Date lastDate = trips.get(trips.size() - 1).getFirstDepartureTime();
|
||||
Date firstDate = trips.get(0).getFirstDepartureTime();
|
||||
if (context.nextDate == null || lastDate.after(context.nextDate))
|
||||
context.nextDate = lastDate;
|
||||
if (context.prevDate == null || firstDate.before(context.prevDate))
|
||||
context.prevDate = firstDate;
|
||||
context.trips = trips;
|
||||
return new QueryTripsResult(header, uri.toString(), from, via, to, context, trips);
|
||||
} catch (final XmlPullParserException x) {
|
||||
throw new ParserException("cannot parse xml: " + firstChars, x);
|
||||
} finally {
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
httpClient.getInputStream(callback, HttpUrl.parse(uri.toString()));
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ import de.schildbach.pte.dto.StationDepartures;
|
|||
import de.schildbach.pte.dto.Style;
|
||||
import de.schildbach.pte.util.ParserUtils;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
|
@ -171,7 +173,7 @@ public class InvgProvider extends AbstractHafasProvider {
|
|||
// scrape page
|
||||
final StringBuilder uri = new StringBuilder(stationBoardEndpoint);
|
||||
appendXmlStationBoardParameters(uri, time, stationId, maxDepartures, false, null);
|
||||
final CharSequence page = httpClient.get(uri.toString());
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()));
|
||||
|
||||
// parse page
|
||||
final Matcher mHeadCoarse = P_DEPARTURES_HEAD_COARSE.matcher(page);
|
||||
|
|
|
@ -51,6 +51,8 @@ import de.schildbach.pte.dto.ResultHeader;
|
|||
import de.schildbach.pte.dto.StationDepartures;
|
||||
import de.schildbach.pte.util.ParserUtils;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
|
@ -134,7 +136,7 @@ public class SeptaProvider extends AbstractHafasProvider {
|
|||
// scrape page
|
||||
final StringBuilder uri = new StringBuilder(stationBoardEndpoint);
|
||||
appendXmlStationBoardParameters(uri, time, stationId, maxDepartures, false, null);
|
||||
final CharSequence page = httpClient.get(uri.toString());
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()));
|
||||
|
||||
// parse page
|
||||
final Matcher mPageCoarse = P_DEPARTURES_PAGE_COARSE.matcher(page);
|
||||
|
|
|
@ -73,6 +73,8 @@ import de.schildbach.pte.dto.Trip;
|
|||
import de.schildbach.pte.dto.Trip.Leg;
|
||||
import de.schildbach.pte.util.ParserUtils;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Michael Dyrna
|
||||
*/
|
||||
|
@ -370,7 +372,7 @@ public class VrsProvider extends AbstractNetworkProvider {
|
|||
uri.append("&s=").append(Math.min(16, maxLocations)); // artificial server limit
|
||||
}
|
||||
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
|
||||
try {
|
||||
final List<Location> locations = new ArrayList<Location>();
|
||||
|
@ -427,7 +429,7 @@ public class VrsProvider extends AbstractNetworkProvider {
|
|||
uri.append("&t=");
|
||||
appendDate(uri, time);
|
||||
}
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
|
||||
try {
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
@ -514,7 +516,7 @@ public class VrsProvider extends AbstractNetworkProvider {
|
|||
final StringBuilder uri = new StringBuilder(API_BASE);
|
||||
uri.append("?eID=tx_vrsinfo_his_info&i=").append(ParserUtils.urlEncode(stationId));
|
||||
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
|
||||
try {
|
||||
final JSONObject head = new JSONObject(page.toString());
|
||||
|
@ -573,7 +575,7 @@ public class VrsProvider extends AbstractNetworkProvider {
|
|||
final String uri = API_BASE + "?eID=tx_vrsinfo_ass2_objects&sc=" + sc + "&ac=" + ac + "&pc=" + ac + "&t=sap&q="
|
||||
+ ParserUtils.urlEncode(new Location(LocationType.ANY, null, null, constraint.toString()).name);
|
||||
|
||||
final CharSequence page = httpClient.get(uri, Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri), Charsets.UTF_8);
|
||||
|
||||
try {
|
||||
final List<SuggestedLocation> locations = new ArrayList<SuggestedLocation>();
|
||||
|
@ -691,7 +693,7 @@ public class VrsProvider extends AbstractNetworkProvider {
|
|||
uri.append("p");
|
||||
}
|
||||
|
||||
final CharSequence page = httpClient.get(uri.toString(), Charsets.UTF_8);
|
||||
final CharSequence page = httpClient.get(HttpUrl.parse(uri.toString()), Charsets.UTF_8);
|
||||
|
||||
try {
|
||||
final List<Trip> trips = new ArrayList<Trip>();
|
||||
|
|
|
@ -18,45 +18,32 @@
|
|||
package de.schildbach.pte.exception;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
|
||||
import de.schildbach.pte.util.HttpClient;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractHttpException extends IOException {
|
||||
private final URL url;
|
||||
private final Reader errorReader;
|
||||
private final HttpUrl url;
|
||||
private final CharSequence bodyPeek;
|
||||
|
||||
public AbstractHttpException(final URL url) {
|
||||
public AbstractHttpException(final HttpUrl url) {
|
||||
this(url, null);
|
||||
}
|
||||
|
||||
public AbstractHttpException(final URL url, final Reader errorReader) {
|
||||
public AbstractHttpException(final HttpUrl url, final CharSequence bodyPeek) {
|
||||
super(url.toString());
|
||||
this.url = url;
|
||||
this.errorReader = errorReader;
|
||||
this.bodyPeek = bodyPeek;
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
public HttpUrl getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Reader getErrorReader() {
|
||||
return errorReader;
|
||||
}
|
||||
|
||||
public CharSequence scrapeErrorStream() throws IOException {
|
||||
if (errorReader == null)
|
||||
return null;
|
||||
|
||||
final StringBuilder error = new StringBuilder(HttpClient.SCRAPE_INITIAL_CAPACITY);
|
||||
HttpClient.copy(errorReader, error);
|
||||
errorReader.close();
|
||||
|
||||
return error;
|
||||
public CharSequence getBodyPeek() {
|
||||
return bodyPeek;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
|
||||
package de.schildbach.pte.exception;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class BlockedException extends AbstractHttpException {
|
||||
public BlockedException(final URL url, final Reader errorReader) {
|
||||
super(url, errorReader);
|
||||
public BlockedException(final HttpUrl url, final CharSequence bodyPeek) {
|
||||
super(url, bodyPeek);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
|
||||
package de.schildbach.pte.exception;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class InternalErrorException extends AbstractHttpException {
|
||||
public InternalErrorException(final URL url, final Reader errorReader) {
|
||||
super(url, errorReader);
|
||||
public InternalErrorException(final HttpUrl url, final CharSequence bodyPeek) {
|
||||
super(url, bodyPeek);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
|
||||
package de.schildbach.pte.exception;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class NotFoundException extends AbstractHttpException {
|
||||
public NotFoundException(final URL url, final Reader errorReader) {
|
||||
super(url, errorReader);
|
||||
public NotFoundException(final HttpUrl url, final CharSequence bodyPeek) {
|
||||
super(url, bodyPeek);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,21 +17,21 @@
|
|||
|
||||
package de.schildbach.pte.exception;
|
||||
|
||||
import java.net.URL;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class UnexpectedRedirectException extends AbstractHttpException {
|
||||
private final URL redirectedUrl;
|
||||
private final HttpUrl redirectedUrl;
|
||||
|
||||
public UnexpectedRedirectException(final URL originalUrl, final URL redirectedUrl) {
|
||||
public UnexpectedRedirectException(final HttpUrl originalUrl, final HttpUrl redirectedUrl) {
|
||||
super(originalUrl);
|
||||
this.redirectedUrl = redirectedUrl;
|
||||
}
|
||||
|
||||
public URL getRedirectedUrl() {
|
||||
public HttpUrl getRedirectedUrl() {
|
||||
return redirectedUrl;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,27 +17,19 @@
|
|||
|
||||
package de.schildbach.pte.util;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -51,6 +43,18 @@ import de.schildbach.pte.exception.NotFoundException;
|
|||
import de.schildbach.pte.exception.SessionExpiredException;
|
||||
import de.schildbach.pte.exception.UnexpectedRedirectException;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
|
@ -61,15 +65,33 @@ public final class HttpClient {
|
|||
@Nullable
|
||||
private String sessionCookieName = null;
|
||||
@Nullable
|
||||
private HttpCookie sessionCookie = null;
|
||||
private Cookie sessionCookie = null;
|
||||
private boolean sslAcceptAllHostnames = false;
|
||||
|
||||
private static final OkHttpClient OKHTTP_CLIENT;
|
||||
static {
|
||||
final HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
|
||||
new HttpLoggingInterceptor.Logger() {
|
||||
@Override
|
||||
public void log(final String message) {
|
||||
log.debug(message);
|
||||
}
|
||||
});
|
||||
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
|
||||
|
||||
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
builder.followRedirects(false);
|
||||
builder.followSslRedirects(true);
|
||||
builder.connectTimeout(5, TimeUnit.SECONDS);
|
||||
builder.writeTimeout(5, TimeUnit.SECONDS);
|
||||
builder.readTimeout(15, TimeUnit.SECONDS);
|
||||
builder.addNetworkInterceptor(loggingInterceptor);
|
||||
OKHTTP_CLIENT = builder.build();
|
||||
}
|
||||
|
||||
private static final String SCRAPE_ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
|
||||
public static final int SCRAPE_INITIAL_CAPACITY = 4096;
|
||||
private static final int SCRAPE_COPY_SIZE = 2048;
|
||||
private static final int SCRAPE_PEEK_SIZE = 4096;
|
||||
private static final int SCRAPE_CONNECT_TIMEOUT = 5000;
|
||||
private static final int SCRAPE_READ_TIMEOUT = 15000;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(HttpClient.class);
|
||||
|
||||
|
@ -89,201 +111,129 @@ public final class HttpClient {
|
|||
this.sslAcceptAllHostnames = sslAcceptAllHostnames;
|
||||
}
|
||||
|
||||
public CharSequence get(final String url) throws IOException {
|
||||
public CharSequence get(final HttpUrl url) throws IOException {
|
||||
return get(url, null);
|
||||
}
|
||||
|
||||
public CharSequence get(final String urlStr, final Charset requestEncoding) throws IOException {
|
||||
return get(urlStr, null, null, requestEncoding);
|
||||
public CharSequence get(final HttpUrl url, final Charset requestEncoding) throws IOException {
|
||||
return get(url, null, null, requestEncoding);
|
||||
}
|
||||
|
||||
public CharSequence get(final String urlStr, final String postRequest, final String requestContentType,
|
||||
public CharSequence get(final HttpUrl url, final String postRequest, final String requestContentType,
|
||||
Charset requestEncoding) throws IOException {
|
||||
if (requestEncoding == null)
|
||||
requestEncoding = Charsets.ISO_8859_1;
|
||||
|
||||
final StringBuilder buffer = new StringBuilder(SCRAPE_INITIAL_CAPACITY);
|
||||
final InputStream is = getInputStream(urlStr, postRequest, requestContentType, requestEncoding, null);
|
||||
final Reader pageReader = new InputStreamReader(is, requestEncoding);
|
||||
copy(pageReader, buffer);
|
||||
pageReader.close();
|
||||
final Callback callback = new Callback() {
|
||||
@Override
|
||||
public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException {
|
||||
buffer.append(body.string());
|
||||
}
|
||||
};
|
||||
getInputStream(callback, url, postRequest, requestContentType, requestEncoding, null);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public InputStream getInputStream(final String url) throws IOException {
|
||||
return getInputStream(url, null, null);
|
||||
public interface Callback {
|
||||
void onSuccessful(CharSequence bodyPeek, ResponseBody body) throws IOException;
|
||||
}
|
||||
|
||||
public InputStream getInputStream(final String urlStr, final Charset requestEncoding, final String referer)
|
||||
throws IOException {
|
||||
return getInputStream(urlStr, null, null, requestEncoding, referer);
|
||||
public void getInputStream(final Callback callback, final HttpUrl url) throws IOException {
|
||||
getInputStream(callback, url, null, null);
|
||||
}
|
||||
|
||||
public InputStream getInputStream(final String urlStr, final String postRequest, final String requestContentType,
|
||||
Charset requestEncoding, final String referer) throws IOException {
|
||||
log.debug("{}: {}", postRequest != null ? "POST" : "GET", urlStr);
|
||||
public void getInputStream(final Callback callback, final HttpUrl url, final Charset requestEncoding,
|
||||
final String referer) throws IOException {
|
||||
getInputStream(callback, url, null, null, requestEncoding, referer);
|
||||
}
|
||||
|
||||
public void getInputStream(final Callback callback, final HttpUrl url, final String postRequest,
|
||||
final String requestContentType, Charset requestEncoding, final String referer) throws IOException {
|
||||
if (requestEncoding == null)
|
||||
requestEncoding = Charsets.ISO_8859_1;
|
||||
|
||||
int tries = 3;
|
||||
|
||||
while (true) {
|
||||
final URL url = new URL(urlStr);
|
||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
if (connection instanceof HttpsURLConnection && sslAcceptAllHostnames)
|
||||
((HttpsURLConnection) connection).setHostnameVerifier(SSL_ACCEPT_ALL_HOSTNAMES);
|
||||
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(postRequest != null);
|
||||
connection.setConnectTimeout(SCRAPE_CONNECT_TIMEOUT);
|
||||
connection.setReadTimeout(SCRAPE_READ_TIMEOUT);
|
||||
for (final Map.Entry<String, String> entry : headers.entrySet())
|
||||
connection.addRequestProperty(entry.getKey(), entry.getValue());
|
||||
final Request.Builder request = new Request.Builder();
|
||||
request.url(url);
|
||||
request.headers(Headers.of(headers));
|
||||
if (postRequest != null)
|
||||
request.post(RequestBody.create(MediaType.parse(requestContentType), postRequest));
|
||||
request.header("Accept", SCRAPE_ACCEPT);
|
||||
if (userAgent != null)
|
||||
connection.addRequestProperty("User-Agent", userAgent);
|
||||
connection.addRequestProperty("Accept", SCRAPE_ACCEPT);
|
||||
connection.addRequestProperty("Accept-Encoding", "gzip");
|
||||
// workaround to disable Vodafone compression
|
||||
connection.addRequestProperty("Cache-Control", "no-cache");
|
||||
|
||||
request.header("User-Agent", userAgent);
|
||||
if (referer != null)
|
||||
connection.addRequestProperty("Referer", referer);
|
||||
request.header("Referer", referer);
|
||||
final Cookie sessionCookie = this.sessionCookie;
|
||||
if (sessionCookie != null && sessionCookie.name().equals(sessionCookieName))
|
||||
request.header("Cookie", sessionCookie.toString());
|
||||
|
||||
final HttpCookie sessionCookie = this.sessionCookie;
|
||||
if (sessionCookie != null && sessionCookie.getName().equals(sessionCookieName))
|
||||
connection.addRequestProperty("Cookie", sessionCookie.toString());
|
||||
final OkHttpClient okHttpClient;
|
||||
if (sslAcceptAllHostnames)
|
||||
okHttpClient = OKHTTP_CLIENT.newBuilder().hostnameVerifier(SSL_ACCEPT_ALL_HOSTNAMES).build();
|
||||
else
|
||||
okHttpClient = OKHTTP_CLIENT;
|
||||
|
||||
if (postRequest != null) {
|
||||
final byte[] postRequestBytes = postRequest.getBytes(requestEncoding.name());
|
||||
final Call call = okHttpClient.newCall(request.build());
|
||||
Response response = null;
|
||||
try {
|
||||
response = call.execute();
|
||||
final int responseCode = response.code();
|
||||
final String bodyPeek = response.peekBody(SCRAPE_PEEK_SIZE).string().replaceAll("\\p{C}", "");
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Content-Type", requestContentType);
|
||||
connection.addRequestProperty("Content-Length", Integer.toString(postRequestBytes.length));
|
||||
final HttpUrl redirectUrl = testRedirect(url, bodyPeek);
|
||||
if (redirectUrl != null)
|
||||
throw new UnexpectedRedirectException(url, redirectUrl);
|
||||
|
||||
final OutputStream os = connection.getOutputStream();
|
||||
os.write(postRequestBytes);
|
||||
os.close();
|
||||
}
|
||||
if (testExpired(bodyPeek))
|
||||
throw new SessionExpiredException();
|
||||
if (testInternalError(bodyPeek))
|
||||
throw new InternalErrorException(url, bodyPeek);
|
||||
|
||||
final int responseCode = connection.getResponseCode();
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
final String contentType = connection.getContentType();
|
||||
final String contentEncoding = connection.getContentEncoding();
|
||||
|
||||
InputStream is = new BufferedInputStream(connection.getInputStream());
|
||||
|
||||
if ("gzip".equalsIgnoreCase(contentEncoding)
|
||||
|| "application/octet-stream".equalsIgnoreCase(contentType))
|
||||
is = wrapGzip(is);
|
||||
|
||||
if (!url.getHost().equals(connection.getURL().getHost()))
|
||||
throw new UnexpectedRedirectException(url, connection.getURL());
|
||||
|
||||
final String firstChars = peekFirstChars(is);
|
||||
|
||||
final URL redirectUrl = testRedirect(url, firstChars);
|
||||
if (redirectUrl != null)
|
||||
throw new UnexpectedRedirectException(url, redirectUrl);
|
||||
|
||||
if (testExpired(firstChars))
|
||||
throw new SessionExpiredException();
|
||||
|
||||
if (testInternalError(firstChars))
|
||||
throw new InternalErrorException(url, new InputStreamReader(is, requestEncoding));
|
||||
|
||||
// save cookie
|
||||
if (sessionCookieName != null) {
|
||||
c: for (final Map.Entry<String, List<String>> entry : connection.getHeaderFields().entrySet()) {
|
||||
if ("set-cookie".equalsIgnoreCase(entry.getKey())
|
||||
|| "set-cookie2".equalsIgnoreCase(entry.getKey())) {
|
||||
for (final String value : entry.getValue()) {
|
||||
for (final HttpCookie cookie : HttpCookie.parse(value)) {
|
||||
if (cookie.getName().equals(sessionCookieName)) {
|
||||
this.sessionCookie = cookie;
|
||||
break c;
|
||||
}
|
||||
}
|
||||
// save cookie
|
||||
if (sessionCookieName != null) {
|
||||
final List<Cookie> cookies = Cookie.parseAll(url, response.headers());
|
||||
for (final Iterator<Cookie> i = cookies.iterator(); i.hasNext();) {
|
||||
final Cookie cookie = i.next();
|
||||
if (cookie.name().equals(sessionCookieName)) {
|
||||
this.sessionCookie = cookie;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback.onSuccessful(bodyPeek, response.body());
|
||||
return;
|
||||
} else if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST
|
||||
|| responseCode == HttpURLConnection.HTTP_UNAUTHORIZED
|
||||
|| responseCode == HttpURLConnection.HTTP_FORBIDDEN
|
||||
|| responseCode == HttpURLConnection.HTTP_NOT_ACCEPTABLE
|
||||
|| responseCode == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
throw new BlockedException(url, bodyPeek);
|
||||
} else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||
throw new NotFoundException(url, bodyPeek);
|
||||
} else if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
|
||||
throw new UnexpectedRedirectException(url, HttpUrl.parse(response.header("Location")));
|
||||
} else if (responseCode == HttpURLConnection.HTTP_INTERNAL_ERROR) {
|
||||
throw new InternalErrorException(url, bodyPeek);
|
||||
} else {
|
||||
final String message = "got response: " + responseCode + " " + response.message();
|
||||
if (tries-- > 0)
|
||||
log.info("{}, retrying...", message);
|
||||
else
|
||||
throw new IOException(message + ": " + url);
|
||||
}
|
||||
|
||||
return is;
|
||||
} else if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST
|
||||
|| responseCode == HttpURLConnection.HTTP_UNAUTHORIZED
|
||||
|| responseCode == HttpURLConnection.HTTP_FORBIDDEN
|
||||
|| responseCode == HttpURLConnection.HTTP_NOT_ACCEPTABLE
|
||||
|| responseCode == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
throw new BlockedException(url, new InputStreamReader(connection.getErrorStream(), requestEncoding));
|
||||
} else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||
throw new NotFoundException(url, new InputStreamReader(connection.getErrorStream(), requestEncoding));
|
||||
} else if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
|
||||
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
|
||||
throw new UnexpectedRedirectException(url, connection.getURL());
|
||||
} else if (responseCode == HttpURLConnection.HTTP_INTERNAL_ERROR) {
|
||||
throw new InternalErrorException(url,
|
||||
new InputStreamReader(connection.getErrorStream(), requestEncoding));
|
||||
} else {
|
||||
final String message = "got response: " + responseCode + " " + connection.getResponseMessage();
|
||||
if (tries-- > 0)
|
||||
log.info("{}, retrying...", message);
|
||||
else
|
||||
throw new IOException(message + ": " + url);
|
||||
} finally {
|
||||
if (response != null)
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final long copy(final Reader reader, final StringBuilder builder) throws IOException {
|
||||
final char[] buffer = new char[SCRAPE_COPY_SIZE];
|
||||
long count = 0;
|
||||
int n = 0;
|
||||
while (-1 != (n = reader.read(buffer))) {
|
||||
builder.append(buffer, 0, n);
|
||||
count += n;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private static InputStream wrapGzip(final InputStream is) throws IOException {
|
||||
is.mark(2);
|
||||
final int byte0 = is.read();
|
||||
final int byte1 = is.read();
|
||||
is.reset();
|
||||
|
||||
// check for gzip header
|
||||
if (byte0 == 0x1f && byte1 == 0x8b) {
|
||||
final BufferedInputStream is2 = new BufferedInputStream(new GZIPInputStream(is));
|
||||
is2.mark(2);
|
||||
final int byte0_2 = is2.read();
|
||||
final int byte1_2 = is2.read();
|
||||
is2.reset();
|
||||
|
||||
// check for gzip header again
|
||||
if (byte0_2 == 0x1f && byte1_2 == 0x8b) {
|
||||
// double gzipped
|
||||
return new BufferedInputStream(new GZIPInputStream(is2));
|
||||
} else {
|
||||
// gzipped
|
||||
return is2;
|
||||
}
|
||||
} else {
|
||||
// uncompressed
|
||||
return is;
|
||||
}
|
||||
}
|
||||
|
||||
public static String peekFirstChars(final InputStream is) throws IOException {
|
||||
is.mark(SCRAPE_PEEK_SIZE);
|
||||
final byte[] firstBytes = new byte[SCRAPE_PEEK_SIZE];
|
||||
final int read = is.read(firstBytes);
|
||||
if (read == -1)
|
||||
return "";
|
||||
is.reset();
|
||||
return new String(firstBytes, 0, read).replaceAll("\\p{C}", "");
|
||||
}
|
||||
|
||||
private static final Pattern P_REDIRECT_HTTP_EQUIV = Pattern.compile(
|
||||
"<META\\s+http-equiv=\"?refresh\"?\\s+content=\"\\d+;\\s*URL=([^\"]+)\"", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
|
@ -291,16 +241,16 @@ public final class HttpClient {
|
|||
"<script\\s+(?:type=\"text/javascript\"|language=\"javascript\")>\\s*(?:window.location|location.href)\\s*=\\s*\"([^\"]+)\"",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static URL testRedirect(final URL context, final String content) throws MalformedURLException {
|
||||
public static HttpUrl testRedirect(final HttpUrl base, final String content) {
|
||||
// check for redirect by http-equiv meta tag header
|
||||
final Matcher mHttpEquiv = P_REDIRECT_HTTP_EQUIV.matcher(content);
|
||||
if (mHttpEquiv.find())
|
||||
return new URL(context, mHttpEquiv.group(1));
|
||||
return base.resolve(mHttpEquiv.group(1));
|
||||
|
||||
// check for redirect by window.location javascript
|
||||
final Matcher mScript = P_REDIRECT_SCRIPT.matcher(content);
|
||||
if (mScript.find())
|
||||
return new URL(context, mScript.group(1));
|
||||
return base.resolve(mScript.group(1));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -21,51 +21,51 @@ import static org.junit.Assert.assertEquals;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
public class HttpClientTest {
|
||||
private URL context;
|
||||
private HttpUrl base;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
context = new URL("http://example.com");
|
||||
base = HttpUrl.parse("http://example.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void vodafoneRedirect() throws Exception {
|
||||
final URL url = HttpClient.testRedirect(context,
|
||||
final HttpUrl url = HttpClient.testRedirect(base,
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.1//EN \" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile11.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\"><head><title>Vodafone Center</title><meta http-equiv=\"Cache-Control\" content=\"no-cache\"/><meta http-equiv=\"refresh\" content=\"1;URL=https://center.vodafone.de/vfcenter/index.html?targetUrl=http%3A%2F%2Fwww.fahrinfo-berlin.de/Fahrinfo/bin/query.bin/dn%3fstart=Suchen&REQ0JourneyStopsS0ID=A%253D1%2540L%253D9083301&REQ0JourneyStopsZ0ID=A%253D1%2540L%253D9195009&REQ0HafasSearchForw=1&REQ0JourneyDate=16.06.14&REQ0JourneyTime=16%253A32&REQ0JourneyProduct_prod_list_1=11111011&h2g-direct=11&L=vs_oeffi\"/><style type=\"text/css\">*{border:none;font-family:Arial,Helvetica,sans-serif} body{font-size:69%;line-height:140%;background-color:#F4F4F4 !important}</style></head><body><h1>Sie werden weitergeleitet ...</h1><p>Sollten Sie nicht weitergeleitet werden, klicken Sie bitte <a href=\"https://center.vodafo");
|
||||
assertNotNull(url);
|
||||
assertEquals("center.vodafone.de", url.getHost());
|
||||
assertEquals("center.vodafone.de", url.host());
|
||||
}
|
||||
|
||||
public void kabelDeutschlandRedirect() throws Exception {
|
||||
final URL url = HttpClient.testRedirect(context,
|
||||
final HttpUrl url = HttpClient.testRedirect(base,
|
||||
"<script type=\"text/javascript\"> window.location = \"http://www.hotspot.kabeldeutschland.de/portal/?RequestedURI=http%3A%2F%2Fwww.fahrinfo-berlin.de%2FFahrinfo%2Fbin%2Fajax-getstop.bin%2Fdny%3Fgetstop%3D1%26REQ0JourneyStopsS0A%3D255%26REQ0JourneyStopsS0G%3Dgneisenustra%25DFe%3F%26js%3Dtrue&RedirectReason=Policy&RedirectAqpId=100&DiscardAqpId=100&SubscriberId=4fa432d4a653e5f8b2acb27aa862f98d&SubscriberType=ESM&ClientIP=10.136.25.241&SystemId=10.143.181.2-1%2F2&GroupId=1&PartitionId=2&Application=Unknown&ApplicationGroup=Unknown\" </script>");
|
||||
assertNotNull(url);
|
||||
assertEquals("www.hotspot.kabeldeutschland.de", url.getHost());
|
||||
assertEquals("www.hotspot.kabeldeutschland.de", url.host());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tplinkRedirect() throws Exception {
|
||||
final URL url = HttpClient.testRedirect(context,
|
||||
final HttpUrl url = HttpClient.testRedirect(base,
|
||||
"<body><script language=\"javaScript\">location.href=\"http://tplinkextender.net/\";</script></body></html>");
|
||||
assertNotNull(url);
|
||||
assertEquals("tplinkextender.net", url.getHost());
|
||||
assertEquals("tplinkextender.net", url.host());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mshtmlRedirect() throws Exception {
|
||||
final URL url = HttpClient.testRedirect(context,
|
||||
final HttpUrl url = HttpClient.testRedirect(base,
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><HEAD><TITLE>HTML Redirection</TITLE><META http-equiv=Content-Type content=\"text/html; \"><META http-equiv=Refresh content=\"0;URL=/cgi-bin/index.cgi\"><META content=\"MSHTML 6.00.2900.2873\" name=GENERATOR></HEAD><BODY > <NOSCRIPT> If your browser can not redirect you to home page automatically.<br> Please click <a href=/cgi-bin/welcome.cgi?lang=0>here</a>. </NOSCRIPT></BODY></HTML>");
|
||||
assertNotNull(url);
|
||||
assertEquals("example.com", url.getHost());
|
||||
assertEquals("example.com", url.host());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue