VirtuProbe Studio
Get the app
← All posts
Walkthrough 30 June 2026 7 min read

Chaining requests, across protocols.

Most real tests aren't one request — they're a sequence where each step depends on the last: log in, take the token, call the authenticated endpoint, check the result. VirtuProbe models that as a chain, and it doesn't much care whether the next step is HTTP, DNS, SMTP or LDAP. Here's exactly how a value gets from one step to the next.

The whole idea: extract → variable → resolve

A chain is an ordered list of steps. You attach an extractor to a step; it pulls a value out of that step's response into a named variable; and any later step references it as {{variable}}. That one loop is the entire mechanism — everything else is convenience on top of it.

# Log in, keep the token, call an authenticated endpoint

01  HTTP  POST /login  {"user":"x","pass":"y"}
          extract  HTTP_JSON_PATH  $.token            → {{token}}
          assert   HTTP_STATUS     EQUALS 200

02  HTTP  GET /me   Authorization: Bearer {{token}}
          assert   HTTP_STATUS     EQUALS 200

Pulling the value out: extractors

Every protocol ships its own extractors, and two generic ones work on any response:

  • HTTPHTTP_STATUS, HTTP_JSON_PATH, HTTP_HEADER, HTTP_BODY_RAW.
  • DNSDNS_ANSWER_VALUE (and DNS_SUCCESS).
  • SMTP / IMAP / LDAP — a *_SUCCESS flag plus an exchange reader (SMTP_EXCHANGE_LINES, IMAP_EXCHANGE_LINES, LDAP_EXCHANGE_RESULT_CODE).
  • GenericCONSTANT (a fixed value) and REGEX (the first capture group of a pattern over the raw response). REGEX is the escape hatch — it's how you lift a link out of an email body or an id out of plain text when there's no purpose-built extractor.

Injecting it back: {{variables}}

A resolved variable drops in anywhere in the following steps — a URL, a request body, a header, an LDAP DN or filter, a DNS name. One small piece of honesty the tool enforces for you: a single brace like {token} is almost always a typo, so VirtuProbe stops with a clear error rather than sending the literal text and letting you wonder why the request 401'd.

When it isn't a straight line: control flow

Steps aren't only protocol calls. A handful of control-flow steps handle the shapes real tests take:

  • ITERATE — run child steps once per item from an inline list or a file, with optional jitter between iterations and stop-on-first-success.
  • CONDITION — branch on a Groovy expression over your variables ({{status}} == '200').
  • ASSERT — gate the run: EQUALS, NOT_EQUALS, CONTAINS, NOT_CONTAINS, MATCHES, GT/LT/GTE/LTE.
  • PARALLEL — fan steps out; each branch gets a snapshot of the variables, merged back last-writer-wins.
  • CHAIN_REF — call another chain with explicit input/output variable mapping.
  • PRINT — render a line into the run log for readability.

The part that's actually different: protocols mix freely

Because a step is just a step, you can cross protocols mid-chain — which is where this stops being a nicer HTTP runner and starts being the point. Resolve a domain's MX over DNS, hand the hostname to an SMTP step, deliver a message, and confirm it landed over IMAP — one runnable artefact. Or the signup case: register over HTTP, catch the mail over IMAP, bind the new account over LDAP.

What you keep afterwards

Runs are synchronous and saved — the last 20 per chain. Compare two runs to see exactly which step's response changed, and export any run as JSON evidence with no re-run and no re-auth. A chain isn't just a test you ran; it's one you can hand to someone else and have them run identically.

Build your first chain. VirtuProbe Studio is free to download — no account, no cloud, no telemetry. Chaining, environments and request history are all on the free tier.

Join our Discord