Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 590a7871 authored by David Luhmer's avatar David Luhmer Committed by GitHub
Browse files

Merge pull request #64 from nextcloud/improve-query-params-parsing

parse query parameters in url and put them into the parameterMap
parents 22f7eb22 e77876c0
Loading
Loading
Loading
Loading
+39 −22
Original line number Diff line number Diff line
package com.nextcloud.android.sso.api;

import androidx.annotation.Nullable;
import android.util.Log;

import androidx.annotation.Nullable;

import com.nextcloud.android.sso.aidl.NextcloudRequest;
import com.nextcloud.android.sso.helper.Okhttp3Helper;
import com.nextcloud.android.sso.helper.ReactivexHelper;
@@ -22,6 +23,7 @@ import java.lang.reflect.Type;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@@ -63,6 +65,7 @@ public class NextcloudRetrofitServiceMethod<T> {
    private @Nullable Headers headers;
    private Type returnType;
    private boolean followRedirects = false;
    private Map<String, String> queryParameters;
    //private boolean formUrlEncoded = false;

    private final NextcloudRequest.Builder requestBuilder;
@@ -79,6 +82,8 @@ public class NextcloudRetrofitServiceMethod<T> {
            parseMethodAnnotation(annotation);
        }

        this.queryParameters = parsePathParameters();

        if(headers == null) {
            headers = new Headers.Builder().build();
        }
@@ -105,6 +110,10 @@ public class NextcloudRetrofitServiceMethod<T> {

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

        // Copy all static query params into parameters array
        parameters.putAll(this.queryParameters);

        // Build/parse dynamic parameters
        for(int i = 0; i < parameterAnnotationsArray.length; i++) {
            Annotation annotation = parameterAnnotationsArray[i][0];

@@ -237,20 +246,7 @@ public class NextcloudRetrofitServiceMethod<T> {
            return;
        }

        // Get the relative URL path and existing query string, if present.
        int question = value.indexOf('?');
        if (question != -1 && question < value.length() - 1) {
            // Ensure the query string does not have any named parameters.
            String queryParams = value.substring(question + 1);
            Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
            if (queryParamMatcher.find()) {
                throw methodError(method, "URL query string \"%s\" must not have replace block. "
                        + "For dynamic query parameters use @Query.", queryParams);
            }
        }

        this.relativeUrl = value;
        //Set<String> relativeUrlParamNames = parsePathParameters(value);
    }

    private Headers parseHeaders(String[] headers) {
@@ -282,16 +278,37 @@ public class NextcloudRetrofitServiceMethod<T> {
     * Gets the set of unique path parameters used in the given URI. If a parameter is used twice
     * in the URI, it will only show up once in the set.
     */
    /*
    private static Set<String> parsePathParameters(String path) {
        Matcher m = PARAM_URL_REGEX.matcher(path);
        Set<String> patterns = new LinkedHashSet<>();
        while (m.find()) {
            patterns.add(m.group(1));
    private Map<String, String> parsePathParameters() {
        Map<String, String> queryPairs = new LinkedHashMap<>();

        if(this.relativeUrl == null) {
            return queryPairs;
        }

        int idxQuery = this.relativeUrl.indexOf("?");
        if (idxQuery != -1 && idxQuery < this.relativeUrl.length() - 1) {
            // Ensure the query string does not have any named parameters.
            String query = this.relativeUrl.substring(idxQuery + 1);

            // Check for named parameters
            Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(query);
            if (queryParamMatcher.find()) {
                throw methodError(method, "URL query string \"%s\" must not have replace block. "
                        + "For dynamic query parameters use @Query.", query);
            }
        return patterns;

            // If none found.. parse the static query parameters
            String[] pairs = query.split("&");
            for (String pair : pairs) {
                int idx = pair.indexOf("=");
                queryPairs.put(pair.substring(0, idx), pair.substring(idx + 1));
            }

            // Remove query params from url
            this.relativeUrl = this.relativeUrl.substring(0, idxQuery);
        }
        return queryPairs;
    }
    */



+3 −0
Original line number Diff line number Diff line
@@ -100,4 +100,7 @@ public interface API {
    @POST("/test")
    Call<ResponseBody> postFormUrlEncodedField(@Field("name") String name);

    @GET("cloud/capabilities?format=json")
    Call<ResponseBody> getCapabilities(@Query("test") long test);

}
+27 −0
Original line number Diff line number Diff line
@@ -425,6 +425,33 @@ public class TestRetrofitAPI {
    }


    @Test
    public void testQueryParamInUrl() {
        try {
            mApi.getCapabilities(1).execute();
        } catch (IOException e) {
            fail(e.getMessage());
        }

        Map<String, String> map = new HashMap<>();
        map.put("format", "json");
        map.put("test", "1");

        NextcloudRequest request = new NextcloudRequest.Builder()
                .setMethod("GET")
                .setUrl(mApiEndpoint + "cloud/capabilities")
                .setParameter(map)
                .build();

        Type type = new TypeToken<ResponseBody>() {}.getType();
        try {
            verify(nextcloudApiMock).performRequest(eq(type), eq(request));
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }


    @Test
    public void testExecute() {
        try {