[GH-ISSUE #511] Mapping with Non-deterministic Ordering of Query Parameters #507

Open
opened 2026-03-03 19:19:24 +03:00 by kerem · 4 comments
Owner

Originally created by @grantjbutler on GitHub (May 28, 2020).
Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/511

Originally assigned to: @NghiaTranUIT on GitHub.

Proxyman version? (Ex. Proxyman 1.4.3)

Version 1.23.0 (12300)

macOS Version? (Ex. mac 10.14)

macOS 10.15.4 (19E287)

Steps to reproduce

Set up mapping for a URL that has multiple query parameters in it (I've tested with local mapping, so I'm not sure if this applies to remote mapping, too). For example, a URL that looks something like https://domain.tld/path?param1=value1&param2=value2. With that mapping enable, sometimes requests are still let through to the remote server because the ordering of query parameters has changed. If we're using the above URL as an example, requests matching those exact query parameters will be served the local file, but requests with the URL https://domain.tld/path?param2=value2&param1=value1 will not. The only thing that has changed about this URL is the ordering of the parameters.

To handle both URLs where the ordering changes, I have to create a new mapping for each combination of parameters. This is problematic because it is a factorial problem. For however many parameters I have, I have to create n! mappings to handle all possible permutations of parameter ordering. This creates extra work on my end, as if I make a change to the response, I have to make the same change across multiple mappings.

Expected behavior

If I have mapping set up for the URL https://domain.tld/path?param1=value1&param2=value2, I would like for requests matching https://domain.tld/path?param1=value1&param2=value2 and https://domain.tld/path?param2=value2&param1=value1 to both match the mapping and be served the local content. However, I realize that this only works because the ordering of parameters does not affect the functionality. That these two URLs are functionally equivalent. However, this is not true of a URL with query parameters that, say, match to an array (for example, https://domain.tld/path?param[]=value1&param[]=value2). Changing the order of the parameters does change the meaning of the request (maybe these values indicate some kind of sorting method, where each value corresponds to a column on a database table, and the response will be sorted by the given values in the order they are given. In such a case, changing the order of the parameters does change the functionality of the endpoint).

I'm not sure how to resolve that part of it. Maybe Proxyman checks if there is an array query parameter and if it is assigned multiple values. If it detects that, then maybe it falls back to the old behavior, with some kind of message to indicate how Proxyman will behave? Maybe Proxyman needs an additional check box when creating the mapping for the user to indicate whether order matters, which, if it does not, then Proxyman would treat requests with different parameter orderings as the same requests. I could then have one mapping to handle all possible permutations of ordering of parameters.

Screenshots (optional)

Originally created by @grantjbutler on GitHub (May 28, 2020). Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/511 Originally assigned to: @NghiaTranUIT on GitHub. ### Proxyman version? (Ex. Proxyman 1.4.3) Version 1.23.0 (12300) ### macOS Version? (Ex. mac 10.14) macOS 10.15.4 (19E287) ### Steps to reproduce Set up mapping for a URL that has multiple query parameters in it (I've tested with local mapping, so I'm not sure if this applies to remote mapping, too). For example, a URL that looks something like `https://domain.tld/path?param1=value1&param2=value2`. With that mapping enable, sometimes requests are still let through to the remote server because the ordering of query parameters has changed. If we're using the above URL as an example, requests matching those exact query parameters will be served the local file, but requests with the URL `https://domain.tld/path?param2=value2&param1=value1` will not. The only thing that has changed about this URL is the ordering of the parameters. To handle both URLs where the ordering changes, I have to create a new mapping for each combination of parameters. This is problematic because it is a factorial problem. For however many parameters I have, I have to create `n!` mappings to handle all possible permutations of parameter ordering. This creates extra work on my end, as if I make a change to the response, I have to make the same change across multiple mappings. ### Expected behavior If I have mapping set up for the URL `https://domain.tld/path?param1=value1&param2=value2`, I would like for requests matching `https://domain.tld/path?param1=value1&param2=value2` and `https://domain.tld/path?param2=value2&param1=value1` to both match the mapping and be served the local content. However, I realize that this only works because the ordering of parameters does not affect the functionality. That these two URLs are functionally equivalent. However, this is not true of a URL with query parameters that, say, match to an array (for example, `https://domain.tld/path?param[]=value1&param[]=value2`). Changing the order of the parameters does change the meaning of the request (maybe these values indicate some kind of sorting method, where each value corresponds to a column on a database table, and the response will be sorted by the given values in the order they are given. In such a case, changing the order of the parameters does change the functionality of the endpoint). I'm not sure how to resolve that part of it. Maybe Proxyman checks if there is an array query parameter and if it is assigned multiple values. If it detects that, then maybe it falls back to the old behavior, with some kind of message to indicate how Proxyman will behave? Maybe Proxyman needs an additional check box when creating the mapping for the user to indicate whether order matters, which, if it does not, then Proxyman would treat requests with different parameter orderings as the same requests. I could then have one mapping to handle all possible permutations of ordering of parameters. ### Screenshots (optional)
Author
Owner

@NghiaTranUIT commented on GitHub (May 29, 2020):

Thanks for the detailed proposal. It totally makes sense that Proxyman should add a checkbox to determine if the Query Order should be evaluated when finding the matching rule.

I will consider and support it soon, after the Core V2 is out. For now, I would suggest duplicating the rule with a different param combination for the workaround as you described.

<!-- gh-comment-id:635747852 --> @NghiaTranUIT commented on GitHub (May 29, 2020): Thanks for the detailed proposal. It totally makes sense that Proxyman should add a checkbox to determine if the Query Order should be evaluated when finding the matching rule. I will consider and support it soon, after the [Core V2](https://github.com/ProxymanApp/Proxyman/issues/500) is out. For now, I would suggest duplicating the rule with a different param combination for the workaround as you described.
Author
Owner

@miguelrojascortes commented on GitHub (Sep 16, 2024):

Any updates on this proposal? It would be super helpful since mapping all the possible query parameter combinations is really annoying and time-consuming!

<!-- gh-comment-id:2353967256 --> @miguelrojascortes commented on GitHub (Sep 16, 2024): Any updates on this proposal? It would be super helpful since mapping all the possible query parameter combinations is really annoying and time-consuming!
Author
Owner

@NghiaTranUIT commented on GitHub (Sep 17, 2024):

@miguelrojascortes It's really simple to use the Scripting Tool.

Here is the code: Map with non-ordering Query, and map the Response Body with a local file, similar to the Map Local.

For example, the following will work with:

  1. Tools menu -> Scripting
  2. Create new Script with URL = https://yourdomain.com/*, select Method = ANY, and check on the "Include all subpath"
  3. Use this JS code
async function onResponse(context, url, request, response) {
  // console.log(response);

  const queries = request.queries;
  const {
    param1,
    param2,
    param3
  } = queries;

  // define your condition to match
  if (param1 == "value1" && param2 == "value2" && param3 == "value3") {
    // Map with a local file
    response.headers["Content-Type"] = "application/json"
    response.bodyFilePath = "~/Desktop/file.json"
  }

  // Done
  return response;
}

You can write your own If-else logic to match your URL 👍

Screenshots

Proxyman with Scripting tool

Proxyman maps with a non-ordering query

<!-- gh-comment-id:2354317046 --> @NghiaTranUIT commented on GitHub (Sep 17, 2024): @miguelrojascortes It's really simple to use the Scripting Tool. Here is the code: Map with non-ordering Query, and map the Response Body with a local file, similar to the Map Local. For example, the following will work with: - https://domain.tld/path?param1=value1&param2=value2&param3=value3 - https://domain.tld/path?param2=value2&param1=value1&param3=value3 - https://domain.tld/path?param3=value3&param1=value1&param2=value2 - ... (The query order doesn't matter) 1. Tools menu -> Scripting 2. Create new Script with URL = `https://yourdomain.com/*`, select Method = ANY, and check on the "Include all subpath" 3. Use this JS code ```js async function onResponse(context, url, request, response) { // console.log(response); const queries = request.queries; const { param1, param2, param3 } = queries; // define your condition to match if (param1 == "value1" && param2 == "value2" && param3 == "value3") { // Map with a local file response.headers["Content-Type"] = "application/json" response.bodyFilePath = "~/Desktop/file.json" } // Done return response; } ``` You can write your own If-else logic to match your URL 👍 ### Screenshots ![Proxyman with Scripting tool](https://github.com/user-attachments/assets/e9532324-ae49-48e7-aed4-7b6b766ecb39) ![Proxyman maps with a non-ordering query](https://github.com/user-attachments/assets/547f0ede-35cf-4dd4-8508-e23b02b09b78)
Author
Owner

@NghiaTranUIT commented on GitHub (Sep 17, 2024):

You can find a list of snippet code at https://docs.proxyman.io/scripting/snippet-code

It's super useful 👍

<!-- gh-comment-id:2354317552 --> @NghiaTranUIT commented on GitHub (Sep 17, 2024): You can find a list of snippet code at https://docs.proxyman.io/scripting/snippet-code It's super useful 👍
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/Proxyman#507
No description provided.