Skip to content

operation

In Whistle, each rule consists of two parts: Pattern (pattern) and Operation (operation). The general syntax for operation is:

txt
protocol://[value]
  • protocol: Specifies the operation type (such as file, proxy, resReplace, etc.)
  • value: Operation content (supports multiple formats, see below)

Inline Values

txt
pattern reqHeaders://x-proxy=Whistle   # Set request headers
pattern statusCode://404               # Modify status code
pattern file://({"ec":0})              # Respond with inline content (value inside parentheses: `{"ec":0}`)

When the operation content (Value) contains spaces, line breaks, or special characters, inline method cannot be used directly. Use the following alternative methods instead:

Embedded Values

txt
``` ua.txt
Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1
```
pattern ua://{ua.txt}

Equivalent to:

txt
``` headers.json
user-agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1
```
pattern reqHeaders://{headers.json}

Values References

When operation values (Value) need to be shared by multiple rules, embedding them directly in rules makes them non-reusable. In such cases, these values can be stored in the Values module of the Whistle interface and referenced by key name:

  1. Create a key named result.json in Values and fill in the operation content
  2. In rules, reference it via {result.json}, e.g.: www.test.com/cgi-bin/test file://{result.json}

File/Remote Resources

txt
pattern reqHeaders:///User/xxx/filepath             # Load operation content from local file
pattern resHeadrs://https://example.com/config.json # Load JSON object from remote URL
pattern resHeaders://temp/blank.json                # Through editing temporary files

⚠️ Note: Protocols like http/https/ws/wss/tunnel/host/enable/cache... prohibit obtaining content via file paths or remote URLs. See each protocol's documentation for details.

Temporary Files

When frequent content editing is needed, you can use Whistle's temporary file functionality.

txt
pattern protocol://temp.json

Operation Steps:

  1. In the Rules editor, hold Command (Mac) / Ctrl (Windows)
  2. Click with mouse on protocol://temp.json
  3. Enter the response content in the pop-up editing dialog
  4. Click Save to save

Parentheses Usage

In Whistle rules, the value part of protocol://value can have three types of indirect references:

  1. {key} - Reference embedded values
  2. remote-url - Remote resource address
  3. localfilepath - Local file path

When you need to directly reference the above content itself (rather than what they indirectly reference) as operation content, you can wrap it with parentheses:

txt
protocol://(value)

Examples:

  1. reqHeaders:///User/xxx/yyy.txt - Load operation content from local file /User/xxx/yyy.txt
  2. reqHeaders://(/User/xxx/yyy.txt) - Treat /User/xxx/yyy.txt directly as operation content

Template Strings

Whistle provides template string functionality similar to ES6, allowing you to dynamically reference request information and apply it to rule configurations. Supports the following template string types:

General Inline Values
txt
pattern protocol://`...${version}...`
Embedded Values or Values References
txt
``` test.key
...${reqId}...
...${version}...
```
pattern protocol://`{test.key}`
Parenthesized Content
txt
pattern protocol://`(...${now}...)`
String Variables
Variable NameValue
${now}Date.now()
${random}Math.random()
${randomUUID}crypto.randomUUID()
${randomInt(n)} or ${randomInt(n1-n2)}Get a random positive integer from [0, n] or [n1, n2] (Added in: v2.9.104)
${reqId}ID assigned by Whistle to each request
${url.protocol}url.parse(fullUrl).protocol
${url.hostname}url.parse(fullUrl).hostname
${url.host}url.parse(fullUrl).host
${url.port}url.parse(fullUrl).port
${url.path}url.parse(fullUrl).path
${url.pathname}url.parse(fullUrl).pathname
${url.search}url.parse(fullUrl).search
${query.xxx}Value of request parameter xxx
${url}Complete request URL
${querystring}url.parse(fullUrl).search || '?' (not empty)
${searchstring}url.parse(fullUrl).search || '?' (not empty)
${method}Request method
${reqHeaders.xxx}Value of request header field xxx
${resHeaders.xxx}Value of response header field xxx
${version}Whistle version number
${port}Whistle port number
${host}Network interface IP that Whistle listens on (empty by default)
${realPort}port displayed in Whistle interface's Online dialog (usually Whistle port number)
${realHost}host displayed in Whistle interface's Online dialog (usually the network interface IP that Whistle listens on)
${clientIp}Client IP
${clientPort}Client port
${serverIp}Server IP
${serverPort}Server port
${reqCookies.xxx}Value of request cookie xxx
${resCookies.xxx}Value of response cookie xxx
${statusCode}Response status code
${env.xxx}process.env.xxx
${whistle.plugin-name}value of whistle.plugin-name://value or plugin-name://value

