CHttp Visual Studio Code Extension
10/20/2023
4 minutes
I have been recently working on CHttp which is a tool to send HTTP requests and to measure the performance of REST APIs.
The primary goal of the tool is the ability to measure GET HTTP requests using version HTTP/2 and HTTP/3. As the tool is based on .NET (currently version 8), it requires a reasonably up-to-date Windows installation or the libmsquic package in case of Linux.
The standalone tool can be installed from GitHub, as a dotnet tool by using the dotnet tool install -g LaDeak.CHttp
command or by as a Visual Studio Code Extension.
Using CHttp Visual Studio Code Extension
The extension works with CHttp files. It is based on a file format that has been introduced by Huachao's REST Client extension.
Let's take a simple example to send an HTTP request:
GET https://localhost:5001/endpoint
Note, that the tool in the VS Code Extensions uses HTTP/2 by default. To change it, one can specify a different HTTP version as:
GET https://localhost:5001/endpoint HTTP/1.1
One can define headers and content. Separate headers and content with an empty line.
POST https://localhost:5001/jsonrequest
Content-Type:application/json
{
"message": "hello world"
}
To add comments use #
or //
characters. To separate queries, use the ###
character combination.
Variables
It is possible to define and re-use file level variables using the @variable
syntax. Then a variable can be referenced with the {{variable}}
syntax.
@baseUrl = localhost:5001
@path = delay
###
GET https://{{baseUrl}}/{{path}} HTTP/2
Variables may also reference another request's response content or headers. To achieve this, create a named request:
###
# @name jsonSample
GET https://localhost:5001/jsonresponse
###
@nextRequestContent = {{jsonSample.response.body.message}}
###
# echo
GET https://localhost:5001/echo
{{nextRequestContent}}
In the above case the top request is named by the # @name jsonSample
attribute. A variable @nextRequestContent
references the response body's message JSON field. Use json-path to refer to a custom element of the response. Use the [requestname].response.header.content-type
to refer to response headers.
Then use this variable in another request with {{nextRequestContent}}
reference.
Attributes
Use attributes to change the HTTP request behavior. At the time of writing the following attributes are supported:
clientscount
requestcount
timeout (in seconds)
no-certificate-validation
no-redirect
name
kerberos-auth
For example, to ignore certificate validation errors, set the @no-certificate-validation
attribute with value true.
# @no-certificate-validation true
GET https://localhost:5001/endpoint HTTP/1.1
Performance Measurements
Run performance measurements by defining either @clientscount
or @requestcount
attributes. Their default values are 10 and 100 respectively.
@baseUrl = localhost:5001
###
# @clientsCount 10
# @requestCount 100
GET https://{{baseUrl}}
While it is possible to set a request content, for performance measurements it is not suggested as larger requests can impact the performance measurement on client side.
Such requests will result an output of:
RequestCount: 100, Clients: 10
| Mean: 322,698 us |
| StdDev: 80,236 us |
| Error: 8,024 us |
| Median: 310,700 us |
| Min: 198,700 us |
| Max: 652,700 us |
| 95th: 473,700 us |
| Throughput: 0.000 B/s |
| Req/Sec: 2,82E+04 |
------------------------------------------------------------------------
244,100 us #########
289,500 us ###################
334,900 us ###################
380,300 us ##############
425,700 us ####
471,100 us ##
516,500 us ##
561,900 us #
607,300 us
652,700 us #
------------------------------------------------------------------------
HTTP status codes:
1xx: 0, 2xx: 100, 3xx: 0, 4xx: 0, 5xx: 0, Other: 0
------------------------------------------------------------------------
The output has three sections. The top section displays statistical results. The middle section draws a distribution of requests. The last section displays an aggregate view of the response codes.
I this case the mean execution time is 322.698 us. The distribution has a single mode. All requests 100 returned status codes from the 200-299 range.
Diff Performance Measurements
Compare two named performance measurement results with the DIFF
command. Use the @name [value]
pattern to give a referrable name to a query:
###
# @name comparison
# @clientsCount 10
# @requestCount 100
GET https://{{baseUrl}}/post HTTP/2
###
# @name basePerformance
# @clientsCount 10
# @requestCount 100
POST https://{{baseUrl}}/post
{"data":"hello world"}
###
DIFF basePerformance comparison
Diff results an aggregate view of the differences between the two requests.
RequestCount: 100, Clients: 10
| Mean: 448,127 us -55,265 us |
| StdDev: 151,588 us +120,312 us |
| Error: 15,159 us +12,031 us |
| Median: 413,600 us -115,100 us |
| Min: 265,300 us -137,600 us |
| Max: 1,285 ms +225,800 us |
| 95th: 763,700 us +220,100 us |
| Throughput: 0.000 B/s 0 B/s |
| Req/Sec: 1,16E+04 +9244,993 |
------------------------------------------------------------------------
266,040 us +++++++++++++
404,380 us =============###
542,720 us ====############
681,060 us =++
819,400 us ##
957,740 us =
1,096 ms =+
1,234 ms
1,373 ms
1,511 ms +
------------------------------------------------------------------------
HTTP status codes:
1xx: 0 +0, 2xx: 100 +0, 3xx: 0 +0, 4xx: 0 +0, 5xx: 0 +0, Other: 0 +0
------------------------------------------------------------------------
*Warning: session files contain different urls: https://localhost:5001/,https://localhost:5001/post
------------------------------------------------------------------------