Skip to content

HTTP ​

The HTTP screen is a request inspector and a load tool in one:

  • send a single request and see the status, the time it took, the headers and the body;
  • authenticate with Basic, a Bearer token or Digest;
  • keep the cookies a server sets, as a browser does;
  • send the same request many times at once — a Load burst — and read the throughput and the latency percentiles.

Sending a request ​

  1. Open HTTP.
  2. Choose the method and type the URL, for example http://127.0.0.1:8080/health.
  3. Add Headers if the server needs them; + header adds a row, ✕ removes one. A row without a name is not sent.
  4. For a method other than GET and HEAD, write the Body. The text stays in the field while you switch to GET or HEAD and comes back with the other method, but is not sent meanwhile.
  5. Press Send.

The line under the buttons gives the verdict at once — status, time and size, or why there was no response — and the Response panel shows the rest. The request (method, URL, headers, body, timeout and Keep cookies) is kept when you switch screens and when you restart the app; credentials are not.

KeyWhereDoes
Enterthe URL, a header, a credential, the timeoutsends
Ctrl+Enterany field of the request, the body includedsends
Ctrl+Sany field of the requestsaves it as a signal (below)

Request fields ​

FieldWhatDefault
MethodGET, POST, PUT, PATCH, DELETE, HEAD or OPTIONSGET
URLAn http:// or https:// URLhttp://127.0.0.1:8080/
HeadersName and value pairs, sent as written. Without a User-Agent of your own, Signal Lab sends SignalLab/0.1.Accept: application/json
AuthenticationHow the request authenticates (below)None
Keep cookiesSend back the cookies servers set (below)on
BodySent exactly as written; no Content-Type is added, so add the header that matches. An empty body is not sent. The field is not shown for GET and HEAD, and then the request carries no body at all — not in the send, not in a saved signal, not in Add to experiment — even if you typed one under another method.empty
Timeout (ms)How long the whole exchange may take, answer and body included10 000

Authentication ​

AuthenticationFieldsWhat is sent
None—no Authorization header
BasicUser name, PasswordAuthorization: Basic …, the name and password in base64, with the first request
Bearer tokenTokenAuthorization: Bearer <token>
DigestUser name, Passwordnothing at first; the answer to the server's challenge (below)

Switching between Basic and Digest keeps the name and password.

Digest ​

With Digest, Signal Lab sends the request without credentials. When the server answers 401 with a Digest challenge, Signal Lab works out the answer from the challenge and your password and sends the request again. The response you see is the one to that second request, marked Digest: challenge answered, and the latency counts both exchanges — what a client waits.

  • Algorithms: MD5 and SHA-256, and their -sess variants. When a server offers both, SHA-256 is used.
  • Quality of protection: auth and auth-int, and the older answer without qop.
  • When the server says the nonce ran out (stale), or asks again with a new one, the request is answered again, up to 3 more times. When it refuses the answer to the nonce it gave last, the 401 stands: the name or the password is wrong.
  • Redirects are followed by Signal Lab itself, so the URL that asks is the one answered. A challenge from another origin is not answered: credentials typed for one host go to no other. Moving from http:// to https:// on the same host and default ports counts as the same host.

When the challenge cannot be answered, the 401 stands and the panel says why:

MessageMeaning
The server answered 401 without asking for DigestThe server wants another scheme; try Basic or Bearer.
The server asked for Digest with …An algorithm Signal Lab does not speak; it speaks MD5 and SHA-256.
The server asked for Digest without a realm or nonceThe server's challenge is incomplete.
The request was sent on to …, which asked for DigestA redirect led to another origin, whose challenge is not answered.

Where the credentials go ​

Credentials go only into the request's Authorization header as it is sent. The Inspector, the console and experiment reports never show that header. On this screen they are kept in memory only and are gone after a restart — unless the request is tied to a saved signal, which brings them back.

WARNING

A request saved as a signal keeps its credentials in the library file, signals.json, as plain text. In an experiment, write a password as {{secret.NAME}} instead; see Data and templates.

Cookies ​

With Keep cookies on, what a server sets with Set-Cookie is kept in the screen's cookie jar and sent back with later requests to that server, following the browser rules (domain, path, Secure, expiry). The jar is used by this screen's requests, its burst and the HTTP signals you fire from the library. Turn it off to send requests with no cookies and keep none.

The cookies panel under the request and the response lists what the jar holds: Name, Value, Domain and path (a domain starting with . also covers its subdomains), Expires (with the session for a cookie with no expiry) and Flags (Secure, HttpOnly, SameSite). Expired cookies are not listed. Clear empties the jar.

The jar lives as long as the app: a restart starts with an empty one. On a server, there is one jar for every page signed in to it. An experiment run has a jar of its own (see Experiments), and signallab send http uses none.

The response ​

PartWhat
StatusThe status code and its reason; ERR when no response came
LatencyFrom sending to the last byte of the body, in milliseconds
SizeThe size of the body
Response headersClick the line with their count to show or hide them
BodyFormatted when it is JSON; Show raw and Format JSON switch. Up to 256 KiB is shown, then … (truncated).

When there is no response, the panel says why, in the same words as everywhere in Signal Lab: refused, no answer in time, the name does not resolve, a certificate problem and so on. The technical detail from the system is folded under it.

Redirects ​

Redirects (301, 302, 303, 307, 308) are followed, up to 10; the response shown is the last one. After 301, 302 and 303 the request goes on as GET without a body (HEAD stays HEAD); after 307 and 308 as it was. Authorization and cookies typed for one host are not sent on to another.

Secure connections ​

An https:// server's certificate is checked against the certificates this system trusts. A self-signed or expired certificate is refused with "A secure connection to … could not be made"; there is no setting to skip the check. To test a server with your own certificate, add it to the system's trusted certificates.