${whistle.plugin-name} may only have values in internal rules of plugins

Example
txt
``` test.txt
now: ${now}
random: ${random}
randomUUID: ${randomUUID}
reqId: ${reqId}
url.protocol: ${url.protocol}
url.hostname: ${url.hostname}
url.host: ${url.host}
url.port: ${url.port}
url.path: ${url.path}
url.pathname: ${url.pathname}
url.search; ${url.search}
query: ${query.name}
url: ${url}
querystring: ${querystring}
searchstring: ${searchstring}
method: ${method}
reqHeaders.accept: ${reqHeaders.accept}
resHeaders.content-type: ${resHeaders.content-type}
version: ${version}
port: ${port}
host: ${host}
realPort: ${realPort}
realHost: ${realHost}
clientIp: ${clientIp}
clientPort: ${clientPort}
serverIp: ${serverIp}
serverPort: ${serverPort}
reqCookies.test: ${reqCookies.test}
resCookies.test: ${resCookies.test}
statusCode: ${statusCode}
env.USER: ${env.USER}
```

www.test.com/index.html file://`{test.txt}`

Accessing https://www.test.com/index.html?name=avenwu returns response content:

txt
now: 1752301623295
random: 0.6819241513880432
randomUUID: e917b9fc-e2ef-4255-9209-11eb417235c5
reqId: 1752301623294-339
url.protocol: https:
url.hostname: www.test.com
url.host: www.test.com
url.port: 
url.path: /index.html?name=avenwu
url.pathname: /index.html
url.search; ?name=avenwu
query: avenwu
url: https://www.test.com/index.html?name=avenwu
querystring: ?name=avenwu
searchstring: ?name=avenwu
method: GET
reqHeaders.accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
resHeaders.content-type: 
version: 2.9.100
port: 8899
host: 
realPort: 8899
realHost: 
clientIp: 127.0.0.1
clientPort: 60582
serverIp: 
serverPort: 
reqCookies.test: 
resCookies.test: 
statusCode: 
env.USER: av

Data Objects

Operation content can be not only text or binary content but also JSON objects. Whistle supports the following 3 data object formats:

JSON Format

js
{
  "key1": value1,
  "key2": value2,
  "keyN": valueN
}

Line Format

txt
key1: value1
key2:value2
keyN: valueN

Separated by colon + space. If there's no colon + space, then separated by the first colon. If there's no colon, then value is an empty string

Multi-level nesting:

txt
a.b.c: 123
c\.d\.e: abc

Equivalent to:

json
{
  "a": {
    "b": {
      "c": 123
    }
  },
  "c.d.e": "abc"
}

Inline Format (Request Parameter Format)

txt
key1=value1&key2=value2&keyN=valueN

Both key and value should ideally be encodeURIComponent

Quick Reference Manual for Common Operation Commands


1. Modifying Request Content

1.1 Modifying Request Method

txt
# Basic Syntax
pattern method://NewMethod

# Example
www.example.com/path method://post

Supported Data Sources:

  • Direct specification: method://get
  • Embedded value: method://{keyOfEmbedded}
  • Values configuration: method://{keyOfValues}

Notes:

  • Method names are case-insensitive.
  • Not supported from local files or remote URLs.

Practical Examples:

txt
# Example 1: Change all request methods to POST
www.example.com/path method://post

# Example 2: Change only PUT requests to POST
www.example.com/path method://post includeFilter://m:put

# Example 3: Modify method based on request body content
www.example.com/api method://put includeFilter://b:cmdname=test

1.2 Modifying Request URL

URL Mapping

txt
www.example.com/path/to www.test.com/test

Mapping Effect:

  • https://www.example.com/path/to?query=abchttps://www.test.com/test?query=abc
  • https://www.example.com/path/to/subpagehttps://www.test.com/test/subpage
  • wss://www.example.com/path/to/apiwss://www.test.com/test/api

Modifying Request Parameters

txt
# Add/Replace parameters
pattern urlParams://({"key":"value"})

# Delete parameter
pattern delete://urlParams.paramName

# Example: Modify parameters and delete a specific parameter
www.example.com/api urlParams://({"cmdname":"Test"}) delete://urlParams.oldParam

Modifying Path

txt
# Regular expression replacement
pattern pathReplace://({"/old/ig":"new"})

# Keyword replacement
pattern pathReplace://({"old":"new"})

Supported Data Sources:

  • Inline JSON
  • Embedded value
  • Values configuration
  • Local file
  • Remote URL

