diff --git a/services-core/src/main/java/com/mapbox/core/MapboxService.java b/services-core/src/main/java/com/mapbox/core/MapboxService.java index 76fc0f895..7322d3821 100644 --- a/services-core/src/main/java/com/mapbox/core/MapboxService.java +++ b/services-core/src/main/java/com/mapbox/core/MapboxService.java @@ -21,7 +21,7 @@ * @since 1.0.0 */ public abstract class MapboxService { - + protected static final int MAX_URL_SIZE = 1024 * 8; private final Class serviceType; private boolean enableDebug; protected OkHttpClient okHttpClient; diff --git a/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java b/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java index 6f49195b3..62eefb02d 100644 --- a/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java +++ b/services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java @@ -56,7 +56,6 @@ @AutoValue public abstract class MapboxDirections extends MapboxService { - private static final int MAX_URL_SIZE = 1024 * 8; protected MapboxDirections() { super(DirectionsService.class); diff --git a/services-matching/src/main/java/com/mapbox/api/matching/v5/MapboxMapMatching.java b/services-matching/src/main/java/com/mapbox/api/matching/v5/MapboxMapMatching.java index 61aadaee9..110591730 100644 --- a/services-matching/src/main/java/com/mapbox/api/matching/v5/MapboxMapMatching.java +++ b/services-matching/src/main/java/com/mapbox/api/matching/v5/MapboxMapMatching.java @@ -60,29 +60,26 @@ protected GsonBuilder getGsonBuilder() { @Override protected Call initializeCall() { + if (usePostMethod() == null) { + return callForUrlLength(); + } + if (usePostMethod()) { - return getService().postCall( - ApiCallHelper.getHeaderUserAgent(clientAppName()), - user(), - profile(), - coordinates(), - accessToken(), - geometries(), - radiuses(), - steps(), - overview(), - timestamps(), - annotations(), - language(), - tidy(), - roundaboutExits(), - bannerInstructions(), - voiceInstructions(), - voiceUnits(), - waypointIndices(), - waypointNames(), - approaches()); + return post(); + } + + return get(); + } + + private Call callForUrlLength() { + Call get = get(); + if (get.request().url().toString().length() < MAX_URL_SIZE) { + return get; } + return post(); + } + + private Call get() { return getService().getCall( ApiCallHelper.getHeaderUserAgent(clientAppName()), user(), @@ -106,6 +103,30 @@ protected Call initializeCall() { approaches()); } + private Call post() { + return getService().postCall( + ApiCallHelper.getHeaderUserAgent(clientAppName()), + user(), + profile(), + coordinates(), + accessToken(), + geometries(), + radiuses(), + steps(), + overview(), + timestamps(), + annotations(), + language(), + tidy(), + roundaboutExits(), + bannerInstructions(), + voiceInstructions(), + voiceUnits(), + waypointIndices(), + waypointNames(), + approaches()); + } + /** * Wrapper method for Retrofits {@link Call#execute()} call returning a response specific to the * Map Matching API. @@ -149,7 +170,7 @@ public void onFailure(Call call, Throwable throwable) { }); } - @NonNull + @Nullable abstract Boolean usePostMethod(); @Nullable @@ -228,8 +249,7 @@ public static Builder builder() { .baseUrl(Constants.BASE_API_URL) .profile(DirectionsCriteria.PROFILE_DRIVING) .geometries(DirectionsCriteria.GEOMETRY_POLYLINE6) - .user(DirectionsCriteria.PROFILE_DEFAULT_USER) - .usePostMethod(false); + .user(DirectionsCriteria.PROFILE_DEFAULT_USER); } /** @@ -666,7 +686,7 @@ public MapboxMapMatching build() { "Waypoints must be a list of at least two indexes separated by ';'"); } if (waypointIndices[0] != 0 - || waypointIndices[waypointIndices.length - 1] != coordinates.size() - 1) { + || waypointIndices[waypointIndices.length - 1] != coordinates.size() - 1) { throw new ServicesException( "Waypoints must contain indices of the first and last coordinates" ); diff --git a/services-matching/src/test/java/com/mapbox/api/matching/v5/MapboxMapMatchingTest.java b/services-matching/src/test/java/com/mapbox/api/matching/v5/MapboxMapMatchingTest.java index 873844edf..cfd8484c2 100644 --- a/services-matching/src/test/java/com/mapbox/api/matching/v5/MapboxMapMatchingTest.java +++ b/services-matching/src/test/java/com/mapbox/api/matching/v5/MapboxMapMatchingTest.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Random; import okhttp3.HttpUrl; import okhttp3.mockwebserver.MockResponse; @@ -674,4 +675,94 @@ public void testUsePostMethod() throws Exception { assertNotNull(response.body().matchings()); assertEquals(1, response.body().matchings().size()); } + + @Test + public void testCallForUrlLength_longUrl() { + MapboxMapMatching.Builder builder = MapboxMapMatching.builder() + .profile(PROFILE_CYCLING) + .steps(true) + .coordinate(Point.fromLngLat(-122.42,37.78)) + .coordinate(Point.fromLngLat(-77.03,38.91)) + .voiceInstructions(true) + .voiceUnits(DirectionsCriteria.IMPERIAL) + .accessToken(ACCESS_TOKEN) + .baseUrl(mockUrl.toString()); + addWaypoints(builder, 400); + + retrofit2.Call call = builder.build().initializeCall(); + + assertEquals("POST", call.request().method()); + } + + @Test + public void testCallForUrlLength_shortUrl() { + MapboxMapMatching.Builder builder = MapboxMapMatching.builder() + .profile(PROFILE_CYCLING) + .steps(true) + .coordinate(Point.fromLngLat(-122.42,37.78)) + .coordinate(Point.fromLngLat(-77.03,38.91)) + .voiceInstructions(true) + .voiceUnits(DirectionsCriteria.IMPERIAL) + .accessToken(ACCESS_TOKEN) + .baseUrl(mockUrl.toString()); + addWaypoints(builder, 10); + + retrofit2.Call call = builder.build().initializeCall(); + + assertEquals("GET", call.request().method()); + } + + @Test + public void testPostIsUsed() { + MapboxMapMatching.Builder builder = MapboxMapMatching.builder() + .profile(PROFILE_CYCLING) + .steps(true) + .coordinate(Point.fromLngLat(-122.42,37.78)) + .coordinate(Point.fromLngLat(-77.03,38.91)) + .voiceInstructions(true) + .voiceUnits(DirectionsCriteria.IMPERIAL) + .accessToken(ACCESS_TOKEN) + .baseUrl(mockUrl.toString()) + .post(); + + retrofit2.Call call = builder.build().initializeCall(); + + assertEquals("POST", call.request().method()); + } + + @Test + public void testGetIsUsed() { + MapboxMapMatching.Builder builder = MapboxMapMatching.builder() + .profile(PROFILE_CYCLING) + .steps(true) + .coordinate(Point.fromLngLat(-122.42,37.78)) + .coordinate(Point.fromLngLat(-77.03,38.91)) + .voiceInstructions(true) + .voiceUnits(DirectionsCriteria.IMPERIAL) + .accessToken(ACCESS_TOKEN) + .baseUrl(mockUrl.toString()) + .get(); + + retrofit2.Call call = builder.build().initializeCall(); + + assertEquals("GET", call.request().method()); + } + + private void addWaypoints(MapboxMapMatching.Builder builder, int number) { + for (int i = 0; i < number; i++) { + builder.coordinate(Point.fromLngLat(getRandomLng(), getRandomLat())); + } + } + + private double getRandomLng() { + Random random = new Random(); + double lng = random.nextDouble() % 360; + return lng - 180; + } + + private double getRandomLat() { + Random random = new Random(); + double lat = random.nextDouble() % 180; + return lat - 90; + } }