Load burst ​

The Load burst sends the request on screen — with its authentication and, while Keep cookies is on, the cookie jar — many times, and measures it.

  1. Set Concurrency, Total, Duration, s and Rate, req/s.
  2. Press Start burst. The burst is a job: Stop burst, or stopping it in the console strip, ends it.
FieldWhatDefault
ConcurrencyRequests in flight at once, 1–51220
TotalRequests to send; 0 — keep sending until the duration ends500
Duration, sSeconds to run; 0 — stop when the total is sent0
Rate, req/sRequests started per second, 0.1–100 000; 0 — as fast as the workers go0

With both Total and Duration, s at 0, the burst runs until you stop it.

There are two ways to send:

  • Rate, req/s 0. Each of the workers sends again as soon as it has an answer. This finds how much the server takes, but a slow server also slows the burst down.
  • A rate. The requests start on a fixed schedule — at 10 per second, one every 100 ms from the start — however slow the answers. A request whose moment comes while every worker is busy waits at most 50 ms for one; after that it is skipped and counted as Missed, never sent late. Missed requests mean the concurrency is too low for this rate, or the server is slower than the rate needs.
NumberWhat
SentRequests that have had an answer or failed
OKAnswered with a 2xx status
FailedNo answer, or any status outside 200–299
MissedSkipped, as above (only with a rate)
RPSRequests per second over the last tenth of a second; when the burst has ended, over the whole burst. With a rate, the label names the rate asked for.
p50, p90, p95, p99The time within which that share of the requests finished, failures included; accurate to within 0.5 %
Avg, Min, MaxThe mean, fastest and slowest

The numbers are updated about 10 times a second. The chart beside them draws the requests per second over the last 24 seconds or so.

With Digest, the first request's challenge is answered once and that answer serves every request of the burst.

WARNING

A burst is real load. Aim it only at servers you own or are allowed to test.

For ramps, steps, spikes and pass/fail thresholds, run the request under load in an experiment.

In the Inspector ​

With capture armed, each exchange appears as one frame with the protocol http and the source http: the method, URL, status and time in the summary, the response headers and the start of the body (2000 characters) in its detail, the status as its verdict (failed when no response came, · digest after 401 when a challenge was answered). The frame records the size of the body, not its bytes. The request's Authorization header is never in it. A burst puts at most one exchange every 100 ms into the capture. See Inspector.

Saving and reusing ​

  • Save as a signal. Save… keeps the request — method, URL, headers, body, timeout and authentication — in the signal library. The screen stays tied to it: Save (Ctrl+S) updates it, Save as… copies it, the chip opens it in Signals. Opening an HTTP signal from the library loads it back here, credentials included. See Signals.
  • Add to an experiment. Add to experiment adds an HTTP request step with the same request to the open experiment, right before End or after the selected step, and opens it.
  • Mock this. Below a response, Mock this makes an emulator route that answers this method and path with this status, headers and body. Choose an HTTP emulator in Add to, or A new emulator, and press Add the route; the route goes first in that emulator, and the Emulators screen opens on it. See Emulators.

In experiments ​

StepWhat it does
HTTP requestSends a request; its URL, headers, body and credentials take {{templates}}. It can run under load. Details
HTTP status, Response text, Response header, Response timeCheck the latest response. Details
Extract valueKeeps a JSON field, a header, the status, the body or a regular expression's match as a variable. Details
Status branchGoes on through Yes or No by the status. Details
Wait for HTTP requestWaits for a request to arrive — from the system you test — at the run's own listener or emulator. Details
EmulatorAn HTTP API that answers by routes for the whole run. Details

From the command line ​

signallab send http sends one request, as this screen does:

bash
signallab send http GET http://127.0.0.1:8080/health --expect-status 200
signallab send http POST http://127.0.0.1:8080/api/items \
  -H 'Content-Type: application/json' --body '{"name":"lamp"}'
signallab send http GET http://127.0.0.1:8080/private -u admin:secret --digest

The status line goes to standard error and the body to standard output:

text
HTTP 200 OK · 3 ms · 15 B
{"status":"ok"}
OptionWhatDefault
-H, --header 'Name: value'A header; repeat for more—
--body TEXT, --body @FILEThe body, or a file's contents—
--expect-status NExit 1 unless the status is N—
--timeout MSHow long to wait for the response10 000
-u, --user NAME:PASSWORDBasic authentication—
--digestWith --user: answer the server's Digest challenge instead—
--bearer TOKENAuthorization: Bearer TOKEN—
--jsonPrint the whole response as JSON on standard output—

It exits with 0 when a response came (and had the expected status), 1 when none came, the status was not the one expected or a Digest challenge could not be answered, and 2 when an option is invalid. It keeps no cookies. See Command line.

Problems ​

What you seeUsual cause
… refused the connection — nothing is listening on that portThe server is not running, or listens on another port or address.
No answer from … in timeThe server is slow or unreachable; check the address, or raise Timeout (ms).
Cannot resolve …The host name does not resolve on this machine — a typo, or a name only another network knows.
A secure connection to … could not be madeThe certificate is not trusted here (self-signed, expired, another name), or TLS failed. See Secure connections.
… is not a valid addressThe URL is malformed or does not start with http:// or https://.
The server says the body is missing or of the wrong typeNo Content-Type header that matches the body, or an empty body.
401 with DigestRead the message under the status: see Digest.
Missed above 0Raise Concurrency, or lower the rate: the server answers slower than the rate needs.
Failed high though the server answersEvery status outside 200–299 counts as failed, 404 and 500 included.

On a server, requests go out from the server: 127.0.0.1 is the server itself. See Server.

Every error message is listed in Error messages.