1.3 Modifying HTTP Version

txt
# Force using standard HTTPS (disable HTTP/2)
pattern disable://h2

By default, attempts to establish a connection using HTTP/2; automatically downgrades to HTTPS if not supported.

1.4 Modifying Request Headers

txt
# Add/Replace request header
pattern reqHeaders://({"Header-Name":"value"})

# Delete request header
pattern delete://reqHeaders.headerName

# Example
www.example.com reqHeaders://({"X-Custom-Header":"test"})

1.5 Modifying Request Body

Merge Modification (JSON/Form)

txt
pattern reqMerge://({"newField":"value"})

Text Replacement

txt
# Regular expression replacement
pattern reqReplace://({"/search/ig":"replace"})

# Keyword replacement
pattern reqReplace://({"search":"replace"})

Complete Replacement

txt
pattern reqBody://(NewContent)

Deletion Operations

txt
# Delete specific field
pattern delete://reqBody.fieldName

# Delete entire request body
pattern delete://reqBody

Supported Data Sources:

  • Inline value
  • Embedded value
  • Values configuration
  • Local file
  • Remote URL

2. Modifying Response Content

2.1 Modifying Status Code

txt
# Replace existing response status code (request reaches server)
pattern replaceStatus://500

# Respond directly with status code (request not sent to server)
pattern statusCode://500

2.2 Modifying Response Headers

txt
# Add/Replace response header
pattern resHeaders://({"Header-Name":"value"})

# Delete response header
pattern delete://resHeaders.headerName

2.3 Modifying Response Body

Merge Modification (JSON/JSONP)

txt
pattern resMerge://({"newData":"value"})

Text Replacement

txt
pattern resReplace://({"/old/ig":"new"})

Replace Response Body

txt
# Replace content returned by server
pattern resBody://(NewContent)

Respond Directly with Content

txt
# Request not sent to server
pattern file://(Content to return directly) resType://html

Deletion Operations

txt
# Delete response body field
pattern delete://resBody.fieldName

# Clear response body
pattern delete://resBody

2.4 Modifying Trailers

Trailers are additional header fields sent after the chunked transfer response.

txt
# Add/Replace Trailers
pattern trailers://({"Trailer-Name":"value"})

# Delete Trailers
pattern delete://trailers.trailerName

3. Modifying Connection Process

3.1 Modifying DNS

txt
# Set IP address
pattern 127.0.0.1

# Set IP and port
pattern 127.0.0.1:8080

# CNAME effect (pointing to another host)
pattern host://www.target.com:8080

3.2 Setting Proxy

txt
# HTTP proxy
pattern proxy://127.0.0.1:8080

# SOCKS5 proxy
pattern socks://127.0.0.1:1080

# Supports domain name
pattern proxy://proxy.example.com:8080

3.3 Proxy and DNS Taking Effect Simultaneously

Priority Description:

  • Default: Host configuration takes precedence over proxy.
  • Adjustable: Use lineProps://proxyHost to make both take effect simultaneously.
txt
# Example 1: Only host configuration takes effect
pattern 127.0.0.1:8080 socks://10.1.1.1:1080

# Example 2: Only proxy configuration takes effect
pattern 127.0.0.1:8080 socks://10.1.1.1:1080 ignore://host

# Example 3: Both host and proxy take effect
pattern 127.0.0.1:8080 socks://10.1.1.1:1080 lineProps://proxyHost

4. Page Debugging Tools

4.1 Viewing Page DOM Structure

txt
pattern weinre://DebugSessionName

Detailed usage reference: weinre documentation

4.2 Viewing Page Logs and Error Information

txt
pattern log://LogSessionName

Detailed usage reference: log documentation


Data Source Quick Reference Table

Operation TypeDirect InlineEmbedded ValueValuesLocal FileRemote URL
Request Method
URL Parameters
Request Headers
Request Body
Response Headers
Response Body
Trailers

Syntax Examples:

txt
# Direct inline
protocol://({"key":"value"})

# Embedded value
protocol://{embeddedKey}

# Values configuration
protocol://{valuesKey}

# Local file
protocol:///path/to/file.json

# Remote URL
protocol://https://example.com/data.json

Common Filter Conditions

FilterDescriptionExample
includeFilter://m:MethodFilter by request methodincludeFilter://m:put
includeFilter://b:ContentFilter by request body contentincludeFilter://b:cmdname=test
Regular ExpressionCase-sensitive matching/Test/

Tip: For more protocols and advanced usage, refer to the Complete Protocol List.