Skip to content

Commit 590a787

Browse files
Merge pull request #64 from nextcloud/improve-query-params-parsing
parse query parameters in url and put them into the parameterMap
2 parents 22f7eb2 + e77876c commit 590a787

File tree

3 files changed

+69
-22
lines changed

3 files changed

+69
-22
lines changed

src/main/java/com/nextcloud/android/sso/api/NextcloudRetrofitServiceMethod.java

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.nextcloud.android.sso.api;
22

3-
import androidx.annotation.Nullable;
43
import android.util.Log;
54

5+
import androidx.annotation.Nullable;
6+
67
import com.nextcloud.android.sso.aidl.NextcloudRequest;
78
import com.nextcloud.android.sso.helper.Okhttp3Helper;
89
import com.nextcloud.android.sso.helper.ReactivexHelper;
@@ -22,6 +23,7 @@
2223
import java.security.InvalidParameterException;
2324
import java.util.ArrayList;
2425
import java.util.HashMap;
26+
import java.util.LinkedHashMap;
2527
import java.util.List;
2628
import java.util.Map;
2729
import java.util.regex.Matcher;
@@ -63,6 +65,7 @@ public class NextcloudRetrofitServiceMethod<T> {
6365
private @Nullable Headers headers;
6466
private Type returnType;
6567
private boolean followRedirects = false;
68+
private Map<String, String> queryParameters;
6669
//private boolean formUrlEncoded = false;
6770

6871
private final NextcloudRequest.Builder requestBuilder;
@@ -79,6 +82,8 @@ public NextcloudRetrofitServiceMethod(String apiEndpoint, Method method) {
7982
parseMethodAnnotation(annotation);
8083
}
8184

85+
this.queryParameters = parsePathParameters();
86+
8287
if(headers == null) {
8388
headers = new Headers.Builder().build();
8489
}
@@ -105,6 +110,10 @@ public T invoke(NextcloudAPI nextcloudAPI, Object[] args) throws Exception {
105110

106111
Map<String, String> parameters = new HashMap<>();
107112

113+
// Copy all static query params into parameters array
114+
parameters.putAll(this.queryParameters);
115+
116+
// Build/parse dynamic parameters
108117
for(int i = 0; i < parameterAnnotationsArray.length; i++) {
109118
Annotation annotation = parameterAnnotationsArray[i][0];
110119

@@ -237,20 +246,7 @@ private void parseHttpMethodAndPath(String httpMethod, String value, boolean has
237246
return;
238247
}
239248

240-
// Get the relative URL path and existing query string, if present.
241-
int question = value.indexOf('?');
242-
if (question != -1 && question < value.length() - 1) {
243-
// Ensure the query string does not have any named parameters.
244-
String queryParams = value.substring(question + 1);
245-
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
246-
if (queryParamMatcher.find()) {
247-
throw methodError(method, "URL query string \"%s\" must not have replace block. "
248-
+ "For dynamic query parameters use @Query.", queryParams);
249-
}
250-
}
251-
252249
this.relativeUrl = value;
253-
//Set<String> relativeUrlParamNames = parsePathParameters(value);
254250
}
255251

256252
private Headers parseHeaders(String[] headers) {
@@ -282,16 +278,37 @@ private Headers parseHeaders(String[] headers) {
282278
* Gets the set of unique path parameters used in the given URI. If a parameter is used twice
283279
* in the URI, it will only show up once in the set.
284280
*/
285-
/*
286-
private static Set<String> parsePathParameters(String path) {
287-
Matcher m = PARAM_URL_REGEX.matcher(path);
288-
Set<String> patterns = new LinkedHashSet<>();
289-
while (m.find()) {
290-
patterns.add(m.group(1));
281+
private Map<String, String> parsePathParameters() {
282+
Map<String, String> queryPairs = new LinkedHashMap<>();
283+
284+
if(this.relativeUrl == null) {
285+
return queryPairs;
286+
}
287+
288+
int idxQuery = this.relativeUrl.indexOf("?");
289+
if (idxQuery != -1 && idxQuery < this.relativeUrl.length() - 1) {
290+
// Ensure the query string does not have any named parameters.
291+
String query = this.relativeUrl.substring(idxQuery + 1);
292+
293+
// Check for named parameters
294+
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(query);
295+
if (queryParamMatcher.find()) {
296+
throw methodError(method, "URL query string \"%s\" must not have replace block. "
297+
+ "For dynamic query parameters use @Query.", query);
298+
}
299+
300+
// If none found.. parse the static query parameters
301+
String[] pairs = query.split("&");
302+
for (String pair : pairs) {
303+
int idx = pair.indexOf("=");
304+
queryPairs.put(pair.substring(0, idx), pair.substring(idx + 1));
305+
}
306+
307+
// Remove query params from url
308+
this.relativeUrl = this.relativeUrl.substring(0, idxQuery);
291309
}
292-
return patterns;
310+
return queryPairs;
293311
}
294-
*/
295312

296313

297314

src/test/java/com/nextcloud/android/sso/api/API.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,7 @@ Observable<ResponseBody> getStreamingUpdatedItems(
100100
@POST("/test")
101101
Call<ResponseBody> postFormUrlEncodedField(@Field("name") String name);
102102

103+
@GET("cloud/capabilities?format=json")
104+
Call<ResponseBody> getCapabilities(@Query("test") long test);
105+
103106
}

src/test/java/com/nextcloud/android/sso/api/TestRetrofitAPI.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,33 @@ public void testFormUrlEncodedField() {
425425
}
426426

427427

428+
@Test
429+
public void testQueryParamInUrl() {
430+
try {
431+
mApi.getCapabilities(1).execute();
432+
} catch (IOException e) {
433+
fail(e.getMessage());
434+
}
435+
436+
Map<String, String> map = new HashMap<>();
437+
map.put("format", "json");
438+
map.put("test", "1");
439+
440+
NextcloudRequest request = new NextcloudRequest.Builder()
441+
.setMethod("GET")
442+
.setUrl(mApiEndpoint + "cloud/capabilities")
443+
.setParameter(map)
444+
.build();
445+
446+
Type type = new TypeToken<ResponseBody>() {}.getType();
447+
try {
448+
verify(nextcloudApiMock).performRequest(eq(type), eq(request));
449+
} catch (Exception e) {
450+
fail(e.getMessage());
451+
}
452+
}
453+
454+
428455
@Test
429456
public void testExecute() {
430457
try {

0 commit comments

Comments
 (0)