[GH-ISSUE #1612] Scripting changes + to %2B in request body #1604

Closed
opened 2026-03-03 19:52:50 +03:00 by kerem · 6 comments
Owner

Originally created by @Liu-huaicheng on GitHub (Apr 25, 2023).
Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/1612

Originally assigned to: @NghiaTranUIT on GitHub.

Description

When using a script like the following :

// Addons List: https://docs.proxyman.io/scripting/addons
const {
  sayHello
} = require("@addons/HelloWorld.js");

/// This func is called if the Request Checkbox is Enabled. You can modify the Request Data here before the request hits to the server
/// e.g. Add/Update/Remove: host, scheme, port, path, headers, queries, comment, color and body (json, form, plain-text, base64 encoded string)
///
/// Action Menu -> Import File to import a JSON file and use in the script. Or Import directly with request.bodyFilePath = "~/Desktop/myfile.json" (Applied for Response too)
/// Use global object `sharedState` to share data between Requests/Response from different scripts (e.g. sharedState.data = "My-Data")
///
async function onRequest(context, url, request) {
  // console.log(request);
  console.log(url);

  // Update or Add new headers
  // request.headers["X-New-Headers"] = "My-Value";

  // Update or Add new queries
  // request.queries["name"] = "Proxyman";

  // Body
  // var body = request.body;
  // body["new-key"] = "new-value"
  // request.body = body;

  // Done
  return request;
}

/// This func is called if the Response Checkbox is Enabled. You can modify the Response Data here before it goes to the client
/// e.g. Add/Update/Remove: headers, statusCode, comment, color and body (json, plain-text, base64 encoded string)
///
async function onResponse(context, url, request, response) {
  // console.log(response);

  // Update or Add new headers

  response.headers["set-cookie"] = removeDomainFromSid(response.headers["set-cookie"]);


  // Update status Code
  // response.statusCode = 500;

  // Update Body
  // var body = response.body;
  // body["new-key"] = "Proxyman";
  // response.body = body;

  // Or map a local file as a body
  // response.bodyFilePath = "~/Desktop/myfile.json"

  // Done
  return response;
}

If the original request body contains "+" characters, they will be interpreted as "%2B" characters on the server.

image image

Steps to Reproduce

  1. Make a request which content type is application/x-www-form-urlencoded; charset=UTF-8 and its body contains +
  2. Make a script which will handle the request

Current Behavior

+ chars are changed to %2B

Expected Behavior

+ chars should be preserved.

Environment

  • App version: Proxyman 4.6.1 (46010)
  • macOS version: macOS 13.3.1 (22E261)
Originally created by @Liu-huaicheng on GitHub (Apr 25, 2023). Original GitHub issue: https://github.com/ProxymanApp/Proxyman/issues/1612 Originally assigned to: @NghiaTranUIT on GitHub. ## Description When using a script like the following : ```js // Addons List: https://docs.proxyman.io/scripting/addons const { sayHello } = require("@addons/HelloWorld.js"); /// This func is called if the Request Checkbox is Enabled. You can modify the Request Data here before the request hits to the server /// e.g. Add/Update/Remove: host, scheme, port, path, headers, queries, comment, color and body (json, form, plain-text, base64 encoded string) /// /// Action Menu -> Import File to import a JSON file and use in the script. Or Import directly with request.bodyFilePath = "~/Desktop/myfile.json" (Applied for Response too) /// Use global object `sharedState` to share data between Requests/Response from different scripts (e.g. sharedState.data = "My-Data") /// async function onRequest(context, url, request) { // console.log(request); console.log(url); // Update or Add new headers // request.headers["X-New-Headers"] = "My-Value"; // Update or Add new queries // request.queries["name"] = "Proxyman"; // Body // var body = request.body; // body["new-key"] = "new-value" // request.body = body; // Done return request; } /// This func is called if the Response Checkbox is Enabled. You can modify the Response Data here before it goes to the client /// e.g. Add/Update/Remove: headers, statusCode, comment, color and body (json, plain-text, base64 encoded string) /// async function onResponse(context, url, request, response) { // console.log(response); // Update or Add new headers response.headers["set-cookie"] = removeDomainFromSid(response.headers["set-cookie"]); // Update status Code // response.statusCode = 500; // Update Body // var body = response.body; // body["new-key"] = "Proxyman"; // response.body = body; // Or map a local file as a body // response.bodyFilePath = "~/Desktop/myfile.json" // Done return response; } ``` If the original request body contains "+" characters, they will be interpreted as "%2B" characters on the server. <img width="1024" alt="image" src="https://user-images.githubusercontent.com/57707288/234332154-d5d5fdbe-109b-4b7b-87ea-0e718f242180.png"> <img width="766" alt="image" src="https://user-images.githubusercontent.com/57707288/234193341-24279ba6-9613-4aee-bab5-01d366e31faa.png"> ## Steps to Reproduce <!-- Add relevant code and/or a live example --> 1. Make a request which content type is `application/x-www-form-urlencoded; charset=UTF-8` and its body contains `+` 2. Make a script which will handle the request ## Current Behavior `+` chars are changed to `%2B` ## Expected Behavior `+` chars should be preserved. ## Environment - App version: Proxyman 4.6.1 (46010) - macOS version: macOS 13.3.1 (22E261)
kerem 2026-03-03 19:52:50 +03:00
Author
Owner

@NghiaTranUIT commented on GitHub (Apr 25, 2023):

It automatically decodes the + character to %2B. It should not do it. Let me check 👍

<!-- gh-comment-id:1521291174 --> @NghiaTranUIT commented on GitHub (Apr 25, 2023): It automatically decodes the `+` character to %2B. It should not do it. Let me check 👍
Author
Owner

@NghiaTranUIT commented on GitHub (Apr 25, 2023):

@Liu-huaicheng from what I'm investigating: It looks like it's a UI Bug (In the body tab). The Script doesn't change your form body, it preserves how it's.

Here is how I Test:

  1. Make 2 cURL requests
curl 'https://httpbin.org/post?action=form' \
-X POST \
-H 'User-Agent: PostmanRuntime/7.32.2' \
-H 'Accept: */*' \
-H 'Cache-Control: no-cache' \
-H 'Postman-Token: a3d50781-1bcf-492d-aebe-0abb3dc461cc' \
-H 'Host: httpbin.org' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-raw 'sku=1231231313&title=new+product&name=proxyman%20LLC' \
--proxy http://localhost:9090
  • One with no script and one with the script.
  • The diff tool shows that the httpbin.org backend receives the same Request Body.

CleanShot 2023-04-25 at 15 11 48@2x


@Liu-huaicheng Does it change your Response after running the Script?

<!-- gh-comment-id:1521362882 --> @NghiaTranUIT commented on GitHub (Apr 25, 2023): @Liu-huaicheng from what I'm investigating: It looks like it's a UI Bug (In the body tab). The Script doesn't change your form body, it preserves how it's. Here is how I Test: 1. Make 2 cURL requests ``` curl 'https://httpbin.org/post?action=form' \ -X POST \ -H 'User-Agent: PostmanRuntime/7.32.2' \ -H 'Accept: */*' \ -H 'Cache-Control: no-cache' \ -H 'Postman-Token: a3d50781-1bcf-492d-aebe-0abb3dc461cc' \ -H 'Host: httpbin.org' \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-raw 'sku=1231231313&title=new+product&name=proxyman%20LLC' \ --proxy http://localhost:9090 ``` - One with no script and one with the script. - The diff tool shows that the httpbin.org backend receives the same Request Body. ![CleanShot 2023-04-25 at 15 11 48@2x](https://user-images.githubusercontent.com/5878421/234215867-efdc67f0-39c7-4368-b11a-14606bf364b6.jpg) -------------------- @Liu-huaicheng Does it change your Response after running the Script?
Author
Owner

@Liu-huaicheng commented on GitHub (Apr 25, 2023):

Hi @NghiaTranUIT I just did the further investigation. I don't think it is a UI bug, if the origin request body contains + then it will be encoded to %2B with scripting in Proxyman. (Sorry, I described a bit wrong at first)
Here is my reproduce steps:

  1. Make 2 curl request(one is with scripting, another is without scripting):
curl 'https://httpbin.org/post?action=form' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Pragma: no-cache' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "macOS"' \
  --data-raw 'sku=12345678990&title=Product+name+with+blank+space' \
  --proxy http://localhost:9090
  1. there request bodies are showing different in diff tool
    image
    image
<!-- gh-comment-id:1522016640 --> @Liu-huaicheng commented on GitHub (Apr 25, 2023): Hi @NghiaTranUIT I just did the further investigation. I don't think it is a UI bug, if the origin request body contains `+` then it will be encoded to `%2B` with scripting in Proxyman. (Sorry, I described a bit wrong at first) Here is my reproduce steps: 1. Make 2 curl request(one is with scripting, another is without scripting): ```bash curl 'https://httpbin.org/post?action=form' \ -H 'Accept: */*' \ -H 'Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7' \ -H 'Cache-Control: no-cache' \ -H 'Connection: keep-alive' \ -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \ -H 'Pragma: no-cache' \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' \ -H 'X-Requested-With: XMLHttpRequest' \ -H 'sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"' \ -H 'sec-ch-ua-mobile: ?0' \ -H 'sec-ch-ua-platform: "macOS"' \ --data-raw 'sku=12345678990&title=Product+name+with+blank+space' \ --proxy http://localhost:9090 ``` 2. there request bodies are showing different in diff tool <img width="1152" alt="image" src="https://user-images.githubusercontent.com/57707288/234328876-14e6cbc7-cf06-48ce-b1d8-1aeb30fe4283.png"> <img width="1152" alt="image" src="https://user-images.githubusercontent.com/57707288/234329077-b361eb74-1303-4b58-b5ee-4971d8d13663.png">
Author
Owner

@NghiaTranUIT commented on GitHub (Apr 25, 2023):

@Liu-huaicheng can you try this Beta build: https://download.proxyman.io/beta/Proxyman_4.6.1_Fix_scripting_with_form_body_encoding.dmg

It doesn't escape the + char in the form body 👍

<!-- gh-comment-id:1522093844 --> @NghiaTranUIT commented on GitHub (Apr 25, 2023): @Liu-huaicheng can you try this Beta build: https://download.proxyman.io/beta/Proxyman_4.6.1_Fix_scripting_with_form_body_encoding.dmg It doesn't escape the `+` char in the form body 👍
Author
Owner

@Liu-huaicheng commented on GitHub (Apr 26, 2023):

@NghiaTranUIT Fixed in that package 👍

<!-- gh-comment-id:1522846793 --> @Liu-huaicheng commented on GitHub (Apr 26, 2023): @NghiaTranUIT Fixed in that package 👍
Author
Owner

@NghiaTranUIT commented on GitHub (Apr 26, 2023):

Awesome, we will release this fix on the next update 👍

<!-- gh-comment-id:1522868094 --> @NghiaTranUIT commented on GitHub (Apr 26, 2023): Awesome, we will release this fix on the next update 👍
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#1604
No description provided.