HttpRequest Configuration
The HttpRequest configuration specifies the details of each HTTP interaction with options for capturing responses, using payloads, and applying headers.
Key Attributes
- URL: The endpoint to which the request is sent.
- HTTP Method: Defines the type of request (e.g., GET, POST, PUT).
- Headers: Key-value pairs included in the request.
- Payload: Data sent with the request (e.g., JSON body).
- skipIf: Optional condition to skip this HTTP request only.
- before: Optional list of expressions that run first (before the request's
skipIfis checked and its URL/headers are built), so any variable they store — typically via$find(..., variable=x)— is ready for this same request to use. - after: Optional list of expressions that run after the request completes and its response is captured, so they can read the response and store data for later steps.
- Retry: Optional retry policy with conditional retry/stop expressions and fixed or exponential delays.
- Version: HTTP version (e.g., 1.1, 2.0).
- Client Certificate Path: Path to a client certificate file for mutual TLS (mTLS) authentication. Supported formats:
.pfx,.p12,.pem,.cer,.crt. - Client Certificate Password: Password for the certificate file (if password-protected).
httpRequest:
url: https://api.example.com/resource
httpMethod: POST
headers:
Content-Type: application/json
payload:
type: Raw
raw: '{"key": "value"}'
httpVersion: 2.0
clientCertificatePath: .\mycert.pfx
clientCertificatePassword: optional-password
Transport Options
supportH2C: Enable HTTP/2 cleartext when backend supports it.downloadHtmlEmbeddedResources: Auto-download page sub-resources (images/css/js) for page-load realism.
Other Options
saveResponse: Saves the response to the disk. Do not use unless you really need it. This may have serious impact on the load test performance.
skipIf at HttpRequest Level
httpRequest.skipIf skips only the HTTP request block when its expression evaluates to true. This is useful when the iteration should still exist in the flow, but the outbound request should be conditionally suppressed.
iterations:
- name: userDetails
httpRequest:
skipIf: ${users.Body[$length($users.Body)-1].id} = 10
httpMethod: Get
url: https://httpbin.org/
Typical use cases:
- Avoid a follow-up request when a captured response already shows the terminal condition.
- Skip calls based on a previous status code or response body value.
- Combine capture, declarative methods, and arithmetic path expressions in one condition.
before at HttpRequest Level
httpRequest.before is a list of setup expressions that run first — before the request's skipIf is checked and before its URL, headers, and payload are built. Each expression runs in order and is used for its side effect: it stores a variable (typically via $find(..., variable=x)) and its return value is ignored.
Because before runs first, the variables it produces are immediately available to the same request. This is what lets a request look something up and then use it in its own skipIf, URL, or headers — which is otherwise impossible, since those are all computed at send time.
Order of evaluation for one request:
- run each
beforeexpression (e.g. storeuserId) - evaluate
skipIf(can now read${userId}) - build the URL and headers (can now read
${userId}) - send the request
iterations:
- name: getAlbums
httpRequest:
before:
# 1) look up the id first and store it in `userId`
- '$find(source=$users.Body, where=item.username == "Bret", select=item.id, match=first, variable=userId)'
# 2) now the URL can use it
url: 'https://jsonplaceholder.typicode.com/users/${userId}/albums'
method: GET
before is also available at the iteration level (runs once when the iteration starts, before the iteration's skipIf). See the Before Expressions article.
after at HttpRequest Level
httpRequest.after is a list of expressions that run after the request has completed and its response has been captured. Each expression runs in order and is used for its side effect: it stores a variable (typically via $find(..., variable=x) or a declarative method with variable=) and its return value is ignored.
Because after runs after the response is received and captured, it can read the response and prepare data for the next iteration/request — the mirror image of before.
When it runs: after the request finishes (including its retries). It runs on both success and failure, but not when skipIf skipped the request, and not on cancellation.
iterations:
- name: getUser
httpRequest:
capture:
to: user
as: Json
makeGlobal: true
url: https://jsonplaceholder.typicode.com/users/1
method: GET
after:
# post-process the captured response and store a value for later
- '$setvariable(variable=userCity, value=${user.Body.address.city})'
after is also available at the iteration level (runs once when the iteration completes). See the before & after Expressions article.
Retry
httpRequest.retry retries the same request when retry.if evaluates to true. This is useful for transient failures such as 5xx responses, rate limits, or temporary upstream errors.
httpRequest:
capture:
to: LastResponse
as: Json
makeGlobal: false
url: https://httpbin.org/status/500
method: GET
retry:
if: ${LastResponse.StatusCode} >= 500
stopIf: ${LastResponse.StatusCode} = 400
maxRetries: 5
delayInMs: 1000
strategy: Exponential
maxDelayInMs: 11000
Retry fields
if: Optional boolean expression evaluated after each attempt. When it evaluates totrue, LPS schedules another attempt while retries remain. When omitted,ifdefaults totrue— the request retries unconditionally (still bounded bystopIfandmaxRetries).stopIf: Optional boolean expression evaluated beforeretry.if. If it evaluates totrue, retries stop immediately.maxRetries: Maximum number of retry attempts after the initial request. Use0to disable retry while keeping the block present.delayInMs: Base delay between retries in milliseconds.strategy: Delay strategy. Supported values areFixedandExponential.maxDelayInMs: Optional cap for exponential backoff. Omit it whenstrategy: Fixed.
Retry behavior
retry.ifandretry.stopIfuse the same Flee expression support asskipIf.retry.ifis optional; when omitted it defaults totrue, so the request retries unconditionally (subject tostopIfandmaxRetries).stopIfis checked first on each cycle. If it istrue, no more retries are attempted.- With
strategy: Fixed, every retry waits exactlydelayInMs. - With
strategy: Exponential, delay grows asdelayInMs * 2^(attempt-1)and is capped bymaxDelayInMswhen provided. - Capturing the response is the typical way to drive retry decisions, for example
${LastResponse.StatusCode} >= 500.
Validation rules
maxRetriesmust be explicitly provided and be greater than or equal to0.delayInMsmust be explicitly provided and be greater than0.strategymust be eitherFixedorExponential.- For
Fixed, omitmaxDelayInMs. - For
Exponential,maxDelayInMsis optional, but when provided it must be greater than or equal todelayInMs. retry.ifis optional (defaults totrue);retry.stopIfis optional too.- When both are provided,
retry.ifandretry.stopIfmust not be the same expression.
Common patterns
Retry server errors with exponential backoff:
retry:
if: ${LastResponse.StatusCode} >= 500
maxRetries: 5
delayInMs: 1000
strategy: Exponential
maxDelayInMs: 11000
Retry with a fixed delay:
retry:
if: ${LastResponse.StatusCode} = 429
maxRetries: 3
delayInMs: 500
strategy: Fixed
Response Capture
Capture responses to variables for later usage:
httpRequest:
capture:
to: VariableName
as: Json|QJson|String|QString|Xml|QXml|Csv|QCsv|Int|Double|Boolean
regex: "optional-regex"
makeGlobal: false
to: VariableName stores a session variable with .StatusCode, .StatusReason, .Headers.<Name>[i], .Body (supports JSONPath via ${VariableName.Body.field}).
Capture Details
The capture: property stores the full HTTP response into a built-in response variable type. The variable exposes:
- Body — the default value; typed by
as:(e.g.,Json,QJson,Xml,QXml,Csv,QCsv,String,QString). - StatusCode — numeric HTTP status code.
- StatusReason — HTTP reason phrase.
- Headers — header values; case-insensitive lookup; multiple values supported via index
[i].
Scope: Captured variables are session-scoped by default. Set makeGlobal: true to publish globally.
name: WebFlow
rounds:
- name: Auth
iterations:
- name: Login
httpRequest:
url: https://api.example.com/login
method: POST
payload:
type: Json
value: '{"user":"${U}","pass":"${P}"}'
capture:
to: LoginResponse
as: Json
makeGlobal: false
Access Patterns
- Body (typed):
${LoginResponse.Body}; JSON:${LoginResponse.Body.token}; XML:${LoginResponse.Body.Root.Element}; CSV:${LoginResponse.Body[0,2]} - Status/Reason:
${LoginResponse.StatusCode},${LoginResponse.StatusReason} - Headers:
${LoginResponse.Headers.Content-Type},${LoginResponse.Headers.Set-Cookie[0]}
Arithmetic Expressions in Captured Values
Captured JSON, XML, and CSV values support arithmetic expressions in index positions:
- JSON:
${UsersResponse.Body[0+1].id} - JSON with method call:
${UsersResponse.Body[$length($UsersResponse.Body)-1].id} - XML:
${CatalogResponse.Body/items/item[1+1]/name} - CSV:
${CsvUsers.Body[0+1,1]}
Notes:
- JSON and CSV indexes are zero-based.
- XML uses XPath semantics, so repeated element positions are one-based.
- Non-arithmetic selectors such as
['name'],[*], and XPath attribute predicates are preserved as-is.
Typical skipIf Usage
skipIf: ${LoginResponse.StatusCode} == 401
skipIf: ${LoginResponse.Body.token} == ""
Client Certificate Authentication (Mutual TLS)
Use clientCertificatePath and clientCertificatePassword to authenticate with servers that require client certificates.
Supported certificate formats:
.pfx/.p12— PKCS#12 format (may require password).pem/.cer/.crt— Base64-encoded certificate
YAML Example (Basic)
httpRequest:
url: https://secure-api.example.com/resource
method: GET
httpVersion: 2.0
clientCertificatePath: ./certs/client.pfx
clientCertificatePassword: mysecretpassword
YAML Example (Using Environment Variable)
Use the $read() method to securely read the password from an environment variable:
name: SecureAPITest
variables:
- name: certPassword
value: $read(source: env, name: CERT_PASSWORD)
rounds:
- name: TestRound
numberOfClients: 1
iterations:
- name: SecureRequest
httpRequest:
url: https://secure-api.example.com/resource
method: GET
clientCertificatePath: ./certs/client.pfx
clientCertificatePassword: $certPassword
mode: R
requestCount: 1
CLI Example
lps --url https://secure-api.example.com/resource --clientcertificatepath ./certs/client.pfx --clientcertificatepassword mysecretpassword
CLI Options:
| Option | Alias | Description |
|---|---|---|
--clientcertificatepath | -ccp | Path to the client certificate file |
--clientcertificatepassword | -ccpw | Password for PFX/P12 certificate files |
Notes:
- Path can be absolute or relative to the working directory
- Password supports variable placeholders (e.g.,
$certPassword) - Use
$read(source: env, name: VAR_NAME)to read sensitive values from environment variables - Certificate is loaded per-request, enabling different certificates for different endpoints
- For
.pem,.cer,.crtfiles, password is typically not required
Label: HttpRequest retry features (retry.if, retry.stopIf, maxRetries, delayInMs, strategy, maxDelayInMs) are currently available in lps.3.0.5.2-Preview.